diff --git a/headers/enduro2d/high/components/spine_player.hpp b/headers/enduro2d/high/components/spine_player.hpp index 1854df76..ae2a15a9 100644 --- a/headers/enduro2d/high/components/spine_player.hpp +++ b/headers/enduro2d/high/components/spine_player.hpp @@ -22,9 +22,13 @@ namespace e2d spine_player() = default; spine_player(const spine_model_asset::ptr& model); - spine_player& set_animation(u32 track, const str& name, bool loop); - spine_player& add_animation(u32 track, const str& name, bool loop, secf delay); - spine_player& add_empty_animation(u32 track, secf duration, secf delay); + spine_player& set_animation(u32 track, const str& name, bool loop = false); + + spine_player& add_animation(u32 track, const str& name, bool loop, secf delay = secf(0.0f)); + spine_player& add_animation(u32 track, const str& name, secf delay = secf(0.0f)); + + spine_player& add_empty_animation(u32 track, secf duration, secf delay = secf(0.0f)); + spine_player& clear(u32 track); spine_player& clear(); diff --git a/samples/bin/library/spine_raptor.json b/samples/bin/library/spine_raptor.json index daf58174..93f11198 100644 --- a/samples/bin/library/spine_raptor.json +++ b/samples/bin/library/spine_raptor.json @@ -1,6 +1,38 @@ { - "skeleton" : "raptor/raptor-pro.json-large", - "atlas" : "raptor/raptor.atlas", - "scale" : 1.0, - "premultiplied_alpha" : false -} \ No newline at end of file + "skeleton": "raptor/raptor-pro.json-large", + "atlas": "raptor/raptor.atlas", + "scale": 1.0, + "premultiplied_alpha": false, + "mix_animations": [ + { + "from_anim": "walk", + "to_anim": "roar", + "duration": 0.5 + }, + { + "from_anim": "roar", + "to_anim": "walk", + "duration": 0.5 + }, + { + "from_anim": "walk", + "to_anim": "jump", + "duration": 0.5 + }, + { + "from_anim": "jump", + "to_anim": "walk", + "duration": 0.5 + }, + { + "from_anim": "roar", + "to_anim": "jump", + "duration": 0.5 + }, + { + "from_anim": "jump", + "to_anim": "roar", + "duration": 0.5 + } + ] +} diff --git a/samples/sources/sample_07/sample_07.cpp b/samples/sources/sample_07/sample_07.cpp index c84df02f..7cffc429 100644 --- a/samples/sources/sample_07/sample_07.cpp +++ b/samples/sources/sample_07/sample_07.cpp @@ -11,6 +11,11 @@ namespace { class game_system final : public ecs::system { public: + game_system(gobject_iptr raptor) + : raptor_gobj_(raptor) {} + + ~game_system() noexcept override {} + void process(ecs::registry& owner) override { E2D_UNUSED(owner); const keyboard& k = the().keyboard(); @@ -26,7 +31,35 @@ namespace if ( k.is_key_pressed(keyboard_key::lsuper) && k.is_key_just_released(keyboard_key::enter) ) { the().toggle_fullscreen(!the().fullscreen()); } + + // use keys R, J, G to start animations + if ( raptor_gobj_ ) { + if ( k.is_key_just_pressed(keyboard_key::r) ) { + auto player = raptor_gobj_->get_component(); + if ( player ) { + (*player).set_animation(0, "roar") + .add_animation(0, "walk", true); + } + } + if ( k.is_key_just_pressed(keyboard_key::j) ) { + auto player = raptor_gobj_->get_component(); + if ( player ) { + (*player).set_animation(0, "jump") + .add_animation(0, "walk", true); + } + } + if ( k.is_key_just_pressed(keyboard_key::g) ) { + auto player = raptor_gobj_->get_component(); + if ( player ) { + (*player).set_animation(1, "gun-grab") + .add_animation(1, "gun-holster", secf(3.0f)); + } + } + } } + + private: + gobject_iptr raptor_gobj_; }; class camera_system final : public ecs::system { @@ -69,7 +102,6 @@ namespace node_iptr scene_r = scene_i->get_component().get().node(); - #if 1 auto coin_i = the().instantiate(); coin_i->entity_filler() .component(node::create(coin_i, scene_r)) @@ -80,42 +112,22 @@ namespace .set_animation(0, "animation", true)); node_iptr coin_n = coin_i->get_component().get().node(); - coin_n->scale(v3f(0.5f)); - coin_n->translation(v3f{150.0f, 0.0f, 0.0f}); + coin_n->scale(v3f(0.125f)); + coin_n->translation(v3f{200.0f, 200.0f, 0.0f}); - auto raptor_i = the().instantiate(); - raptor_i->entity_filler() - .component(node::create(raptor_i, scene_r)) + raptor_gobj_ = the().instantiate(); + raptor_gobj_->entity_filler() + .component(node::create(raptor_gobj_, scene_r)) .component(renderer() .materials({spine_mat})) .component(spine_renderer(spine_raptor)) .component(spine_player(spine_raptor) - .set_animation(0, "walk", true) - .add_animation(1, "gun-grab", false, secf(2.0f))); + .set_animation(0, "walk", true)); - node_iptr raptor_n = raptor_i->get_component().get().node(); + node_iptr raptor_n = raptor_gobj_->get_component().get().node(); raptor_n->scale(v3f(0.25f)); - raptor_n->translation(v3f{-170.f, -100.f, 0.0f}); + raptor_n->translation(v3f{-80.f, -100.f, 0.0f}); - #else - // performace test - for ( std::size_t i = 0; i < 20; ++i ) - for ( std::size_t j = 0; j < 40; ++j ) { - auto spine_i = the().instantiate(); - spine_i->entity_filler() - .component(node::create(spine_i, scene_r)) - .component(renderer() - .materials({spine_mat})) - .component(spine_renderer(spine_raptor)) - .component(spine_player(spine_raptor) - .set_animation(0, "walk", true) - .add_animation(1, "gun-grab", false, secf(2.0f))); - - node_iptr spine_n = spine_i->get_component().get().node(); - spine_n->scale(v3f(0.05f)); - spine_n->translation(v3f{-400.f, -300.f, 0.0f} + v3f{j * 30.f, i * 30.f, 0}); - } - #endif return true; } @@ -130,11 +142,14 @@ namespace bool create_systems() { ecs::registry_filler(the().registry()) - .system(world::priority_update) + .system(world::priority_update, raptor_gobj_) .system(world::priority_pre_render) .system(world::priority_update); return true; } + + private: + gobject_iptr raptor_gobj_; }; } diff --git a/sources/enduro2d/high/assets/spine_model_asset.cpp b/sources/enduro2d/high/assets/spine_model_asset.cpp index 178f4a28..e1bfb2f7 100644 --- a/sources/enduro2d/high/assets/spine_model_asset.cpp +++ b/sources/enduro2d/high/assets/spine_model_asset.cpp @@ -32,10 +32,7 @@ namespace "scale" : { "type" : "number" }, "atlas" : { "$ref" : "#/common_definitions/address" }, "premultiplied_alpha" : { "type" : "boolean" }, - "mix_animations" : { - "type" : "array", - "items" : { "$ref": "#/definitions/spine_animation_mix_array" } - } + "mix_animations" : { "$ref": "#/definitions/spine_animation_mix_array" } }, "definitions" : { "spine_animation_mix_array" : { diff --git a/sources/enduro2d/high/components/spine_player.cpp b/sources/enduro2d/high/components/spine_player.cpp index 7c7f9bc3..157232c9 100644 --- a/sources/enduro2d/high/components/spine_player.cpp +++ b/sources/enduro2d/high/components/spine_player.cpp @@ -41,6 +41,10 @@ namespace e2d return *this; } + spine_player& spine_player::add_animation(u32 track, const str& name, secf delay) { + return add_animation(track, name, false, delay); + } + spine_player& spine_player::add_animation(u32 track, const str& name, bool loop, secf delay) { E2D_ASSERT(model_ && animation_); E2D_ASSERT(track < max_track_count); diff --git a/sources/enduro2d/high/spine_model.cpp b/sources/enduro2d/high/spine_model.cpp index c78b54aa..e1f28b66 100644 --- a/sources/enduro2d/high/spine_model.cpp +++ b/sources/enduro2d/high/spine_model.cpp @@ -80,8 +80,11 @@ namespace e2d spine_model& spine_model::mix_animations(const str& from, const str& to, secf duration) { E2D_ASSERT(animation_); - spAnimationStateData_setMixByName(animation_.get(), from.c_str(), to.c_str(), duration.value); - return *this; + E2D_ASSERT(spSkeletonData_findAnimation(animation_->skeletonData, from.c_str())); + E2D_ASSERT(spSkeletonData_findAnimation(animation_->skeletonData, to.c_str())); + + spAnimationStateData_setMixByName(animation_.get(), from.c_str(), to.c_str(), duration.value); + return *this; } const spine_model::atlas_ptr& spine_model::atlas() const noexcept { diff --git a/sources/enduro2d/high/systems/spine_system.cpp b/sources/enduro2d/high/systems/spine_system.cpp index 88a480c4..deaa31e6 100644 --- a/sources/enduro2d/high/systems/spine_system.cpp +++ b/sources/enduro2d/high/systems/spine_system.cpp @@ -14,10 +14,11 @@ namespace e2d { - spine_system::spine_system() - {} + spine_system::spine_system() {} - spine_system::~spine_system() noexcept = default; + spine_system::~spine_system() noexcept { + spAnimationState_disposeStatics(); + } void spine_system::process(ecs::registry& owner) { float dt = the().delta_time();