diff --git a/src/modules/character/animation_system.cpp b/src/modules/character/animation_system.cpp index a2adac2..c128d38 100644 --- a/src/modules/character/animation_system.cpp +++ b/src/modules/character/animation_system.cpp @@ -89,20 +89,22 @@ void ECS::play(struct ECS::AnimationPlayerData *player, } c.current.from = &player->animation_set[name]; + flecs::log::trace("setting animation from %p", c.current.from); if (c.assigned != name) { // reset c.current.pos = p_from_end - ? c.current.from->animation->get_length() + ? c.current.from->get_animation()->get_length() : 0; } else { if (p_from_end && c.current.pos == 0) { // Animation reset BUT played backwards, set position // to the end c.current.pos = - c.current.from->animation->get_length(); + c.current.from->get_animation()->get_length(); } else if (!p_from_end && c.current.pos == - c.current.from->animation->get_length()) { + c.current.from->get_animation() + ->get_length()) { // Animation resumed but already ended, set position to // the beginning c.current.pos = 0; @@ -133,18 +135,21 @@ void ECS::play(struct ECS::AnimationPlayerData *player, if (next != StringName() && player->animation_set.has(next)) { queue(player, next); } + flecs::log::trace("%s(): %d animation %p", __func__, __LINE__, + c.current.from->get_animation().ptr()); } static void ECS::_ensure_node_caches(struct ECS::AnimationPlayerData *player, flecs::entity_t entity, flecs::world &ecs, AnimationData *p_anim, Node *p_root_override) { // Already cached? - assert(p_anim->animation.is_valid()); - if (p_anim->node_cache_size == p_anim->animation->get_track_count()) { + assert(p_anim->get_animation().is_valid()); + if (p_anim->node_cache_size == + p_anim->get_animation()->get_track_count()) { return; } - Animation *a = p_anim->animation.operator->(); + const Animation *a = p_anim->get_animation().operator->(); p_anim->node_cache_size = a->get_track_count(); @@ -238,9 +243,9 @@ static void ECS::_animation_process_animation(flecs::entity_t entity, { _ensure_node_caches(player, entity, ecs, p_anim); ERR_FAIL_COND(p_anim->node_cache_size != - p_anim->animation->get_track_count()); + p_anim->get_animation()->get_track_count()); - Animation *a = p_anim->animation.ptr(); + const Animation *a = p_anim->get_animation().ptr(); for (int i = 0; i < a->get_track_count(); i++) { // If an animation changes this animation (or it @@ -871,13 +876,15 @@ static void ECS::_animation_process_data(flecs::entity_t entity, { float delta = p_delta * player->speed_scale * cd.speed_scale; float next_pos = cd.pos + delta; - if (cd.from->animation.is_null()) { + if (cd.from->get_animation().is_null()) { ERR_PRINT("bad animation"); return; } - assert(cd.from->animation.is_valid()); - float len = cd.from->animation->get_length(); - bool loop = cd.from->animation->has_loop(); + assert(cd.from->get_animation().is_valid()); + flecs::log::trace("%s(): %d animation %p", __func__, __LINE__, + cd.from->get_animation().ptr()); + float len = cd.from->get_animation()->get_length(); + bool loop = cd.from->get_animation()->has_loop(); if (!loop) { if (next_pos < 0) next_pos = 0; @@ -925,10 +932,12 @@ static void ECS::_animation_process2(flecs::entity_t entity, flecs::world &ecs, ECS::Playback &c = player->playback; player->accum_pass++; - if (c.current.from->animation.is_null()) { + if (c.current.from->get_animation().is_null()) { ERR_PRINT("bad animation2"); return; } + flecs::log::trace("%s(): %d animation %p", __func__, __LINE__, + c.current.from->get_animation().ptr()); _animation_process_data(entity, ecs, player, c.current, p_delta, 1.0f, c.seeked && p_delta != 0, p_started); if (p_delta != 0) @@ -937,7 +946,7 @@ static void ECS::_animation_process2(flecs::entity_t entity, flecs::world &ecs, for (List::Element *E = c.blend.back(); E; E = prev) { Blend &b = E->get(); float blend = b.blend_left / b.blend_time; - if (b.data.from->animation.is_null()) { + if (b.data.from->get_animation().is_null()) { ERR_PRINT("bad animation3"); b.blend_left -= Math::absf(player->speed_scale * p_delta); @@ -953,6 +962,8 @@ static void ECS::_animation_process2(flecs::entity_t entity, flecs::world &ecs, if (b.blend_left < 0) c.blend.erase(E); } + flecs::log::trace("%s(): %d animation %p", __func__, __LINE__, + c.current.from->get_animation().ptr()); } /* transforms are set here */ static void ECS::_animation_update_transforms(flecs::entity_t entity, @@ -973,6 +984,8 @@ static void ECS::_animation_update_transforms(flecs::entity_t entity, bone_entity.modified(); } } + flecs::log::trace("update bones %f %f %f\n", t.origin.x, + t.origin.y, t.origin.z); } player->cache_update_size = 0; #ifdef VALUE_TRACK_SUPPORT @@ -1014,16 +1027,16 @@ static void ECS::_animation_update_transforms(flecs::entity_t entity, break; } } -#endif player->cache_update_prop_size = 0; +#endif #ifdef BEZIER_TRACK_SUPPORT for (i = 0; i < player->cache_update_bezier_size; i++) { TrackNodeCache::BezierAnim *ba = player->cache_update_bezier[i]; ba->object->set_indexed(ba->bezier_property, ba->bezier_accum); } -#endif player->cache_update_bezier_size = 0; +#endif } static void ECS::_set_process( struct ECS::AnimationPlayerData *player, bool p_process, bool p_force) @@ -1033,9 +1046,13 @@ static void ECS::_set_process( static void ECS::_animation_process(flecs::entity_t entity, flecs::world &ecs, struct ECS::AnimationPlayerData *player, float p_time) { + flecs::log::trace("animation_pocess: %f", p_time); if (player->playback.current.from) { + flecs::log::trace("animation at start: %p %p", + player->playback.current.from, + player->playback.current.from->get_animation().ptr()); flecs::log::trace("length: %f", - player->playback.current.from->animation + player->playback.current.from->get_animation() ->get_length()); player->end_reached = false; player->end_notify = false; @@ -1062,6 +1079,8 @@ static void ECS::_animation_process(flecs::entity_t entity, flecs::world &ecs, } player->end_reached = false; } + flecs::log::trace("animation at end: %p", + player->playback.current.from->get_animation().ptr()); } else _set_process(player, false); } @@ -1098,14 +1117,16 @@ Error ECS::add_animation(struct ECS::AnimationPlayerData *player, ERR_FAIL_COND_V(p_animation.is_null(), ERR_INVALID_PARAMETER); if (player->animation_set.has(p_name)) { - player->animation_set[p_name].animation = p_animation; - clear_caches(player); - } else { - AnimationData ad; - ad.animation = p_animation; + AnimationData ad(p_animation); + ad.name = p_name; + player->animation_set[p_name] = ad; + // player->animation_set[p_name].animation = + //p_animation; + clear_caches(player); + } else { + AnimationData ad(p_animation); ad.name = p_name; player->animation_set[p_name] = ad; - player->animation_set[p_name].animation = p_animation; } return OK; @@ -1129,15 +1150,27 @@ void ECS::clear_caches(struct ECS::AnimationPlayerData *player) E; E = E->next()) E->get().node_cache_size = 0; player->cache_update_size = 0; +#if 0 player->cache_update_prop_size = 0; player->cache_update_bezier_size = 0; +#endif } void ECS::advance(flecs::entity_t entity, flecs::world &ecs, ECS::AnimationPlayerData *player, float p_time) { + flecs::log::trace( + "start current.from %p", player->playback.current.from); + flecs::log::trace("advance animation at start: %p %p", + player->playback.current.from, + player->playback.current.from->get_animation().ptr()); ECS::_animation_process(entity, ecs, player, p_time); - player->playback.current.from = nullptr; + // player->playback.current.from = nullptr; + flecs::log::trace("advance animation at end: %p %p", + player->playback.current.from, + player->playback.current.from->get_animation().ptr()); + flecs::log::trace( + "end current.from %p", player->playback.current.from); } void ECS::stop(struct ECS::AnimationPlayerData *player, bool p_reset) { diff --git a/src/modules/character/animation_system.h b/src/modules/character/animation_system.h index f30f2eb..e075037 100644 --- a/src/modules/character/animation_system.h +++ b/src/modules/character/animation_system.h @@ -186,14 +186,63 @@ struct BasicTrack : public Track { struct AnimationData { String name; StringName next; - Ref animation; int node_cache_size; struct TrackNodeCache *node_cache[128]; AnimationData(Ref anim) : animation(anim), node_cache_size(0) { + assert(animation.is_valid()); } - AnimationData() : animation(Ref()), node_cache_size(0) {} + AnimationData() : + animation(Ref(nullptr)), node_cache_size(0) + { + } + AnimationData(const AnimationData &d) + { + int i; + name = d.name; + next = d.next; + node_cache_size = d.node_cache_size; + for (i = 0; i < 128; i++) + node_cache[i] = d.node_cache[i]; + animation = d.animation; + assert(animation.is_valid()); + flecs::log::trace("%s copy-constructed normally %p: %p", + __func__, this, animation.ptr()); + } + AnimationData(AnimationData &&d) + { + int i; + name = d.name; + next = d.next; + node_cache_size = d.node_cache_size; + for (i = 0; i < 128; i++) + node_cache[i] = d.node_cache[i]; + animation = d.animation; + assert(animation.is_valid()); + d.node_cache_size = 0; + d.name = ""; + d.next = ""; + d.animation = Ref(nullptr); + flecs::log::trace("%s move-constructed normally %p: %p", + __func__, this, animation.ptr()); + } + AnimationData &operator=(const AnimationData &d) + { + memnew_placement(this, AnimationData(d)); + return *this; + } + const Ref &get_animation() const + { + assert(animation.is_valid()); + flecs::log::trace("animation ptr %p", animation.ptr()); + return animation; + } + + ~AnimationData() { animation = Ref(nullptr); } + + private: + Ref animation; }; struct PlaybackData { AnimationData *from; @@ -206,6 +255,32 @@ struct PlaybackData { speed_scale = 1.0; from = nullptr; } + PlaybackData(const PlaybackData &d) + { + pos = d.pos; + speed_scale = d.speed_scale; + from = d.from; + flecs::log::trace( + "%s copy-constructed normally %p", __func__, this); + } + PlaybackData(PlaybackData &&d) + { + pos = d.pos; + speed_scale = d.speed_scale; + from = d.from; + d.pos = 0; + d.speed_scale = 1.0f; + d.from = nullptr; + flecs::log::trace( + "%s move-constructed normally %p", __func__, this); + } + PlaybackData &operator=(const PlaybackData &d) + { + from = d.from; + pos = d.pos; + speed_scale = d.speed_scale; + return *this; + } }; struct Blend { PlaybackData data; @@ -216,6 +291,29 @@ struct Blend { blend_left = 0.0f; blend_time = 0.0f; } + Blend(const Blend &d) + { + data = PlaybackData(d.data); + blend_time = d.blend_time; + blend_left = d.blend_left; + flecs::log::trace( + "%s copy-constructed normally %p", __func__, this); + } + Blend(Blend &&d) + { + data = std::move(d.data); + blend_time = d.blend_time; + blend_left = d.blend_left; + d.blend_left = 0.0f; + d.blend_time = 0.0f; + flecs::log::trace( + "%s move-constructed normally %p", __func__, this); + } + Blend &operator=(const Blend &d) + { + memnew_placement(this, Blend(d)); + return *this; + } }; struct Playback { List blend; @@ -223,6 +321,45 @@ struct Playback { StringName assigned; bool seeked; bool started; + Playback() + { + blend.clear(); + seeked = false; + started = false; + flecs::log::trace( + "%s constructed normally %p", __func__, this); + } + Playback(const Playback &d) + { + blend = List(); + const List::Element *e = d.blend.front(); + /* copy construct blends */ + while (e) { + blend.push_back(Blend(e->get())); + e = e->next(); + } + current = PlaybackData(d.current); + StringName assigned = d.assigned; + seeked = d.seeked; + started = d.started; + flecs::log::trace( + "%s copy-constructed normally %p", __func__, this); + } + Playback(Playback &&d) + { + blend = std::move(d.blend); + current = std::move(d.current); + StringName assigned = d.assigned; + seeked = d.seeked; + started = d.started; + flecs::log::trace( + "%s move-constructed normally %p", __func__, this); + } + Playback &operator=(const Playback &d) + { + memnew_placement(this, Playback(d)); + return *this; + } }; struct BlendKey { StringName from; @@ -252,10 +389,13 @@ struct AnimationPlayerData { Map node_cache_map; TrackNodeCache *cache_update[NODE_CACHE_UPDATE_MAX]; int cache_update_size; + +#if 0 TrackNodeCache::PropertyAnim *cache_update_prop[NODE_CACHE_UPDATE_MAX]; int cache_update_prop_size; TrackNodeCache::BezierAnim *cache_update_bezier[NODE_CACHE_UPDATE_MAX]; int cache_update_bezier_size; +#endif Set playing_caches; uint64_t accum_pass; float speed_scale; @@ -270,13 +410,158 @@ struct AnimationPlayerData { String autoplay; bool reset_on_save; AnimationProcessMode animation_process_mode; - AnimationMethodCallMode method_call_mode; bool processing; bool active; #if 0 NodePath root; #endif bool playing; + AnimationPlayerData() + { + processing = false; + playing = false; + active = false; + node_cache_map.clear(); + cache_update_size = 0; + playing_caches.clear(); + accum_pass = 0; + speed_scale = 1.0f; + default_blend_time = 0; + animation_set.clear(); + blend_times.clear(); + queued.clear(); + end_reached = false; + end_notify = false; + autoplay = ""; + reset_on_save = false; + animation_process_mode = + AnimationProcessMode::ANIMATION_PROCESS_MANUAL; + processing = false; + active = false; + flecs::log::trace( + "%s constructed normally %p", __func__, this); + } + AnimationPlayerData(const AnimationPlayerData &d) + { + int i; + node_cache_map = d.node_cache_map; + for (i = 0; i < NODE_CACHE_UPDATE_MAX; i++) + cache_update[i] = d.cache_update[i]; + cache_update_size = d.cache_update_size; + playing_caches = d.playing_caches; + accum_pass = d.accum_pass; + speed_scale = d.speed_scale; + default_blend_time = d.default_blend_time; + animation_set = d.animation_set; + blend_times = d.blend_times; + playback = d.playback; + queued = d.queued; + end_reached = d.end_reached; + end_notify = d.end_notify; + autoplay = d.autoplay; + reset_on_save = d.reset_on_save; + animation_process_mode = d.animation_process_mode; + processing = d.processing; + active = d.active; + playing = d.playing; + flecs::log::trace( + "%s copy-constructed normally %p", __func__, this); + } + AnimationPlayerData(AnimationPlayerData &&d) + { + memnew_placement(this, AnimationPlayerData(d)); +#if 0 + int i; + node_cache_map = d.node_cache_map; + for (i = 0; i < NODE_CACHE_UPDATE_MAX; i++) + cache_update[i] = d.cache_update[i]; + cache_update_size = d.cache_update_size; + playing_caches = d.playing_caches; + accum_pass = d.accum_pass; + speed_scale = d.speed_scale; + default_blend_time = d.default_blend_time; + animation_set = d.animation_set; + blend_times = d.blend_times; + playback = d.playback; + queued = d.queued; + end_reached = d.end_reached; + end_notify = d.end_notify; + autoplay = d.autoplay; + reset_on_save = d.reset_on_save; + animation_process_mode = d.animation_process_mode; + processing = d.processing; + active = d.active; + playing = d.playing; +#endif + d.playing = playing; + d.cache_update_size = 0; + d.active = false; + flecs::log::trace( + "%s move-constructed normally %p", __func__, this); + } + AnimationPlayerData &operator=(const AnimationPlayerData &d) + { + memnew_placement(this, AnimationPlayerData(d)); +#if 0 + int i; + node_cache_map = d.node_cache_map; + for (i = 0; i < NODE_CACHE_UPDATE_MAX; i++) + cache_update[i] = d.cache_update[i]; + cache_update_size = d.cache_update_size; + playing_caches = d.playing_caches; + accum_pass = d.accum_pass; + speed_scale = d.speed_scale; + default_blend_time = d.default_blend_time; + animation_set = d.animation_set; + blend_times = d.blend_times; + playback = d.playback; + queued = d.queued; + end_reached = d.end_reached; + end_notify = d.end_notify; + autoplay = d.autoplay; + reset_on_save = d.reset_on_save; + animation_process_mode = d.animation_process_mode; + processing = d.processing; + active = d.active; + playing = d.playing; +#endif + flecs::log::trace( + "%s copy-assigned normally %p", __func__, this); + + return *this; + } + AnimationPlayerData &operator=(AnimationPlayerData &&d) + { + int i; + node_cache_map = d.node_cache_map; + for (i = 0; i < NODE_CACHE_UPDATE_MAX; i++) + cache_update[i] = d.cache_update[i]; + cache_update_size = d.cache_update_size; + playing_caches = d.playing_caches; + accum_pass = d.accum_pass; + speed_scale = d.speed_scale; + default_blend_time = d.default_blend_time; + animation_set = d.animation_set; + blend_times = d.blend_times; + playback = d.playback; + queued = d.queued; + end_reached = d.end_reached; + end_notify = d.end_notify; + autoplay = d.autoplay; + reset_on_save = d.reset_on_save; + animation_process_mode = d.animation_process_mode; + processing = d.processing; + active = d.active; + playing = d.playing; + d.playing = playing; + d.cache_update_size = 0; + d.active = false; + flecs::log::trace( + "%s move-assigned normally %p", __func__, this); + + return *this; + } + ~AnimationPlayerData() { playing = false; } }; /* public functions */ StringName find_animation( diff --git a/src/modules/character/character.cpp b/src/modules/character/character.cpp index 662979d..b7f74f5 100644 --- a/src/modules/character/character.cpp +++ b/src/modules/character/character.cpp @@ -354,16 +354,33 @@ void Character::init_bone() void Character::animation_system_init() { ecs.component().on_set( - [](flecs::entity e, ECS::AnimationPlayerData &s) {}); + [](flecs::entity e, ECS::AnimationPlayerData &s) { + flecs::log::trace("AnimationPlayerData is written to"); + }); ecs.system("UpdateAnimation") .kind(flecs::OnUpdate) .each([](flecs::entity e, ECS::AnimationPlayerData &player) { + flecs::log::trace("== start of animation frame %p", + player.playback.current.from); + if (player.playback.current.from) + flecs::log::trace("start animation %p", + player.playback.current.from + ->get_animation() + .ptr()); + if (!player.playing) + flecs::log::trace("not playing any animation"); if (!player.playing) ECS::play(&player, "male-mx-walk-loop"); flecs::world w = e.world(); ECS::advance(e.id(), w, &player, SceneTree::get_singleton() ->get_physics_process_time()); + if (player.playback.current.from) + flecs::log::trace("end animation %p", + player.playback.current.from + ->get_animation() + .ptr()); + flecs::log::trace("== end of animation frame"); }); } void Character::initialize() diff --git a/src/modules/character/character_skeleton.cpp b/src/modules/character/character_skeleton.cpp index 2fee044..1c4fa1b 100644 --- a/src/modules/character/character_skeleton.cpp +++ b/src/modules/character/character_skeleton.cpp @@ -197,8 +197,6 @@ void Character::init_skeleton() } } } - // flecs::log::trace("transform should be - // ready"); e.add(); assert(sk.skin_bone_indices_ptrs); uint32_t bind_count = sk.skin->get_bind_count();