mirror of https://github.com/AxioDL/metaforce.git
Define ChannelDescPC for 24-bit ANIM3
This commit is contained in:
parent
f9cef44029
commit
c5ddb51dfc
|
@ -287,40 +287,82 @@ void ANIM::ANIM2::read(athena::io::IStreamReader& reader)
|
||||||
bones.reserve(head.boneChannelCount);
|
bones.reserve(head.boneChannelCount);
|
||||||
channels.clear();
|
channels.clear();
|
||||||
channels.reserve(head.boneChannelCount);
|
channels.reserve(head.boneChannelCount);
|
||||||
atUint16 keyframeCount = 0;
|
atUint32 keyframeCount = 0;
|
||||||
for (size_t b=0 ; b<head.boneChannelCount ; ++b)
|
|
||||||
|
if (m_version == 3)
|
||||||
{
|
{
|
||||||
ChannelDesc desc;
|
for (size_t b=0 ; b<head.boneChannelCount ; ++b)
|
||||||
desc.read(reader);
|
|
||||||
bones.emplace_back(desc.id, desc.keyCount2 != 0);
|
|
||||||
|
|
||||||
if (desc.keyCount1)
|
|
||||||
{
|
{
|
||||||
channels.emplace_back();
|
ChannelDescPC desc;
|
||||||
DNAANIM::Channel& chan = channels.back();
|
desc.read(reader);
|
||||||
chan.type = DNAANIM::Channel::Type::Rotation;
|
bones.emplace_back(desc.id, desc.keyCount2 != 0);
|
||||||
chan.id = desc.id;
|
|
||||||
chan.i[0] = desc.initRX;
|
if (desc.keyCount1)
|
||||||
chan.q[0] = desc.qRX;
|
{
|
||||||
chan.i[1] = desc.initRY;
|
channels.emplace_back();
|
||||||
chan.q[1] = desc.qRY;
|
DNAANIM::Channel& chan = channels.back();
|
||||||
chan.i[2] = desc.initRZ;
|
chan.type = DNAANIM::Channel::Type::Rotation;
|
||||||
chan.q[2] = desc.qRZ;
|
chan.id = desc.id;
|
||||||
|
chan.i[0] = atInt32(desc.QinitRX) >> 8;
|
||||||
|
chan.q[0] = desc.QinitRX & 0xff;
|
||||||
|
chan.i[1] = atInt32(desc.QinitRY) >> 8;
|
||||||
|
chan.q[1] = desc.QinitRY & 0xff;
|
||||||
|
chan.i[2] = atInt32(desc.QinitRZ) >> 8;
|
||||||
|
chan.q[2] = desc.QinitRZ & 0xff;
|
||||||
|
}
|
||||||
|
keyframeCount = std::max(keyframeCount, desc.keyCount1);
|
||||||
|
|
||||||
|
if (desc.keyCount2)
|
||||||
|
{
|
||||||
|
channels.emplace_back();
|
||||||
|
DNAANIM::Channel& chan = channels.back();
|
||||||
|
chan.type = DNAANIM::Channel::Type::Translation;
|
||||||
|
chan.id = desc.id;
|
||||||
|
chan.i[0] = atInt32(desc.QinitTX) >> 8;
|
||||||
|
chan.q[0] = desc.QinitTX & 0xff;
|
||||||
|
chan.i[1] = atInt32(desc.QinitTY) >> 8;
|
||||||
|
chan.q[1] = desc.QinitTY & 0xff;
|
||||||
|
chan.i[2] = atInt32(desc.QinitTZ) >> 8;
|
||||||
|
chan.q[2] = desc.QinitTZ & 0xff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
keyframeCount = std::max(keyframeCount, desc.keyCount1);
|
}
|
||||||
|
else
|
||||||
if (desc.keyCount2)
|
{
|
||||||
|
for (size_t b=0 ; b<head.boneChannelCount ; ++b)
|
||||||
{
|
{
|
||||||
channels.emplace_back();
|
ChannelDesc desc;
|
||||||
DNAANIM::Channel& chan = channels.back();
|
desc.read(reader);
|
||||||
chan.type = DNAANIM::Channel::Type::Translation;
|
bones.emplace_back(desc.id, desc.keyCount2 != 0);
|
||||||
chan.id = desc.id;
|
|
||||||
chan.i[0] = desc.initTX;
|
if (desc.keyCount1)
|
||||||
chan.q[0] = desc.qTX;
|
{
|
||||||
chan.i[1] = desc.initTY;
|
channels.emplace_back();
|
||||||
chan.q[1] = desc.qTY;
|
DNAANIM::Channel& chan = channels.back();
|
||||||
chan.i[2] = desc.initTZ;
|
chan.type = DNAANIM::Channel::Type::Rotation;
|
||||||
chan.q[2] = desc.qTZ;
|
chan.id = desc.id;
|
||||||
|
chan.i[0] = desc.initRX;
|
||||||
|
chan.q[0] = desc.qRX;
|
||||||
|
chan.i[1] = desc.initRY;
|
||||||
|
chan.q[1] = desc.qRY;
|
||||||
|
chan.i[2] = desc.initRZ;
|
||||||
|
chan.q[2] = desc.qRZ;
|
||||||
|
}
|
||||||
|
keyframeCount = std::max(keyframeCount, atUint32(desc.keyCount1));
|
||||||
|
|
||||||
|
if (desc.keyCount2)
|
||||||
|
{
|
||||||
|
channels.emplace_back();
|
||||||
|
DNAANIM::Channel& chan = channels.back();
|
||||||
|
chan.type = DNAANIM::Channel::Type::Translation;
|
||||||
|
chan.id = desc.id;
|
||||||
|
chan.i[0] = desc.initTX;
|
||||||
|
chan.q[0] = desc.qTX;
|
||||||
|
chan.i[1] = desc.initTY;
|
||||||
|
chan.q[1] = desc.qTY;
|
||||||
|
chan.i[2] = desc.initTZ;
|
||||||
|
chan.q[2] = desc.qTZ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,30 +412,56 @@ void ANIM::ANIM2::write(athena::io::IStreamWriter& writer) const
|
||||||
writer.writeUint32Big(head.boneChannelCount);
|
writer.writeUint32Big(head.boneChannelCount);
|
||||||
writer.writeUint32Big(head.boneChannelCount);
|
writer.writeUint32Big(head.boneChannelCount);
|
||||||
auto cit = qChannels.begin();
|
auto cit = qChannels.begin();
|
||||||
for (const std::pair<atUint32, bool>& bone : bones)
|
|
||||||
|
if (m_version == 3)
|
||||||
{
|
{
|
||||||
ChannelDesc desc;
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
desc.id = bone.first;
|
|
||||||
DNAANIM::Channel& chan = *cit++;
|
|
||||||
desc.keyCount1 = keyframeCount;
|
|
||||||
desc.initRX = chan.i[0];
|
|
||||||
desc.qRX = chan.q[0];
|
|
||||||
desc.initRY = chan.i[1];
|
|
||||||
desc.qRY = chan.q[1];
|
|
||||||
desc.initRZ = chan.i[2];
|
|
||||||
desc.qRZ = chan.q[2];
|
|
||||||
if (bone.second)
|
|
||||||
{
|
{
|
||||||
|
ChannelDescPC desc;
|
||||||
|
desc.id = bone.first;
|
||||||
DNAANIM::Channel& chan = *cit++;
|
DNAANIM::Channel& chan = *cit++;
|
||||||
desc.keyCount2 = keyframeCount;
|
desc.keyCount1 = keyframeCount;
|
||||||
desc.initTX = chan.i[0];
|
desc.QinitRX = (chan.i[0] << 8) | chan.q[0];
|
||||||
desc.qTX = chan.q[0];
|
desc.QinitRY = (chan.i[1] << 8) | chan.q[1];
|
||||||
desc.initTY = chan.i[1];
|
desc.QinitRZ = (chan.i[2] << 8) | chan.q[2];
|
||||||
desc.qTY = chan.q[1];
|
if (bone.second)
|
||||||
desc.initTZ = chan.i[2];
|
{
|
||||||
desc.qTZ = chan.q[2];
|
DNAANIM::Channel& chan = *cit++;
|
||||||
|
desc.keyCount2 = keyframeCount;
|
||||||
|
desc.QinitTX = (chan.i[0] << 8) | chan.q[0];
|
||||||
|
desc.QinitTY = (chan.i[1] << 8) | chan.q[1];
|
||||||
|
desc.QinitTZ = (chan.i[2] << 8) | chan.q[2];
|
||||||
|
}
|
||||||
|
desc.write(writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
|
{
|
||||||
|
ChannelDesc desc;
|
||||||
|
desc.id = bone.first;
|
||||||
|
DNAANIM::Channel& chan = *cit++;
|
||||||
|
desc.keyCount1 = keyframeCount;
|
||||||
|
desc.initRX = chan.i[0];
|
||||||
|
desc.qRX = chan.q[0];
|
||||||
|
desc.initRY = chan.i[1];
|
||||||
|
desc.qRY = chan.q[1];
|
||||||
|
desc.initRZ = chan.i[2];
|
||||||
|
desc.qRZ = chan.q[2];
|
||||||
|
if (bone.second)
|
||||||
|
{
|
||||||
|
DNAANIM::Channel& chan = *cit++;
|
||||||
|
desc.keyCount2 = keyframeCount;
|
||||||
|
desc.initTX = chan.i[0];
|
||||||
|
desc.qTX = chan.q[0];
|
||||||
|
desc.initTY = chan.i[1];
|
||||||
|
desc.qTY = chan.q[1];
|
||||||
|
desc.initTZ = chan.i[2];
|
||||||
|
desc.qTZ = chan.q[2];
|
||||||
|
}
|
||||||
|
desc.write(writer);
|
||||||
}
|
}
|
||||||
desc.write(writer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.writeUBytes(bsData.get(), bsSize);
|
writer.writeUBytes(bsData.get(), bsSize);
|
||||||
|
@ -414,11 +482,23 @@ size_t ANIM::ANIM2::binarySize(size_t __isz) const
|
||||||
__isz = head.binarySize(__isz);
|
__isz = head.binarySize(__isz);
|
||||||
__isz = keyBmp.binarySize(__isz);
|
__isz = keyBmp.binarySize(__isz);
|
||||||
__isz += 8;
|
__isz += 8;
|
||||||
for (const std::pair<atUint32, bool>& bone : bones)
|
if (m_version == 3)
|
||||||
{
|
{
|
||||||
__isz += 17;
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
if (bone.second)
|
{
|
||||||
__isz += 9;
|
__isz += 24;
|
||||||
|
if (bone.second)
|
||||||
|
__isz += 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
|
{
|
||||||
|
__isz += 17;
|
||||||
|
if (bone.second)
|
||||||
|
__isz += 9;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return __isz + DNAANIM::ComputeBitstreamSize(frames.size(), channels);
|
return __isz + DNAANIM::ComputeBitstreamSize(frames.size(), channels);
|
||||||
|
|
|
@ -141,6 +141,58 @@ struct ANIM : BigDNA
|
||||||
return __isz;
|
return __isz;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ChannelDescPC : BigDNA
|
||||||
|
{
|
||||||
|
Delete expl;
|
||||||
|
Value<atUint32> id = 0;
|
||||||
|
Value<atUint32> keyCount1 = 0;
|
||||||
|
Value<atUint32> QinitRX = 0;
|
||||||
|
Value<atUint32> QinitRY = 0;
|
||||||
|
Value<atUint32> QinitRZ = 0;
|
||||||
|
Value<atUint32> keyCount2 = 0;
|
||||||
|
Value<atUint32> QinitTX = 0;
|
||||||
|
Value<atUint32> QinitTY = 0;
|
||||||
|
Value<atUint32> QinitTZ = 0;
|
||||||
|
|
||||||
|
void read(athena::io::IStreamReader& reader)
|
||||||
|
{
|
||||||
|
id = reader.readUint32Big();
|
||||||
|
keyCount1 = reader.readUint32Big();
|
||||||
|
QinitRX = reader.readUint32Big();
|
||||||
|
QinitRY = reader.readUint32Big();
|
||||||
|
QinitRZ = reader.readUint32Big();
|
||||||
|
keyCount2 = reader.readUint32Big();
|
||||||
|
if (keyCount2)
|
||||||
|
{
|
||||||
|
QinitTX = reader.readUint32Big();
|
||||||
|
QinitTY = reader.readUint32Big();
|
||||||
|
QinitTZ = reader.readUint32Big();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void write(athena::io::IStreamWriter& writer) const
|
||||||
|
{
|
||||||
|
writer.writeUint32Big(id);
|
||||||
|
writer.writeUint32Big(keyCount1);
|
||||||
|
writer.writeUint32Big(QinitRX);
|
||||||
|
writer.writeUint32Big(QinitRY);
|
||||||
|
writer.writeUint32Big(QinitRZ);
|
||||||
|
writer.writeUint32Big(keyCount2);
|
||||||
|
if (keyCount2)
|
||||||
|
{
|
||||||
|
writer.writeUint32Big(QinitTX);
|
||||||
|
writer.writeUint32Big(QinitTY);
|
||||||
|
writer.writeUint32Big(QinitTZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t binarySize(size_t __isz) const
|
||||||
|
{
|
||||||
|
__isz += 24;
|
||||||
|
if (keyCount2)
|
||||||
|
__isz += 12;
|
||||||
|
return __isz;
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IANIM> m_anim;
|
std::unique_ptr<IANIM> m_anim;
|
||||||
|
|
|
@ -3,6 +3,19 @@
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void CFBStreamedAnimReaderTotals::Allocate(u32 chanCount)
|
||||||
|
{
|
||||||
|
u32 chan16 = chanCount * 16;
|
||||||
|
u32 chan2 = chanCount * 2;
|
||||||
|
u32 chan32 = chanCount * 32;
|
||||||
|
|
||||||
|
x0_buffer.reset(new u8[chan16 + chanCount + chan2 + chan32]);
|
||||||
|
x4_first16 = x0_buffer.get();
|
||||||
|
x8_second1 = x4_first16 + chan16;
|
||||||
|
xc_third2 = x8_second1 + chanCount;
|
||||||
|
x10_fourth32 = xc_third2 + chan2;
|
||||||
|
}
|
||||||
|
|
||||||
CFBStreamedAnimReaderTotals::CFBStreamedAnimReaderTotals(const CFBStreamedCompression& source)
|
CFBStreamedAnimReaderTotals::CFBStreamedAnimReaderTotals(const CFBStreamedCompression& source)
|
||||||
{
|
{
|
||||||
const CFBStreamedCompression::Header* header =
|
const CFBStreamedCompression::Header* header =
|
||||||
|
@ -16,13 +29,12 @@ CFBStreamedAnimReaderTotals::CFBStreamedAnimReaderTotals(const CFBStreamedCompre
|
||||||
const u8* chans = reinterpret_cast<const u8*>(bitmap + bitmapWordCount + 1);
|
const u8* chans = reinterpret_cast<const u8*>(bitmap + bitmapWordCount + 1);
|
||||||
u32 boneChanCount = *reinterpret_cast<const u32*>(chans);
|
u32 boneChanCount = *reinterpret_cast<const u32*>(chans);
|
||||||
x24_boneChanCount = boneChanCount;
|
x24_boneChanCount = boneChanCount;
|
||||||
|
Allocate(x24_boneChanCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFBStreamedPairOfTotals::CFBStreamedPairOfTotals(const TSubAnimTypeToken<CFBStreamedCompression>& source)
|
CFBStreamedPairOfTotals::CFBStreamedPairOfTotals(const TSubAnimTypeToken<CFBStreamedCompression>& source)
|
||||||
: x0_source(source), xc_rotsAndOffs(source->xc_rotsAndOffs.get()), x14_(*source), x3c_(*source)
|
: x0_source(source), xc_rotsAndOffs(source->xc_rotsAndOffs.get()), x14_(*source), x3c_(*source)
|
||||||
{
|
{
|
||||||
x0_source.Lock();
|
|
||||||
|
|
||||||
const u32* bitmap = reinterpret_cast<const u32*>(source->xc_rotsAndOffs.get() + 9);
|
const u32* bitmap = reinterpret_cast<const u32*>(source->xc_rotsAndOffs.get() + 9);
|
||||||
u32 bitmapWordCount = (bitmap[0] + 31) / 32;
|
u32 bitmapWordCount = (bitmap[0] + 31) / 32;
|
||||||
|
|
||||||
|
@ -30,15 +42,29 @@ CFBStreamedPairOfTotals::CFBStreamedPairOfTotals(const TSubAnimTypeToken<CFBStre
|
||||||
u32 boneChanCount = *reinterpret_cast<const u32*>(chans);
|
u32 boneChanCount = *reinterpret_cast<const u32*>(chans);
|
||||||
chans += 4;
|
chans += 4;
|
||||||
|
|
||||||
for (int b=0 ; b<boneChanCount ; ++b)
|
if (source->m_pc)
|
||||||
{
|
{
|
||||||
chans += 15;
|
for (int b=0 ; b<boneChanCount ; ++b)
|
||||||
|
{
|
||||||
|
chans += 20;
|
||||||
|
|
||||||
u16 tCount = *reinterpret_cast<const u16*>(chans);
|
u32 tCount = *reinterpret_cast<const u32*>(chans);
|
||||||
chans += 2;
|
chans += 4;
|
||||||
|
if (tCount)
|
||||||
|
chans += 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int b=0 ; b<boneChanCount ; ++b)
|
||||||
|
{
|
||||||
|
chans += 15;
|
||||||
|
|
||||||
if (tCount)
|
u16 tCount = *reinterpret_cast<const u16*>(chans);
|
||||||
chans += 9;
|
chans += 2;
|
||||||
|
if (tCount)
|
||||||
|
chans += 9;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x88_ = chans;
|
x88_ = chans;
|
||||||
|
@ -54,7 +80,6 @@ CFBStreamedAnimReader::CFBStreamedAnimReader(const TSubAnimTypeToken<CFBStreamed
|
||||||
: CAnimSourceReaderBase(std::make_unique<TAnimSourceInfo<CFBStreamedCompression>>(source), time),
|
: CAnimSourceReaderBase(std::make_unique<TAnimSourceInfo<CFBStreamedCompression>>(source), time),
|
||||||
x54_source(source), x7c_(source), x114_(x7c_.x10_ ? x7c_.x14_ : x7c_.x3c_)
|
x54_source(source), x7c_(source), x114_(x7c_.x10_ ? x7c_.x14_ : x7c_.x3c_)
|
||||||
{
|
{
|
||||||
x54_source.Lock();
|
|
||||||
x64_steadyStateInfo.x64_duration = x54_source->GetAnimationDuration();
|
x64_steadyStateInfo.x64_duration = x54_source->GetAnimationDuration();
|
||||||
x64_steadyStateInfo.x6c_curRootOffset = x54_source->x14_rootOffset;
|
x64_steadyStateInfo.x6c_curRootOffset = x54_source->x14_rootOffset;
|
||||||
|
|
||||||
|
|
|
@ -24,15 +24,16 @@ public:
|
||||||
class CFBStreamedAnimReaderTotals
|
class CFBStreamedAnimReaderTotals
|
||||||
{
|
{
|
||||||
std::unique_ptr<u8[]> x0_buffer;
|
std::unique_ptr<u8[]> x0_buffer;
|
||||||
u32 x4_ = 0;
|
u8* x4_first16;
|
||||||
u32 x8_ = 0;
|
u8* x8_second1;
|
||||||
u32 xc_ = 0;
|
u8* xc_third2;
|
||||||
u32 x10_ = 0;
|
u8* x10_fourth32;
|
||||||
u32 x14_rotDiv;
|
u32 x14_rotDiv;
|
||||||
float x18_transMult;
|
float x18_transMult;
|
||||||
u32 x1c_ = 0;
|
u32 x1c_ = 0;
|
||||||
bool x20_ = false;
|
bool x20_ = false;
|
||||||
u32 x24_boneChanCount;
|
u32 x24_boneChanCount;
|
||||||
|
void Allocate(u32 chanCount);
|
||||||
public:
|
public:
|
||||||
CFBStreamedAnimReaderTotals(const CFBStreamedCompression& source);
|
CFBStreamedAnimReaderTotals(const CFBStreamedCompression& source);
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
CFBStreamedCompression::CFBStreamedCompression(CInputStream& in, IObjectStore& objStore)
|
CFBStreamedCompression::CFBStreamedCompression(CInputStream& in, IObjectStore& objStore, bool pc)
|
||||||
|
: m_pc(pc)
|
||||||
{
|
{
|
||||||
x0_scratchSize = in.readUint32Big();
|
x0_scratchSize = in.readUint32Big();
|
||||||
x4_evnt = in.readUint32Big();
|
x4_evnt = in.readUint32Big();
|
||||||
|
@ -47,28 +48,46 @@ u8* CFBStreamedCompression::ReadBoneChannelDescriptors(u8* out, CInputStream& in
|
||||||
*reinterpret_cast<u32*>(out) = boneChanCount;
|
*reinterpret_cast<u32*>(out) = boneChanCount;
|
||||||
out += 4;
|
out += 4;
|
||||||
|
|
||||||
for (int b=0 ; b<boneChanCount ; ++b)
|
if (m_pc)
|
||||||
{
|
{
|
||||||
*reinterpret_cast<u32*>(out) = in.readUint32Big();
|
for (int b=0 ; b<boneChanCount ; ++b)
|
||||||
out += 4;
|
|
||||||
|
|
||||||
*reinterpret_cast<u16*>(out) = in.readUint16Big();
|
|
||||||
out += 2;
|
|
||||||
|
|
||||||
for (int i=0 ; i<3 ; ++i)
|
|
||||||
{
|
{
|
||||||
*reinterpret_cast<s16*>(out) = in.readInt16Big();
|
*reinterpret_cast<u32*>(out) = in.readUint32Big();
|
||||||
out += 2;
|
out += 4;
|
||||||
*reinterpret_cast<u8*>(out) = in.readUByte();
|
|
||||||
out += 1;
|
*reinterpret_cast<u32*>(out) = in.readUint32Big();
|
||||||
|
out += 4;
|
||||||
|
|
||||||
|
for (int i=0 ; i<3 ; ++i)
|
||||||
|
{
|
||||||
|
*reinterpret_cast<u32*>(out) = in.readUint32Big();
|
||||||
|
out += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 tCount = in.readUint32Big();
|
||||||
|
*reinterpret_cast<u32*>(out) = tCount;
|
||||||
|
out += 4;
|
||||||
|
|
||||||
|
if (tCount)
|
||||||
|
{
|
||||||
|
for (int i=0 ; i<3 ; ++i)
|
||||||
|
{
|
||||||
|
*reinterpret_cast<u32*>(out) = in.readUint32Big();
|
||||||
|
out += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
u16 tCount = in.readUint16Big();
|
else
|
||||||
*reinterpret_cast<u16*>(out) = tCount;
|
{
|
||||||
out += 2;
|
for (int b=0 ; b<boneChanCount ; ++b)
|
||||||
|
|
||||||
if (tCount)
|
|
||||||
{
|
{
|
||||||
|
*reinterpret_cast<u32*>(out) = in.readUint32Big();
|
||||||
|
out += 4;
|
||||||
|
|
||||||
|
*reinterpret_cast<u16*>(out) = in.readUint16Big();
|
||||||
|
out += 2;
|
||||||
|
|
||||||
for (int i=0 ; i<3 ; ++i)
|
for (int i=0 ; i<3 ; ++i)
|
||||||
{
|
{
|
||||||
*reinterpret_cast<s16*>(out) = in.readInt16Big();
|
*reinterpret_cast<s16*>(out) = in.readInt16Big();
|
||||||
|
@ -76,6 +95,21 @@ u8* CFBStreamedCompression::ReadBoneChannelDescriptors(u8* out, CInputStream& in
|
||||||
*reinterpret_cast<u8*>(out) = in.readUByte();
|
*reinterpret_cast<u8*>(out) = in.readUByte();
|
||||||
out += 1;
|
out += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u16 tCount = in.readUint16Big();
|
||||||
|
*reinterpret_cast<u16*>(out) = tCount;
|
||||||
|
out += 2;
|
||||||
|
|
||||||
|
if (tCount)
|
||||||
|
{
|
||||||
|
for (int i=0 ; i<3 ; ++i)
|
||||||
|
{
|
||||||
|
*reinterpret_cast<s16*>(out) = in.readInt16Big();
|
||||||
|
out += 2;
|
||||||
|
*reinterpret_cast<u8*>(out) = in.readUByte();
|
||||||
|
out += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,22 +121,47 @@ u32 CFBStreamedCompression::ComputeBitstreamWords(const u8* chans)
|
||||||
u32 boneChanCount = *reinterpret_cast<const u32*>(chans);
|
u32 boneChanCount = *reinterpret_cast<const u32*>(chans);
|
||||||
chans += 4;
|
chans += 4;
|
||||||
|
|
||||||
u16 keyCount = *reinterpret_cast<const u16*>(chans);
|
u32 keyCount;
|
||||||
|
|
||||||
u32 totalBits = 0;
|
u32 totalBits = 0;
|
||||||
for (u32 c=0 ; c<boneChanCount ; ++c)
|
if (m_pc)
|
||||||
{
|
{
|
||||||
totalBits += *reinterpret_cast<const u8*>(chans + 0x8);
|
keyCount = *reinterpret_cast<const u32*>(chans + 0x4);
|
||||||
totalBits += *reinterpret_cast<const u8*>(chans + 0xb);
|
for (u32 c=0 ; c<boneChanCount ; ++c)
|
||||||
totalBits += *reinterpret_cast<const u8*>(chans + 0xe);
|
|
||||||
u16 tKeyCount = *reinterpret_cast<const u16*>(chans + 0xf);
|
|
||||||
chans += 0x11;
|
|
||||||
if (tKeyCount)
|
|
||||||
{
|
{
|
||||||
|
chans += 0x8;
|
||||||
|
totalBits += *reinterpret_cast<const u32*>(chans) & 0xff;
|
||||||
|
totalBits += *reinterpret_cast<const u32*>(chans + 0x4) & 0xff;
|
||||||
|
totalBits += *reinterpret_cast<const u32*>(chans + 0x8) & 0xff;
|
||||||
|
u32 tKeyCount = *reinterpret_cast<const u32*>(chans + 0xc);
|
||||||
|
chans += 0x10;
|
||||||
|
if (tKeyCount)
|
||||||
|
{
|
||||||
|
totalBits += *reinterpret_cast<const u32*>(chans) & 0xff;
|
||||||
|
totalBits += *reinterpret_cast<const u32*>(chans + 0x4) & 0xff;
|
||||||
|
totalBits += *reinterpret_cast<const u32*>(chans + 0x8) & 0xff;
|
||||||
|
chans += 0xc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keyCount = *reinterpret_cast<const u16*>(chans + 0x4);
|
||||||
|
for (u32 c=0 ; c<boneChanCount ; ++c)
|
||||||
|
{
|
||||||
|
chans += 0x6;
|
||||||
totalBits += *reinterpret_cast<const u8*>(chans + 0x2);
|
totalBits += *reinterpret_cast<const u8*>(chans + 0x2);
|
||||||
totalBits += *reinterpret_cast<const u8*>(chans + 0x5);
|
totalBits += *reinterpret_cast<const u8*>(chans + 0x5);
|
||||||
totalBits += *reinterpret_cast<const u8*>(chans + 0x8);
|
totalBits += *reinterpret_cast<const u8*>(chans + 0x8);
|
||||||
chans += 0x9;
|
u16 tKeyCount = *reinterpret_cast<const u16*>(chans + 0x9);
|
||||||
|
chans += 0xb;
|
||||||
|
if (tKeyCount)
|
||||||
|
{
|
||||||
|
totalBits += *reinterpret_cast<const u8*>(chans + 0x2);
|
||||||
|
totalBits += *reinterpret_cast<const u8*>(chans + 0x5);
|
||||||
|
totalBits += *reinterpret_cast<const u8*>(chans + 0x8);
|
||||||
|
chans += 0x9;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,17 +51,18 @@ class CFBStreamedCompression
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool m_pc;
|
||||||
u32 x0_scratchSize;
|
u32 x0_scratchSize;
|
||||||
ResId x4_evnt;
|
ResId x4_evnt;
|
||||||
TLockedToken<CAnimPOIData> x8_evntToken;
|
TLockedToken<CAnimPOIData> x8_evntToken;
|
||||||
std::unique_ptr<u32[]> xc_rotsAndOffs;
|
std::unique_ptr<u32[]> xc_rotsAndOffs;
|
||||||
zeus::CVector3f x14_rootOffset;
|
zeus::CVector3f x14_rootOffset;
|
||||||
|
|
||||||
static u8* ReadBoneChannelDescriptors(u8* out, CInputStream& in);
|
u8* ReadBoneChannelDescriptors(u8* out, CInputStream& in);
|
||||||
static std::unique_ptr<u32[]> GetRotationsAndOffsets(u32 words, CInputStream& in);
|
u32 ComputeBitstreamWords(const u8* chans);
|
||||||
static u32 ComputeBitstreamWords(const u8* chans);
|
std::unique_ptr<u32[]> GetRotationsAndOffsets(u32 words, CInputStream& in);
|
||||||
public:
|
public:
|
||||||
CFBStreamedCompression(CInputStream& in, IObjectStore& objStore);
|
CFBStreamedCompression(CInputStream& in, IObjectStore& objStore, bool pc);
|
||||||
CCharAnimTime GetAnimationDuration() const { return reinterpret_cast<const Header*>(xc_rotsAndOffs.get())->duration; }
|
CCharAnimTime GetAnimationDuration() const { return reinterpret_cast<const Header*>(xc_rotsAndOffs.get())->duration; }
|
||||||
const TLockedToken<CAnimPOIData>& GetPOIToken() const { return x8_evntToken; }
|
const TLockedToken<CAnimPOIData>& GetPOIToken() const { return x8_evntToken; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,7 +38,7 @@ struct CSteadyStateAnimInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
using TSubAnimTypeToken = TCachedToken<T>;
|
using TSubAnimTypeToken = TLockedToken<T>;
|
||||||
|
|
||||||
class IAnimReader
|
class IAnimReader
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue