Modified SHAnimationComponent to handle interpolation of separate position, rotation and scale keyframes
This commit is contained in:
parent
7bf0c26052
commit
e9624977cd
|
@ -20,8 +20,8 @@ namespace SHADE
|
|||
/* Constructors */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHAnimationClip::SHAnimationClip(const SHAnimAsset& asset)
|
||||
: ticksPerSecond { asset.ticksPerSecond }
|
||||
, totalTime { asset.duration }
|
||||
: ticksPerSecond { static_cast<int>(asset.ticksPerSecond) }
|
||||
, totalTime { static_cast<float>(asset.duration) }
|
||||
{
|
||||
// Populate keyframes
|
||||
for (const auto& channel : asset.nodeChannels)
|
||||
|
@ -47,6 +47,8 @@ namespace SHADE
|
|||
newChannel.ScaleKeyFrames.emplace_back(SHAnimationKeyFrame<SHVec3>{ static_cast<int>(scaleKey.time), scaleKey.value});
|
||||
}
|
||||
|
||||
newChannel.MaxFrames = std::max({ newChannel.PositionKeyFrames.size(), newChannel.RotationKeyFrames.size(), newChannel.ScaleKeyFrames.size() });
|
||||
|
||||
// Insert the channel
|
||||
channels.emplace_back(std::move(newChannel));
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ namespace SHADE
|
|||
std::vector<SHAnimationKeyFrame<SHVec3>> PositionKeyFrames;
|
||||
std::vector<SHAnimationKeyFrame<SHQuaternion>> RotationKeyFrames;
|
||||
std::vector<SHAnimationKeyFrame<SHVec3>> ScaleKeyFrames;
|
||||
int MaxFrames;
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -83,6 +83,7 @@ namespace SHADE
|
|||
return;
|
||||
|
||||
currClip = newClip;
|
||||
secsPerTick = 1.0f / currClip->GetTicksPerSecond();
|
||||
updatePoseWithClip(0.0f);
|
||||
}
|
||||
|
||||
|
@ -135,36 +136,74 @@ namespace SHADE
|
|||
bones.push(child);
|
||||
}
|
||||
|
||||
// Get interpolated frame
|
||||
auto firstKeyFrame = channel.KeyFrames.end();
|
||||
auto nextKeyFrame = channel.KeyFrames.end();
|
||||
for (auto iter = channel.KeyFrames.begin(); iter != channel.KeyFrames.end(); ++iter)
|
||||
{
|
||||
const auto& KEYFRAME = *iter;
|
||||
|
||||
if(KEYFRAME.TimeStamp <= poseTime)
|
||||
{
|
||||
firstKeyFrame = iter;
|
||||
}
|
||||
else if (KEYFRAME.TimeStamp > poseTime)
|
||||
{
|
||||
nextKeyFrame = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Calculate the matrix
|
||||
// Get closest frame index
|
||||
const int CLOSEST_FRAME_IDX = static_cast<int>(std::floorf(poseTime * currClip->GetTicksPerSecond()));
|
||||
|
||||
// Calculate the matrix from interpolated values
|
||||
const int BONE_MTX_IDX = rig->GetNodeIndex(bone);
|
||||
const float T = (poseTime - firstKeyFrame->TimeStamp) / (nextKeyFrame->TimeStamp - firstKeyFrame->TimeStamp);
|
||||
boneMatrices[BONE_MTX_IDX] = boneMatrices[BONE_MTX_IDX] * SHMatrix::Transform
|
||||
(
|
||||
SHVec3::Lerp(firstKeyFrame->Position, nextKeyFrame->Position, T),
|
||||
SHQuaternion::Slerp(firstKeyFrame->Orientation, nextKeyFrame->Orientation, T),
|
||||
SHVec3::Lerp(firstKeyFrame->Scale, nextKeyFrame->Scale, T)
|
||||
getInterpolatedValue(channel.PositionKeyFrames, CLOSEST_FRAME_IDX, poseTime),
|
||||
getInterpolatedValue(channel.RotationKeyFrames, CLOSEST_FRAME_IDX, poseTime),
|
||||
getInterpolatedValue(channel.ScaleKeyFrames, CLOSEST_FRAME_IDX, poseTime)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SHVec3 SHAnimatorComponent::getInterpolatedValue(const std::vector<SHAnimationKeyFrame<SHVec3>>& keyframes, int closestFrameIndex, float poseTime)
|
||||
{
|
||||
// Find the key frames that surround the current frame index
|
||||
auto firstKeyFrame = keyframes.end();
|
||||
auto nextKeyFrame = keyframes.end();
|
||||
for (auto iter = keyframes.begin(); iter != keyframes.end(); ++iter)
|
||||
{
|
||||
const auto& KEYFRAME = *iter;
|
||||
|
||||
if (KEYFRAME.FrameIndex <= closestFrameIndex)
|
||||
{
|
||||
firstKeyFrame = iter;
|
||||
}
|
||||
else if (KEYFRAME.FrameIndex > closestFrameIndex)
|
||||
{
|
||||
nextKeyFrame = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get interpolated vector
|
||||
const float PREV_FRAME_TIME = firstKeyFrame->FrameIndex * secsPerTick;
|
||||
const float NEXT_FRAME_TIME = nextKeyFrame->FrameIndex * secsPerTick;
|
||||
const float T = (poseTime - PREV_FRAME_TIME) / (NEXT_FRAME_TIME - PREV_FRAME_TIME);
|
||||
return SHVec3::Lerp(firstKeyFrame->Data, nextKeyFrame->Data, T);
|
||||
}
|
||||
|
||||
SHQuaternion SHAnimatorComponent::getInterpolatedValue(const std::vector<SHAnimationKeyFrame<SHQuaternion>>& keyframes, int closestFrameIndex, float poseTime)
|
||||
{
|
||||
// Find the key frames that surround the current frame index
|
||||
auto firstKeyFrame = keyframes.end();
|
||||
auto nextKeyFrame = keyframes.end();
|
||||
for (auto iter = keyframes.begin(); iter != keyframes.end(); ++iter)
|
||||
{
|
||||
const auto& KEYFRAME = *iter;
|
||||
|
||||
if (KEYFRAME.FrameIndex <= closestFrameIndex)
|
||||
{
|
||||
firstKeyFrame = iter;
|
||||
}
|
||||
else if (KEYFRAME.FrameIndex > closestFrameIndex)
|
||||
{
|
||||
nextKeyFrame = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get interpolated vector
|
||||
const float PREV_FRAME_TIME = firstKeyFrame->FrameIndex * secsPerTick;
|
||||
const float NEXT_FRAME_TIME = nextKeyFrame->FrameIndex * secsPerTick;
|
||||
const float T = (poseTime - PREV_FRAME_TIME) / (NEXT_FRAME_TIME - PREV_FRAME_TIME);
|
||||
return SHQuaternion::Slerp(firstKeyFrame->Data, nextKeyFrame->Data, T);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -19,6 +19,9 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "ECS_Base/Components/SHComponent.h"
|
||||
#include "Resource/SHHandle.h"
|
||||
#include "Math/SHMatrix.h"
|
||||
#include "Math/Vector/SHVec3.h"
|
||||
#include "Math/SHQuaternion.h"
|
||||
#include "SHAnimationClip.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -119,6 +122,8 @@ namespace SHADE
|
|||
// Playback Tracking
|
||||
float currPlaybackTime = 0.0f;
|
||||
bool isPlaying = false;
|
||||
// Useful Cached Data
|
||||
float secsPerTick = 0.0f;
|
||||
// Buffer
|
||||
std::vector<SHMatrix> boneMatrices;
|
||||
|
||||
|
@ -126,6 +131,8 @@ namespace SHADE
|
|||
/* Helper Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void updatePoseWithClip(float poseTime);
|
||||
SHVec3 getInterpolatedValue(const std::vector<SHAnimationKeyFrame<SHVec3>>& keyframes, int closestFrameIndex, float poseTime);
|
||||
SHQuaternion getInterpolatedValue(const std::vector<SHAnimationKeyFrame<SHQuaternion>>& keyframes, int closestFrameIndex, float poseTime);
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* RTTR */
|
||||
|
|
Loading…
Reference in New Issue