Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

536 lines
20 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef BASEANIMATING_H
  7. #define BASEANIMATING_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "baseentity.h"
  12. #include "entityoutput.h"
  13. #include "studio.h"
  14. #include "datacache/idatacache.h"
  15. #include "tier0/threadtools.h"
  16. struct animevent_t;
  17. struct matrix3x4_t;
  18. class CIKContext;
  19. class KeyValues;
  20. FORWARD_DECLARE_HANDLE( memhandle_t );
  21. #define BCF_NO_ANIMATION_SKIP ( 1 << 0 ) // Do not allow PVS animation skipping (mostly for attachments being critical to an entity)
  22. #define BCF_IS_IN_SPAWN ( 1 << 1 ) // Is currently inside of spawn, always evaluate animations
  23. class CBaseAnimating : public CBaseEntity
  24. {
  25. public:
  26. DECLARE_CLASS( CBaseAnimating, CBaseEntity );
  27. CBaseAnimating();
  28. ~CBaseAnimating();
  29. DECLARE_PREDICTABLE();
  30. enum
  31. {
  32. NUM_POSEPAREMETERS = 24,
  33. NUM_BONECTRLS = 4
  34. };
  35. DECLARE_DATADESC();
  36. DECLARE_SERVERCLASS();
  37. virtual void SetModel( const char *szModelName );
  38. virtual void Activate();
  39. virtual void Spawn();
  40. virtual void Precache();
  41. virtual void SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways );
  42. virtual int Restore( IRestore &restore );
  43. virtual void OnRestore();
  44. CStudioHdr *GetModelPtr( void );
  45. void InvalidateMdlCache();
  46. virtual CStudioHdr *OnNewModel();
  47. virtual CBaseAnimating* GetBaseAnimating() { return this; }
  48. // Cycle access
  49. void SetCycle( float flCycle );
  50. float GetCycle() const;
  51. float GetAnimTimeInterval( void ) const;
  52. // Call this in your constructor to tell it that you will not use animtime. Then the
  53. // interpolation will be done correctly on the client.
  54. // This defaults to off.
  55. void UseClientSideAnimation();
  56. // Tells whether or not we're using client-side animation. Used for controlling
  57. // the transmission of animtime.
  58. bool IsUsingClientSideAnimation() { return m_bClientSideAnimation; }
  59. // Basic NPC Animation functions
  60. virtual float GetIdealSpeed( ) const;
  61. virtual float GetIdealAccel( ) const;
  62. virtual void StudioFrameAdvance(); // advance animation frame to some time in the future
  63. void StudioFrameAdvanceManual( float flInterval );
  64. bool IsValidSequence( int iSequence );
  65. inline float GetPlaybackRate();
  66. inline void SetPlaybackRate( float rate );
  67. inline int GetSequence() { return m_nSequence; }
  68. virtual void SetSequence(int nSequence);
  69. /* inline */ void ResetSequence(int nSequence);
  70. // FIXME: push transitions support down into CBaseAnimating?
  71. virtual bool IsActivityFinished( void ) { return m_bSequenceFinished; }
  72. inline bool IsSequenceFinished( void ) { return m_bSequenceFinished; }
  73. inline bool SequenceLoops( void ) { return m_bSequenceLoops; }
  74. bool IsSequenceLooping( CStudioHdr *pStudioHdr, int iSequence );
  75. inline bool IsSequenceLooping( int iSequence ) { return IsSequenceLooping(GetModelPtr(),iSequence); }
  76. inline float SequenceDuration( void ) { return SequenceDuration( m_nSequence ); }
  77. float SequenceDuration( CStudioHdr *pStudioHdr, int iSequence );
  78. inline float SequenceDuration( int iSequence ) { return SequenceDuration(GetModelPtr(), iSequence); }
  79. float GetSequenceCycleRate( CStudioHdr *pStudioHdr, int iSequence );
  80. inline float GetSequenceCycleRate( int iSequence ) { return GetSequenceCycleRate(GetModelPtr(),iSequence); }
  81. float GetLastVisibleCycle( CStudioHdr *pStudioHdr, int iSequence );
  82. virtual float GetSequenceGroundSpeed( CStudioHdr *pStudioHdr, int iSequence );
  83. inline float GetSequenceGroundSpeed( int iSequence ) { return GetSequenceGroundSpeed(GetModelPtr(), iSequence); }
  84. void ResetActivityIndexes ( void );
  85. void ResetEventIndexes ( void );
  86. int SelectWeightedSequence ( Activity activity );
  87. int SelectWeightedSequence ( Activity activity, int curSequence );
  88. int SelectWeightedSequenceFromModifiers( Activity activity, CUtlSymbol *pActivityModifiers, int iModifierCount );
  89. int SelectHeaviestSequence ( Activity activity );
  90. int LookupActivity( const char *label );
  91. int LookupSequence ( const char *label );
  92. KeyValues *GetSequenceKeyValues( int iSequence );
  93. float GetSequenceMoveYaw( int iSequence );
  94. float GetSequenceMoveDist( CStudioHdr *pStudioHdr, int iSequence );
  95. inline float GetSequenceMoveDist( int iSequence ) { return GetSequenceMoveDist(GetModelPtr(),iSequence);}
  96. void GetSequenceLinearMotion( int iSequence, Vector *pVec );
  97. const char *GetSequenceName( int iSequence );
  98. const char *GetSequenceActivityName( int iSequence );
  99. Activity GetSequenceActivity( int iSequence );
  100. void ResetSequenceInfo ( );
  101. // This will stop animation until you call ResetSequenceInfo() at some point in the future
  102. inline void StopAnimation( void ) { m_flPlaybackRate = 0; }
  103. virtual void ClampRagdollForce( const Vector &vecForceIn, Vector *vecForceOut ) { *vecForceOut = vecForceIn; } // Base class does nothing.
  104. virtual bool BecomeRagdollOnClient( const Vector &force );
  105. virtual bool IsRagdoll();
  106. virtual bool CanBecomeRagdoll( void ); //Check if this entity will ragdoll when dead.
  107. virtual void GetSkeleton( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], int boneMask );
  108. virtual void GetBoneTransform( int iBone, matrix3x4_t &pBoneToWorld );
  109. virtual void SetupBones( matrix3x4_t *pBoneToWorld, int boneMask );
  110. virtual void CalculateIKLocks( float currentTime );
  111. virtual void Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity );
  112. bool HasAnimEvent( int nSequence, int nEvent );
  113. virtual void DispatchAnimEvents ( CBaseAnimating *eventHandler ); // Handle events that have happend since last time called up until X seconds into the future
  114. virtual void HandleAnimEvent( animevent_t *pEvent );
  115. int LookupPoseParameter( CStudioHdr *pStudioHdr, const char *szName );
  116. inline int LookupPoseParameter( const char *szName ) { return LookupPoseParameter(GetModelPtr(), szName); }
  117. float SetPoseParameter( CStudioHdr *pStudioHdr, const char *szName, float flValue );
  118. inline float SetPoseParameter( const char *szName, float flValue ) { return SetPoseParameter( GetModelPtr(), szName, flValue ); }
  119. float SetPoseParameter( CStudioHdr *pStudioHdr, int iParameter, float flValue );
  120. inline float SetPoseParameter( int iParameter, float flValue ) { return SetPoseParameter( GetModelPtr(), iParameter, flValue ); }
  121. float GetPoseParameter( const char *szName );
  122. float GetPoseParameter( int iParameter );
  123. bool GetPoseParameterRange( int index, float &minValue, float &maxValue );
  124. bool HasPoseParameter( int iSequence, const char *szName );
  125. bool HasPoseParameter( int iSequence, int iParameter );
  126. float EdgeLimitPoseParameter( int iParameter, float flValue, float flBase = 0.0f );
  127. protected:
  128. // The modus operandi for pose parameters is that you should not use the const char * version of the functions
  129. // in general code -- it causes many many string comparisons, which is slower than you think. Better is to
  130. // save off your pose parameters in member variables in your derivation of this function:
  131. virtual void PopulatePoseParameters( void );
  132. public:
  133. int LookupBone( const char *szName );
  134. void GetBonePosition( const char *szName, Vector &origin, QAngle &angles );
  135. void GetBonePosition( int iBone, Vector &origin, QAngle &angles );
  136. int GetPhysicsBone( int boneIndex );
  137. int GetNumBones ( void );
  138. int FindTransitionSequence( int iCurrentSequence, int iGoalSequence, int *piDir );
  139. bool GotoSequence( int iCurrentSequence, float flCurrentCycle, float flCurrentRate, int iGoalSequence, int &iNextSequence, float &flCycle, int &iDir );
  140. int GetEntryNode( int iSequence );
  141. int GetExitNode( int iSequence );
  142. void GetEyeballs( Vector &origin, QAngle &angles ); // ?? remove ??
  143. int LookupAttachment( const char *szName );
  144. // These return the attachment in world space
  145. bool GetAttachment( const char *szName, Vector &absOrigin, QAngle &absAngles );
  146. bool GetAttachment( int iAttachment, Vector &absOrigin, QAngle &absAngles );
  147. int GetAttachmentBone( int iAttachment );
  148. virtual bool GetAttachment( int iAttachment, matrix3x4_t &attachmentToWorld );
  149. // These return the attachment in the space of the entity
  150. bool GetAttachmentLocal( const char *szName, Vector &origin, QAngle &angles );
  151. bool GetAttachmentLocal( int iAttachment, Vector &origin, QAngle &angles );
  152. bool GetAttachmentLocal( int iAttachment, matrix3x4_t &attachmentToLocal );
  153. // Non-angle versions of the attachments in world space
  154. bool GetAttachment( const char *szName, Vector &absOrigin, Vector *forward = NULL, Vector *right = NULL, Vector *up = NULL );
  155. bool GetAttachment( int iAttachment, Vector &absOrigin, Vector *forward = NULL, Vector *right = NULL, Vector *up = NULL );
  156. void SetBodygroup( int iGroup, int iValue );
  157. int GetBodygroup( int iGroup );
  158. const char *GetBodygroupName( int iGroup );
  159. int FindBodygroupByName( const char *name );
  160. int GetBodygroupCount( int iGroup );
  161. int GetNumBodyGroups( void );
  162. void SetHitboxSet( int setnum );
  163. void SetHitboxSetByName( const char *setname );
  164. int GetHitboxSet( void );
  165. char const *GetHitboxSetName( void );
  166. int GetHitboxSetCount( void );
  167. int GetHitboxBone( int hitboxIndex );
  168. bool LookupHitbox( const char *szName, int& outSet, int& outBox );
  169. // Computes a box that surrounds all hitboxes
  170. bool ComputeHitboxSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs );
  171. bool ComputeEntitySpaceHitboxSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs );
  172. // Clone a CBaseAnimating from another (copies model & sequence data)
  173. void CopyAnimationDataFrom( CBaseAnimating *pSource );
  174. int ExtractBbox( int sequence, Vector& mins, Vector& maxs );
  175. void SetSequenceBox( void );
  176. int RegisterPrivateActivity( const char *pszActivityName );
  177. void ResetClientsideFrame( void );
  178. // Controllers.
  179. virtual void InitBoneControllers ( void );
  180. // Return's the controller's angle/position in bone space.
  181. float GetBoneController ( int iController );
  182. // Maps the angle/position value you specify into the bone's start/end and sets the specified controller to the value.
  183. float SetBoneController ( int iController, float flValue );
  184. void GetVelocity(Vector *vVelocity, AngularImpulse *vAngVelocity);
  185. // these two need to move somewhere else
  186. LocalFlexController_t GetNumFlexControllers( void );
  187. const char *GetFlexDescFacs( int iFlexDesc );
  188. const char *GetFlexControllerName( LocalFlexController_t iFlexController );
  189. const char *GetFlexControllerType( LocalFlexController_t iFlexController );
  190. virtual Vector GetGroundSpeedVelocity( void );
  191. bool GetIntervalMovement( float flIntervalUsed, bool &bMoveSeqFinished, Vector &newPosition, QAngle &newAngles );
  192. bool GetSequenceMovement( int nSequence, float fromCycle, float toCycle, Vector &deltaPosition, QAngle &deltaAngles );
  193. float GetInstantaneousVelocity( float flInterval = 0.0 );
  194. float GetEntryVelocity( int iSequence );
  195. float GetExitVelocity( int iSequence );
  196. float GetMovementFrame( float flDist );
  197. bool HasMovement( int iSequence );
  198. void ReportMissingActivity( int iActivity );
  199. virtual bool TestCollision( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr );
  200. virtual bool TestHitboxes( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr );
  201. class CBoneCache *GetBoneCache( void );
  202. void InvalidateBoneCache();
  203. void InvalidateBoneCacheIfOlderThan( float deltaTime );
  204. virtual int DrawDebugTextOverlays( void );
  205. // See note in code re: bandwidth usage!!!
  206. void DrawServerHitboxes( float duration = 0.0f, bool monocolor = false );
  207. void DrawRawSkeleton( matrix3x4_t boneToWorld[], int boneMask, bool noDepthTest = true, float duration = 0.0f, bool monocolor = false );
  208. void SetModelScale( float scale, float change_duration = 0.0f );
  209. float GetModelScale() const { return m_flModelScale; }
  210. void UpdateModelScale();
  211. virtual void RefreshCollisionBounds( void );
  212. // also calculate IK on server? (always done on client)
  213. void EnableServerIK();
  214. void DisableServerIK();
  215. // for ragdoll vs. car
  216. int GetHitboxesFrontside( int *boxList, int boxMax, const Vector &normal, float dist );
  217. void GetInputDispatchEffectPosition( const char *sInputString, Vector &pOrigin, QAngle &pAngles );
  218. virtual void ModifyOrAppendCriteria( AI_CriteriaSet& set );
  219. // Send a muzzle flash event to the client for this entity.
  220. void DoMuzzleFlash();
  221. // Fire
  222. virtual void Ignite( float flFlameLifetime, bool bNPCOnly = true, float flSize = 0.0f, bool bCalledByLevelDesigner = false );
  223. virtual void IgniteLifetime( float flFlameLifetime );
  224. virtual void IgniteNumHitboxFires( int iNumHitBoxFires );
  225. virtual void IgniteHitboxFireScale( float flHitboxFireScale );
  226. virtual void Extinguish() { RemoveFlag( FL_ONFIRE ); }
  227. bool IsOnFire() { return ( (GetFlags() & FL_ONFIRE) != 0 ); }
  228. void Scorch( int rate, int floor );
  229. void InputIgnite( inputdata_t &inputdata );
  230. void InputIgniteLifetime( inputdata_t &inputdata );
  231. void InputIgniteNumHitboxFires( inputdata_t &inputdata );
  232. void InputIgniteHitboxFireScale( inputdata_t &inputdata );
  233. void InputBecomeRagdoll( inputdata_t &inputdata );
  234. // Dissolve, returns true if the ragdoll has been created
  235. bool Dissolve( const char *pMaterialName, float flStartTime, bool bNPCOnly = true, int nDissolveType = 0, Vector vDissolverOrigin = vec3_origin, int iMagnitude = 0 );
  236. bool IsDissolving() { return ( (GetFlags() & FL_DISSOLVING) != 0 ); }
  237. void TransferDissolveFrom( CBaseAnimating *pAnim );
  238. // animation needs
  239. float m_flGroundSpeed; // computed linear movement rate for current sequence
  240. float m_flLastEventCheck; // cycle index of when events were last checked
  241. virtual void SetLightingOriginRelative( CBaseEntity *pLightingOriginRelative );
  242. void SetLightingOriginRelative( string_t strLightingOriginRelative );
  243. CBaseEntity *GetLightingOriginRelative();
  244. virtual void SetLightingOrigin( CBaseEntity *pLightingOrigin );
  245. void SetLightingOrigin( string_t strLightingOrigin );
  246. CBaseEntity *GetLightingOrigin();
  247. const float* GetPoseParameterArray() { return m_flPoseParameter.Base(); }
  248. const float* GetEncodedControllerArray() { return m_flEncodedController.Base(); }
  249. void BuildMatricesWithBoneMerge( const CStudioHdr *pStudioHdr, const QAngle& angles,
  250. const Vector& origin, const Vector pos[MAXSTUDIOBONES],
  251. const Quaternion q[MAXSTUDIOBONES], matrix3x4_t bonetoworld[MAXSTUDIOBONES],
  252. CBaseAnimating *pParent, CBoneCache *pParentCache );
  253. void SetFadeDistance( float minFadeDist, float maxFadeDist );
  254. int GetBoneCacheFlags( void ) { return m_fBoneCacheFlags; }
  255. inline void SetBoneCacheFlags( unsigned short fFlag ) { m_fBoneCacheFlags |= fFlag; }
  256. inline void ClearBoneCacheFlags( unsigned short fFlag ) { m_fBoneCacheFlags &= ~fFlag; }
  257. bool PrefetchSequence( int iSequence );
  258. private:
  259. void LockStudioHdr();
  260. void UnlockStudioHdr();
  261. void StudioFrameAdvanceInternal( CStudioHdr *pStudioHdr, float flInterval );
  262. void InputSetLightingOriginRelative( inputdata_t &inputdata );
  263. void InputSetLightingOrigin( inputdata_t &inputdata );
  264. void InputSetModelScale( inputdata_t &inputdata );
  265. bool CanSkipAnimation( void );
  266. public:
  267. CNetworkVar( int, m_nForceBone );
  268. CNetworkVector( m_vecForce );
  269. CNetworkVar( int, m_nSkin );
  270. CNetworkVar( int, m_nBody );
  271. CNetworkVar( int, m_nHitboxSet );
  272. // For making things thin during barnacle swallowing, e.g.
  273. CNetworkVar( float, m_flModelScale );
  274. // was pev->framerate
  275. CNetworkVar( float, m_flPlaybackRate );
  276. public:
  277. void InitStepHeightAdjust( void );
  278. void SetIKGroundContactInfo( float minHeight, float maxHeight );
  279. void UpdateStepOrigin( void );
  280. protected:
  281. float m_flIKGroundContactTime;
  282. float m_flIKGroundMinHeight;
  283. float m_flIKGroundMaxHeight;
  284. float m_flEstIkFloor; // debounced
  285. float m_flEstIkOffset;
  286. CIKContext *m_pIk;
  287. int m_iIKCounter;
  288. public:
  289. Vector GetStepOrigin( void ) const;
  290. QAngle GetStepAngles( void ) const;
  291. private:
  292. bool m_bSequenceFinished;// flag set when StudioAdvanceFrame moves across a frame boundry
  293. bool m_bSequenceLoops; // true if the sequence loops
  294. bool m_bResetSequenceInfoOnLoad; // true if a ResetSequenceInfo was queued up during dynamic load
  295. float m_flDissolveStartTime;
  296. // was pev->frame
  297. CNetworkVar( float, m_flCycle );
  298. CNetworkVar( int, m_nSequence );
  299. CNetworkArray( float, m_flPoseParameter, NUM_POSEPAREMETERS ); // must be private so manual mode works!
  300. CNetworkArray( float, m_flEncodedController, NUM_BONECTRLS ); // bone controller setting (0..1)
  301. // Client-side animation (useful for looping animation objects)
  302. CNetworkVar( bool, m_bClientSideAnimation );
  303. CNetworkVar( bool, m_bClientSideFrameReset );
  304. CNetworkVar( int, m_nNewSequenceParity );
  305. CNetworkVar( int, m_nResetEventsParity );
  306. // Incremented each time the entity is told to do a muzzle flash.
  307. // The client picks up the change and draws the flash.
  308. CNetworkVar( unsigned char, m_nMuzzleFlashParity );
  309. CNetworkHandle( CBaseEntity, m_hLightingOrigin );
  310. CNetworkHandle( CBaseEntity, m_hLightingOriginRelative );
  311. string_t m_iszLightingOriginRelative; // for reading from the file only
  312. string_t m_iszLightingOrigin; // for reading from the file only
  313. memhandle_t m_boneCacheHandle;
  314. unsigned short m_fBoneCacheFlags; // Used for bone cache state on model
  315. protected:
  316. CNetworkVar( float, m_fadeMinDist ); // Point at which fading is absolute
  317. CNetworkVar( float, m_fadeMaxDist ); // Point at which fading is inactive
  318. CNetworkVar( float, m_flFadeScale ); // Scale applied to min / max
  319. public:
  320. COutputEvent m_OnIgnite;
  321. private:
  322. CStudioHdr *m_pStudioHdr;
  323. CThreadFastMutex m_StudioHdrInitLock;
  324. CThreadFastMutex m_BoneSetupMutex;
  325. // FIXME: necessary so that cyclers can hack m_bSequenceFinished
  326. friend class CFlexCycler;
  327. friend class CCycler;
  328. friend class CBlendingCycler;
  329. };
  330. //-----------------------------------------------------------------------------
  331. // Purpose: return a pointer to an updated studiomdl cache cache
  332. //-----------------------------------------------------------------------------
  333. inline CStudioHdr *CBaseAnimating::GetModelPtr( void )
  334. {
  335. if ( IsDynamicModelLoading() )
  336. return NULL;
  337. #ifdef _DEBUG
  338. if ( !HushAsserts() )
  339. {
  340. // GetModelPtr() is often called before OnNewModel() so go ahead and set it up first chance.
  341. static IDataCacheSection *pModelCache = datacache->FindSection( "ModelData" );
  342. AssertOnce( pModelCache->IsFrameLocking() );
  343. }
  344. #endif
  345. if ( !m_pStudioHdr && GetModel() )
  346. {
  347. LockStudioHdr();
  348. }
  349. return ( m_pStudioHdr && m_pStudioHdr->IsValid() ) ? m_pStudioHdr : NULL;
  350. }
  351. inline void CBaseAnimating::InvalidateMdlCache()
  352. {
  353. UnlockStudioHdr();
  354. if ( m_pStudioHdr != NULL )
  355. {
  356. delete m_pStudioHdr;
  357. m_pStudioHdr = NULL;
  358. }
  359. }
  360. //-----------------------------------------------------------------------------
  361. // Purpose: Serves the 90% case of calling SetSequence / ResetSequenceInfo.
  362. //-----------------------------------------------------------------------------
  363. /*
  364. inline void CBaseAnimating::ResetSequence(int nSequence)
  365. {
  366. m_nSequence = nSequence;
  367. ResetSequenceInfo();
  368. }
  369. */
  370. inline float CBaseAnimating::GetPlaybackRate()
  371. {
  372. return m_flPlaybackRate;
  373. }
  374. inline void CBaseAnimating::SetPlaybackRate( float rate )
  375. {
  376. m_flPlaybackRate = rate;
  377. }
  378. inline void CBaseAnimating::SetLightingOrigin( CBaseEntity *pLightingOrigin )
  379. {
  380. m_hLightingOrigin = pLightingOrigin;
  381. }
  382. inline CBaseEntity *CBaseAnimating::GetLightingOrigin()
  383. {
  384. return m_hLightingOrigin;
  385. }
  386. inline void CBaseAnimating::SetLightingOriginRelative( CBaseEntity *pLightingOriginRelative )
  387. {
  388. m_hLightingOriginRelative = pLightingOriginRelative;
  389. }
  390. inline CBaseEntity *CBaseAnimating::GetLightingOriginRelative()
  391. {
  392. return m_hLightingOriginRelative;
  393. }
  394. //-----------------------------------------------------------------------------
  395. // Cycle access
  396. //-----------------------------------------------------------------------------
  397. inline float CBaseAnimating::GetCycle() const
  398. {
  399. return m_flCycle;
  400. }
  401. inline void CBaseAnimating::SetCycle( float flCycle )
  402. {
  403. m_flCycle = flCycle;
  404. }
  405. EXTERN_SEND_TABLE(DT_BaseAnimating);
  406. #define ANIMATION_SEQUENCE_BITS 12 // 4096 sequences
  407. #define ANIMATION_SKIN_BITS 10 // 1024 body skin selections FIXME: this seems way high
  408. #define ANIMATION_BODY_BITS 32 // body combinations
  409. #define ANIMATION_HITBOXSET_BITS 2 // hit box sets
  410. #if defined( TF_DLL )
  411. #define ANIMATION_POSEPARAMETER_BITS 8 // pose parameter resolution
  412. #else
  413. #define ANIMATION_POSEPARAMETER_BITS 11 // pose parameter resolution
  414. #endif
  415. #define ANIMATION_PLAYBACKRATE_BITS 8 // default playback rate, only used on leading edge detect sequence changes
  416. #endif // BASEANIMATING_H