diff --git a/demo/main.tscn b/demo/main.tscn index 44e348c..bc1df57 100644 --- a/demo/main.tscn +++ b/demo/main.tscn @@ -23,6 +23,7 @@ libraries = { } [node name="SyncedAnimationGraph" type="SyncedAnimationGraph" parent="."] +active = false animation_tree = NodePath("../AnimationTree") skeleton = NodePath("../MixamoAmy/Armature/Skeleton3D") diff --git a/synced_animation_graph.cpp b/synced_animation_graph.cpp index 3632554..113f0ce 100644 --- a/synced_animation_graph.cpp +++ b/synced_animation_graph.cpp @@ -4,7 +4,6 @@ #include "scene/3d/skeleton_3d.h" #include "scene/animation/animation_player.h" - void SyncedAnimationGraph::_bind_methods() { print_line(vformat("binding methods")); @@ -219,14 +218,12 @@ void SyncedAnimationGraph::_process_graph(double p_delta, bool p_update_only) { default: { break; } - } } -// skeleton->set_bone_pose_position(3, Vector3(sin(current_time) * 10., 0., 0.)); + // skeleton->set_bone_pose_position(3, Vector3(sin(current_time) * 10., 0., 0.)); skeleton->force_update_all_bone_transforms(); - // TrackCache *track = track_num_to_track_cache[i]; // if (track == nullptr) { // continue; // No path, but avoid error spamming. @@ -248,7 +245,6 @@ void SyncedAnimationGraph::_process_graph(double p_delta, bool p_update_only) { // print_line(vformat(" %s", node_name)); // } - void SyncedAnimationGraph::_set_process(bool p_process, bool p_force) { if (processing == p_process && !p_force) { return; @@ -262,3 +258,16 @@ void SyncedAnimationGraph::_set_process(bool p_process, bool p_force) { SyncedAnimationGraph::SyncedAnimationGraph() { } + +void AnimationSamplerNode::initialize(GraphEvaluationContext &context) { + animation = context.animation_tree->get_animation(animation_name); +} + +void AnimationSamplerNode::evaluate(AnimationData &output) { + const Vector tracks = animation->get_tracks(); + Animation::Track *const *tracks_ptr = tracks.ptr(); + // real_t a_length = animation->get_length(); + int count = tracks.size(); + for (int i = 0; i < count; i++) { + } +} \ No newline at end of file diff --git a/synced_animation_graph.h b/synced_animation_graph.h index 27d9748..220833d 100644 --- a/synced_animation_graph.h +++ b/synced_animation_graph.h @@ -1,8 +1,9 @@ #pragma once -#include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_tree.h" +#include + class SyncedAnimationGraph : public Node { GDCLASS(SyncedAnimationGraph, Node); @@ -17,7 +18,7 @@ private: NodePath get_skeleton() const; // AnimationMixer::TrackCache - + protected: void _notification(int p_what); static void _bind_methods(); @@ -50,4 +51,79 @@ public: private: void _set_process(bool p_process, bool p_force = false); +}; + +struct AnimationData { + struct TrackValue { + Animation::Track *track = nullptr; + }; + + struct PositionTrackValue : public TrackValue { + int bone_idx = -1; + Vector3 position = Vector3(0, 0, 0); + }; + + struct RotationTrackValue : public TrackValue { + int bone_idx = -1; + Quaternion rotation = Quaternion(0, 0, 0, 1); + }; + + struct ScaleTrackValue : public TrackValue { + int bone_idx = -1; + Vector3 scale; + }; + + AHashMap> track_values; +}; + +struct GraphEvaluationContext { + AnimationTree *animation_tree = nullptr; +}; + +class SyncedAnimationNode { +public: + struct NodeTimeInfo { + double length = 0.0; + double position = 0.0; + double delta = 0.0; + + Animation::LoopMode loop_mode = Animation::LOOP_NONE; + }; + NodeTimeInfo node_time_info; + + virtual ~SyncedAnimationNode() = default; + virtual void initialize(GraphEvaluationContext &context) {} + virtual void activate_inputs(Vector input_names) {} + virtual void calculate_sync_track() {} + virtual void update_time(double p_delta) { + node_time_info.position += p_delta; + if (node_time_info.position > node_time_info.length) { + switch (node_time_info.loop_mode) { + case Animation::LOOP_NONE: { + node_time_info.position = node_time_info.length; + break; + } + case Animation::LOOP_LINEAR: { + assert(node_time_info.length > 0.0); + while (node_time_info.position > node_time_info.length) { + node_time_info.position -= node_time_info.length; + } + break; + } + case Animation::LOOP_PINGPONG: { + assert(false && !"Not yet implemented."); + break; + } + } + } + } + virtual void evaluate(AnimationData &output) {} +}; + +class AnimationSamplerNode : public SyncedAnimationNode { + StringName animation_name; + Ref animation; + + void initialize(GraphEvaluationContext &context) override; + void evaluate(AnimationData &output) override; }; \ No newline at end of file