//========= Copyright Valve Corporation, All rights reserved. ============// // //---------------------------------------------------------------------------------------- #ifndef REPLAY_RAGDOLL_H #define REPLAY_RAGDOLL_H #ifdef _WIN32 #pragma once #endif //-------------------------------------------------------------------------------- class C_BaseAnimating; //-------------------------------------------------------------------------------- struct RagdollSimulationFrame_t { RagdollSimulationFrame_t() : pPositions(NULL), pAngles(NULL), nTick(-1) {} static RagdollSimulationFrame_t* Alloc( int nNumBones ); int nTick; Vector* pPositions; QAngle* pAngles; Vector vRootPosition; QAngle angRootAngles; }; //-------------------------------------------------------------------------------- struct RagdollSimulationData_t { RagdollSimulationData_t( C_BaseAnimating* pEntity = NULL, int nStartTick = 0, int nNumBones = 0 ); void Record(); int m_nEntityIndex; int m_nStartTick; int m_nDuration; int m_nNumBones; typedef unsigned short Iterator_t; CUtlLinkedList< RagdollSimulationFrame_t*, Iterator_t > m_lstFrames; C_BaseAnimating* m_pEntity; }; //-------------------------------------------------------------------------------- // TODO: Refactor this into an interface and hide implementation in cpp file class CReplayRagdollRecorder { private: CReplayRagdollRecorder(); ~CReplayRagdollRecorder(); public: static CReplayRagdollRecorder& Instance(); void Init(); void Shutdown(); void Think(); void AddEntry( C_BaseAnimating* pEntity, int nStartTick, int nNumBones ); void StopRecordingRagdoll( C_BaseAnimating* pEntity ); void CleanupStartupTicksAndDurations( int nStartTick ); bool DumpRagdollsToDisk( char const* pszFilename ) const; bool IsRecording() const { return m_bIsRecording; } private: typedef unsigned short Iterator_t; void StopRecordingRagdollAtIndex( Iterator_t nIndex ); void StopRecordingSleepingRagdolls(); void Record(); bool FindEntryInRecordingList( C_BaseAnimating* pEntity, Iterator_t& nOutIndex ); void PrintDebug(); CUtlLinkedList< RagdollSimulationData_t*, Iterator_t > m_lstRagdolls; CUtlLinkedList< RagdollSimulationData_t*, Iterator_t > m_lstRagdollsToRecord; // Contains some of the elements from m_lstRagdolls - // the ones which are still recording bool m_bIsRecording; }; //-------------------------------------------------------------------------------- class CReplayRagdollCache { private: CReplayRagdollCache(); public: static CReplayRagdollCache& Instance(); bool Init( char const* pszFilename ); void Shutdown(); void Think(); bool IsInitialized() const { return m_bInit; } // // Returns false is no frame exists for the given entity at the given tick. // Otherwise, returns a // bool GetFrame( C_BaseAnimating* pEntity, int nTick, bool* pBoneSimulated, CBoneAccessor* pBoneAccessor ) const; private: RagdollSimulationData_t* FindRagdollEntry( C_BaseAnimating* pEntity, int nTick ); const RagdollSimulationData_t* FindRagdollEntry( C_BaseAnimating* pEntity, int nTick ) const; bool FindFrame( RagdollSimulationFrame_t*& pFrameOut, RagdollSimulationFrame_t*& pNextFrameOut, const RagdollSimulationData_t* pRagdollEntry, int nTick ); bool FindFrame( RagdollSimulationFrame_t*& pFrameOut, RagdollSimulationFrame_t*& pNextFrameOut, const RagdollSimulationData_t* pRagdollEntry, int nTick ) const; typedef unsigned short Iterator_t; bool m_bInit; CUtlLinkedList< RagdollSimulationData_t*, Iterator_t > m_lstRagdolls; }; //-------------------------------------------------------------------------------- bool Replay_CacheRagdolls( const char* pFilename, int nStartTick ); //-------------------------------------------------------------------------------- inline const RagdollSimulationData_t* CReplayRagdollCache::FindRagdollEntry( C_BaseAnimating* pEntity, int nTick ) const { return const_cast< CReplayRagdollCache* >( this )->FindRagdollEntry( pEntity, nTick ); } inline bool CReplayRagdollCache::FindFrame( RagdollSimulationFrame_t*& pFrameOut, RagdollSimulationFrame_t*& pNextFrameOut, const RagdollSimulationData_t* pRagdollEntry, int nTick ) const { return const_cast< CReplayRagdollCache* >( this )->FindFrame( pFrameOut, pNextFrameOut, pRagdollEntry, nTick ); } //-------------------------------------------------------------------------------- #endif // REPLAY_RAGDOLL_H