mirror of https://github.com/AxioDL/metaforce.git
Additional CFBStreamedCompression imps
This commit is contained in:
parent
8dacdd18b8
commit
6d35a656fd
|
@ -5,81 +5,273 @@ namespace urde
|
||||||
|
|
||||||
void CFBStreamedAnimReaderTotals::Allocate(u32 chanCount)
|
void CFBStreamedAnimReaderTotals::Allocate(u32 chanCount)
|
||||||
{
|
{
|
||||||
u32 chan16 = chanCount * 16;
|
|
||||||
u32 chan2 = chanCount * 2;
|
u32 chan2 = chanCount * 2;
|
||||||
u32 chan32 = chanCount * 32;
|
u32 chan32 = chanCount * 32;
|
||||||
|
|
||||||
x0_buffer.reset(new u8[chan16 + chanCount + chan2 + chan32]);
|
x0_buffer.reset(new u8[chan32 + chanCount + chan2 + chan32]);
|
||||||
x4_first16 = x0_buffer.get();
|
x4_cumulativeInts32 = reinterpret_cast<s32*>(x0_buffer.get());
|
||||||
x8_second1 = x4_first16 + chan16;
|
x8_hasTrans1 = reinterpret_cast<u8*>(x4_cumulativeInts32 + chanCount * 8);
|
||||||
xc_third2 = x8_second1 + chanCount;
|
xc_segIds2 = reinterpret_cast<u16*>(x8_hasTrans1 + chanCount);
|
||||||
x10_fourth32 = xc_third2 + chan2;
|
x10_computedFloats32 = reinterpret_cast<float*>(xc_segIds2 + chanCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFBStreamedAnimReaderTotals::CFBStreamedAnimReaderTotals(const CFBStreamedCompression& source)
|
void CFBStreamedAnimReaderTotals::Initialize(const CFBStreamedCompression& source)
|
||||||
{
|
{
|
||||||
const CFBStreamedCompression::Header* header =
|
const u8* chans = source.GetPerChannelHeaders();
|
||||||
reinterpret_cast<const CFBStreamedCompression::Header*>(source.xc_rotsAndOffs.get());
|
|
||||||
const u32* bitmap = reinterpret_cast<const u32*>(source.xc_rotsAndOffs.get() + 9);
|
|
||||||
u32 bitmapWordCount = (bitmap[0] + 31) / 32;
|
|
||||||
|
|
||||||
x14_rotDiv = header->rotDiv;
|
|
||||||
x18_transMult = header->translationMult;
|
|
||||||
|
|
||||||
const u8* chans = reinterpret_cast<const u8*>(bitmap + bitmapWordCount + 1);
|
|
||||||
u32 boneChanCount = *reinterpret_cast<const u32*>(chans);
|
|
||||||
x24_boneChanCount = boneChanCount;
|
|
||||||
Allocate(x24_boneChanCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
CFBStreamedPairOfTotals::CFBStreamedPairOfTotals(const TSubAnimTypeToken<CFBStreamedCompression>& source)
|
|
||||||
: x0_source(source), xc_rotsAndOffs(source->xc_rotsAndOffs.get()), x14_(*source), x3c_(*source)
|
|
||||||
{
|
|
||||||
const u32* bitmap = reinterpret_cast<const u32*>(source->xc_rotsAndOffs.get() + 9);
|
|
||||||
u32 bitmapWordCount = (bitmap[0] + 31) / 32;
|
|
||||||
|
|
||||||
const u8* chans = reinterpret_cast<const u8*>(bitmap + bitmapWordCount + 1);
|
|
||||||
u32 boneChanCount = *reinterpret_cast<const u32*>(chans);
|
u32 boneChanCount = *reinterpret_cast<const u32*>(chans);
|
||||||
chans += 4;
|
chans += 4;
|
||||||
|
|
||||||
if (source->m_pc)
|
if (source.m_pc)
|
||||||
{
|
{
|
||||||
for (int b=0 ; b<boneChanCount ; ++b)
|
for (int b=0 ; b<boneChanCount ; ++b)
|
||||||
{
|
{
|
||||||
chans += 20;
|
xc_segIds2[b] = *reinterpret_cast<const u32*>(chans);
|
||||||
|
chans += 8;
|
||||||
|
|
||||||
|
s32* cumulativesOut = &x4_cumulativeInts32[8*b];
|
||||||
|
const s32* cumulativesIn = reinterpret_cast<const s32*>(chans);
|
||||||
|
cumulativesOut[0] = cumulativesIn[0] >> 8;
|
||||||
|
cumulativesOut[1] = cumulativesIn[1] >> 8;
|
||||||
|
cumulativesOut[2] = cumulativesIn[2] >> 8;
|
||||||
|
chans += 12;
|
||||||
|
|
||||||
u32 tCount = *reinterpret_cast<const u32*>(chans);
|
u32 tCount = *reinterpret_cast<const u32*>(chans);
|
||||||
chans += 4;
|
chans += 4;
|
||||||
if (tCount)
|
if (tCount)
|
||||||
|
{
|
||||||
|
x8_hasTrans1[b] = true;
|
||||||
|
const s32* cumulativesIn = reinterpret_cast<const s32*>(chans);
|
||||||
|
cumulativesOut[3] = cumulativesIn[0] >> 8;
|
||||||
|
cumulativesOut[4] = cumulativesIn[1] >> 8;
|
||||||
|
cumulativesOut[5] = cumulativesIn[2] >> 8;
|
||||||
chans += 12;
|
chans += 12;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
x8_hasTrans1[b] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int b=0 ; b<boneChanCount ; ++b)
|
for (int b=0 ; b<boneChanCount ; ++b)
|
||||||
{
|
{
|
||||||
chans += 15;
|
xc_segIds2[b] = *reinterpret_cast<const u32*>(chans);
|
||||||
|
chans += 6;
|
||||||
|
|
||||||
|
s32* cumulativesOut = &x4_cumulativeInts32[8*b];
|
||||||
|
cumulativesOut[0] = *reinterpret_cast<const s16*>(chans);
|
||||||
|
cumulativesOut[1] = *reinterpret_cast<const s16*>(chans + 3);
|
||||||
|
cumulativesOut[2] = *reinterpret_cast<const s16*>(chans + 6);
|
||||||
|
chans += 9;
|
||||||
|
|
||||||
u16 tCount = *reinterpret_cast<const u16*>(chans);
|
u16 tCount = *reinterpret_cast<const u16*>(chans);
|
||||||
chans += 2;
|
chans += 2;
|
||||||
if (tCount)
|
if (tCount)
|
||||||
|
{
|
||||||
|
x8_hasTrans1[b] = true;
|
||||||
|
cumulativesOut[3] = *reinterpret_cast<const s16*>(chans);
|
||||||
|
cumulativesOut[4] = *reinterpret_cast<const s16*>(chans + 3);
|
||||||
|
cumulativesOut[5] = *reinterpret_cast<const s16*>(chans + 6);
|
||||||
chans += 9;
|
chans += 9;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
x8_hasTrans1[b] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
x88_ = chans;
|
CFBStreamedAnimReaderTotals::CFBStreamedAnimReaderTotals(const CFBStreamedCompression& source)
|
||||||
x8c_ = &x88_;
|
{
|
||||||
x90_ = *reinterpret_cast<const u32*>(*x8c_);
|
const CFBStreamedCompression::Header& header = source.MainHeader();
|
||||||
|
x14_rotDiv = header.rotDiv;
|
||||||
|
x18_transMult = header.translationMult;
|
||||||
|
|
||||||
|
const u8* chans = source.GetPerChannelHeaders();
|
||||||
|
x24_boneChanCount = *reinterpret_cast<const u32*>(chans);
|
||||||
|
Allocate(x24_boneChanCount);
|
||||||
|
Initialize(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFBStreamedAnimReaderTotals::IncrementInto(CBitLevelLoader& loader,
|
||||||
|
const CFBStreamedCompression& source,
|
||||||
|
CFBStreamedAnimReaderTotals& dest)
|
||||||
|
{
|
||||||
|
const u8* chans = source.GetPerChannelHeaders();
|
||||||
|
u32 boneChanCount = *reinterpret_cast<const u32*>(chans);
|
||||||
|
chans += 4;
|
||||||
|
|
||||||
|
if (source.m_pc)
|
||||||
|
{
|
||||||
|
for (int b=0 ; b<boneChanCount ; ++b)
|
||||||
|
{
|
||||||
|
chans += 8;
|
||||||
|
|
||||||
|
const s32* cumulativesIn = &x4_cumulativeInts32[8*b];
|
||||||
|
s32* cumulativesOut = &dest.x4_cumulativeInts32[8*b];
|
||||||
|
const s32* qsIn = reinterpret_cast<const s32*>(chans);
|
||||||
|
cumulativesOut[0] = loader.LoadBool();
|
||||||
|
cumulativesOut[1] = cumulativesIn[1] + loader.LoadSigned(qsIn[0] & 0xff);
|
||||||
|
cumulativesOut[2] = cumulativesIn[2] + loader.LoadSigned(qsIn[1] & 0xff);
|
||||||
|
cumulativesOut[3] = cumulativesIn[3] + loader.LoadSigned(qsIn[2] & 0xff);
|
||||||
|
chans += 12;
|
||||||
|
|
||||||
|
u32 tCount = *reinterpret_cast<const u32*>(chans);
|
||||||
|
chans += 4;
|
||||||
|
if (tCount)
|
||||||
|
{
|
||||||
|
const s32* qsIn = reinterpret_cast<const s32*>(chans);
|
||||||
|
cumulativesOut[4] = cumulativesIn[4] + loader.LoadSigned(qsIn[0] & 0xff);
|
||||||
|
cumulativesOut[5] = cumulativesIn[5] + loader.LoadSigned(qsIn[1] & 0xff);
|
||||||
|
cumulativesOut[6] = cumulativesIn[6] + loader.LoadSigned(qsIn[2] & 0xff);
|
||||||
|
chans += 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int b=0 ; b<boneChanCount ; ++b)
|
||||||
|
{
|
||||||
|
chans += 6;
|
||||||
|
|
||||||
|
const s32* cumulativesIn = &x4_cumulativeInts32[8*b];
|
||||||
|
s32* cumulativesOut = &dest.x4_cumulativeInts32[8*b];
|
||||||
|
cumulativesOut[0] = loader.LoadBool();
|
||||||
|
cumulativesOut[1] = cumulativesIn[1] + loader.LoadSigned(*reinterpret_cast<const u8*>(chans + 2));
|
||||||
|
cumulativesOut[2] = cumulativesIn[2] + loader.LoadSigned(*reinterpret_cast<const u8*>(chans + 5));
|
||||||
|
cumulativesOut[3] = cumulativesIn[3] + loader.LoadSigned(*reinterpret_cast<const u8*>(chans + 8));
|
||||||
|
chans += 9;
|
||||||
|
|
||||||
|
u16 tCount = *reinterpret_cast<const u16*>(chans);
|
||||||
|
chans += 2;
|
||||||
|
if (tCount)
|
||||||
|
{
|
||||||
|
cumulativesOut[4] = cumulativesIn[4] + loader.LoadSigned(*reinterpret_cast<const u8*>(chans + 2));
|
||||||
|
cumulativesOut[5] = cumulativesIn[5] + loader.LoadSigned(*reinterpret_cast<const u8*>(chans + 5));
|
||||||
|
cumulativesOut[6] = cumulativesIn[5] + loader.LoadSigned(*reinterpret_cast<const u8*>(chans + 8));
|
||||||
|
chans += 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFBStreamedAnimReaderTotals::CalculateDown()
|
||||||
|
{
|
||||||
|
for (int b=0 ; b<x24_boneChanCount ; ++b)
|
||||||
|
{
|
||||||
|
const s32* cumulativesIn = &x4_cumulativeInts32[8*b];
|
||||||
|
float* compOut = &x10_computedFloats32[8*b];
|
||||||
|
|
||||||
|
float q = M_PIF / 2.f / float(x14_rotDiv);
|
||||||
|
compOut[1] = std::sin(cumulativesIn[1] * q);
|
||||||
|
compOut[2] = std::sin(cumulativesIn[2] * q);
|
||||||
|
compOut[3] = std::sin(cumulativesIn[3] * q);
|
||||||
|
|
||||||
|
compOut[0] = std::sqrt(std::max(1.f - (compOut[1] * compOut[1] +
|
||||||
|
compOut[2] * compOut[2] +
|
||||||
|
compOut[3] * compOut[3]), 0.f));
|
||||||
|
if (cumulativesIn[0])
|
||||||
|
compOut[0] = -compOut[0];
|
||||||
|
|
||||||
|
if (x8_hasTrans1[b])
|
||||||
|
{
|
||||||
|
compOut[4] = cumulativesIn[4] * x18_transMult;
|
||||||
|
compOut[5] = cumulativesIn[5] * x18_transMult;
|
||||||
|
compOut[6] = cumulativesIn[6] * x18_transMult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CFBStreamedPairOfTotals::CFBStreamedPairOfTotals(const TSubAnimTypeToken<CFBStreamedCompression>& source)
|
||||||
|
: x0_source(source), xc_rotsAndOffs(source->xc_rotsAndOffs.get()), x14_(*source), x3c_(*source)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 CBitLevelLoader::LoadUnsigned(u8 q)
|
||||||
|
{
|
||||||
|
u32 byteCur = (m_bitIdx / 32) * 4;
|
||||||
|
u32 bitRem = m_bitIdx % 32;
|
||||||
|
|
||||||
|
/* Fill 32 bit buffer with region containing bits */
|
||||||
|
/* Make them least significant */
|
||||||
|
u32 tempBuf = hecl::SBig(*reinterpret_cast<const u32*>(m_data + byteCur)) >> bitRem;
|
||||||
|
|
||||||
|
/* If this shift underflows the value, buffer the next 32 bits */
|
||||||
|
/* And tack onto shifted buffer */
|
||||||
|
if ((bitRem + q) > 32)
|
||||||
|
{
|
||||||
|
u32 tempBuf2 = hecl::SBig(*reinterpret_cast<const u32*>(m_data + byteCur + 4));
|
||||||
|
tempBuf |= (tempBuf2 << (32 - bitRem));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mask it */
|
||||||
|
u32 mask = (1 << q) - 1;
|
||||||
|
tempBuf &= mask;
|
||||||
|
|
||||||
|
/* Return delta value */
|
||||||
|
m_bitIdx += q;
|
||||||
|
return tempBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 CBitLevelLoader::LoadSigned(u8 q)
|
||||||
|
{
|
||||||
|
u32 byteCur = (m_bitIdx / 32) * 4;
|
||||||
|
u32 bitRem = m_bitIdx % 32;
|
||||||
|
|
||||||
|
/* Fill 32 bit buffer with region containing bits */
|
||||||
|
/* Make them least significant */
|
||||||
|
u32 tempBuf = hecl::SBig(*reinterpret_cast<const u32*>(m_data + byteCur)) >> bitRem;
|
||||||
|
|
||||||
|
/* If this shift underflows the value, buffer the next 32 bits */
|
||||||
|
/* And tack onto shifted buffer */
|
||||||
|
if ((bitRem + q) > 32)
|
||||||
|
{
|
||||||
|
u32 tempBuf2 = hecl::SBig(*reinterpret_cast<const u32*>(m_data + byteCur + 4));
|
||||||
|
tempBuf |= (tempBuf2 << (32 - bitRem));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mask it */
|
||||||
|
u32 mask = (1 << q) - 1;
|
||||||
|
tempBuf &= mask;
|
||||||
|
|
||||||
|
/* Sign extend */
|
||||||
|
u32 sign = (tempBuf >> (q - 1)) & 0x1;
|
||||||
|
if (sign)
|
||||||
|
tempBuf |= ~0u << q;
|
||||||
|
|
||||||
|
/* Return delta value */
|
||||||
|
m_bitIdx += q;
|
||||||
|
return s32(tempBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBitLevelLoader::LoadBool()
|
||||||
|
{
|
||||||
|
u32 byteCur = (m_bitIdx / 32) * 4;
|
||||||
|
u32 bitRem = m_bitIdx % 32;
|
||||||
|
|
||||||
|
/* Fill 32 bit buffer with region containing bits */
|
||||||
|
/* Make them least significant */
|
||||||
|
u32 tempBuf = hecl::SBig(*reinterpret_cast<const u32*>(m_data + byteCur)) >> bitRem;
|
||||||
|
|
||||||
|
/* That's it */
|
||||||
|
m_bitIdx += 1;
|
||||||
|
return tempBuf & 0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSegIdToIndexConverter::CSegIdToIndexConverter(const CFBStreamedAnimReaderTotals& totals)
|
CSegIdToIndexConverter::CSegIdToIndexConverter(const CFBStreamedAnimReaderTotals& totals)
|
||||||
{
|
{
|
||||||
|
for (u32 b=0 ; b<totals.x24_boneChanCount ; ++b)
|
||||||
|
{
|
||||||
|
u16 segId = totals.xc_segIds2[b];
|
||||||
|
if (segId >= 96)
|
||||||
|
continue;
|
||||||
|
x0_indices[segId] = b;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CFBStreamedAnimReader::CFBStreamedAnimReader(const TSubAnimTypeToken<CFBStreamedCompression>& source, const CCharAnimTime& time)
|
CFBStreamedAnimReader::CFBStreamedAnimReader(const TSubAnimTypeToken<CFBStreamedCompression>& source, const CCharAnimTime& time)
|
||||||
: CAnimSourceReaderBase(std::make_unique<TAnimSourceInfo<CFBStreamedCompression>>(source), time), x54_source(source),
|
: CAnimSourceReaderBase(std::make_unique<TAnimSourceInfo<CFBStreamedCompression>>(source), time), x54_source(source),
|
||||||
x64_steadyStateInfo(source->IsLooping(), source->GetAnimationDuration(), source->GetRootOffset()),
|
x64_steadyStateInfo(source->IsLooping(), source->GetAnimationDuration(), source->GetRootOffset()),
|
||||||
x7c_(source), x114_(x7c_.x10_ ? x7c_.x14_ : x7c_.x3c_)
|
x7c_totals(source), x88_bitstreamData(source->GetBitstreamPointer()), x8c_bitLoader(x88_bitstreamData),
|
||||||
|
x114_segIdToIndex(x7c_totals.x10_ ? x7c_totals.x14_ : x7c_totals.x3c_)
|
||||||
{
|
{
|
||||||
PostConstruct(time);
|
PostConstruct(time);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
class CBitLevelLoader;
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class TAnimSourceInfo : public IAnimSourceInfo
|
class TAnimSourceInfo : public IAnimSourceInfo
|
||||||
|
@ -23,19 +24,24 @@ public:
|
||||||
|
|
||||||
class CFBStreamedAnimReaderTotals
|
class CFBStreamedAnimReaderTotals
|
||||||
{
|
{
|
||||||
|
friend class CSegIdToIndexConverter;
|
||||||
std::unique_ptr<u8[]> x0_buffer;
|
std::unique_ptr<u8[]> x0_buffer;
|
||||||
u8* x4_first16;
|
s32* x4_cumulativeInts32; /* Used to be 16 per channel */
|
||||||
u8* x8_second1;
|
u8* x8_hasTrans1;
|
||||||
u8* xc_third2;
|
u16* xc_segIds2;
|
||||||
u8* x10_fourth32;
|
float* x10_computedFloats32;
|
||||||
u32 x14_rotDiv;
|
u32 x14_rotDiv;
|
||||||
float x18_transMult;
|
float x18_transMult;
|
||||||
u32 x1c_ = 0;
|
u32 x1c_curKey = 0;
|
||||||
bool x20_ = false;
|
bool x20_ = false;
|
||||||
u32 x24_boneChanCount;
|
u32 x24_boneChanCount;
|
||||||
void Allocate(u32 chanCount);
|
void Allocate(u32 chanCount);
|
||||||
|
void Initialize(const CFBStreamedCompression& source);
|
||||||
public:
|
public:
|
||||||
CFBStreamedAnimReaderTotals(const CFBStreamedCompression& source);
|
CFBStreamedAnimReaderTotals(const CFBStreamedCompression& source);
|
||||||
|
void IncrementInto(CBitLevelLoader& loader, const CFBStreamedCompression& source,
|
||||||
|
CFBStreamedAnimReaderTotals& dest);
|
||||||
|
void CalculateDown();
|
||||||
};
|
};
|
||||||
|
|
||||||
class CFBStreamedPairOfTotals
|
class CFBStreamedPairOfTotals
|
||||||
|
@ -47,27 +53,38 @@ class CFBStreamedPairOfTotals
|
||||||
bool x10_ = true;
|
bool x10_ = true;
|
||||||
CFBStreamedAnimReaderTotals x14_;
|
CFBStreamedAnimReaderTotals x14_;
|
||||||
CFBStreamedAnimReaderTotals x3c_;
|
CFBStreamedAnimReaderTotals x3c_;
|
||||||
const u8* x88_;
|
|
||||||
const u8** x8c_;
|
|
||||||
u32 x90_;
|
|
||||||
u32 x94_ = 0;
|
|
||||||
public:
|
public:
|
||||||
CFBStreamedPairOfTotals(const TSubAnimTypeToken<CFBStreamedCompression>& source);
|
CFBStreamedPairOfTotals(const TSubAnimTypeToken<CFBStreamedCompression>& source);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CBitLevelLoader
|
||||||
|
{
|
||||||
|
const u8* m_data;
|
||||||
|
size_t m_bitIdx = 0;
|
||||||
|
public:
|
||||||
|
CBitLevelLoader(const void* data)
|
||||||
|
: m_data(reinterpret_cast<const u8*>(data)) {}
|
||||||
|
u32 LoadUnsigned(u8 q);
|
||||||
|
s32 LoadSigned(u8 q);
|
||||||
|
bool LoadBool();
|
||||||
|
};
|
||||||
|
|
||||||
class CSegIdToIndexConverter
|
class CSegIdToIndexConverter
|
||||||
{
|
{
|
||||||
u32 x0_indices[96] = {-1};
|
u32 x0_indices[96] = {-1};
|
||||||
public:
|
public:
|
||||||
CSegIdToIndexConverter(const CFBStreamedAnimReaderTotals& totals);
|
CSegIdToIndexConverter(const CFBStreamedAnimReaderTotals& totals);
|
||||||
|
u32 SegIdToIndex(const CSegId& id) const { return x0_indices[id]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class CFBStreamedAnimReader : public CAnimSourceReaderBase
|
class CFBStreamedAnimReader : public CAnimSourceReaderBase
|
||||||
{
|
{
|
||||||
TSubAnimTypeToken<CFBStreamedCompression> x54_source;
|
TSubAnimTypeToken<CFBStreamedCompression> x54_source;
|
||||||
CSteadyStateAnimInfo x64_steadyStateInfo;
|
CSteadyStateAnimInfo x64_steadyStateInfo;
|
||||||
CFBStreamedPairOfTotals x7c_;
|
CFBStreamedPairOfTotals x7c_totals;
|
||||||
CSegIdToIndexConverter x114_;
|
const u8* x88_bitstreamData;
|
||||||
|
CBitLevelLoader x8c_bitLoader;
|
||||||
|
CSegIdToIndexConverter x114_segIdToIndex;
|
||||||
public:
|
public:
|
||||||
CFBStreamedAnimReader(const TSubAnimTypeToken<CFBStreamedCompression>& source, const CCharAnimTime& time);
|
CFBStreamedAnimReader(const TSubAnimTypeToken<CFBStreamedCompression>& source, const CCharAnimTime& time);
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,50 @@ CFBStreamedCompression::CFBStreamedCompression(CInputStream& in, IObjectStore& o
|
||||||
x8_evntToken = objStore.GetObj(SObjectTag{FOURCC('EVNT'), x4_evnt});
|
x8_evntToken = objStore.GetObj(SObjectTag{FOURCC('EVNT'), x4_evnt});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const u8* CFBStreamedCompression::GetPerChannelHeaders() const
|
||||||
|
{
|
||||||
|
const u32* bitmap = reinterpret_cast<const u32*>(xc_rotsAndOffs.get() + 9);
|
||||||
|
u32 bitmapWordCount = (bitmap[0] + 31) / 32;
|
||||||
|
return reinterpret_cast<const u8*>(bitmap + bitmapWordCount + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8* CFBStreamedCompression::GetBitstreamPointer() const
|
||||||
|
{
|
||||||
|
const u32* bitmap = reinterpret_cast<const u32*>(xc_rotsAndOffs.get() + 9);
|
||||||
|
u32 bitmapWordCount = (bitmap[0] + 31) / 32;
|
||||||
|
|
||||||
|
const u8* chans = reinterpret_cast<const u8*>(bitmap + bitmapWordCount + 1);
|
||||||
|
u32 boneChanCount = *reinterpret_cast<const u32*>(chans);
|
||||||
|
chans += 4;
|
||||||
|
|
||||||
|
if (m_pc)
|
||||||
|
{
|
||||||
|
for (int b=0 ; b<boneChanCount ; ++b)
|
||||||
|
{
|
||||||
|
chans += 20;
|
||||||
|
|
||||||
|
u32 tCount = *reinterpret_cast<const u32*>(chans);
|
||||||
|
chans += 4;
|
||||||
|
if (tCount)
|
||||||
|
chans += 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int b=0 ; b<boneChanCount ; ++b)
|
||||||
|
{
|
||||||
|
chans += 15;
|
||||||
|
|
||||||
|
u16 tCount = *reinterpret_cast<const u16*>(chans);
|
||||||
|
chans += 2;
|
||||||
|
if (tCount)
|
||||||
|
chans += 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return chans;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<u32[]> CFBStreamedCompression::GetRotationsAndOffsets(u32 words, CInputStream& in)
|
std::unique_ptr<u32[]> CFBStreamedCompression::GetRotationsAndOffsets(u32 words, CInputStream& in)
|
||||||
{
|
{
|
||||||
std::unique_ptr<u32[]> ret(new u32[words]);
|
std::unique_ptr<u32[]> ret(new u32[words]);
|
||||||
|
|
|
@ -67,6 +67,8 @@ private:
|
||||||
public:
|
public:
|
||||||
CFBStreamedCompression(CInputStream& in, IObjectStore& objStore, bool pc);
|
CFBStreamedCompression(CInputStream& in, IObjectStore& objStore, bool pc);
|
||||||
const Header& MainHeader() const { return *reinterpret_cast<const Header*>(xc_rotsAndOffs.get()); }
|
const Header& MainHeader() const { return *reinterpret_cast<const Header*>(xc_rotsAndOffs.get()); }
|
||||||
|
const u8* GetPerChannelHeaders() const;
|
||||||
|
const u8* GetBitstreamPointer() const;
|
||||||
bool IsLooping() const { return MainHeader().looping; }
|
bool IsLooping() const { return MainHeader().looping; }
|
||||||
CCharAnimTime GetAnimationDuration() const { return MainHeader().duration; }
|
CCharAnimTime GetAnimationDuration() const { return MainHeader().duration; }
|
||||||
const zeus::CVector3f& GetRootOffset() const { return x14_rootOffset; }
|
const zeus::CVector3f& GetRootOffset() const { return x14_rootOffset; }
|
||||||
|
|
Loading…
Reference in New Issue