From 63041d5b7091adfb01e2507630c685af26f9e166 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sat, 12 Mar 2022 13:55:12 -0500 Subject: [PATCH] CAnimSource: Fixes for frame interpolation --- Runtime/Character/CAnimSource.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Runtime/Character/CAnimSource.cpp b/Runtime/Character/CAnimSource.cpp index 689bf6380..b3bef0e07 100644 --- a/Runtime/Character/CAnimSource.cpp +++ b/Runtime/Character/CAnimSource.cpp @@ -45,7 +45,7 @@ std::unique_ptr RotationAndOffsetStorage::GetRotationsAndOffsets(const const std::vector& offs, u32 frameCount) { u32 size = DataSizeInBytes(rots.size() / frameCount, offs.size() / frameCount, frameCount); - std::unique_ptr ret(new float[(size / 4 + 1) * 4]); + auto ret = std::make_unique((size / 4 + 1) * 4); CopyRotationsAndOffsets(rots, offs, frameCount, ret.get()); return ret; } @@ -118,6 +118,7 @@ CAnimSource::CAnimSource(CInputStream& in, IObjectStore& store) void CAnimSource::GetSegStatementSet(const CSegIdList& list, CSegStatementSet& set, const CCharAnimTime& time) const { const auto frameIdx = u32(time / x8_interval); + const auto nextFrameIdx = (frameIdx + 1) % x10_frameCount; float remTime = time.GetSeconds() - frameIdx * x8_interval.GetSeconds(); if (std::fabs(remTime) < 0.00001f) { remTime = 0.f; @@ -131,7 +132,7 @@ void CAnimSource::GetSegStatementSet(const CSegIdList& list, CSegStatementSet& s const u8 rotIdx = x20_rotationChannels[id]; if (rotIdx != 0xff) { const float* frameDataA = &x40_data.x0_storage[frameIdx * floatsPerFrame + rotIdx * 4]; - const float* frameDataB = &x40_data.x0_storage[(frameIdx + 1) * floatsPerFrame + rotIdx * 4]; + const float* frameDataB = &x40_data.x0_storage[nextFrameIdx * floatsPerFrame + rotIdx * 4]; const zeus::CQuaternion quatA(frameDataA[0], frameDataA[1], frameDataA[2], frameDataA[3]); const zeus::CQuaternion quatB(frameDataB[0], frameDataB[1], frameDataB[2], frameDataB[3]); @@ -141,7 +142,7 @@ void CAnimSource::GetSegStatementSet(const CSegIdList& list, CSegStatementSet& s if (transIdx != 0xff) { const float* frameVecDataA = &x40_data.x0_storage[frameIdx * floatsPerFrame + rotFloatsPerFrame + transIdx * 3]; const float* frameVecDataB = - &x40_data.x0_storage[(frameIdx - 1) * floatsPerFrame + rotFloatsPerFrame + transIdx * 3]; + &x40_data.x0_storage[nextFrameIdx * floatsPerFrame + rotFloatsPerFrame + transIdx * 3]; const zeus::CVector3f vecA(frameVecDataA[0], frameVecDataA[1], frameVecDataA[2]); const zeus::CVector3f vecB(frameVecDataB[0], frameVecDataB[1], frameVecDataB[2]); set[id].x10_offset = zeus::CVector3f::lerp(vecA, vecB, t); @@ -164,7 +165,8 @@ const std::vector& CAnimSource::GetBoolPOIStream() const { return zeus::CQuaternion CAnimSource::GetRotation(const CSegId& seg, const CCharAnimTime& time) const { u8 rotIdx = x20_rotationChannels[seg]; if (rotIdx != 0xff) { - u32 frameIdx = unsigned(time / x8_interval); + const auto frameIdx = u32(time / x8_interval); + const auto nextFrameIdx = (frameIdx + 1) % x10_frameCount; float remTime = time.GetSeconds() - frameIdx * x8_interval.GetSeconds(); if (std::fabs(remTime) < 0.00001f) remTime = 0.f; @@ -172,7 +174,7 @@ zeus::CQuaternion CAnimSource::GetRotation(const CSegId& seg, const CCharAnimTim const u32 floatsPerFrame = x40_data.x10_transPerFrame * 3 + x40_data.xc_rotPerFrame * 4; const float* frameDataA = &x40_data.x0_storage[frameIdx * floatsPerFrame + rotIdx * 4]; - const float* frameDataB = &x40_data.x0_storage[(frameIdx + 1) * floatsPerFrame + rotIdx * 4]; + const float* frameDataB = &x40_data.x0_storage[nextFrameIdx * floatsPerFrame + rotIdx * 4]; zeus::CQuaternion quatA(frameDataA[0], frameDataA[1], frameDataA[2], frameDataA[3]); zeus::CQuaternion quatB(frameDataB[0], frameDataB[1], frameDataB[2], frameDataB[3]); @@ -189,7 +191,8 @@ zeus::CVector3f CAnimSource::GetOffset(const CSegId& seg, const CCharAnimTime& t if (transIdx == 0xff) return {}; - u32 frameIdx = unsigned(time / x8_interval); + const auto frameIdx = u32(time / x8_interval); + const auto nextFrameIdx = (frameIdx + 1) % x10_frameCount; float remTime = time.GetSeconds() - frameIdx * x8_interval.GetSeconds(); if (std::fabs(remTime) < 0.00001f) remTime = 0.f; @@ -198,7 +201,7 @@ zeus::CVector3f CAnimSource::GetOffset(const CSegId& seg, const CCharAnimTime& t const u32 floatsPerFrame = x40_data.x10_transPerFrame * 3 + x40_data.xc_rotPerFrame * 4; const u32 rotFloatsPerFrame = x40_data.xc_rotPerFrame * 4; const float* frameDataA = &x40_data.x0_storage[frameIdx * floatsPerFrame + rotFloatsPerFrame + transIdx * 3]; - const float* frameDataB = &x40_data.x0_storage[(frameIdx - 1) * floatsPerFrame + rotFloatsPerFrame + transIdx * 3]; + const float* frameDataB = &x40_data.x0_storage[nextFrameIdx * floatsPerFrame + rotFloatsPerFrame + transIdx * 3]; zeus::CVector3f vecA(frameDataA[0], frameDataA[1], frameDataA[2]); zeus::CVector3f vecB(frameDataB[0], frameDataB[1], frameDataB[2]); return zeus::CVector3f::lerp(vecA, vecB, t);