From a5577eceea1d389cfe75be741b6cfb334ff99376 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Fri, 16 Jan 2026 09:51:49 +0100 Subject: [PATCH] Added profiling statements to SyncedAnimationGraph. --- demo/main.gd | 2 +- synced_animation_graph.cpp | 7 +++++++ synced_animation_graph.h | 2 -- synced_animation_node.cpp | 8 +++++++- synced_animation_node.h | 21 +++++++++++++++------ 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/demo/main.gd b/demo/main.gd index 67e67ac..cedb685 100644 --- a/demo/main.gd +++ b/demo/main.gd @@ -10,7 +10,7 @@ extends Node3D # Called when the node enters the scene tree for the first time. func _ready() -> void: - blend_weight_slider.value = 0.0 + blend_weight_slider.value = 0.5 # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta: float) -> void: diff --git a/synced_animation_graph.cpp b/synced_animation_graph.cpp index 5599305..9747743 100644 --- a/synced_animation_graph.cpp +++ b/synced_animation_graph.cpp @@ -1,6 +1,7 @@ #include "synced_animation_graph.h" #include "core/os/time.h" +#include "core/profiling/profiling.h" #include "scene/3d/skeleton_3d.h" #include "scene/animation/animation_player.h" @@ -141,6 +142,8 @@ void SyncedAnimationGraph::_tree_changed() { } void SyncedAnimationGraph::_notification(int p_what) { + GodotProfileZone("SyncedAnimationGraph::_notification"); + switch (p_what) { case Node::NOTIFICATION_READY: { _setup_evaluation_context(); @@ -292,6 +295,8 @@ void SyncedAnimationGraph::_process_graph(double p_delta, bool p_update_only) { return; } + GodotProfileZone("SyncedAnimationGraph::_process_graph"); + _update_properties(); root_animation_node->activate_inputs(Vector>()); @@ -303,6 +308,8 @@ void SyncedAnimationGraph::_process_graph(double p_delta, bool p_update_only) { } void SyncedAnimationGraph::_apply_animation_data(const AnimationData &output_data) const { + GodotProfileZone("SyncedAnimationGraph::_apply_animation_data"); + for (const KeyValue &K : output_data.track_values) { const AnimationData::TrackValue *track_value = K.value; switch (track_value->type) { diff --git a/synced_animation_graph.h b/synced_animation_graph.h index 2ee715a..589f1fb 100644 --- a/synced_animation_graph.h +++ b/synced_animation_graph.h @@ -3,8 +3,6 @@ #include "scene/animation/animation_player.h" #include "synced_animation_node.h" -#include - class Skeleton3D; class SyncedAnimationGraph : public Node { diff --git a/synced_animation_node.cpp b/synced_animation_node.cpp index df8e938..1a57ccf 100644 --- a/synced_animation_node.cpp +++ b/synced_animation_node.cpp @@ -135,7 +135,9 @@ bool SyncedBlendTree::_set(const StringName &p_name, const Variant &p_value) { } void AnimationData::sample_from_animation(const Ref &animation, const Skeleton3D *skeleton_3d, double p_time) { - const Vector tracks = animation->get_tracks(); + GodotProfileZone("AnimationData::sample_from_animation"); + + const LocalVector tracks = animation->get_tracks(); Animation::Track *const *tracks_ptr = tracks.ptr(); int count = tracks.size(); @@ -250,6 +252,8 @@ void AnimationSamplerNode::update_time(double p_time) { } void AnimationSamplerNode::evaluate(GraphEvaluationContext &context, const LocalVector &inputs, AnimationData &output) { + GodotProfileZone("AnimationSamplerNode::evaluate"); + assert(inputs.size() == 0); if (node_time_info.is_synced) { @@ -276,6 +280,8 @@ void AnimationSamplerNode::_bind_methods() { } void AnimationBlend2Node::evaluate(GraphEvaluationContext &context, const LocalVector &inputs, AnimationData &output) { + GodotProfileZone("AnimationBlend2Node::evaluate"); + output = *inputs[0]; output.blend(*inputs[1], blend_weight); } diff --git a/synced_animation_node.h b/synced_animation_node.h index 2fc26dc..7067554 100644 --- a/synced_animation_node.h +++ b/synced_animation_node.h @@ -1,9 +1,10 @@ #pragma once -#include "scene/animation/animation_player.h" - #include "core/io/resource.h" +#include "core/profiling/profiling.h" + #include "scene/3d/skeleton_3d.h" +#include "scene/animation/animation_player.h" #include "sync_track.h" #include @@ -113,9 +114,8 @@ struct AnimationData { }; AnimationData() = default; - ~AnimationData() { - _clear_values(); - } + ~AnimationData() = default; + AnimationData(const AnimationData &other) { for (const KeyValue &K : other.track_values) { track_values.insert(K.key, K.value->clone()); @@ -165,6 +165,8 @@ struct AnimationData { } void blend(const AnimationData &to_data, const float lambda) { + GodotProfileZone("AnimationData::blend"); + if (!has_same_tracks(to_data)) { print_error("Cannot blend AnimationData: tracks do not match."); return; @@ -502,7 +504,7 @@ struct BlendTreeGraph { LocalVector sorted_node_indices = get_sorted_node_indices(); Vector> sorted_nodes; - Vector old_node_connection_info = node_connection_info; + LocalVector old_node_connection_info = node_connection_info; for (unsigned int i = 0; i < sorted_node_indices.size(); i++) { int node_index = sorted_node_indices[i]; sorted_nodes.push_back(nodes[node_index]); @@ -714,6 +716,8 @@ public: } void activate_inputs(Vector> input_nodes) override { + GodotProfileZone("SyncedBlendTree::activate_inputs"); + tree_graph.nodes[0]->active = true; for (int i = 0; i < tree_graph.nodes.size(); i++) { const Ref &node = tree_graph.nodes[i]; @@ -728,6 +732,7 @@ public: } void calculate_sync_track(Vector> input_nodes) override { + GodotProfileZone("SyncedBlendTree::calculate_sync_track"); for (int i = tree_graph.nodes.size() - 1; i > 0; i--) { const Ref &node = tree_graph.nodes[i]; @@ -742,6 +747,8 @@ public: } void update_time(double p_delta) override { + GodotProfileZone("SyncedBlendTree::update_time"); + tree_graph.nodes[0]->node_time_info.delta = p_delta; tree_graph.nodes[0]->node_time_info.position += p_delta; @@ -763,6 +770,8 @@ public: } void evaluate(GraphEvaluationContext &context, const LocalVector &input_datas, AnimationData &output_data) override { + ZoneScopedN("SyncedBlendTree::evaluate"); + for (int i = tree_graph.nodes.size() - 1; i > 0; i--) { const Ref &node = tree_graph.nodes[i];