|
|
|
@@ -160,7 +160,6 @@ void AnimationMixer::_animation_set_cache_update() {
|
|
|
|
|
for (const AnimationLibraryData &lib : animation_libraries) {
|
|
|
|
|
for (const KeyValue<StringName, Ref<Animation>> &K : lib.library->animations) {
|
|
|
|
|
StringName key = lib.name == StringName() ? K.key : StringName(String(lib.name) + "/" + String(K.key));
|
|
|
|
|
|
|
|
|
|
AnimationData *ad = animation_set.getptr(key);
|
|
|
|
|
|
|
|
|
|
if (!ad) {
|
|
|
|
@@ -588,7 +587,7 @@ void AnimationMixer::_clear_caches() {
|
|
|
|
|
_init_root_motion_cache();
|
|
|
|
|
_clear_audio_streams();
|
|
|
|
|
_clear_playing_caches();
|
|
|
|
|
for (KeyValue<Animation::TypeHash, TrackCache *> &K : track_cache) {
|
|
|
|
|
for (KeyValue<Animation::TrackCacheID, TrackCache *> &K : track_cache) {
|
|
|
|
|
memdelete(K.value);
|
|
|
|
|
}
|
|
|
|
|
track_cache.clear();
|
|
|
|
@@ -640,7 +639,7 @@ void AnimationMixer::_create_track_num_to_track_cache_for_animation(const Ref<An
|
|
|
|
|
|
|
|
|
|
track_num_to_track_cache.resize(tracks.size());
|
|
|
|
|
for (uint32_t i = 0; i < tracks.size(); i++) {
|
|
|
|
|
TrackCache **track_ptr = track_cache.getptr(tracks[i]->thash);
|
|
|
|
|
TrackCache **track_ptr = track_cache.getptr(tracks[i]->get_unique_id());
|
|
|
|
|
if (track_ptr == nullptr) {
|
|
|
|
|
track_num_to_track_cache[i] = nullptr;
|
|
|
|
|
} else {
|
|
|
|
@@ -699,12 +698,12 @@ bool AnimationMixer::_update_caches() {
|
|
|
|
|
NodePath path = anim->track_get_path(i);
|
|
|
|
|
(void)path.hash(); // Make sure the cache is valid for faster comparison.
|
|
|
|
|
|
|
|
|
|
Animation::TypeHash thash = anim->track_get_type_hash(i);
|
|
|
|
|
const Animation::TrackCacheID &track_unique_id = anim->track_get_unique_id(i);
|
|
|
|
|
Animation::TrackType track_src_type = anim->track_get_type(i);
|
|
|
|
|
Animation::TrackType track_cache_type = Animation::get_cache_type(track_src_type);
|
|
|
|
|
|
|
|
|
|
TrackCache *track = nullptr;
|
|
|
|
|
if (TrackCache **p = track_cache.getptr(thash)) {
|
|
|
|
|
if (TrackCache **p = track_cache.getptr(track_unique_id)) {
|
|
|
|
|
track = *p;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -712,7 +711,7 @@ bool AnimationMixer::_update_caches() {
|
|
|
|
|
if (track && (track->type != track_cache_type || ObjectDB::get_instance(track->object_id) == nullptr)) {
|
|
|
|
|
playing_caches.erase(track);
|
|
|
|
|
memdelete(track);
|
|
|
|
|
track_cache.erase(thash);
|
|
|
|
|
track_cache.erase(track_unique_id);
|
|
|
|
|
track = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -923,7 +922,7 @@ bool AnimationMixer::_update_caches() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
track->path = path;
|
|
|
|
|
track_cache[thash] = track;
|
|
|
|
|
track_cache[track_unique_id] = track;
|
|
|
|
|
} else if (track_cache_type == Animation::TYPE_POSITION_3D) {
|
|
|
|
|
TrackCacheTransform *track_xform = static_cast<TrackCacheTransform *>(track);
|
|
|
|
|
if (track->setup_pass != setup_pass) {
|
|
|
|
@@ -963,28 +962,28 @@ bool AnimationMixer::_update_caches() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LocalVector<Animation::TypeHash> to_delete;
|
|
|
|
|
LocalVector<Animation::TrackCacheID> to_delete;
|
|
|
|
|
|
|
|
|
|
for (const KeyValue<Animation::TypeHash, TrackCache *> &K : track_cache) {
|
|
|
|
|
for (const KeyValue<Animation::TrackCacheID, TrackCache *> &K : track_cache) {
|
|
|
|
|
if (K.value->setup_pass != setup_pass) {
|
|
|
|
|
to_delete.push_back(K.key);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const Animation::TypeHash &thash : to_delete) {
|
|
|
|
|
memdelete(track_cache[thash]);
|
|
|
|
|
track_cache.erase(thash);
|
|
|
|
|
for (const Animation::TrackCacheID &unique_id : to_delete) {
|
|
|
|
|
memdelete(track_cache[unique_id]);
|
|
|
|
|
track_cache.erase(unique_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
track_map.clear();
|
|
|
|
|
|
|
|
|
|
int idx = 0;
|
|
|
|
|
for (const KeyValue<Animation::TypeHash, TrackCache *> &K : track_cache) {
|
|
|
|
|
for (const KeyValue<Animation::TrackCacheID, TrackCache *> &K : track_cache) {
|
|
|
|
|
track_map[K.value->path] = idx;
|
|
|
|
|
idx++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (KeyValue<Animation::TypeHash, TrackCache *> &K : track_cache) {
|
|
|
|
|
for (KeyValue<Animation::TrackCacheID, TrackCache *> &K : track_cache) {
|
|
|
|
|
K.value->blend_idx = track_map[K.value->path];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -1066,7 +1065,7 @@ void AnimationMixer::_blend_init() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Init all value/transform/blend/bezier tracks that track_cache has.
|
|
|
|
|
for (const KeyValue<Animation::TypeHash, TrackCache *> &K : track_cache) {
|
|
|
|
|
for (const KeyValue<Animation::TrackCacheID, TrackCache *> &K : track_cache) {
|
|
|
|
|
TrackCache *track = K.value;
|
|
|
|
|
|
|
|
|
|
track->total_weight = 0.0;
|
|
|
|
@@ -1171,7 +1170,7 @@ void AnimationMixer::_blend_calc_total_weight() {
|
|
|
|
|
uint64_t pass_id = ++animation_instance_weight_pass_counter;
|
|
|
|
|
// Handle wrap (slower but rare).
|
|
|
|
|
if (unlikely(pass_id == 0)) {
|
|
|
|
|
for (KeyValue<Animation::TypeHash, TrackCache *> &kv : track_cache) {
|
|
|
|
|
for (KeyValue<Animation::TrackCacheID, TrackCache *> &kv : track_cache) {
|
|
|
|
|
if (kv.value) {
|
|
|
|
|
kv.value->animation_instance_weight_applied_at = 0;
|
|
|
|
|
}
|
|
|
|
@@ -1897,7 +1896,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
|
|
|
|
|
|
|
|
|
|
void AnimationMixer::_blend_apply() {
|
|
|
|
|
// Finally, set the tracks.
|
|
|
|
|
for (const KeyValue<Animation::TypeHash, TrackCache *> &K : track_cache) {
|
|
|
|
|
for (const KeyValue<Animation::TrackCacheID, TrackCache *> &K : track_cache) {
|
|
|
|
|
TrackCache *track = K.value;
|
|
|
|
|
bool is_zero_amount = Math::is_zero_approx(track->total_weight);
|
|
|
|
|
if (!deterministic && is_zero_amount) {
|
|
|
|
@@ -2170,7 +2169,7 @@ bool AnimationMixer::can_apply_reset() const {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AnimationMixer::_build_backup_track_cache() {
|
|
|
|
|
for (const KeyValue<Animation::TypeHash, TrackCache *> &K : track_cache) {
|
|
|
|
|
for (const KeyValue<Animation::TrackCacheID, TrackCache *> &K : track_cache) {
|
|
|
|
|
TrackCache *track = K.value;
|
|
|
|
|
track->total_weight = 1.0;
|
|
|
|
|
switch (track->type) {
|
|
|
|
@@ -2267,7 +2266,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::make_backup() {
|
|
|
|
|
make_animation_instance(SceneStringName(RESET), pi);
|
|
|
|
|
_build_backup_track_cache();
|
|
|
|
|
|
|
|
|
|
backup->set_data(AHashMap<Animation::TypeHash, TrackCache *, HashHasher>(track_cache));
|
|
|
|
|
backup->set_data(AHashMap<Animation::TrackCacheID, TrackCache *, HashHasher>(track_cache));
|
|
|
|
|
clear_animation_instances();
|
|
|
|
|
|
|
|
|
|
return backup;
|
|
|
|
@@ -2299,7 +2298,7 @@ void AnimationMixer::restore(const Ref<AnimatedValuesBackup> &p_backup) {
|
|
|
|
|
ERR_FAIL_COND(p_backup.is_null());
|
|
|
|
|
track_cache = p_backup->get_data();
|
|
|
|
|
_blend_apply();
|
|
|
|
|
track_cache = AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher>();
|
|
|
|
|
track_cache = AHashMap<Animation::TrackCacheID, AnimationMixer::TrackCache *, HashHasher>();
|
|
|
|
|
cache_valid = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -2357,7 +2356,7 @@ void AnimationMixer::capture(const StringName &p_name, double p_duration, Tween:
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (reference_animation->track_get_type(i) == Animation::TYPE_VALUE && reference_animation->value_track_get_update_mode(i) == Animation::UPDATE_CAPTURE) {
|
|
|
|
|
TrackCacheValue *t = static_cast<TrackCacheValue *>(track_cache[reference_animation->track_get_type_hash(i)]);
|
|
|
|
|
TrackCacheValue *t = static_cast<TrackCacheValue *>(track_cache[reference_animation->track_get_unique_id(i)]);
|
|
|
|
|
Object *t_obj = ObjectDB::get_instance(t->object_id);
|
|
|
|
|
if (t_obj) {
|
|
|
|
|
Variant value = t_obj->get_indexed(t->subpath);
|
|
|
|
@@ -2541,10 +2540,10 @@ AnimationMixer::AnimationMixer() {
|
|
|
|
|
AnimationMixer::~AnimationMixer() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AnimatedValuesBackup::set_data(const AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> &p_data) {
|
|
|
|
|
void AnimatedValuesBackup::set_data(const AHashMap<Animation::TrackCacheID, AnimationMixer::TrackCache *, HashHasher> &p_data) {
|
|
|
|
|
clear_data();
|
|
|
|
|
|
|
|
|
|
for (const KeyValue<Animation::TypeHash, AnimationMixer::TrackCache *> &E : p_data) {
|
|
|
|
|
for (const KeyValue<Animation::TrackCacheID, 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.
|
|
|
|
@@ -2554,9 +2553,9 @@ void AnimatedValuesBackup::set_data(const AHashMap<Animation::TypeHash, Animatio
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> AnimatedValuesBackup::get_data() const {
|
|
|
|
|
AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> ret;
|
|
|
|
|
for (const KeyValue<Animation::TypeHash, AnimationMixer::TrackCache *> &E : data) {
|
|
|
|
|
AHashMap<Animation::TrackCacheID, AnimationMixer::TrackCache *, HashHasher> AnimatedValuesBackup::get_data() const {
|
|
|
|
|
AHashMap<Animation::TrackCacheID, AnimationMixer::TrackCache *, HashHasher> ret;
|
|
|
|
|
for (const KeyValue<Animation::TrackCacheID, 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.
|
|
|
|
|
|
|
|
|
@@ -2566,7 +2565,7 @@ AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> Animated
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AnimatedValuesBackup::clear_data() {
|
|
|
|
|
for (KeyValue<Animation::TypeHash, AnimationMixer::TrackCache *> &K : data) {
|
|
|
|
|
for (KeyValue<Animation::TrackCacheID, AnimationMixer::TrackCache *> &K : data) {
|
|
|
|
|
memdelete(K.value);
|
|
|
|
|
}
|
|
|
|
|
data.clear();
|
|
|
|
|