From 21082a68348f2fedecfafd5e1827fcd5670cca92 Mon Sep 17 00:00:00 2001 From: "Silc Lizard (Tokage) Renew" <61938263+TokageItLab@users.noreply.github.com> Date: Tue, 12 Mar 2024 01:03:26 +0900 Subject: [PATCH] Make AnimationMixer consider Discrete for RESET track --- scene/animation/animation_mixer.cpp | 14 +++++++++++--- scene/animation/animation_mixer.h | 7 +++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/scene/animation/animation_mixer.cpp b/scene/animation/animation_mixer.cpp index 757ac68e461..01e1de8f23c 100644 --- a/scene/animation/animation_mixer.cpp +++ b/scene/animation/animation_mixer.cpp @@ -689,14 +689,19 @@ bool AnimationMixer::_update_caches() { track_value->init_value = anim->track_get_key_value(i, 0); track_value->init_value.zero(); + track_value->init_use_continuous = callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS; + // Can't interpolate them, need to convert. track_value->is_variant_interpolatable = Animation::is_variant_interpolatable(track_value->init_value); // If there is a Reset Animation, it takes precedence by overwriting. if (has_reset_anim) { int rt = reset_anim->find_track(path, track_src_type); - if (rt >= 0 && reset_anim->track_get_key_count(rt) > 0) { - track_value->init_value = track_src_type == Animation::TYPE_VALUE ? reset_anim->track_get_key_value(rt, 0) : (reset_anim->track_get_key_value(rt, 0).operator Array())[0]; + if (rt >= 0) { + track_value->init_use_continuous = track_value->init_use_continuous || (reset_anim->value_track_get_update_mode(rt) != Animation::UPDATE_DISCRETE); // Take precedence Force Continuous. + if (reset_anim->track_get_key_count(rt) > 0) { + track_value->init_value = track_src_type == Animation::TYPE_VALUE ? reset_anim->track_get_key_value(rt, 0) : (reset_anim->track_get_key_value(rt, 0).operator Array())[0]; + } } } @@ -996,6 +1001,7 @@ void AnimationMixer::_blend_init() { TrackCacheValue *t = static_cast(track); t->value = Animation::cast_to_blendwise(t->init_value); t->element_size = t->init_value.is_string() ? (real_t)(t->init_value.operator String()).length() : 0; + t->use_continuous = t->init_use_continuous; t->use_discrete = false; } break; case Animation::TYPE_AUDIO: { @@ -1415,6 +1421,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) { bool is_discrete = is_value && a->value_track_get_update_mode(i) == Animation::UPDATE_DISCRETE; bool force_continuous = callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS; if (t->is_variant_interpolatable && (!is_discrete || force_continuous)) { + t->use_continuous = true; Variant value = is_value ? a->value_track_interpolate(i, time, is_discrete && force_continuous ? backward : false) : Variant(a->bezier_track_interpolate(i, time)); value = post_process_key_value(a, i, value, t->object_id); if (value == Variant()) { @@ -1727,7 +1734,7 @@ void AnimationMixer::_blend_apply() { case Animation::TYPE_VALUE: { TrackCacheValue *t = static_cast(track); - if (!t->is_variant_interpolatable || (callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT && t->use_discrete)) { + if (!t->is_variant_interpolatable || !t->use_continuous || (callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT && t->use_discrete)) { break; // Don't overwrite the value set by UPDATE_DISCRETE. } @@ -1969,6 +1976,7 @@ void AnimationMixer::_build_backup_track_cache() { if (t_obj) { t->value = Animation::cast_to_blendwise(t_obj->get_indexed(t->subpath)); } + t->use_continuous = true; t->use_discrete = false; if (t->init_value.is_array()) { t->element_size = MAX(t->element_size.operator int(), (t->value.operator Array()).size()); diff --git a/scene/animation/animation_mixer.h b/scene/animation/animation_mixer.h index ed291bfe63d..b7898cffc91 100644 --- a/scene/animation/animation_mixer.h +++ b/scene/animation/animation_mixer.h @@ -222,9 +222,14 @@ protected: Variant init_value; Variant value; Vector subpath; + + // TODO: There are many boolean, can be packed into one integer. + bool init_use_continuous = false; + bool use_continuous = false; bool use_discrete = false; bool is_using_angle = false; bool is_variant_interpolatable = true; + Variant element_size; TrackCacheValue(const TrackCacheValue &p_other) : @@ -232,6 +237,8 @@ protected: init_value(p_other.init_value), value(p_other.value), subpath(p_other.subpath), + init_use_continuous(p_other.init_use_continuous), + use_continuous(p_other.use_continuous), use_discrete(p_other.use_discrete), is_using_angle(p_other.is_using_angle), is_variant_interpolatable(p_other.is_variant_interpolatable),