Various ANIM reader imps

This commit is contained in:
Jack Andersen 2016-04-11 13:35:37 -10:00
parent b10bd229e6
commit faacffba77
21 changed files with 613 additions and 16 deletions

View File

@ -0,0 +1,32 @@
#include "CAllFormatsAnimSource.hpp"
#include "logvisor/logvisor.hpp"
namespace urde
{
static logvisor::Module Log("urde::CAllFormatsAnimSource");
void CAnimFormatUnion::SubConstruct(u8* storage, EAnimFormat fmt,
CInputStream& in, IObjectStore& store)
{
switch (fmt)
{
case EAnimFormat::Uncompressed:
new (storage) CAnimSource(in, store);
break;
default:
Log.report(logvisor::Fatal, "unable to read ANIM format %d", int(fmt));
}
}
CAnimFormatUnion::CAnimFormatUnion(CInputStream& in, IObjectStore& store)
{
x0_format = EAnimFormat(in.readUint32Big());
SubConstruct(x4_storage, x0_format, in, store);
}
CAllFormatsAnimSource::CAllFormatsAnimSource(CInputStream& in,
IObjectStore& store,
const SObjectTag& tag)
: CAnimFormatUnion(in, store), x74_tag(tag) {}
}

View File

@ -0,0 +1,40 @@
#ifndef __PSHAG_CALLFORMATANIMSOURCE_HPP__
#define __PSHAG_CALLFORMATANIMSOURCE_HPP__
#include "RetroTypes.hpp"
#include "zeus/CVector3f.hpp"
#include "CAnimSource.hpp"
namespace urde
{
class IObjectStore;
enum class EAnimFormat
{
Uncompressed,
Unknown,
BitstreamCompressed
};
class CAnimFormatUnion
{
EAnimFormat x0_format;
u8 x4_storage[sizeof(CAnimSource)];
static void SubConstruct(u8* storage, EAnimFormat fmt,
CInputStream& in, IObjectStore& store);
public:
CAnimFormatUnion(CInputStream& in, IObjectStore& store);
operator CAnimSource&() {return *reinterpret_cast<CAnimSource*>(x4_storage);}
};
class CAllFormatsAnimSource : public CAnimFormatUnion
{
zeus::CVector3f x68_;
SObjectTag x74_tag;
public:
CAllFormatsAnimSource(CInputStream& in, IObjectStore& store, const SObjectTag& tag);
};
}
#endif // __PSHAG_CALLFORMATANIMSOURCE_HPP__

View File

@ -0,0 +1,17 @@
#include "CAnimPOIData.hpp"
#include "CToken.hpp"
namespace urde
{
CAnimPOIData::CAnimPOIData(CInputStream& in)
{
}
CFactoryFnReturn AnimPOIDataFactory(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer& parms)
{
return TToken<CAnimPOIData>::GetIObjObjectFor(std::make_unique<CAnimPOIData>(in));
}
}

View File

@ -0,0 +1,33 @@
#ifndef __PSHAG_CANIMPOIDATA_HPP__
#define __PSHAG_CANIMPOIDATA_HPP__
#include "CFactoryMgr.hpp"
#include "CBoolPOINode.hpp"
#include "CInt32POINode.hpp"
#include "CParticlePOINode.hpp"
#include "CSoundPOINode.hpp"
namespace urde
{
class CAnimPOIData
{
std::vector<CBoolPOINode> x4_boolNodes;
std::vector<CInt32POINode> x14_int32Nodes;
std::vector<CParticlePOINode> x24_particleNodes;
std::vector<CSoundPOINode> x34_soundNodes;
public:
CAnimPOIData(CInputStream& in);
const std::vector<CBoolPOINode>& GetBoolPOIStream() const {return x4_boolNodes;}
const std::vector<CInt32POINode>& GetInt32POIStream() const {return x14_int32Nodes;}
const std::vector<CParticlePOINode>& GetParticlePOIStream() const {return x24_particleNodes;}
const std::vector<CSoundPOINode>& GetSoundPOIStream() const {return x34_soundNodes;}
};
CFactoryFnReturn AnimPOIDataFactory(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer& parms);
}
#endif // __PSHAG_CANIMPOIDATA_HPP__

View File

@ -0,0 +1,243 @@
#include "CAnimSource.hpp"
#include "CAnimPOIData.hpp"
#include "CSegId.hpp"
namespace urde
{
static float ClampZeroToOne(float in)
{
return std::max(0.f, std::min(1.f, in));
}
u32 RotationAndOffsetStorage::DataSizeInBytes(u32 rotPerFrame, u32 transPerFrame, u32 frameCount)
{
return (transPerFrame * 12 + rotPerFrame * 16) * frameCount;
}
void RotationAndOffsetStorage::CopyRotationsAndOffsets(const std::vector<zeus::CQuaternion>& rots,
const std::vector<zeus::CVector3f>& offs,
u32 frameCount, float* arrOut)
{
std::vector<zeus::CQuaternion>::const_iterator rit = rots.cbegin();
std::vector<zeus::CVector3f>::const_iterator oit = offs.cbegin();
u32 rotsPerFrame = rots.size() / frameCount;
u32 offsPerFrame = offs.size() / frameCount;
for (u32 i=0 ; i<frameCount ; ++i)
{
for (u32 j=0 ; j<rotsPerFrame ; ++j)
{
const zeus::CQuaternion& rot = *rit++;
arrOut[0] = rot.w;
arrOut[1] = rot.x;
arrOut[2] = rot.y;
arrOut[3] = rot.z;
arrOut += 4;
}
for (u32 j=0 ; j<offsPerFrame ; ++j)
{
const zeus::CVector3f& off = *oit++;
arrOut[0] = off.x;
arrOut[1] = off.y;
arrOut[2] = off.z;
arrOut += 3;
}
}
}
std::unique_ptr<float[]>
RotationAndOffsetStorage::GetRotationsAndOffsets(const std::vector<zeus::CQuaternion>& rots,
const std::vector<zeus::CVector3f>& offs,
u32 frameCount)
{
u32 size = DataSizeInBytes(rots.size() / frameCount, offs.size() / frameCount, frameCount);
std::unique_ptr<float[]> ret(new float[(size / 4 + 1) * 4]);
CopyRotationsAndOffsets(rots, offs, frameCount, ret.get());
return ret;
}
RotationAndOffsetStorage::CRotationAndOffsetVectors::CRotationAndOffsetVectors(CInputStream& in)
{
u32 quatCount = in.readUint32Big();
x0_rotations.reserve(quatCount);
for (u32 i=0 ; i<quatCount ; ++i)
{
x0_rotations.emplace_back();
x0_rotations.back().readBig(in);
}
u32 vecCount = in.readUint32Big();
x10_offsets.reserve(vecCount);
for (u32 i=0 ; i<vecCount ; ++i)
{
x10_offsets.emplace_back();
x10_offsets.back().readBig(in);
}
}
u32 RotationAndOffsetStorage::GetFrameSizeInBytes() const
{
return (x10_transPerFrame * 12 + xc_rotPerFrame * 16);
}
RotationAndOffsetStorage::RotationAndOffsetStorage(const CRotationAndOffsetVectors& vectors,
u32 frameCount)
{
x0_storage = GetRotationsAndOffsets(vectors.x0_rotations, vectors.x10_offsets, frameCount);
x8_frameCount = frameCount;
xc_rotPerFrame = vectors.x0_rotations.size() / frameCount;
x10_transPerFrame = vectors.x10_offsets.size() / frameCount;
}
static std::vector<u8> ReadIndexTable(CInputStream& in)
{
std::vector<u8> ret;
u32 count = in.readUint32Big();
ret.reserve(count);
for (u32 i=0 ; i<count ; ++i)
ret.push_back(in.readUByte());
return ret;
}
void CAnimSource::CalcAverageVelocity()
{
u8 rootIdx = x20_rotationChannels[3];
u8 rootTransIdx = x30_translationChannels[rootIdx];
float accum = 0.f;
const u32 floatsPerFrame = x40_data.x10_transPerFrame * 3 + x40_data.xc_rotPerFrame * 4;
const u32 rotFloatsPerFrame = x40_data.xc_rotPerFrame * 4;
for (u32 i=1 ; i<x10_frameCount ; ++i)
{
const float* frameDataA =
&x40_data.x0_storage[(i-1)*floatsPerFrame+rotFloatsPerFrame+rootTransIdx*3];
const float* frameDataB =
&x40_data.x0_storage[i*floatsPerFrame+rotFloatsPerFrame+rootTransIdx*3];
zeus::CVector3f vecA(frameDataA[0], frameDataA[1], frameDataA[2]);
zeus::CVector3f vecB(frameDataB[0], frameDataB[1], frameDataB[2]);
float frameVel = (vecB - vecA).magnitude();
if (frameVel > 0.00001f)
accum += frameVel;
}
x60_averageVelocity = accum / x0_duration;
}
CAnimSource::CAnimSource(CInputStream& in, IObjectStore& store)
: x0_duration(in.readFloatBig()),
x4_(in.readUint32Big()),
x8_interval(in.readFloatBig()),
xc_(in.readUint32Big()),
x10_frameCount(in.readUint32Big()),
x1c_(in.readUint32Big()),
x20_rotationChannels(ReadIndexTable(in)),
x30_translationChannels(ReadIndexTable(in)),
x40_data(RotationAndOffsetStorage::CRotationAndOffsetVectors(in), x10_frameCount),
x54_evntId(in.readUint32Big())
{
if (x54_evntId)
{
x58_evntData = store.GetObj({SBIG('EVNT'), x54_evntId});
x58_evntData.GetObj();
}
CalcAverageVelocity();
}
void CAnimSource::GetSegStatementSet(const CSegIdList& list,
CSegStatementSet& set,
const CCharAnimTime& time) const
{
u32 frameIdx = unsigned(time / x8_interval);
float remTime = time - frameIdx * x8_interval;
if (std::fabs(remTime) < 0.00001f)
remTime = 0.f;
float t = ClampZeroToOne(remTime / x8_interval);
/* TODO: Finish */
}
const std::vector<CSoundPOINode>& CAnimSource::GetSoundPOIStream() const
{
return x58_evntData->GetSoundPOIStream();
}
const std::vector<CParticlePOINode>& CAnimSource::GetParticlePOIStream() const
{
return x58_evntData->GetParticlePOIStream();
}
const std::vector<CInt32POINode>& CAnimSource::GetInt32POIStream() const
{
return x58_evntData->GetInt32POIStream();
}
const std::vector<CBoolPOINode>& CAnimSource::GetBoolPOIStream() const
{
return x58_evntData->GetBoolPOIStream();
}
zeus::CQuaternion CAnimSource::GetRotation(const CSegId& seg, const CCharAnimTime& time) const
{
u8 rotIdx = x20_rotationChannels[seg.GetId()];
if (rotIdx != 0xff)
{
u32 frameIdx = unsigned(time / x8_interval);
float remTime = time - frameIdx * x8_interval;
if (std::fabs(remTime) < 0.00001f)
remTime = 0.f;
float t = ClampZeroToOne(remTime / x8_interval);
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* frameDataB =
&x40_data.x0_storage[(frameIdx+1)*floatsPerFrame+rotIdx*4];
zeus::CQuaternion quatA(frameDataA[0], frameDataA[1], frameDataA[2], frameDataA[3]);
zeus::CQuaternion quatB(frameDataB[0], frameDataB[1], frameDataB[2], frameDataB[3]);
return zeus::CQuaternion::slerp(quatA, quatB, t);
}
else
{
return {};
}
}
zeus::CVector3f CAnimSource::GetOffset(const CSegId& seg, const CCharAnimTime& time) const
{
u8 rotIdx = x20_rotationChannels[seg.GetId()];
if (rotIdx != 0xff)
{
u8 transIdx = x30_translationChannels[rotIdx];
if (transIdx == 0xff)
return {};
u32 frameIdx = unsigned(time / x8_interval);
float tmp = time - frameIdx * x8_interval;
if (std::fabs(tmp) < 0.00001f)
tmp = 0.f;
float t = ClampZeroToOne(tmp / x8_interval);
const u32 floatsPerFrame = x40_data.x10_transPerFrame * 3 + 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* frameDataB =
&x40_data.x0_storage[(frameIdx-1)*floatsPerFrame+rotFloatsPerFrame+transIdx*3];
zeus::CVector3f vecA(frameDataA[0], frameDataA[1], frameDataA[2]);
zeus::CVector3f vecB(frameDataB[0], frameDataB[1], frameDataB[2]);
return zeus::CVector3f::lerp(vecA, vecB, t);
}
else
{
return {};
}
}
bool CAnimSource::HasOffset(const CSegId& seg) const
{
u8 rotIdx = x20_rotationChannels[seg.GetId()];
if (rotIdx == 0xff)
return false;
u8 transIdx = x30_translationChannels[rotIdx];
return transIdx != 0xff;
}
}

View File

@ -0,0 +1,84 @@
#ifndef __PSHAG_CANIMSOURCE_HPP__
#define __PSHAG_CANIMSOURCE_HPP__
#include "RetroTypes.hpp"
#include "CCharAnimTime.hpp"
#include "zeus/CQuaternion.hpp"
#include "zeus/CVector3f.hpp"
#include "CToken.hpp"
namespace urde
{
class IObjectStore;
class CSegIdList;
class CSegStatementSet;
class CSegId;
class CAnimPOIData;
class CBoolPOINode;
class CInt32POINode;
class CParticlePOINode;
class CSoundPOINode;
class RotationAndOffsetStorage
{
friend class CAnimSource;
std::unique_ptr<float[]> x0_storage;
u32 x8_frameCount;
u32 xc_rotPerFrame;
u32 x10_transPerFrame;
std::unique_ptr<float[]> GetRotationsAndOffsets(const std::vector<zeus::CQuaternion>& rots,
const std::vector<zeus::CVector3f>& offs,
u32 frameCount);
static void CopyRotationsAndOffsets(const std::vector<zeus::CQuaternion>& rots,
const std::vector<zeus::CVector3f>& offs,
u32 frameCount, float*);
static u32 DataSizeInBytes(u32 rotPerFrame, u32 transPerFrame, u32 frameCount);
public:
struct CRotationAndOffsetVectors
{
std::vector<zeus::CQuaternion> x0_rotations;
std::vector<zeus::CVector3f> x10_offsets;
CRotationAndOffsetVectors(CInputStream& in);
};
u32 GetFrameSizeInBytes() const;
RotationAndOffsetStorage(const CRotationAndOffsetVectors& vectors, u32 frameCount);
};
class CAnimSource
{
float x0_duration;
u32 x4_;
float x8_interval;
u32 xc_;
u32 x10_frameCount;
u32 x1c_;
std::vector<u8> x20_rotationChannels;
std::vector<u8> x30_translationChannels;
RotationAndOffsetStorage x40_data;
TResId x54_evntId;
TCachedToken<CAnimPOIData> x58_evntData;
float x60_averageVelocity;
void CalcAverageVelocity();
public:
CAnimSource(CInputStream& in, IObjectStore& store);
void GetSegStatementSet(const CSegIdList& list,
CSegStatementSet& set,
const CCharAnimTime& time) const;
const std::vector<CSoundPOINode>& GetSoundPOIStream() const;
const std::vector<CParticlePOINode>& GetParticlePOIStream() const;
const std::vector<CInt32POINode>& GetInt32POIStream() const;
const std::vector<CBoolPOINode>& GetBoolPOIStream() const;
zeus::CQuaternion GetRotation(const CSegId& seg, const CCharAnimTime& time) const;
zeus::CVector3f GetOffset(const CSegId& seg, const CCharAnimTime& time) const;
bool HasOffset(const CSegId& seg) const;
};
}
#endif // __PSHAG_CANIMSOURCE_HPP__

View File

@ -0,0 +1,18 @@
#include "CAnimSourceReader.hpp"
namespace urde
{
CAnimSourceReaderBase::CAnimSourceReaderBase(std::unique_ptr<IAnimSourceInfo>&& sourceInfo,
const CCharAnimTime& time)
: x4_sourceInfo(std::move(sourceInfo)), xc_curTime(time) {}
CAnimSourceReader::CAnimSourceReader(const TSubAnimTypeToken<CAnimSource>& source,
const CCharAnimTime& time)
: CAnimSourceReaderBase(std::make_unique<CAnimSourceInfo>(source), CCharAnimTime()),
x54_source(source)
{
CAnimSource* sourceData = x54_source.GetObj();
}
}

View File

@ -0,0 +1,84 @@
#ifndef __PSHAG_CANIMSOURCEREADER_HPP__
#define __PSHAG_CANIMSOURCEREADER_HPP__
#include "IAnimReader.hpp"
#include "CToken.hpp"
#include "CAnimSource.hpp"
#include "CParticleData.hpp"
namespace urde
{
template <class T>
class TSubAnimTypeToken : public TCachedToken<T>
{
};
class IAnimSourceInfo
{
public:
virtual ~IAnimSourceInfo() = default;
virtual bool HasPOIData() const=0;
virtual void GetBoolPOIStream() const=0;
virtual void GetInt32POIStream() const=0;
virtual void GetParticlePOIStream() const=0;
virtual void GetSoundPOIStream() const=0;
virtual void GetAnimationDuration() const=0;
};
class CAnimSourceInfo : public IAnimSourceInfo
{
TSubAnimTypeToken<CAnimSource> x4_token;
public:
CAnimSourceInfo(const TSubAnimTypeToken<CAnimSource>& token);
bool HasPOIData() const;
void GetBoolPOIStream() const;
void GetInt32POIStream() const;
void GetParticlePOIStream() const;
void GetSoundPOIStream() const;
void GetAnimationDuration() const;
};
class CAnimSourceReaderBase : public IAnimReader
{
std::unique_ptr<IAnimSourceInfo> x4_sourceInfo;
CCharAnimTime xc_curTime;
u32 x14_passedBoolCount;
u32 x18_passedIntCount;
u32 x1c_passedParticleCount;
u32 x20_passedSoundCount;
std::vector<std::pair<std::string, bool>> x24_boolPOIs;
std::vector<std::pair<std::string, s32>> x34_int32POIs;
std::vector<std::pair<std::string, CParticleData::EParentedMode>> x44_particlePOIs;
std::map<std::string, CParticleData::EParentedMode> GetUniqueParticlePOIs() const;
std::map<std::string, s32> GetUniqueInt32POIs() const;
std::map<std::string, bool> GetUniqueBoolPOIs() const;
void PostConstruct(const CCharAnimTime& time);
protected:
void UpdatePOIStates();
public:
CAnimSourceReaderBase(std::unique_ptr<IAnimSourceInfo>&& sourceInfo,
const CCharAnimTime& time);
u32 VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut, u32 capacity, u32 iterator, u32) const;
u32 VGetInt32POIList(const CCharAnimTime& time, CInt32POINode* listOut, u32 capacity, u32 iterator, u32) const;
u32 VGetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut, u32 capacity, u32 iterator, u32) const;
u32 VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator, u32) const;
void VGetBoolPOIState(const char*) const;
void VGetInt32POIState(const char*) const;
void VGetParticlePOIState(const char*) const;
};
class CAnimSourceReader : public CAnimSourceReaderBase
{
TSubAnimTypeToken<CAnimSource> x54_source;
public:
CAnimSourceReader(const TSubAnimTypeToken<CAnimSource>& source, const CCharAnimTime& time);
};
}
#endif // __PSHAG_CANIMSOURCEREADER_HPP__

View File

@ -1,11 +1,16 @@
#ifndef __PSHAG_CANIMTREEANIMREADERCONTAINER_HPP__
#define __PSHAG_CANIMTREEANIMREADERCONTAINER_HPP__
#include "CAnimTreeNode.hpp"
namespace urde
{
class CAnimTreeAnimReaderContainer
class CAnimTreeAnimReaderContainer : public CAnimTreeNode
{
std::shared_ptr<IAnimReader> x14_
public:
CAnimTreeAnimReaderContainer(const std::string& name, std::shared_ptr<>);
};
}

View File

@ -21,8 +21,8 @@ public:
SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const;
void Depth() const;
void VGetContributionOfHighestInfluence() const;
void VGetNumChildren() const;
void VGetBestUnblendedChild() const;
u32 VGetNumChildren() const;
std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const;
};
}

View File

@ -0,0 +1,16 @@
#include "CAnimTreeNode.hpp"
namespace urde
{
u32 CAnimTreeNode::GetNumChildren() const
{
return VGetNumChildren();
}
std::shared_ptr<IAnimReader> CAnimTreeNode::GetBestUnblendedChild() const
{
return VGetBestUnblendedChild();
}
}

View File

@ -12,6 +12,10 @@ class CAnimTreeNode : public IAnimReader
public:
CAnimTreeNode(const std::string& name) : x4_name(name) {}
bool IsCAnimTreeNode() const {return true;}
void GetContributionOfHighestInfluence() const;
u32 GetNumChildren() const;
std::shared_ptr<IAnimReader> GetBestUnblendedChild() const;
};
}

View File

@ -90,7 +90,7 @@ void CAnimTreeSingleChild::Depth() const
{
}
void CAnimTreeSingleChild::VGetNumChildren() const
u32 CAnimTreeSingleChild::VGetNumChildren() const
{
}

View File

@ -29,7 +29,7 @@ public:
void VSetPhase(float);
SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const;
void Depth() const;
void VGetNumChildren() const;
u32 VGetNumChildren() const;
};
}

View File

@ -55,9 +55,14 @@ add_library(RuntimeCommonCharacter
CHalfTransition.hpp CHalfTransition.cpp
CTimeScaleFunctions.hpp CTimeScaleFunctions.cpp
CParticleData.hpp CParticleData.cpp
CAnimPOIData.hpp CAnimPOIData.cpp
CPOINode.hpp CPOINode.cpp
CBoolPOINode.hpp CBoolPOINode.cpp
CInt32POINode.hpp CInt32POINode.cpp
CSoundPOINode.hpp CSoundPOINode.cpp
CParticlePOINode.hpp CParticlePOINode.cpp
CAnimSourceReader.hpp CAnimSourceReader.cpp
CAnimSource.hpp CAnimSource.cpp
CAllFormatsAnimSource.hpp CAllFormatsAnimSource.cpp
CSegStatementSet.hpp CSegStatementSet.cpp
CBodyState.hpp)

View File

@ -7,15 +7,16 @@
namespace urde
{
enum class EParentedMode
{
Initial,
ContinuousEmitter,
ContinuousSystem
};
class CParticleData
{
public:
enum class EParentedMode
{
Initial,
ContinuousEmitter,
ContinuousSystem
};
private:
u32 x0_duration;
SObjectTag x4_particle;
std::string xc_boneName;

View File

@ -14,6 +14,8 @@ class CSegId
public:
CSegId() = default;
CSegId(CInputStream& in) : x0_segId(in.readUint32Big()) {}
operator bool() const {return x0_segId != 0xff;}
u8 GetId() const {return x0_segId;}
};
}

View File

View File

@ -0,0 +1,13 @@
#ifndef __PSHAG_CSEGSTATEMENTSET_HPP__
#define __PSHAG_CSEGSTATEMENTSET_HPP__
namespace urde
{
class CSegStatementSet
{
};
}
#endif // __PSHAG_CSEGSTATEMENTSET_HPP__

View File

@ -44,13 +44,13 @@ public:
virtual void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const=0;
virtual void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const=0;
virtual void VClone() const=0;
virtual std::unique_ptr<IAnimReader> VSimplified() {return {};}
virtual std::shared_ptr<IAnimReader> VSimplified() {return {};}
virtual void VSetPhase(float)=0;
virtual SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const;
virtual void Depth() const=0;
virtual void VGetContributionOfHighestInfluence() const=0;
virtual void VGetNumChildren() const=0;
virtual void VGetBestUnblendedChild() const=0;
virtual u32 VGetNumChildren() const=0;
virtual std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const=0;
u32 GetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut, u32 capacity, u32 iterator, u32) const;
u32 GetInt32POIList(const CCharAnimTime& time, CInt32POINode* listOut, u32 capacity, u32 iterator, u32) const;

2
hecl

@ -1 +1 @@
Subproject commit d6b0f29fbce05f193822fbd4d05cd9b4d59d36f2
Subproject commit ca8f24d78bbe80c5d61ed0f25d83176be204f1b8