//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #ifndef BONE_SETUP_PS3_H #define BONE_SETUP_PS3_H #ifndef __SPU__ #include "studio.h" #endif #include "studio_PS3.h" #ifndef __SPU__ #include "bone_setup.h" #include "vjobs/root.h" #include "vjobs/accumpose_shared.h" #include #include #include #endif // __SPU__ #if defined( _PS3 ) #if defined(__SPU__) #include "ps3/spu_job_shared.h" #define SNPROF(name) ((void)0) #define SNPROF_ANIM(name) ((void)0) #endif //#define _DEBUG_SPUvPPU_ANIMATION 1 #define ANIM_EPS 0.3f //----------------------------------------------------------------------------- // Purpose: SPU version of data collected and required by AccumulatePose // this data gets sent to SPU //----------------------------------------------------------------------------- #define MAX_ACCUMPOSECALLS (20) //(MAX_OVERLAYS) #define MAX_LAYERS_SPU MAX_ACCUMPOSECALLS #define MAX_PQSTACKLEVEL 4 #define MAX_IKCHAINELEMENTS 32 #define MAX_IKCHAINS 16 #define MAX_IKLOCKS 16 #define MAX_IKRULES 48 #define MAX_IKTARGETS 12 #define MAX_BLENDANIMS 4 class CBoneBitList_PS3 { public: CBoneBitList_PS3() { memset( &m_markedBones, 0, MAXSTUDIOBONES_PS3 ); } inline void MarkBone( int iBone ) { m_markedBones[ iBone ] = 1; } inline bool IsBoneMarked( int iBone ) { return m_markedBones[ iBone ]; } inline void ResetMarkedBones( int numbones ) { memset( &m_markedBones, 0, numbones ); } byte m_markedBones[ MAXSTUDIOBONES_PS3 ]; }; struct animData_SPU { void *pEA_animdesc; // mstudioanimdesc_t * int animstudiohdr_numbones; int seqdesc_anim; float flStall; float seqdesc_weight; int animdesc_iLocalFrame; void *pEA_animdesc_panim; // mstudio_rle_anim_t * void *pEA_animdesc_pFrameanim; // mstudio_frame_anim_t_PS3 * void *pEA_animdesc_ikrule; // mstudioikrule_t_PS3 * void *pEA_animdesc_ikrulezeroframe; // zero frame rule of above void *pEA_animgroup_masterbone; // int * void *pEA_anim_bones_pos; // Vector *, start of Vector pos, Quaternion quat, RadianEuler rot, Vector posscale, Vector rotscale, matrix3x4_t poseToBone, Quaternion qAlignment, int flags void *pEA_anim_bones_flags; // int *, start of flags void *pEA_anim_linearBones; // mstudiolinearbone_t_PS3 * }; struct ALIGN128 accumposeentry_SPU { void *pEA_seqdesc; // mstudioseqdesc_t_PS3 * void *pEA_seqgroup_boneMap; // const int * void *pEA_seqgroup_masterBone; // const int * void *pEA_seqdesc_boneWeight; // float * void *pEA_seqdesc_iklocks; // mstudioiklock_t * // from seqstudiohdr void *pEA_seq_linearBones; // mstudiolinearbone_t_PS3 * void *pEA_seq_linearbones_pos; // Vector * void *pEA_seq_linearbones_quat; // Quaternion * void *pEA_seq_bones_pos; // mstudiobone_t_PS3 * offset to .pos int seqdesc_flags; int cpsPath; // CalcPoseSingle path animData_SPU anims[ MAX_BLENDANIMS ]; int8 animIndices[ MAX_BLENDANIMS ]; // index into anims[] int pqStackLevel; int iSeq; float cycle; float weight; int i0; int i1; int seqdesc_numiklocks; int seqdesc_numikrules; float s0; float s1; float cyclePoseSingle; int numLocalLayers; int numSequenceLayers; #if !defined(__SPU__) bool SetAnimData( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int x, int y, int animIndex ); #endif } ALIGN128_POST; struct ALIGN128 bonejob_SPU { accumposeentry_SPU accumPoseEntry[ MAX_LAYERS_SPU ]; int numTotalPoses; int numPoses_PreAutoSeq; int numPoses_AutoSeq; // same for all calls int boneFlags[ MAXSTUDIOBONES_PS3 ]; // 1k int boneParent[ MAXSTUDIOBONES_PS3 ]; // 1k float poseparam[ MAXSTUDIOPOSEPARAM_PS3 ]; // 96B void *pEA_IKAutoplayLocks[ MAX_IKLOCKS ]; // mstudioiklock_t float currentTime; int numBones; int maxBones; // takes into account virtual bonemapping, used for SPU mem worst-case allocations int numikchains; int boneMask; int studiobone_posoffset; // mstudiobone_t offset in bytes to pos field BoneVector autoikOrigin; QAngle autoikAngles; int autoikFramecount; int numikAutoplayLocks; void *pEA_hdr; // CStudioHdr* void *pEA_IKContext; // CIKContext * void *pEA_studiohdr_ikchains; // mstudioikchain_t * void *pEA_studiohdr_ikautoplaylocks; // mstudioiklock_t * void *pEA_studiohdr_vmodel; // virtualmodel_t * void *pEA_studiohdr_bones; // mstudiobone_t_PS3 * void *pEA_studiohdr_bones_pos; // Vector *, start of Vector pos, Quaternion quat, RadianEuler rot, Vector posscale, Vector rotscale, matrix3x4_t poseToBone, Quaternion qAlignment, int flags void *pEA_studiohdr_linearBones; // mstudiolinearbone_t_PS3 * void *pEA_linearbones_posscale; // Vector * void *pEA_linearbones_pos; // Vector * void *pEA_linearbones_rot; // RadianEuler * void *pEA_linearbones_rotscale; // Vector * void *pEA_linearbones_flags; // int * void *pEA_linearbones_quat; // Quaternion * void *pEA_linearbones_qalignment; // Quaternion * // dst data ea ptrs void *pEA_pos; // BoneVector * void *pEA_q; // BoneQuaternion * void *pEA_addDep_IKRules; // ikcontextikrule_t * void *pEA_addDep_numIKRules; // int * void *pEA_flags; // int * int debugJob; // for dynamic switching of DebuggerBreak } ALIGN128_POST; #if !defined(__SPU__) struct bonejob_PPU { public: matrix3x4_t parentTransform; float cycle; int maxBones; int boneMask; int bonesMaskNeedsRecalc; int oldReadableBones; void *pBaseAnimating; // C_BaseAnimating* CStudioHdr *pStudioHdr; matrix3x4a_t *pBoneToWorldOut; }; struct ALIGN128 PS3BoneJobData { public: job_accumpose::JobDescriptor_t jobDescriptor ALIGN128; // dst. SPU in/out - could be init'd entirely from SPU, in which case it's out only BoneVector pos[ MAXSTUDIOBONES_PS3 ] ALIGN16; // 2k BoneQuaternion q[ MAXSTUDIOBONES_PS3 ] ALIGN16; // 2k // dst, SPU out only ikcontextikrule_t addDep_IKRules[ MAX_IKRULES ] ALIGN16; // 4k int addDep_numIKRules ALIGN16; // [4] to pad to 16B int pad[3]; // src, SPU in only, going to SPU at start of job bonejob_SPU bonejobSPU; // src, PPU only, work data, and data required if job needs to be executed from scratch on PPU if SPU fails bonejob_PPU bonejobPPU; } ALIGN128_POST; class CBoneJobs : public VJobInstance { public: CBoneJobs() { } ~CBoneJobs() { Shutdown(); } void Init( void ); void Shutdown( void ); void OnVjobsInit( void ); // gets called after m_pRoot was created and assigned void OnVjobsShutdown( void ); // gets called before m_pRoot is about to be destructed and NULL'ed void StartFrame( int maxBoneJobs ); void EndFrame( void ); void ResetBoneJobs( void ); int AddBoneJob( void ); int GetNumBoneJobs( void ); int GetNextFreeSPURSPort( void ); PS3BoneJobData *GetJobData( int job ); private: CUtlVector m_boneJobData; int m_boneJobCount; int m_boneJobNextSPURSPort; bool m_bEnabled; }; extern CBoneJobs* g_pBoneJobs; #endif // #if !defined SPU //----------------------------------------------------------------------------- // // Main spu job class // //----------------------------------------------------------------------------- class C_AccumulatePose_SPU { public: C_AccumulatePose_SPU( bonejob_SPU *pBoneJob ) { m_pBoneJob = pBoneJob; }; inline void ResetCount() { m_iCount = 0; }; inline int GetCount() { return m_iCount; }; void AccumulatePose( BoneVector pos[], BoneQuaternion q[] ); void AddLocalLayers( accumposeentry_SPU *pAccPoseEntry, BoneVector pos[], BoneQuaternion q[] ); void AddSequenceLayers( accumposeentry_SPU *pAccPoseEntry, BoneVector pos[], BoneQuaternion q[] ); void SetIKContext( void *pIKContext ) { m_pIKContext = pIKContext; }; void *GetIKContext( void ) { return m_pIKContext; }; private: bool CalcPoseSingle( const bonejob_SPU *pBonejob, accumposeentry_SPU *pPoseEntry, BoneVector *pos, BoneQuaternion *q, int *boneMap, float *boneWeight, int sequence, const float poseParameter[], int boneMask, float flTime ); void *m_pIKContext; // CIKContext * bonejob_SPU *m_pBoneJob; // next index into bonejob accumposeentry to execute int m_iCount; }; //----------------------------------------------------------------------------- // 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_SPU( bonejob_SPU* pSPUJob, accumposeentry_SPU *pPoseEntry, BoneQuaternion *q1, BoneVector *pos1, const BoneQuaternion *q2, const BoneVector *pos2, const int *boneMap, const float *boneWeight, float s, int boneMask ); #if !defined(__SPU__) class CBoneSetup_PS3; class IBoneSetup_PS3 { public: IBoneSetup_PS3( const CStudioHdr *pStudioHdr, int boneMask, const float poseParameter[], bonejob_SPU *pBoneJobSPU ); ~IBoneSetup_PS3( void ); void InitPose_PS3( BoneVector pos[], BoneQuaternion q[] ); void CalcAutoplaySequences_AddPoseCalls( float flRealTime ); void AccumulatePose_AddToBoneJob( bonejob_SPU* pBonejobSPU, int sequence, float cycle, float flWeight, CIKContext *pIKContext, int pqStackLevel ); int RunAccumulatePoseJobs_PPU( bonejob_SPU *pBoneJobSPU ); int RunAccumulatePoseJobs_SPU( bonejob_SPU *pBoneJobSPU, job_accumpose::JobDescriptor_t *pJobDescriptor ); CStudioHdr *GetStudioHdr(); void ResetErrorFlags(); int ErrorFlags(); bonejob_SPU *GetBoneJobSPU(); private: CBoneSetup_PS3 *m_pBoneSetup; }; #endif // 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_PS3( // CStudioHdr_PS3 *pOwnerHdr, // int nSequence, // int iFrame, // int iBone, // matrix3x4_t &mBoneLocal ); // Purpose: build boneToWorld transforms for a specific bone void BuildBoneChain_PS3( const int *pBoneParent, const matrix3x4a_t &rootxform, const BoneVector pos[], const BoneQuaternion q[], int iBone, matrix3x4a_t *pBoneToWorld ); void BuildBoneChain_PS3( const int *pBoneParent, const matrix3x4a_t &rootxform, const BoneVector pos[], const BoneQuaternion q[], int iBone, matrix3x4a_t *pBoneToWorld, CBoneBitList_PS3 &boneComputed ); //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- // ik info class CIKTarget_PS3 { 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 { // matrix3x4a_t worldTarget; bool bNeedsLatch; bool bHasLatch; float influence; int iFramecounter; int owner; Vector absOrigin; QAngle absAngles; Vector pos; Quaternion q; Vector deltaPos; // accumulated 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_PS3; }; struct ikchainresult_t_PS3 { // accumulated offset from ideal footplant location int target; Vector pos; Quaternion q; float flWeight; }; struct ikcontextikrule_t_PS3 { int index; int type; int chain; int bone; int slot; // iktarget slot. Usually same as chain. float height; float radius; float floor; Vector pos; float pad1; 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; float pad2; Vector kneePos; float pad3; ikcontextikrule_t_PS3() {} private: // No copy constructors allowed ikcontextikrule_t_PS3(const ikcontextikrule_t_PS3& vOther); }; void Studio_AlignIKMatrix_PS3( matrix3x4a_t &mMat, const Vector &vAlignTo ); bool Studio_SolveIK_PS3( int8 iThigh, int8 iKnee, int8 iFoot, Vector &targetFoot, matrix3x4a_t* pBoneToWorld ); bool Studio_SolveIK_PS3( int8 iThigh, int8 iKnee, int8 iFoot, Vector &targetFoot, Vector &targetKneePos, Vector &targetKneeDir, matrix3x4a_t* pBoneToWorld ); class CIKContext_PS3 { public: CIKContext_PS3( ); // void Init( const CStudioHdr *pStudioHdr, const QAngle &angles, const BoneVector &pos, float flTime, int iFramecounter, int boneMask ); void Init( bonejob_SPU *pBonejobSPU, const QAngle &angles, const Vector &pos, float flTime, int iFramecounter, int boneMask ); // void AddDependencies( mstudioseqdesc_t_PS3 &seqdesc, int iSequence, float flCycle, const float poseParameters[], float flWeight = 1.0f ); void ClearTargets( void ); // void UpdateTargets( Vector pos[], Quaternion q[], matrix3x4a_t boneToWorld[], CBoneBitList &boneComputed ); // void AutoIKRelease( void ); void AddAutoplayLocks( bonejob_SPU *pBonejob, BoneVector pos[], BoneQuaternion q[] ); void SolveAutoplayLocks( bonejob_SPU *pBonejob, BoneVector pos[], BoneQuaternion q[] ); // void AddSequenceLocks( mstudioseqdesc_t &SeqDesc, BoneVector pos[], BoneQuaternion q[] ); void AddSequenceLocks( bonejob_SPU *pBonejob, accumposeentry_SPU* pPoseEntry, BoneVector pos[], BoneQuaternion q[] ); void SolveSequenceLocks( bonejob_SPU *pBonejob, accumposeentry_SPU* pPoseEntry, BoneVector pos[], BoneQuaternion q[] ); // void AddAllLocks( BoneVector pos[], BoneQuaternion q[] ); // void SolveAllLocks( BoneVector pos[], BoneQuaternion q[] ); void SolveLock( bonejob_SPU *pBonejob, const mstudioiklock_t_PS3 *plock, int i, BoneVector pos[], BoneQuaternion q[], matrix3x4a_t boneToWorld[], CBoneBitList_PS3 &boneComputed ); // CUtlVectorFixed< CIKTarget, 12 > m_target; CIKTarget_PS3 m_target[ 12 ]; int m_targetCount; int m_numTarget; private: // CStudioHdr const *m_pStudioHdr; // // bool Estimate( int iSequence, float flCycle, int iTarget, const float poseParameter[], float flWeight = 1.0f ); void BuildBoneChain( const bonejob_SPU *pBonejob, const BoneVector pos[], const BoneQuaternion q[], int iBone, matrix3x4a_t *pBoneToWorld, CBoneBitList_PS3 &boneComputed ); // // // virtual IK rules, filtered and combined from each sequence // CUtlVector< CUtlVector< ikcontextikrule_t_PS3 > > m_ikChainRule; // CUtlVector< ikcontextikrule_t_PS3 > m_ikLock; ikcontextikrule_t_PS3 m_ikLock[ MAX_IKLOCKS ]; matrix3x4a_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_PS3( // const CStudioHdr_PS3 *pStudioHdr, // int iBone, // CBoneAccessor_PS3 &bonetoworld // ); // void Studio_BuildMatrices( // const CStudioHdr_PS3 *pStudioHdr, // const QAngle& angles, // const BoneVector& origin, // const BoneVector pos[], // const BoneQuaternion q[], // int iBone, // float flScale, // matrix3x4a_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 //int Studio_LocalPoseParameter( const CStudioHdr *pStudioHdr, const float poseParameter[], mstudioseqdesc_t &seqdesc, int iSequence, int iLocalIndex, float &flSetting ); //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 ); //float Studio_SeqMovementAndDuration( const CStudioHdr *pStudioHdr, int iSequence, float flCycleFrom, float flCycleTo, const float poseParameter[], Vector &deltaPos ); // 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; // matrix3x4a_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 matrix3x4a_t *pBoneToWorld, int numbones, float curtime ); // matrix3x4a_t *GetCachedBone( int studioIndex ); // void ReadCachedBones( matrix3x4a_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: // matrix3x4a_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; // }; // // void Studio_LockBoneCache(); // void Studio_UnlockBoneCache(); // // CBoneCache *Studio_GetBoneCache( memhandle_t cacheHandle, bool bLock = false ); // void Studio_ReleaseBoneCache( memhandle_t cacheHandle ); // memhandle_t Studio_CreateBoneCache( bonecacheparams_t ¶ms ); // void Studio_DestroyBoneCache( memhandle_t cacheHandle ); // void Studio_InvalidateBoneCacheIfNotMatching( memhandle_t cacheHandle, float flTimeValid ); // 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 ); // TERROR: TraceToStudio variant that prioritizes hitgroups, so bullets can pass through arms and chest to hit the head, for instance // bool TraceToStudioGrouped( IPhysicsSurfaceProps *pProps, const Ray_t& ray, CStudioHdr *pStudioHdr, mstudiohitboxset_t *set, // matrix3x4_t **hitboxbones, int fContentsMask, trace_t &tr, const CUtlVector< int > &sortedHitgroups ); void QuaternionSM_PS3( float s, const Quaternion &p, const Quaternion &q, Quaternion &qt ); void QuaternionMA_PS3( const Quaternion &p, float s, const Quaternion &q, Quaternion &qt ); // // bool Studio_PrefetchSequence( const CStudioHdr *pStudioHdr, int iSequence ); // // void Studio_RunBoneFlexDrivers( float *pFlexController, const CStudioHdr *pStudioHdr, const Vector *pPositions, const matrix3x4_t *pBoneToWorld, const matrix3x4_t &mRootToWorld ); //----------------------------------------------------------------------------- // Computes a number of twist bones given a parent/child pair // pqTwists, pflWeights, pqTwistBinds must all have at least nCount elements //----------------------------------------------------------------------------- // void ComputeTwistBones( // Quaternion *pqTwists, // int nCount, // bool bInverse, // const Vector &vUp, // const Quaternion &qParent, // const matrix3x4_t &mChild, // const Quaternion &qBaseInv, // const float *pflWeights, // const Quaternion *pqTwistBinds ); //----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- // round up to next 16B boundary, then add 16B #define ROUNDUPTONEXT16B( a ) (0x10 + (a + (0x10 - (a%0x10)))) //----------------------------------------------------------------------------- // Squeezing memory for SPU - manual float and int allocs //----------------------------------------------------------------------------- #define LS_FLOATSTACK_SIZE ((MAXSTUDIOBONES_PS3 + 32) * 4 * 3 * 3) // 24k #define LS_INTSTACK_SIZE ((MAXSTUDIOBONES_PS3 * 2) + 16) // 1k extern ALIGN16 byte g_ls_Stack[ (LS_FLOATSTACK_SIZE * sizeof(float)) + (LS_INTSTACK_SIZE * sizeof(int)) ]; extern byte *g_ls_StackPtr; extern byte *g_ls_StackPtr_MAX; // init when starting Job FORCEINLINE void InitLSStack() { g_ls_StackPtr = g_ls_Stack; } // term when exiting Job FORCEINLINE void TermLSStack() { #if !defined( _CERT ) // ensure pop'd to start if( g_ls_StackPtr != g_ls_Stack ) { Msg("*** IMPROPER LS STACK ON TERM ***\n"); Msg("*** IMPROPER LS STACK ON TERM ***\n"); Msg("*** IMPROPER LS STACK ON TERM ***\n"); Msg("*** IMPROPER LS STACK ON TERM ***\n"); DebuggerBreak(); } #endif // float watermark // Msg("LS stack - high: %d, max: %d\n", (int)(g_ls_StackPtr_MAX - g_ls_Stack), (int)sizeof(g_ls_Stack) ); } // keep it simple, ensure allocation is multiple of 16B to keep vectors aligned // size is number of bytes FORCEINLINE byte *PushLSStack( int size ) { byte *pStack = g_ls_StackPtr; g_ls_StackPtr += ROUNDUPTONEXT16B( size ); #if !defined( _CERT ) if( g_ls_StackPtr > (g_ls_Stack + sizeof(g_ls_Stack)) ) { Msg("*** EXCEEDED LS STACK ***\n"); Msg("*** EXCEEDED LS STACK ***\n"); Msg("*** EXCEEDED LS STACK ***\n"); Msg("*** EXCEEDED LS STACK ***\n"); DebuggerBreak(); } #endif // maintain watermark if( g_ls_StackPtr > g_ls_StackPtr_MAX ) { g_ls_StackPtr_MAX = g_ls_StackPtr; } return pStack; } FORCEINLINE void PopLSStack( int size ) { g_ls_StackPtr -= ROUNDUPTONEXT16B( size ); #if !defined( _CERT ) if( g_ls_StackPtr < g_ls_Stack ) { Msg("*** EXCEEDED LS STACK - POP ***\n"); Msg("*** EXCEEDED LS STACK - POP ***\n"); Msg("*** EXCEEDED LS STACK - POP ***\n"); Msg("*** EXCEEDED LS STACK - POP ***\n"); DebuggerBreak(); } #endif } // class CLSStack // { // public: // CLSStack( int size ) // { // ; // } // ~CLSStack() // { // ; // } // }; // // #define LSSTACK(size) CLSStack //----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- #if defined(__SPU__) extern BoneVector *g_posInit; extern BoneQuaternion *g_qInit; extern ikcontextikrule_t_PS3 *g_addDep_IKRules; extern int g_addDep_numIKRules; #else extern BoneVector g_posInit[ MAXSTUDIOBONES_PS3 ]; extern BoneQuaternion g_qInit[ MAXSTUDIOBONES_PS3 ]; extern ikcontextikrule_t_PS3 g_addDep_IKRules[ MAX_IKRULES ] ALIGN16; extern int g_addDep_numIKRules; #endif #endif // _PS3 #endif // BONE_SETUP_H