SleakEngine 1.0.0
C++23 multi-backend game engine
Loading...
Searching...
No Matches
AnimatorComponent.hpp
Go to the documentation of this file.
1#ifndef _ANIMATORCOMPONENT_HPP_
2#define _ANIMATORCOMPONENT_HPP_
3
4#include <ECS/Component.hpp>
7#include <Memory/RefPtr.hpp>
8#include <Math/Matrix.hpp>
9#include <vector>
10#include <string>
11
12namespace Sleak {
13
14 namespace RenderEngine {
15 class BufferBase;
16 }
17
19
20 /// Samples a skeleton's bones from clips or a state machine and uploads
21 /// the result to the sibling MeshComponent's bone buffer each frame.
22 /// @ingroup scene
23 class ENGINE_API AnimatorComponent : public Component {
24 public:
26 std::vector<AnimationClip*> clips);
27 virtual ~AnimatorComponent();
28
29 /// Allocates the bone constant buffer and attaches it to the sibling MeshComponent.
30 virtual bool Initialize() override;
31 /// Samples the active state machine or clip and pushes the resulting bone matrices to the GPU.
32 virtual void Update(float deltaTime) override;
33
34 // Animation control
35 /// Switches to the clip by name, restarting from time zero.
36 void Play(const std::string& clipName, bool loop = true);
37 /// Switches to the clip by index, restarting from time zero.
38 void Play(int clipIndex, bool loop = true);
39 void Stop();
40 void Pause();
41 void Resume();
42 void SetSpeed(float speed);
43 float GetSpeed() const;
44 bool IsPlaying() const;
45 float GetCurrentTime() const;
46 const std::string& GetCurrentClipName() const;
47
48 // State machine
49 /// Replaces any existing state machine with a fresh, empty one.
51 AnimationStateMachine* GetStateMachine() const { return m_stateMachine; }
52
53 // Clip management
54 void AddClip(AnimationClip* clip);
55 Skeleton* GetSkeleton() const { return m_skeleton; }
56 const std::vector<AnimationClip*>& GetClips() const { return m_clips; }
57
58 // Get the bone matrix buffer for MeshComponent attachment
59 RefPtr<RenderEngine::BufferBase> GetBoneBuffer() const;
60
61 private:
62 // Compute bone transforms for a specific clip/time into output buffer
63 /// Walks the skeleton's node tree for clip at animTime, writing final bone matrices to outMatrices.
64 void ComputeBoneTransformsForClip(AnimationClip* clip, float animTime,
65 std::vector<Math::Matrix4>& outMatrices);
66 /// Recursive step of ComputeBoneTransformsForClip, propagating parentTransform down the hierarchy.
67 void ProcessNodeHierarchyForClip(int nodeIndex, const Math::Matrix4& parentTransform,
68 AnimationClip* clip, float animTime,
69 std::vector<Math::Matrix4>& outMatrices);
70
71 // Legacy single-clip path
72 /// Same as ComputeBoneTransformsForClip but samples m_clips[m_currentClip] into m_boneMatrices.
73 void ComputeBoneTransforms(float animTime);
74 /// Recursive step of ComputeBoneTransforms.
75 void ProcessNodeHierarchy(int nodeIndex, const Math::Matrix4& parentTransform,
76 float animTime);
77
78 // Blend two sets of bone matrices
79 /// Linearly interpolates each matrix element between a and b, storing the result in out.
80 static void BlendBoneMatrices(const std::vector<Math::Matrix4>& a,
81 const std::vector<Math::Matrix4>& b,
82 float weight,
83 std::vector<Math::Matrix4>& out);
84
85 // Keyframe interpolation
86 Math::Vector3D InterpolatePosition(const AnimationChannel& channel, float time);
87 Math::Quaternion InterpolateRotation(const AnimationChannel& channel, float time);
88 Math::Vector3D InterpolateScale(const AnimationChannel& channel, float time);
89
90 // Quaternion slerp (engine doesn't have one)
91 static Math::Quaternion Slerp(const Math::Quaternion& a, const Math::Quaternion& b, float t);
92
93 Skeleton* m_skeleton;
94 std::vector<AnimationClip*> m_clips;
95
96 int m_currentClip = -1;
97 float m_currentTime = 0.0f;
98 float m_speed = 1.0f;
99 bool m_playing = false;
100 bool m_loop = true;
101
102 // Final bone matrices: finalMatrix[i] = globalInverse * globalTransform[i] * offsetMatrix[i]
103 std::vector<Math::Matrix4> m_boneMatrices;
104 std::vector<Math::Matrix4> m_boneMatricesB; // second pose for blending
106
107 // State machine (owned)
108 AnimationStateMachine* m_stateMachine = nullptr;
109 };
110
111} // namespace Sleak
112
113#endif // _ANIMATORCOMPONENT_HPP_
const std::string & GetCurrentClipName() const
AnimationStateMachine * GetStateMachine() const
AnimationStateMachine * CreateStateMachine()
Replaces any existing state machine with a fresh, empty one.
virtual void Update(float deltaTime) override
Samples the active state machine or clip and pushes the resulting bone matrices to the GPU.
Skeleton * GetSkeleton() const
AnimatorComponent(GameObject *owner, Skeleton *skeleton, std::vector< AnimationClip * > clips)
void Play(const std::string &clipName, bool loop=true)
Switches to the clip by name, restarting from time zero.
const std::vector< AnimationClip * > & GetClips() const
virtual bool Initialize() override
Allocates the bone constant buffer and attaches it to the sibling MeshComponent.
GameObject * owner
Definition Component.hpp:81
Component(GameObject *object)
Definition Component.hpp:61
Represents a quaternion for 3D rotations.
Backend-agnostic GPU buffer: vertex, index, constant, or resource view target.
Matrix< float, 4, 4 > Matrix4
Definition Matrix.hpp:413
Backend-facing rendering layer shared by the four graphics backends.
Root namespace for everything the engine exposes.
Definition Camera.hpp:10