CAnimSource: Fixes for frame interpolation

This commit is contained in:
Luke Street 2022-03-12 13:55:12 -05:00
parent d47ce662da
commit 63041d5b70
1 changed files with 10 additions and 7 deletions

View File

@ -45,7 +45,7 @@ std::unique_ptr<float[]> RotationAndOffsetStorage::GetRotationsAndOffsets(const
const std::vector<zeus::CVector3f>& offs, const std::vector<zeus::CVector3f>& offs,
u32 frameCount) { u32 frameCount) {
u32 size = DataSizeInBytes(rots.size() / frameCount, offs.size() / frameCount, frameCount); u32 size = DataSizeInBytes(rots.size() / frameCount, offs.size() / frameCount, frameCount);
std::unique_ptr<float[]> ret(new float[(size / 4 + 1) * 4]); auto ret = std::make_unique<float[]>((size / 4 + 1) * 4);
CopyRotationsAndOffsets(rots, offs, frameCount, ret.get()); CopyRotationsAndOffsets(rots, offs, frameCount, ret.get());
return ret; return ret;
} }
@ -118,6 +118,7 @@ CAnimSource::CAnimSource(CInputStream& in, IObjectStore& store)
void CAnimSource::GetSegStatementSet(const CSegIdList& list, CSegStatementSet& set, const CCharAnimTime& time) const { void CAnimSource::GetSegStatementSet(const CSegIdList& list, CSegStatementSet& set, const CCharAnimTime& time) const {
const auto frameIdx = u32(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(); float remTime = time.GetSeconds() - frameIdx * x8_interval.GetSeconds();
if (std::fabs(remTime) < 0.00001f) { if (std::fabs(remTime) < 0.00001f) {
remTime = 0.f; remTime = 0.f;
@ -131,7 +132,7 @@ void CAnimSource::GetSegStatementSet(const CSegIdList& list, CSegStatementSet& s
const u8 rotIdx = x20_rotationChannels[id]; const u8 rotIdx = x20_rotationChannels[id];
if (rotIdx != 0xff) { if (rotIdx != 0xff) {
const float* frameDataA = &x40_data.x0_storage[frameIdx * floatsPerFrame + rotIdx * 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];
const zeus::CQuaternion quatA(frameDataA[0], frameDataA[1], frameDataA[2], frameDataA[3]); const zeus::CQuaternion quatA(frameDataA[0], frameDataA[1], frameDataA[2], frameDataA[3]);
const zeus::CQuaternion quatB(frameDataB[0], frameDataB[1], frameDataB[2], frameDataB[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) { if (transIdx != 0xff) {
const float* frameVecDataA = &x40_data.x0_storage[frameIdx * floatsPerFrame + rotFloatsPerFrame + transIdx * 3]; const float* frameVecDataA = &x40_data.x0_storage[frameIdx * floatsPerFrame + rotFloatsPerFrame + transIdx * 3];
const float* frameVecDataB = 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 vecA(frameVecDataA[0], frameVecDataA[1], frameVecDataA[2]);
const zeus::CVector3f vecB(frameVecDataB[0], frameVecDataB[1], frameVecDataB[2]); const zeus::CVector3f vecB(frameVecDataB[0], frameVecDataB[1], frameVecDataB[2]);
set[id].x10_offset = zeus::CVector3f::lerp(vecA, vecB, t); set[id].x10_offset = zeus::CVector3f::lerp(vecA, vecB, t);
@ -164,7 +165,8 @@ const std::vector<CBoolPOINode>& CAnimSource::GetBoolPOIStream() const { return
zeus::CQuaternion CAnimSource::GetRotation(const CSegId& seg, const CCharAnimTime& time) const { zeus::CQuaternion CAnimSource::GetRotation(const CSegId& seg, const CCharAnimTime& time) const {
u8 rotIdx = x20_rotationChannels[seg]; u8 rotIdx = x20_rotationChannels[seg];
if (rotIdx != 0xff) { 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(); float remTime = time.GetSeconds() - frameIdx * x8_interval.GetSeconds();
if (std::fabs(remTime) < 0.00001f) if (std::fabs(remTime) < 0.00001f)
remTime = 0.f; 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 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* 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 quatA(frameDataA[0], frameDataA[1], frameDataA[2], frameDataA[3]);
zeus::CQuaternion quatB(frameDataB[0], frameDataB[1], frameDataB[2], frameDataB[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) if (transIdx == 0xff)
return {}; 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(); float remTime = time.GetSeconds() - frameIdx * x8_interval.GetSeconds();
if (std::fabs(remTime) < 0.00001f) if (std::fabs(remTime) < 0.00001f)
remTime = 0.f; 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 floatsPerFrame = x40_data.x10_transPerFrame * 3 + x40_data.xc_rotPerFrame * 4;
const u32 rotFloatsPerFrame = 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* 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 vecA(frameDataA[0], frameDataA[1], frameDataA[2]);
zeus::CVector3f vecB(frameDataB[0], frameDataB[1], frameDataB[2]); zeus::CVector3f vecB(frameDataB[0], frameDataB[1], frameDataB[2]);
return zeus::CVector3f::lerp(vecA, vecB, t); return zeus::CVector3f::lerp(vecA, vecB, t);