Enhance anim playback
This commit is contained in:
parent
251871c776
commit
e982cd73a8
@ -65,7 +65,7 @@ void game::MeshInstance::UpdateBoneMatrices()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void game::MeshInstance::PlayAnim(const std::string& name)
|
void game::MeshInstance::PlayAnim(const std::string& name, int flags)
|
||||||
{
|
{
|
||||||
if (!IsSkeletal())
|
if (!IsSkeletal())
|
||||||
{
|
{
|
||||||
@ -75,7 +75,9 @@ void game::MeshInstance::PlayAnim(const std::string& name)
|
|||||||
const auto& skeleton = mesh_->GetSkeleton();
|
const auto& skeleton = mesh_->GetSkeleton();
|
||||||
|
|
||||||
current_anim_ = skeleton->GetAnimation(name); // Can be nullptr
|
current_anim_ = skeleton->GetAnimation(name); // Can be nullptr
|
||||||
anim_time_ = 0.0f;
|
anim_start_ = *time_ptr_;
|
||||||
|
anim_flags_ = flags;
|
||||||
|
anim_done_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void game::MeshInstance::Update()
|
void game::MeshInstance::Update()
|
||||||
@ -119,28 +121,42 @@ const gfx::UniformBuffer<glm::mat4>& game::MeshInstance::GetBoneUBO()
|
|||||||
|
|
||||||
void game::MeshInstance::ApplyAnimFrame()
|
void game::MeshInstance::ApplyAnimFrame()
|
||||||
{
|
{
|
||||||
ApplySkelAnim(current_anim_, anim_time_, 1.0f);
|
if (!current_anim_)
|
||||||
|
{
|
||||||
|
return; // No animation to apply
|
||||||
}
|
}
|
||||||
|
|
||||||
void game::MeshInstance::ApplySkelAnim(const assets::Animation* anim, float time, float weight)
|
float anim_time = *time_ptr_ - anim_start_;
|
||||||
|
float anim_duration = current_anim_->GetDuration();
|
||||||
|
|
||||||
|
if (!(anim_flags_ & ANIM_LOOP) && anim_time >= anim_duration)
|
||||||
{
|
{
|
||||||
float anim_frame = (*time_ptr_ - time) * anim->GetTPS();
|
anim_done_ = true;
|
||||||
|
anim_time = anim_duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplySkelAnim(*current_anim_, anim_time, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void game::MeshInstance::ApplySkelAnim(const assets::Animation& anim, float time, float weight)
|
||||||
|
{
|
||||||
|
float anim_frame = time * anim.GetTPS();
|
||||||
|
|
||||||
if (anim_frame < 0.0f)
|
if (anim_frame < 0.0f)
|
||||||
{
|
{
|
||||||
anim_frame = 0.0f;
|
anim_frame = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t num_anim_frames = anim->GetNumFrames();
|
size_t num_anim_frames = anim.GetNumFrames();
|
||||||
|
|
||||||
size_t frame_i = static_cast<size_t>(anim_frame);
|
size_t frame_i = static_cast<size_t>(anim_frame);
|
||||||
size_t frame0 = frame_i % num_anim_frames;
|
size_t frame0 = frame_i % num_anim_frames;
|
||||||
size_t frame1 = (frame_i + 1) % num_anim_frames;
|
size_t frame1 = (frame_i + 1) % num_anim_frames;
|
||||||
float t = anim_frame - static_cast<float>(frame_i);
|
float t = anim_frame - static_cast<float>(frame_i);
|
||||||
|
|
||||||
for (size_t i = 0; i < anim->GetNumChannels(); ++i)
|
for (size_t i = 0; i < anim.GetNumChannels(); ++i)
|
||||||
{
|
{
|
||||||
const assets::AnimationChannel& channel = anim->GetChannel(i);
|
const assets::AnimationChannel& channel = anim.GetChannel(i);
|
||||||
TransformNode& node = bone_nodes_[channel.bone_index];
|
TransformNode& node = bone_nodes_[channel.bone_index];
|
||||||
|
|
||||||
const Transform* t0 = channel.frames[frame0];
|
const Transform* t0 = channel.frames[frame0];
|
||||||
|
|||||||
@ -6,6 +6,11 @@
|
|||||||
|
|
||||||
namespace game
|
namespace game
|
||||||
{
|
{
|
||||||
|
enum PlayAnimFlags
|
||||||
|
{
|
||||||
|
ANIM_LOOP = 1 << 0,
|
||||||
|
};
|
||||||
|
|
||||||
class MeshInstance
|
class MeshInstance
|
||||||
{
|
{
|
||||||
std::shared_ptr<const assets::Mesh> mesh_;
|
std::shared_ptr<const assets::Mesh> mesh_;
|
||||||
@ -20,14 +25,16 @@ namespace game
|
|||||||
bool bone_ubo_dirty_ = true;
|
bool bone_ubo_dirty_ = true;
|
||||||
|
|
||||||
const assets::Animation* current_anim_ = nullptr;
|
const assets::Animation* current_anim_ = nullptr;
|
||||||
float anim_time_ = 0.0f;
|
float anim_start_ = 0.0f;
|
||||||
|
int anim_flags_ = 0;
|
||||||
|
bool anim_done_ = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MeshInstance(std::shared_ptr<const assets::Mesh> mesh, const TransformNode* root_node, const float* time_ptr);
|
MeshInstance(std::shared_ptr<const assets::Mesh> mesh, const TransformNode* root_node, const float* time_ptr);
|
||||||
|
|
||||||
bool IsSkeletal() const { return skeletal_; }
|
bool IsSkeletal() const { return skeletal_; }
|
||||||
|
|
||||||
void PlayAnim(const std::string& name);
|
void PlayAnim(const std::string& name, int flags = 0);
|
||||||
|
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
@ -38,6 +45,8 @@ namespace game
|
|||||||
const TransformNode& GetBoneNode(size_t index) const { return bone_nodes_[index]; }
|
const TransformNode& GetBoneNode(size_t index) const { return bone_nodes_[index]; }
|
||||||
const TransformNode* GetBoneNodeByName(const std::string& name) const;
|
const TransformNode* GetBoneNodeByName(const std::string& name) const;
|
||||||
|
|
||||||
|
bool AnimDone() const { return anim_done_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetupBoneNodes();
|
void SetupBoneNodes();
|
||||||
void UpdateBoneMatrices();
|
void UpdateBoneMatrices();
|
||||||
@ -47,7 +56,7 @@ namespace game
|
|||||||
virtual void ApplyAnimFrame();
|
virtual void ApplyAnimFrame();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ApplySkelAnim(const assets::Animation* anim, float time, float weight);
|
void ApplySkelAnim(const assets::Animation& anim, float time, float weight);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user