From 9a9adfbfb4695e215eb036a8a0aee03386c71519 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Sun, 16 Nov 2025 21:06:39 +0100 Subject: [PATCH] Deriving SyncedAnimationGraph from Node instead of Mixer for easier prototyping. --- synced_animation_graph.cpp | 182 +++++++++++-------------------------- synced_animation_graph.h | 39 +++----- 2 files changed, 65 insertions(+), 156 deletions(-) diff --git a/synced_animation_graph.cpp b/synced_animation_graph.cpp index c5f7b42..1848f92 100644 --- a/synced_animation_graph.cpp +++ b/synced_animation_graph.cpp @@ -5,152 +5,76 @@ void SyncedAnimationGraph::_bind_methods() { print_line(vformat("binding methods")); - ClassDB::bind_method(D_METHOD("set_tree_root", "animation_node"), &SyncedAnimationGraph::set_root_animation_node); - ClassDB::bind_method(D_METHOD("get_tree_root"), &SyncedAnimationGraph::get_root_animation_node); + ClassDB::bind_method(D_METHOD("set_animation_tree", "animation_tree"), &SyncedAnimationGraph::set_animation_tree); + ClassDB::bind_method(D_METHOD("get_animation_tree"), &SyncedAnimationGraph::get_animation_tree); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "animation_tree", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationTree"), "set_animation_tree", "get_animation_tree"); - ClassDB::bind_method(D_METHOD("set_animation_player", "path"), &SyncedAnimationGraph::set_animation_player); - ClassDB::bind_method(D_METHOD("get_animation_player"), &SyncedAnimationGraph::get_animation_player); - - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode"), "set_tree_root", "get_tree_root"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_animation_player", "get_animation_player"); - - ADD_SIGNAL(MethodInfo(SNAME("animation_player_changed"))); -} - -void SyncedAnimationGraph::_set_active(bool p_active) { - _set_process(p_active); - started = p_active; -} - -void SyncedAnimationGraph::_process_animation(double p_delta, bool p_update_only) { - print_line(vformat("updating blend tree! %f", p_delta)); - if (!root_animation_node.is_valid()) { - return; - } - - Ref blend_tree = root_animation_node; - if (!blend_tree.is_valid()) { - print_line("Cannot process animation graph: root not AnimationNodeBlendTree"); - return; - } - - LocalVector node_names = blend_tree->get_node_list(); - for (StringName node_name : node_names) { - print_line(vformat(" %s", node_name)); - } -} - -SyncedAnimationGraph::SyncedAnimationGraph() { -} - -void SyncedAnimationGraph::_update_properties() const { - if (!properties_dirty) { - return; - } - - properties_dirty = false; - - const_cast(this)->notify_property_list_changed(); -} - -void SyncedAnimationGraph::set_root_animation_node(const Ref &p_animation_node) { - if (root_animation_node.is_valid()) { - root_animation_node->disconnect(SNAME("tree_changed"), callable_mp(this, &SyncedAnimationGraph::_tree_changed)); - // root_animation_node->disconnect(SNAME("animation_node_renamed"), callable_mp(this, &SyncedAnimationGraph::_animation_node_renamed)); - // root_animation_node->disconnect(SNAME("animation_node_removed"), callable_mp(this, &SyncedAnimationGraph::_animation_node_removed)); - } - - root_animation_node = p_animation_node; - - if (root_animation_node.is_valid()) { - root_animation_node->connect(SNAME("tree_changed"), callable_mp(this, &SyncedAnimationGraph::_tree_changed)); - // root_animation_node->connect(SNAME("animation_node_renamed"), callable_mp(this, &SyncedAnimationGraph::_animation_node_renamed)); - // root_animation_node->connect(SNAME("animation_node_removed"), callable_mp(this, &SyncedAnimationGraph::_animation_node_removed)); - } - - properties_dirty = true; - - update_configuration_warnings(); -} - -Ref SyncedAnimationGraph::get_root_animation_node() const { - return root_animation_node; + ADD_SIGNAL(MethodInfo(SNAME("animation_tree_changed"))); } void SyncedAnimationGraph::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - _setup_animation_player(); - if (active) { - _set_process(true); - } + case NOTIFICATION_READY: { + _set_process(true); + } break; + + case NOTIFICATION_INTERNAL_PROCESS: { + _process_animation(get_process_delta_time()); + } break; + + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + _process_animation(get_physics_process_delta_time()); } break; } } -void SyncedAnimationGraph::_tree_changed() { - if (properties_dirty) { - return; - } - - callable_mp(this, &SyncedAnimationGraph::_update_properties).call_deferred(); - properties_dirty = true; -} - -void SyncedAnimationGraph::set_animation_player(const NodePath &p_path) { - animation_player = p_path; +void SyncedAnimationGraph::set_animation_tree(const NodePath &p_path) { + animation_tree = p_path; if (p_path.is_empty()) { - set_root_node(SceneStringName(path_pp)); - while (animation_libraries.size()) { - remove_animation_library(animation_libraries[0].name); - } + // set_root_node(SceneStringName(path_pp)); + // while (animation_libraries.size()) { + // remove_animation_library(animation_libraries[0].name); + // } } - emit_signal(SNAME("animation_player_changed")); // Needs to unpin AnimationPlayerEditor. - _setup_animation_player(); - notify_property_list_changed(); + emit_signal(SNAME("animation_tree_changed")); // Needs to unpin AnimationPlayerEditor. } -NodePath SyncedAnimationGraph::get_animation_player() const { - return animation_player; +NodePath SyncedAnimationGraph::get_animation_tree() const { + return animation_tree; } -void SyncedAnimationGraph::_setup_animation_player() { - if (!is_inside_tree()) { +void SyncedAnimationGraph::_ready(const NodePath &p_path) { + print_line(vformat("synced animation graph ready!")); +} + +void SyncedAnimationGraph::_process_animation(double p_delta, bool p_update_only) { + print_line(vformat("updating blend tree! %f", p_delta)); + // if (!root_animation_node.is_valid()) { + // return; + // } + // + // Ref blend_tree = root_animation_node; + // if (!blend_tree.is_valid()) { + // print_line("Cannot process animation graph: root not AnimationNodeBlendTree"); + // return; + // } + // + // LocalVector node_names = blend_tree->get_node_list(); + // for (StringName node_name : node_names) { + // print_line(vformat(" %s", node_name)); + // } +} + +void SyncedAnimationGraph::_set_process(bool p_process, bool p_force) { + if (processing == p_process && !p_force) { return; } - cache_valid = false; + set_physics_process_internal(false); + set_process_internal(true); - if (animation_player.is_empty()) { - clear_caches(); - return; - } - - // Using AnimationPlayer here is for compatibility. Changing to AnimationMixer needs extra work like error handling. - AnimationPlayer *player = Object::cast_to(get_node_or_null(animation_player)); - if (player) { - if (!player->is_connected(SNAME("caches_cleared"), callable_mp(this, &SyncedAnimationGraph::_setup_animation_player))) { - player->connect(SNAME("caches_cleared"), callable_mp(this, &SyncedAnimationGraph::_setup_animation_player), CONNECT_DEFERRED); - } - if (!player->is_connected(SNAME("animation_list_changed"), callable_mp(this, &SyncedAnimationGraph::_setup_animation_player))) { - player->connect(SNAME("animation_list_changed"), callable_mp(this, &SyncedAnimationGraph::_setup_animation_player), CONNECT_DEFERRED); - } - Node *root = player->get_node_or_null(player->get_root_node()); - if (root) { - set_root_node(get_path_to(root, true)); - } - while (animation_libraries.size()) { - remove_animation_library(animation_libraries[0].name); - } - List list; - player->get_animation_library_list(&list); - for (const StringName &E : list) { - Ref lib = player->get_animation_library(E); - if (lib.is_valid()) { - add_animation_library(E, lib); - } - } - } - - clear_caches(); + processing = p_process; +} + +SyncedAnimationGraph::SyncedAnimationGraph() { } diff --git a/synced_animation_graph.h b/synced_animation_graph.h index 021d763..2594268 100644 --- a/synced_animation_graph.h +++ b/synced_animation_graph.h @@ -3,41 +3,26 @@ #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_tree.h" -class SyncedAnimationGraph : public AnimationMixer { - GDCLASS(SyncedAnimationGraph, AnimationMixer); +class SyncedAnimationGraph : public Node { + GDCLASS(SyncedAnimationGraph, Node); private: - bool started = true; + NodePath animation_tree; + bool processing = false; - friend class AnimationNode; - - Ref root_animation_node; - - mutable bool properties_dirty = true; - - void _update_properties() const; - - NodePath animation_player; - void set_animation_player(const NodePath &p_path); - NodePath get_animation_player() const; - - void set_root_animation_node(const Ref &p_animation_node); - Ref get_root_animation_node() const; - - void _tree_changed(); - - void _setup_animation_player(); - void _animation_player_changed(); - - void _notification(int p_what); - - virtual void _set_active(bool p_active) override; + void set_animation_tree(const NodePath &p_path); + NodePath get_animation_tree() const; protected: + void _notification(int p_what); static void _bind_methods(); public: - void _process_animation(double p_delta, bool p_update_only = false) override; + void _ready(const NodePath &p_path); + void _process_animation(double p_delta, bool p_update_only = false); SyncedAnimationGraph(); + +private: + void _set_process(bool p_process, bool p_force = false); }; \ No newline at end of file