From 2cedbf5e1a50acb37c5ced4ca07ca603bed75a34 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Sat, 13 Nov 2021 12:35:23 +0100 Subject: [PATCH] Added comments and minor refactor. --- src/AnimNode.h | 25 ++++++++++++++----------- src/AnimNodes/AnimSamplerNode.h | 6 ++---- src/AnimNodes/BlendNode.h | 9 ++++----- src/AnimNodes/SpeedScaleNode.h | 8 +++----- src/AnimationController.cc | 28 +++++++++++++++++++++++++--- src/AnimationController.h | 10 ++++++---- 6 files changed, 54 insertions(+), 32 deletions(-) diff --git a/src/AnimNode.h b/src/AnimNode.h index bdf8184..b572884 100644 --- a/src/AnimNode.h +++ b/src/AnimNode.h @@ -9,11 +9,7 @@ #include "AnimationController.h" -enum class AnimNodeType { - Blend, - SpeedScale, - AnimSampler -}; +enum class AnimNodeType { Blend, SpeedScale, AnimSampler }; struct AnimNode { AnimNode(AnimationController* animation_controller) @@ -25,24 +21,31 @@ struct AnimNode { AnimNodeType m_anim_node_type; std::string m_name; - float m_current_time; - bool m_is_time_synced; - float m_anim_duration; AnimationController* m_animation_controller; - ozz::vector m_local_matrices; + + // When synced then current time is relative to the node's anim duration.:w + bool m_is_time_synced; + float m_current_time; + float m_anim_duration; virtual void Reset() { m_current_time = 0.f; } + // Mark current node according to is_synced and propagate flag to animation inputs. virtual void UpdateIsSynced(bool is_synced) = 0; + // Evaluate the animation duration of this node. All input nodes must have already evaluated + // their anim durations. virtual void EvalAnimDuration() = 0; - virtual void UpdateTime(float dt) { m_current_time += dt; } + // Evaluate current time and propagate time step to inputs. + virtual void UpdateTime(float dt) = 0; + // Evaluate the current node and write output to local_matrices. virtual void Evaluate( ozz::vector* local_matrices) = 0; - virtual void CollectNodeOrdering(std::vector& anim_nodes) = 0; + // Returns a list of animation nodes that provide input for this node. + virtual void GetInputNodes(std::vector& input_nodes) const = 0 ; virtual void DrawDebugUi(){}; }; diff --git a/src/AnimNodes/AnimSamplerNode.h b/src/AnimNodes/AnimSamplerNode.h index ab07938..b6a81f4 100644 --- a/src/AnimNodes/AnimSamplerNode.h +++ b/src/AnimNodes/AnimSamplerNode.h @@ -22,6 +22,7 @@ struct AnimSamplerNode : public AnimNode { bool m_override_ratio; float m_anim_ratio; + ozz::vector m_local_matrices; ozz::animation::SamplingCache m_sampling_cache; void SetAnimation(ozz::animation::Animation* animation); @@ -54,10 +55,7 @@ struct AnimSamplerNode : public AnimNode { virtual void Evaluate( ozz::vector* local_matrices) override; - virtual void CollectNodeOrdering( - std::vector& anim_nodes) override { - anim_nodes.push_back(this); - }; + virtual void GetInputNodes(std::vector& input_nodes) const override{}; virtual void DrawDebugUi(); }; diff --git a/src/AnimNodes/BlendNode.h b/src/AnimNodes/BlendNode.h index 49be09d..20c965a 100644 --- a/src/AnimNodes/BlendNode.h +++ b/src/AnimNodes/BlendNode.h @@ -60,11 +60,10 @@ struct BlendNode : public AnimNode { virtual void Evaluate( ozz::vector* local_matrices) override; - virtual void CollectNodeOrdering (std::vector& anim_nodes) override { - anim_nodes.push_back(this); - m_input_A->CollectNodeOrdering(anim_nodes); - m_input_B->CollectNodeOrdering(anim_nodes); - } + virtual void GetInputNodes(std::vector& input_nodes) const override { + input_nodes.push_back(m_input_A); + input_nodes.push_back(m_input_B); + }; virtual void DrawDebugUi(); }; diff --git a/src/AnimNodes/SpeedScaleNode.h b/src/AnimNodes/SpeedScaleNode.h index 1b11d39..e0ba4d2 100644 --- a/src/AnimNodes/SpeedScaleNode.h +++ b/src/AnimNodes/SpeedScaleNode.h @@ -43,11 +43,9 @@ struct SpeedScaleNode : public AnimNode { m_input_node->Evaluate(local_matrices); }; - virtual void CollectNodeOrdering( - std::vector& anim_nodes) override { - anim_nodes.push_back(this); - m_input_node->CollectNodeOrdering(anim_nodes); - } + virtual void GetInputNodes(std::vector& input_nodes) const override { + input_nodes.push_back(m_input_node); + }; virtual void DrawDebugUi() override; }; diff --git a/src/AnimationController.cc b/src/AnimationController.cc index e2abbc2..5852eae 100644 --- a/src/AnimationController.cc +++ b/src/AnimationController.cc @@ -9,6 +9,8 @@ #include #include +#include + #include "AnimNodes/AnimSamplerNode.h" #include "AnimNodes/BlendNode.h" #include "AnimNodes/SpeedScaleNode.h" @@ -23,8 +25,6 @@ AnimationController::AnimationController(SkinnedMesh* skinned_mesh) m_local_matrices.resize(num_soa_joints); - assert(skinned_mesh->m_animations.size() > 1); - SetBlendAnims(skinned_mesh->m_animations[1], skinned_mesh->m_animations[0]); ResetAnims(); AnimSamplerNode* sampler_node0 = new AnimSamplerNode(this); @@ -56,7 +56,7 @@ AnimationController::AnimationController(SkinnedMesh* skinned_mesh) m_output_node = speed_node1; - m_output_node->CollectNodeOrdering(m_ordered_nodes); + UpdateOrderedNodes(); m_output_node->Reset(); } @@ -78,13 +78,34 @@ void AnimationController::ResetAnims() { } } +void AnimationController::UpdateOrderedNodes() { + std::vector node_stack; + node_stack.push_back(m_output_node); + + m_ordered_nodes.clear(); + + while (node_stack.size() > 0) { + AnimNode* node = node_stack.back(); + m_ordered_nodes.push_back(node); + node_stack.pop_back(); + + std::vector node_inputs; + node->GetInputNodes(node_inputs); + for (int i = node_inputs.size() - 1; i >= 0; i--) { + node_stack.push_back(node_inputs[i]); + } + } +} + void AnimationController::Update(float dt) { if (m_output_node == nullptr) { return; } + // Mark all nodes that evaluate time using sync tracks. m_output_node->UpdateIsSynced(false); + // For all synced nodes calculate their current sync track durations for (int i = m_ordered_nodes.size() - 1; i >= 0; i--) { AnimNode* node = m_ordered_nodes[i]; if (node->m_is_time_synced) { @@ -92,6 +113,7 @@ void AnimationController::Update(float dt) { } } + // Update the time of all nodes. m_output_node->UpdateTime(dt); } diff --git a/src/AnimationController.h b/src/AnimationController.h index d70aa0c..78ec63e 100644 --- a/src/AnimationController.h +++ b/src/AnimationController.h @@ -18,13 +18,15 @@ struct AnimationController { explicit AnimationController(SkinnedMesh* skinned_mesh); virtual ~AnimationController(); - void SetBlendAnims( - ozz::animation::Animation* blend_anim_A, - ozz::animation::Animation* blend_anim_B) { - } void ResetAnims(); + // Creates a list of nodes where for node at index i for all inputs holds index > i. + void UpdateOrderedNodes(); + + // Updates all nodes. void Update(float dt); + + // Recursively evaluates all nodes. void Evaluate(); void DrawDebugUi();