87 lines
2.7 KiB
C++
87 lines
2.7 KiB
C++
#ifndef ANIMATOR_H
|
|
#define ANIMATOR_H
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include <glm/mat4x4.hpp>
|
|
|
|
#include <destrum/ObjectModel/Component.h>
|
|
#include <destrum/Graphics/Resources/Mesh.h>
|
|
#include <destrum/Graphics/SkeletalAnimation.h>
|
|
|
|
class SkinningPipeline;
|
|
|
|
class Animator final: public Component {
|
|
public:
|
|
explicit Animator(GameObject& parent);
|
|
|
|
using Component::Update;
|
|
void Update(float dt) override;
|
|
std::string GetTypeName() const override
|
|
{
|
|
return "Animator";
|
|
}
|
|
nlohmann::json Serialize() const override;
|
|
void Deserialize(const nlohmann::json& data) override;
|
|
void ImGuiInspector() override;
|
|
|
|
// The source reference is carried by the AssetManager-loaded clip.
|
|
void addClip(std::shared_ptr<SkeletalAnimation> clip);
|
|
void play(const std::string& name, float blendTime = 0.f);
|
|
void stop();
|
|
|
|
[[nodiscard]] bool isPlaying() const { return m_current.clip != nullptr; }
|
|
[[nodiscard]] const std::string& currentClipName() const { return m_currentClipName; }
|
|
[[nodiscard]] float currentTime() const { return m_current.time; }
|
|
|
|
std::size_t uploadJointMatrices(const RenderContext& ctx, const Skeleton& skeleton, std::size_t frameIndex);
|
|
Skeleton* getSkeleton() {
|
|
return &m_skeleton;
|
|
}
|
|
|
|
// A source reference is required when this Animator is saved to a scene.
|
|
void setSkeleton(Skeleton skeleton) {
|
|
m_skeletonAsset = skeleton.assetReference;
|
|
m_skeleton = std::move(skeleton);
|
|
m_referencesResolved = true;
|
|
}
|
|
|
|
void ResolveReferences(const ObjectMap& objects) override;
|
|
|
|
private:
|
|
struct PlaybackState {
|
|
SkeletalAnimation* clip = nullptr;
|
|
float time = 0.f;
|
|
float speed = 1.f;
|
|
};
|
|
|
|
Skeleton m_skeleton{};
|
|
|
|
PlaybackState m_current;
|
|
PlaybackState m_previous;
|
|
float m_blendT = 0.f;
|
|
float m_blendDuration = 0.f;
|
|
std::string m_currentClipName;
|
|
std::string m_previousClipName;
|
|
|
|
std::unordered_map<std::string, std::shared_ptr<SkeletalAnimation>> m_clips;
|
|
std::vector<std::string> m_clipOrder;
|
|
std::unordered_map<std::string, AssetReference> m_clipAssets;
|
|
AssetReference m_skeletonAsset;
|
|
bool m_referencesResolved{true};
|
|
|
|
std::vector<glm::mat4> computeJointMatrices(const Skeleton& skeleton);
|
|
|
|
glm::vec3 sampleTranslation(const SkeletalAnimation::Track& track, float t);
|
|
glm::quat sampleRotation (const SkeletalAnimation::Track& track, float t);
|
|
glm::vec3 sampleScale (const SkeletalAnimation::Track& track, float t);
|
|
|
|
void RestorePlaybackState(const nlohmann::json& data);
|
|
void LoadAssetReferences();
|
|
};
|
|
|
|
#endif // ANIMATOR_H
|