Counter Strike : Global Offensive Source Code
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.

491 lines
17 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef BONE_SETUP_H
  8. #define BONE_SETUP_H
  9. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. #include "studio.h"
  13. #include "cmodel.h"
  14. #include "bitvec.h"
  15. class CBoneToWorld;
  16. class CIKContext;
  17. class CBoneAccessor;
  18. class IPoseDebugger;
  19. // This provides access to networked arrays, so if this code actually changes a value,
  20. // the entity is marked as changed.
  21. abstract_class IParameterAccess
  22. {
  23. public:
  24. virtual float GetParameter( int iParam ) = 0;
  25. virtual void SetParameter( int iParam, float flValue ) = 0;
  26. };
  27. class CBoneBitList : public CBitVec<MAXSTUDIOBONES>
  28. {
  29. public:
  30. inline void MarkBone(int iBone)
  31. {
  32. Set(iBone);
  33. }
  34. inline bool IsBoneMarked(int iBone)
  35. {
  36. return Get(iBone) != 0 ? true : false;
  37. }
  38. };
  39. //-----------------------------------------------------------------------------
  40. // Purpose: blends together all the bones from two p:q lists
  41. //
  42. // p1 = p1 * (1 - s) + p2 * s
  43. // q1 = q1 * (1 - s) + q2 * s
  44. //-----------------------------------------------------------------------------
  45. void SlerpBones(
  46. const CStudioHdr *pStudioHdr,
  47. BoneQuaternion q1[MAXSTUDIOBONES],
  48. BoneVector pos1[MAXSTUDIOBONES],
  49. mstudioseqdesc_t &seqdesc, // source of q2 and pos2
  50. int sequence,
  51. const BoneQuaternionAligned q2[MAXSTUDIOBONES],
  52. const BoneVector pos2[MAXSTUDIOBONES],
  53. float s,
  54. int boneMask
  55. );
  56. class CBoneSetup;
  57. class IBoneSetup
  58. {
  59. public:
  60. IBoneSetup( const CStudioHdr *pStudioHdr, int boneMask, const float poseParameter[], IPoseDebugger *pPoseDebugger = NULL );
  61. ~IBoneSetup( void );
  62. void InitPose( BoneVector pos[], BoneQuaternionAligned q[] );
  63. void AccumulatePose( BoneVector pos[], BoneQuaternion q[], int sequence, float cycle, float flWeight, float flTime, CIKContext *pIKContext );
  64. void CalcAutoplaySequences( BoneVector pos[], BoneQuaternion q[], float flRealTime, CIKContext *pIKContext );
  65. void CalcBoneAdj( BoneVector pos[], BoneQuaternion q[], const float controllers[] );
  66. CStudioHdr *GetStudioHdr();
  67. private:
  68. CBoneSetup *m_pBoneSetup;
  69. };
  70. // Given two samples of a bone separated in time by dt,
  71. // compute the velocity and angular velocity of that bone
  72. void CalcBoneDerivatives( Vector &velocity, AngularImpulse &angVel, const matrix3x4_t &prev, const matrix3x4_t &current, float dt );
  73. // Give a derivative of a bone, compute the velocity & angular velocity of that bone
  74. void CalcBoneVelocityFromDerivative( const QAngle &vecAngles, Vector &velocity, AngularImpulse &angVel, const matrix3x4_t &current );
  75. // This function sets up the local transform for a single frame of animation. It doesn't handle
  76. // pose parameters or interpolation between frames.
  77. void SetupSingleBoneMatrix(
  78. CStudioHdr *pOwnerHdr,
  79. int nSequence,
  80. int iFrame,
  81. int iBone,
  82. matrix3x4_t &mBoneLocal );
  83. // Purpose: build boneToWorld transforms for a specific bone
  84. void BuildBoneChain(
  85. const CStudioHdr *pStudioHdr,
  86. const matrix3x4a_t &rootxform,
  87. const BoneVector pos[],
  88. const BoneQuaternion q[],
  89. int iBone,
  90. matrix3x4a_t *pBoneToWorld );
  91. void BuildBoneChain(
  92. const CStudioHdr *pStudioHdr,
  93. const matrix3x4a_t &rootxform,
  94. const BoneVector pos[],
  95. const BoneQuaternion q[],
  96. int iBone,
  97. matrix3x4a_t *pBoneToWorld,
  98. CBoneBitList &boneComputed );
  99. //-----------------------------------------------------------------------------
  100. // Purpose:
  101. //-----------------------------------------------------------------------------
  102. // ik info
  103. class CIKTarget
  104. {
  105. public:
  106. void SetOwner( int entindex, const Vector &pos, const QAngle &angles );
  107. void ClearOwner( void );
  108. int GetOwner( void );
  109. void UpdateOwner( int entindex, const Vector &pos, const QAngle &angles );
  110. void SetPos( const Vector &pos );
  111. void SetAngles( const QAngle &angles );
  112. void SetQuaternion( const Quaternion &q );
  113. void SetNormal( const Vector &normal );
  114. void SetPosWithNormalOffset( const Vector &pos, const Vector &normal );
  115. void SetOnWorld( bool bOnWorld = true );
  116. bool IsActive( void );
  117. void IKFailed( void );
  118. int chain;
  119. int type;
  120. void MoveReferenceFrame( Vector &deltaPos, QAngle &deltaAngles );
  121. // accumulated offset from ideal footplant location
  122. public:
  123. struct x2 {
  124. char *pAttachmentName;
  125. Vector pos;
  126. Quaternion q;
  127. } offset;
  128. private:
  129. struct x3 {
  130. Vector pos;
  131. Quaternion q;
  132. } ideal;
  133. public:
  134. struct x4 {
  135. float latched;
  136. float release;
  137. float height;
  138. float floor;
  139. float radius;
  140. float flTime;
  141. float flWeight;
  142. Vector pos;
  143. Quaternion q;
  144. bool onWorld;
  145. } est; // estimate contact position
  146. struct x5 {
  147. float hipToFoot; // distance from hip
  148. float hipToKnee; // distance from hip to knee
  149. float kneeToFoot; // distance from knee to foot
  150. Vector hip; // location of hip
  151. Vector closest; // closest valid location from hip to foot that the foot can move to
  152. Vector knee; // pre-ik location of knee
  153. Vector farthest; // farthest valid location from hip to foot that the foot can move to
  154. Vector lowest; // lowest position directly below hip that the foot can drop to
  155. } trace;
  156. private:
  157. // internally latched footset, position
  158. struct x1 {
  159. // matrix3x4a_t worldTarget;
  160. bool bNeedsLatch;
  161. bool bHasLatch;
  162. float influence;
  163. int iFramecounter;
  164. int owner;
  165. Vector absOrigin;
  166. QAngle absAngles;
  167. Vector pos;
  168. Quaternion q;
  169. Vector deltaPos; // acculated error
  170. Quaternion deltaQ;
  171. Vector debouncePos;
  172. Quaternion debounceQ;
  173. } latched;
  174. struct x6 {
  175. float flTime; // time last error was detected
  176. float flErrorTime;
  177. float ramp;
  178. bool bInError;
  179. } error;
  180. friend class CIKContext;
  181. };
  182. struct ikchainresult_t
  183. {
  184. // accumulated offset from ideal footplant location
  185. int target;
  186. Vector pos;
  187. Quaternion q;
  188. float flWeight;
  189. };
  190. struct ikcontextikrule_t
  191. {
  192. int index;
  193. int type;
  194. int chain;
  195. int bone;
  196. int slot; // iktarget slot. Usually same as chain.
  197. float height;
  198. float radius;
  199. float floor;
  200. Vector pos;
  201. float pad1;
  202. Quaternion q;
  203. float start; // beginning of influence
  204. float peak; // start of full influence
  205. float tail; // end of full influence
  206. float end; // end of all influence
  207. float top;
  208. float drop;
  209. float commit; // frame footstep target should be committed
  210. float release; // frame ankle should end rotation from latched orientation
  211. float flWeight; // processed version of start-end cycle
  212. float flRuleWeight; // blending weight
  213. float latched; // does the IK rule use a latched value?
  214. char *szLabel;
  215. Vector kneeDir;
  216. float pad2;
  217. Vector kneePos;
  218. float pad3;
  219. ikcontextikrule_t() {}
  220. private:
  221. // No copy constructors allowed
  222. ikcontextikrule_t(const ikcontextikrule_t& vOther);
  223. };
  224. void Studio_AlignIKMatrix( matrix3x4a_t &mMat, const Vector &vAlignTo );
  225. bool Studio_SolveIK( int iThigh, int iKnee, int iFoot, Vector &targetFoot, matrix3x4a_t* pBoneToWorld );
  226. bool Studio_SolveIK( int iThigh, int iKnee, int iFoot, Vector &targetFoot, Vector &targetKneePos, Vector &targetKneeDir, matrix3x4a_t* pBoneToWorld );
  227. class CIKContext
  228. {
  229. public:
  230. CIKContext( );
  231. void Init( const CStudioHdr *pStudioHdr, const QAngle &angles, const Vector &pos, float flTime, int iFramecounter, int boneMask );
  232. void AddDependencies( mstudioseqdesc_t &seqdesc, int iSequence, float flCycle, const float poseParameters[], float flWeight = 1.0f );
  233. #if defined( _PS3 )
  234. void AddAllDependencies_PS3( ikcontextikrule_t *ikRules, int numRules );
  235. #endif
  236. void ClearTargets( void );
  237. void UpdateTargets( BoneVector pos[], BoneQuaternion q[], matrix3x4a_t boneToWorld[], CBoneBitList &boneComputed );
  238. void AutoIKRelease( void );
  239. void SolveDependencies( BoneVector pos[], BoneQuaternion q[], matrix3x4a_t boneToWorld[], CBoneBitList &boneComputed );
  240. void AddAutoplayLocks( BoneVector pos[], BoneQuaternion q[] );
  241. void SolveAutoplayLocks( BoneVector pos[], BoneQuaternion q[] );
  242. void AddSequenceLocks( mstudioseqdesc_t &SeqDesc, BoneVector pos[], BoneQuaternion q[] );
  243. void SolveSequenceLocks( mstudioseqdesc_t &SeqDesc, BoneVector pos[], BoneQuaternion q[] );
  244. void AddAllLocks( BoneVector pos[], BoneQuaternion q[] );
  245. void SolveAllLocks( BoneVector pos[], BoneQuaternion q[] );
  246. void SolveLock( const mstudioiklock_t *plock, int i, BoneVector pos[], BoneQuaternion q[], matrix3x4a_t boneToWorld[], CBoneBitList &boneComputed );
  247. CUtlVectorFixed< CIKTarget, 12 > m_target;
  248. void CopyTo( CIKContext* pOther, const unsigned short * iRemapping );
  249. void BuildBoneChain( const BoneVector pos[], const BoneQuaternion q[], int iBone, matrix3x4a_t *pBoneToWorld, CBoneBitList &boneComputed );
  250. const int GetBoneMask( void ) { return m_boneMask; }
  251. private:
  252. CStudioHdr const *m_pStudioHdr;
  253. bool Estimate( int iSequence, float flCycle, int iTarget, const float poseParameter[], float flWeight = 1.0f );
  254. // virtual IK rules, filtered and combined from each sequence
  255. CUtlVector< CUtlVector< ikcontextikrule_t > > m_ikChainRule;
  256. CUtlVector< ikcontextikrule_t > m_ikLock;
  257. matrix3x4a_t m_rootxform;
  258. int m_iFramecounter;
  259. float m_flTime;
  260. int m_boneMask;
  261. };
  262. //-----------------------------------------------------------------------------
  263. // Purpose:
  264. //-----------------------------------------------------------------------------
  265. // replaces the bonetoworld transforms for all bones that are procedural
  266. bool CalcProceduralBone(
  267. const CStudioHdr *pStudioHdr,
  268. int iBone,
  269. CBoneAccessor &bonetoworld
  270. );
  271. void Studio_BuildMatrices(
  272. const CStudioHdr *pStudioHdr,
  273. const QAngle& angles,
  274. const Vector& origin,
  275. const BoneVector pos[],
  276. const BoneQuaternion q[],
  277. int iBone,
  278. float flScale,
  279. matrix3x4a_t bonetoworld[MAXSTUDIOBONES],
  280. int boneMask
  281. );
  282. // Get a bone->bone relative transform
  283. void Studio_CalcBoneToBoneTransform( const CStudioHdr *pStudioHdr, int inputBoneIndex, int outputBoneIndex, matrix3x4_t &matrixOut );
  284. // Given a bone rotation value, figures out the value you need to give to the controller
  285. // to have the bone at that value.
  286. // [in] flValue = the desired bone rotation value
  287. // [out] ctlValue = the (0-1) value to set the controller t.
  288. // return value = flValue, unwrapped to lie between the controller's start and end.
  289. float Studio_SetController( const CStudioHdr *pStudioHdr, int iController, float flValue, float &ctlValue );
  290. // Given a 0-1 controller value, maps it into the controller's start and end and returns the bone rotation angle.
  291. // [in] ctlValue = value in controller space (0-1).
  292. // return value = value in bone space
  293. float Studio_GetController( const CStudioHdr *pStudioHdr, int iController, float ctlValue );
  294. void Studio_CalcDefaultPoseParameters( const CStudioHdr *pStudioHdr, float flPoseParameter[MAXSTUDIOPOSEPARAM], int nCount );
  295. float Studio_GetPoseParameter( const CStudioHdr *pStudioHdr, int iParameter, float ctlValue );
  296. float Studio_SetPoseParameter( const CStudioHdr *pStudioHdr, int iParameter, float flValue, float &ctlValue );
  297. // converts a global 0..1 pose parameter into the local sequences blending value
  298. int Studio_LocalPoseParameter( const CStudioHdr *pStudioHdr, const float poseParameter[], mstudioseqdesc_t &seqdesc, int iSequence, int iLocalIndex, float &flSetting );
  299. void Studio_SeqAnims( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int iSequence, const float poseParameter[], mstudioanimdesc_t *panim[4], float *weight );
  300. int Studio_MaxFrame( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] );
  301. float Studio_FPS( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] );
  302. float Studio_CPS( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int iSequence, const float poseParameter[] );
  303. float Studio_Duration( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] );
  304. void Studio_MovementRate( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], Vector *pVec );
  305. float Studio_SeqMovementAndDuration( const CStudioHdr *pStudioHdr, int iSequence, float flCycleFrom, float flCycleTo, const float poseParameter[], Vector &deltaPos );
  306. // void Studio_Movement( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], Vector *pVec );
  307. //void Studio_AnimPosition( mstudioanimdesc_t *panim, float flCycle, Vector &vecPos, Vector &vecAngle );
  308. //void Studio_AnimVelocity( mstudioanimdesc_t *panim, float flCycle, Vector &vecVelocity );
  309. //float Studio_FindAnimDistance( mstudioanimdesc_t *panim, float flDist );
  310. bool Studio_AnimMovement( mstudioanimdesc_t *panim, float flCycleFrom, float flCycleTo, Vector &deltaPos, QAngle &deltaAngle );
  311. bool Studio_SeqMovement( const CStudioHdr *pStudioHdr, int iSequence, float flCycleFrom, float flCycleTo, const float poseParameter[], Vector &deltaMovement, QAngle &deltaAngle );
  312. bool Studio_SeqVelocity( const CStudioHdr *pStudioHdr, int iSequence, float flCycle, const float poseParameter[], Vector &vecVelocity );
  313. float Studio_FindSeqDistance( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], float flDist );
  314. float Studio_FindSeqVelocity( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], float flVelocity );
  315. int Studio_FindAttachment( const CStudioHdr *pStudioHdr, const char *pAttachmentName );
  316. int Studio_FindRandomAttachment( const CStudioHdr *pStudioHdr, const char *pAttachmentName );
  317. int Studio_BoneIndexByName( const CStudioHdr *pStudioHdr, const char *pName );
  318. const char *Studio_GetDefaultSurfaceProps( CStudioHdr *pstudiohdr );
  319. float Studio_GetMass( CStudioHdr *pstudiohdr );
  320. const char *Studio_GetKeyValueText( const CStudioHdr *pStudioHdr, int iSequence );
  321. FORWARD_DECLARE_HANDLE( memhandle_t );
  322. struct bonecacheparams_t
  323. {
  324. CStudioHdr *pStudioHdr;
  325. matrix3x4a_t *pBoneToWorld;
  326. float curtime;
  327. int boneMask;
  328. };
  329. class CBoneCache
  330. {
  331. public:
  332. // you must implement these static functions for the ResourceManager
  333. // -----------------------------------------------------------
  334. static CBoneCache *CreateResource( const bonecacheparams_t &params );
  335. static unsigned int EstimatedSize( const bonecacheparams_t &params );
  336. // -----------------------------------------------------------
  337. // member functions that must be present for the ResourceManager
  338. void DestroyResource();
  339. CBoneCache *GetData() { return this; }
  340. unsigned int Size() { return m_size; }
  341. // -----------------------------------------------------------
  342. CBoneCache();
  343. // was constructor, but placement new is messy wrt memdebug - so cast & init instead
  344. void Init( const bonecacheparams_t &params, unsigned int size, short *pStudioToCached, short *pCachedToStudio, int cachedBoneCount );
  345. void UpdateBones( const matrix3x4a_t *pBoneToWorld, int numbones, float curtime );
  346. matrix3x4a_t *GetCachedBone( int studioIndex );
  347. void ReadCachedBones( matrix3x4a_t *pBoneToWorld );
  348. void ReadCachedBonePointers( matrix3x4_t **bones, int numbones );
  349. bool IsValid( float curtime, float dt = 0.1f );
  350. public:
  351. float m_timeValid;
  352. int m_boneMask;
  353. private:
  354. matrix3x4a_t *BoneArray();
  355. short *StudioToCached();
  356. short *CachedToStudio();
  357. unsigned int m_size;
  358. unsigned short m_cachedBoneCount;
  359. unsigned short m_matrixOffset;
  360. unsigned short m_cachedToStudioOffset;
  361. unsigned short m_boneOutOffset;
  362. };
  363. void Studio_LockBoneCache();
  364. void Studio_UnlockBoneCache();
  365. CBoneCache *Studio_GetBoneCache( memhandle_t cacheHandle, bool bLock = false );
  366. void Studio_ReleaseBoneCache( memhandle_t cacheHandle );
  367. memhandle_t Studio_CreateBoneCache( bonecacheparams_t &params );
  368. void Studio_DestroyBoneCache( memhandle_t cacheHandle );
  369. void Studio_InvalidateBoneCacheIfNotMatching( memhandle_t cacheHandle, float flTimeValid );
  370. // Given a ray, trace for an intersection with this studiomodel. Get the array of bones from StudioSetupHitboxBones
  371. bool TraceToStudio( class IPhysicsSurfaceProps *pProps, const Ray_t& ray, CStudioHdr *pStudioHdr, mstudiohitboxset_t *set, matrix3x4_t **hitboxbones, int fContentsMask, const Vector &vecOrigin, float flScale, trace_t &trace );
  372. // Given a ray, trace for an intersection with this studiomodel, bullets will hit bodyparts that result in higher damage
  373. bool TraceToStudioCsgoHitgroupsPriority( class IPhysicsSurfaceProps *pProps, const Ray_t& ray, CStudioHdr *pStudioHdr, mstudiohitboxset_t *set, matrix3x4_t **hitboxbones, int fContentsMask, const Vector &vecOrigin, float flScale, trace_t &trace );
  374. // TERROR: TraceToStudio variant that prioritizes hitgroups, so bullets can pass through arms and chest to hit the head, for instance
  375. bool TraceToStudioGrouped( IPhysicsSurfaceProps *pProps, const Ray_t& ray, CStudioHdr *pStudioHdr, mstudiohitboxset_t *set,
  376. matrix3x4_t **hitboxbones, int fContentsMask, trace_t &tr, const CUtlVector< int > &sortedHitgroups );
  377. void QuaternionSM( float s, const Quaternion &p, const Quaternion &q, Quaternion &qt );
  378. void QuaternionMA( const Quaternion &p, float s, const Quaternion &q, Quaternion &qt );
  379. bool Studio_PrefetchSequence( const CStudioHdr *pStudioHdr, int iSequence );
  380. void Studio_RunBoneFlexDrivers( float *pFlexController, const CStudioHdr *pStudioHdr, const Vector *pPositions, const matrix3x4_t *pBoneToWorld, const matrix3x4_t &mRootToWorld );
  381. //-----------------------------------------------------------------------------
  382. // Computes a number of twist bones given a parent/child pair
  383. // pqTwists, pflWeights, pqTwistBinds must all have at least nCount elements
  384. //-----------------------------------------------------------------------------
  385. void ComputeTwistBones(
  386. Quaternion *pqTwists,
  387. int nCount,
  388. bool bInverse,
  389. const Vector &vUp,
  390. const Quaternion &qParent,
  391. const matrix3x4_t &mChild,
  392. const Quaternion &qBaseInv,
  393. const float *pflWeights,
  394. const Quaternion *pqTwistBinds );
  395. #endif // BONE_SETUP_H