mirror of https://github.com/AxioDL/metaforce.git
CAnimSource: Fixes for frame interpolation
This commit is contained in:
parent
d47ce662da
commit
63041d5b70
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue