Constructor changes

This commit is contained in:
2023-09-20 23:55:36 +03:00
parent cd23364269
commit 44f2b9b47b
4 changed files with 363 additions and 30 deletions

View File

@@ -89,20 +89,22 @@ void ECS::play(struct ECS::AnimationPlayerData *player,
} }
c.current.from = &player->animation_set[name]; c.current.from = &player->animation_set[name];
flecs::log::trace("setting animation from %p", c.current.from);
if (c.assigned != name) { // reset if (c.assigned != name) { // reset
c.current.pos = p_from_end c.current.pos = p_from_end
? c.current.from->animation->get_length() ? c.current.from->get_animation()->get_length()
: 0; : 0;
} else { } else {
if (p_from_end && c.current.pos == 0) { if (p_from_end && c.current.pos == 0) {
// Animation reset BUT played backwards, set position // Animation reset BUT played backwards, set position
// to the end // to the end
c.current.pos = c.current.pos =
c.current.from->animation->get_length(); c.current.from->get_animation()->get_length();
} else if (!p_from_end && } else if (!p_from_end &&
c.current.pos == c.current.pos ==
c.current.from->animation->get_length()) { c.current.from->get_animation()
->get_length()) {
// Animation resumed but already ended, set position to // Animation resumed but already ended, set position to
// the beginning // the beginning
c.current.pos = 0; c.current.pos = 0;
@@ -133,18 +135,21 @@ void ECS::play(struct ECS::AnimationPlayerData *player,
if (next != StringName() && player->animation_set.has(next)) { if (next != StringName() && player->animation_set.has(next)) {
queue(player, 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, static void ECS::_ensure_node_caches(struct ECS::AnimationPlayerData *player,
flecs::entity_t entity, flecs::world &ecs, AnimationData *p_anim, flecs::entity_t entity, flecs::world &ecs, AnimationData *p_anim,
Node *p_root_override) Node *p_root_override)
{ {
// Already cached? // Already cached?
assert(p_anim->animation.is_valid()); assert(p_anim->get_animation().is_valid());
if (p_anim->node_cache_size == p_anim->animation->get_track_count()) { if (p_anim->node_cache_size ==
p_anim->get_animation()->get_track_count()) {
return; return;
} }
Animation *a = p_anim->animation.operator->(); const Animation *a = p_anim->get_animation().operator->();
p_anim->node_cache_size = a->get_track_count(); 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); _ensure_node_caches(player, entity, ecs, p_anim);
ERR_FAIL_COND(p_anim->node_cache_size != 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++) { for (int i = 0; i < a->get_track_count(); i++) {
// If an animation changes this animation (or it // 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 delta = p_delta * player->speed_scale * cd.speed_scale;
float next_pos = cd.pos + delta; float next_pos = cd.pos + delta;
if (cd.from->animation.is_null()) { if (cd.from->get_animation().is_null()) {
ERR_PRINT("bad animation"); ERR_PRINT("bad animation");
return; return;
} }
assert(cd.from->animation.is_valid()); assert(cd.from->get_animation().is_valid());
float len = cd.from->animation->get_length(); flecs::log::trace("%s(): %d animation %p", __func__, __LINE__,
bool loop = cd.from->animation->has_loop(); cd.from->get_animation().ptr());
float len = cd.from->get_animation()->get_length();
bool loop = cd.from->get_animation()->has_loop();
if (!loop) { if (!loop) {
if (next_pos < 0) if (next_pos < 0)
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; ECS::Playback &c = player->playback;
player->accum_pass++; player->accum_pass++;
if (c.current.from->animation.is_null()) { if (c.current.from->get_animation().is_null()) {
ERR_PRINT("bad animation2"); ERR_PRINT("bad animation2");
return; 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, _animation_process_data(entity, ecs, player, c.current, p_delta, 1.0f,
c.seeked && p_delta != 0, p_started); c.seeked && p_delta != 0, p_started);
if (p_delta != 0) if (p_delta != 0)
@@ -937,7 +946,7 @@ static void ECS::_animation_process2(flecs::entity_t entity, flecs::world &ecs,
for (List<Blend>::Element *E = c.blend.back(); E; E = prev) { for (List<Blend>::Element *E = c.blend.back(); E; E = prev) {
Blend &b = E->get(); Blend &b = E->get();
float blend = b.blend_left / b.blend_time; 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"); ERR_PRINT("bad animation3");
b.blend_left -= b.blend_left -=
Math::absf(player->speed_scale * p_delta); 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) if (b.blend_left < 0)
c.blend.erase(E); c.blend.erase(E);
} }
flecs::log::trace("%s(): %d animation %p", __func__, __LINE__,
c.current.from->get_animation().ptr());
} }
/* transforms are set here */ /* transforms are set here */
static void ECS::_animation_update_transforms(flecs::entity_t entity, 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<ECS::BonePose>(); bone_entity.modified<ECS::BonePose>();
} }
} }
flecs::log::trace("update bones %f %f %f\n", t.origin.x,
t.origin.y, t.origin.z);
} }
player->cache_update_size = 0; player->cache_update_size = 0;
#ifdef VALUE_TRACK_SUPPORT #ifdef VALUE_TRACK_SUPPORT
@@ -1014,16 +1027,16 @@ static void ECS::_animation_update_transforms(flecs::entity_t entity,
break; break;
} }
} }
#endif
player->cache_update_prop_size = 0; player->cache_update_prop_size = 0;
#endif
#ifdef BEZIER_TRACK_SUPPORT #ifdef BEZIER_TRACK_SUPPORT
for (i = 0; i < player->cache_update_bezier_size; i++) { for (i = 0; i < player->cache_update_bezier_size; i++) {
TrackNodeCache::BezierAnim *ba = TrackNodeCache::BezierAnim *ba =
player->cache_update_bezier[i]; player->cache_update_bezier[i];
ba->object->set_indexed(ba->bezier_property, ba->bezier_accum); ba->object->set_indexed(ba->bezier_property, ba->bezier_accum);
} }
#endif
player->cache_update_bezier_size = 0; player->cache_update_bezier_size = 0;
#endif
} }
static void ECS::_set_process( static void ECS::_set_process(
struct ECS::AnimationPlayerData *player, bool p_process, bool p_force) 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, static void ECS::_animation_process(flecs::entity_t entity, flecs::world &ecs,
struct ECS::AnimationPlayerData *player, float p_time) struct ECS::AnimationPlayerData *player, float p_time)
{ {
flecs::log::trace("animation_pocess: %f", p_time);
if (player->playback.current.from) { 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", flecs::log::trace("length: %f",
player->playback.current.from->animation player->playback.current.from->get_animation()
->get_length()); ->get_length());
player->end_reached = false; player->end_reached = false;
player->end_notify = 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; player->end_reached = false;
} }
flecs::log::trace("animation at end: %p",
player->playback.current.from->get_animation().ptr());
} else } else
_set_process(player, false); _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); ERR_FAIL_COND_V(p_animation.is_null(), ERR_INVALID_PARAMETER);
if (player->animation_set.has(p_name)) { if (player->animation_set.has(p_name)) {
player->animation_set[p_name].animation = p_animation; AnimationData ad(p_animation);
clear_caches(player); ad.name = p_name;
} else { player->animation_set[p_name] = ad;
AnimationData ad; // player->animation_set[p_name].animation =
ad.animation = p_animation; //p_animation;
clear_caches(player);
} else {
AnimationData ad(p_animation);
ad.name = p_name; ad.name = p_name;
player->animation_set[p_name] = ad; player->animation_set[p_name] = ad;
player->animation_set[p_name].animation = p_animation;
} }
return OK; return OK;
@@ -1129,15 +1150,27 @@ void ECS::clear_caches(struct ECS::AnimationPlayerData *player)
E; E = E->next()) E; E = E->next())
E->get().node_cache_size = 0; E->get().node_cache_size = 0;
player->cache_update_size = 0; player->cache_update_size = 0;
#if 0
player->cache_update_prop_size = 0; player->cache_update_prop_size = 0;
player->cache_update_bezier_size = 0; player->cache_update_bezier_size = 0;
#endif
} }
void ECS::advance(flecs::entity_t entity, flecs::world &ecs, void ECS::advance(flecs::entity_t entity, flecs::world &ecs,
ECS::AnimationPlayerData *player, float p_time) 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); 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) void ECS::stop(struct ECS::AnimationPlayerData *player, bool p_reset)
{ {

View File

@@ -186,14 +186,63 @@ struct BasicTrack : public Track {
struct AnimationData { struct AnimationData {
String name; String name;
StringName next; StringName next;
Ref<Animation> animation;
int node_cache_size; int node_cache_size;
struct TrackNodeCache *node_cache[128]; struct TrackNodeCache *node_cache[128];
AnimationData(Ref<Animation> anim) : AnimationData(Ref<Animation> anim) :
animation(anim), node_cache_size(0) animation(anim), node_cache_size(0)
{ {
assert(animation.is_valid());
} }
AnimationData() : animation(Ref<Animation>()), node_cache_size(0) {} AnimationData() :
animation(Ref<Animation>(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<Animation>(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<Animation> &get_animation() const
{
assert(animation.is_valid());
flecs::log::trace("animation ptr %p", animation.ptr());
return animation;
}
~AnimationData() { animation = Ref<Animation>(nullptr); }
private:
Ref<Animation> animation;
}; };
struct PlaybackData { struct PlaybackData {
AnimationData *from; AnimationData *from;
@@ -206,6 +255,32 @@ struct PlaybackData {
speed_scale = 1.0; speed_scale = 1.0;
from = nullptr; 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 { struct Blend {
PlaybackData data; PlaybackData data;
@@ -216,6 +291,29 @@ struct Blend {
blend_left = 0.0f; blend_left = 0.0f;
blend_time = 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 { struct Playback {
List<Blend> blend; List<Blend> blend;
@@ -223,6 +321,45 @@ struct Playback {
StringName assigned; StringName assigned;
bool seeked; bool seeked;
bool started; bool started;
Playback()
{
blend.clear();
seeked = false;
started = false;
flecs::log::trace(
"%s constructed normally %p", __func__, this);
}
Playback(const Playback &d)
{
blend = List<Blend>();
const List<Blend>::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 { struct BlendKey {
StringName from; StringName from;
@@ -252,10 +389,13 @@ struct AnimationPlayerData {
Map<TrackNodeCacheKey, TrackNodeCache> node_cache_map; Map<TrackNodeCacheKey, TrackNodeCache> node_cache_map;
TrackNodeCache *cache_update[NODE_CACHE_UPDATE_MAX]; TrackNodeCache *cache_update[NODE_CACHE_UPDATE_MAX];
int cache_update_size; int cache_update_size;
#if 0
TrackNodeCache::PropertyAnim *cache_update_prop[NODE_CACHE_UPDATE_MAX]; TrackNodeCache::PropertyAnim *cache_update_prop[NODE_CACHE_UPDATE_MAX];
int cache_update_prop_size; int cache_update_prop_size;
TrackNodeCache::BezierAnim *cache_update_bezier[NODE_CACHE_UPDATE_MAX]; TrackNodeCache::BezierAnim *cache_update_bezier[NODE_CACHE_UPDATE_MAX];
int cache_update_bezier_size; int cache_update_bezier_size;
#endif
Set<TrackNodeCache *> playing_caches; Set<TrackNodeCache *> playing_caches;
uint64_t accum_pass; uint64_t accum_pass;
float speed_scale; float speed_scale;
@@ -270,13 +410,158 @@ struct AnimationPlayerData {
String autoplay; String autoplay;
bool reset_on_save; bool reset_on_save;
AnimationProcessMode animation_process_mode; AnimationProcessMode animation_process_mode;
AnimationMethodCallMode method_call_mode;
bool processing; bool processing;
bool active; bool active;
#if 0 #if 0
NodePath root; NodePath root;
#endif #endif
bool playing; 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 */ /* public functions */
StringName find_animation( StringName find_animation(

View File

@@ -354,16 +354,33 @@ void Character::init_bone()
void Character::animation_system_init() void Character::animation_system_init()
{ {
ecs.component<ECS::AnimationPlayerData>().on_set( ecs.component<ECS::AnimationPlayerData>().on_set(
[](flecs::entity e, ECS::AnimationPlayerData &s) {}); [](flecs::entity e, ECS::AnimationPlayerData &s) {
flecs::log::trace("AnimationPlayerData is written to");
});
ecs.system<ECS::AnimationPlayerData>("UpdateAnimation") ecs.system<ECS::AnimationPlayerData>("UpdateAnimation")
.kind(flecs::OnUpdate) .kind(flecs::OnUpdate)
.each([](flecs::entity e, ECS::AnimationPlayerData &player) { .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) if (!player.playing)
ECS::play(&player, "male-mx-walk-loop"); ECS::play(&player, "male-mx-walk-loop");
flecs::world w = e.world(); flecs::world w = e.world();
ECS::advance(e.id(), w, &player, ECS::advance(e.id(), w, &player,
SceneTree::get_singleton() SceneTree::get_singleton()
->get_physics_process_time()); ->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() void Character::initialize()

View File

@@ -197,8 +197,6 @@ void Character::init_skeleton()
} }
} }
} }
// flecs::log::trace("transform should be
// ready");
e.add<ECS::SkeletonTransformReady>(); e.add<ECS::SkeletonTransformReady>();
assert(sk.skin_bone_indices_ptrs); assert(sk.skin_bone_indices_ptrs);
uint32_t bind_count = sk.skin->get_bind_count(); uint32_t bind_count = sk.skin->get_bind_count();