CAnimationLoader: Make use of ranged for where applicable
This commit is contained in:
parent
87fac0896d
commit
4b980458ef
|
@ -10,29 +10,29 @@ bool CAnimationLoader::UncompressedCheckEchoes()
|
||||||
// a little weird because we have to make sure we don't try to seek or read anything
|
// a little weird because we have to make sure we don't try to seek or read anything
|
||||||
// past the end of the file. The +4 being added to each size we test is to account
|
// past the end of the file. The +4 being added to each size we test is to account
|
||||||
// for the next size value of the next array.
|
// for the next size value of the next array.
|
||||||
uint32 End = mpInput->Size();
|
const uint32 End = mpInput->Size();
|
||||||
|
|
||||||
uint32 NumRotIndices = mpInput->ReadLong();
|
const uint32 NumRotIndices = mpInput->ReadLong();
|
||||||
if (mpInput->Tell() + NumRotIndices + 4 >= End) return false;
|
if (mpInput->Tell() + NumRotIndices + 4 >= End) return false;
|
||||||
mpInput->Seek(NumRotIndices, SEEK_CUR);
|
mpInput->Seek(NumRotIndices, SEEK_CUR);
|
||||||
|
|
||||||
uint32 NumTransIndices = mpInput->ReadLong();
|
const uint32 NumTransIndices = mpInput->ReadLong();
|
||||||
if (mpInput->Tell() + NumTransIndices + 4 >= End) return false;
|
if (mpInput->Tell() + NumTransIndices + 4 >= End) return false;
|
||||||
mpInput->Seek(NumTransIndices, SEEK_CUR);
|
mpInput->Seek(NumTransIndices, SEEK_CUR);
|
||||||
|
|
||||||
uint32 NumScaleIndices = mpInput->ReadLong();
|
const uint32 NumScaleIndices = mpInput->ReadLong();
|
||||||
if (mpInput->Tell() + NumScaleIndices + 4 >= End) return false;
|
if (mpInput->Tell() + NumScaleIndices + 4 >= End) return false;
|
||||||
mpInput->Seek(NumScaleIndices, SEEK_CUR);
|
mpInput->Seek(NumScaleIndices, SEEK_CUR);
|
||||||
|
|
||||||
uint32 ScaleKeysSize = mpInput->ReadLong() * 0xC;
|
const uint32 ScaleKeysSize = mpInput->ReadLong() * 0xC;
|
||||||
if (mpInput->Tell() + ScaleKeysSize + 4 >= End) return false;
|
if (mpInput->Tell() + ScaleKeysSize + 4 >= End) return false;
|
||||||
mpInput->Seek(ScaleKeysSize, SEEK_CUR);
|
mpInput->Seek(ScaleKeysSize, SEEK_CUR);
|
||||||
|
|
||||||
uint32 RotKeysSize = mpInput->ReadLong() * 0x10;
|
const uint32 RotKeysSize = mpInput->ReadLong() * 0x10;
|
||||||
if (mpInput->Tell() + RotKeysSize + 4 >= End) return false;
|
if (mpInput->Tell() + RotKeysSize + 4 >= End) return false;
|
||||||
mpInput->Seek(RotKeysSize, SEEK_CUR);
|
mpInput->Seek(RotKeysSize, SEEK_CUR);
|
||||||
|
|
||||||
uint32 TransKeysSize = mpInput->ReadLong() * 0xC;
|
const uint32 TransKeysSize = mpInput->ReadLong() * 0xC;
|
||||||
return (mpInput->Tell() + TransKeysSize == End);
|
return (mpInput->Tell() + TransKeysSize == End);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,8 +40,8 @@ EGame CAnimationLoader::UncompressedCheckVersion()
|
||||||
{
|
{
|
||||||
// Call this function after the bone channel index array
|
// Call this function after the bone channel index array
|
||||||
// No version number, so this is how we have to determine the version...
|
// No version number, so this is how we have to determine the version...
|
||||||
uint32 Start = mpInput->Tell();
|
const uint32 Start = mpInput->Tell();
|
||||||
bool Echoes = UncompressedCheckEchoes();
|
const bool Echoes = UncompressedCheckEchoes();
|
||||||
mpInput->Seek(Start, SEEK_SET);
|
mpInput->Seek(Start, SEEK_SET);
|
||||||
return (Echoes ? EGame::Echoes : EGame::Prime);
|
return (Echoes ? EGame::Echoes : EGame::Prime);
|
||||||
}
|
}
|
||||||
|
@ -63,15 +63,15 @@ void CAnimationLoader::ReadUncompressedANIM()
|
||||||
uint32 NumTranslationChannels = 0;
|
uint32 NumTranslationChannels = 0;
|
||||||
|
|
||||||
// Bone channel list
|
// Bone channel list
|
||||||
uint32 NumBoneIndices = mpInput->ReadLong();
|
const uint32 NumBoneIndices = mpInput->ReadLong();
|
||||||
ASSERT(NumBoneIndices == 100);
|
ASSERT(NumBoneIndices == 100);
|
||||||
std::vector<uint8> BoneIndices(NumBoneIndices);
|
std::vector<uint8> BoneIndices(NumBoneIndices);
|
||||||
|
|
||||||
for (uint32 iChan = 0; iChan < NumBoneIndices; iChan++)
|
for (auto& index : BoneIndices)
|
||||||
{
|
{
|
||||||
BoneIndices[iChan] = mpInput->ReadByte();
|
index = static_cast<uint8>(mpInput->ReadByte());
|
||||||
|
|
||||||
if (BoneIndices[iChan] != 0xFF)
|
if (index != 0xFF)
|
||||||
NumBoneChannels++;
|
NumBoneChannels++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,42 +83,41 @@ void CAnimationLoader::ReadUncompressedANIM()
|
||||||
|
|
||||||
if (mGame >= EGame::EchoesDemo)
|
if (mGame >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
uint32 NumRotationIndices = mpInput->ReadLong();
|
const uint32 NumRotationIndices = mpInput->ReadLong();
|
||||||
RotationIndices.resize(NumRotationIndices);
|
RotationIndices.resize(NumRotationIndices);
|
||||||
|
|
||||||
for (uint32 iRot = 0; iRot < NumRotationIndices; iRot++)
|
for (auto& index : RotationIndices)
|
||||||
{
|
{
|
||||||
RotationIndices[iRot] = mpInput->ReadByte();
|
index = static_cast<uint8>(mpInput->ReadByte());
|
||||||
|
|
||||||
if (RotationIndices[iRot] != 0xFF)
|
if (index != 0xFF)
|
||||||
NumRotationChannels++;
|
NumRotationChannels++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// In MP1 every bone channel has a rotation, so just copy the valid channels from the bone channel list.
|
// In MP1 every bone channel has a rotation, so just copy the valid channels from the bone channel list.
|
||||||
RotationIndices.resize(NumBoneChannels);
|
RotationIndices.resize(NumBoneChannels);
|
||||||
|
|
||||||
for (uint32 iBone = 0; iBone < BoneIndices.size(); iBone++)
|
for (const auto index : BoneIndices)
|
||||||
{
|
{
|
||||||
if (BoneIndices[iBone] != 0xFF)
|
if (index != 0xFF)
|
||||||
{
|
{
|
||||||
RotationIndices[NumRotationChannels] = BoneIndices[iBone];
|
RotationIndices[NumRotationChannels] = index;
|
||||||
NumRotationChannels++;
|
NumRotationChannels++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translation channel indices
|
// Translation channel indices
|
||||||
uint32 NumTransIndices = mpInput->ReadLong();
|
const uint32 NumTransIndices = mpInput->ReadLong();
|
||||||
std::vector<uint8> TransIndices(NumTransIndices);
|
std::vector<uint8> TransIndices(NumTransIndices);
|
||||||
|
|
||||||
for (uint32 iTrans = 0; iTrans < NumTransIndices; iTrans++)
|
for (auto& index : TransIndices)
|
||||||
{
|
{
|
||||||
TransIndices[iTrans] = mpInput->ReadByte();
|
index = static_cast<uint8>(mpInput->ReadByte());
|
||||||
|
|
||||||
if (TransIndices[iTrans] != 0xFF)
|
if (index != 0xFF)
|
||||||
NumTranslationChannels++;
|
NumTranslationChannels++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,22 +126,22 @@ void CAnimationLoader::ReadUncompressedANIM()
|
||||||
|
|
||||||
if (mGame >= EGame::EchoesDemo)
|
if (mGame >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
uint32 NumScaleIndices = mpInput->ReadLong();
|
const uint32 NumScaleIndices = mpInput->ReadLong();
|
||||||
ScaleIndices.resize(NumScaleIndices);
|
ScaleIndices.resize(NumScaleIndices);
|
||||||
|
|
||||||
for (uint32 iScale = 0; iScale < NumScaleIndices; iScale++)
|
for (auto& index : ScaleIndices)
|
||||||
{
|
{
|
||||||
ScaleIndices[iScale] = mpInput->ReadByte();
|
index = static_cast<uint8>(mpInput->ReadByte());
|
||||||
|
|
||||||
if (ScaleIndices[iScale] != 0xFF)
|
if (index != 0xFF)
|
||||||
NumScaleChannels++;
|
NumScaleChannels++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up bone channel info
|
// Set up bone channel info
|
||||||
for (uint32 iBone = 0, iChan = 0; iBone < NumBoneIndices; iBone++)
|
for (size_t iBone = 0, iChan = 0; iBone < NumBoneIndices; iBone++)
|
||||||
{
|
{
|
||||||
uint8 BoneIdx = BoneIndices[iBone];
|
const uint8 BoneIdx = BoneIndices[iBone];
|
||||||
|
|
||||||
if (BoneIdx != 0xFF)
|
if (BoneIdx != 0xFF)
|
||||||
{
|
{
|
||||||
|
@ -166,11 +165,11 @@ void CAnimationLoader::ReadUncompressedANIM()
|
||||||
mpInput->Seek(0x4, SEEK_CUR); // Skipping scale key count
|
mpInput->Seek(0x4, SEEK_CUR); // Skipping scale key count
|
||||||
mpAnim->mScaleChannels.resize(NumScaleChannels);
|
mpAnim->mScaleChannels.resize(NumScaleChannels);
|
||||||
|
|
||||||
for (uint32 iScale = 0; iScale < NumScaleChannels; iScale++)
|
for (size_t iScale = 0; iScale < NumScaleChannels; iScale++)
|
||||||
{
|
{
|
||||||
mpAnim->mScaleChannels[iScale].resize(mpAnim->mNumKeys);
|
mpAnim->mScaleChannels[iScale].resize(mpAnim->mNumKeys);
|
||||||
|
|
||||||
for (uint32 iKey = 0; iKey < mpAnim->mNumKeys; iKey++)
|
for (size_t iKey = 0; iKey < mpAnim->mNumKeys; iKey++)
|
||||||
mpAnim->mScaleChannels[iScale][iKey] = CVector3f(*mpInput);
|
mpAnim->mScaleChannels[iScale][iKey] = CVector3f(*mpInput);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,22 +177,22 @@ void CAnimationLoader::ReadUncompressedANIM()
|
||||||
mpInput->Seek(0x4, SEEK_CUR); // Skipping rotation key count
|
mpInput->Seek(0x4, SEEK_CUR); // Skipping rotation key count
|
||||||
mpAnim->mRotationChannels.resize(NumRotationChannels);
|
mpAnim->mRotationChannels.resize(NumRotationChannels);
|
||||||
|
|
||||||
for (uint32 iRot = 0; iRot < NumRotationChannels; iRot++)
|
for (size_t iRot = 0; iRot < NumRotationChannels; iRot++)
|
||||||
{
|
{
|
||||||
mpAnim->mRotationChannels[iRot].resize(mpAnim->mNumKeys);
|
mpAnim->mRotationChannels[iRot].resize(mpAnim->mNumKeys);
|
||||||
|
|
||||||
for (uint32 iKey = 0; iKey < mpAnim->mNumKeys; iKey++)
|
for (size_t iKey = 0; iKey < mpAnim->mNumKeys; iKey++)
|
||||||
mpAnim->mRotationChannels[iRot][iKey] = CQuaternion(*mpInput);
|
mpAnim->mRotationChannels[iRot][iKey] = CQuaternion(*mpInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
mpInput->Seek(0x4, SEEK_CUR); // Skipping translation key count
|
mpInput->Seek(0x4, SEEK_CUR); // Skipping translation key count
|
||||||
mpAnim->mTranslationChannels.resize(NumTranslationChannels);
|
mpAnim->mTranslationChannels.resize(NumTranslationChannels);
|
||||||
|
|
||||||
for (uint32 iTrans = 0; iTrans < NumTranslationChannels; iTrans++)
|
for (size_t iTrans = 0; iTrans < NumTranslationChannels; iTrans++)
|
||||||
{
|
{
|
||||||
mpAnim->mTranslationChannels[iTrans].resize(mpAnim->mNumKeys);
|
mpAnim->mTranslationChannels[iTrans].resize(mpAnim->mNumKeys);
|
||||||
|
|
||||||
for (uint32 iKey = 0; iKey < mpAnim->mNumKeys; iKey++)
|
for (size_t iKey = 0; iKey < mpAnim->mNumKeys; iKey++)
|
||||||
mpAnim->mTranslationChannels[iTrans][iKey] = CVector3f(*mpInput);
|
mpAnim->mTranslationChannels[iTrans][iKey] = CVector3f(*mpInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,19 +224,20 @@ void CAnimationLoader::ReadCompressedANIM()
|
||||||
|
|
||||||
mRotationDivisor = mpInput->ReadLong();
|
mRotationDivisor = mpInput->ReadLong();
|
||||||
mTranslationMultiplier = mpInput->ReadFloat();
|
mTranslationMultiplier = mpInput->ReadFloat();
|
||||||
if (mGame >= EGame::EchoesDemo) mScaleMultiplier = mpInput->ReadFloat();
|
if (mGame >= EGame::EchoesDemo)
|
||||||
uint32 NumBoneChannels = mpInput->ReadLong();
|
mScaleMultiplier = mpInput->ReadFloat();
|
||||||
|
const uint32 NumBoneChannels = mpInput->ReadLong();
|
||||||
mpInput->Seek(0x4, SEEK_CUR); // Skip unknown value
|
mpInput->Seek(0x4, SEEK_CUR); // Skip unknown value
|
||||||
|
|
||||||
// Read key flags
|
// Read key flags
|
||||||
uint32 NumKeys = mpInput->ReadLong();
|
const uint32 NumKeys = mpInput->ReadLong();
|
||||||
mpAnim->mNumKeys = NumKeys;
|
mpAnim->mNumKeys = NumKeys;
|
||||||
mKeyFlags.resize(NumKeys);
|
mKeyFlags.resize(NumKeys);
|
||||||
{
|
{
|
||||||
CBitStreamInWrapper BitStream(mpInput);
|
CBitStreamInWrapper BitStream(mpInput);
|
||||||
|
|
||||||
for (uint32 iBit = 0; iBit < NumKeys; iBit++)
|
for (auto& flag : mKeyFlags)
|
||||||
mKeyFlags[iBit] = BitStream.ReadBit();
|
flag = BitStream.ReadBit();
|
||||||
}
|
}
|
||||||
mpInput->Seek(mGame == EGame::Prime ? 0x8 : 0x4, SEEK_CUR);
|
mpInput->Seek(mGame == EGame::Prime ? 0x8 : 0x4, SEEK_CUR);
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ void CAnimationLoader::ReadCompressedANIM()
|
||||||
mpAnim->mRotationChannels.resize(NumBoneChannels);
|
mpAnim->mRotationChannels.resize(NumBoneChannels);
|
||||||
mpAnim->mTranslationChannels.resize(NumBoneChannels);
|
mpAnim->mTranslationChannels.resize(NumBoneChannels);
|
||||||
|
|
||||||
for (uint32 iChan = 0; iChan < NumBoneChannels; iChan++)
|
for (size_t iChan = 0; iChan < NumBoneChannels; iChan++)
|
||||||
{
|
{
|
||||||
SCompressedChannel& rChan = mCompressedChannels[iChan];
|
SCompressedChannel& rChan = mCompressedChannels[iChan];
|
||||||
rChan.BoneID = (mGame == EGame::Prime ? mpInput->ReadLong() : mpInput->ReadByte());
|
rChan.BoneID = (mGame == EGame::Prime ? mpInput->ReadLong() : mpInput->ReadByte());
|
||||||
|
@ -257,30 +257,36 @@ void CAnimationLoader::ReadCompressedANIM()
|
||||||
|
|
||||||
if (rChan.NumRotationKeys > 0)
|
if (rChan.NumRotationKeys > 0)
|
||||||
{
|
{
|
||||||
for (uint32 iComp = 0; iComp < 3; iComp++)
|
for (size_t iComp = 0; iComp < 3; iComp++)
|
||||||
{
|
{
|
||||||
rChan.Rotation[iComp] = mpInput->ReadShort();
|
rChan.Rotation[iComp] = mpInput->ReadShort();
|
||||||
rChan.RotationBits[iComp] = mpInput->ReadByte();
|
rChan.RotationBits[iComp] = mpInput->ReadByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
mpAnim->mBoneInfo[rChan.BoneID].RotationChannelIdx = (uint8) iChan;
|
mpAnim->mBoneInfo[rChan.BoneID].RotationChannelIdx = static_cast<uint8>(iChan);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mpAnim->mBoneInfo[rChan.BoneID].RotationChannelIdx = 0xFF;
|
||||||
}
|
}
|
||||||
else mpAnim->mBoneInfo[rChan.BoneID].RotationChannelIdx = 0xFF;
|
|
||||||
|
|
||||||
// Read translation parameters
|
// Read translation parameters
|
||||||
rChan.NumTranslationKeys = mpInput->ReadShort();
|
rChan.NumTranslationKeys = mpInput->ReadShort();
|
||||||
|
|
||||||
if (rChan.NumTranslationKeys > 0)
|
if (rChan.NumTranslationKeys > 0)
|
||||||
{
|
{
|
||||||
for (uint32 iComp = 0; iComp < 3; iComp++)
|
for (size_t iComp = 0; iComp < 3; iComp++)
|
||||||
{
|
{
|
||||||
rChan.Translation[iComp] = mpInput->ReadShort();
|
rChan.Translation[iComp] = mpInput->ReadShort();
|
||||||
rChan.TranslationBits[iComp] = mpInput->ReadByte();
|
rChan.TranslationBits[iComp] = mpInput->ReadByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
mpAnim->mBoneInfo[rChan.BoneID].TranslationChannelIdx = (uint8) iChan;
|
mpAnim->mBoneInfo[rChan.BoneID].TranslationChannelIdx = static_cast<uint8>(iChan);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mpAnim->mBoneInfo[rChan.BoneID].TranslationChannelIdx = 0xFF;
|
||||||
}
|
}
|
||||||
else mpAnim->mBoneInfo[rChan.BoneID].TranslationChannelIdx = 0xFF;
|
|
||||||
|
|
||||||
// Read scale parameters
|
// Read scale parameters
|
||||||
uint8 ScaleIdx = 0xFF;
|
uint8 ScaleIdx = 0xFF;
|
||||||
|
@ -291,13 +297,13 @@ void CAnimationLoader::ReadCompressedANIM()
|
||||||
|
|
||||||
if (rChan.NumScaleKeys > 0)
|
if (rChan.NumScaleKeys > 0)
|
||||||
{
|
{
|
||||||
for (uint32 iComp = 0; iComp < 3; iComp++)
|
for (size_t iComp = 0; iComp < 3; iComp++)
|
||||||
{
|
{
|
||||||
rChan.Scale[iComp] = mpInput->ReadShort();
|
rChan.Scale[iComp] = mpInput->ReadShort();
|
||||||
rChan.ScaleBits[iComp] = mpInput->ReadByte();
|
rChan.ScaleBits[iComp] = mpInput->ReadByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
ScaleIdx = (uint8) iChan;
|
ScaleIdx = static_cast<uint8>(iChan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mpAnim->mBoneInfo[rChan.BoneID].ScaleChannelIdx = ScaleIdx;
|
mpAnim->mBoneInfo[rChan.BoneID].ScaleChannelIdx = ScaleIdx;
|
||||||
|
@ -312,7 +318,7 @@ void CAnimationLoader::ReadCompressedAnimationData()
|
||||||
CBitStreamInWrapper BitStream(mpInput);
|
CBitStreamInWrapper BitStream(mpInput);
|
||||||
|
|
||||||
// Initialize
|
// Initialize
|
||||||
for (uint32 iChan = 0; iChan < mCompressedChannels.size(); iChan++)
|
for (size_t iChan = 0; iChan < mCompressedChannels.size(); iChan++)
|
||||||
{
|
{
|
||||||
SCompressedChannel& rChan = mCompressedChannels[iChan];
|
SCompressedChannel& rChan = mCompressedChannels[iChan];
|
||||||
|
|
||||||
|
@ -340,11 +346,11 @@ void CAnimationLoader::ReadCompressedAnimationData()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read keys
|
// Read keys
|
||||||
for (uint32 iKey = 0; iKey < mpAnim->mNumKeys - 1; iKey++)
|
for (size_t iKey = 0; iKey < mpAnim->mNumKeys - 1; iKey++)
|
||||||
{
|
{
|
||||||
bool KeyPresent = mKeyFlags[iKey+1];
|
const bool KeyPresent = mKeyFlags[iKey + 1];
|
||||||
|
|
||||||
for (uint32 iChan = 0; iChan < mCompressedChannels.size(); iChan++)
|
for (size_t iChan = 0; iChan < mCompressedChannels.size(); iChan++)
|
||||||
{
|
{
|
||||||
SCompressedChannel& rChan = mCompressedChannels[iChan];
|
SCompressedChannel& rChan = mCompressedChannels[iChan];
|
||||||
|
|
||||||
|
@ -353,16 +359,16 @@ void CAnimationLoader::ReadCompressedAnimationData()
|
||||||
{
|
{
|
||||||
// Note if KeyPresent is false, this isn't the correct value of WSign.
|
// Note if KeyPresent is false, this isn't the correct value of WSign.
|
||||||
// However, we're going to recreate this key later via interpolation, so it doesn't matter what value we use here.
|
// However, we're going to recreate this key later via interpolation, so it doesn't matter what value we use here.
|
||||||
bool WSign = (KeyPresent ? BitStream.ReadBit() : false);
|
const bool WSign = (KeyPresent ? BitStream.ReadBit() : false);
|
||||||
|
|
||||||
if (KeyPresent)
|
if (KeyPresent)
|
||||||
{
|
{
|
||||||
rChan.Rotation[0] += (int16) BitStream.ReadBits(rChan.RotationBits[0]);
|
rChan.Rotation[0] += static_cast<int16>(BitStream.ReadBits(rChan.RotationBits[0]));
|
||||||
rChan.Rotation[1] += (int16) BitStream.ReadBits(rChan.RotationBits[1]);
|
rChan.Rotation[1] += static_cast<int16>(BitStream.ReadBits(rChan.RotationBits[1]));
|
||||||
rChan.Rotation[2] += (int16) BitStream.ReadBits(rChan.RotationBits[2]);
|
rChan.Rotation[2] += static_cast<int16>(BitStream.ReadBits(rChan.RotationBits[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
CQuaternion Rotation = DequantizeRotation(WSign, rChan.Rotation[0], rChan.Rotation[1], rChan.Rotation[2]);
|
const CQuaternion Rotation = DequantizeRotation(WSign, rChan.Rotation[0], rChan.Rotation[1], rChan.Rotation[2]);
|
||||||
mpAnim->mRotationChannels[iChan].push_back(Rotation);
|
mpAnim->mRotationChannels[iChan].push_back(Rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,12 +377,12 @@ void CAnimationLoader::ReadCompressedAnimationData()
|
||||||
{
|
{
|
||||||
if (KeyPresent)
|
if (KeyPresent)
|
||||||
{
|
{
|
||||||
rChan.Translation[0] += (int16) BitStream.ReadBits(rChan.TranslationBits[0]);
|
rChan.Translation[0] += static_cast<int16>(BitStream.ReadBits(rChan.TranslationBits[0]));
|
||||||
rChan.Translation[1] += (int16) BitStream.ReadBits(rChan.TranslationBits[1]);
|
rChan.Translation[1] += static_cast<int16>(BitStream.ReadBits(rChan.TranslationBits[1]));
|
||||||
rChan.Translation[2] += (int16) BitStream.ReadBits(rChan.TranslationBits[2]);
|
rChan.Translation[2] += static_cast<int16>(BitStream.ReadBits(rChan.TranslationBits[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
CVector3f Translate = CVector3f(rChan.Translation[0], rChan.Translation[1], rChan.Translation[2]) * mTranslationMultiplier;
|
const CVector3f Translate = CVector3f(rChan.Translation[0], rChan.Translation[1], rChan.Translation[2]) * mTranslationMultiplier;
|
||||||
mpAnim->mTranslationChannels[iChan].push_back(Translate);
|
mpAnim->mTranslationChannels[iChan].push_back(Translate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,12 +391,12 @@ void CAnimationLoader::ReadCompressedAnimationData()
|
||||||
{
|
{
|
||||||
if (KeyPresent)
|
if (KeyPresent)
|
||||||
{
|
{
|
||||||
rChan.Scale[0] += (int16) BitStream.ReadBits(rChan.ScaleBits[0]);
|
rChan.Scale[0] += static_cast<int16>(BitStream.ReadBits(rChan.ScaleBits[0]));
|
||||||
rChan.Scale[1] += (int16) BitStream.ReadBits(rChan.ScaleBits[1]);
|
rChan.Scale[1] += static_cast<int16>(BitStream.ReadBits(rChan.ScaleBits[1]));
|
||||||
rChan.Scale[2] += (int16) BitStream.ReadBits(rChan.ScaleBits[2]);
|
rChan.Scale[2] += static_cast<int16>(BitStream.ReadBits(rChan.ScaleBits[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
CVector3f Scale = CVector3f(rChan.Scale[0], rChan.Scale[1], rChan.Scale[2]) * mScaleMultiplier;
|
const CVector3f Scale = CVector3f(rChan.Scale[0], rChan.Scale[1], rChan.Scale[2]) * mScaleMultiplier;
|
||||||
mpAnim->mScaleChannels[iChan].push_back(Scale);
|
mpAnim->mScaleChannels[iChan].push_back(Scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -399,47 +405,48 @@ void CAnimationLoader::ReadCompressedAnimationData()
|
||||||
// Fill in missing keys
|
// Fill in missing keys
|
||||||
uint32 NumMissedKeys = 0;
|
uint32 NumMissedKeys = 0;
|
||||||
|
|
||||||
for (uint32 iKey = 0; iKey < mpAnim->mNumKeys; iKey++)
|
for (size_t iKey = 0; iKey < mpAnim->mNumKeys; iKey++)
|
||||||
{
|
{
|
||||||
if (!mKeyFlags[iKey])
|
if (!mKeyFlags[iKey])
|
||||||
|
{
|
||||||
NumMissedKeys++;
|
NumMissedKeys++;
|
||||||
|
}
|
||||||
else if (NumMissedKeys > 0)
|
else if (NumMissedKeys > 0)
|
||||||
{
|
{
|
||||||
uint32 FirstIndex = iKey - NumMissedKeys - 1;
|
const uint32 FirstIndex = iKey - NumMissedKeys - 1;
|
||||||
uint32 LastIndex = iKey;
|
const size_t LastIndex = iKey;
|
||||||
uint32 RelLastIndex = LastIndex - FirstIndex;
|
const uint32 RelLastIndex = LastIndex - FirstIndex;
|
||||||
|
|
||||||
for (uint32 iMissed = 0; iMissed < NumMissedKeys; iMissed++)
|
for (size_t iMissed = 0; iMissed < NumMissedKeys; iMissed++)
|
||||||
{
|
{
|
||||||
uint32 KeyIndex = FirstIndex + iMissed + 1;
|
const size_t KeyIndex = FirstIndex + iMissed + 1;
|
||||||
uint32 RelKeyIndex = (KeyIndex - FirstIndex);
|
const size_t RelKeyIndex = (KeyIndex - FirstIndex);
|
||||||
float Interp = (float) RelKeyIndex / (float) RelLastIndex;
|
const float Interp = static_cast<float>(RelKeyIndex) / static_cast<float>(RelLastIndex);
|
||||||
|
|
||||||
for (uint32 iChan = 0; iChan < mCompressedChannels.size(); iChan++)
|
for (uint32 iChan = 0; iChan < mCompressedChannels.size(); iChan++)
|
||||||
{
|
{
|
||||||
bool HasTranslationKeys = mCompressedChannels[iChan].NumTranslationKeys > 0;
|
const bool HasTranslationKeys = mCompressedChannels[iChan].NumTranslationKeys > 0;
|
||||||
bool HasRotationKeys = mCompressedChannels[iChan].NumRotationKeys > 0;
|
const bool HasRotationKeys = mCompressedChannels[iChan].NumRotationKeys > 0;
|
||||||
bool HasScaleKeys = mCompressedChannels[iChan].NumScaleKeys > 0;
|
const bool HasScaleKeys = mCompressedChannels[iChan].NumScaleKeys > 0;
|
||||||
|
|
||||||
if (HasRotationKeys)
|
if (HasRotationKeys)
|
||||||
{
|
{
|
||||||
CQuaternion Left = mpAnim->mRotationChannels[iChan][FirstIndex];
|
const CQuaternion Left = mpAnim->mRotationChannels[iChan][FirstIndex];
|
||||||
CQuaternion Right = mpAnim->mRotationChannels[iChan][LastIndex];
|
const CQuaternion Right = mpAnim->mRotationChannels[iChan][LastIndex];
|
||||||
mpAnim->mRotationChannels[iChan][KeyIndex] = Left.Slerp(Right, Interp);
|
mpAnim->mRotationChannels[iChan][KeyIndex] = Left.Slerp(Right, Interp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasTranslationKeys)
|
if (HasTranslationKeys)
|
||||||
{
|
{
|
||||||
CVector3f Left = mpAnim->mTranslationChannels[iChan][FirstIndex];
|
const CVector3f Left = mpAnim->mTranslationChannels[iChan][FirstIndex];
|
||||||
CVector3f Right = mpAnim->mTranslationChannels[iChan][LastIndex];
|
const CVector3f Right = mpAnim->mTranslationChannels[iChan][LastIndex];
|
||||||
mpAnim->mTranslationChannels[iChan][KeyIndex] = Math::Lerp<CVector3f>(Left, Right, Interp);
|
mpAnim->mTranslationChannels[iChan][KeyIndex] = Math::Lerp<CVector3f>(Left, Right, Interp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasScaleKeys)
|
if (HasScaleKeys)
|
||||||
{
|
{
|
||||||
CVector3f Left = mpAnim->mScaleChannels[iChan][FirstIndex];
|
const CVector3f Left = mpAnim->mScaleChannels[iChan][FirstIndex];
|
||||||
CVector3f Right = mpAnim->mScaleChannels[iChan][LastIndex];
|
const CVector3f Right = mpAnim->mScaleChannels[iChan][LastIndex];
|
||||||
mpAnim->mScaleChannels[iChan][KeyIndex] = Math::Lerp<CVector3f>(Left, Right, Interp);
|
mpAnim->mScaleChannels[iChan][KeyIndex] = Math::Lerp<CVector3f>(Left, Right, Interp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -450,15 +457,19 @@ void CAnimationLoader::ReadCompressedAnimationData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CQuaternion CAnimationLoader::DequantizeRotation(bool Sign, int16 X, int16 Y, int16 Z)
|
CQuaternion CAnimationLoader::DequantizeRotation(bool Sign, int16 X, int16 Y, int16 Z) const
|
||||||
{
|
{
|
||||||
|
const float Multiplier = Math::skHalfPi / static_cast<float>(mRotationDivisor);
|
||||||
|
|
||||||
CQuaternion Out;
|
CQuaternion Out;
|
||||||
float Multiplier = Math::skHalfPi / (float) mRotationDivisor;
|
Out.X = std::sinf(static_cast<float>(X) * Multiplier);
|
||||||
Out.X = sinf(X * Multiplier);
|
Out.Y = std::sinf(static_cast<float>(Y) * Multiplier);
|
||||||
Out.Y = sinf(Y * Multiplier);
|
Out.Z = std::sinf(static_cast<float>(Z) * Multiplier);
|
||||||
Out.Z = sinf(Z * Multiplier);
|
Out.W = Math::Sqrt(std::fmax(1.f - ((Out.X * Out.X) + (Out.Y * Out.Y) + (Out.Z * Out.Z)), 0.f));
|
||||||
Out.W = Math::Sqrt( fmax(1.f - ((Out.X * Out.X) + (Out.Y * Out.Y) + (Out.Z * Out.Z)), 0.f) );
|
|
||||||
if (Sign) Out.W = -Out.W;
|
if (Sign)
|
||||||
|
Out.W = -Out.W;
|
||||||
|
|
||||||
return Out;
|
return Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,7 +480,7 @@ std::unique_ptr<CAnimation> CAnimationLoader::LoadANIM(IInputStream& rANIM, CRes
|
||||||
if (pEntry->Game() > EGame::Echoes)
|
if (pEntry->Game() > EGame::Echoes)
|
||||||
return std::make_unique<CAnimation>(pEntry);
|
return std::make_unique<CAnimation>(pEntry);
|
||||||
|
|
||||||
uint32 CompressionType = rANIM.ReadLong();
|
const uint32 CompressionType = rANIM.ReadLong();
|
||||||
|
|
||||||
if (CompressionType != 0 && CompressionType != 2)
|
if (CompressionType != 0 && CompressionType != 2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,7 +40,7 @@ class CAnimationLoader
|
||||||
void ReadUncompressedANIM();
|
void ReadUncompressedANIM();
|
||||||
void ReadCompressedANIM();
|
void ReadCompressedANIM();
|
||||||
void ReadCompressedAnimationData();
|
void ReadCompressedAnimationData();
|
||||||
CQuaternion DequantizeRotation(bool Sign, int16 X, int16 Y, int16 Z);
|
CQuaternion DequantizeRotation(bool Sign, int16 X, int16 Y, int16 Z) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<CAnimation> LoadANIM(IInputStream& rANIM, CResourceEntry *pEntry);
|
static std::unique_ptr<CAnimation> LoadANIM(IInputStream& rANIM, CResourceEntry *pEntry);
|
||||||
|
|
Loading…
Reference in New Issue