Force non-numeric ValueTrack use Discrete with Dominant

This commit is contained in:
Silc Lizard (Tokage) Renew 2024-02-22 20:35:04 +09:00
parent 16d61427ca
commit 8423574a24
3 changed files with 8 additions and 2 deletions

View File

@ -357,6 +357,7 @@
</constant>
<constant name="ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT" value="0" enum="AnimationCallbackModeDiscrete">
An [constant Animation.UPDATE_DISCRETE] track value takes precedence when blending [constant Animation.UPDATE_CONTINUOUS] or [constant Animation.UPDATE_CAPTURE] track values and [constant Animation.UPDATE_DISCRETE] track values. This is the default behavior for [AnimationPlayer].
[b]Note:[/b] If a value track has non-numeric type key values, it is internally converted to use [constant ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT] with [constant Animation.UPDATE_DISCRETE].
</constant>
<constant name="ANIMATION_CALLBACK_MODE_DISCRETE_RECESSIVE" value="1" enum="AnimationCallbackModeDiscrete">
An [constant Animation.UPDATE_CONTINUOUS] or [constant Animation.UPDATE_CAPTURE] track value takes precedence when blending the [constant Animation.UPDATE_CONTINUOUS] or [constant Animation.UPDATE_CAPTURE] track values and the [constant Animation.UPDATE_DISCRETE] track values.

View File

@ -693,6 +693,9 @@ bool AnimationMixer::_update_caches() {
track_value->init_value = anim->track_get_key_value(i, 0);
track_value->init_value.zero();
// 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);
@ -1414,7 +1417,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
bool is_value = ttype == Animation::TYPE_VALUE;
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 (!is_discrete || force_continuous) {
if (t->is_variant_interpolatable && (!is_discrete || force_continuous)) {
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 +1730,7 @@ void AnimationMixer::_blend_apply() {
case Animation::TYPE_VALUE: {
TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
if (callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT && t->use_discrete) {
if (!t->is_variant_interpolatable || (callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT && t->use_discrete)) {
break; // Don't overwrite the value set by UPDATE_DISCRETE.
}

View File

@ -224,6 +224,7 @@ protected:
Vector<StringName> subpath;
bool use_discrete = false;
bool is_using_angle = false;
bool is_variant_interpolatable = true;
Variant element_size;
TrackCacheValue(const TrackCacheValue &p_other) :
@ -233,6 +234,7 @@ protected:
subpath(p_other.subpath),
use_discrete(p_other.use_discrete),
is_using_angle(p_other.is_using_angle),
is_variant_interpolatable(p_other.is_variant_interpolatable),
element_size(p_other.element_size) {}
TrackCacheValue() { type = Animation::TYPE_VALUE; }