From 43fd04dd5ea02e4199d4e38ce341cfa2e0eff2ff Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 6 Mar 2023 18:59:04 +0800 Subject: [PATCH] Modified SHAnimationClip and SHAnimatorComponent to use frame timestamps instead of indices --- SHADE_Engine/src/Animation/SHAnimationClip.cpp | 6 +++--- SHADE_Engine/src/Animation/SHAnimationClip.h | 4 ++-- SHADE_Engine/src/Animation/SHAnimatorComponent.cpp | 14 ++++++-------- SHADE_Engine/src/Animation/SHAnimatorComponent.h | 4 ++-- SHADE_Engine/src/Animation/SHAnimatorComponent.hpp | 10 +++++----- .../Graphics/MiddleEnd/Textures/SHTextureLibrary.h | 2 +- 6 files changed, 19 insertions(+), 21 deletions(-) diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.cpp b/SHADE_Engine/src/Animation/SHAnimationClip.cpp index e1a67be8..b1745ed2 100644 --- a/SHADE_Engine/src/Animation/SHAnimationClip.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationClip.cpp @@ -36,15 +36,15 @@ namespace SHADE // Populate Keyframes for (const auto& posKey : channel.positionKeys) { - newChannel.PositionKeyFrames.emplace_back(SHAnimationKeyFrame{ static_cast(posKey.time), posKey.value}); + newChannel.PositionKeyFrames.emplace_back(SHAnimationKeyFrame{ posKey.time, posKey.value}); } for (const auto& rotKey : channel.rotationKeys) { - newChannel.RotationKeyFrames.emplace_back(SHAnimationKeyFrame{ static_cast(rotKey.time), rotKey.value}); + newChannel.RotationKeyFrames.emplace_back(SHAnimationKeyFrame{ rotKey.time, rotKey.value}); } for (const auto& scaleKey : channel.scaleKeys) { - newChannel.ScaleKeyFrames.emplace_back(SHAnimationKeyFrame{ static_cast(scaleKey.time), scaleKey.value}); + newChannel.ScaleKeyFrames.emplace_back(SHAnimationKeyFrame{ scaleKey.time, scaleKey.value }); } newChannel.MaxFrames = std::max({ newChannel.PositionKeyFrames.size(), newChannel.RotationKeyFrames.size(), newChannel.ScaleKeyFrames.size() }); diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.h b/SHADE_Engine/src/Animation/SHAnimationClip.h index bf70c980..03d6eee6 100644 --- a/SHADE_Engine/src/Animation/SHAnimationClip.h +++ b/SHADE_Engine/src/Animation/SHAnimationClip.h @@ -27,8 +27,8 @@ namespace SHADE template struct SHAnimationKeyFrame { - int FrameIndex; - T Data; + float TimeStamp; + T Data; }; /// diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp index 355ca787..04d355b8 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp @@ -124,12 +124,10 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ void SHAnimatorComponent::updatePoseWithClip(float poseTime) { - // Get closest frame index - const int CLOSEST_FRAME_IDX = static_cast(std::floorf(poseTime * currClip->GetTicksPerSecond())); - updatePoseWithClip(CLOSEST_FRAME_IDX, poseTime, rig->GetRootNode(), SHMatrix::Identity); + updatePoseWithClip(poseTime, rig->GetRootNode(), SHMatrix::Identity); } - void SHAnimatorComponent::updatePoseWithClip(int closestFrameIndex, float poseTime, Handle node, const SHMatrix& parentMatrix) + void SHAnimatorComponent::updatePoseWithClip(float poseTime, Handle node, const SHMatrix& parentMatrix) { // Check if there is a channel for this node SHMatrix transformMatrix = node->TransformMatrix; @@ -140,9 +138,9 @@ namespace SHADE const auto& CHANNEL = CHANNELS[BONE_IDX]; transformMatrix = SHMatrix::Transform ( - getInterpolatedValue(CHANNEL.PositionKeyFrames, closestFrameIndex, poseTime), - getInterpolatedValue(CHANNEL.RotationKeyFrames, closestFrameIndex, poseTime), - getInterpolatedValue(CHANNEL.ScaleKeyFrames, closestFrameIndex, poseTime) + getInterpolatedValue(CHANNEL.PositionKeyFrames, poseTime), + getInterpolatedValue(CHANNEL.RotationKeyFrames, poseTime), + getInterpolatedValue(CHANNEL.ScaleKeyFrames, poseTime) ); } @@ -160,7 +158,7 @@ namespace SHADE // Apply pose to children for (auto& child : node->Children) { - updatePoseWithClip(closestFrameIndex, poseTime, child, transformMatrix); + updatePoseWithClip(poseTime, child, transformMatrix); } } } diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.h b/SHADE_Engine/src/Animation/SHAnimatorComponent.h index e9b6c501..d6c05135 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.h +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.h @@ -139,9 +139,9 @@ namespace SHADE /* Helper Functions */ /*---------------------------------------------------------------------------------*/ void updatePoseWithClip(float poseTime); - void updatePoseWithClip(int closestFrameIndex, float poseTime, Handle node, const SHMatrix& parentMatrix); + void updatePoseWithClip(float poseTime, Handle node, const SHMatrix& parentMatrix); template - T getInterpolatedValue(const std::vector>& keyframes, int closestFrameIndex, float poseTime); + T getInterpolatedValue(const std::vector>& keyframes, float poseTime); /*---------------------------------------------------------------------------------*/ /* RTTR */ diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp index 9c6a5d3a..82ed0600 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp @@ -26,7 +26,7 @@ namespace SHADE /* Helper Functions */ /*-----------------------------------------------------------------------------------*/ template - T SHAnimatorComponent::getInterpolatedValue(const std::vector>& keyframes, int closestFrameIndex, float poseTime) + T SHAnimatorComponent::getInterpolatedValue(const std::vector>& keyframes, float poseTime) { // Only allow SHVec3 and SHQuaternion static_assert(std::is_same_v || std::is_same_v, "Only interpolation for SHVec3 and SHQuaternion is allowed."); @@ -38,11 +38,11 @@ namespace SHADE { const auto& KEYFRAME = *iter; - if (KEYFRAME.FrameIndex <= closestFrameIndex) + if (KEYFRAME.TimeStamp <= poseTime) { firstKeyFrame = iter; } - else // KEYFRAME.FrameIndex > closestFrameIndex + else // KEYFRAME.FrameIndex > poseTime { nextKeyFrame = iter; break; @@ -66,8 +66,8 @@ namespace SHADE } // Get interpolated vector - const float PREV_FRAME_TIME = firstKeyFrame->FrameIndex * secsPerTick; - const float NEXT_FRAME_TIME = nextKeyFrame->FrameIndex * secsPerTick; + const float PREV_FRAME_TIME = firstKeyFrame->TimeStamp; + const float NEXT_FRAME_TIME = nextKeyFrame->TimeStamp; const float NORMALISED_TIME = (poseTime - PREV_FRAME_TIME) / (NEXT_FRAME_TIME - PREV_FRAME_TIME); if constexpr (std::is_same_v) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h index bbc72a1a..e1c93349 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h @@ -71,7 +71,7 @@ namespace SHADE //! of the texture library would mean the recreation of the desc set that also //! involves the generic data, which is bad bad bad. Solution is to separate the //! 2 desc sets. - static constexpr uint32_t DEFAULT_MAX_TEXTURES = 2000; + static constexpr uint32_t DEFAULT_MAX_TEXTURES = 1000; /*-----------------------------------------------------------------------------*/ /* Usage Functions */