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())
|
||||
{
|
||||
@ -75,7 +75,9 @@ void game::MeshInstance::PlayAnim(const std::string& name)
|
||||
const auto& skeleton = mesh_->GetSkeleton();
|
||||
|
||||
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()
|
||||
@ -119,28 +121,42 @@ const gfx::UniformBuffer<glm::mat4>& game::MeshInstance::GetBoneUBO()
|
||||
|
||||
void game::MeshInstance::ApplyAnimFrame()
|
||||
{
|
||||
ApplySkelAnim(current_anim_, anim_time_, 1.0f);
|
||||
if (!current_anim_)
|
||||
{
|
||||
return; // No animation to apply
|
||||
}
|
||||
|
||||
float anim_time = *time_ptr_ - anim_start_;
|
||||
float anim_duration = current_anim_->GetDuration();
|
||||
|
||||
if (!(anim_flags_ & ANIM_LOOP) && anim_time >= anim_duration)
|
||||
{
|
||||
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)
|
||||
void game::MeshInstance::ApplySkelAnim(const assets::Animation& anim, float time, float weight)
|
||||
{
|
||||
float anim_frame = (*time_ptr_ - time) * anim->GetTPS();
|
||||
float anim_frame = time * anim.GetTPS();
|
||||
|
||||
if (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 frame0 = frame_i % num_anim_frames;
|
||||
size_t frame1 = (frame_i + 1) % num_anim_frames;
|
||||
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];
|
||||
|
||||
const Transform* t0 = channel.frames[frame0];
|
||||
|
||||
@ -6,6 +6,11 @@
|
||||
|
||||
namespace game
|
||||
{
|
||||
enum PlayAnimFlags
|
||||
{
|
||||
ANIM_LOOP = 1 << 0,
|
||||
};
|
||||
|
||||
class MeshInstance
|
||||
{
|
||||
std::shared_ptr<const assets::Mesh> mesh_;
|
||||
@ -20,14 +25,16 @@ namespace game
|
||||
bool bone_ubo_dirty_ = true;
|
||||
|
||||
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:
|
||||
MeshInstance(std::shared_ptr<const assets::Mesh> mesh, const TransformNode* root_node, const float* time_ptr);
|
||||
|
||||
bool IsSkeletal() const { return skeletal_; }
|
||||
|
||||
void PlayAnim(const std::string& name);
|
||||
void PlayAnim(const std::string& name, int flags = 0);
|
||||
|
||||
void Update();
|
||||
|
||||
@ -38,6 +45,8 @@ namespace game
|
||||
const TransformNode& GetBoneNode(size_t index) const { return bone_nodes_[index]; }
|
||||
const TransformNode* GetBoneNodeByName(const std::string& name) const;
|
||||
|
||||
bool AnimDone() const { return anim_done_; }
|
||||
|
||||
private:
|
||||
void SetupBoneNodes();
|
||||
void UpdateBoneMatrices();
|
||||
@ -47,7 +56,7 @@ namespace game
|
||||
virtual void ApplyAnimFrame();
|
||||
|
||||
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