diff options
author | Juan Linietsky <reduzio@gmail.com> | 2016-06-08 18:03:06 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2016-06-08 18:03:06 -0300 |
commit | beabefe432bc8f6ec75f2cbdac96e055ae74f3fa (patch) | |
tree | 2a8931d0370ff5c798291a8320ece814ab450b5a /scene/3d | |
parent | c1705899299566609fece7ff890c658505557f19 (diff) |
port changes from AnimatedSprite to AnimatedSprite3D
Diffstat (limited to 'scene/3d')
-rw-r--r-- | scene/3d/sprite_3d.cpp | 499 | ||||
-rw-r--r-- | scene/3d/sprite_3d.h | 63 |
2 files changed, 561 insertions, 1 deletions
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index da83e9b6d2..a65d199937 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -600,6 +600,7 @@ Sprite3D::Sprite3D() { //////////////////////////////////////// +#if 0 void AnimatedSprite3D::_draw() { @@ -811,3 +812,501 @@ AnimatedSprite3D::AnimatedSprite3D() { } + +#endif + + +void AnimatedSprite3D::_draw() { + + RID immediate = get_immediate(); + VS::get_singleton()->immediate_clear(immediate); + + + if (frames.is_null()) { + return; + } + + if (frame<0) { + return; + } + + if (!frames->has_animation(animation)) { + return; + } + + + Ref<Texture> texture = frames->get_frame(animation,frame); + if (!texture.is_valid()) + return; //no texuture no life + Vector2 tsize = texture->get_size(); + if (tsize.x==0 || tsize.y==0) + return; + + Size2i s=tsize; + Rect2i src_rect; + + src_rect.size=s; + + Point2i ofs=get_offset(); + if (is_centered()) + ofs-=s/2; + + Rect2i dst_rect(ofs,s); + + + Rect2 final_rect; + Rect2 final_src_rect; + if (!texture->get_rect_region(dst_rect,src_rect,final_rect,final_src_rect)) + return; + + + if (final_rect.size.x==0 || final_rect.size.y==0) + return; + + Color color=_get_color_accum(); + color.a*=get_opacity(); + + float pixel_size=get_pixel_size(); + + Vector2 vertices[4]={ + + (final_rect.pos+Vector2(0,final_rect.size.y)) * pixel_size, + (final_rect.pos+final_rect.size) * pixel_size, + (final_rect.pos+Vector2(final_rect.size.x,0)) * pixel_size, + final_rect.pos * pixel_size, + + + }; + Vector2 uvs[4]={ + final_src_rect.pos / tsize, + (final_src_rect.pos+Vector2(final_src_rect.size.x,0)) / tsize, + (final_src_rect.pos+final_src_rect.size) / tsize, + (final_src_rect.pos+Vector2(0,final_src_rect.size.y)) / tsize, + }; + + if (is_flipped_h()) { + SWAP(uvs[0],uvs[1]); + SWAP(uvs[2],uvs[3]); + } + if (is_flipped_v()) { + + SWAP(uvs[0],uvs[3]); + SWAP(uvs[1],uvs[2]); + } + + + Vector3 normal; + int axis = get_axis(); + normal[axis]=1.0; + + RID mat = VS::get_singleton()->material_2d_get(get_draw_flag(FLAG_SHADED),get_draw_flag(FLAG_TRANSPARENT),get_alpha_cut_mode()==ALPHA_CUT_DISCARD,get_alpha_cut_mode()==ALPHA_CUT_OPAQUE_PREPASS); + VS::get_singleton()->immediate_set_material(immediate,mat); + + VS::get_singleton()->immediate_begin(immediate,VS::PRIMITIVE_TRIANGLE_FAN,texture->get_rid()); + + int x_axis = ((axis + 1) % 3); + int y_axis = ((axis + 2) % 3); + + if (axis!=Vector3::AXIS_Z) { + SWAP(x_axis,y_axis); + + for(int i=0;i<4;i++) { + //uvs[i] = Vector2(1.0,1.0)-uvs[i]; + //SWAP(vertices[i].x,vertices[i].y); + if (axis==Vector3::AXIS_Y) { + vertices[i].y = - vertices[i].y; + } else if (axis==Vector3::AXIS_X) { + vertices[i].x = - vertices[i].x; + } + } + } + + AABB aabb; + + for(int i=0;i<4;i++) { + VS::get_singleton()->immediate_normal(immediate,normal); + VS::get_singleton()->immediate_color(immediate,color); + VS::get_singleton()->immediate_uv(immediate,uvs[i]); + + Vector3 vtx; + vtx[x_axis]=vertices[i][0]; + vtx[y_axis]=vertices[i][1]; + VS::get_singleton()->immediate_vertex(immediate,vtx); + if (i==0) { + aabb.pos=vtx; + aabb.size=Vector3(); + } else { + aabb.expand_to(vtx); + } + } + set_aabb(aabb); + VS::get_singleton()->immediate_end(immediate); + +} + + + +void AnimatedSprite3D::_validate_property(PropertyInfo& property) const { + + if (!frames.is_valid()) + return; + if (property.name=="animation") { + + property.hint=PROPERTY_HINT_ENUM; + List<StringName> names; + frames->get_animation_list(&names); + names.sort_custom<StringName::AlphCompare>(); + + bool current_found=false; + + for (List<StringName>::Element *E=names.front();E;E=E->next()) { + if (E->prev()) { + property.hint_string+=","; + } + + property.hint_string+=String(E->get()); + if (animation==E->get()) { + current_found=true; + } + } + + if (!current_found) { + if (property.hint_string==String()) { + property.hint_string=String(animation); + } else { + property.hint_string=String(animation)+","+property.hint_string; + } + } + } + + + if (property.name=="frame") { + + property.hint=PROPERTY_HINT_RANGE; + + if (frames->has_animation(animation)) { + property.hint_string="0,"+itos(frames->get_frame_count(animation)-1)+",1"; + } else { + property.hint_string="0,0,0"; + } + } + +} + +void AnimatedSprite3D::_notification(int p_what) { + + switch(p_what) { + case NOTIFICATION_PROCESS: { + + if (frames.is_null()) + return; + if (!frames->has_animation(animation)) + return; + if (frame<0) + return; + + float speed = frames->get_animation_speed(animation); + if (speed==0) + return; //do nothing + + float remaining = get_process_delta_time(); + + while(remaining) { + + if (timeout<=0) { + + timeout=1.0/speed; + + int fc = frames->get_frame_count(animation); + if (frame>=fc-1) { + if (frames->get_animation_loop(animation)) { + frame=0; + } else { + frame=fc-1; + } + } else { + frame++; + } + + _queue_update(); + _change_notify("frame"); + } + + float to_process = MIN(timeout,remaining); + remaining-=to_process; + timeout-=to_process; + } + } break; +#if 0 + case NOTIFICATION_DRAW: { + + if (frames.is_null()) { + print_line("no draw no faemos"); + return; + } + + if (frame<0) { + print_line("no draw frame <0"); + return; + } + + if (!frames->has_animation(animation)) { + print_line("no draw no anim: "+String(animation)); + return; + } + + + + Ref<Texture> texture = frames->get_frame(animation,frame); + if (texture.is_null()) { + print_line("no draw texture is null"); + return; + } + + //print_line("DECIDED TO DRAW"); + + RID ci = get_canvas_item(); + + /* + texture->draw(ci,Point2()); + break; + */ + + Size2i s; + s = texture->get_size(); + Point2 ofs=offset; + if (centered) + ofs-=s/2; + + if (OS::get_singleton()->get_use_pixel_snap()) { + ofs=ofs.floor(); + } + Rect2 dst_rect(ofs,s); + + if (hflip) + dst_rect.size.x=-dst_rect.size.x; + if (vflip) + dst_rect.size.y=-dst_rect.size.y; + + //texture->draw_rect(ci,dst_rect,false,modulate); + texture->draw_rect_region(ci,dst_rect,Rect2(Vector2(),texture->get_size()),modulate); +// VisualServer::get_singleton()->canvas_item_add_texture_rect_region(ci,dst_rect,texture->get_rid(),src_rect,modulate); + + } break; +#endif + } + +} + +void AnimatedSprite3D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { + + if (frames.is_valid()) + frames->disconnect("changed",this,"_res_changed"); + frames=p_frames; + if (frames.is_valid()) + frames->connect("changed",this,"_res_changed"); + + if (!frames.is_valid()) { + frame=0; + } else { + set_frame(frame); + } + + + + _change_notify(); + _reset_timeout(); + _queue_update(); + update_configuration_warning(); + +} + +Ref<SpriteFrames> AnimatedSprite3D::get_sprite_frames() const { + + return frames; +} + +void AnimatedSprite3D::set_frame(int p_frame) { + + if (!frames.is_valid()) { + return; + } + + if (frames->has_animation(animation)) { + int limit = frames->get_frame_count(animation); + if (p_frame>=limit) + p_frame=limit-1; + + } + + if (p_frame<0) + p_frame=0; + + + if (frame==p_frame) + return; + + frame=p_frame; + _reset_timeout(); + _queue_update();; + _change_notify("frame"); + emit_signal(SceneStringNames::get_singleton()->frame_changed); + + + +} +int AnimatedSprite3D::get_frame() const { + + return frame; +} + + + +Rect2 AnimatedSprite3D::get_item_rect() const { + + if (!frames.is_valid() || !frames->has_animation(animation) || frame<0 || frame>=frames->get_frame_count(animation)) { + return Rect2(0,0,1,1); + } + + Ref<Texture> t; + if (animation) + t = frames->get_frame(animation,frame); + if (t.is_null()) + return Rect2(0,0,1,1); + Size2i s = t->get_size(); + + Point2 ofs=offset; + if (centered) + ofs-=s/2; + + if (s==Size2(0,0)) + s=Size2(1,1); + + return Rect2(ofs,s); +} + +void AnimatedSprite3D::_res_changed() { + + set_frame(frame); + _change_notify("frame"); + _change_notify("animation"); + _queue_update(); +} + +void AnimatedSprite3D::_set_playing(bool p_playing) { + + if (playing==p_playing) + return; + playing=p_playing; + _reset_timeout(); + set_process(playing); +} + +bool AnimatedSprite3D::_is_playing() const { + + return playing; +} + +void AnimatedSprite3D::play(const StringName& p_animation) { + + if (p_animation) + set_animation(p_animation); + _set_playing(true); +} + +void AnimatedSprite3D::stop(){ + + _set_playing(false); +} + +bool AnimatedSprite3D::is_playing() const { + + return is_processing(); +} + +void AnimatedSprite3D::_reset_timeout() { + + if (!playing) + return; + + if (frames.is_valid() && frames->has_animation(animation)) { + float speed = frames->get_animation_speed(animation); + if (speed>0) { + timeout=1.0/speed; + } else { + timeout=0; + } + } else { + timeout=0; + } + +} + +void AnimatedSprite3D::set_animation(const StringName& p_animation){ + + if (animation==p_animation) + return; + + animation=p_animation; + _reset_timeout(); + set_frame(0); + _change_notify(); + _queue_update();; +} +StringName AnimatedSprite3D::get_animation() const{ + + return animation; +} + +String AnimatedSprite3D::get_configuration_warning() const { + + if (frames.is_null()) { + return TTR("A SpriteFrames resource must be created or set in the 'Frames' property in order for AnimatedSprite3D to display frames."); + } + + return String(); +} + +void AnimatedSprite3D::_bind_methods() { + + + ObjectTypeDB::bind_method(_MD("set_sprite_frames","sprite_frames:SpriteFrames"),&AnimatedSprite3D::set_sprite_frames); + ObjectTypeDB::bind_method(_MD("get_sprite_frames:SpriteFrames"),&AnimatedSprite3D::get_sprite_frames); + + ObjectTypeDB::bind_method(_MD("set_animation","animation"),&AnimatedSprite3D::set_animation); + ObjectTypeDB::bind_method(_MD("get_animation"),&AnimatedSprite3D::get_animation); + + ObjectTypeDB::bind_method(_MD("_set_playing","playing"),&AnimatedSprite3D::_set_playing); + ObjectTypeDB::bind_method(_MD("_is_playing"),&AnimatedSprite3D::_is_playing); + + ObjectTypeDB::bind_method(_MD("play","anim"),&AnimatedSprite3D::play,DEFVAL(StringName())); + ObjectTypeDB::bind_method(_MD("stop"),&AnimatedSprite3D::stop); + ObjectTypeDB::bind_method(_MD("is_playing"),&AnimatedSprite3D::is_playing); + + + ObjectTypeDB::bind_method(_MD("set_frame","frame"),&AnimatedSprite3D::set_frame); + ObjectTypeDB::bind_method(_MD("get_frame"),&AnimatedSprite3D::get_frame); + + ObjectTypeDB::bind_method(_MD("_res_changed"),&AnimatedSprite3D::_res_changed); + + ADD_SIGNAL(MethodInfo("frame_changed")); + + ADD_PROPERTYNZ( PropertyInfo( Variant::OBJECT, "frames",PROPERTY_HINT_RESOURCE_TYPE,"SpriteFrames"), _SCS("set_sprite_frames"),_SCS("get_sprite_frames")); + ADD_PROPERTY( PropertyInfo( Variant::STRING, "animation"), _SCS("set_animation"),_SCS("get_animation")); + ADD_PROPERTYNZ( PropertyInfo( Variant::INT, "frame",PROPERTY_HINT_SPRITE_FRAME), _SCS("set_frame"),_SCS("get_frame")); + ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "playing"), _SCS("_set_playing"),_SCS("_is_playing")); + + +} + +AnimatedSprite3D::AnimatedSprite3D() { + + frame=0; + playing=false; + animation="default"; + timeout=0; + + +} + + diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index d8e589556c..d1d859f634 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -158,7 +158,7 @@ public: // ~Sprite3D(); }; - +#if 0 class AnimatedSprite3D : public SpriteBase3D { OBJ_TYPE(AnimatedSprite3D,SpriteBase3D); @@ -187,6 +187,67 @@ public: AnimatedSprite3D(); // ~AnimatedSprite3D(); }; +#endif + + + + +class AnimatedSprite3D : public SpriteBase3D { + + OBJ_TYPE(AnimatedSprite3D,SpriteBase3D); + + Ref<SpriteFrames> frames; + bool playing; + StringName animation; + int frame; + + bool centered; + Point2 offset; + + float timeout; + + bool hflip; + bool vflip; + + Color modulate; + + void _res_changed(); + + void _reset_timeout(); + void _set_playing(bool p_playing); + bool _is_playing() const; + + +protected: + + virtual void _draw(); + static void _bind_methods(); + void _notification(int p_what); + virtual void _validate_property(PropertyInfo& property) const; + +public: + + + + void set_sprite_frames(const Ref<SpriteFrames> &p_frames); + Ref<SpriteFrames> get_sprite_frames() const; + + void play(const StringName& p_animation=StringName()); + void stop(); + bool is_playing() const; + + void set_animation(const StringName& p_animation); + StringName get_animation() const; + + void set_frame(int p_frame); + int get_frame() const; + + + virtual Rect2 get_item_rect() const; + + virtual String get_configuration_warning() const; + AnimatedSprite3D(); +}; VARIANT_ENUM_CAST(SpriteBase3D::DrawFlags); |