diff --git a/DataSpec/DNAMP1/ANIM.cpp b/DataSpec/DNAMP1/ANIM.cpp index 738b5479e..0933f85eb 100644 --- a/DataSpec/DNAMP1/ANIM.cpp +++ b/DataSpec/DNAMP1/ANIM.cpp @@ -379,7 +379,7 @@ void ANIM::ANIM2::write(athena::io::IStreamWriter& writer) const head.unk0 = 1; head.interval = mainInterval; head.rootBoneId = 3; - head.unk2 = 0; + head.looping = 0; head.unk3 = 1; WordBitmap keyBmp; diff --git a/DataSpec/DNAMP1/ANIM.hpp b/DataSpec/DNAMP1/ANIM.hpp index 7f11ebf47..efc2c642d 100644 --- a/DataSpec/DNAMP1/ANIM.hpp +++ b/DataSpec/DNAMP1/ANIM.hpp @@ -64,7 +64,7 @@ struct ANIM : BigDNA Value duration; Value interval; Value rootBoneId = 3; - Value unk2 = 0; + Value looping = 0; Value rotDiv; Value translationMult; Value boneChannelCount; diff --git a/DataSpec/DNAMP2/ANIM.cpp b/DataSpec/DNAMP2/ANIM.cpp index beac45ed9..6abacdb4d 100644 --- a/DataSpec/DNAMP2/ANIM.cpp +++ b/DataSpec/DNAMP2/ANIM.cpp @@ -475,7 +475,7 @@ void ANIM::ANIM2::write(athena::io::IStreamWriter& writer) const { Header head; head.unk1 = 1; - head.unk2 = 1; + head.looping = 1; head.interval = mainInterval; head.rootBoneId = 0; head.scaleMult = 0.f; diff --git a/DataSpec/DNAMP2/ANIM.hpp b/DataSpec/DNAMP2/ANIM.hpp index 00b30ca2e..83ca79ec8 100644 --- a/DataSpec/DNAMP2/ANIM.hpp +++ b/DataSpec/DNAMP2/ANIM.hpp @@ -62,7 +62,7 @@ struct ANIM : BigDNA Value duration; Value interval; Value rootBoneId = 3; - Value unk2 = 0; + Value looping = 0; Value rotDiv; Value translationMult; Value scaleMult; diff --git a/Runtime/Character/CAnimSourceReader.cpp b/Runtime/Character/CAnimSourceReader.cpp index ac743b2e2..23ad691cc 100644 --- a/Runtime/Character/CAnimSourceReader.cpp +++ b/Runtime/Character/CAnimSourceReader.cpp @@ -450,11 +450,9 @@ zeus::CQuaternion CAnimSourceReader::VGetRotation(const CSegId& seg) const CAnimSourceReader::CAnimSourceReader(const TSubAnimTypeToken& source, const CCharAnimTime& time) : CAnimSourceReaderBase(std::make_unique(source), CCharAnimTime()), - x54_source(source) + x54_source(source), x64_steadyStateInfo(false, source->GetDuration(), + source->GetOffset(source->GetRootBoneId(), time)) { - CAnimSource* sourceData = x54_source.GetObj(); - x64_steadyStateInfo.x64_duration = sourceData->GetDuration(); - x64_steadyStateInfo.x6c_curRootOffset = sourceData->GetOffset(sourceData->GetRootBoneId(), time); PostConstruct(time); } diff --git a/Runtime/Character/CAnimTreeAnimReaderContainer.cpp b/Runtime/Character/CAnimTreeAnimReaderContainer.cpp index 7f2737e08..57c8c709a 100644 --- a/Runtime/Character/CAnimTreeAnimReaderContainer.cpp +++ b/Runtime/Character/CAnimTreeAnimReaderContainer.cpp @@ -10,11 +10,32 @@ CAnimTreeAnimReaderContainer::CAnimTreeAnimReaderContainer(const std::string& na { } +u32 CAnimTreeAnimReaderContainer::Depth() const +{ + return 1; +} + CAnimTreeEffectiveContribution CAnimTreeAnimReaderContainer::VGetContributionOfHighestInfluence() const { return {1.f, x4_name, VGetSteadyStateAnimInfo(), VGetTimeRemaining(), x1c_animDbIdx}; } +u32 CAnimTreeAnimReaderContainer::VGetNumChildren() const +{ + return 0; +} + +std::shared_ptr CAnimTreeAnimReaderContainer::VGetBestUnblendedChild() const +{ + return {}; +} + +void CAnimTreeAnimReaderContainer::VGetWeightedReaders +(std::vector>>& out, float w) const +{ + out.push_back(std::make_pair(w, x14_reader)); +} + SAdvancementResults CAnimTreeAnimReaderContainer::VAdvanceView(const CCharAnimTime& dt) { return x14_reader->VAdvanceView(dt); @@ -101,6 +122,11 @@ std::shared_ptr CAnimTreeAnimReaderContainer::VClone() const return ret; } +std::shared_ptr CAnimTreeAnimReaderContainer::VSimplified() +{ + return {}; +} + void CAnimTreeAnimReaderContainer::VSetPhase(float ph) { x14_reader->VSetPhase(ph); diff --git a/Runtime/Character/CAnimTreeAnimReaderContainer.hpp b/Runtime/Character/CAnimTreeAnimReaderContainer.hpp index 8963df35b..de5502aaf 100644 --- a/Runtime/Character/CAnimTreeAnimReaderContainer.hpp +++ b/Runtime/Character/CAnimTreeAnimReaderContainer.hpp @@ -15,10 +15,11 @@ public: std::shared_ptr reader, u32 animDbIdx); - u32 Depth() const { return 1; } + u32 Depth() const; CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const; - u32 VGetNumChildren() const { return 0; } - std::shared_ptr VGetBestUnblendedChild() const { return {}; } + u32 VGetNumChildren() const; + std::shared_ptr VGetBestUnblendedChild() const; + void VGetWeightedReaders(std::vector>>& out, float w) const; SAdvancementResults VAdvanceView(const CCharAnimTime& a); CCharAnimTime VGetTimeRemaining() const; @@ -36,7 +37,7 @@ public: void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const; void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const; std::shared_ptr VClone() const; - std::shared_ptr VSimplified() { return {}; } + std::shared_ptr VSimplified(); void VSetPhase(float); SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const; }; diff --git a/Runtime/Character/CAnimTreeNode.cpp b/Runtime/Character/CAnimTreeNode.cpp index 8b75f4898..284d811da 100644 --- a/Runtime/Character/CAnimTreeNode.cpp +++ b/Runtime/Character/CAnimTreeNode.cpp @@ -3,6 +3,11 @@ namespace urde { +CAnimTreeEffectiveContribution CAnimTreeNode::GetContributionOfHighestInfluence() const +{ + return VGetContributionOfHighestInfluence(); +} + u32 CAnimTreeNode::GetNumChildren() const { return VGetNumChildren(); diff --git a/Runtime/Character/CAnimTreeNode.hpp b/Runtime/Character/CAnimTreeNode.hpp index 40803e670..4c1ce299f 100644 --- a/Runtime/Character/CAnimTreeNode.hpp +++ b/Runtime/Character/CAnimTreeNode.hpp @@ -18,8 +18,9 @@ public: virtual CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const=0; virtual u32 VGetNumChildren() const=0; virtual std::shared_ptr VGetBestUnblendedChild() const=0; + virtual void VGetWeightedReaders(std::vector>>& out, float w) const=0; - void GetContributionOfHighestInfluence() const; + CAnimTreeEffectiveContribution GetContributionOfHighestInfluence() const; u32 GetNumChildren() const; std::shared_ptr GetBestUnblendedChild() const; }; diff --git a/Runtime/Character/CAnimTreeSequence.cpp b/Runtime/Character/CAnimTreeSequence.cpp index e69de29bb..1b86909bb 100644 --- a/Runtime/Character/CAnimTreeSequence.cpp +++ b/Runtime/Character/CAnimTreeSequence.cpp @@ -0,0 +1,96 @@ +#include "CAnimTreeSequence.hpp" +#include "IMetaAnim.hpp" +#include "CAnimSysContext.hpp" + +namespace urde +{ + +CAnimTreeSequence::CAnimTreeSequence(const std::vector>& seq, + const CAnimSysContext& animSys, + const std::string& name) +: CAnimTreeSingleChild(seq[0]->GetAnimationTree(animSys, CMetaAnimTreeBuildOrders::NoSpecialOrders()), name), + x18_(animSys), x3c_fundamentals(CSequenceHelper(seq, animSys).ComputeSequenceFundamentals()), x94_curTime(0.f) +{ +} + +CAnimTreeSequence::CAnimTreeSequence(const std::shared_ptr& curNode, + const std::vector>& metaAnims, + const CAnimSysContext& animSys, + const std::string& name, + const CSequenceFundamentals& fundamentals, + const CCharAnimTime& time) +: CAnimTreeSingleChild(curNode, name), x18_(animSys), x28_(metaAnims), x3c_fundamentals(fundamentals), x94_curTime(time) +{ +} + +CAnimTreeEffectiveContribution CAnimTreeSequence::VGetContributionOfHighestInfluence() const +{ + return x14_child->GetContributionOfHighestInfluence(); +} + +std::shared_ptr CAnimTreeSequence::VGetBestUnblendedChild() const +{ + std::shared_ptr ch = x14_child->GetBestUnblendedChild(); + if (!ch) + return ch; + return std::make_shared(std::static_pointer_cast(ch->Clone()), + x28_, x18_, x4_name, x3c_fundamentals, x94_curTime); +} + +void CAnimTreeSequence::VGetWeightedReaders +(std::vector>>& out, float w) const +{ + x14_child->VGetWeightedReaders(out, w); +} + +SAdvancementResults CAnimTreeSequence::VAdvanceView(const CCharAnimTime& a) +{ +} + +CCharAnimTime CAnimTreeSequence::VGetTimeRemaining() const +{ + if (x38_curIdx == x28_.size() - 1) + return x14_child->VGetTimeRemaining(); + return x3c_fundamentals.GetSteadyStateAnimInfo().GetDuration() - x94_curTime; +} + +CSteadyStateAnimInfo CAnimTreeSequence::VGetSteadyStateAnimInfo() const +{ + return x3c_fundamentals.GetSteadyStateAnimInfo(); +} + +u32 CAnimTreeSequence::VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut, + u32 capacity, u32 iterator, u32 unk) const +{ + return _getPOIList(time, listOut, capacity, iterator, unk, + x3c_fundamentals.GetBoolPointsOfInterest(), x94_curTime); +} + +u32 CAnimTreeSequence::VGetInt32POIList(const CCharAnimTime& time, CInt32POINode* listOut, + u32 capacity, u32 iterator, u32 unk) const +{ + return _getPOIList(time, listOut, capacity, iterator, unk, + x3c_fundamentals.GetInt32PointsOfInterest(), x94_curTime); +} + +u32 CAnimTreeSequence::VGetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut, + u32 capacity, u32 iterator, u32 unk) const +{ + return _getPOIList(time, listOut, capacity, iterator, unk, + x3c_fundamentals.GetParticlePointsOfInterest(), x94_curTime); +} + +u32 CAnimTreeSequence::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, + u32 capacity, u32 iterator, u32 unk) const +{ + return _getPOIList(time, listOut, capacity, iterator, unk, + x3c_fundamentals.GetSoundPointsOfInterest(), x94_curTime); +} + +std::shared_ptr CAnimTreeSequence::VClone() const +{ + return std::make_shared(std::static_pointer_cast(x14_child->Clone()), + x28_, x18_, x4_name, x3c_fundamentals, x94_curTime); +} + +} diff --git a/Runtime/Character/CAnimTreeSequence.hpp b/Runtime/Character/CAnimTreeSequence.hpp index 23f233f17..a0944d908 100644 --- a/Runtime/Character/CAnimTreeSequence.hpp +++ b/Runtime/Character/CAnimTreeSequence.hpp @@ -1,11 +1,45 @@ #ifndef __URDE_CANIMTREESEQUENCE_HPP__ #define __URDE_CANIMTREESEQUENCE_HPP__ +#include "CAnimTreeSingleChild.hpp" +#include "CAnimSysContext.hpp" +#include "CSequenceHelper.hpp" + namespace urde { +class IMetaAnim; +class CTransitionDatabaseGame; -class CAnimTreeSequence +class CAnimTreeSequence : public CAnimTreeSingleChild { + CAnimSysContext x18_; + std::vector> x28_; + u32 x38_curIdx = 0; + CSequenceFundamentals x3c_fundamentals; + CCharAnimTime x94_curTime; +public: + CAnimTreeSequence(const std::vector>& seq, + const CAnimSysContext& animSys, + const std::string& name); + CAnimTreeSequence(const std::shared_ptr& curNode, + const std::vector>& metaAnims, + const CAnimSysContext& animSys, + const std::string& name, + const CSequenceFundamentals& fundamentals, + const CCharAnimTime& time); + + CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const; + std::shared_ptr VGetBestUnblendedChild() const; + void VGetWeightedReaders(std::vector>>& out, float w) const; + + SAdvancementResults VAdvanceView(const CCharAnimTime& a); + CCharAnimTime VGetTimeRemaining() const; + CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const; + 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; + std::shared_ptr VClone() const; }; } diff --git a/Runtime/Character/CAnimTreeSingleChild.hpp b/Runtime/Character/CAnimTreeSingleChild.hpp index 67296577b..fecd3868a 100644 --- a/Runtime/Character/CAnimTreeSingleChild.hpp +++ b/Runtime/Character/CAnimTreeSingleChild.hpp @@ -8,6 +8,7 @@ namespace urde class CAnimTreeSingleChild : public CAnimTreeNode { +protected: std::shared_ptr x14_child; public: CAnimTreeSingleChild(const std::weak_ptr& node, const std::string& name); diff --git a/Runtime/Character/CFBStreamedAnimReader.cpp b/Runtime/Character/CFBStreamedAnimReader.cpp index c122c91e0..c86cf3db6 100644 --- a/Runtime/Character/CFBStreamedAnimReader.cpp +++ b/Runtime/Character/CFBStreamedAnimReader.cpp @@ -77,16 +77,10 @@ CSegIdToIndexConverter::CSegIdToIndexConverter(const CFBStreamedAnimReaderTotals } CFBStreamedAnimReader::CFBStreamedAnimReader(const TSubAnimTypeToken& source, const CCharAnimTime& time) -: CAnimSourceReaderBase(std::make_unique>(source), time), - x54_source(source), x7c_(source), x114_(x7c_.x10_ ? x7c_.x14_ : x7c_.x3c_) +: CAnimSourceReaderBase(std::make_unique>(source), time), x54_source(source), + x64_steadyStateInfo(source->IsLooping(), source->GetAnimationDuration(), source->GetRootOffset()), + x7c_(source), x114_(x7c_.x10_ ? x7c_.x14_ : x7c_.x3c_) { - x64_steadyStateInfo.x64_duration = x54_source->GetAnimationDuration(); - x64_steadyStateInfo.x6c_curRootOffset = x54_source->x14_rootOffset; - - const CFBStreamedCompression::Header* header = - reinterpret_cast(x54_source->xc_rotsAndOffs.get()); - x64_steadyStateInfo.x78_ = header->unk2; - PostConstruct(time); } diff --git a/Runtime/Character/CFBStreamedAnimReader.hpp b/Runtime/Character/CFBStreamedAnimReader.hpp index f06970fad..768370221 100644 --- a/Runtime/Character/CFBStreamedAnimReader.hpp +++ b/Runtime/Character/CFBStreamedAnimReader.hpp @@ -13,11 +13,11 @@ class TAnimSourceInfo : public IAnimSourceInfo TSubAnimTypeToken x4_token; public: TAnimSourceInfo(const TSubAnimTypeToken& token); - bool HasPOIData() const { return x4_token->GetPOIToken(); } - const std::vector& GetBoolPOIStream() const { return x4_token->GetPOIToken()->GetBoolPOIStream(); } - const std::vector& GetInt32POIStream() const { return x4_token->GetPOIToken()->GetInt32POIStream(); } - const std::vector& GetParticlePOIStream() const { return x4_token->GetPOIToken()->GetParticlePOIStream(); } - const std::vector& GetSoundPOIStream() const { return x4_token->GetPOIToken()->GetSoundPOIStream(); } + bool HasPOIData() const { return x4_token->HasPOIData(); } + const std::vector& GetBoolPOIStream() const { return x4_token->GetBoolPOIStream(); } + const std::vector& GetInt32POIStream() const { return x4_token->GetInt32POIStream(); } + const std::vector& GetParticlePOIStream() const { return x4_token->GetParticlePOIStream(); } + const std::vector& GetSoundPOIStream() const { return x4_token->GetSoundPOIStream(); } CCharAnimTime GetAnimationDuration() const { return x4_token->GetAnimationDuration(); } }; diff --git a/Runtime/Character/CFBStreamedCompression.hpp b/Runtime/Character/CFBStreamedCompression.hpp index 8e6f08cd4..49c9f9b96 100644 --- a/Runtime/Character/CFBStreamedCompression.hpp +++ b/Runtime/Character/CFBStreamedCompression.hpp @@ -16,13 +16,14 @@ class CFBStreamedCompression friend class CFBStreamedAnimReaderTotals; friend class CFBStreamedPairOfTotals; +public: struct Header { u32 unk0; float duration; float interval; u32 rootBoneId; - u32 unk2; + u32 looping; u32 rotDiv; float translationMult; u32 boneChannelCount; @@ -38,8 +39,8 @@ class CFBStreamedCompression interval = in.readFloatBig(); /* rootBoneId */ rootBoneId = in.readUint32Big(); - /* unk2 */ - unk2 = in.readUint32Big(); + /* looping */ + looping = in.readUint32Big(); /* rotDiv */ rotDiv = in.readUint32Big(); /* translationMult */ @@ -51,6 +52,7 @@ class CFBStreamedCompression } }; +private: bool m_pc; u32 x0_scratchSize; ResId x4_evnt; @@ -61,10 +63,18 @@ class CFBStreamedCompression u8* ReadBoneChannelDescriptors(u8* out, CInputStream& in); u32 ComputeBitstreamWords(const u8* chans); std::unique_ptr GetRotationsAndOffsets(u32 words, CInputStream& in); + public: CFBStreamedCompression(CInputStream& in, IObjectStore& objStore, bool pc); - CCharAnimTime GetAnimationDuration() const { return reinterpret_cast(xc_rotsAndOffs.get())->duration; } - const TLockedToken& GetPOIToken() const { return x8_evntToken; } + const Header& MainHeader() const { return *reinterpret_cast(xc_rotsAndOffs.get()); } + bool IsLooping() const { return MainHeader().looping; } + CCharAnimTime GetAnimationDuration() const { return MainHeader().duration; } + const zeus::CVector3f& GetRootOffset() const { return x14_rootOffset; } + bool HasPOIData() const { return x8_evntToken; } + const std::vector& GetBoolPOIStream() const { return x8_evntToken->GetBoolPOIStream(); } + const std::vector& GetInt32POIStream() const { return x8_evntToken->GetInt32POIStream(); } + const std::vector& GetParticlePOIStream() const { return x8_evntToken->GetParticlePOIStream(); } + const std::vector& GetSoundPOIStream() const { return x8_evntToken->GetSoundPOIStream(); } }; } diff --git a/Runtime/Character/CMakeLists.txt b/Runtime/Character/CMakeLists.txt index d0d1a93dc..b97a25fd6 100644 --- a/Runtime/Character/CMakeLists.txt +++ b/Runtime/Character/CMakeLists.txt @@ -48,6 +48,7 @@ set(CHARACTER_SOURCES CMetaTransSnap.hpp CMetaTransSnap.cpp CAnimTreeLoopIn.hpp CAnimTreeLoopIn.cpp CAnimTreeSequence.hpp CAnimTreeSequence.cpp + CSequenceHelper.hpp CSequenceHelper.cpp CAnimTreeAnimReaderContainer.hpp CAnimTreeAnimReaderContainer.cpp CAnimTreeBlend.hpp CAnimTreeBlend.cpp CAnimTreeNode.hpp CAnimTreeNode.cpp diff --git a/Runtime/Character/CMetaAnimBlend.cpp b/Runtime/Character/CMetaAnimBlend.cpp index ed6148754..0eec79e19 100644 --- a/Runtime/Character/CMetaAnimBlend.cpp +++ b/Runtime/Character/CMetaAnimBlend.cpp @@ -12,13 +12,6 @@ CMetaAnimBlend::CMetaAnimBlend(CInputStream& in) x10_ = in.readBool(); } -std::shared_ptr -CMetaAnimBlend::GetAnimationTree(const CAnimSysContext& animSys, - const CMetaAnimTreeBuildOrders& orders) const -{ - return {}; -} - void CMetaAnimBlend::GetUniquePrimitives(std::set& primsOut) const { } diff --git a/Runtime/Character/CMetaAnimBlend.hpp b/Runtime/Character/CMetaAnimBlend.hpp index 9986e98f2..432112401 100644 --- a/Runtime/Character/CMetaAnimBlend.hpp +++ b/Runtime/Character/CMetaAnimBlend.hpp @@ -17,8 +17,6 @@ public: CMetaAnimBlend(CInputStream& in); EMetaAnimType GetType() const {return EMetaAnimType::Blend;} - std::shared_ptr GetAnimationTree(const CAnimSysContext& animSys, - const CMetaAnimTreeBuildOrders& orders) const; void GetUniquePrimitives(std::set& primsOut) const; std::shared_ptr VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const; diff --git a/Runtime/Character/CMetaAnimPhaseBlend.cpp b/Runtime/Character/CMetaAnimPhaseBlend.cpp index e1068eaaf..473090c42 100644 --- a/Runtime/Character/CMetaAnimPhaseBlend.cpp +++ b/Runtime/Character/CMetaAnimPhaseBlend.cpp @@ -12,13 +12,6 @@ CMetaAnimPhaseBlend::CMetaAnimPhaseBlend(CInputStream& in) x10_ = in.readBool(); } -std::shared_ptr -CMetaAnimPhaseBlend::GetAnimationTree(const CAnimSysContext& animSys, - const CMetaAnimTreeBuildOrders& orders) const -{ - return {}; -} - void CMetaAnimPhaseBlend::GetUniquePrimitives(std::set& primsOut) const { } diff --git a/Runtime/Character/CMetaAnimPhaseBlend.hpp b/Runtime/Character/CMetaAnimPhaseBlend.hpp index 0840da406..60958739c 100644 --- a/Runtime/Character/CMetaAnimPhaseBlend.hpp +++ b/Runtime/Character/CMetaAnimPhaseBlend.hpp @@ -17,8 +17,6 @@ public: CMetaAnimPhaseBlend(CInputStream& in); EMetaAnimType GetType() const {return EMetaAnimType::PhaseBlend;} - std::shared_ptr GetAnimationTree(const CAnimSysContext& animSys, - const CMetaAnimTreeBuildOrders& orders) const; void GetUniquePrimitives(std::set& primsOut) const; std::shared_ptr VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const; diff --git a/Runtime/Character/CMetaAnimPlay.cpp b/Runtime/Character/CMetaAnimPlay.cpp index e611df89b..828003b61 100644 --- a/Runtime/Character/CMetaAnimPlay.cpp +++ b/Runtime/Character/CMetaAnimPlay.cpp @@ -10,15 +10,9 @@ namespace urde CMetaAnimPlay::CMetaAnimPlay(CInputStream& in) : x4_primitive(in), x1c_startTime(in) {} -std::shared_ptr -CMetaAnimPlay::GetAnimationTree(const CAnimSysContext& animSys, - const CMetaAnimTreeBuildOrders& orders) const -{ - return {}; -} - void CMetaAnimPlay::GetUniquePrimitives(std::set& primsOut) const { + primsOut.insert(x4_primitive); } std::shared_ptr diff --git a/Runtime/Character/CMetaAnimPlay.hpp b/Runtime/Character/CMetaAnimPlay.hpp index ea49c088c..dd13e351d 100644 --- a/Runtime/Character/CMetaAnimPlay.hpp +++ b/Runtime/Character/CMetaAnimPlay.hpp @@ -16,8 +16,6 @@ public: CMetaAnimPlay(CInputStream& in); EMetaAnimType GetType() const {return EMetaAnimType::Primitive;} - std::shared_ptr GetAnimationTree(const CAnimSysContext& animSys, - const CMetaAnimTreeBuildOrders& orders) const; void GetUniquePrimitives(std::set& primsOut) const; std::shared_ptr VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const; diff --git a/Runtime/Character/CMetaAnimRandom.cpp b/Runtime/Character/CMetaAnimRandom.cpp index 08b241f6e..f2f471d43 100644 --- a/Runtime/Character/CMetaAnimRandom.cpp +++ b/Runtime/Character/CMetaAnimRandom.cpp @@ -22,13 +22,6 @@ CMetaAnimRandom::RandomData CMetaAnimRandom::CreateRandomData(CInputStream& in) CMetaAnimRandom::CMetaAnimRandom(CInputStream& in) : x4_randomData(CreateRandomData(in)) {} -std::shared_ptr -CMetaAnimRandom::GetAnimationTree(const CAnimSysContext& animSys, - const CMetaAnimTreeBuildOrders& orders) const -{ - return {}; -} - void CMetaAnimRandom::GetUniquePrimitives(std::set& primsOut) const { } diff --git a/Runtime/Character/CMetaAnimRandom.hpp b/Runtime/Character/CMetaAnimRandom.hpp index c44411666..4f9a1e80b 100644 --- a/Runtime/Character/CMetaAnimRandom.hpp +++ b/Runtime/Character/CMetaAnimRandom.hpp @@ -16,8 +16,6 @@ public: CMetaAnimRandom(CInputStream& in); EMetaAnimType GetType() const {return EMetaAnimType::Random;} - std::shared_ptr GetAnimationTree(const CAnimSysContext& animSys, - const CMetaAnimTreeBuildOrders& orders) const; void GetUniquePrimitives(std::set& primsOut) const; std::shared_ptr VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const; diff --git a/Runtime/Character/CMetaAnimSequence.cpp b/Runtime/Character/CMetaAnimSequence.cpp index e560a0d58..ba395d87b 100644 --- a/Runtime/Character/CMetaAnimSequence.cpp +++ b/Runtime/Character/CMetaAnimSequence.cpp @@ -1,5 +1,6 @@ #include "CMetaAnimSequence.hpp" #include "CMetaAnimFactory.hpp" +#include "CAnimTreeSequence.hpp" namespace urde { @@ -19,22 +20,32 @@ std::vector> CMetaAnimSequence::CreateSequence(CInput CMetaAnimSequence::CMetaAnimSequence(CInputStream& in) : x4_sequence(CreateSequence(in)) {} -std::shared_ptr -CMetaAnimSequence::GetAnimationTree(const CAnimSysContext& animSys, - const CMetaAnimTreeBuildOrders& orders) const -{ - return {}; -} - void CMetaAnimSequence::GetUniquePrimitives(std::set& primsOut) const { + for (const std::shared_ptr& anim : x4_sequence) + anim->GetUniquePrimitives(primsOut); } std::shared_ptr CMetaAnimSequence::VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const { - return {}; + if (orders.x0_) + { + CMetaAnimTreeBuildOrders modOrders; + modOrders.PreAdvanceForAll(*orders.x0_); + return GetAnimationTree(animSys, modOrders); + } + + for (const std::shared_ptr& anim : x4_sequence) + { + + } + + std::shared_ptr ret = + std::make_shared(x4_sequence, animSys, ""); + + return ret; } } diff --git a/Runtime/Character/CMetaAnimSequence.hpp b/Runtime/Character/CMetaAnimSequence.hpp index 32a8ae0d9..1377a48db 100644 --- a/Runtime/Character/CMetaAnimSequence.hpp +++ b/Runtime/Character/CMetaAnimSequence.hpp @@ -15,8 +15,6 @@ public: CMetaAnimSequence(CInputStream& in); EMetaAnimType GetType() const {return EMetaAnimType::Sequence;} - std::shared_ptr GetAnimationTree(const CAnimSysContext& animSys, - const CMetaAnimTreeBuildOrders& orders) const; void GetUniquePrimitives(std::set& primsOut) const; std::shared_ptr VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const; diff --git a/Runtime/Character/CPOINode.cpp b/Runtime/Character/CPOINode.cpp index 696824d6f..4943acc23 100644 --- a/Runtime/Character/CPOINode.cpp +++ b/Runtime/Character/CPOINode.cpp @@ -1,4 +1,9 @@ #include "CPOINode.hpp" +#include "CBoolPOINode.hpp" +#include "CInt32POINode.hpp" +#include "CParticlePOINode.hpp" +#include "CSoundPOINode.hpp" +#include "CAnimSourceReader.hpp" namespace urde { @@ -28,4 +33,110 @@ CPOINode::CPOINode(CInputStream& in) x34_flags(in.readUint32Big()) {} +template +u32 _getPOIList(const CCharAnimTime& time, + T* listOut, + u32 capacity, u32 iterator, u32 unk1, + const std::vector& stream, + const CCharAnimTime& curTime, + const IAnimSourceInfo& animInfo, u32 passedCount) +{ + u32 ret = 0; + if (animInfo.HasPOIData() && stream.size()) + { + CCharAnimTime dur = animInfo.GetAnimationDuration(); + CCharAnimTime targetTime = curTime + time; + if (targetTime >= dur) + targetTime = dur; + + if (passedCount >= stream.size()) + return ret; + + CCharAnimTime nodeTime = stream[passedCount].GetTime(); + while (nodeTime <= targetTime) + { + u32 idx = iterator + ret; + if (idx < capacity) + listOut[idx] = T::CopyNodeMinusStartTime(stream[passedCount], curTime); + ++passedCount; + ++ret; + nodeTime = stream[passedCount].GetTime(); + } + } + return ret; +} + +template +u32 _getPOIList(const CCharAnimTime& time, + T* listOut, + u32 capacity, u32 iterator, u32 unk1, + const std::vector& stream, + const CCharAnimTime& curTime) +{ + u32 ret = 0; + + CCharAnimTime targetTime = curTime + time; + + for (u32 it = iterator ; it < stream.size() ; ++it) + { + CCharAnimTime nodeTime = stream[ret].GetTime(); + if (nodeTime > targetTime) + return ret; + u32 idx = iterator + ret; + if (idx < capacity) + listOut[idx] = T::CopyNodeMinusStartTime(stream[ret], curTime); + ++ret; + } + + return ret; +} + +template u32 _getPOIList(const CCharAnimTime& time, + CBoolPOINode* listOut, + u32 capacity, u32 iterator, u32 unk1, + const std::vector& stream, + const CCharAnimTime& curTime, + const IAnimSourceInfo& animInfo, u32 passedCount); +template u32 _getPOIList(const CCharAnimTime& time, + CBoolPOINode* listOut, + u32 capacity, u32 iterator, u32 unk1, + const std::vector& stream, + const CCharAnimTime& curTime); + +template u32 _getPOIList(const CCharAnimTime& time, + CInt32POINode* listOut, + u32 capacity, u32 iterator, u32 unk1, + const std::vector& stream, + const CCharAnimTime& curTime, + const IAnimSourceInfo& animInfo, u32 passedCount); +template u32 _getPOIList(const CCharAnimTime& time, + CInt32POINode* listOut, + u32 capacity, u32 iterator, u32 unk1, + const std::vector& stream, + const CCharAnimTime& curTime); + +template u32 _getPOIList(const CCharAnimTime& time, + CParticlePOINode* listOut, + u32 capacity, u32 iterator, u32 unk1, + const std::vector& stream, + const CCharAnimTime& curTime, + const IAnimSourceInfo& animInfo, u32 passedCount); +template u32 _getPOIList(const CCharAnimTime& time, + CParticlePOINode* listOut, + u32 capacity, u32 iterator, u32 unk1, + const std::vector& stream, + const CCharAnimTime& curTime); + +template u32 _getPOIList(const CCharAnimTime& time, + CSoundPOINode* listOut, + u32 capacity, u32 iterator, u32 unk1, + const std::vector& stream, + const CCharAnimTime& curTime, + const IAnimSourceInfo& animInfo, u32 passedCount); +template u32 _getPOIList(const CCharAnimTime& time, + CSoundPOINode* listOut, + u32 capacity, u32 iterator, u32 unk1, + const std::vector& stream, + const CCharAnimTime& curTime); + } diff --git a/Runtime/Character/CPOINode.hpp b/Runtime/Character/CPOINode.hpp index 64a1d627e..fda27a9a5 100644 --- a/Runtime/Character/CPOINode.hpp +++ b/Runtime/Character/CPOINode.hpp @@ -6,6 +6,7 @@ namespace urde { +class IAnimSourceInfo; enum class EPOIType : u16 { @@ -45,6 +46,21 @@ public: u32 GetFlags() const { return x34_flags; } }; +template +u32 _getPOIList(const CCharAnimTime& time, + T* listOut, + u32 capacity, u32 iterator, u32 unk1, + const std::vector& stream, + const CCharAnimTime& curTime, + const IAnimSourceInfo& animInfo, u32 passedCount); + +template +u32 _getPOIList(const CCharAnimTime& time, + T* listOut, + u32 capacity, u32 iterator, u32 unk1, + const std::vector& stream, + const CCharAnimTime& curTime); + } #endif // __URDE_CPOINODE_HPP__ diff --git a/Runtime/Character/CPrimitive.hpp b/Runtime/Character/CPrimitive.hpp index 9f1df34d0..1adabc3c6 100644 --- a/Runtime/Character/CPrimitive.hpp +++ b/Runtime/Character/CPrimitive.hpp @@ -17,6 +17,7 @@ public: ResId GetAnimResId() const { return x0_animId; } u32 GetAnimDbIdx() const { return x4_animIdx; } const std::string& GetName() const { return x8_animName; } + bool operator<(const CPrimitive& other) const { return x8_animName < other.x8_animName; } }; } diff --git a/Runtime/Character/CSequenceHelper.cpp b/Runtime/Character/CSequenceHelper.cpp new file mode 100644 index 000000000..6d43c3f2a --- /dev/null +++ b/Runtime/Character/CSequenceHelper.cpp @@ -0,0 +1,40 @@ +#include "CSequenceHelper.hpp" +#include "CAnimSysContext.hpp" +#include "CBoolPOINode.hpp" +#include "CInt32POINode.hpp" +#include "CParticlePOINode.hpp" +#include "CSoundPOINode.hpp" + +namespace urde +{ + +CSequenceFundamentals::CSequenceFundamentals(const CSteadyStateAnimInfo& ssInfo, + const std::vector& boolNodes, + const std::vector& int32Nodes, + const std::vector& particleNodes, + const std::vector& soundNodes) +: x0_ssInfo(ssInfo), x18_boolNodes(boolNodes), x28_int32Nodes(int32Nodes), x38_particleNodes(particleNodes), + x48_soundNodes(soundNodes) +{ +} + +CSequenceHelper::CSequenceHelper(const std::shared_ptr& a, + const std::shared_ptr& b, + const CAnimSysContext& animCtx) +: x0_transDB(animCtx.x0_transDB) +{ + x10_treeNodes.reserve(2); + x10_treeNodes.push_back(a); + x10_treeNodes.push_back(b); +} + +CSequenceHelper::CSequenceHelper(const std::vector>& nodes, + const CAnimSysContext& animCtx) +{ +} + +CSequenceFundamentals CSequenceHelper::ComputeSequenceFundamentals() +{ +} + +} diff --git a/Runtime/Character/CSequenceHelper.hpp b/Runtime/Character/CSequenceHelper.hpp new file mode 100644 index 000000000..97795cb5a --- /dev/null +++ b/Runtime/Character/CSequenceHelper.hpp @@ -0,0 +1,53 @@ +#ifndef __URDE_CSEQUENCEHELPER_HPP__ +#define __URDE_CSEQUENCEHELPER_HPP__ + +#include "CAnimTreeNode.hpp" +#include "CBoolPOINode.hpp" +#include "CInt32POINode.hpp" +#include "CParticlePOINode.hpp" +#include "CSoundPOINode.hpp" + +namespace urde +{ +class CAnimSysContext; +class IMetaAnim; +class CTransitionDatabaseGame; + +class CSequenceFundamentals +{ + CSteadyStateAnimInfo x0_ssInfo; + std::vector x18_boolNodes; + std::vector x28_int32Nodes; + std::vector x38_particleNodes; + std::vector x48_soundNodes; +public: + CSequenceFundamentals(const CSteadyStateAnimInfo& ssInfo, + const std::vector& boolNodes, + const std::vector& int32Nodes, + const std::vector& particleNodes, + const std::vector& soundNodes); + + const CSteadyStateAnimInfo& GetSteadyStateAnimInfo() const { return x0_ssInfo; } + const std::vector& GetBoolPointsOfInterest() const { return x18_boolNodes; } + const std::vector& GetInt32PointsOfInterest() const { return x28_int32Nodes; } + const std::vector& GetParticlePointsOfInterest() const { return x38_particleNodes; } + const std::vector& GetSoundPointsOfInterest() const { return x48_soundNodes; } +}; + +class CSequenceHelper +{ + TLockedToken x0_transDB; + std::vector> x10_treeNodes; + std::vector x20_; +public: + CSequenceHelper(const std::shared_ptr& a, + const std::shared_ptr& b, + const CAnimSysContext& animCtx); + CSequenceHelper(const std::vector>& nodes, + const CAnimSysContext& animCtx); + CSequenceFundamentals ComputeSequenceFundamentals(); +}; + +} + +#endif // __URDE_CSEQUENCEHELPER_HPP__ diff --git a/Runtime/Character/IAnimReader.hpp b/Runtime/Character/IAnimReader.hpp index 0c50838cf..190f83184 100644 --- a/Runtime/Character/IAnimReader.hpp +++ b/Runtime/Character/IAnimReader.hpp @@ -30,11 +30,19 @@ struct SAdvancementResults SAdvancementDeltas x8_deltas; }; -struct CSteadyStateAnimInfo +class CSteadyStateAnimInfo { - CCharAnimTime x64_duration; - zeus::CVector3f x6c_curRootOffset; - bool x78_ = false; + CCharAnimTime x0_duration; + zeus::CVector3f x8_offset; + bool x14_looping = false; + +public: + CSteadyStateAnimInfo(bool looping, const CCharAnimTime& duration, const zeus::CVector3f& offset) + : x0_duration(duration), x8_offset(offset), x14_looping(looping) {} + + const CCharAnimTime& GetDuration() const { return x0_duration; } + const zeus::CVector3f& GetOffset() const { return x8_offset; } + bool IsLooping() const { return x14_looping; } }; struct CAnimTreeEffectiveContribution diff --git a/Runtime/Character/IMetaAnim.cpp b/Runtime/Character/IMetaAnim.cpp index e09053338..af2417015 100644 --- a/Runtime/Character/IMetaAnim.cpp +++ b/Runtime/Character/IMetaAnim.cpp @@ -2,6 +2,7 @@ #include "CCharAnimTime.hpp" #include "IAnimReader.hpp" #include "CBoolPOINode.hpp" +#include "CAnimTreeNode.hpp" namespace urde { @@ -10,7 +11,18 @@ std::shared_ptr IMetaAnim::GetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const { - return {}; + if (orders.x44_) + { + std::shared_ptr tree = + VGetAnimationTree(animSys, CMetaAnimTreeBuildOrders::NoSpecialOrders()); + if (orders.x44_->IsTime() || orders.x44_->IsString()) + { + CCharAnimTime time = GetTime(*orders.x44_, *tree); + AdvanceAnim(*tree, time); + } + return tree; + } + return VGetAnimationTree(animSys, CMetaAnimTreeBuildOrders::NoSpecialOrders()); } void IMetaAnim::AdvanceAnim(IAnimReader& anim, const CCharAnimTime& dt) diff --git a/Runtime/Character/IMetaAnim.hpp b/Runtime/Character/IMetaAnim.hpp index db30998a9..9190ebc2a 100644 --- a/Runtime/Character/IMetaAnim.hpp +++ b/Runtime/Character/IMetaAnim.hpp @@ -70,7 +70,7 @@ public: const CMetaAnimTreeBuildOrders& orders) const=0; static void AdvanceAnim(IAnimReader& anim, const CCharAnimTime& dt); - CCharAnimTime GetTime(const CPreAdvanceIndicator& ind, const IAnimReader& anim); + static CCharAnimTime GetTime(const CPreAdvanceIndicator& ind, const IAnimReader& anim); }; }