diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /mp/src/public/bone_setup.h | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/public/bone_setup.h')
| -rw-r--r-- | mp/src/public/bone_setup.h | 447 |
1 files changed, 447 insertions, 0 deletions
diff --git a/mp/src/public/bone_setup.h b/mp/src/public/bone_setup.h new file mode 100644 index 00000000..1d38ad5f --- /dev/null +++ b/mp/src/public/bone_setup.h @@ -0,0 +1,447 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef BONE_SETUP_H
+#define BONE_SETUP_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "studio.h"
+#include "cmodel.h"
+#include "bitvec.h"
+
+
+class CBoneToWorld;
+class CIKContext;
+class CBoneAccessor;
+class IPoseDebugger;
+
+
+// This provides access to networked arrays, so if this code actually changes a value,
+// the entity is marked as changed.
+abstract_class IParameterAccess
+{
+public:
+ virtual float GetParameter( int iParam ) = 0;
+ virtual void SetParameter( int iParam, float flValue ) = 0;
+};
+
+
+
+class CBoneBitList : public CBitVec<MAXSTUDIOBONES>
+{
+public:
+ inline void MarkBone(int iBone)
+ {
+ Set(iBone);
+ }
+ inline bool IsBoneMarked(int iBone)
+ {
+ return Get(iBone) != 0 ? true : false;
+ }
+};
+
+class CBoneSetup;
+class IBoneSetup
+{
+public:
+ IBoneSetup( const CStudioHdr *pStudioHdr, int boneMask, const float poseParameter[], IPoseDebugger *pPoseDebugger = NULL );
+ ~IBoneSetup( void );
+ void InitPose( Vector pos[], Quaternion[] );
+ void AccumulatePose( Vector pos[], Quaternion q[], int sequence, float cycle, float flWeight, float flTime, CIKContext *pIKContext );
+ void CalcAutoplaySequences( Vector pos[], Quaternion q[], float flRealTime, CIKContext *pIKContext );
+ void CalcBoneAdj( Vector pos[], Quaternion q[], const float controllers[] );
+ CStudioHdr *GetStudioHdr();
+private:
+ CBoneSetup *m_pBoneSetup;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: blends together all the bones from two p:q lists
+//
+// p1 = p1 * (1 - s) + p2 * s
+// q1 = q1 * (1 - s) + q2 * s
+//-----------------------------------------------------------------------------
+void SlerpBones(
+ const CStudioHdr *pStudioHdr,
+ Quaternion q1[MAXSTUDIOBONES],
+ Vector pos1[MAXSTUDIOBONES],
+ mstudioseqdesc_t &seqdesc, // source of q2 and pos2
+ int sequence,
+ const Quaternion q2[MAXSTUDIOBONES],
+ const Vector pos2[MAXSTUDIOBONES],
+ float s,
+ int boneMask
+ );
+
+// Given two samples of a bone separated in time by dt,
+// compute the velocity and angular velocity of that bone
+void CalcBoneDerivatives( Vector &velocity, AngularImpulse &angVel, const matrix3x4_t &prev, const matrix3x4_t ¤t, float dt );
+// Give a derivative of a bone, compute the velocity & angular velocity of that bone
+void CalcBoneVelocityFromDerivative( const QAngle &vecAngles, Vector &velocity, AngularImpulse &angVel, const matrix3x4_t ¤t );
+
+// This function sets up the local transform for a single frame of animation. It doesn't handle
+// pose parameters or interpolation between frames.
+void SetupSingleBoneMatrix(
+ CStudioHdr *pOwnerHdr,
+ int nSequence,
+ int iFrame,
+ int iBone,
+ matrix3x4_t &mBoneLocal );
+
+
+// Purpose: build boneToWorld transforms for a specific bone
+void BuildBoneChain(
+ const CStudioHdr *pStudioHdr,
+ const matrix3x4_t &rootxform,
+ const Vector pos[],
+ const Quaternion q[],
+ int iBone,
+ matrix3x4_t *pBoneToWorld );
+
+void BuildBoneChain(
+ const CStudioHdr *pStudioHdr,
+ const matrix3x4_t &rootxform,
+ const Vector pos[],
+ const Quaternion q[],
+ int iBone,
+ matrix3x4_t *pBoneToWorld,
+ CBoneBitList &boneComputed );
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+
+// ik info
+class CIKTarget
+{
+public:
+ void SetOwner( int entindex, const Vector &pos, const QAngle &angles );
+ void ClearOwner( void );
+ int GetOwner( void );
+ void UpdateOwner( int entindex, const Vector &pos, const QAngle &angles );
+ void SetPos( const Vector &pos );
+ void SetAngles( const QAngle &angles );
+ void SetQuaternion( const Quaternion &q );
+ void SetNormal( const Vector &normal );
+ void SetPosWithNormalOffset( const Vector &pos, const Vector &normal );
+ void SetOnWorld( bool bOnWorld = true );
+
+ bool IsActive( void );
+ void IKFailed( void );
+ int chain;
+ int type;
+ void MoveReferenceFrame( Vector &deltaPos, QAngle &deltaAngles );
+ // accumulated offset from ideal footplant location
+public:
+ struct x2 {
+ char *pAttachmentName;
+ Vector pos;
+ Quaternion q;
+ } offset;
+private:
+ struct x3 {
+ Vector pos;
+ Quaternion q;
+ } ideal;
+public:
+ struct x4 {
+ float latched;
+ float release;
+ float height;
+ float floor;
+ float radius;
+ float flTime;
+ float flWeight;
+ Vector pos;
+ Quaternion q;
+ bool onWorld;
+ } est; // estimate contact position
+ struct x5 {
+ float hipToFoot; // distance from hip
+ float hipToKnee; // distance from hip to knee
+ float kneeToFoot; // distance from knee to foot
+ Vector hip; // location of hip
+ Vector closest; // closest valid location from hip to foot that the foot can move to
+ Vector knee; // pre-ik location of knee
+ Vector farthest; // farthest valid location from hip to foot that the foot can move to
+ Vector lowest; // lowest position directly below hip that the foot can drop to
+ } trace;
+private:
+ // internally latched footset, position
+ struct x1 {
+ // matrix3x4_t worldTarget;
+ bool bNeedsLatch;
+ bool bHasLatch;
+ float influence;
+ int iFramecounter;
+ int owner;
+ Vector absOrigin;
+ QAngle absAngles;
+ Vector pos;
+ Quaternion q;
+ Vector deltaPos; // acculated error
+ Quaternion deltaQ;
+ Vector debouncePos;
+ Quaternion debounceQ;
+ } latched;
+ struct x6 {
+ float flTime; // time last error was detected
+ float flErrorTime;
+ float ramp;
+ bool bInError;
+ } error;
+
+ friend class CIKContext;
+};
+
+
+struct ikchainresult_t
+{
+ // accumulated offset from ideal footplant location
+ int target;
+ Vector pos;
+ Quaternion q;
+ float flWeight;
+};
+
+
+
+struct ikcontextikrule_t
+{
+ int index;
+
+ int type;
+ int chain;
+
+ int bone;
+
+ int slot; // iktarget slot. Usually same as chain.
+ float height;
+ float radius;
+ float floor;
+ Vector pos;
+ Quaternion q;
+
+ float start; // beginning of influence
+ float peak; // start of full influence
+ float tail; // end of full influence
+ float end; // end of all influence
+
+ float top;
+ float drop;
+
+ float commit; // frame footstep target should be committed
+ float release; // frame ankle should end rotation from latched orientation
+
+ float flWeight; // processed version of start-end cycle
+ float flRuleWeight; // blending weight
+ float latched; // does the IK rule use a latched value?
+ char *szLabel;
+
+ Vector kneeDir;
+ Vector kneePos;
+
+ ikcontextikrule_t() {}
+
+private:
+ // No copy constructors allowed
+ ikcontextikrule_t(const ikcontextikrule_t& vOther);
+};
+
+
+void Studio_AlignIKMatrix( matrix3x4_t &mMat, const Vector &vAlignTo );
+
+bool Studio_SolveIK( int iThigh, int iKnee, int iFoot, Vector &targetFoot, matrix3x4_t* pBoneToWorld );
+
+bool Studio_SolveIK( int iThigh, int iKnee, int iFoot, Vector &targetFoot, Vector &targetKneePos, Vector &targetKneeDir, matrix3x4_t* pBoneToWorld );
+
+
+
+class CIKContext
+{
+public:
+ CIKContext( );
+ void Init( const CStudioHdr *pStudioHdr, const QAngle &angles, const Vector &pos, float flTime, int iFramecounter, int boneMask );
+ void AddDependencies( mstudioseqdesc_t &seqdesc, int iSequence, float flCycle, const float poseParameters[], float flWeight = 1.0f );
+
+ void ClearTargets( void );
+ void UpdateTargets( Vector pos[], Quaternion q[], matrix3x4_t boneToWorld[], CBoneBitList &boneComputed );
+ void AutoIKRelease( void );
+ void SolveDependencies( Vector pos[], Quaternion q[], matrix3x4_t boneToWorld[], CBoneBitList &boneComputed );
+
+ void AddAutoplayLocks( Vector pos[], Quaternion q[] );
+ void SolveAutoplayLocks( Vector pos[], Quaternion q[] );
+
+ void AddSequenceLocks( mstudioseqdesc_t &SeqDesc, Vector pos[], Quaternion q[] );
+ void SolveSequenceLocks( mstudioseqdesc_t &SeqDesc, Vector pos[], Quaternion q[] );
+
+ void AddAllLocks( Vector pos[], Quaternion q[] );
+ void SolveAllLocks( Vector pos[], Quaternion q[] );
+
+ void SolveLock( const mstudioiklock_t *plock, int i, Vector pos[], Quaternion q[], matrix3x4_t boneToWorld[], CBoneBitList &boneComputed );
+
+ CUtlVectorFixed< CIKTarget, 12 > m_target;
+
+private:
+
+ CStudioHdr const *m_pStudioHdr;
+
+ bool Estimate( int iSequence, float flCycle, int iTarget, const float poseParameter[], float flWeight = 1.0f );
+ void BuildBoneChain( const Vector pos[], const Quaternion q[], int iBone, matrix3x4_t *pBoneToWorld, CBoneBitList &boneComputed );
+
+ // virtual IK rules, filtered and combined from each sequence
+ CUtlVector< CUtlVector< ikcontextikrule_t > > m_ikChainRule;
+ CUtlVector< ikcontextikrule_t > m_ikLock;
+ matrix3x4_t m_rootxform;
+
+ int m_iFramecounter;
+ float m_flTime;
+ int m_boneMask;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+
+// replaces the bonetoworld transforms for all bones that are procedural
+bool CalcProceduralBone(
+ const CStudioHdr *pStudioHdr,
+ int iBone,
+ CBoneAccessor &bonetoworld
+ );
+
+void Studio_BuildMatrices(
+ const CStudioHdr *pStudioHdr,
+ const QAngle& angles,
+ const Vector& origin,
+ const Vector pos[],
+ const Quaternion q[],
+ int iBone,
+ float flScale,
+ matrix3x4_t bonetoworld[MAXSTUDIOBONES],
+ int boneMask
+ );
+
+
+// Get a bone->bone relative transform
+void Studio_CalcBoneToBoneTransform( const CStudioHdr *pStudioHdr, int inputBoneIndex, int outputBoneIndex, matrix3x4_t &matrixOut );
+
+// Given a bone rotation value, figures out the value you need to give to the controller
+// to have the bone at that value.
+// [in] flValue = the desired bone rotation value
+// [out] ctlValue = the (0-1) value to set the controller t.
+// return value = flValue, unwrapped to lie between the controller's start and end.
+float Studio_SetController( const CStudioHdr *pStudioHdr, int iController, float flValue, float &ctlValue );
+
+
+// Given a 0-1 controller value, maps it into the controller's start and end and returns the bone rotation angle.
+// [in] ctlValue = value in controller space (0-1).
+// return value = value in bone space
+float Studio_GetController( const CStudioHdr *pStudioHdr, int iController, float ctlValue );
+
+void Studio_CalcDefaultPoseParameters( const CStudioHdr *pStudioHdr, float flPoseParameter[MAXSTUDIOPOSEPARAM], int nCount );
+float Studio_GetPoseParameter( const CStudioHdr *pStudioHdr, int iParameter, float ctlValue );
+float Studio_SetPoseParameter( const CStudioHdr *pStudioHdr, int iParameter, float flValue, float &ctlValue );
+
+// converts a global 0..1 pose parameter into the local sequences blending value
+void Studio_LocalPoseParameter( const CStudioHdr *pStudioHdr, const float poseParameter[], mstudioseqdesc_t &seqdesc, int iSequence, int iLocalIndex, float &flSetting, int &index );
+
+void Studio_SeqAnims( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int iSequence, const float poseParameter[], mstudioanimdesc_t *panim[4], float *weight );
+int Studio_MaxFrame( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] );
+float Studio_FPS( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] );
+float Studio_CPS( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int iSequence, const float poseParameter[] );
+float Studio_Duration( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] );
+void Studio_MovementRate( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], Vector *pVec );
+
+// void Studio_Movement( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], Vector *pVec );
+
+//void Studio_AnimPosition( mstudioanimdesc_t *panim, float flCycle, Vector &vecPos, Vector &vecAngle );
+//void Studio_AnimVelocity( mstudioanimdesc_t *panim, float flCycle, Vector &vecVelocity );
+//float Studio_FindAnimDistance( mstudioanimdesc_t *panim, float flDist );
+bool Studio_AnimMovement( mstudioanimdesc_t *panim, float flCycleFrom, float flCycleTo, Vector &deltaPos, QAngle &deltaAngle );
+bool Studio_SeqMovement( const CStudioHdr *pStudioHdr, int iSequence, float flCycleFrom, float flCycleTo, const float poseParameter[], Vector &deltaMovement, QAngle &deltaAngle );
+bool Studio_SeqVelocity( const CStudioHdr *pStudioHdr, int iSequence, float flCycle, const float poseParameter[], Vector &vecVelocity );
+float Studio_FindSeqDistance( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], float flDist );
+float Studio_FindSeqVelocity( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], float flVelocity );
+int Studio_FindAttachment( const CStudioHdr *pStudioHdr, const char *pAttachmentName );
+int Studio_FindRandomAttachment( const CStudioHdr *pStudioHdr, const char *pAttachmentName );
+int Studio_BoneIndexByName( const CStudioHdr *pStudioHdr, const char *pName );
+const char *Studio_GetDefaultSurfaceProps( CStudioHdr *pstudiohdr );
+float Studio_GetMass( CStudioHdr *pstudiohdr );
+const char *Studio_GetKeyValueText( const CStudioHdr *pStudioHdr, int iSequence );
+
+FORWARD_DECLARE_HANDLE( memhandle_t );
+struct bonecacheparams_t
+{
+ CStudioHdr *pStudioHdr;
+ matrix3x4_t *pBoneToWorld;
+ float curtime;
+ int boneMask;
+};
+
+class CBoneCache
+{
+public:
+
+ // you must implement these static functions for the ResourceManager
+ // -----------------------------------------------------------
+ static CBoneCache *CreateResource( const bonecacheparams_t ¶ms );
+ static unsigned int EstimatedSize( const bonecacheparams_t ¶ms );
+ // -----------------------------------------------------------
+ // member functions that must be present for the ResourceManager
+ void DestroyResource();
+ CBoneCache *GetData() { return this; }
+ unsigned int Size() { return m_size; }
+ // -----------------------------------------------------------
+
+ CBoneCache();
+
+ // was constructor, but placement new is messy wrt memdebug - so cast & init instead
+ void Init( const bonecacheparams_t ¶ms, unsigned int size, short *pStudioToCached, short *pCachedToStudio, int cachedBoneCount );
+
+ void UpdateBones( const matrix3x4_t *pBoneToWorld, int numbones, float curtime );
+ matrix3x4_t *GetCachedBone( int studioIndex );
+ void ReadCachedBones( matrix3x4_t *pBoneToWorld );
+ void ReadCachedBonePointers( matrix3x4_t **bones, int numbones );
+
+ bool IsValid( float curtime, float dt = 0.1f );
+
+public:
+ float m_timeValid;
+ int m_boneMask;
+
+private:
+ matrix3x4_t *BoneArray();
+ short *StudioToCached();
+ short *CachedToStudio();
+
+ unsigned int m_size;
+ unsigned short m_cachedBoneCount;
+ unsigned short m_matrixOffset;
+ unsigned short m_cachedToStudioOffset;
+ unsigned short m_boneOutOffset;
+};
+
+CBoneCache *Studio_GetBoneCache( memhandle_t cacheHandle );
+memhandle_t Studio_CreateBoneCache( bonecacheparams_t ¶ms );
+void Studio_DestroyBoneCache( memhandle_t cacheHandle );
+void Studio_InvalidateBoneCache( memhandle_t cacheHandle );
+
+// Given a ray, trace for an intersection with this studiomodel. Get the array of bones from StudioSetupHitboxBones
+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 );
+
+void QuaternionSM( float s, const Quaternion &p, const Quaternion &q, Quaternion &qt );
+void QuaternionMA( const Quaternion &p, float s, const Quaternion &q, Quaternion &qt );
+
+bool Studio_PrefetchSequence( const CStudioHdr *pStudioHdr, int iSequence );
+
+#endif // BONE_SETUP_H
|