#pragma once #include #include #include #include "Runtime/CToken.hpp" #include "Runtime/RetroTypes.hpp" #include "Runtime/rstl.hpp" #include "Runtime/Character/CAdditiveAnimPlayback.hpp" #include "Runtime/Character/CAnimPlaybackParms.hpp" #include "Runtime/Character/CCharLayoutInfo.hpp" #include "Runtime/Character/CCharacterFactory.hpp" #include "Runtime/Character/CCharacterInfo.hpp" #include "Runtime/Character/CHierarchyPoseBuilder.hpp" #include "Runtime/Character/CParticleDatabase.hpp" #include "Runtime/Character/CPoseAsTransforms.hpp" #include "Runtime/Character/IAnimReader.hpp" #include "Runtime/Graphics/CSkinnedModel.hpp" #include #include #include enum class EUserEventType { Projectile = 0, EggLay = 1, LoopedSoundStop = 2, AlignTargetPos = 3, AlignTargetRot = 4, ChangeMaterial = 5, Delete = 6, GenerateEnd = 7, DamageOn = 8, DamageOff = 9, AlignTargetPosStart = 10, DeGenerate = 11, Landing = 12, TakeOff = 13, FadeIn = 14, FadeOut = 15, ScreenShake = 16, BeginAction = 17, EndAction = 18, BecomeRagDoll = 19, IkLock = 20, IkRelease = 21, BreakLockOn = 22, BecomeShootThrough = 23, RemoveCollision = 24, ObjectPickUp = 25, ObjectDrop = 26, EventStart = 27, EventStop = 28, Activate = 29, Deactivate = 30, SoundPlay = 31, SoundStop = 32, EffectOn = 33, EffectOff = 34 }; namespace urde { class CAnimTreeNode; class CAnimationManager; class CBoolPOINode; class CCharAnimTime; class CCharLayoutInfo; class CInt32POINode; class CModel; class CMorphableSkinnedModel; class CParticlePOINode; class CPrimitive; class CRandom16; class CSegIdList; class CSegStatementSet; class CSkinRules; class CSoundPOINode; class CStateManager; class CTransitionManager; class CVertexMorphEffect; class IAnimReader; class IMetaAnim; struct CAnimSysContext; struct CModelFlags; struct SAdvancementDeltas; struct SAdvancementResults; class CAnimData { friend class CModelData; friend class CActor; friend class CPlayerGun; friend class CGrappleArm; friend class CWallCrawlerSwarm; public: enum class EAnimDir { Forward, Backward }; private: TLockedToken x0_charFactory; CCharacterInfo xc_charInfo; TLockedToken xcc_layoutData; TLockedToken xd8_modelData; TLockedToken xe4_iceModelData; std::shared_ptr xf4_xrayModel; std::shared_ptr xf8_infraModel; std::shared_ptr xfc_animCtx; std::shared_ptr x100_animMgr; EAnimDir x104_animDir = EAnimDir::Forward; zeus::CAABox x108_aabb; CParticleDatabase x120_particleDB; CAssetId x1d8_selfId; zeus::CVector3f x1dc_alignPos; zeus::CQuaternion x1e8_alignRot; std::shared_ptr x1f8_animRoot; std::shared_ptr x1fc_transMgr; float x200_speedScale = 1.f; s32 x204_charIdx; s32 x208_defaultAnim; u32 x20c_passedBoolCount = 0; u32 x210_passedIntCount = 0; u32 x214_passedParticleCount = 0; u32 x218_passedSoundCount = 0; s32 x21c_particleLightIdx = 0; union { u32 x220_flags = 0; struct { bool x220_24_animating : 1; bool x220_25_loop : 1; bool x220_26_aligningPos : 1; bool x220_27_ : 1; bool x220_28_ : 1; bool x220_29_animationJustStarted : 1; bool x220_30_poseBuilt : 1; bool x220_31_poseCached : 1; }; }; CPoseAsTransforms x224_pose; CHierarchyPoseBuilder x2fc_poseBuilder; CAnimPlaybackParms x40c_playbackParms; rstl::reserved_vector, 8> x434_additiveAnims; static rstl::reserved_vector g_BoolPOINodes; static rstl::reserved_vector g_Int32POINodes; static rstl::reserved_vector g_ParticlePOINodes; static rstl::reserved_vector g_SoundPOINodes; static rstl::reserved_vector g_TransientInt32POINodes; int m_drawInstCount; public: CAnimData(CAssetId, const CCharacterInfo& character, int defaultAnim, int charIdx, bool loop, TLockedToken layout, TToken model, const std::optional>& iceModel, const std::weak_ptr& ctx, std::shared_ptr animMgr, std::shared_ptr transMgr, TLockedToken charFactory, int drawInstCount); void SetParticleEffectState(std::string_view effectName, bool active, CStateManager& mgr); void InitializeEffects(CStateManager& mgr, TAreaId aId, const zeus::CVector3f& scale); CAssetId GetEventResourceIdForAnimResourceId(CAssetId id) const; void AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stSet); static SAdvancementResults AdvanceAdditiveAnim(std::shared_ptr& anim, const CCharAnimTime& time); SAdvancementDeltas AdvanceAdditiveAnims(float dt); SAdvancementDeltas UpdateAdditiveAnims(float dt); bool IsAdditiveAnimation(s32 idx) const; bool IsAdditiveAnimationAdded(s32 idx) const; const std::shared_ptr& GetRootAnimationTree() const { return x1f8_animRoot; } const std::shared_ptr& GetAdditiveAnimationTree(s32 idx) const; bool IsAdditiveAnimationActive(s32 idx) const; void DelAdditiveAnimation(s32 idx); void AddAdditiveAnimation(s32 idx, float weight, bool active, bool fadeOut); float GetAdditiveAnimationWeight(s32 idx) const; std::shared_ptr GetAnimationManager(); const CCharacterInfo& GetCharacterInfo() const { return xc_charInfo; } const CCharLayoutInfo& GetCharLayoutInfo() const { return *xcc_layoutData.GetObj(); } void SetPhase(float ph); void Touch(const CSkinnedModel& model, int shaderIdx) const; SAdvancementDeltas GetAdvancementDeltas(const CCharAnimTime& a, const CCharAnimTime& b) const; CCharAnimTime GetTimeOfUserEvent(EUserEventType type, const CCharAnimTime& time) const; void MultiplyPlaybackRate(float mul); void SetPlaybackRate(float set); void SetRandomPlaybackRate(CRandom16& r); void CalcPlaybackAlignmentParms(const CAnimPlaybackParms& parms, const std::shared_ptr& node); zeus::CTransform GetLocatorTransform(CSegId id, const CCharAnimTime* time) const; zeus::CTransform GetLocatorTransform(std::string_view name, const CCharAnimTime* time) const; bool IsAnimTimeRemaining(float rem, std::string_view name) const; float GetAnimTimeRemaining(std::string_view name) const; float GetAnimationDuration(int animIn) const; bool GetIsLoop() const { return x220_25_loop; } void EnableLooping(bool val) { x220_25_loop = val; x220_24_animating = true; } void EnableAnimation(bool val) { x220_24_animating = val; } bool IsAnimating() const { return x220_24_animating; } void SetAnimDir(EAnimDir dir) { x104_animDir = dir; } std::shared_ptr GetAnimSysContext() const; std::shared_ptr GetAnimationManager() const; void RecalcPoseBuilder(const CCharAnimTime* time); void RenderAuxiliary(const zeus::CFrustum& frustum) const; void Render(CSkinnedModel& model, const CModelFlags& drawFlags, const std::optional& morphEffect, const float* morphMagnitudes); void SetupRender(CSkinnedModel& model, const CModelFlags& drawFlags, const std::optional& morphEffect, const float* morphMagnitudes); static void DrawSkinnedModel(CSkinnedModel& model, const CModelFlags& flags); void PreRender(); void BuildPose(); const CPoseAsTransforms& GetPose() const { return x224_pose; } static void PrimitiveSetToTokenVector(const std::set& primSet, std::vector& tokensOut, bool preLock); void GetAnimationPrimitives(const CAnimPlaybackParms& parms, std::set& primsOut) const; void SetAnimation(const CAnimPlaybackParms& parms, bool noTrans); SAdvancementDeltas DoAdvance(float dt, bool& suspendParticles, CRandom16& random, bool advTree); SAdvancementDeltas Advance(float dt, const zeus::CVector3f& scale, CStateManager& stateMgr, TAreaId aid, bool advTree); SAdvancementDeltas AdvanceIgnoreParticles(float dt, CRandom16& random, bool advTree); void AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus::CQuaternion& quat); void SetXRayModel(const TLockedToken& model, const TLockedToken& skinRules); std::shared_ptr GetXRayModel() const { return xf4_xrayModel; } void SetInfraModel(const TLockedToken& model, const TLockedToken& skinRules); std::shared_ptr GetInfraModel() const { return xf8_infraModel; } TLockedToken& GetModelData() { return xd8_modelData; } const TLockedToken& GetModelData() const { return xd8_modelData; } static void PoseSkinnedModel(CSkinnedModel& model, const CPoseAsTransforms& pose, const CModelFlags& drawFlags, const std::optional& morphEffect, const float* morphMagnitudes); void AdvanceParticles(const zeus::CTransform& xf, float dt, const zeus::CVector3f&, CStateManager& stateMgr); float GetAverageVelocity(int animIn) const; void ResetPOILists(); CSegId GetLocatorSegId(std::string_view name) const; zeus::CAABox GetBoundingBox(const zeus::CTransform& xf) const; zeus::CAABox GetBoundingBox() const; void SubstituteModelData(const TCachedToken& model); static void FreeCache(); static void InitializeCache(); CHierarchyPoseBuilder& PoseBuilder() { return x2fc_poseBuilder; } const CHierarchyPoseBuilder& GetPoseBuilder() const { return x2fc_poseBuilder; } const CParticleDatabase& GetParticleDB() const { return x120_particleDB; } CParticleDatabase& GetParticleDB() { return x120_particleDB; } void SetParticleCEXTValue(std::string_view name, int idx, float value); float GetSpeedScale() const { return x200_speedScale; } u32 GetPassedBoolPOICount() const { return x20c_passedBoolCount; } u32 GetPassedIntPOICount() const { return x210_passedIntCount; } u32 GetPassedParticlePOICount() const { return x214_passedParticleCount; } u32 GetPassedSoundPOICount() const { return x218_passedSoundCount; } s32 GetCharacterIndex() const { return x204_charIdx; } u16 GetDefaultAnimation() const { return x208_defaultAnim; } TLockedToken& GetIceModel() { return xe4_iceModelData; } const TLockedToken& GetIceModel() const { return xe4_iceModelData; } void SetParticleLightIdx(s32 idx) { x21c_particleLightIdx = idx; } void MarkPoseDirty() { x220_30_poseBuilt = false; } }; } // namespace urde