diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2024-03-24 01:12:42 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2024-03-24 01:12:42 +0100 |
commit | f8bae10be6a5d33acf8409b915aba9dd6493dcf6 (patch) | |
tree | 5ea8566cc6a2dedfdd9849a03e2b68fce066cf4c /scene/animation/animation_tree.cpp | |
parent | 0ebcba858354581d29d51d19dfb24edba03252e1 (diff) | |
parent | 6dd410854c0a9bab155ba020a1e5055f7384f453 (diff) | |
download | redot-engine-f8bae10be6a5d33acf8409b915aba9dd6493dcf6.tar.gz |
Merge pull request #87171 from TokageItLab/retrieve-time-info-from-anim-tree
Rework AnimationNode process for retrieving the semantic time info
Diffstat (limited to 'scene/animation/animation_tree.cpp')
-rw-r--r-- | scene/animation/animation_tree.cpp | 99 |
1 files changed, 71 insertions, 28 deletions
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 4889cd82af..2d0bd9c258 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -46,6 +46,10 @@ void AnimationNode::get_parameter_list(List<PropertyInfo> *r_list) const { r_list->push_back(PropertyInfo::from_dict(d)); } } + + r_list->push_back(PropertyInfo(Variant::FLOAT, current_length, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_READ_ONLY)); + r_list->push_back(PropertyInfo(Variant::FLOAT, current_position, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_READ_ONLY)); + r_list->push_back(PropertyInfo(Variant::FLOAT, current_delta, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_READ_ONLY)); } Variant AnimationNode::get_parameter_default_value(const StringName &p_parameter) const { @@ -56,8 +60,15 @@ Variant AnimationNode::get_parameter_default_value(const StringName &p_parameter bool AnimationNode::is_parameter_read_only(const StringName &p_parameter) const { bool ret = false; - GDVIRTUAL_CALL(_is_parameter_read_only, p_parameter, ret); - return ret; + if (GDVIRTUAL_CALL(_is_parameter_read_only, p_parameter, ret) && ret) { + return true; + } + + if (p_parameter == current_length || p_parameter == current_position || p_parameter == current_delta) { + return true; + } + + return false; } void AnimationNode::set_parameter(const StringName &p_name, const Variant &p_value) { @@ -81,6 +92,20 @@ Variant AnimationNode::get_parameter(const StringName &p_name) const { return process_state->tree->property_map[path].first; } +void AnimationNode::set_node_time_info(const NodeTimeInfo &p_node_time_info) { + set_parameter(current_length, p_node_time_info.length); + set_parameter(current_position, p_node_time_info.position); + set_parameter(current_delta, p_node_time_info.delta); +} + +AnimationNode::NodeTimeInfo AnimationNode::get_node_time_info() const { + NodeTimeInfo nti; + nti.length = get_parameter(current_length); + nti.position = get_parameter(current_position); + nti.delta = get_parameter(current_delta); + return nti; +} + void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) { Dictionary cn; if (GDVIRTUAL_CALL(_get_child_nodes, cn)) { @@ -101,11 +126,11 @@ void AnimationNode::blend_animation(const StringName &p_animation, AnimationMixe process_state->tree->make_animation_instance(p_animation, p_playback_info); } -double AnimationNode::_pre_process(ProcessState *p_process_state, AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only) { +AnimationNode::NodeTimeInfo AnimationNode::_pre_process(ProcessState *p_process_state, AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only) { process_state = p_process_state; - double t = process(p_playback_info, p_test_only); + NodeTimeInfo nti = process(p_playback_info, p_test_only); process_state = nullptr; - return t; + return nti; } void AnimationNode::make_invalid(const String &p_reason) { @@ -122,11 +147,11 @@ AnimationTree *AnimationNode::get_animation_tree() const { return process_state->tree; } -double AnimationNode::blend_input(int p_input, AnimationMixer::PlaybackInfo p_playback_info, FilterAction p_filter, bool p_sync, bool p_test_only) { - ERR_FAIL_INDEX_V(p_input, inputs.size(), 0); +AnimationNode::NodeTimeInfo AnimationNode::blend_input(int p_input, AnimationMixer::PlaybackInfo p_playback_info, FilterAction p_filter, bool p_sync, bool p_test_only) { + ERR_FAIL_INDEX_V(p_input, inputs.size(), NodeTimeInfo()); AnimationNodeBlendTree *blend_tree = Object::cast_to<AnimationNodeBlendTree>(node_state.parent); - ERR_FAIL_NULL_V(blend_tree, 0); + ERR_FAIL_NULL_V(blend_tree, NodeTimeInfo()); // Update connections. StringName current_name = blend_tree->get_node_name(Ref<AnimationNode>(this)); @@ -136,32 +161,31 @@ double AnimationNode::blend_input(int p_input, AnimationMixer::PlaybackInfo p_pl StringName node_name = node_state.connections[p_input]; if (!blend_tree->has_node(node_name)) { make_invalid(vformat(RTR("Nothing connected to input '%s' of node '%s'."), get_input_name(p_input), current_name)); - return 0; + return NodeTimeInfo(); } Ref<AnimationNode> node = blend_tree->get_node(node_name); - ERR_FAIL_COND_V(node.is_null(), 0); + ERR_FAIL_COND_V(node.is_null(), NodeTimeInfo()); real_t activity = 0.0; Vector<AnimationTree::Activity> *activity_ptr = process_state->tree->input_activity_map.getptr(node_state.base_path); - double ret = _blend_node(node, node_name, nullptr, p_playback_info, p_filter, p_sync, p_test_only, &activity); + NodeTimeInfo nti = _blend_node(node, node_name, nullptr, p_playback_info, p_filter, p_sync, p_test_only, &activity); if (activity_ptr && p_input < activity_ptr->size()) { activity_ptr->write[p_input].last_pass = process_state->last_pass; activity_ptr->write[p_input].activity = activity; } - return ret; + return nti; } -double AnimationNode::blend_node(Ref<AnimationNode> p_node, const StringName &p_subpath, AnimationMixer::PlaybackInfo p_playback_info, FilterAction p_filter, bool p_sync, bool p_test_only) { - ERR_FAIL_COND_V(p_node.is_null(), 0); - +AnimationNode::NodeTimeInfo AnimationNode::blend_node(Ref<AnimationNode> p_node, const StringName &p_subpath, AnimationMixer::PlaybackInfo p_playback_info, FilterAction p_filter, bool p_sync, bool p_test_only) { + ERR_FAIL_COND_V(p_node.is_null(), NodeTimeInfo()); p_node->node_state.connections.clear(); return _blend_node(p_node, p_subpath, this, p_playback_info, p_filter, p_sync, p_test_only, nullptr); } -double AnimationNode::_blend_node(Ref<AnimationNode> p_node, const StringName &p_subpath, AnimationNode *p_new_parent, AnimationMixer::PlaybackInfo p_playback_info, FilterAction p_filter, bool p_sync, bool p_test_only, real_t *r_activity) { - ERR_FAIL_NULL_V(process_state, 0); +AnimationNode::NodeTimeInfo AnimationNode::_blend_node(Ref<AnimationNode> p_node, const StringName &p_subpath, AnimationNode *p_new_parent, AnimationMixer::PlaybackInfo p_playback_info, FilterAction p_filter, bool p_sync, bool p_test_only, real_t *r_activity) { + ERR_FAIL_NULL_V(process_state, NodeTimeInfo()); int blend_count = node_state.track_weights.size(); @@ -261,7 +285,7 @@ double AnimationNode::_blend_node(Ref<AnimationNode> p_node, const StringName &p new_parent = p_new_parent; new_path = String(node_state.base_path) + String(p_subpath) + "/"; } else { - ERR_FAIL_NULL_V(node_state.parent, 0); + ERR_FAIL_NULL_V(node_state.parent, NodeTimeInfo()); new_parent = node_state.parent; new_path = String(new_parent->node_state.base_path) + String(p_subpath) + "/"; } @@ -271,7 +295,7 @@ double AnimationNode::_blend_node(Ref<AnimationNode> p_node, const StringName &p p_node->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.time = 0.0; + p_playback_info.delta = 0.0; return p_node->_pre_process(process_state, p_playback_info, p_test_only); } return p_node->_pre_process(process_state, p_playback_info, p_test_only); @@ -328,15 +352,31 @@ int AnimationNode::find_input(const String &p_name) const { return idx; } -double AnimationNode::process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only) { +AnimationNode::NodeTimeInfo AnimationNode::process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only) { process_state->is_testing = p_test_only; - return _process(p_playback_info, p_test_only); + + AnimationMixer::PlaybackInfo pi = p_playback_info; + if (p_playback_info.seeked) { + pi.delta = get_node_time_info().position - p_playback_info.time; + } else { + pi.time = get_node_time_info().position + p_playback_info.delta; + } + + NodeTimeInfo nti = _process(pi, p_test_only); + + if (!p_test_only) { + set_node_time_info(nti); + } + + return nti; } -double AnimationNode::_process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only) { - double ret = 0; - GDVIRTUAL_CALL(_process, p_playback_info.time, p_playback_info.seeked, p_playback_info.is_external_seeking, p_test_only, ret); - return ret; +AnimationNode::NodeTimeInfo AnimationNode::_process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only) { + double r_ret = 0.0; + GDVIRTUAL_CALL(_process, p_playback_info.time, p_playback_info.seeked, p_playback_info.is_external_seeking, p_test_only, r_ret); + NodeTimeInfo nti; + nti.delta = r_ret; + return nti; } void AnimationNode::set_filter_path(const NodePath &p_path, bool p_enable) { @@ -432,7 +472,8 @@ double AnimationNode::blend_node_ex(const StringName &p_sub_path, Ref<AnimationN info.seeked = p_seek; info.is_external_seeking = p_is_external_seeking; info.weight = p_blend; - return blend_node(p_node, p_sub_path, info, p_filter, p_sync, p_test_only); + NodeTimeInfo nti = blend_node(p_node, p_sub_path, info, p_filter, p_sync, p_test_only); + return nti.length - nti.position; } double AnimationNode::blend_input_ex(int p_input, double p_time, bool p_seek, bool p_is_external_seeking, real_t p_blend, FilterAction p_filter, bool p_sync, bool p_test_only) { @@ -441,7 +482,8 @@ double AnimationNode::blend_input_ex(int p_input, double p_time, bool p_seek, bo info.seeked = p_seek; info.is_external_seeking = p_is_external_seeking; info.weight = p_blend; - return blend_input(p_input, info, p_filter, p_sync, p_test_only); + NodeTimeInfo nti = blend_input(p_input, info, p_filter, p_sync, p_test_only); + return nti.length - nti.position; } #ifdef TOOLS_ENABLED @@ -596,11 +638,12 @@ bool AnimationTree::_blend_pre_process(double p_delta, int p_track_count, const if (started) { // If started, seek. pi.seeked = true; + pi.delta = p_delta; root_animation_node->_pre_process(&process_state, pi, false); started = false; } else { pi.seeked = false; - pi.time = p_delta; + pi.delta = p_delta; root_animation_node->_pre_process(&process_state, pi, false); } } |