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.

449 lines
15 KiB

  1. //========= Copyright 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. class CBoneSetup;
  40. class IBoneSetup
  41. {
  42. public:
  43. IBoneSetup( const CStudioHdr *pStudioHdr, int boneMask, const float poseParameter[], IPoseDebugger *pPoseDebugger = NULL );
  44. ~IBoneSetup( void );
  45. void InitPose( Vector pos[], Quaternion[] );
  46. void AccumulatePose( Vector pos[], Quaternion q[], int sequence, float cycle, float flWeight, float flTime, CIKContext *pIKContext );
  47. void CalcAutoplaySequences( Vector pos[], Quaternion q[], float flRealTime, CIKContext *pIKContext );
  48. void CalcBoneAdj( Vector pos[], Quaternion q[], const float controllers[] );
  49. CStudioHdr *GetStudioHdr();
  50. private:
  51. CBoneSetup *m_pBoneSetup;
  52. };
  53. //-----------------------------------------------------------------------------
  54. // Purpose: blends together all the bones from two p:q lists
  55. //
  56. // p1 = p1 * (1 - s) + p2 * s
  57. // q1 = q1 * (1 - s) + q2 * s
  58. //-----------------------------------------------------------------------------
  59. void SlerpBones(
  60. const CStudioHdr *pStudioHdr,
  61. Quaternion q1[MAXSTUDIOBONES],
  62. Vector pos1[MAXSTUDIOBONES],
  63. mstudioseqdesc_t &seqdesc, // source of q2 and pos2
  64. int sequence,
  65. const Quaternion q2[MAXSTUDIOBONES],
  66. const Vector pos2[MAXSTUDIOBONES],
  67. float s,
  68. int boneMask
  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 matrix3x4_t &rootxform,
  87. const Vector pos[],
  88. const Quaternion q[],
  89. int iBone,
  90. matrix3x4_t *pBoneToWorld );
  91. void BuildBoneChain(
  92. const CStudioHdr *pStudioHdr,
  93. const matrix3x4_t &rootxform,
  94. const Vector pos[],
  95. const Quaternion q[],
  96. int iBone,
  97. matrix3x4_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. // matrix3x4_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. Quaternion q;
  202. float start; // beginning of influence
  203. float peak; // start of full influence
  204. float tail; // end of full influence
  205. float end; // end of all influence
  206. float top;
  207. float drop;
  208. float commit; // frame footstep target should be committed
  209. float release; // frame ankle should end rotation from latched orientation
  210. float flWeight; // processed version of start-end cycle
  211. float flRuleWeight; // blending weight
  212. float latched; // does the IK rule use a latched value?
  213. char *szLabel;
  214. Vector kneeDir;
  215. Vector kneePos;
  216. ikcontextikrule_t() {}
  217. private:
  218. // No copy constructors allowed
  219. ikcontextikrule_t(const ikcontextikrule_t& vOther);
  220. };
  221. void Studio_AlignIKMatrix( matrix3x4_t &mMat, const Vector &vAlignTo );
  222. bool Studio_SolveIK( int iThigh, int iKnee, int iFoot, Vector &targetFoot, matrix3x4_t* pBoneToWorld );
  223. bool Studio_SolveIK( int iThigh, int iKnee, int iFoot, Vector &targetFoot, Vector &targetKneePos, Vector &targetKneeDir, matrix3x4_t* pBoneToWorld );
  224. class CIKContext
  225. {
  226. public:
  227. CIKContext( );
  228. void Init( const CStudioHdr *pStudioHdr, const QAngle &angles, const Vector &pos, float flTime, int iFramecounter, int boneMask );
  229. void AddDependencies( mstudioseqdesc_t &seqdesc, int iSequence, float flCycle, const float poseParameters[], float flWeight = 1.0f );
  230. void ClearTargets( void );
  231. void UpdateTargets( Vector pos[], Quaternion q[], matrix3x4_t boneToWorld[], CBoneBitList &boneComputed );
  232. void AutoIKRelease( void );
  233. void SolveDependencies( Vector pos[], Quaternion q[], matrix3x4_t boneToWorld[], CBoneBitList &boneComputed );
  234. void AddAutoplayLocks( Vector pos[], Quaternion q[] );
  235. void SolveAutoplayLocks( Vector pos[], Quaternion q[] );
  236. void AddSequenceLocks( mstudioseqdesc_t &SeqDesc, Vector pos[], Quaternion q[] );
  237. void SolveSequenceLocks( mstudioseqdesc_t &SeqDesc, Vector pos[], Quaternion q[] );
  238. void AddAllLocks( Vector pos[], Quaternion q[] );
  239. void SolveAllLocks( Vector pos[], Quaternion q[] );
  240. void SolveLock( const mstudioiklock_t *plock, int i, Vector pos[], Quaternion q[], matrix3x4_t boneToWorld[], CBoneBitList &boneComputed );
  241. CUtlVectorFixed< CIKTarget, 12 > m_target;
  242. private:
  243. CStudioHdr const *m_pStudioHdr;
  244. bool Estimate( int iSequence, float flCycle, int iTarget, const float poseParameter[], float flWeight = 1.0f );
  245. void BuildBoneChain( const Vector pos[], const Quaternion q[], int iBone, matrix3x4_t *pBoneToWorld, CBoneBitList &boneComputed );
  246. // virtual IK rules, filtered and combined from each sequence
  247. CUtlVector< CUtlVector< ikcontextikrule_t > > m_ikChainRule;
  248. CUtlVector< ikcontextikrule_t > m_ikLock;
  249. matrix3x4_t m_rootxform;
  250. int m_iFramecounter;
  251. float m_flTime;
  252. int m_boneMask;
  253. };
  254. //-----------------------------------------------------------------------------
  255. // Purpose:
  256. //-----------------------------------------------------------------------------
  257. // replaces the bonetoworld transforms for all bones that are procedural
  258. bool CalcProceduralBone(
  259. const CStudioHdr *pStudioHdr,
  260. int iBone,
  261. CBoneAccessor &bonetoworld
  262. );
  263. void Studio_BuildMatrices(
  264. const CStudioHdr *pStudioHdr,
  265. const QAngle& angles,
  266. const Vector& origin,
  267. const Vector pos[],
  268. const Quaternion q[],
  269. int iBone,
  270. float flScale,
  271. matrix3x4_t bonetoworld[MAXSTUDIOBONES],
  272. int boneMask
  273. );
  274. // Get a bone->bone relative transform
  275. void Studio_CalcBoneToBoneTransform( const CStudioHdr *pStudioHdr, int inputBoneIndex, int outputBoneIndex, matrix3x4_t &matrixOut );
  276. // Given a bone rotation value, figures out the value you need to give to the controller
  277. // to have the bone at that value.
  278. // [in] flValue = the desired bone rotation value
  279. // [out] ctlValue = the (0-1) value to set the controller t.
  280. // return value = flValue, unwrapped to lie between the controller's start and end.
  281. float Studio_SetController( const CStudioHdr *pStudioHdr, int iController, float flValue, float &ctlValue );
  282. // Given a 0-1 controller value, maps it into the controller's start and end and returns the bone rotation angle.
  283. // [in] ctlValue = value in controller space (0-1).
  284. // return value = value in bone space
  285. float Studio_GetController( const CStudioHdr *pStudioHdr, int iController, float ctlValue );
  286. void Studio_CalcDefaultPoseParameters( const CStudioHdr *pStudioHdr, float flPoseParameter[MAXSTUDIOPOSEPARAM], int nCount );
  287. float Studio_GetPoseParameter( const CStudioHdr *pStudioHdr, int iParameter, float ctlValue );
  288. float Studio_SetPoseParameter( const CStudioHdr *pStudioHdr, int iParameter, float flValue, float &ctlValue );
  289. // converts a global 0..1 pose parameter into the local sequences blending value
  290. void Studio_LocalPoseParameter( const CStudioHdr *pStudioHdr, const float poseParameter[], mstudioseqdesc_t &seqdesc, int iSequence, int iLocalIndex, float &flSetting, int &index );
  291. void Studio_SeqAnims( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int iSequence, const float poseParameter[], mstudioanimdesc_t *panim[4], float *weight );
  292. int Studio_MaxFrame( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] );
  293. float Studio_FPS( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] );
  294. float Studio_CPS( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int iSequence, const float poseParameter[] );
  295. float Studio_Duration( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] );
  296. void Studio_MovementRate( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], Vector *pVec );
  297. // void Studio_Movement( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], Vector *pVec );
  298. //void Studio_AnimPosition( mstudioanimdesc_t *panim, float flCycle, Vector &vecPos, Vector &vecAngle );
  299. //void Studio_AnimVelocity( mstudioanimdesc_t *panim, float flCycle, Vector &vecVelocity );
  300. //float Studio_FindAnimDistance( mstudioanimdesc_t *panim, float flDist );
  301. bool Studio_AnimMovement( mstudioanimdesc_t *panim, float flCycleFrom, float flCycleTo, Vector &deltaPos, QAngle &deltaAngle );
  302. bool Studio_SeqMovement( const CStudioHdr *pStudioHdr, int iSequence, float flCycleFrom, float flCycleTo, const float poseParameter[], Vector &deltaMovement, QAngle &deltaAngle );
  303. bool Studio_SeqVelocity( const CStudioHdr *pStudioHdr, int iSequence, float flCycle, const float poseParameter[], Vector &vecVelocity );
  304. float Studio_FindSeqDistance( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], float flDist );
  305. float Studio_FindSeqVelocity( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], float flVelocity );
  306. int Studio_FindAttachment( const CStudioHdr *pStudioHdr, const char *pAttachmentName );
  307. int Studio_FindRandomAttachment( const CStudioHdr *pStudioHdr, const char *pAttachmentName );
  308. int Studio_BoneIndexByName( const CStudioHdr *pStudioHdr, const char *pName );
  309. const char *Studio_GetDefaultSurfaceProps( CStudioHdr *pstudiohdr );
  310. float Studio_GetMass( CStudioHdr *pstudiohdr );
  311. const char *Studio_GetKeyValueText( const CStudioHdr *pStudioHdr, int iSequence );
  312. FORWARD_DECLARE_HANDLE( memhandle_t );
  313. struct bonecacheparams_t
  314. {
  315. CStudioHdr *pStudioHdr;
  316. matrix3x4_t *pBoneToWorld;
  317. float curtime;
  318. int boneMask;
  319. };
  320. class CBoneCache
  321. {
  322. public:
  323. // you must implement these static functions for the ResourceManager
  324. // -----------------------------------------------------------
  325. static CBoneCache *CreateResource( const bonecacheparams_t &params );
  326. static unsigned int EstimatedSize( const bonecacheparams_t &params );
  327. // -----------------------------------------------------------
  328. // member functions that must be present for the ResourceManager
  329. void DestroyResource();
  330. CBoneCache *GetData() { return this; }
  331. unsigned int Size() { return m_size; }
  332. // -----------------------------------------------------------
  333. CBoneCache();
  334. // was constructor, but placement new is messy wrt memdebug - so cast & init instead
  335. void Init( const bonecacheparams_t &params, unsigned int size, short *pStudioToCached, short *pCachedToStudio, int cachedBoneCount );
  336. void UpdateBones( const matrix3x4_t *pBoneToWorld, int numbones, float curtime );
  337. matrix3x4_t *GetCachedBone( int studioIndex );
  338. void ReadCachedBones( matrix3x4_t *pBoneToWorld );
  339. void ReadCachedBonePointers( matrix3x4_t **bones, int numbones );
  340. bool IsValid( float curtime, float dt = 0.1f );
  341. public:
  342. float m_timeValid;
  343. int m_boneMask;
  344. private:
  345. matrix3x4_t *BoneArray();
  346. short *StudioToCached();
  347. short *CachedToStudio();
  348. unsigned int m_size;
  349. unsigned short m_cachedBoneCount;
  350. unsigned short m_matrixOffset;
  351. unsigned short m_cachedToStudioOffset;
  352. unsigned short m_boneOutOffset;
  353. };
  354. CBoneCache *Studio_GetBoneCache( memhandle_t cacheHandle );
  355. memhandle_t Studio_CreateBoneCache( bonecacheparams_t &params );
  356. void Studio_DestroyBoneCache( memhandle_t cacheHandle );
  357. void Studio_InvalidateBoneCache( memhandle_t cacheHandle );
  358. // Given a ray, trace for an intersection with this studiomodel. Get the array of bones from StudioSetupHitboxBones
  359. 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 );
  360. void QuaternionSM( float s, const Quaternion &p, const Quaternion &q, Quaternion &qt );
  361. void QuaternionMA( const Quaternion &p, float s, const Quaternion &q, Quaternion &qt );
  362. bool Studio_PrefetchSequence( const CStudioHdr *pStudioHdr, int iSequence );
  363. void Studio_RunBoneFlexDrivers( float *pFlexController, const CStudioHdr *pStudioHdr, const Vector *pPositions, const matrix3x4_t *pBoneToWorld, const matrix3x4_t &mRootToWorld );
  364. #endif // BONE_SETUP_H