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"
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<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; }
// 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<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(){};
};

View File

@ -22,6 +22,7 @@ struct AnimSamplerNode : public AnimNode {
bool m_override_ratio;
float m_anim_ratio;
ozz::vector<ozz::math::SoaTransform> 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<ozz::math::SoaTransform>* local_matrices) override;
virtual void CollectNodeOrdering(
std::vector<AnimNode*>& anim_nodes) override {
anim_nodes.push_back(this);
};
virtual void GetInputNodes(std::vector<AnimNode*>& input_nodes) const override{};
virtual void DrawDebugUi();
};

View File

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

View File

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

View File

@ -9,6 +9,8 @@
#include <ozz/animation/runtime/local_to_model_job.h>
#include <ozz/animation/runtime/sampling_job.h>
#include <queue>
#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<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) {
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);
}

View File

@ -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();