Additive animation integration

This commit is contained in:
Jack Andersen 2017-02-28 20:02:54 -10:00
parent 5277d445d3
commit 7334074798
26 changed files with 204 additions and 59 deletions

View File

@ -27,18 +27,17 @@ public:
float GetFadeOutDuration() const {return x4_fadeOutDur;}
};
enum class EAdditivePlaybackPhase
{
None,
FadingIn,
FadingOut,
FadedIn,
FadedOut
};
class CAdditiveAnimPlayback
{
public:
enum class EAdditivePlaybackPhase
{
None,
FadingIn,
FadingOut,
FadedIn,
FadedOut
};
private:
CAdditiveAnimationInfo x0_info;
std::shared_ptr<CAnimTreeNode> x8_anim;
float xc_targetWeight;
@ -57,7 +56,12 @@ public:
void SetWeight(float w);
float GetTargetWeight() const {return xc_targetWeight;}
bool IsActive() const {return x14_active;}
void SetActive(bool active) {x14_active = active;}
const std::shared_ptr<CAnimTreeNode>& GetAnim() const {return x8_anim;}
std::shared_ptr<CAnimTreeNode>& GetAnim() {return x8_anim;}
EAdditivePlaybackPhase GetPhase() const {return x1c_phase;}
void Set20(bool b) {x20_ = b;}
bool Get20() const {return x20_;}
};
}

View File

@ -24,6 +24,8 @@
namespace urde
{
static logvisor::Module Log("CAnimData");
rstl::reserved_vector<CBoolPOINode, 8>CAnimData::g_BoolPOINodes;
rstl::reserved_vector<CInt32POINode, 16> CAnimData::g_Int32POINodes;
rstl::reserved_vector<CParticlePOINode, 20> CAnimData::g_ParticlePOINodes;
@ -74,6 +76,23 @@ CAnimData::CAnimData(ResId id,
x108_aabb = xd8_modelData->GetModel()->GetAABB();
x120_particleDB.CacheParticleDesc(xc_charInfo.GetParticleResData());
CHierarchyPoseBuilder pb(xcc_layoutData);
pb.BuildNoScale(x224_pose);
x220_30_poseBuilt = true;
if (defaultAnim == -1)
{
defaultAnim = 0;
Log.report(logvisor::Warning, "Character %s has invalid initial animation, so defaulting to first.",
character.GetCharacterName().c_str());
}
std::shared_ptr<CAnimTreeNode> treeNode =
GetAnimationManager()->GetAnimationTree(character.GetAnimationIndex(defaultAnim),
CMetaAnimTreeBuildOrders::NoSpecialOrders());
if (treeNode != x1f8_animRoot)
x1f8_animRoot = treeNode;
}
ResId CAnimData::GetEventResourceIdForAnimResourceId(ResId id) const
@ -88,34 +107,79 @@ void CAnimData::AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stS
additive.second.AddToSegStatementSet(list, *xcc_layoutData.GetObj(), stSet);
}
static void AdvanceAnimationTree(std::weak_ptr<CAnimTreeNode>& anim, const CCharAnimTime& dt)
SAdvancementResults CAnimData::AdvanceAdditiveAnim(std::shared_ptr<CAnimTreeNode>& anim, const CCharAnimTime& time)
{
SAdvancementResults ret = anim->VAdvanceView(time);
std::pair<std::unique_ptr<IAnimReader>, bool> simplified = anim->Simplified();
if (simplified.second)
anim = std::static_pointer_cast<CAnimTreeNode>(std::shared_ptr<IAnimReader>(std::move(simplified.first)));
return ret;
}
SAdvancementDeltas CAnimData::AdvanceAdditiveAnims(float dt)
{
CCharAnimTime time(dt);
SAdvancementDeltas deltas = {};
for (std::pair<u32, CAdditiveAnimPlayback>& additive : x434_additiveAnims)
{
std::shared_ptr<CAnimTreeNode>& anim = additive.second.GetAnim();
if (additive.second.IsActive())
{
while (time.GreaterThanZero() && std::fabs(time) >= 0.00001f)
{
//additive.second.GetAnim()->GetInt32POIList(time, );
x210_passedIntCount += anim->GetInt32POIList(time, g_Int32POINodes.data(), 16, x210_passedIntCount, 0);
x20c_passedBoolCount += anim->GetBoolPOIList(time, g_BoolPOINodes.data(), 8, x20c_passedBoolCount, 0);
x214_passedParticleCount += anim->GetParticlePOIList(time, g_ParticlePOINodes.data(), 8, x214_passedParticleCount, 0);
x218_passedSoundCount += anim->GetSoundPOIList(time, g_SoundPOINodes.data(), 8, x218_passedSoundCount, 0);
SAdvancementResults results = AdvanceAdditiveAnim(anim, time);
deltas.x0_posDelta += results.x8_deltas.x0_posDelta;
deltas.xc_rotDelta *= results.x8_deltas.xc_rotDelta;
time = results.x0_remTime;
}
}
else
{
CCharAnimTime remTime = anim->VGetTimeRemaining();
while (remTime.GreaterThanZero() && std::fabs(remTime) >= 0.00001f)
{
x210_passedIntCount += anim->GetInt32POIList(time, g_Int32POINodes.data(), 16, x210_passedIntCount, 0);
x20c_passedBoolCount += anim->GetBoolPOIList(time, g_BoolPOINodes.data(), 8, x20c_passedBoolCount, 0);
x214_passedParticleCount += anim->GetParticlePOIList(time, g_ParticlePOINodes.data(), 8, x214_passedParticleCount, 0);
x218_passedSoundCount += anim->GetSoundPOIList(time, g_SoundPOINodes.data(), 8, x218_passedSoundCount, 0);
SAdvancementResults results = AdvanceAdditiveAnim(anim, time);
deltas.x0_posDelta += results.x8_deltas.x0_posDelta;
deltas.xc_rotDelta *= results.x8_deltas.xc_rotDelta;
CCharAnimTime tmpTime = anim->VGetTimeRemaining();
if (tmpTime < results.x0_remTime)
remTime = tmpTime;
else
remTime = results.x0_remTime;
}
}
}
return {};
return deltas;
}
SAdvancementDeltas CAnimData::UpdateAdditiveAnims(float dt)
{
for (auto it = x434_additiveAnims.begin() ; it != x434_additiveAnims.end() ;)
{
it->second.Update(dt);
CCharAnimTime timeRem = it->second.GetAnim()->VGetTimeRemaining();
if (timeRem.EpsilonZero() && it->second.Get20())
it->second.FadeOut();
if (it->second.GetPhase() == EAdditivePlaybackPhase::FadedOut)
{
it = x434_additiveAnims.erase(it);
continue;
}
++it;
}
return AdvanceAdditiveAnims(dt);
}
@ -153,12 +217,42 @@ bool CAnimData::IsAdditiveAnimationActive(u32 idx) const
return search->second.IsActive();
}
void CAnimData::DelAdditiveAnimation(u32)
void CAnimData::DelAdditiveAnimation(u32 idx)
{
u32 animIdx = xc_charInfo.GetAnimationIndex(idx);
for (std::pair<u32, CAdditiveAnimPlayback>& anim : x434_additiveAnims)
{
if (anim.first == animIdx &&
anim.second.GetPhase() != EAdditivePlaybackPhase::FadingOut &&
anim.second.GetPhase() != EAdditivePlaybackPhase::FadedOut)
{
anim.second.FadeOut();
return;
}
}
}
void CAnimData::AddAdditiveAnimation(u32, float, bool, bool)
void CAnimData::AddAdditiveAnimation(u32 idx, float weight, bool active, bool b)
{
u32 animIdx = xc_charInfo.GetAnimationIndex(idx);
for (std::pair<u32, CAdditiveAnimPlayback>& anim : x434_additiveAnims)
{
if (anim.first == animIdx &&
anim.second.GetPhase() != EAdditivePlaybackPhase::FadingOut &&
anim.second.GetPhase() != EAdditivePlaybackPhase::FadedOut)
{
anim.second.SetActive(active);
anim.second.SetWeight(weight);
anim.second.Set20(!anim.second.IsActive() && b);
return;
}
}
std::shared_ptr<CAnimTreeNode> node =
GetAnimationManager()->GetAnimationTree(animIdx, CMetaAnimTreeBuildOrders::NoSpecialOrders());
const CAdditiveAnimationInfo& info = x0_charFactory->FindAdditiveInfo(animIdx);
x434_additiveAnims.emplace_back(std::make_pair(idx, CAdditiveAnimPlayback(node, weight, active, info, b)));
}
std::shared_ptr<CAnimationManager> CAnimData::GetAnimationManager()
@ -559,23 +653,18 @@ SAdvancementDeltas CAnimData::AdvanceIgnoreParticles(float dt, CRandom16& random
void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus::CQuaternion& quat)
{
SAdvancementResults results;
std::shared_ptr<IAnimReader> simplified;
std::pair<std::unique_ptr<IAnimReader>, bool> simplified = {};
if (!x104_)
{
results = x1f8_animRoot->VAdvanceView(time);
simplified = x1f8_animRoot->VSimplified();
simplified = x1f8_animRoot->Simplified();
}
if (simplified)
if (simplified.second)
{
if (simplified->IsCAnimTreeNode())
{
if (x1f8_animRoot != simplified)
x1f8_animRoot = std::static_pointer_cast<CAnimTreeNode>(std::move(simplified));
}
else
x1f8_animRoot.reset();
x1f8_animRoot = std::static_pointer_cast<CAnimTreeNode>(
std::shared_ptr<IAnimReader>(std::move(simplified.first)));
}
if ((x220_28_ || x220_27_) && x210_passedIntCount > 0)

View File

@ -78,6 +78,7 @@ class CParticlePOINode;
class CSoundPOINode;
class IAnimReader;
struct SAdvancementDeltas;
struct SAdvancementResults;
class CAnimData
{
@ -153,6 +154,7 @@ public:
ResId GetEventResourceIdForAnimResourceId(ResId) const;
void AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stSet);
static SAdvancementResults AdvanceAdditiveAnim(std::shared_ptr<CAnimTreeNode>& anim, const CCharAnimTime& time);
SAdvancementDeltas AdvanceAdditiveAnims(float);
SAdvancementDeltas UpdateAdditiveAnims(float);
bool IsAdditiveAnimation(u32) const;

View File

@ -355,9 +355,9 @@ SAdvancementResults CAnimSourceReader::VReverseView(const CCharAnimTime& dt)
}
}
std::shared_ptr<IAnimReader> CAnimSourceReader::VClone() const
std::unique_ptr<IAnimReader> CAnimSourceReader::VClone() const
{
return std::make_shared<CAnimSourceReader>(*this);
return std::make_unique<CAnimSourceReader>(*this);
}
void CAnimSourceReader::VGetSegStatementSet(const CSegIdList& list,

View File

@ -86,7 +86,7 @@ public:
bool VSupportsReverseView() const {return true;}
void VSetPhase(float);
SAdvancementResults VReverseView(const CCharAnimTime& time);
std::shared_ptr<IAnimReader> VClone() const;
std::unique_ptr<IAnimReader> VClone() const;
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const;
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const;
SAdvancementResults VAdvanceView(const CCharAnimTime& a);

View File

@ -115,14 +115,12 @@ void CAnimTreeAnimReaderContainer::VGetSegStatementSet(const CSegIdList& list, C
return x14_reader->VGetSegStatementSet(list, setOut, time);
}
std::shared_ptr<IAnimReader> CAnimTreeAnimReaderContainer::VClone() const
std::unique_ptr<IAnimReader> CAnimTreeAnimReaderContainer::VClone() const
{
std::shared_ptr<IAnimReader> ret =
std::make_shared<CAnimTreeAnimReaderContainer>(x4_name, x14_reader->Clone(), x1c_animDbIdx);
return ret;
return std::make_unique<CAnimTreeAnimReaderContainer>(x4_name, x14_reader->Clone(), x1c_animDbIdx);
}
std::shared_ptr<IAnimReader> CAnimTreeAnimReaderContainer::VSimplified()
std::pair<std::unique_ptr<IAnimReader>, bool> CAnimTreeAnimReaderContainer::VSimplified()
{
return {};
}

View File

@ -36,8 +36,8 @@ public:
CParticleData::EParentedMode VGetParticlePOIState(const char*) const;
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const;
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const;
std::shared_ptr<IAnimReader> VClone() const;
std::shared_ptr<IAnimReader> VSimplified();
std::unique_ptr<IAnimReader> VClone() const;
std::pair<std::unique_ptr<IAnimReader>, bool> VSimplified();
void VSetPhase(float);
SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const;
};

View File

@ -34,7 +34,7 @@ CSteadyStateAnimInfo CAnimTreeBlend::VGetSteadyStateAnimInfo() const
return {};
}
std::shared_ptr<IAnimReader> CAnimTreeBlend::VClone() const
std::unique_ptr<IAnimReader> CAnimTreeBlend::VClone() const
{
return {};
}

View File

@ -22,7 +22,7 @@ public:
SAdvancementResults VAdvanceView(const CCharAnimTime& a);
CCharAnimTime VGetTimeRemaining() const;
CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const;
std::shared_ptr<IAnimReader> VClone() const;
std::unique_ptr<IAnimReader> VClone() const;
void SetBlendingWeight(float w);
float VGetBlendingWeight() const;
};

View File

@ -33,7 +33,8 @@ std::shared_ptr<IAnimReader> CAnimTreeSequence::VGetBestUnblendedChild() const
std::shared_ptr<IAnimReader> ch = x14_child->GetBestUnblendedChild();
if (!ch)
return ch;
return std::make_shared<CAnimTreeSequence>(std::static_pointer_cast<CAnimTreeNode>(ch->Clone()),
return std::make_shared<CAnimTreeSequence>(std::static_pointer_cast<CAnimTreeNode>(
std::shared_ptr<IAnimReader>(ch->Clone())),
x28_, x18_, x4_name, x3c_fundamentals, x94_curTime);
}
@ -88,9 +89,10 @@ u32 CAnimTreeSequence::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode
x3c_fundamentals.GetSoundPointsOfInterest(), x94_curTime);
}
std::shared_ptr<IAnimReader> CAnimTreeSequence::VClone() const
std::unique_ptr<IAnimReader> CAnimTreeSequence::VClone() const
{
return std::make_shared<CAnimTreeSequence>(std::static_pointer_cast<CAnimTreeNode>(x14_child->Clone()),
return std::make_unique<CAnimTreeSequence>(std::static_pointer_cast<CAnimTreeNode>(
std::shared_ptr<IAnimReader>(x14_child->Clone())),
x28_, x18_, x4_name, x3c_fundamentals, x94_curTime);
}

View File

@ -39,7 +39,7 @@ public:
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;
std::shared_ptr<IAnimReader> VClone() const;
std::unique_ptr<IAnimReader> VClone() const;
};
}

View File

@ -42,7 +42,7 @@ void CAnimTreeTimeScale::VSetPhase(float phase)
x14_child->VSetPhase(phase);
}
std::shared_ptr<IAnimReader> CAnimTreeTimeScale::VSimplified()
std::pair<std::unique_ptr<IAnimReader>, bool> CAnimTreeTimeScale::VSimplified()
{
return {};
}

View File

@ -19,7 +19,7 @@ public:
CCharAnimTime GetRealLifeTime(const CCharAnimTime&) const;
void VSetPhase(float);
std::shared_ptr<IAnimReader> VSimplified();
std::pair<std::unique_ptr<IAnimReader>, bool> VSimplified();
};
}

View File

@ -49,10 +49,12 @@ CSteadyStateAnimInfo CAnimTreeTransition::VGetSteadyStateAnimInfo() const
return CSteadyStateAnimInfo(bInfo.IsLooping(), x24_, bInfo.GetOffset());
}
std::shared_ptr<IAnimReader> CAnimTreeTransition::VClone() const
std::unique_ptr<IAnimReader> CAnimTreeTransition::VClone() const
{
return std::make_shared<CAnimTreeTransition>(x20_31_b1, std::static_pointer_cast<CAnimTreeNode>(x14_a->Clone()),
std::static_pointer_cast<CAnimTreeNode>(x18_b->Clone()), x24_, x2c_,
return std::make_unique<CAnimTreeTransition>(x20_31_b1, std::static_pointer_cast<CAnimTreeNode>(
std::shared_ptr<IAnimReader>(x14_a->Clone())),
std::static_pointer_cast<CAnimTreeNode>(
std::shared_ptr<IAnimReader>(x18_b->Clone())), x24_, x2c_,
x34_, x35_, x1c_flags, x4_name, x36_);
}

View File

@ -26,7 +26,7 @@ public:
std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const;
CCharAnimTime VGetTimeRemaining() const;
CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const;
std::shared_ptr<IAnimReader> VClone() const;
std::unique_ptr<IAnimReader> VClone() const;
SAdvancementResults VAdvanceView(const CCharAnimTime& a) const;
void SetBlendingWeight(float w);
float VGetBlendingWeight() const;

View File

@ -49,5 +49,5 @@ zeus::CQuaternion CAnimTreeTweenBase::VGetRotation(const CSegId& seg) const
return zeus::CQuaternion::slerp(qA, qB, weight);
}
std::shared_ptr<IAnimReader> CAnimTreeTweenBase::VSimplified() { return {}; }
std::pair<std::unique_ptr<IAnimReader>, bool> CAnimTreeTweenBase::VSimplified() { return {}; }
}

View File

@ -33,7 +33,7 @@ public:
zeus::CVector3f VGetOffset(const CSegId& seg) const;
zeus::CQuaternion VGetRotation(const CSegId& seg) const;
std::shared_ptr<IAnimReader> VSimplified();
std::pair<std::unique_ptr<IAnimReader>, bool> VSimplified();
bool ShouldCullTree() const { return false; }
static void IncAdvancementDepth() { sAdvancementDepth++; }

View File

@ -148,6 +148,16 @@ ResId CCharacterFactory::GetEventResourceIdForAnimResourceId(ResId id) const
return search->second;
}
const CAdditiveAnimationInfo& CCharacterFactory::FindAdditiveInfo(u32 idx) const
{
auto search = std::lower_bound(x40_additiveInfo.cbegin(), x40_additiveInfo.cend(), idx,
[](const auto& anim, u32 test) -> bool { return anim.first < test; });
if (search == x40_additiveInfo.cend() || idx != search->first)
return x50_defaultAdditiveInfo;
return search->second;
}
std::vector<CCharacterInfo>
CCharacterFactory::GetCharacterInfoDB(const CAnimCharacterSet& ancs)
{

View File

@ -71,6 +71,7 @@ public:
ResId GetEventResourceIdForAnimResourceId(ResId animId) const;
const CCharacterInfo& GetCharInfo(int charIdx) const { return x4_charInfoDB[charIdx]; }
const CAdditiveAnimationInfo& FindAdditiveInfo(u32 idx) const;
};
}

View File

@ -16,9 +16,9 @@ CCharacterInfo::CParticleResData::CParticleResData(CInputStream& in, u16 tableCo
x10_swhc.push_back(in.readUint32Big());
u32 unkCount = in.readUint32Big();
x20_.reserve(unkCount);
x20_elsc.reserve(unkCount);
for (u32 i=0 ; i<unkCount ; ++i)
x20_.push_back(in.readUint32Big());
x20_elsc.push_back(in.readUint32Big());
if (tableCount > 5)
{

View File

@ -16,7 +16,7 @@ public:
{
std::vector<ResId> x0_part;
std::vector<ResId> x10_swhc;
std::vector<ResId> x20_;
std::vector<ResId> x20_elsc;
std::vector<ResId> x30_elsc;
CParticleResData(CInputStream& in, u16 tableCount);
};

View File

@ -437,9 +437,9 @@ SAdvancementResults CFBStreamedAnimReader::VReverseView(const CCharAnimTime& tim
return {};
}
std::shared_ptr<IAnimReader> CFBStreamedAnimReader::VClone() const
std::unique_ptr<IAnimReader> CFBStreamedAnimReader::VClone() const
{
return std::make_shared<CFBStreamedAnimReader>(x54_source, xc_curTime);
return std::make_unique<CFBStreamedAnimReader>(x54_source, xc_curTime);
}
void CFBStreamedAnimReader::VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const

View File

@ -109,7 +109,7 @@ public:
bool VSupportsReverseView() const {return false;}
void VSetPhase(float);
SAdvancementResults VReverseView(const CCharAnimTime& time);
std::shared_ptr<IAnimReader> VClone() const;
std::unique_ptr<IAnimReader> VClone() const;
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const;
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const;
SAdvancementResults VAdvanceView(const CCharAnimTime& a);

View File

@ -1,10 +1,33 @@
#include "CParticleDatabase.hpp"
#include "CSimplePool.hpp"
#include "GameGlobalObjects.hpp"
namespace urde
{
void CParticleDatabase::CacheParticleDesc(const CCharacterInfo::CParticleResData& desc)
{
for (ResId id : desc.x0_part)
{
auto search = x0_particleDescs.find(id);
if (search == x0_particleDescs.cend())
x0_particleDescs[id] = std::make_shared<TLockedToken<CGenDescription>>(
g_SimplePool->GetObj(SObjectTag{FOURCC('PART'), id}));
}
for (ResId id : desc.x10_swhc)
{
auto search = x14_swooshDescs.find(id);
if (search == x14_swooshDescs.cend())
x14_swooshDescs[id] = std::make_shared<TLockedToken<CSwooshDescription>>(
g_SimplePool->GetObj(SObjectTag{FOURCC('SWHC'), id}));
}
for (ResId id : desc.x20_elsc)
{
auto search = x28_electricDescs.find(id);
if (search == x28_electricDescs.cend())
x28_electricDescs[id] = std::make_shared<TLockedToken<CElectricDescription>>(
g_SimplePool->GetObj(SObjectTag{FOURCC('ELSC'), id}));
}
}
void CParticleDatabase::SetModulationColorAllActiveEffects(const zeus::CColor& color)

View File

@ -4,16 +4,28 @@
#include "CCharacterInfo.hpp"
#include "CParticleGenInfo.hpp"
#include "zeus/CFrustum.hpp"
#include "CToken.hpp"
#include <map>
namespace urde
{
class CPoseAsTransforms;
class CCharLayoutInfo;
class CGenDescription;
class CSwooshDescription;
class CElectricDescription;
class CParticleDatabase
{
std::map<ResId, std::shared_ptr<TLockedToken<CGenDescription>>> x0_particleDescs;
std::map<ResId, std::shared_ptr<TLockedToken<CSwooshDescription>>> x14_swooshDescs;
std::map<ResId, std::shared_ptr<TLockedToken<CElectricDescription>>> x28_electricDescs;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x3c_;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x50_;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x64_;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x78_;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x8c_;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> xa0_;
public:
void CacheParticleDesc(const CCharacterInfo::CParticleResData& desc);

View File

@ -123,8 +123,8 @@ public:
virtual CParticleData::EParentedMode VGetParticlePOIState(const char*) const=0;
virtual void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const=0;
virtual void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const=0;
virtual std::shared_ptr<IAnimReader> VClone() const=0;
virtual std::shared_ptr<IAnimReader> VSimplified() {return {};}
virtual std::unique_ptr<IAnimReader> VClone() const=0;
virtual std::pair<std::unique_ptr<IAnimReader>, bool> VSimplified() {return {};}
virtual void VSetPhase(float)=0;
virtual SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const;
@ -133,7 +133,9 @@ public:
u32 GetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut, u32 capacity, u32 iterator, u32) const;
u32 GetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator, u32) const;
std::shared_ptr<IAnimReader> Clone() const { return VClone(); }
std::pair<std::unique_ptr<IAnimReader>, bool> Simplified() { return VSimplified(); }
std::unique_ptr<IAnimReader> Clone() const { return VClone(); }
};
}