summaryrefslogtreecommitdiffstats
path: root/scene/animation/animation_mixer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/animation/animation_mixer.cpp')
-rw-r--r--scene/animation/animation_mixer.cpp53
1 files changed, 34 insertions, 19 deletions
diff --git a/scene/animation/animation_mixer.cpp b/scene/animation/animation_mixer.cpp
index d22b58346f..e600de6b8b 100644
--- a/scene/animation/animation_mixer.cpp
+++ b/scene/animation/animation_mixer.cpp
@@ -35,7 +35,6 @@
#include "core/config/project_settings.h"
#include "scene/animation/animation_player.h"
#include "scene/resources/animation.h"
-#include "scene/scene_string_names.h"
#include "servers/audio/audio_stream.h"
#ifndef _3D_DISABLED
@@ -301,7 +300,7 @@ Error AnimationMixer::add_animation_library(const StringName &p_name, const Ref<
ald.library->connect(SNAME("animation_added"), callable_mp(this, &AnimationMixer::_animation_added).bind(p_name));
ald.library->connect(SNAME("animation_removed"), callable_mp(this, &AnimationMixer::_animation_removed).bind(p_name));
ald.library->connect(SNAME("animation_renamed"), callable_mp(this, &AnimationMixer::_animation_renamed).bind(p_name));
- ald.library->connect(SNAME("animation_changed"), callable_mp(this, &AnimationMixer::_animation_changed));
+ ald.library->connect(SceneStringName(animation_changed), callable_mp(this, &AnimationMixer::_animation_changed));
_animation_set_cache_update();
@@ -325,7 +324,7 @@ void AnimationMixer::remove_animation_library(const StringName &p_name) {
animation_libraries[at_pos].library->disconnect(SNAME("animation_added"), callable_mp(this, &AnimationMixer::_animation_added));
animation_libraries[at_pos].library->disconnect(SNAME("animation_removed"), callable_mp(this, &AnimationMixer::_animation_removed));
animation_libraries[at_pos].library->disconnect(SNAME("animation_renamed"), callable_mp(this, &AnimationMixer::_animation_renamed));
- animation_libraries[at_pos].library->disconnect(SNAME("animation_changed"), callable_mp(this, &AnimationMixer::_animation_changed));
+ animation_libraries[at_pos].library->disconnect(SceneStringName(animation_changed), callable_mp(this, &AnimationMixer::_animation_changed));
animation_libraries.remove_at(at_pos);
_animation_set_cache_update();
@@ -502,6 +501,7 @@ AnimationMixer::AnimationCallbackModeMethod AnimationMixer::get_callback_mode_me
void AnimationMixer::set_callback_mode_discrete(AnimationCallbackModeDiscrete p_mode) {
callback_mode_discrete = p_mode;
+ _clear_caches();
emit_signal(SNAME("mixer_updated"));
}
@@ -628,9 +628,9 @@ bool AnimationMixer::_update_caches() {
#endif
Ref<Animation> reset_anim;
- bool has_reset_anim = has_animation(SceneStringNames::get_singleton()->RESET);
+ bool has_reset_anim = has_animation(SceneStringName(RESET));
if (has_reset_anim) {
- reset_anim = get_animation(SceneStringNames::get_singleton()->RESET);
+ reset_anim = get_animation(SceneStringName(RESET));
}
for (const StringName &E : sname) {
Ref<Animation> anim = get_animation(E);
@@ -689,7 +689,7 @@ 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;
+ track_value->is_init = false;
// Can't interpolate them, need to convert.
track_value->is_variant_interpolatable = Animation::is_variant_interpolatable(track_value->init_value);
@@ -699,7 +699,6 @@ bool AnimationMixer::_update_caches() {
int rt = reset_anim->find_track(path, track_src_type);
if (rt >= 0) {
if (track_src_type == Animation::TYPE_VALUE) {
- 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 = reset_anim->track_get_key_value(rt, 0);
}
@@ -1007,7 +1006,7 @@ void AnimationMixer::_blend_init() {
TrackCacheValue *t = static_cast<TrackCacheValue *>(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_continuous = false;
t->use_discrete = false;
} break;
case Animation::TYPE_AUDIO: {
@@ -1463,12 +1462,12 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
t->value = Animation::blend_variant(t->value, value, blend);
}
} else {
- t->use_discrete = true;
if (seeked) {
int idx = a->track_find_key(i, time, is_external_seeking ? Animation::FIND_MODE_NEAREST : Animation::FIND_MODE_EXACT, true);
if (idx < 0) {
continue;
}
+ t->use_discrete = true;
Variant value = a->track_get_key_value(i, idx);
value = post_process_key_value(a, i, value, t->object_id);
Object *t_obj = ObjectDB::get_instance(t->object_id);
@@ -1479,6 +1478,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
List<int> indices;
a->track_get_key_indices_in_range(i, time, delta, &indices, looped_flag);
for (int &F : indices) {
+ t->use_discrete = true;
Variant value = a->track_get_key_value(i, F);
value = post_process_key_value(a, i, value, t->object_id);
Object *t_obj = ObjectDB::get_instance(t->object_id);
@@ -1683,7 +1683,8 @@ void AnimationMixer::_blend_apply() {
// Finally, set the tracks.
for (const KeyValue<Animation::TypeHash, TrackCache *> &K : track_cache) {
TrackCache *track = K.value;
- if (!deterministic && Math::is_zero_approx(track->total_weight)) {
+ bool is_zero_amount = Math::is_zero_approx(track->total_weight);
+ if (!deterministic && is_zero_amount) {
continue;
}
switch (track->type) {
@@ -1743,10 +1744,24 @@ void AnimationMixer::_blend_apply() {
case Animation::TYPE_VALUE: {
TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
- if (!t->is_variant_interpolatable || !t->use_continuous || (callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT && t->use_discrete)) {
+ if (t->use_discrete && !t->use_continuous) {
+ t->is_init = true; // If only disctere value is applied, no more RESET.
+ }
+
+ if ((t->is_init && (is_zero_amount || !t->use_continuous)) ||
+ (callback_mode_discrete != ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS &&
+ !is_zero_amount &&
+ callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT &&
+ t->use_discrete)) {
break; // Don't overwrite the value set by UPDATE_DISCRETE.
}
+ if (callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS) {
+ t->is_init = false; // Always update in Force Continuous.
+ } else {
+ t->is_init = !t->use_continuous; // If there is no Continuous in non-Force Continuous type, it means RESET.
+ }
+
// Trim unused elements if init array/string is not blended.
if (t->value.is_array()) {
int actual_blended_size = (int)Math::round(Math::abs(t->element_size.operator real_t()));
@@ -1926,7 +1941,7 @@ bool AnimationMixer::is_reset_on_save_enabled() const {
}
bool AnimationMixer::can_apply_reset() const {
- return has_animation(SceneStringNames::get_singleton()->RESET);
+ return has_animation(SceneStringName(RESET));
}
void AnimationMixer::_build_backup_track_cache() {
@@ -2013,7 +2028,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::make_backup() {
Ref<AnimatedValuesBackup> backup;
backup.instantiate();
- Ref<Animation> reset_anim = animation_set[SceneStringNames::get_singleton()->RESET].animation;
+ Ref<Animation> reset_anim = animation_set[SceneStringName(RESET)].animation;
ERR_FAIL_COND_V(reset_anim.is_null(), Ref<AnimatedValuesBackup>());
_blend_init();
@@ -2022,7 +2037,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::make_backup() {
pi.delta = 0;
pi.seeked = true;
pi.weight = 1.0;
- make_animation_instance(SceneStringNames::get_singleton()->RESET, pi);
+ make_animation_instance(SceneStringName(RESET), pi);
_build_backup_track_cache();
backup->set_data(track_cache);
@@ -2034,7 +2049,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::make_backup() {
void AnimationMixer::reset() {
ERR_FAIL_COND(!can_apply_reset());
- Ref<Animation> reset_anim = animation_set[SceneStringNames::get_singleton()->RESET].animation;
+ Ref<Animation> reset_anim = animation_set[SceneStringName(RESET)].animation;
ERR_FAIL_COND(reset_anim.is_null());
Node *root_node_object = get_node_or_null(root_node);
@@ -2044,11 +2059,11 @@ void AnimationMixer::reset() {
root_node_object->add_child(aux_player);
Ref<AnimationLibrary> al;
al.instantiate();
- al->add_animation(SceneStringNames::get_singleton()->RESET, reset_anim);
+ al->add_animation(SceneStringName(RESET), reset_anim);
aux_player->set_reset_on_save_enabled(false);
aux_player->set_root_node(aux_player->get_path_to(root_node_object));
aux_player->add_animation_library("", al);
- aux_player->set_assigned_animation(SceneStringNames::get_singleton()->RESET);
+ aux_player->set_assigned_animation(SceneStringName(RESET));
aux_player->seek(0.0f, true);
aux_player->queue_free();
}
@@ -2068,7 +2083,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::apply_reset(bool p_user_initiated) {
}
ERR_FAIL_COND_V(!can_apply_reset(), Ref<AnimatedValuesBackup>());
- Ref<Animation> reset_anim = animation_set[SceneStringNames::get_singleton()->RESET].animation;
+ Ref<Animation> reset_anim = animation_set[SceneStringName(RESET)].animation;
ERR_FAIL_COND_V(reset_anim.is_null(), Ref<AnimatedValuesBackup>());
Ref<AnimatedValuesBackup> backup_current = make_backup();
@@ -2286,7 +2301,7 @@ void AnimationMixer::_bind_methods() {
}
AnimationMixer::AnimationMixer() {
- root_node = SceneStringNames::get_singleton()->path_pp;
+ root_node = SceneStringName(path_pp);
}
AnimationMixer::~AnimationMixer() {