diff --git a/.vscode/settings.json b/.vscode/settings.json index bace45e..be4dc7e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,6 +6,10 @@ "future": "cpp", "istream": "cpp", "functional": "cpp", - "numbers": "cpp" + "numbers": "cpp", + "*.inc": "cpp", + "*.tcc": "cpp", + "ranges": "cpp", + "streambuf": "cpp" } } \ No newline at end of file diff --git a/src/modules/character/animation_system.cpp b/src/modules/character/animation_system.cpp index 5c1daed..1bdc14d 100644 --- a/src/modules/character/animation_system.cpp +++ b/src/modules/character/animation_system.cpp @@ -5,23 +5,27 @@ #include #include "animation_system.h" +#include "character.h" /* private functions */ namespace ECS { -static void _animation_process_animation(struct AnimationPlayerData *player, +static void _animation_process_animation(flecs::entity_t entity, + flecs::world &ecs, struct AnimationPlayerData *player, AnimationData *p_anim, float p_time, float p_delta, float p_interp, bool p_is_current = true, bool p_seeked = false, bool p_started = false); static void _ensure_node_caches(struct AnimationPlayerData *player, - AnimationData *p_anim, Node *p_root_override = NULL); -static void _animation_process_data(struct AnimationPlayerData *player, - PlaybackData &cd, float p_delta, float p_blend, bool p_seeked, - bool p_started); -static void _animation_process2( + flecs::entity_t entity, flecs::world &ecs, AnimationData *p_anim, + Node *p_root_override = NULL); +static void _animation_process_data(flecs::entity_t entity, flecs::world &ecs, + struct AnimationPlayerData *player, PlaybackData &cd, float p_delta, + float p_blend, bool p_seeked, bool p_started); +static void _animation_process2(flecs::entity_t entity, flecs::world &ecs, struct AnimationPlayerData *player, float p_delta, bool p_started); -static void _animation_update_transforms(struct AnimationPlayerData *player); -static void _animation_process( - struct AnimationPlayerData *player, float p_delta); +static void _animation_update_transforms(flecs::entity_t entity, + flecs::world &ecs, struct AnimationPlayerData *player); +static void _animation_process(flecs::entity_t entity, flecs::world &ecs, + struct AnimationPlayerData *player, float p_time); // static void _node_removed(struct AnimationPlayerData *player, // Node *p_node); static void _stop_playing_caches(struct AnimationPlayerData *player); @@ -145,7 +149,8 @@ void ECS::play(struct ECS::AnimationPlayerData *player, } } static void ECS::_ensure_node_caches(struct ECS::AnimationPlayerData *player, - AnimationData *p_anim, Node *p_root_override) + flecs::entity_t entity, flecs::world &ecs, AnimationData *p_anim, + Node *p_root_override) { // Already cached? assert(p_anim->animation.is_valid()); @@ -205,12 +210,16 @@ static void ECS::_ensure_node_caches(struct ECS::AnimationPlayerData *player, #endif ECS::TrackNodeCacheKey key; - key.id = id; - key.bone_idx = bone_idx; - String path = a->track_get_path(i); + key.id = entity; + flecs::entity e = ecs.entity(entity); + flecs::entity bone_e = + e.lookup(String(np.get_subname(0)).ascii().get_data()); + flecs::entity_t bone_id = bone_e.id(); + key.bone_idx = bone_id; + String path = np.get_subname(0); print_line("TRACK: " + itos(i) + - " BONE IDX: " + itos(bone_idx) + " ID: " + itos(id) + - " PATH: " + path); + " BONE IDX: " + itos(bone_id) + + " ID: " + itos(entity) + " PATH: " + path); if (!player->node_cache_map.has(key)) player->node_cache_map[key] = ECS::TrackNodeCache(); @@ -240,17 +249,18 @@ static void ECS::_ensure_node_caches(struct ECS::AnimationPlayerData *player, .get_subname(0); /* use entities */ + p_anim->node_cache[i]->bone_idx = + key.bone_idx; #if 0 p_anim->node_cache[i]->bone_idx = p_anim->node_cache[i]->skeleton->find_bone(bone_name); #endif +#if 0 if (p_anim->node_cache[i]->bone_idx < 0) { // broken track (nonexistent // bone) -#if 0 p_anim->node_cache[i]->skeleton = nullptr; p_anim->node_cache[i]->spatial = nullptr; -#endif ERR_CONTINUE( p_anim->node_cache[i] ->bone_idx < @@ -260,55 +270,58 @@ static void ECS::_ensure_node_caches(struct ECS::AnimationPlayerData *player, #if 0 // no property, just use spatialnode p_anim->node_cache[i]->skeleton = nullptr; +#endif + } #endif } } - } - if (a->track_get_type(i) == Animation::TYPE_VALUE) { - if (!p_anim->node_cache[i]->property_anim.has( - a->track_get_path(i) - .get_concatenated_subnames())) { - TrackNodeCache::PropertyAnim pa; - pa.subpath = leftover_path; +#if 0 + if (a->track_get_type(i) == Animation::TYPE_VALUE) { + if (!p_anim->node_cache[i]->property_anim.has( + a->track_get_path(i) + .get_concatenated_subnames())) { + TrackNodeCache::PropertyAnim pa; + pa.subpath = leftover_path; #if 0 pa.object = resource.is_valid() ? (Object *)resource.ptr() : (Object *)child; #endif - pa.special = SP_NONE; - pa.owner = p_anim->node_cache[i]; - p_anim->node_cache[i]->property_anim - [a->track_get_path(i) - .get_concatenated_subnames()] = - pa; + pa.special = SP_NONE; + pa.owner = p_anim->node_cache[i]; + p_anim->node_cache[i]->property_anim + [a->track_get_path(i) + .get_concatenated_subnames()] = + pa; + } } - } - if (a->track_get_type(i) == Animation::TYPE_BEZIER && - leftover_path.size()) { - if (!p_anim->node_cache[i]->bezier_anim.has( - a->track_get_path(i) - .get_concatenated_subnames())) { - TrackNodeCache::BezierAnim ba; - ba.bezier_property = leftover_path; + if (a->track_get_type(i) == Animation::TYPE_BEZIER && + leftover_path.size()) { + if (!p_anim->node_cache[i]->bezier_anim.has( + a->track_get_path(i) + .get_concatenated_subnames())) { + TrackNodeCache::BezierAnim ba; + ba.bezier_property = leftover_path; #if 0 ba.object = resource.is_valid() ? (Object *)resource.ptr() : (Object *)child; #endif - ba.owner = p_anim->node_cache[i]; + ba.owner = p_anim->node_cache[i]; - p_anim->node_cache[i]->bezier_anim - [a->track_get_path(i) - .get_concatenated_subnames()] = - ba; - } + p_anim->node_cache[i]->bezier_anim + [a->track_get_path(i) + .get_concatenated_subnames()] = + ba; + } +#endif } } } -static void ECS::_animation_process_animation( - struct ECS::AnimationPlayerData *player, ECS::AnimationData *p_anim, - float p_time, float p_delta, float p_interp, bool p_is_current, - bool p_seeked, bool p_started) +static void ECS::_animation_process_animation(flecs::entity_t entity, + flecs::world &ecs, struct ECS::AnimationPlayerData *player, + ECS::AnimationData *p_anim, float p_time, float p_delta, + float p_interp, bool p_is_current, bool p_seeked, bool p_started) { - _ensure_node_caches(player, p_anim); + _ensure_node_caches(player, entity, ecs, p_anim); ERR_FAIL_COND(p_anim->node_cache_size != p_anim->animation->get_track_count()); @@ -318,20 +331,23 @@ static void ECS::_animation_process_animation( #endif for (int i = 0; i < a->get_track_count(); i++) { - // If an animation changes this animation (or it animates - // itself) we need to recreate our animation cache + // If an animation changes this animation (or it + // animates itself) we need to recreate our animation + // cache if (p_anim->node_cache_size != a->get_track_count()) { - _ensure_node_caches(player, p_anim); + _ensure_node_caches(player, entity, ecs, p_anim); } TrackNodeCache *nc = p_anim->node_cache[i]; if (!nc) { - continue; // no node cache for this track, skip it + continue; // no node cache for this track, skip + // it } if (!a->track_is_enabled(i)) { - continue; // do nothing if the track is disabled + continue; // do nothing if the track is + // disabled } flecs::log::trace("track keys: %d", i); if (a->track_get_key_count(i) == 0) { @@ -351,8 +367,8 @@ static void ECS::_animation_process_animation( Error err = a->transform_track_interpolate( i, p_time, &loc, &rot, &scale); - //ERR_CONTINUE(err!=OK); //used for testing, - //should be removed + //ERR_CONTINUE(err!=OK); //used for + //testing, should be removed if (err != OK) { continue; @@ -369,6 +385,8 @@ static void ECS::_animation_process_animation( nc->loc_accum = loc; nc->rot_accum = rot; nc->scale_accum = scale; + print_line("cache update: " + + itos(nc->bone_idx)); } else { nc->loc_accum = @@ -382,6 +400,8 @@ static void ECS::_animation_process_animation( .linear_interpolate( scale, p_interp); + print_line("cache update2: " + + itos(nc->bone_idx)); } } break; @@ -418,7 +438,8 @@ static void ECS::_animation_process_animation( int key_count = a->track_get_key_count(i); if (key_count == 0) { - continue; //eeh not worth it + continue; //eeh not + //worth it } float first_key_time = @@ -427,11 +448,15 @@ static void ECS::_animation_process_animation( int first_key = 0; if (first_key_time == 0.0) { - //ignore, use for transition + //ignore, use for + //transition if (key_count == 1) { - continue; //with one - //key we - //can't do + continue; //with + //one + //key + //we + //can't + //do //anything } transition = @@ -497,14 +522,14 @@ static void ECS::_animation_process_animation( continue; } - //thanks to trigger mode, this should - //be solved now.. + //thanks to trigger mode, this + //should be solved now.. /* if (p_delta==0 && value.get_type()==Variant::STRING) - continue; // doing this with - strings is messy, should find another - way + continue; // doing this + with strings is messy, should + find another way */ if (pa->accum_pass != player->accum_pass) { @@ -623,8 +648,10 @@ static void ECS::_animation_process_animation( #endif static_assert(VARIANT_ARG_MAX == 8, - "This code needs to be " - "updated if VARIANT_ARG_MAX " + "This code needs to " + "be " + "updated if " + "VARIANT_ARG_MAX " "!= 8"); #if 0 if (player->can_call) { @@ -703,7 +730,8 @@ static void ECS::_animation_process_animation( } if (p_seeked) { - //find whatever should be playing + //find whatever should be + //playing int idx = a->track_find_key(i, p_time); if (idx < 0) { continue; @@ -863,7 +891,8 @@ static void ECS::_animation_process_animation( } break; case Animation::TYPE_ANIMATION: { - /* animations of animations - need rework */ + /* animations of animations - need + * rework */ #if 0 AnimationPlayer *player = Object::cast_to(nc->node); if (!player) { @@ -930,9 +959,10 @@ static void ECS::_animation_process_animation( } } } -static void ECS::_animation_process_data( - struct ECS::AnimationPlayerData *player, PlaybackData &cd, - float p_delta, float p_blend, bool p_seeked, bool p_started) +static void ECS::_animation_process_data(flecs::entity_t entity, + flecs::world &ecs, struct ECS::AnimationPlayerData *player, + PlaybackData &cd, float p_delta, float p_blend, bool p_seeked, + bool p_started) { float delta = p_delta * player->speed_scale * cd.speed_scale; float next_pos = cd.pos + delta; @@ -953,36 +983,39 @@ static void ECS::_animation_process_data( bool backwards = signbit(delta); // Negative zero means playing backwards too delta = next_pos - - cd.pos; // Fix delta (after determination of backwards because - // negative zero is lost here) + cd.pos; // Fix delta (after determination of backwards + // because negative zero is lost here) if (&cd == &player->playback.current) { if (!backwards && cd.pos <= len && next_pos == len) { //playback finished player->end_reached = true; - player->end_notify = cd.pos < - len; // Notify only if not already at the end + player->end_notify = + cd.pos < len; // Notify only if not + // already at the end } if (backwards && cd.pos >= 0 && next_pos == 0) { //playback finished player->end_reached = true; player->end_notify = - cd.pos > 0; // Notify only if not already at - // the beginning + cd.pos > 0; // Notify only if not + // already at the beginning } } else { float looped_next_pos = Math::fposmod(next_pos, len); if (looped_next_pos == 0 && next_pos != 0) - // Loop multiples of the length to it, rather than 0 - // so state at time=length is previewable in the editor + // Loop multiples of the length to it, rather + // than 0 so state at time=length is + // previewable in the editor next_pos = len; else next_pos = looped_next_pos; } cd.pos = next_pos; - _animation_process_animation(player, cd.from, cd.pos, delta, p_blend, - &cd == &player->playback.current, p_seeked, p_started); + _animation_process_animation(entity, ecs, player, cd.from, cd.pos, + delta, p_blend, &cd == &player->playback.current, p_seeked, + p_started); } -static void ECS::_animation_process2( +static void ECS::_animation_process2(flecs::entity_t entity, flecs::world &ecs, struct ECS::AnimationPlayerData *player, float p_delta, bool p_started) { ECS::Playback &c = player->playback; @@ -994,7 +1027,7 @@ static void ECS::_animation_process2( } flecs::log::trace("length: %d", player->playback.current.from->animation->get_length()); - _animation_process_data(player, c.current, p_delta, 1.0f, + _animation_process_data(entity, ecs, player, c.current, p_delta, 1.0f, c.seeked && p_delta != 0, p_started); if (p_delta != 0) c.seeked = false; @@ -1011,16 +1044,17 @@ static void ECS::_animation_process2( c.blend.erase(E); continue; } - _animation_process_data( - player, b.data, p_delta, blend, false, false); + _animation_process_data(entity, ecs, player, b.data, p_delta, + blend, false, false); b.blend_left -= Math::absf(player->speed_scale * p_delta); prev = E->prev(); if (b.blend_left < 0) c.blend.erase(E); } } -static void ECS::_animation_update_transforms( - struct ECS::AnimationPlayerData *player) +/* transforms are set here */ +static void ECS::_animation_update_transforms(flecs::entity_t entity, + flecs::world &ecs, struct ECS::AnimationPlayerData *player) { int i; { @@ -1029,6 +1063,15 @@ static void ECS::_animation_update_transforms( TrackNodeCache *nc = player->cache_update[i]; t.origin = nc->loc_accum; t.basis.set_quat_scale(nc->rot_accum, nc->scale_accum); + flecs::entity bone_entity = ecs.entity(nc->bone_idx); + if (bone_entity) { + ECS::BonePose *bone = + bone_entity.get_mut(); + bone->pose = t; + bone_entity.modified(); + flecs::log::err("good bone %d", nc->bone_idx); + } else + flecs::log::err("bad bone %d", nc->bone_idx); #if 0 /* update transform on skeleton or node */ if (nc->skeleton && nc->bone_idx >= 0) @@ -1049,14 +1092,17 @@ static void ECS::_animation_update_transforms( pa->subpath, pa->value_accum, &valid); if (!valid) { /* error setting key - ERR_PRINT("Failed setting key at time " - + rtos(playback.current.pos) + " in - Animation '" + get_current_animation() - + "' at Node '" + get_path() + "', - Track '" + String(pa->owner->path) + - "'. Check if property exists or the - type of key is right for the - property"); + ERR_PRINT("Failed setting key + at time " + + rtos(playback.current.pos) + + " in Animation '" + + get_current_animation() + + "' at Node '" + get_path() + + "', Track '" + + String(pa->owner->path) + + "'. Check if property exists or + the type of key is right for + the property"); */ } } break; @@ -1087,7 +1133,7 @@ static void ECS::_set_process( { /* Nothing */ } -static void ECS::_animation_process( +static void ECS::_animation_process(flecs::entity_t entity, flecs::world &ecs, struct ECS::AnimationPlayerData *player, float p_time) { if (player->playback.current.from) { @@ -1096,10 +1142,11 @@ static void ECS::_animation_process( ->get_length()); player->end_reached = false; player->end_notify = false; - _animation_process2(player, p_time, player->playback.started); + _animation_process2( + entity, ecs, player, p_time, player->playback.started); if (player->playback.started) player->playback.started = false; - _animation_update_transforms(player); + _animation_update_transforms(entity, ecs, player); if (player->end_reached) { if (player->queued.size()) { String old = player->playback.assigned; @@ -1222,13 +1269,14 @@ void ECS::clear_caches(struct ECS::AnimationPlayerData *player) player->cache_update_bezier_size = 0; } -void ECS::advance(struct ECS::AnimationPlayerData *player, float p_time) +void ECS::advance(flecs::entity_t entity, flecs::world &ecs, + ECS::AnimationPlayerData *player, float p_time) { if (player->playback.current.from) { flecs::log::trace("length: %f", player->playback.current.from->animation ->get_length()); } - ECS::_animation_process(player, p_time); + ECS::_animation_process(entity, ecs, player, p_time); player->playback.current.from = nullptr; } diff --git a/src/modules/character/animation_system.h b/src/modules/character/animation_system.h index acdbb32..df9f7b6 100644 --- a/src/modules/character/animation_system.h +++ b/src/modules/character/animation_system.h @@ -28,7 +28,7 @@ struct TrackNodeCache { Node2D *node_2d; Skeleton *skeleton; #endif - int bone_idx; + flecs::entity_t bone_idx; // accumulated transforms Vector3 loc_accum; Quat rot_accum; @@ -234,8 +234,7 @@ struct BlendKey { } }; struct TrackNodeCacheKey { - uint32_t id; - int bone_idx; + flecs::entity_t id, bone_idx; inline bool operator<(const TrackNodeCacheKey &p_right) const { @@ -348,7 +347,8 @@ void seek_delta( struct AnimationPlayerData *player, float p_time, float p_delta); float get_current_animation_position(struct AnimationPlayerData *player); float get_current_animation_length(struct AnimationPlayerData *player); -void advance(struct AnimationPlayerData *player, float p_time); +void advance(flecs::entity_t entity, flecs::world &ecs, + AnimationPlayerData *player, float p_time); void set_root(struct AnimationPlayerData *player, const NodePath &p_root); NodePath get_root(struct AnimationPlayerData *player); void clear_caches(struct AnimationPlayerData *player); diff --git a/src/modules/character/character.cpp b/src/modules/character/character.cpp index 7a749b3..1092398 100644 --- a/src/modules/character/character.cpp +++ b/src/modules/character/character.cpp @@ -124,15 +124,14 @@ int Character::create_character(int id) } for (i = 0; i < scene_data[id].meshes.size(); i++) { // flecs::log::trace("creating slot -"); - flecs::entity entity = - ecs.entity(scene_data[id] - .meshes[i] - .slot_name.ascii() - .get_data()) - .child_of(root) - .emplace( - scene_data[id].meshes[i].mesh, - scene_data[id].meshes[i].skin); + ecs.entity(scene_data[id] + .meshes[i] + .slot_name.ascii() + .get_data()) + .child_of(root) + .emplace( + scene_data[id].meshes[i].mesh, + scene_data[id].meshes[i].skin); } // print_line("character created"); int xid = entities.size(); @@ -383,7 +382,8 @@ void Character::animation_system_init() .each([](flecs::entity e, ECS::AnimationPlayerData &player) { if (!player.playing) ECS::play(&player, "stand1-loop"); - ECS::advance(&player, + flecs::world w = e.world(); + ECS::advance(e.id(), w, &player, SceneTree::get_singleton() ->get_physics_process_time()); });