diff --git a/Runtime/Character/CAllFormatsAnimSource.cpp b/Runtime/Character/CAllFormatsAnimSource.cpp index 315a8edcf..35ac80f3b 100644 --- a/Runtime/Character/CAllFormatsAnimSource.cpp +++ b/Runtime/Character/CAllFormatsAnimSource.cpp @@ -2,6 +2,7 @@ #include "logvisor/logvisor.hpp" #include "CSimplePool.hpp" #include "CAnimSourceReader.hpp" +#include "CFBStreamedAnimReader.hpp" namespace urde { @@ -15,8 +16,11 @@ void CAnimFormatUnion::SubConstruct(u8* storage, EAnimFormat fmt, case EAnimFormat::Uncompressed: new (storage) CAnimSource(in, store); break; + case EAnimFormat::BitstreamCompressed: + new (storage) CFBStreamedCompression(in, store, false); + break; case EAnimFormat::BitstreamCompressed24: - new (storage) CAnimSource(in, store); + new (storage) CFBStreamedCompression(in, store, true); break; default: Log.report(logvisor::Fatal, "unable to read ANIM format %d", int(fmt)); @@ -35,11 +39,15 @@ CAnimFormatUnion::~CAnimFormatUnion() { case EAnimFormat::Uncompressed: reinterpret_cast(x4_storage)->~CAnimSource(); + break; + case EAnimFormat::BitstreamCompressed: + case EAnimFormat::BitstreamCompressed24: + reinterpret_cast(x4_storage)->~CFBStreamedCompression(); default: break; } } -std::shared_ptr +std::shared_ptr CAllFormatsAnimSource::GetNewReader(const TLockedToken& tok, const CCharAnimTime& startTime) { diff --git a/Runtime/Character/CAllFormatsAnimSource.hpp b/Runtime/Character/CAllFormatsAnimSource.hpp index c2a5d2519..e4106ecbc 100644 --- a/Runtime/Character/CAllFormatsAnimSource.hpp +++ b/Runtime/Character/CAllFormatsAnimSource.hpp @@ -4,12 +4,13 @@ #include "RetroTypes.hpp" #include "zeus/CVector3f.hpp" #include "CAnimSource.hpp" +#include "CFBStreamedCompression.hpp" #include "CFactoryMgr.hpp" namespace urde { class IObjectStore; -class CAnimSourceReaderBase; +class IAnimReader; enum class EAnimFormat { @@ -26,7 +27,7 @@ class CAnimFormatUnion EAnimFormat x0_format; intptr_t _align = 0; }; - u8 x4_storage[sizeof(CAnimSource)]; + u8 x4_storage[std::max(sizeof(CAnimSource), sizeof(CFBStreamedCompression))]; static void SubConstruct(u8* storage, EAnimFormat fmt, CInputStream& in, IObjectStore& store); public: @@ -41,8 +42,8 @@ class CAllFormatsAnimSource : public CAnimFormatUnion SObjectTag x74_tag; public: CAllFormatsAnimSource(CInputStream& in, IObjectStore& store, const SObjectTag& tag); - static std::shared_ptr GetNewReader(const TLockedToken& tok, - const CCharAnimTime& startTime); + static std::shared_ptr GetNewReader(const TLockedToken& tok, + const CCharAnimTime& startTime); }; CFactoryFnReturn AnimSourceFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params); diff --git a/Runtime/Character/CAnimTreeAnimReaderContainer.cpp b/Runtime/Character/CAnimTreeAnimReaderContainer.cpp index e69de29bb..7f2737e08 100644 --- a/Runtime/Character/CAnimTreeAnimReaderContainer.cpp +++ b/Runtime/Character/CAnimTreeAnimReaderContainer.cpp @@ -0,0 +1,114 @@ +#include "CAnimTreeAnimReaderContainer.hpp" + +namespace urde +{ + +CAnimTreeAnimReaderContainer::CAnimTreeAnimReaderContainer(const std::string& name, + std::shared_ptr reader, + u32 dbIdx) +: CAnimTreeNode(name), x14_reader(reader), x1c_animDbIdx(dbIdx) +{ +} + +CAnimTreeEffectiveContribution CAnimTreeAnimReaderContainer::VGetContributionOfHighestInfluence() const +{ + return {1.f, x4_name, VGetSteadyStateAnimInfo(), VGetTimeRemaining(), x1c_animDbIdx}; +} + +SAdvancementResults CAnimTreeAnimReaderContainer::VAdvanceView(const CCharAnimTime& dt) +{ + return x14_reader->VAdvanceView(dt); +} + +CCharAnimTime CAnimTreeAnimReaderContainer::VGetTimeRemaining() const +{ + return x14_reader->VGetTimeRemaining(); +} + +CSteadyStateAnimInfo CAnimTreeAnimReaderContainer::VGetSteadyStateAnimInfo() const +{ + return x14_reader->VGetSteadyStateAnimInfo(); +} + +bool CAnimTreeAnimReaderContainer::VHasOffset(const CSegId& seg) const +{ + return x14_reader->VHasOffset(seg); +} + +zeus::CVector3f CAnimTreeAnimReaderContainer::VGetOffset(const CSegId& seg) const +{ + return x14_reader->VGetOffset(seg); +} + +zeus::CQuaternion CAnimTreeAnimReaderContainer::VGetRotation(const CSegId& seg) const +{ + return x14_reader->VGetRotation(seg); +} + +u32 CAnimTreeAnimReaderContainer::VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut, + u32 capacity, u32 iterator, u32 unk) const +{ + return x14_reader->GetBoolPOIList(time, listOut, capacity, iterator, unk); +} + +u32 CAnimTreeAnimReaderContainer::VGetInt32POIList(const CCharAnimTime& time, CInt32POINode* listOut, + u32 capacity, u32 iterator, u32 unk) const +{ + return x14_reader->GetInt32POIList(time, listOut, capacity, iterator, unk); +} + +u32 CAnimTreeAnimReaderContainer::VGetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut, + u32 capacity, u32 iterator, u32 unk) const +{ + return x14_reader->GetParticlePOIList(time, listOut, capacity, iterator, unk); +} + +u32 CAnimTreeAnimReaderContainer::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, + u32 capacity, u32 iterator, u32 unk) const +{ + return x14_reader->GetSoundPOIList(time, listOut, capacity, iterator, unk); +} + +bool CAnimTreeAnimReaderContainer::VGetBoolPOIState(const char* name) const +{ + return x14_reader->VGetBoolPOIState(name); +} + +s32 CAnimTreeAnimReaderContainer::VGetInt32POIState(const char* name) const +{ + return x14_reader->VGetBoolPOIState(name); +} + +CParticleData::EParentedMode CAnimTreeAnimReaderContainer::VGetParticlePOIState(const char* name) const +{ + return x14_reader->VGetParticlePOIState(name); +} + +void CAnimTreeAnimReaderContainer::VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const +{ + return x14_reader->VGetSegStatementSet(list, setOut); +} + +void CAnimTreeAnimReaderContainer::VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const +{ + return x14_reader->VGetSegStatementSet(list, setOut, time); +} + +std::shared_ptr CAnimTreeAnimReaderContainer::VClone() const +{ + std::shared_ptr ret = + std::make_shared(x4_name, x14_reader->Clone(), x1c_animDbIdx); + return ret; +} + +void CAnimTreeAnimReaderContainer::VSetPhase(float ph) +{ + x14_reader->VSetPhase(ph); +} + +SAdvancementResults CAnimTreeAnimReaderContainer::VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const +{ + return x14_reader->VGetAdvancementResults(a, b); +} + +} diff --git a/Runtime/Character/CAnimTreeAnimReaderContainer.hpp b/Runtime/Character/CAnimTreeAnimReaderContainer.hpp index a5fc19b1e..8963df35b 100644 --- a/Runtime/Character/CAnimTreeAnimReaderContainer.hpp +++ b/Runtime/Character/CAnimTreeAnimReaderContainer.hpp @@ -8,9 +8,37 @@ namespace urde class CAnimTreeAnimReaderContainer : public CAnimTreeNode { - std::shared_ptr x14_ + std::shared_ptr x14_reader; + u32 x1c_animDbIdx; public: - CAnimTreeAnimReaderContainer(const std::string& name, std::shared_ptr<>); + CAnimTreeAnimReaderContainer(const std::string& name, + std::shared_ptr reader, + u32 animDbIdx); + + u32 Depth() const { return 1; } + CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const; + u32 VGetNumChildren() const { return 0; } + std::shared_ptr VGetBestUnblendedChild() const { return {}; } + + SAdvancementResults VAdvanceView(const CCharAnimTime& a); + CCharAnimTime VGetTimeRemaining() const; + CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const; + bool VHasOffset(const CSegId& seg) const; + zeus::CVector3f VGetOffset(const CSegId& seg) const; + zeus::CQuaternion VGetRotation(const CSegId& seg) 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; + bool VGetBoolPOIState(const char*) const; + s32 VGetInt32POIState(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 CCharAnimTime& time) const; + std::shared_ptr VClone() const; + std::shared_ptr VSimplified() { return {}; } + void VSetPhase(float); + SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const; }; } diff --git a/Runtime/Character/CAnimTreeDoubleChild.hpp b/Runtime/Character/CAnimTreeDoubleChild.hpp index eee20d212..f208b2ccb 100644 --- a/Runtime/Character/CAnimTreeDoubleChild.hpp +++ b/Runtime/Character/CAnimTreeDoubleChild.hpp @@ -19,8 +19,8 @@ public: CParticleData::EParentedMode VGetParticlePOIState(const char* name) const; void VSetPhase(float); SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const; - void Depth() const; - void VGetContributionOfHighestInfluence() const; + u32 Depth() const; + CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const; u32 VGetNumChildren() const; std::shared_ptr VGetBestUnblendedChild() const; }; diff --git a/Runtime/Character/CAnimTreeNode.hpp b/Runtime/Character/CAnimTreeNode.hpp index 03672fe12..40803e670 100644 --- a/Runtime/Character/CAnimTreeNode.hpp +++ b/Runtime/Character/CAnimTreeNode.hpp @@ -8,13 +8,14 @@ namespace urde class CAnimTreeNode : public IAnimReader { +protected: std::string x4_name; public: CAnimTreeNode(const std::string& name) : x4_name(name) {} bool IsCAnimTreeNode() const {return true;} - virtual void Depth() const=0; - virtual void VGetContributionOfHighestInfluence() const=0; + virtual u32 Depth() const=0; + virtual CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const=0; virtual u32 VGetNumChildren() const=0; virtual std::shared_ptr VGetBestUnblendedChild() const=0; diff --git a/Runtime/Character/CAnimTreeSingleChild.cpp b/Runtime/Character/CAnimTreeSingleChild.cpp index 109b6d7e9..b0b9ad940 100644 --- a/Runtime/Character/CAnimTreeSingleChild.cpp +++ b/Runtime/Character/CAnimTreeSingleChild.cpp @@ -99,8 +99,9 @@ CAnimTreeSingleChild::VGetAdvancementResults(const CCharAnimTime& a, return {}; } -void CAnimTreeSingleChild::Depth() const +u32 CAnimTreeSingleChild::Depth() const { + return 1; } u32 CAnimTreeSingleChild::VGetNumChildren() const diff --git a/Runtime/Character/CAnimTreeSingleChild.hpp b/Runtime/Character/CAnimTreeSingleChild.hpp index bd127cf0e..67296577b 100644 --- a/Runtime/Character/CAnimTreeSingleChild.hpp +++ b/Runtime/Character/CAnimTreeSingleChild.hpp @@ -28,7 +28,7 @@ public: void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const; void VSetPhase(float); SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const; - void Depth() const; + u32 Depth() const; u32 VGetNumChildren() const; }; diff --git a/Runtime/Character/CMetaAnimPlay.cpp b/Runtime/Character/CMetaAnimPlay.cpp index a2c75fb1f..e611df89b 100644 --- a/Runtime/Character/CMetaAnimPlay.cpp +++ b/Runtime/Character/CMetaAnimPlay.cpp @@ -1,10 +1,14 @@ #include "CMetaAnimPlay.hpp" +#include "CAnimSysContext.hpp" +#include "CSimplePool.hpp" +#include "CAllFormatsAnimSource.hpp" +#include "CAnimTreeAnimReaderContainer.hpp" namespace urde { CMetaAnimPlay::CMetaAnimPlay(CInputStream& in) -: x4_primitive(in), x1c_(in.readFloatBig()), x20_(in.readUint32Big()) {} +: x4_primitive(in), x1c_startTime(in) {} std::shared_ptr CMetaAnimPlay::GetAnimationTree(const CAnimSysContext& animSys, @@ -21,7 +25,20 @@ std::shared_ptr CMetaAnimPlay::VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const { - return {}; + if (orders.x0_) + { + CMetaAnimTreeBuildOrders modOrders; + modOrders.PreAdvanceForAll(*orders.x0_); + return GetAnimationTree(animSys, modOrders); + } + + TLockedToken prim = + animSys.xc_store.GetObj(SObjectTag{FOURCC('ANIM'), x4_primitive.GetAnimResId()}); + std::shared_ptr ret = + std::make_shared(x4_primitive.GetName(), + CAllFormatsAnimSource::GetNewReader(prim, x1c_startTime), + x4_primitive.GetAnimDbIdx()); + return ret; } } diff --git a/Runtime/Character/CMetaAnimPlay.hpp b/Runtime/Character/CMetaAnimPlay.hpp index 07d77dd60..ea49c088c 100644 --- a/Runtime/Character/CMetaAnimPlay.hpp +++ b/Runtime/Character/CMetaAnimPlay.hpp @@ -11,8 +11,7 @@ namespace urde class CMetaAnimPlay : public IMetaAnim { CPrimitive x4_primitive; - float x1c_; - u32 x20_; + CCharAnimTime x1c_startTime; public: CMetaAnimPlay(CInputStream& in); EMetaAnimType GetType() const {return EMetaAnimType::Primitive;} diff --git a/Runtime/Character/CPrimitive.hpp b/Runtime/Character/CPrimitive.hpp index c6a2e1b1e..9f1df34d0 100644 --- a/Runtime/Character/CPrimitive.hpp +++ b/Runtime/Character/CPrimitive.hpp @@ -14,7 +14,9 @@ class CPrimitive std::string x8_animName; public: CPrimitive(CInputStream& in); - ResId GetAnimResId() const {return x0_animId;} + ResId GetAnimResId() const { return x0_animId; } + u32 GetAnimDbIdx() const { return x4_animIdx; } + const std::string& GetName() const { return x8_animName; } }; } diff --git a/Runtime/Character/IAnimReader.hpp b/Runtime/Character/IAnimReader.hpp index 912140ee0..0c50838cf 100644 --- a/Runtime/Character/IAnimReader.hpp +++ b/Runtime/Character/IAnimReader.hpp @@ -37,6 +37,24 @@ struct CSteadyStateAnimInfo bool x78_ = false; }; +struct CAnimTreeEffectiveContribution +{ + float x0_contributionWeight; + std::string x4_name; + CSteadyStateAnimInfo x14_ssInfo; + CCharAnimTime x2c_remTime; + u32 x34_dbIdx; +public: + CAnimTreeEffectiveContribution(float cweight, const std::string& name, const CSteadyStateAnimInfo& ssInfo, + const CCharAnimTime& remTime, u32 dbIdx) + : x0_contributionWeight(cweight), x4_name(name), x14_ssInfo(ssInfo), x2c_remTime(remTime), x34_dbIdx(dbIdx) {} + float GetContributionWeight() const { return x0_contributionWeight; } + const std::string& GetPrimitiveName() const { return x4_name; } + const CSteadyStateAnimInfo& GetSteadyStateAnimInfo() const { return x14_ssInfo; } + const CCharAnimTime& GetTimeRemaining() const { return x2c_remTime; } + u32 GetAnimDatabaseIndex() const { return x34_dbIdx; } +}; + template using TSubAnimTypeToken = TLockedToken; @@ -69,6 +87,8 @@ public: u32 GetInt32POIList(const CCharAnimTime& time, CInt32POINode* 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; + + std::shared_ptr Clone() const { return VClone(); } }; } diff --git a/Runtime/Character/IMetaAnim.hpp b/Runtime/Character/IMetaAnim.hpp index a7974a628..db30998a9 100644 --- a/Runtime/Character/IMetaAnim.hpp +++ b/Runtime/Character/IMetaAnim.hpp @@ -27,6 +27,18 @@ class CPreAdvanceIndicator bool x0_isTime; CCharAnimTime x4_time; const char* xc_string; + u32 x10_; + u32 x14_; + u32 x18_; + u32 x1c_; + u32 x20_; + u32 x24_; + u32 x28_; + u32 x2c_; + u32 x30_; + u32 x34_; + u32 x38_; + u16 x3c_; public: CPreAdvanceIndicator(const CCharAnimTime& time) : x0_isTime(true), x4_time(time) {} @@ -38,6 +50,14 @@ public: bool IsTime() const {return x0_isTime;} }; +struct CMetaAnimTreeBuildOrders +{ + std::experimental::optional x0_; + std::experimental::optional x44_; + static CMetaAnimTreeBuildOrders NoSpecialOrders() { return {}; } + void PreAdvanceForAll(const CPreAdvanceIndicator& ind) { x44_.emplace(ind); } +}; + class IMetaAnim { public: