diff options
Diffstat (limited to 'scene/animation/animation_mixer.cpp')
-rw-r--r-- | scene/animation/animation_mixer.cpp | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/scene/animation/animation_mixer.cpp b/scene/animation/animation_mixer.cpp index eb8bc8c382..0fa6810d23 100644 --- a/scene/animation/animation_mixer.cpp +++ b/scene/animation/animation_mixer.cpp @@ -563,6 +563,7 @@ void AnimationMixer::_clear_caches() { memdelete(K.value); } track_cache.clear(); + animation_track_num_to_track_cashe.clear(); cache_valid = false; capture_cache.clear(); @@ -922,6 +923,27 @@ bool AnimationMixer::_update_caches() { idx++; } + for (KeyValue<Animation::TypeHash, TrackCache *> &K : track_cache) { + K.value->blend_idx = track_map[K.value->path]; + } + + animation_track_num_to_track_cashe.clear(); + LocalVector<TrackCache *> track_num_to_track_cashe; + for (const StringName &E : sname_list) { + Ref<Animation> anim = get_animation(E); + const Vector<Animation::Track *> tracks = anim->get_tracks(); + track_num_to_track_cashe.resize(tracks.size()); + for (int i = 0; i < tracks.size(); i++) { + TrackCache **track_ptr = track_cache.getptr(tracks[i]->thash); + if (track_ptr == nullptr) { + track_num_to_track_cashe[i] = nullptr; + } else { + track_num_to_track_cashe[i] = *track_ptr; + } + } + animation_track_num_to_track_cashe.insert(anim, track_num_to_track_cashe); + } + track_count = idx; cache_valid = true; @@ -946,7 +968,7 @@ void AnimationMixer::_process_animation(double p_delta, bool p_update_only) { clear_animation_instances(); } -Variant AnimationMixer::_post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, ObjectID p_object_id, int p_object_sub_idx) { +Variant AnimationMixer::_post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant &p_value, ObjectID p_object_id, int p_object_sub_idx) { #ifndef _3D_DISABLED switch (p_anim->track_get_type(p_track)) { case Animation::TYPE_POSITION_3D: { @@ -1033,7 +1055,7 @@ void AnimationMixer::_blend_init() { } } -bool AnimationMixer::_blend_pre_process(double p_delta, int p_track_count, const HashMap<NodePath, int> &p_track_map) { +bool AnimationMixer::_blend_pre_process(double p_delta, int p_track_count, const AHashMap<NodePath, int> &p_track_map) { return true; } @@ -1084,26 +1106,30 @@ void AnimationMixer::_blend_calc_total_weight() { real_t weight = ai.playback_info.weight; const real_t *track_weights_ptr = ai.playback_info.track_weights.ptr(); int track_weights_count = ai.playback_info.track_weights.size(); - static LocalVector<Animation::TypeHash> processed_hashes; + ERR_CONTINUE_EDMSG(!animation_track_num_to_track_cashe.has(a), "No animation in cache."); + LocalVector<TrackCache *> &track_num_to_track_cashe = animation_track_num_to_track_cashe[a]; + thread_local HashSet<Animation::TypeHash, HashHasher> processed_hashes; processed_hashes.clear(); const Vector<Animation::Track *> tracks = a->get_tracks(); - for (const Animation::Track *animation_track : tracks) { + Animation::Track *const *tracks_ptr = tracks.ptr(); + int count = tracks.size(); + for (int i = 0; i < count; i++) { + Animation::Track *animation_track = tracks_ptr[i]; if (!animation_track->enabled) { continue; } Animation::TypeHash thash = animation_track->thash; - TrackCache **track_ptr = track_cache.getptr(thash); - if (track_ptr == nullptr || processed_hashes.has(thash)) { + TrackCache *track = track_num_to_track_cashe[i]; + if (track == nullptr || processed_hashes.has(thash)) { // No path, but avoid error spamming. // Or, there is the case different track type with same path; These can be distinguished by hash. So don't add the weight doubly. continue; } - TrackCache *track = *track_ptr; - int blend_idx = track_map[track->path]; + int blend_idx = track->blend_idx; ERR_CONTINUE(blend_idx < 0 || blend_idx >= track_count); real_t blend = blend_idx < track_weights_count ? track_weights_ptr[blend_idx] * weight : weight; track->total_weight += blend; - processed_hashes.push_back(thash); + processed_hashes.insert(thash); } } } @@ -1130,6 +1156,8 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) { #ifndef _3D_DISABLED bool calc_root = !seeked || is_external_seeking; #endif // _3D_DISABLED + ERR_CONTINUE_EDMSG(!animation_track_num_to_track_cashe.has(a), "No animation in cache."); + LocalVector<TrackCache *> &track_num_to_track_cashe = animation_track_num_to_track_cashe[a]; const Vector<Animation::Track *> tracks = a->get_tracks(); Animation::Track *const *tracks_ptr = tracks.ptr(); real_t a_length = a->get_length(); @@ -1139,15 +1167,11 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) { if (!animation_track->enabled) { continue; } - Animation::TypeHash thash = animation_track->thash; - TrackCache **track_ptr = track_cache.getptr(thash); - if (track_ptr == nullptr) { + TrackCache *track = track_num_to_track_cashe[i]; + if (track == nullptr) { continue; // No path, but avoid error spamming. } - TrackCache *track = *track_ptr; - int *blend_idx_ptr = track_map.getptr(track->path); - ERR_CONTINUE(blend_idx_ptr == nullptr); - int blend_idx = *blend_idx_ptr; + int blend_idx = track->blend_idx; ERR_CONTINUE(blend_idx < 0 || blend_idx >= track_count); real_t blend = blend_idx < track_weights_count ? track_weights_ptr[blend_idx] * weight : weight; if (!deterministic) { @@ -1581,7 +1605,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) { track_info.loop = a->get_loop_mode() != Animation::LOOP_NONE; track_info.backward = backward; track_info.use_blend = a->audio_track_is_use_blend(i); - HashMap<int, PlayingAudioStreamInfo> &map = track_info.stream_info; + AHashMap<int, PlayingAudioStreamInfo> &map = track_info.stream_info; // Main process to fire key is started from here. if (p_update_only) { @@ -1850,7 +1874,7 @@ void AnimationMixer::_blend_apply() { PlayingAudioTrackInfo &track_info = L.value; float db = Math::linear_to_db(track_info.use_blend ? track_info.volume : 1.0); LocalVector<int> erase_streams; - HashMap<int, PlayingAudioStreamInfo> &map = track_info.stream_info; + AHashMap<int, PlayingAudioStreamInfo> &map = track_info.stream_info; for (const KeyValue<int, PlayingAudioStreamInfo> &M : map) { PlayingAudioStreamInfo pasi = M.value; @@ -2134,7 +2158,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 = HashMap<Animation::TypeHash, AnimationMixer::TrackCache *>(); + track_cache = AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher>(); cache_valid = false; } @@ -2370,7 +2394,7 @@ AnimationMixer::AnimationMixer() { AnimationMixer::~AnimationMixer() { } -void AnimatedValuesBackup::set_data(const HashMap<Animation::TypeHash, AnimationMixer::TrackCache *> p_data) { +void AnimatedValuesBackup::set_data(const AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> p_data) { clear_data(); for (const KeyValue<Animation::TypeHash, AnimationMixer::TrackCache *> &E : p_data) { @@ -2383,7 +2407,7 @@ void AnimatedValuesBackup::set_data(const HashMap<Animation::TypeHash, Animation } } -HashMap<Animation::TypeHash, AnimationMixer::TrackCache *> AnimatedValuesBackup::get_data() const { +AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> AnimatedValuesBackup::get_data() const { HashMap<Animation::TypeHash, AnimationMixer::TrackCache *> ret; for (const KeyValue<Animation::TypeHash, AnimationMixer::TrackCache *> &E : data) { AnimationMixer::TrackCache *track = get_cache_copy(E.value); |