Added comments and minor refactor.

AnimGraphEditor
Martin Felis 2021-11-13 12:35:23 +01:00
parent 30f1025947
commit 2cedbf5e1a
6 changed files with 54 additions and 32 deletions

View File

@ -9,11 +9,7 @@
#include "AnimationController.h" #include "AnimationController.h"
enum class AnimNodeType { enum class AnimNodeType { Blend, SpeedScale, AnimSampler };
Blend,
SpeedScale,
AnimSampler
};
struct AnimNode { struct AnimNode {
AnimNode(AnimationController* animation_controller) AnimNode(AnimationController* animation_controller)
@ -25,24 +21,31 @@ struct AnimNode {
AnimNodeType m_anim_node_type; AnimNodeType m_anim_node_type;
std::string m_name; std::string m_name;
float m_current_time;
bool m_is_time_synced;
float m_anim_duration;
AnimationController* m_animation_controller; AnimationController* m_animation_controller;
ozz::vector<ozz::math::SoaTransform> 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; } 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; 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 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( virtual void Evaluate(
ozz::vector<ozz::math::SoaTransform>* local_matrices) = 0; ozz::vector<ozz::math::SoaTransform>* local_matrices) = 0;
virtual void CollectNodeOrdering(std::vector<AnimNode*>& anim_nodes) = 0; // Returns a list of animation nodes that provide input for this node.
virtual void GetInputNodes(std::vector<AnimNode*>& input_nodes) const = 0 ;
virtual void DrawDebugUi(){}; virtual void DrawDebugUi(){};
}; };

View File

@ -22,6 +22,7 @@ struct AnimSamplerNode : public AnimNode {
bool m_override_ratio; bool m_override_ratio;
float m_anim_ratio; float m_anim_ratio;
ozz::vector<ozz::math::SoaTransform> m_local_matrices;
ozz::animation::SamplingCache m_sampling_cache; ozz::animation::SamplingCache m_sampling_cache;
void SetAnimation(ozz::animation::Animation* animation); void SetAnimation(ozz::animation::Animation* animation);
@ -54,10 +55,7 @@ struct AnimSamplerNode : public AnimNode {
virtual void Evaluate( virtual void Evaluate(
ozz::vector<ozz::math::SoaTransform>* local_matrices) override; ozz::vector<ozz::math::SoaTransform>* local_matrices) override;
virtual void CollectNodeOrdering( virtual void GetInputNodes(std::vector<AnimNode*>& input_nodes) const override{};
std::vector<AnimNode*>& anim_nodes) override {
anim_nodes.push_back(this);
};
virtual void DrawDebugUi(); virtual void DrawDebugUi();
}; };

View File

@ -60,11 +60,10 @@ struct BlendNode : public AnimNode {
virtual void Evaluate( virtual void Evaluate(
ozz::vector<ozz::math::SoaTransform>* local_matrices) override; ozz::vector<ozz::math::SoaTransform>* local_matrices) override;
virtual void CollectNodeOrdering (std::vector<AnimNode*>& anim_nodes) override { virtual void GetInputNodes(std::vector<AnimNode*>& input_nodes) const override {
anim_nodes.push_back(this); input_nodes.push_back(m_input_A);
m_input_A->CollectNodeOrdering(anim_nodes); input_nodes.push_back(m_input_B);
m_input_B->CollectNodeOrdering(anim_nodes); };
}
virtual void DrawDebugUi(); virtual void DrawDebugUi();
}; };

View File

@ -43,11 +43,9 @@ struct SpeedScaleNode : public AnimNode {
m_input_node->Evaluate(local_matrices); m_input_node->Evaluate(local_matrices);
}; };
virtual void CollectNodeOrdering( virtual void GetInputNodes(std::vector<AnimNode*>& input_nodes) const override {
std::vector<AnimNode*>& anim_nodes) override { input_nodes.push_back(m_input_node);
anim_nodes.push_back(this); };
m_input_node->CollectNodeOrdering(anim_nodes);
}
virtual void DrawDebugUi() override; virtual void DrawDebugUi() override;
}; };

View File

@ -9,6 +9,8 @@
#include <ozz/animation/runtime/local_to_model_job.h> #include <ozz/animation/runtime/local_to_model_job.h>
#include <ozz/animation/runtime/sampling_job.h> #include <ozz/animation/runtime/sampling_job.h>
#include <queue>
#include "AnimNodes/AnimSamplerNode.h" #include "AnimNodes/AnimSamplerNode.h"
#include "AnimNodes/BlendNode.h" #include "AnimNodes/BlendNode.h"
#include "AnimNodes/SpeedScaleNode.h" #include "AnimNodes/SpeedScaleNode.h"
@ -23,8 +25,6 @@ AnimationController::AnimationController(SkinnedMesh* skinned_mesh)
m_local_matrices.resize(num_soa_joints); 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(); ResetAnims();
AnimSamplerNode* sampler_node0 = new AnimSamplerNode(this); AnimSamplerNode* sampler_node0 = new AnimSamplerNode(this);
@ -56,7 +56,7 @@ AnimationController::AnimationController(SkinnedMesh* skinned_mesh)
m_output_node = speed_node1; m_output_node = speed_node1;
m_output_node->CollectNodeOrdering(m_ordered_nodes); UpdateOrderedNodes();
m_output_node->Reset(); m_output_node->Reset();
} }
@ -78,13 +78,34 @@ void AnimationController::ResetAnims() {
} }
} }
void AnimationController::UpdateOrderedNodes() {
std::vector<AnimNode*> 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<AnimNode*> 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) { void AnimationController::Update(float dt) {
if (m_output_node == nullptr) { if (m_output_node == nullptr) {
return; return;
} }
// Mark all nodes that evaluate time using sync tracks.
m_output_node->UpdateIsSynced(false); 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--) { for (int i = m_ordered_nodes.size() - 1; i >= 0; i--) {
AnimNode* node = m_ordered_nodes[i]; AnimNode* node = m_ordered_nodes[i];
if (node->m_is_time_synced) { 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); m_output_node->UpdateTime(dt);
} }

View File

@ -18,13 +18,15 @@ struct AnimationController {
explicit AnimationController(SkinnedMesh* skinned_mesh); explicit AnimationController(SkinnedMesh* skinned_mesh);
virtual ~AnimationController(); virtual ~AnimationController();
void SetBlendAnims(
ozz::animation::Animation* blend_anim_A,
ozz::animation::Animation* blend_anim_B) {
}
void ResetAnims(); 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); void Update(float dt);
// Recursively evaluates all nodes.
void Evaluate(); void Evaluate();
void DrawDebugUi(); void DrawDebugUi();