diff --git a/config/GM8E01_00/symbols.txt b/config/GM8E01_00/symbols.txt index 446b4bc2..05eb2d0f 100644 --- a/config/GM8E01_00/symbols.txt +++ b/config/GM8E01_00/symbols.txt @@ -12468,7 +12468,7 @@ GetNewDerivedObject__45TObjOwnerDerivedFromIObj<17CAnimCharacterSet>FRCQ24rstl29 __dt__Q24rstl29auto_ptr<17CAnimCharacterSet>Fv = .text:0x802D863C; // type:function size:0x64 __ct__17CAnimCharacterSetFR12CInputStream = .text:0x802D86A0; // type:function size:0x5C scope:global __dt__15CAnimTreeLoopInFv = .text:0x802D86FC; // type:function size:0x114 scope:global -fn_802D8810 = .text:0x802D8810; // type:function size:0x1DC +__dt__21CSequenceFundamentalsFv = .text:0x802D8810; // type:function size:0x1DC scope:global Depth__20CAnimTreeSingleChildCFv = .text:0x802D89EC; // type:function size:0x38 scope:global CreatePrimitiveName__15CAnimTreeLoopInFRCQ24rstl25ncrc_ptr<13CAnimTreeNode>RCQ24rstl25ncrc_ptr<13CAnimTreeNode>RCQ24rstl25ncrc_ptr<13CAnimTreeNode> = .text:0x802D8A24; // type:function size:0x34 scope:global VGetContributionOfHighestInfluence__15CAnimTreeLoopInCFv = .text:0x802D8A58; // type:function size:0x34 scope:global @@ -12485,9 +12485,9 @@ VGetSteadyStateAnimInfo__15CAnimTreeLoopInCFv = .text:0x802D90B0; // type:functi VGetTimeRemaining__15CAnimTreeLoopInCFv = .text:0x802D90E4; // type:function size:0x4C scope:global VAdvanceView__15CAnimTreeLoopInFRC13CCharAnimTime = .text:0x802D9130; // type:function size:0x200 scope:global __ct__15CAnimTreeLoopInFRCQ24rstl25ncrc_ptr<13CAnimTreeNode>RCQ24rstl25ncrc_ptr<13CAnimTreeNode>bRC15CAnimSysContextRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC21CSequenceFundamentalsRC13CCharAnimTime = .text:0x802D9330; // type:function size:0xEC scope:global -fn_802D941C = .text:0x802D941C; // type:function size:0x98 -fn_802D94B4 = .text:0x802D94B4; // type:function size:0x14C -fn_802D9600 = .text:0x802D9600; // type:function size:0xB0 +__ct__21CSequenceFundamentalsFRC21CSequenceFundamentals = .text:0x802D941C; // type:function size:0x98 scope:global +__ct__Q24rstl50vector<13CSoundPOINode,Q24rstl17rmemory_allocator>FRCQ24rstl50vector<13CSoundPOINode,Q24rstl17rmemory_allocator> = .text:0x802D94B4; // type:function size:0x14C scope:global +__ct__Q24rstl53vector<16CParticlePOINode,Q24rstl17rmemory_allocator>FRCQ24rstl53vector<16CParticlePOINode,Q24rstl17rmemory_allocator> = .text:0x802D9600; // type:function size:0xB0 scope:global fn_802D96B0 = .text:0x802D96B0; // type:function size:0x110 __ct__Q24rstl50vector<13CInt32POINode,Q24rstl17rmemory_allocator>FRCQ24rstl50vector<13CInt32POINode,Q24rstl17rmemory_allocator> = .text:0x802D97C0; // type:function size:0x148 scope:global __ct__Q24rstl49vector<12CBoolPOINode,Q24rstl17rmemory_allocator>FRCQ24rstl49vector<12CBoolPOINode,Q24rstl17rmemory_allocator> = .text:0x802D9908; // type:function size:0x13C scope:global @@ -12501,7 +12501,7 @@ _getPOIList<16CParticlePOINode>__FRC13CCharAnimTimeP16CParticlePOINodeUiUiiRCQ24 _getPOIList<13CSoundPOINode>__FRC13CCharAnimTimeP13CSoundPOINodeUiUiiRCQ24rstl50vector<13CSoundPOINode,Q24rstl17rmemory_allocator>RC13CCharAnimTime = .text:0x802DA798; // type:function size:0x2F4 scope:global CopyNodeMinusStartTime__13CSoundPOINodeFRC13CSoundPOINodeRC13CCharAnimTime = .text:0x802DAA8C; // type:function size:0xA8 scope:global __dt__17CAnimTreeSequenceFv = .text:0x802DAB34; // type:function size:0x164 scope:global -fn_802DAC98 = .text:0x802DAC98; // type:function size:0x34 +VGetNodeType__17CAnimTreeSequenceCFv = .text:0x802DAC98; // type:function size:0x34 scope:global VGetContributionOfHighestInfluence__17CAnimTreeSequenceCFv = .text:0x802DACCC; // type:function size:0x34 scope:global VSupportsReverseView__17CAnimTreeSequenceCFv = .text:0x802DAD00; // type:function size:0x8 scope:global VGetBestUnblendedChild__17CAnimTreeSequenceCFv = .text:0x802DAD08; // type:function size:0x178 scope:global @@ -12513,7 +12513,7 @@ VGetBoolPOIList__17CAnimTreeSequenceCFRC13CCharAnimTimeP12CBoolPOINodeUiUii = .t VGetSteadyStateAnimInfo__17CAnimTreeSequenceCFv = .text:0x802DB298; // type:function size:0x34 scope:global VGetTimeRemaining__17CAnimTreeSequenceCFv = .text:0x802DB2CC; // type:function size:0x7C scope:global VAdvanceView__17CAnimTreeSequenceFRC13CCharAnimTime = .text:0x802DB348; // type:function size:0x6AC scope:global -fn_802DB9F4 = .text:0x802DB9F4; // type:function size:0x98 +__as__21CSequenceFundamentalsFRC21CSequenceFundamentals = .text:0x802DB9F4; // type:function size:0x98 __as__Q24rstl50vector<13CSoundPOINode,Q24rstl17rmemory_allocator>FRCQ24rstl50vector<13CSoundPOINode,Q24rstl17rmemory_allocator> = .text:0x802DBA8C; // type:function size:0x180 fn_802DBC0C = .text:0x802DBC0C; // type:function size:0xFC fn_802DBD08 = .text:0x802DBD08; // type:function size:0x100 @@ -12521,9 +12521,9 @@ fn_802DBE08 = .text:0x802DBE08; // type:function size:0x17C fn_802DBF84 = .text:0x802DBF84; // type:function size:0x170 __ct__17CAnimTreeSequenceFRCQ24rstl25ncrc_ptr<13CAnimTreeNode>RCQ24rstl62vector,Q24rstl17rmemory_allocator>RC15CAnimSysContextiRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC21CSequenceFundamentalsRC13CCharAnimTime = .text:0x802DC0F4; // type:function size:0x198 scope:global __ct__17CAnimTreeSequenceFRCQ24rstl62vector,Q24rstl17rmemory_allocator>RC15CAnimSysContextRCQ24rstl66basic_string,Q24rstl17rmemory_allocator> = .text:0x802DC28C; // type:function size:0x1FC scope:global -fn_802DC488 = .text:0x802DC488; // type:function size:0x2C4 -fn_802DC74C = .text:0x802DC74C; // type:function size:0x340 -fn_802DCA8C = .text:0x802DCA8C; // type:function size:0x3D4 +_getPOIList<12CBoolPOINode>__FRC13CCharAnimTimeP12CBoolPOINodeUiUiiQ24rstl49vector<12CBoolPOINode,Q24rstl17rmemory_allocator>RC13CCharAnimTime = .text:0x802DC488; // type:function size:0x2C4 scope:global +_getPOIList<13CInt32POINode>__FRC13CCharAnimTimeP13CInt32POINodeUiUiiQ24rstl50vector<13CInt32POINode,Q24rstl17rmemory_allocator>RC13CCharAnimTime = .text:0x802DC74C; // type:function size:0x340 scope:global +_getPOIList<16CParticlePOINode>__FRC13CCharAnimTimeP16CParticlePOINodeUiUiiQ24rstl53vector<16CParticlePOINode,Q24rstl17rmemory_allocator>RC13CCharAnimTime = .text:0x802DCA8C; // type:function size:0x3D4 scope:global _getPOIList<13CSoundPOINode>__FRC13CCharAnimTimeP13CSoundPOINodeUiUiiQ24rstl50vector<13CSoundPOINode,Q24rstl17rmemory_allocator>RC13CCharAnimTime = .text:0x802DCE60; // type:function size:0x2F4 scope:global reserve__Q24rstl49vector<12CBoolPOINode,Q24rstl17rmemory_allocator>Fi = .text:0x802DD154; // type:function size:0xE8 fn_802DD23C = .text:0x802DD23C; // type:function size:0xD8 @@ -17753,7 +17753,7 @@ kUnknownType__10CCallStack = .rodata:0x803D6AA8; // type:object size:0xD scope:g @stringBase0 = .rodata:0x803D6D28; // type:object size:0x7 scope:local data:string lbl_803D6D30 = .rodata:0x803D6D30; // type:object size:0x7 data:string lbl_803D6D38 = .rodata:0x803D6D38; // type:object size:0x8 -lbl_803D6D40 = .rodata:0x803D6D40; // type:object size:0x8 +@stringBase0 = .rodata:0x803D6D40; // type:object size:0x8 scope:local data:string_table lbl_803D6D48 = .rodata:0x803D6D48; // type:object size:0x7 data:string lbl_803D6D50 = .rodata:0x803D6D50; // type:object size:0x7 data:string lbl_803D6D58 = .rodata:0x803D6D58; // type:object size:0x7 data:string @@ -18787,7 +18787,7 @@ __vt__17CCollidableSphere = .data:0x803ECAF8; // type:object size:0x28 scope:glo jumptable_803ECB20 = .data:0x803ECB20; // type:object size:0xAC scope:local __vt__45TObjOwnerDerivedFromIObj<17CAnimCharacterSet> = .data:0x803ECBD0; // type:object size:0x10 lbl_803ECBE0 = .data:0x803ECBE0; // type:object size:0x78 -lbl_803ECC58 = .data:0x803ECC58; // type:object size:0x78 +__vt__17CAnimTreeSequence = .data:0x803ECC58; // type:object size:0x78 scope:global __vt__14CMetaAnimBlend = .data:0x803ECCD0; // type:object size:0x20 __vt__19CMetaAnimPhaseBlend = .data:0x803ECCF0; // type:object size:0x20 lbl_803ECD10 = .data:0x803ECD10; // type:object size:0x20 diff --git a/include/Kyoto/Animation/CAnimSysContext.hpp b/include/Kyoto/Animation/CAnimSysContext.hpp index 7ef7caa9..b0a55453 100644 --- a/include/Kyoto/Animation/CAnimSysContext.hpp +++ b/include/Kyoto/Animation/CAnimSysContext.hpp @@ -20,7 +20,7 @@ class CAnimSysContext { private: TToken< CTransitionDatabaseGame > x0_transDb; - rstl::rc_ptr< CRandom16 > x8_random; + rstl::ncrc_ptr< CRandom16 > x8_random; CSimplePool& xc_store; }; diff --git a/include/Kyoto/Animation/CAnimTreeDoubleChild.hpp b/include/Kyoto/Animation/CAnimTreeDoubleChild.hpp index 5d1162b1..9abbb28e 100644 --- a/include/Kyoto/Animation/CAnimTreeDoubleChild.hpp +++ b/include/Kyoto/Animation/CAnimTreeDoubleChild.hpp @@ -44,7 +44,7 @@ class CAnimTreeDoubleChild : public CAnimTreeNode { uint Depth() const override; CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const override; uint VGetNumChildren() const override; - rstl::rc_ptr< IAnimReader > VGetBestUnblendedChild() const override; + rstl::rc_ptr< CAnimTreeNode > VGetBestUnblendedChild() const override; void VGetWeightedReaders( float w, rstl::reserved_vector< rstl::pair< float, IAnimReader* >, 16 >& out) const override; diff --git a/include/Kyoto/Animation/CAnimTreeNode.hpp b/include/Kyoto/Animation/CAnimTreeNode.hpp index 13d6fbdf..5426367e 100644 --- a/include/Kyoto/Animation/CAnimTreeNode.hpp +++ b/include/Kyoto/Animation/CAnimTreeNode.hpp @@ -17,17 +17,23 @@ class CAnimTreeNode : public IAnimReader { virtual CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const = 0; virtual uint VGetNumChildren() const = 0; - virtual rstl::rc_ptr< IAnimReader > VGetBestUnblendedChild() const = 0; + virtual rstl::rc_ptr< CAnimTreeNode > VGetBestUnblendedChild() const = 0; virtual void VGetWeightedReaders( float w, rstl::reserved_vector< rstl::pair< float, IAnimReader* >, 16 >& out) const = 0; + + CAnimTreeEffectiveContribution GetContributionOfHighestInfluence() const { return VGetContributionOfHighestInfluence(); } + rstl::rc_ptr< CAnimTreeNode > GetBestUnblendedChild() const { + return VGetBestUnblendedChild(); + } + bool IsCAnimTreeNode() const override { return true; } -private: +protected: rstl::string x4_name; }; diff --git a/include/Kyoto/Animation/CAnimTreeSequence.hpp b/include/Kyoto/Animation/CAnimTreeSequence.hpp new file mode 100644 index 00000000..3477c5f6 --- /dev/null +++ b/include/Kyoto/Animation/CAnimTreeSequence.hpp @@ -0,0 +1,53 @@ +#ifndef _CANIMTREESEQUENCE +#define _CANIMTREESEQUENCE + +#include "Kyoto/Animation/CAnimSysContext.hpp" +#include "Kyoto/Animation/CAnimTreeSingleChild.hpp" +#include "Kyoto/Animation/CCharAnimTime.hpp" +#include "Kyoto/Animation/CSequenceHelper.hpp" + +#include "rstl/rc_ptr.hpp" +#include "rstl/vector.hpp" + +class IMetaAnim; + +class CAnimTreeSequence : public CAnimTreeSingleChild { +public: + CAnimTreeSequence(const rstl::vector< rstl::rc_ptr< IMetaAnim > >& seq, + const CAnimSysContext& animSys, const rstl::string& name); + CAnimTreeSequence(const rstl::ncrc_ptr< CAnimTreeNode >& curNode, + const rstl::vector< rstl::rc_ptr< IMetaAnim > >& metaAnims, + const CAnimSysContext& animSys, int curIdx, const rstl::string& name, + const CSequenceFundamentals& fundamentals, const CCharAnimTime& time); + + // IAnimReader + SAdvancementResults VAdvanceView(const CCharAnimTime& dt) override; + CCharAnimTime VGetTimeRemaining() const override; + CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const override; + uint VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut, uint capacity, + uint iterator, int) const override; + uint VGetInt32POIList(const CCharAnimTime& time, CInt32POINode* listOut, uint capacity, + uint iterator, int) const override; + uint VGetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut, uint capacity, + uint iterator, int) const override; + uint VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, uint capacity, + uint iterator, int) const override; + rstl::ownership_transfer< IAnimReader > VClone() const override; + + // CAnimTreeNode + CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const override; + rstl::rc_ptr< CAnimTreeNode > VGetBestUnblendedChild() const override; + + virtual bool VSupportsReverseView() const; + virtual rstl::string VGetNodeType() const; + +private: + CAnimSysContext x18_animCtx; + rstl::vector< rstl::rc_ptr< IMetaAnim > > x28_sequence; + int x38_curIdx; + CSequenceFundamentals x3c_fundamentals; + CCharAnimTime x94_curTime; +}; +CHECK_SIZEOF(CAnimTreeSequence, 0x9C) + +#endif // _CANIMTREESEQUENCE diff --git a/include/Kyoto/Animation/CAnimTreeSingleChild.hpp b/include/Kyoto/Animation/CAnimTreeSingleChild.hpp index befb2cfb..5ee322a1 100644 --- a/include/Kyoto/Animation/CAnimTreeSingleChild.hpp +++ b/include/Kyoto/Animation/CAnimTreeSingleChild.hpp @@ -35,8 +35,10 @@ class CAnimTreeSingleChild : public CAnimTreeNode { void VGetWeightedReaders( float w, rstl::reserved_vector< rstl::pair< float, IAnimReader* >, 16 >& out) const override; + void ReplaceChild(const rstl::ncrc_ptr< CAnimTreeNode >& node) { x14_child = node; } + protected: - rstl::rc_ptr< CAnimTreeNode > x14_child; + rstl::ncrc_ptr< CAnimTreeNode > x14_child; }; #endif // _CANIMTREESINGLECHILD diff --git a/include/Kyoto/Animation/CMetaAnimBlend.hpp b/include/Kyoto/Animation/CMetaAnimBlend.hpp index 864cc8bc..67c5b18e 100644 --- a/include/Kyoto/Animation/CMetaAnimBlend.hpp +++ b/include/Kyoto/Animation/CMetaAnimBlend.hpp @@ -16,7 +16,7 @@ class CMetaAnimBlend : public IMetaAnim { EMetaAnimType GetType() const override { return kMAT_Blend; } void GetUniquePrimitives(rstl::set< CPrimitive >& primsOut) const override; - rstl::rc_ptr< CAnimTreeNode > + rstl::ncrc_ptr< CAnimTreeNode > VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const override; diff --git a/include/Kyoto/Animation/CMetaAnimPhaseBlend.hpp b/include/Kyoto/Animation/CMetaAnimPhaseBlend.hpp index 63e51c09..0a5aa67e 100644 --- a/include/Kyoto/Animation/CMetaAnimPhaseBlend.hpp +++ b/include/Kyoto/Animation/CMetaAnimPhaseBlend.hpp @@ -16,7 +16,7 @@ class CMetaAnimPhaseBlend : public IMetaAnim { EMetaAnimType GetType() const override { return kMAT_PhaseBlend; } void GetUniquePrimitives(rstl::set< CPrimitive >& primsOut) const override; - rstl::rc_ptr< CAnimTreeNode > + rstl::ncrc_ptr< CAnimTreeNode > VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const override; diff --git a/include/Kyoto/Animation/CMetaAnimPlay.hpp b/include/Kyoto/Animation/CMetaAnimPlay.hpp index 149292f8..29d99690 100644 --- a/include/Kyoto/Animation/CMetaAnimPlay.hpp +++ b/include/Kyoto/Animation/CMetaAnimPlay.hpp @@ -14,7 +14,7 @@ class CMetaAnimPlay : public IMetaAnim { EMetaAnimType GetType() const override { return kMAT_Play; } void GetUniquePrimitives(rstl::set< CPrimitive >& primsOut) const override; - rstl::rc_ptr< CAnimTreeNode > + rstl::ncrc_ptr< CAnimTreeNode > VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const override; diff --git a/include/Kyoto/Animation/CMetaAnimRandom.hpp b/include/Kyoto/Animation/CMetaAnimRandom.hpp index 7a345e66..31947cb7 100644 --- a/include/Kyoto/Animation/CMetaAnimRandom.hpp +++ b/include/Kyoto/Animation/CMetaAnimRandom.hpp @@ -15,7 +15,7 @@ class CMetaAnimRandom : public IMetaAnim { EMetaAnimType GetType() const override { return kMAT_Random; } void GetUniquePrimitives(rstl::set< CPrimitive >& primsOut) const override; - rstl::rc_ptr< CAnimTreeNode > + rstl::ncrc_ptr< CAnimTreeNode > VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const override; diff --git a/include/Kyoto/Animation/CMetaAnimSequence.hpp b/include/Kyoto/Animation/CMetaAnimSequence.hpp index b3b5e3b2..bec68d7f 100644 --- a/include/Kyoto/Animation/CMetaAnimSequence.hpp +++ b/include/Kyoto/Animation/CMetaAnimSequence.hpp @@ -14,7 +14,7 @@ class CMetaAnimSequence : public IMetaAnim { EMetaAnimType GetType() const override { return kMAT_Sequence; } void GetUniquePrimitives(rstl::set< CPrimitive >& primsOut) const override; - rstl::rc_ptr< CAnimTreeNode > + rstl::ncrc_ptr< CAnimTreeNode > VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const override; diff --git a/include/Kyoto/Animation/CPOINode.hpp b/include/Kyoto/Animation/CPOINode.hpp index a3beea33..d30980ab 100644 --- a/include/Kyoto/Animation/CPOINode.hpp +++ b/include/Kyoto/Animation/CPOINode.hpp @@ -5,6 +5,7 @@ #include "Kyoto/Animation/CCharAnimTime.hpp" #include "rstl/string.hpp" +#include "rstl/vector.hpp" enum EPOIType { kPT_Loop = 0, @@ -51,5 +52,30 @@ class CPOINode { }; CHECK_SIZEOF(CPOINode, 0x38) +template < class T > +uint _getPOIList(const CCharAnimTime& time, T* listOut, uint capacity, uint iterator, int additive, + rstl::vector< T > stream, const CCharAnimTime& curTime) { + CCharAnimTime curTimeCopy(curTime); + uint count = stream.size(); + CCharAnimTime tmpTime = curTime + time; + uint ret = 0; + uint it = iterator; + while (it < count) { + T node(stream[it]); + if (node.GetTime() > tmpTime) + break; + if (node.GetTime() >= curTimeCopy) { + T adjustedNode = T::CopyNodeMinusStartTime(node, curTimeCopy); + uint idx = iterator + ret; + if (idx < capacity) { + ++ret; + T& dest = listOut[idx]; + dest = adjustedNode; + } + } + ++it; + } + return ret; +} #endif // _CPOINODE diff --git a/include/Kyoto/Animation/CSequenceHelper.hpp b/include/Kyoto/Animation/CSequenceHelper.hpp new file mode 100644 index 00000000..e08acf4a --- /dev/null +++ b/include/Kyoto/Animation/CSequenceHelper.hpp @@ -0,0 +1,62 @@ +#ifndef _CSEQUENCEHELPER +#define _CSEQUENCEHELPER + +#include "Kyoto/Animation/CAnimSysContext.hpp" +#include "Kyoto/Animation/CAnimTreeNode.hpp" +#include "Kyoto/Animation/IAnimReader.hpp" + +#include "rstl/rc_ptr.hpp" +#include "rstl/vector.hpp" + +class CBoolPOINode; +class CInt32POINode; +class CParticlePOINode; +class CSoundPOINode; +class IMetaAnim; + +class CSequenceFundamentals { +public: + CSequenceFundamentals(const CSteadyStateAnimInfo& ssInfo, + const rstl::vector< CBoolPOINode >& boolNodes, + const rstl::vector< CInt32POINode >& int32Nodes, + const rstl::vector< CParticlePOINode >& particleNodes, + const rstl::vector< CSoundPOINode >& soundNodes); + CSequenceFundamentals(const CSequenceFundamentals& other); + ~CSequenceFundamentals(); + + CSequenceFundamentals& operator=(const CSequenceFundamentals& other); + + const CSteadyStateAnimInfo& GetSteadyStateAnimInfo() const { return x0_ssInfo; } + const rstl::vector< CBoolPOINode >& GetBoolPointsOfInterest() const { return x18_boolNodes; } + const rstl::vector< CInt32POINode >& GetInt32PointsOfInterest() const { return x28_int32Nodes; } + const rstl::vector< CParticlePOINode >& GetParticlePointsOfInterest() const { + return x38_particleNodes; + } + const rstl::vector< CSoundPOINode >& GetSoundPointsOfInterest() const { return x48_soundNodes; } + +private: + CSteadyStateAnimInfo x0_ssInfo; + rstl::vector< CBoolPOINode > x18_boolNodes; + rstl::vector< CInt32POINode > x28_int32Nodes; + rstl::vector< CParticlePOINode > x38_particleNodes; + rstl::vector< CSoundPOINode > x48_soundNodes; +}; +CHECK_SIZEOF(CSequenceFundamentals, 0x58) + +class CSequenceHelper { +public: + CSequenceHelper(const rstl::vector< rstl::rc_ptr< IMetaAnim > >& anims, + const CAnimSysContext& animSys); + CSequenceHelper(const rstl::ncrc_ptr< CAnimTreeNode >& a, + const rstl::ncrc_ptr< CAnimTreeNode >& b, const CAnimSysContext& animSys); + ~CSequenceHelper(); + + CSequenceFundamentals ComputeSequenceFundamentals() const; + +private: + CAnimSysContext x0_animCtx; + rstl::vector< rstl::ncrc_ptr< CAnimTreeNode > > x10_treeNodes; + rstl::vector< bool > x20_; +}; + +#endif // _CSEQUENCEHELPER diff --git a/include/Kyoto/Animation/IAnimReader.hpp b/include/Kyoto/Animation/IAnimReader.hpp index a0602056..03a50de5 100644 --- a/include/Kyoto/Animation/IAnimReader.hpp +++ b/include/Kyoto/Animation/IAnimReader.hpp @@ -17,6 +17,8 @@ struct SAdvancementDeltas { CQuaternion xc_rotDelta; SAdvancementDeltas() : x0_posDelta(CVector3f::Zero()), xc_rotDelta(CQuaternion::NoRotation()) {} + SAdvancementDeltas(const CVector3f& pos, const CQuaternion& rot) + : x0_posDelta(pos), xc_rotDelta(rot) {} static SAdvancementDeltas Interpolate(const SAdvancementDeltas& a, const SAdvancementDeltas& b, float oldWeight, float newWeight); static SAdvancementDeltas Blend(const SAdvancementDeltas& a, const SAdvancementDeltas& b, @@ -28,6 +30,8 @@ struct SAdvancementResults { SAdvancementDeltas x8_deltas; SAdvancementResults() {} SAdvancementResults(const CCharAnimTime& time) : x0_remTime(time) {} + SAdvancementResults(const CCharAnimTime& time, const SAdvancementDeltas& deltas) + : x0_remTime(time), x8_deltas(deltas) {} }; class CSteadyStateAnimInfo { @@ -39,7 +43,7 @@ class CSteadyStateAnimInfo { CSteadyStateAnimInfo(bool looping, const CCharAnimTime& duration, const CVector3f& offset) : x0_duration(duration), x8_offset(offset), x14_looping(looping) {} - const CCharAnimTime& GetDuration() const { return x0_duration; } + CCharAnimTime GetDuration() const { return x0_duration; } const CVector3f& GetOffset() const { return x8_offset; } bool IsLooping() const { return x14_looping; } }; @@ -99,7 +103,8 @@ class IAnimReader { virtual void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const = 0; virtual void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const = 0; - virtual rstl::auto_ptr< IAnimReader > VClone() const = 0; + virtual rstl::ownership_transfer< IAnimReader > VClone() const = 0; + rstl::ownership_transfer< IAnimReader > Clone() const { return VClone(); } virtual rstl::optional_object< rstl::ownership_transfer< IAnimReader > > VSimplified(); rstl::optional_object< rstl::ownership_transfer< IAnimReader > > Simplified(); virtual void VSetPhase(float) = 0; diff --git a/include/Kyoto/Animation/IMetaAnim.hpp b/include/Kyoto/Animation/IMetaAnim.hpp index 4636264f..c2f8699a 100644 --- a/include/Kyoto/Animation/IMetaAnim.hpp +++ b/include/Kyoto/Animation/IMetaAnim.hpp @@ -53,11 +53,11 @@ class IMetaAnim { public: virtual ~IMetaAnim() {} - virtual rstl::rc_ptr< CAnimTreeNode > + virtual rstl::ncrc_ptr< CAnimTreeNode > GetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const; virtual void GetUniquePrimitives(rstl::set< CPrimitive >& primsOut) const = 0; virtual EMetaAnimType GetType() const = 0; - virtual rstl::rc_ptr< CAnimTreeNode > + virtual rstl::ncrc_ptr< CAnimTreeNode > VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const = 0; diff --git a/include/Kyoto/Math/CQuaternion.hpp b/include/Kyoto/Math/CQuaternion.hpp index 735e4717..ef8856af 100644 --- a/include/Kyoto/Math/CQuaternion.hpp +++ b/include/Kyoto/Math/CQuaternion.hpp @@ -29,6 +29,10 @@ class CQuaternion { // } CQuaternion operator*(const CQuaternion&) const; + CQuaternion& operator*=(const CQuaternion& other) { + *this = *this * other; + return *this; + } // __amu__11CQuaternionFRC11CQuaternion // ScalarVector__11CQuaternionFfRC9CVector3f // Slerp__11CQuaternionFRC11CQuaternionRC11CQuaternionf diff --git a/include/Kyoto/SObjectTag.hpp b/include/Kyoto/SObjectTag.hpp index 4d7caef1..31dd51b3 100644 --- a/include/Kyoto/SObjectTag.hpp +++ b/include/Kyoto/SObjectTag.hpp @@ -16,6 +16,12 @@ class SObjectTag { SObjectTag(const SObjectTag& other) : mType(other.mType), mId(other.mId) {} SObjectTag(CInputStream& in) : mType(in.Get< FourCC >()), mId(in.Get< CAssetId >()) {} + SObjectTag& operator=(const SObjectTag& other) { + mType = other.mType; + mId = other.mId; + return *this; + } + const CAssetId GetId() const { return mId; } const FourCC GetType() const { return mType; } static const char* Type2Text(FourCC type); diff --git a/src/Kyoto/Animation/CAnimTreeDoubleChild.cpp b/src/Kyoto/Animation/CAnimTreeDoubleChild.cpp index 19209500..58c7aa88 100644 --- a/src/Kyoto/Animation/CAnimTreeDoubleChild.cpp +++ b/src/Kyoto/Animation/CAnimTreeDoubleChild.cpp @@ -98,7 +98,7 @@ void CAnimTreeDoubleChild::VSetPhase(float phase) { SAdvancementResults CAnimTreeDoubleChild::VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const {} -rstl::rc_ptr< IAnimReader > CAnimTreeDoubleChild::VGetBestUnblendedChild() const {} +rstl::rc_ptr< CAnimTreeNode > CAnimTreeDoubleChild::VGetBestUnblendedChild() const {} void CAnimTreeDoubleChild::VGetWeightedReaders( float w, rstl::reserved_vector< rstl::pair< float, IAnimReader* >, 16 >& out) const { diff --git a/src/Kyoto/Animation/CAnimTreeNode.cpp b/src/Kyoto/Animation/CAnimTreeNode.cpp index 92c2f9ab..009beecd 100644 --- a/src/Kyoto/Animation/CAnimTreeNode.cpp +++ b/src/Kyoto/Animation/CAnimTreeNode.cpp @@ -4,12 +4,10 @@ CAnimTreeNode::CAnimTreeNode(const rstl::string& name) : x4_name(name) {} -/* -rstl::rc_ptr< CAnimTreeNode > Cast(const rstl::ownership_transfer< IAnimReader >& ptr) { +rstl::ncrc_ptr< CAnimTreeNode > Cast(const rstl::ownership_transfer< IAnimReader >& ptr) { if (ptr->IsCAnimTreeNode()) { return static_cast< CAnimTreeNode* >(ptr.get()); } - return rstl::rc_ptr< CAnimTreeNode >(); + return rstl::ncrc_ptr< CAnimTreeNode >(); } -*/ diff --git a/src/Kyoto/Animation/CAnimTreeSequence.cpp b/src/Kyoto/Animation/CAnimTreeSequence.cpp new file mode 100644 index 00000000..5e126cfb --- /dev/null +++ b/src/Kyoto/Animation/CAnimTreeSequence.cpp @@ -0,0 +1,149 @@ +#include "Kyoto/Animation/CAnimTreeSequence.hpp" + +#include "Kyoto/Animation/CBoolPOINode.hpp" +#include "Kyoto/Animation/CInt32POINode.hpp" +#include "Kyoto/Animation/CParticlePOINode.hpp" +#include "Kyoto/Animation/CSoundPOINode.hpp" +#include "Kyoto/Animation/CTreeUtils.hpp" +#include "Kyoto/Animation/IMetaAnim.hpp" + +rstl::ncrc_ptr< CAnimTreeNode > Cast(const rstl::ownership_transfer< IAnimReader >& ptr); + +CAnimTreeSequence::CAnimTreeSequence(const rstl::vector< rstl::rc_ptr< IMetaAnim > >& seq, + const CAnimSysContext& animSys, const rstl::string& name) +: CAnimTreeSingleChild( + seq[0]->GetAnimationTree(animSys, CMetaAnimTreeBuildOrders::NoSpecialOrders()), name) +, x18_animCtx(animSys) +, x28_sequence(seq) +, x38_curIdx(0) +, x3c_fundamentals(CSequenceHelper(seq, animSys).ComputeSequenceFundamentals()) +, x94_curTime(0.f) {} + +CAnimTreeSequence::CAnimTreeSequence(const rstl::ncrc_ptr< CAnimTreeNode >& curNode, + const rstl::vector< rstl::rc_ptr< IMetaAnim > >& metaAnims, + const CAnimSysContext& animSys, int curIdx, + const rstl::string& name, + const CSequenceFundamentals& fundamentals, + const CCharAnimTime& time) +: CAnimTreeSingleChild(curNode, name) +, x18_animCtx(animSys) +, x28_sequence(metaAnims) +, x38_curIdx(curIdx) +, x3c_fundamentals(fundamentals) +, x94_curTime(time) { + x14_child->VGetTimeRemaining(); +} + +SAdvancementResults CAnimTreeSequence::VAdvanceView(const CCharAnimTime& dt) { + CCharAnimTime totalDelta(0.f); + CVector3f posDelta(0.f, 0.f, 0.f); + CQuaternion rotDelta = CQuaternion::NoRotation(); + + rstl::ncrc_ptr< CAnimTreeNode > curChild(x14_child); + int seqSize = x28_sequence.size(); + + if (x38_curIdx >= seqSize && curChild->VGetTimeRemaining().EqualsZero()) { + x3c_fundamentals = CSequenceHelper(x28_sequence, x18_animCtx).ComputeSequenceFundamentals(); + x38_curIdx = 0; + x94_curTime = CCharAnimTime::ZeroFlat(); + rstl::ncrc_ptr< CAnimTreeNode > newChild = CTreeUtils::GetTransitionTree( + curChild, + x28_sequence[x38_curIdx]->GetAnimationTree(x18_animCtx, + CMetaAnimTreeBuildOrders::NoSpecialOrders()), + x18_animCtx); + x14_child = newChild; + curChild = x14_child; + } + + CCharAnimTime remTime = dt; + while (remTime.GreaterThanZero() && x38_curIdx < seqSize) { + CCharAnimTime chRem = curChild->VGetTimeRemaining(); + if (chRem.EqualsZero()) { + ++x38_curIdx; + if (x38_curIdx < seqSize) { + rstl::ncrc_ptr< CAnimTreeNode > newChild = CTreeUtils::GetTransitionTree( + curChild, + x28_sequence[x38_curIdx]->GetAnimationTree( + x18_animCtx, CMetaAnimTreeBuildOrders::NoSpecialOrders()), + x18_animCtx); + x14_child = newChild; + } + } + curChild = x14_child; + if (x38_curIdx < seqSize) { + SAdvancementResults res = curChild->VAdvanceView(remTime); + rstl::optional_object< rstl::ownership_transfer< IAnimReader > > simp = + curChild->Simplified(); + if (simp) { + curChild = Cast(*simp); + x14_child = curChild; + curChild = x14_child; + } + CCharAnimTime prevRemTime = remTime; + remTime = res.x0_remTime; + totalDelta += prevRemTime - remTime; + const SAdvancementDeltas& deltas = res.x8_deltas; + posDelta += deltas.x0_posDelta; + rotDelta = rotDelta * deltas.xc_rotDelta; + } + } + + x94_curTime += totalDelta; + return SAdvancementResults(dt - totalDelta, SAdvancementDeltas(posDelta, rotDelta)); +} + +CCharAnimTime CAnimTreeSequence::VGetTimeRemaining() const { + if (x38_curIdx == x28_sequence.size() - 1) + return x14_child->VGetTimeRemaining(); + CCharAnimTime dur = x3c_fundamentals.GetSteadyStateAnimInfo().GetDuration(); + return dur - x94_curTime; +} + +CSteadyStateAnimInfo CAnimTreeSequence::VGetSteadyStateAnimInfo() const { + return x3c_fundamentals.GetSteadyStateAnimInfo(); +} + +uint CAnimTreeSequence::VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut, + uint capacity, uint iterator, int additive) const { + return _getPOIList(time, listOut, capacity, iterator, additive, + x3c_fundamentals.GetBoolPointsOfInterest(), x94_curTime); +} + +uint CAnimTreeSequence::VGetInt32POIList(const CCharAnimTime& time, CInt32POINode* listOut, + uint capacity, uint iterator, int additive) const { + return _getPOIList(time, listOut, capacity, iterator, additive, + x3c_fundamentals.GetInt32PointsOfInterest(), x94_curTime); +} + +uint CAnimTreeSequence::VGetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut, + uint capacity, uint iterator, int additive) const { + return _getPOIList(time, listOut, capacity, iterator, additive, + x3c_fundamentals.GetParticlePointsOfInterest(), x94_curTime); +} + +uint CAnimTreeSequence::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, + uint capacity, uint iterator, int additive) const { + return _getPOIList(time, listOut, capacity, iterator, additive, + x3c_fundamentals.GetSoundPointsOfInterest(), x94_curTime); +} + +rstl::ownership_transfer< IAnimReader > CAnimTreeSequence::VClone() const { + return rs_new CAnimTreeSequence(Cast(x14_child->Clone()), x28_sequence, x18_animCtx, + x38_curIdx, x4_name, x3c_fundamentals, x94_curTime); +} + +rstl::rc_ptr< CAnimTreeNode > CAnimTreeSequence::VGetBestUnblendedChild() const { + rstl::rc_ptr< CAnimTreeNode > ch = x14_child->GetBestUnblendedChild(); + if (ch) + return rs_new CAnimTreeSequence(Cast(ch->Clone()), x28_sequence, x18_animCtx, x38_curIdx, + x4_name, x3c_fundamentals, x94_curTime); + return ch; +} + +bool CAnimTreeSequence::VSupportsReverseView() const { return false; } + +CAnimTreeEffectiveContribution CAnimTreeSequence::VGetContributionOfHighestInfluence() const { + return x14_child->GetContributionOfHighestInfluence(); +} + +rstl::string CAnimTreeSequence::VGetNodeType() const { return rstl::string_l(""); } diff --git a/src/Kyoto/Animation/CMetaAnimBlend.cpp b/src/Kyoto/Animation/CMetaAnimBlend.cpp index 498e9b9c..7a429d00 100644 --- a/src/Kyoto/Animation/CMetaAnimBlend.cpp +++ b/src/Kyoto/Animation/CMetaAnimBlend.cpp @@ -9,7 +9,7 @@ CMetaAnimBlend::CMetaAnimBlend(CInputStream& in) , xc_blend(in.ReadFloat()) , x10_(in.ReadBool()) {} -rstl::rc_ptr< CAnimTreeNode > +rstl::ncrc_ptr< CAnimTreeNode > CMetaAnimBlend::VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const {} diff --git a/src/Kyoto/Animation/CMetaAnimPhaseBlend.cpp b/src/Kyoto/Animation/CMetaAnimPhaseBlend.cpp index f7bd6bc5..bcdb3b5b 100644 --- a/src/Kyoto/Animation/CMetaAnimPhaseBlend.cpp +++ b/src/Kyoto/Animation/CMetaAnimPhaseBlend.cpp @@ -9,7 +9,7 @@ CMetaAnimPhaseBlend::CMetaAnimPhaseBlend(CInputStream& in) , xc_blend(in.ReadFloat()) , x10_(in.ReadBool()) {} -rstl::rc_ptr< CAnimTreeNode > +rstl::ncrc_ptr< CAnimTreeNode > CMetaAnimPhaseBlend::VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const {} diff --git a/src/Kyoto/Animation/CMetaAnimPlay.cpp b/src/Kyoto/Animation/CMetaAnimPlay.cpp index b339acc7..7236ae6b 100644 --- a/src/Kyoto/Animation/CMetaAnimPlay.cpp +++ b/src/Kyoto/Animation/CMetaAnimPlay.cpp @@ -1,7 +1,7 @@ #include "Kyoto/Animation/CMetaAnimPlay.hpp" #include "Kyoto/Streams/COutputStream.hpp" -rstl::rc_ptr< CAnimTreeNode > +rstl::ncrc_ptr< CAnimTreeNode > CMetaAnimPlay::VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const {} diff --git a/src/Kyoto/Animation/CMetaAnimRandom.cpp b/src/Kyoto/Animation/CMetaAnimRandom.cpp index fa08fe62..f12dcf56 100644 --- a/src/Kyoto/Animation/CMetaAnimRandom.cpp +++ b/src/Kyoto/Animation/CMetaAnimRandom.cpp @@ -8,7 +8,7 @@ CMetaAnimRandom::CMetaAnimRandom(CInputStream& in) : x4_randomData(CreateRandomData(in)) {} -rstl::rc_ptr< CAnimTreeNode > +rstl::ncrc_ptr< CAnimTreeNode > CMetaAnimRandom::VGetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const { const int r = const_cast< CAnimSysContext& >(animSys).Random()->Range(1, 100); diff --git a/src/Kyoto/Animation/CMetaAnimSequence.cpp b/src/Kyoto/Animation/CMetaAnimSequence.cpp index e00c3204..5ed03efd 100644 --- a/src/Kyoto/Animation/CMetaAnimSequence.cpp +++ b/src/Kyoto/Animation/CMetaAnimSequence.cpp @@ -6,7 +6,7 @@ CMetaAnimSequence::CMetaAnimSequence(CInputStream& in) : x4_sequence(CMetaAnimSequence::CreateSequence(in)) {} -rstl::rc_ptr< CAnimTreeNode > +rstl::ncrc_ptr< CAnimTreeNode > CMetaAnimSequence::VGetAnimationTree(const CAnimSysContext&, const CMetaAnimTreeBuildOrders&) const {} diff --git a/src/MetroidPrime/CAnimData.cpp b/src/MetroidPrime/CAnimData.cpp index 3e0bbf27..a88c06f2 100644 --- a/src/MetroidPrime/CAnimData.cpp +++ b/src/MetroidPrime/CAnimData.cpp @@ -47,7 +47,7 @@ static rstl::reserved_vector< CInt32POINode, 16 > sInt32TransientCache; static int skPOICacheReferenceCount; static CInt32POINode* sInt32TransientCacheData; -rstl::rc_ptr< CAnimTreeNode > Cast(const rstl::ownership_transfer< IAnimReader >& ptr); +rstl::ncrc_ptr< CAnimTreeNode > Cast(const rstl::ownership_transfer< IAnimReader >& ptr); extern const int lbl_805AE3D8; extern const int lbl_805AE3DC; @@ -65,7 +65,7 @@ class CAnimTreeBlend : public CAnimTreeTweenBase { SAdvancementResults VAdvanceView(const CCharAnimTime& dt); CCharAnimTime VGetTimeRemaining() const; CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const; - rstl::auto_ptr< IAnimReader > VClone() const; + rstl::ownership_transfer< IAnimReader > VClone() const; void SetBlendingWeight(float w); float VGetBlendingWeight() const;