mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-09-19 12:06:07 +08:00
First version of the SOurce SDK 2013
This commit is contained in:
447
public/bone_setup.h
Normal file
447
public/bone_setup.h
Normal file
@ -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
|
Reference in New Issue
Block a user