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.cpp82
1 files changed, 80 insertions, 2 deletions
diff --git a/scene/animation/animation_mixer.cpp b/scene/animation/animation_mixer.cpp
index e23fc56a23..bba3dc6d7d 100644
--- a/scene/animation/animation_mixer.cpp
+++ b/scene/animation/animation_mixer.cpp
@@ -563,7 +563,7 @@ void AnimationMixer::_clear_audio_streams() {
void AnimationMixer::_clear_playing_caches() {
for (const TrackCache *E : playing_caches) {
if (ObjectDB::get_instance(E->object_id)) {
- E->object->call(SNAME("stop"));
+ E->object->call(SNAME("stop"), true);
}
}
playing_caches.clear();
@@ -1708,7 +1708,12 @@ void AnimationMixer::_blend_apply() {
}
}
}
- t->object->set_indexed(t->subpath, Animation::cast_from_blendwise(t->value, t->init_value.get_type()));
+
+ // t->object isn't safe here, get instance from id (GH-85365).
+ Object *obj = ObjectDB::get_instance(t->object_id);
+ if (obj) {
+ obj->set_indexed(t->subpath, Animation::cast_from_blendwise(t->value, t->init_value.get_type()));
+ }
} break;
case Animation::TYPE_BEZIER: {
@@ -2138,3 +2143,76 @@ AnimationMixer::AnimationMixer() {
AnimationMixer::~AnimationMixer() {
}
+
+void AnimatedValuesBackup::set_data(const HashMap<NodePath, AnimationMixer::TrackCache *> p_data) {
+ clear_data();
+
+ for (const KeyValue<NodePath, AnimationMixer::TrackCache *> &E : p_data) {
+ AnimationMixer::TrackCache *track = get_cache_copy(E.value);
+ if (!track) {
+ continue; // Some types of tracks do not get a copy and must be ignored.
+ }
+
+ data.insert(E.key, track);
+ }
+}
+
+HashMap<NodePath, AnimationMixer::TrackCache *> AnimatedValuesBackup::get_data() const {
+ HashMap<NodePath, AnimationMixer::TrackCache *> ret;
+ for (const KeyValue<NodePath, AnimationMixer::TrackCache *> &E : data) {
+ AnimationMixer::TrackCache *track = get_cache_copy(E.value);
+ ERR_CONTINUE(!track); // Backup shouldn't contain tracks that cannot be copied, this is a mistake.
+
+ ret.insert(E.key, track);
+ }
+ return ret;
+}
+
+void AnimatedValuesBackup::clear_data() {
+ for (KeyValue<NodePath, AnimationMixer::TrackCache *> &K : data) {
+ memdelete(K.value);
+ }
+ data.clear();
+}
+
+AnimationMixer::TrackCache *AnimatedValuesBackup::get_cache_copy(AnimationMixer::TrackCache *p_cache) const {
+ switch (p_cache->type) {
+ case Animation::TYPE_VALUE: {
+ AnimationMixer::TrackCacheValue *src = static_cast<AnimationMixer::TrackCacheValue *>(p_cache);
+ AnimationMixer::TrackCacheValue *tc = memnew(AnimationMixer::TrackCacheValue(*src));
+ return tc;
+ }
+
+ case Animation::TYPE_POSITION_3D:
+ case Animation::TYPE_ROTATION_3D:
+ case Animation::TYPE_SCALE_3D: {
+ AnimationMixer::TrackCacheTransform *src = static_cast<AnimationMixer::TrackCacheTransform *>(p_cache);
+ AnimationMixer::TrackCacheTransform *tc = memnew(AnimationMixer::TrackCacheTransform(*src));
+ return tc;
+ }
+
+ case Animation::TYPE_BLEND_SHAPE: {
+ AnimationMixer::TrackCacheBlendShape *src = static_cast<AnimationMixer::TrackCacheBlendShape *>(p_cache);
+ AnimationMixer::TrackCacheBlendShape *tc = memnew(AnimationMixer::TrackCacheBlendShape(*src));
+ return tc;
+ }
+
+ case Animation::TYPE_BEZIER: {
+ AnimationMixer::TrackCacheBezier *src = static_cast<AnimationMixer::TrackCacheBezier *>(p_cache);
+ AnimationMixer::TrackCacheBezier *tc = memnew(AnimationMixer::TrackCacheBezier(*src));
+ return tc;
+ }
+
+ case Animation::TYPE_AUDIO: {
+ AnimationMixer::TrackCacheAudio *src = static_cast<AnimationMixer::TrackCacheAudio *>(p_cache);
+ AnimationMixer::TrackCacheAudio *tc = memnew(AnimationMixer::TrackCacheAudio(*src));
+ return tc;
+ }
+
+ case Animation::TYPE_METHOD:
+ case Animation::TYPE_ANIMATION: {
+ // Nothing to do here.
+ } break;
+ }
+ return nullptr;
+}