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;} float GetFadeOutDuration() const {return x4_fadeOutDur;}
}; };
enum class EAdditivePlaybackPhase
{
None,
FadingIn,
FadingOut,
FadedIn,
FadedOut
};
class CAdditiveAnimPlayback class CAdditiveAnimPlayback
{ {
public:
enum class EAdditivePlaybackPhase
{
None,
FadingIn,
FadingOut,
FadedIn,
FadedOut
};
private:
CAdditiveAnimationInfo x0_info; CAdditiveAnimationInfo x0_info;
std::shared_ptr<CAnimTreeNode> x8_anim; std::shared_ptr<CAnimTreeNode> x8_anim;
float xc_targetWeight; float xc_targetWeight;
@ -57,7 +56,12 @@ public:
void SetWeight(float w); void SetWeight(float w);
float GetTargetWeight() const {return xc_targetWeight;} float GetTargetWeight() const {return xc_targetWeight;}
bool IsActive() const {return x14_active;} bool IsActive() const {return x14_active;}
void SetActive(bool active) {x14_active = active;}
const std::shared_ptr<CAnimTreeNode>& GetAnim() const {return x8_anim;} 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 namespace urde
{ {
static logvisor::Module Log("CAnimData");
rstl::reserved_vector<CBoolPOINode, 8>CAnimData::g_BoolPOINodes; rstl::reserved_vector<CBoolPOINode, 8>CAnimData::g_BoolPOINodes;
rstl::reserved_vector<CInt32POINode, 16> CAnimData::g_Int32POINodes; rstl::reserved_vector<CInt32POINode, 16> CAnimData::g_Int32POINodes;
rstl::reserved_vector<CParticlePOINode, 20> CAnimData::g_ParticlePOINodes; rstl::reserved_vector<CParticlePOINode, 20> CAnimData::g_ParticlePOINodes;
@ -74,6 +76,23 @@ CAnimData::CAnimData(ResId id,
x108_aabb = xd8_modelData->GetModel()->GetAABB(); x108_aabb = xd8_modelData->GetModel()->GetAABB();
x120_particleDB.CacheParticleDesc(xc_charInfo.GetParticleResData()); 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 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); 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) SAdvancementDeltas CAnimData::AdvanceAdditiveAnims(float dt)
{ {
CCharAnimTime time(dt); CCharAnimTime time(dt);
SAdvancementDeltas deltas = {};
for (std::pair<u32, CAdditiveAnimPlayback>& additive : x434_additiveAnims) for (std::pair<u32, CAdditiveAnimPlayback>& additive : x434_additiveAnims)
{ {
std::shared_ptr<CAnimTreeNode>& anim = additive.second.GetAnim();
if (additive.second.IsActive()) if (additive.second.IsActive())
{ {
while (time.GreaterThanZero() && std::fabs(time) >= 0.00001f) 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 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) 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); return AdvanceAdditiveAnims(dt);
} }
@ -153,12 +217,42 @@ bool CAnimData::IsAdditiveAnimationActive(u32 idx) const
return search->second.IsActive(); 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() 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) void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus::CQuaternion& quat)
{ {
SAdvancementResults results; SAdvancementResults results;
std::shared_ptr<IAnimReader> simplified; std::pair<std::unique_ptr<IAnimReader>, bool> simplified = {};
if (!x104_) if (!x104_)
{ {
results = x1f8_animRoot->VAdvanceView(time); results = x1f8_animRoot->VAdvanceView(time);
simplified = x1f8_animRoot->VSimplified(); simplified = x1f8_animRoot->Simplified();
} }
if (simplified) if (simplified.second)
{ {
if (simplified->IsCAnimTreeNode()) x1f8_animRoot = std::static_pointer_cast<CAnimTreeNode>(
{ std::shared_ptr<IAnimReader>(std::move(simplified.first)));
if (x1f8_animRoot != simplified)
x1f8_animRoot = std::static_pointer_cast<CAnimTreeNode>(std::move(simplified));
}
else
x1f8_animRoot.reset();
} }
if ((x220_28_ || x220_27_) && x210_passedIntCount > 0) if ((x220_28_ || x220_27_) && x210_passedIntCount > 0)

View File

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

View File

@ -86,7 +86,7 @@ public:
bool VSupportsReverseView() const {return true;} bool VSupportsReverseView() const {return true;}
void VSetPhase(float); void VSetPhase(float);
SAdvancementResults VReverseView(const CCharAnimTime& time); 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;
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const; void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const;
SAdvancementResults VAdvanceView(const CCharAnimTime& a); 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); 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 = return std::make_unique<CAnimTreeAnimReaderContainer>(x4_name, x14_reader->Clone(), x1c_animDbIdx);
std::make_shared<CAnimTreeAnimReaderContainer>(x4_name, x14_reader->Clone(), x1c_animDbIdx);
return ret;
} }
std::shared_ptr<IAnimReader> CAnimTreeAnimReaderContainer::VSimplified() std::pair<std::unique_ptr<IAnimReader>, bool> CAnimTreeAnimReaderContainer::VSimplified()
{ {
return {}; return {};
} }

View File

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

View File

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

View File

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

View File

@ -33,7 +33,8 @@ std::shared_ptr<IAnimReader> CAnimTreeSequence::VGetBestUnblendedChild() const
std::shared_ptr<IAnimReader> ch = x14_child->GetBestUnblendedChild(); std::shared_ptr<IAnimReader> ch = x14_child->GetBestUnblendedChild();
if (!ch) if (!ch)
return 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); x28_, x18_, x4_name, x3c_fundamentals, x94_curTime);
} }
@ -88,9 +89,10 @@ u32 CAnimTreeSequence::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode
x3c_fundamentals.GetSoundPointsOfInterest(), x94_curTime); 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); 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 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 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; 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); x14_child->VSetPhase(phase);
} }
std::shared_ptr<IAnimReader> CAnimTreeTimeScale::VSimplified() std::pair<std::unique_ptr<IAnimReader>, bool> CAnimTreeTimeScale::VSimplified()
{ {
return {}; return {};
} }

View File

@ -19,7 +19,7 @@ public:
CCharAnimTime GetRealLifeTime(const CCharAnimTime&) const; CCharAnimTime GetRealLifeTime(const CCharAnimTime&) const;
void VSetPhase(float); 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()); 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()), return std::make_unique<CAnimTreeTransition>(x20_31_b1, std::static_pointer_cast<CAnimTreeNode>(
std::static_pointer_cast<CAnimTreeNode>(x18_b->Clone()), x24_, x2c_, 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_); x34_, x35_, x1c_flags, x4_name, x36_);
} }

View File

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

View File

@ -49,5 +49,5 @@ zeus::CQuaternion CAnimTreeTweenBase::VGetRotation(const CSegId& seg) const
return zeus::CQuaternion::slerp(qA, qB, weight); 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::CVector3f VGetOffset(const CSegId& seg) const;
zeus::CQuaternion VGetRotation(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; } bool ShouldCullTree() const { return false; }
static void IncAdvancementDepth() { sAdvancementDepth++; } static void IncAdvancementDepth() { sAdvancementDepth++; }

View File

@ -148,6 +148,16 @@ ResId CCharacterFactory::GetEventResourceIdForAnimResourceId(ResId id) const
return search->second; 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> std::vector<CCharacterInfo>
CCharacterFactory::GetCharacterInfoDB(const CAnimCharacterSet& ancs) CCharacterFactory::GetCharacterInfoDB(const CAnimCharacterSet& ancs)
{ {

View File

@ -71,6 +71,7 @@ public:
ResId GetEventResourceIdForAnimResourceId(ResId animId) const; ResId GetEventResourceIdForAnimResourceId(ResId animId) const;
const CCharacterInfo& GetCharInfo(int charIdx) const { return x4_charInfoDB[charIdx]; } 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()); x10_swhc.push_back(in.readUint32Big());
u32 unkCount = in.readUint32Big(); u32 unkCount = in.readUint32Big();
x20_.reserve(unkCount); x20_elsc.reserve(unkCount);
for (u32 i=0 ; i<unkCount ; ++i) for (u32 i=0 ; i<unkCount ; ++i)
x20_.push_back(in.readUint32Big()); x20_elsc.push_back(in.readUint32Big());
if (tableCount > 5) if (tableCount > 5)
{ {

View File

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

View File

@ -437,9 +437,9 @@ SAdvancementResults CFBStreamedAnimReader::VReverseView(const CCharAnimTime& tim
return {}; 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 void CFBStreamedAnimReader::VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const

View File

@ -109,7 +109,7 @@ public:
bool VSupportsReverseView() const {return false;} bool VSupportsReverseView() const {return false;}
void VSetPhase(float); void VSetPhase(float);
SAdvancementResults VReverseView(const CCharAnimTime& time); 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;
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const; void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const;
SAdvancementResults VAdvanceView(const CCharAnimTime& a); SAdvancementResults VAdvanceView(const CCharAnimTime& a);

View File

@ -1,10 +1,33 @@
#include "CParticleDatabase.hpp" #include "CParticleDatabase.hpp"
#include "CSimplePool.hpp"
#include "GameGlobalObjects.hpp"
namespace urde namespace urde
{ {
void CParticleDatabase::CacheParticleDesc(const CCharacterInfo::CParticleResData& desc) 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) void CParticleDatabase::SetModulationColorAllActiveEffects(const zeus::CColor& color)

View File

@ -4,16 +4,28 @@
#include "CCharacterInfo.hpp" #include "CCharacterInfo.hpp"
#include "CParticleGenInfo.hpp" #include "CParticleGenInfo.hpp"
#include "zeus/CFrustum.hpp" #include "zeus/CFrustum.hpp"
#include "CToken.hpp"
#include <map> #include <map>
namespace urde namespace urde
{ {
class CPoseAsTransforms; class CPoseAsTransforms;
class CCharLayoutInfo; class CCharLayoutInfo;
class CGenDescription;
class CSwooshDescription;
class CElectricDescription;
class CParticleDatabase 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>> 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: public:
void CacheParticleDesc(const CCharacterInfo::CParticleResData& desc); void CacheParticleDesc(const CCharacterInfo::CParticleResData& desc);

View File

@ -123,8 +123,8 @@ public:
virtual CParticleData::EParentedMode VGetParticlePOIState(const char*) const=0; 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=0;
virtual void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) 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::unique_ptr<IAnimReader> VClone() const=0;
virtual std::shared_ptr<IAnimReader> VSimplified() {return {};} virtual std::pair<std::unique_ptr<IAnimReader>, bool> VSimplified() {return {};}
virtual void VSetPhase(float)=0; virtual void VSetPhase(float)=0;
virtual SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const; 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 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; 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(); }
}; };
} }