diff options
author | Spartan322 <Megacake1234@gmail.com> | 2024-10-26 22:41:20 -0400 |
---|---|---|
committer | Spartan322 <Megacake1234@gmail.com> | 2024-10-26 22:41:20 -0400 |
commit | 953af98c795066a5a450a3401cc8a4fbc6c12620 (patch) | |
tree | 9e100139ffacbcae90fbb5e6b10413e50a8e76b6 /scene/animation | |
parent | a43f7f1c02a887d19694bdebac83af4d32cf3433 (diff) | |
parent | 61accf060515416da07d913580419fd8c8490f7b (diff) | |
download | redot-engine-953af98c795066a5a450a3401cc8a4fbc6c12620.tar.gz |
Merge commit godotengine/godot@61accf060515416da07d913580419fd8c8490f7b
Diffstat (limited to 'scene/animation')
-rw-r--r-- | scene/animation/animation_mixer.cpp | 66 | ||||
-rw-r--r-- | scene/animation/animation_mixer.h | 21 | ||||
-rw-r--r-- | scene/animation/animation_node_state_machine.cpp | 2 | ||||
-rw-r--r-- | scene/animation/animation_player.cpp | 4 | ||||
-rw-r--r-- | scene/animation/animation_player.h | 4 | ||||
-rw-r--r-- | scene/animation/animation_tree.cpp | 32 | ||||
-rw-r--r-- | scene/animation/animation_tree.h | 47 |
7 files changed, 126 insertions, 50 deletions
diff --git a/scene/animation/animation_mixer.cpp b/scene/animation/animation_mixer.cpp index 5f4eb02e68..8538e07524 100644 --- a/scene/animation/animation_mixer.cpp +++ b/scene/animation/animation_mixer.cpp @@ -565,6 +565,7 @@ void AnimationMixer::_clear_caches() { memdelete(K.value); } track_cache.clear(); + animation_track_num_to_track_cashe.clear(); cache_valid = false; capture_cache.clear(); @@ -924,6 +925,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; @@ -948,7 +970,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: { @@ -1035,7 +1057,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; } @@ -1086,26 +1108,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); } } } @@ -1132,6 +1158,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(); @@ -1141,15 +1169,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) { @@ -1583,7 +1607,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) { @@ -1852,7 +1876,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; @@ -2136,7 +2160,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; } @@ -2372,7 +2396,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) { @@ -2385,7 +2409,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); diff --git a/scene/animation/animation_mixer.h b/scene/animation/animation_mixer.h index 8cc76d8339..a2ad0e7ef1 100644 --- a/scene/animation/animation_mixer.h +++ b/scene/animation/animation_mixer.h @@ -33,6 +33,7 @@ #ifndef ANIMATION_MIXER_H #define ANIMATION_MIXER_H +#include "core/templates/a_hash_map.h" #include "scene/animation/tween.h" #include "scene/main/node.h" #include "scene/resources/animation.h" @@ -104,7 +105,7 @@ public: protected: /* ---- Data lists ---- */ LocalVector<AnimationLibraryData> animation_libraries; - HashMap<StringName, AnimationData> animation_set; // HashMap<Library name + Animation name, AnimationData> + AHashMap<StringName, AnimationData> animation_set; // HashMap<Library name + Animation name, AnimationData> TypedArray<StringName> _get_animation_library_list() const; Vector<String> _get_animation_list() const { @@ -150,6 +151,7 @@ protected: uint64_t setup_pass = 0; Animation::TrackType type = Animation::TrackType::TYPE_ANIMATION; NodePath path; + int blend_idx = -1; ObjectID object_id; real_t total_weight = 0.0; @@ -271,7 +273,7 @@ protected: // Audio track information for mixng and ending. struct PlayingAudioTrackInfo { - HashMap<int, PlayingAudioStreamInfo> stream_info; + AHashMap<int, PlayingAudioStreamInfo> stream_info; double length = 0.0; double time = 0.0; real_t volume = 0.0; @@ -310,7 +312,8 @@ protected: }; RootMotionCache root_motion_cache; - HashMap<Animation::TypeHash, TrackCache *> track_cache; + AHashMap<Animation::TypeHash, TrackCache *, HashHasher> track_cache; + AHashMap<Ref<Animation>, LocalVector<TrackCache *>> animation_track_num_to_track_cashe; HashSet<TrackCache *> playing_caches; Vector<Node *> playing_audio_stream_players; @@ -326,7 +329,7 @@ protected: /* ---- Blending processor ---- */ LocalVector<AnimationInstance> animation_instances; - HashMap<NodePath, int> track_map; + AHashMap<NodePath, int> track_map; int track_count = 0; bool deterministic = false; @@ -361,12 +364,12 @@ protected: virtual void _process_animation(double p_delta, bool p_update_only = false); // For post process with retrieved key value during blending. - virtual Variant _post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, ObjectID p_object_id, int p_object_sub_idx = -1); + virtual Variant _post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant &p_value, ObjectID p_object_id, int p_object_sub_idx = -1); Variant post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, ObjectID p_object_id, int p_object_sub_idx = -1); GDVIRTUAL5RC(Variant, _post_process_key_value, Ref<Animation>, int, Variant, ObjectID, int); void _blend_init(); - virtual bool _blend_pre_process(double p_delta, int p_track_count, const HashMap<NodePath, int> &p_track_map); + virtual bool _blend_pre_process(double p_delta, int p_track_count, const AHashMap<NodePath, int> &p_track_map); virtual void _blend_capture(double p_delta); void _blend_calc_total_weight(); // For undeterministic blending. void _blend_process(double p_delta, bool p_update_only = false); @@ -487,11 +490,11 @@ public: class AnimatedValuesBackup : public RefCounted { GDCLASS(AnimatedValuesBackup, RefCounted); - HashMap<Animation::TypeHash, AnimationMixer::TrackCache *> data; + AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> data; public: - void set_data(const HashMap<Animation::TypeHash, AnimationMixer::TrackCache *> p_data); - HashMap<Animation::TypeHash, AnimationMixer::TrackCache *> get_data() const; + void set_data(const AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> p_data); + AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> get_data() const; void clear_data(); AnimationMixer::TrackCache *get_cache_copy(AnimationMixer::TrackCache *p_cache) const; diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index eba2de69f2..33b8e314f3 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -1621,7 +1621,7 @@ AnimationNode::NodeTimeInfo AnimationNodeStateMachine::_process(const AnimationM playback_new = playback_new->duplicate(); // Don't process original when testing. } - return playback_new->process(node_state.base_path, this, p_playback_info, p_test_only); + return playback_new->process(node_state.get_base_path(), this, p_playback_info, p_test_only); } String AnimationNodeStateMachine::get_caption() const { diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 5defc53688..4179fb5806 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -135,7 +135,7 @@ void AnimationPlayer::_get_property_list(List<PropertyInfo> *p_list) const { List<PropertyInfo> anim_names; for (const KeyValue<StringName, AnimationData> &E : animation_set) { - HashMap<StringName, StringName>::ConstIterator F = animation_next_set.find(E.key); + AHashMap<StringName, StringName>::ConstIterator F = animation_next_set.find(E.key); if (F && F->value != StringName()) { anim_names.push_back(PropertyInfo(Variant::STRING, "next/" + String(E.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL)); } @@ -301,7 +301,7 @@ void AnimationPlayer::_blend_playback_data(double p_delta, bool p_started) { } } -bool AnimationPlayer::_blend_pre_process(double p_delta, int p_track_count, const HashMap<NodePath, int> &p_track_map) { +bool AnimationPlayer::_blend_pre_process(double p_delta, int p_track_count, const AHashMap<NodePath, int> &p_track_map) { if (!playback.current.from) { _set_process(false); return false; diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 37e463f2ac..659817bff5 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -54,7 +54,7 @@ public: #endif // DISABLE_DEPRECATED private: - HashMap<StringName, StringName> animation_next_set; // For auto advance. + AHashMap<StringName, StringName> animation_next_set; // For auto advance. float speed_scale = 1.0; double default_blend_time = 0.0; @@ -140,7 +140,7 @@ protected: static void _bind_methods(); // Make animation instances. - virtual bool _blend_pre_process(double p_delta, int p_track_count, const HashMap<NodePath, int> &p_track_map) override; + virtual bool _blend_pre_process(double p_delta, int p_track_count, const AHashMap<NodePath, int> &p_track_map) override; virtual void _blend_capture(double p_delta) override; virtual void _blend_post_process() override; diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 77abdd33f5..2bf680c66c 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -77,20 +77,34 @@ void AnimationNode::set_parameter(const StringName &p_name, const Variant &p_val if (process_state->is_testing) { return; } + + const AHashMap<StringName, int>::Iterator it = property_cache.find(p_name); + if (it) { + process_state->tree->property_map.get_by_index(it->value).value.first = p_value; + return; + } + ERR_FAIL_COND(!process_state->tree->property_parent_map.has(node_state.base_path)); ERR_FAIL_COND(!process_state->tree->property_parent_map[node_state.base_path].has(p_name)); StringName path = process_state->tree->property_parent_map[node_state.base_path][p_name]; - - process_state->tree->property_map[path].first = p_value; + int idx = process_state->tree->property_map.get_index(path); + property_cache.insert_new(p_name, idx); + process_state->tree->property_map.get_by_index(idx).value.first = p_value; } Variant AnimationNode::get_parameter(const StringName &p_name) const { ERR_FAIL_NULL_V(process_state, Variant()); + const AHashMap<StringName, int>::ConstIterator it = property_cache.find(p_name); + if (it) { + return process_state->tree->property_map.get_by_index(it->value).value.first; + } ERR_FAIL_COND_V(!process_state->tree->property_parent_map.has(node_state.base_path), Variant()); ERR_FAIL_COND_V(!process_state->tree->property_parent_map[node_state.base_path].has(p_name), Variant()); StringName path = process_state->tree->property_parent_map[node_state.base_path][p_name]; - return process_state->tree->property_map[path].first; + int idx = process_state->tree->property_map.get_index(path); + property_cache.insert_new(p_name, idx); + return process_state->tree->property_map.get_by_index(idx).value.first; } void AnimationNode::set_node_time_info(const NodeTimeInfo &p_node_time_info) { @@ -205,7 +219,7 @@ AnimationNode::NodeTimeInfo AnimationNode::_blend_node(Ref<AnimationNode> p_node } for (const KeyValue<NodePath, bool> &E : filter) { - const HashMap<NodePath, int> &map = *process_state->track_map; + const AHashMap<NodePath, int> &map = *process_state->track_map; if (!map.has(E.key)) { continue; } @@ -294,7 +308,7 @@ AnimationNode::NodeTimeInfo AnimationNode::_blend_node(Ref<AnimationNode> p_node // This process, which depends on p_sync is needed to process sync correctly in the case of // that a synced AnimationNodeSync exists under the un-synced AnimationNodeSync. - p_node->node_state.base_path = new_path; + p_node->set_node_state_base_path(new_path); p_node->node_state.parent = new_parent; if (!p_playback_info.seeked && !p_sync && !any_valid) { p_playback_info.delta = 0.0; @@ -605,7 +619,7 @@ Ref<AnimationRootNode> AnimationTree::get_root_animation_node() const { return root_animation_node; } -bool AnimationTree::_blend_pre_process(double p_delta, int p_track_count, const HashMap<NodePath, int> &p_track_map) { +bool AnimationTree::_blend_pre_process(double p_delta, int p_track_count, const AHashMap<NodePath, int> &p_track_map) { _update_properties(); // If properties need updating, update them. if (!root_animation_node.is_valid()) { @@ -629,7 +643,7 @@ bool AnimationTree::_blend_pre_process(double p_delta, int p_track_count, const for (int i = 0; i < p_track_count; i++) { src_blendsw[i] = 1.0; // By default all go to 1 for the root input. } - root_animation_node->node_state.base_path = SNAME(Animation::PARAMETERS_BASE_PATH.ascii().get_data()); + root_animation_node->set_node_state_base_path(SNAME(Animation::PARAMETERS_BASE_PATH.ascii().get_data())); root_animation_node->node_state.parent = nullptr; } @@ -734,7 +748,7 @@ void AnimationTree::_animation_node_removed(const ObjectID &p_oid, const StringN void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<AnimationNode> p_node) { ERR_FAIL_COND(p_node.is_null()); if (!property_parent_map.has(p_base_path)) { - property_parent_map[p_base_path] = HashMap<StringName, StringName>(); + property_parent_map[p_base_path] = AHashMap<StringName, StringName>(); } if (!property_reference_map.has(p_node->get_instance_id())) { property_reference_map[p_node->get_instance_id()] = p_base_path; @@ -769,7 +783,7 @@ void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<A pinfo.name = p_base_path + key; properties.push_back(pinfo); } - + p_node->make_cache_dirty(); List<AnimationNode::ChildNode> children; p_node->get_child_nodes(&children); diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index eff7637764..07b20f7684 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -62,7 +62,7 @@ public: bool closable = false; Vector<Input> inputs; - HashMap<NodePath, bool> filter; + AHashMap<NodePath, bool> filter; bool filter_enabled = false; // To propagate information from upstream for use in estimation of playback progress. @@ -99,22 +99,57 @@ public: // Temporary state for blending process which needs to be stored in each AnimationNodes. struct NodeState { + friend AnimationNode; + + private: StringName base_path; + + public: AnimationNode *parent = nullptr; Vector<StringName> connections; Vector<real_t> track_weights; + + const StringName get_base_path() const { + return base_path; + } + } node_state; // Temporary state for blending process which needs to be started in the AnimationTree, pass through the AnimationNodes, and then return to the AnimationTree. struct ProcessState { AnimationTree *tree = nullptr; - const HashMap<NodePath, int> *track_map; // TODO: Is there a better way to manage filter/tracks? + const AHashMap<NodePath, int> *track_map; // TODO: Is there a better way to manage filter/tracks? bool is_testing = false; bool valid = false; String invalid_reasons; uint64_t last_pass = 0; } *process_state = nullptr; +private: + mutable AHashMap<StringName, int> property_cache; + +public: + void set_node_state_base_path(const StringName p_base_path) { + if (p_base_path != node_state.base_path) { + node_state.base_path = p_base_path; + make_cache_dirty(); + } + } + + void set_node_state_base_path(const String p_base_path) { + if (p_base_path != node_state.base_path) { + node_state.base_path = p_base_path; + make_cache_dirty(); + } + } + + const StringName get_node_state_base_path() const { + return node_state.get_base_path(); + } + + void make_cache_dirty() { + property_cache.clear(); + } Array _get_filters() const; void _set_filters(const Array &p_filters); friend class AnimationNodeBlendTree; @@ -252,9 +287,9 @@ private: friend class AnimationNode; List<PropertyInfo> properties; - HashMap<StringName, HashMap<StringName, StringName>> property_parent_map; - HashMap<ObjectID, StringName> property_reference_map; - HashMap<StringName, Pair<Variant, bool>> property_map; // Property value and read-only flag. + AHashMap<StringName, AHashMap<StringName, StringName>> property_parent_map; + AHashMap<ObjectID, StringName> property_reference_map; + AHashMap<StringName, Pair<Variant, bool>> property_map; // Property value and read-only flag. bool properties_dirty = true; @@ -288,7 +323,7 @@ private: virtual void _set_active(bool p_active) override; // Make animation instances. - virtual bool _blend_pre_process(double p_delta, int p_track_count, const HashMap<NodePath, int> &p_track_map) override; + virtual bool _blend_pre_process(double p_delta, int p_track_count, const AHashMap<NodePath, int> &p_track_map) override; #ifndef DISABLE_DEPRECATED void _set_process_callback_bind_compat_80813(AnimationProcessCallback p_mode); |