|
|
//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef BONE_UTILS_PS3_H
#define BONE_UTILS_PS3_H
#ifndef _PS3
#error "This header is for PS3 target only"
#endif
#include "vjobs_interface.h"
#if defined(__SPU__)
#include "ps3/spu_job_shared.h"
#include "cell/dma.h"
#endif
#if 1
#define DotProduct_PS3 DotProduct
#define MatrixAngles_PS3 MatrixAngles
#define VectorRotate_PS3 VectorRotate
#define VectorSubtract_PS3 VectorSubtract
#define MatrixPosition_PS3 MatrixPosition
#define _VMX_VectorNormalize_PS3 _VMX_VectorNormalize
#define VectorNormalize_PS3 VectorNormalize
#define VectorMultiply_PS3 VectorMultiply
#define VectorScale_PS3 VectorScale
#define VectorMAInline_PS3 VectorMAInline
#define VectorMA_PS3 VectorMA
#define SimpleSpline_PS3 SimpleSpline
#define ConcatTransforms_PS3 ConcatTransforms
#define ConcatTransforms_Aligned_PS3 ConcatTransforms_Aligned
//#define QuaternionMatrix_PS3 QuaternionMatrix
//#define QuaternionAlign_PS3 QuaternionAlign
//#define QuaternionSlerp_PS3 QuaternionSlerp
//#define QuaternionSlerpNoAlign_PS3 QuaternionSlerpNoAlign
//#define QuaternionNormalize_PS3 QuaternionNormalize
//#define QuaternionBlend_PS3 QuaternionBlend
//#define QuaternionBlendNoAlign_PS3 QuaternionBlendNoAlign
//#define QuaternionIdentityBlend_PS3 QuaternionIdentityBlend
//#define QuaternionScale_PS3 QuaternionScale
//#define QuaternionAdd_PS3 QuaternionAdd
//#define QuaternionDotProduct_PS3 QuaternionDotProduct
//#define QuaternionMult_PS3 QuaternionMult
#define MatrixSetColumn_PS3 MatrixSetColumn
#define MatrixGetColumn_PS3 MatrixGetColumn
#define MatrixInvert_PS3 MatrixInvert
#define VectorRotate_PS3 VectorRotate
#define AngleMatrix_PS3 AngleMatrix
#define AngleQuaternion_PS3 AngleQuaternion
#define Hermite_Spline_PS3 Hermite_Spline
#define Hermite_SplineBasis_PS3 Hermite_SplineBasis
#define SetIdentityMatrix_PS3 SetIdentityMatrix
FORCEINLINE Vector Lerp_PS3( float flPercent, Vector const &A, Vector const &B ) { return A + (B - A) * flPercent; } #endif
// from mathlib.h, mathlib_base.cpp
#if 0
FORCEINLINE float DotProduct_PS3(const Vector& a, const Vector& b) { // return( a.x*b.x + a.y*b.y + a.z*b.z );
return a.Dot(b); } FORCEINLINE float DotProduct_PS3(const float* a, const float* b) { return( a[0]*b[0] + a[1]*b[1] + a[2]*b[2] ); } void ConcatTransforms_PS3( const matrix3x4a_t &m0, const matrix3x4a_t &m1, matrix3x4a_t &out ); void ConcatTransforms_Aligned_PS3( const matrix3x4a_t &m0, const matrix3x4a_t &m1, matrix3x4a_t &out ); void MatrixAngles_PS3( const matrix3x4_t & matrix, float *angles ); // !!!!
void MatrixAngles_PS3( const matrix3x4_t& matrix, RadianEuler &angles, Vector &position ); void MatrixAngles_PS3( const matrix3x4_t &matrix, Quaternion &q, Vector &pos ); inline void MatrixAngles_PS3( const matrix3x4_t &matrix, RadianEuler &angles ) { MatrixAngles_PS3( matrix, &angles.x );
angles.Init( DEG2RAD( angles.z ), DEG2RAD( angles.x ), DEG2RAD( angles.y ) ); } void MatrixGetColumn_PS3( const matrix3x4_t& in, int column, Vector &out ); void MatrixSetColumn_PS3( const Vector &in, int column, matrix3x4_t& out ); void MatrixInvert_PS3( const matrix3x4_t& in, matrix3x4_t& out ); void VectorRotate_PS3( const float *in1, const matrix3x4_t & in2, float *out); inline void VectorRotate_PS3( const Vector& in1, const matrix3x4_t &in2, Vector &out) { VectorRotate_PS3( &in1.x, in2, &out.x ); } FORCEINLINE void VectorSubtract_PS3( const Vector& a, const Vector& b, Vector& c ) { c.x = a.x - b.x; c.y = a.y - b.y; c.z = a.z - b.z; } inline void MatrixPosition_PS3( const matrix3x4_t &matrix, Vector &position ) { position[0] = matrix[0][3]; position[1] = matrix[1][3]; position[2] = matrix[2][3]; } FORCEINLINE float _VMX_VectorNormalize_PS3( Vector &vec ) { vec_float4 vIn; vec_float4 v0, v1; vector unsigned char permMask; v0 = vec_ld( 0, vec.Base() ); permMask = vec_lvsl( 0, vec.Base() ); v1 = vec_ld( 11, vec.Base() ); vIn = vec_perm(v0, v1, permMask); float mag = vmathV3Length((VmathVector3 *)&vIn); float den = 1.f / (mag + FLT_EPSILON ); vec.x *= den; vec.y *= den; vec.z *= den; return mag; } FORCEINLINE float VectorNormalize_PS3( Vector& v ) { return _VMX_VectorNormalize_PS3( v ); }
FORCEINLINE void VectorMultiply_PS3( const Vector& a, float b, Vector& c ) { c.x = a.x * b; c.y = a.y * b; c.z = a.z * b; }
FORCEINLINE void VectorMultiply_PS3( const Vector& a, const Vector& b, Vector& c ) { c.x = a.x * b.x; c.y = a.y * b.y; c.z = a.z * b.z; }
inline void VectorScale_PS3 ( const Vector& in, float scale, Vector& result ) { VectorMultiply_PS3( in, scale, result ); } FORCEINLINE Vector Lerp_PS3( float flPercent, Vector const &A, Vector const &B ) { return A + (B - A) * flPercent; } FORCEINLINE void VectorMAInline_PS3( const float* start, float scale, const float* direction, float* dest ) { dest[0]=start[0]+direction[0]*scale; dest[1]=start[1]+direction[1]*scale; dest[2]=start[2]+direction[2]*scale; } FORCEINLINE void VectorMAInline_PS3( const Vector& start, float scale, const Vector& direction, Vector& dest ) { dest.x=start.x+direction.x*scale; dest.y=start.y+direction.y*scale; dest.z=start.z+direction.z*scale; } FORCEINLINE void VectorMA_PS3( const Vector& start, float scale, const Vector& direction, Vector& dest ) { VectorMAInline_PS3(start, scale, direction, dest); } FORCEINLINE void VectorMA_PS3( const float * start, float scale, const float *direction, float *dest ) { VectorMAInline_PS3(start, scale, direction, dest); } void AngleMatrix_PS3( RadianEuler const &angles, const Vector &position, matrix3x4_t& matrix ); void AngleMatrix_PS3( const RadianEuler& angles, matrix3x4_t& matrix ); void AngleMatrix_PS3( const QAngle &angles, const Vector &position, matrix3x4_t& matrix ); void AngleMatrix_PS3( const QAngle &angles, matrix3x4_t& matrix ); void AngleQuaternion_PS3( const RadianEuler &angles, Quaternion &outQuat ); void Hermite_Spline_PS3( const Vector &p1, const Vector &p2, const Vector &d1, const Vector &d2, float t, Vector& output ); float Hermite_Spline_PS3( float p1, float p2, float d1, float d2, float t ); void Hermite_SplineBasis_PS3( float t, float basis[4] ); void Hermite_Spline_PS3( const Vector &p0, const Vector &p1, const Vector &p2, float t, Vector& output ); float Hermite_Spline_PS3( float p0, float p1, float p2, float t ); void Hermite_Spline_PS3( const Quaternion &q0, const Quaternion &q1, const Quaternion &q2, float t, Quaternion &output ); inline float SimpleSpline_PS3( float value ) { float valueSquared = value * value;
// Nice little ease-in, ease-out spline-like curve
return (3.0f * valueSquared - 2.0f * valueSquared * value); } #endif
void QuaternionMatrix_PS3( const Quaternion &q, const Vector &pos, matrix3x4a_t& matrix ); void QuaternionAlign_PS3( const Quaternion &p, const Quaternion &q, QuaternionAligned &qt ); void QuaternionSlerp_PS3( const Quaternion &p, const Quaternion &q, float t, Quaternion &qt ); void QuaternionSlerpNoAlign_PS3( const Quaternion &p, const Quaternion &q, float t, Quaternion &qt ); float QuaternionNormalize_PS3( Quaternion &q ); void QuaternionBlend_PS3( const Quaternion &p, const Quaternion &q, float t, Quaternion &qt ); void QuaternionBlendNoAlign_PS3( const Quaternion &p, const Quaternion &q, float t, Quaternion &qt ); void QuaternionIdentityBlend_PS3( const Quaternion &p, float t, Quaternion &qt ); void QuaternionScale_PS3( const Quaternion &p, float t, Quaternion &q ); void QuaternionAdd_PS3( const Quaternion &p, const Quaternion &q, Quaternion &qt ); float QuaternionDotProduct_PS3( const Quaternion &p, const Quaternion &q ); void QuaternionMult_PS3( const Quaternion &p, const Quaternion &q, Quaternion &qt );
void AddDependencies_SPU( bonejob_SPU *pBonejobSPU, accumposeentry_SPU *pPoseEntry, float flWeight = 1.0f ); //void AddDependencies_PPU( CStudioHdr *pHdr, float m_flTime, int m_boneMask, mstudioseqdesc_t &seqdesc, int iSequence, float flCycle, const float poseParameters[], float flWeight );
void GetBoneMapBoneWeight_SPU( bonejob_SPU *pSPUJob, accumposeentry_SPU *pPoseEntry, int *&pLS_boneMap, float *&pLS_boneWeight );
void CalcDecompressedAnimation_PS3( void *pEA_Compressed, const mstudiocompressedikerror_t_PS3 *pLS_Compressed, int iFrame, float fraq, BoneVector &pos, BoneQuaternion &q ); void QuaternionAccumulate_PS3( const Quaternion &p, float s, const Quaternion &q, Quaternion &qt ); void CalcAnimation_PS3( const bonejob_SPU *pBonejob, const accumposeentry_SPU *pPoseEntry, BoneVector *pos, BoneQuaternion *q, const int *boneMap, const float *boneWeight, int animIndex, float cycle, int boneMask ); void BlendBones_PS3( const bonejob_SPU *pBonejob, const accumposeentry_SPU *pPoseEntry, BoneQuaternion *q1, BoneVector *pos1, const int *boneMap, const float *boneWeight, const BoneQuaternion *q2, const BoneVector *pos2, float s, int boneMask ); void ScaleBones_PS3( const bonejob_SPU *pBonejob, const accumposeentry_SPU *pPoseEntry, BoneQuaternion *q1, BoneVector *pos1, const int *boneMap, const float *boneWeight, float s, int boneMask );
// void CalcPose( const CStudioHdr *pStudioHdr, CIKContext *pIKContext, Vector pos[], BoneQuaternion q[], int sequence, float cycle, const float poseParameter[], int boneMask, float flWeight = 1.0f, float flTime = 0.0f );
//bool CalcPoseSingle( const CStudioHdr *pStudioHdr, Vector pos[], BoneQuaternion q[], mstudioseqdesc_t &seqdesc, int sequence, float cycle, const float poseParameter[], int boneMask, float flTime );
// void CalcBoneAdj( const CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], const float controllers[], int boneMask );
void BuildBoneChainPartial_PS3( const int *pBoneParent, const matrix3x4a_t &rootxform, const BoneVector pos[], const BoneQuaternion q[], int iBone, matrix3x4a_t *pBoneToWorld, CBoneBitList_PS3 &boneComputed, int iRoot );
struct PS3BoneJobData;
#define BONEJOB_ERROR_EXCEEDEDPQSTACK (1<<0)
#define BONEJOB_ERROR_EXCEEDEDMAXCALLS (1<<1)
#define BONEJOB_ERROR_LOCALHIER (1<<2)
#if !defined(__SPU__)
class CBoneSetup_PS3 { public:
CBoneSetup_PS3( const CStudioHdr *pStudioHdr, int boneMask, const float poseParameter[], bonejob_SPU *pBoneJobSPU ); void CalcAutoplaySequences_AddPoseCalls( float flRealTime ); void AccumulatePose_AddToBoneJob( bonejob_SPU* pSPUJob, int sequence, float cycle, float flWeight, CIKContext *pIKContext, int pqStackLevel );
int RunAccumulatePoseJobs_PPU( bonejob_SPU *pBoneJob ); int RunAccumulatePoseJobs_SPU( bonejob_SPU *pBoneJob, job_accumpose::JobDescriptor_t *pJobDescriptor );
private:
bool SetAnimData( accumposeentry_SPU *pPoseEntry, const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int sequence, int x, int y, int animIndex, float weight );
bool CalcPoseSingle( accumposeentry_SPU *pPoseEntry, const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int sequence, float cycle, const float poseParameter[], float flTime );
int AddSequenceLayers( bonejob_SPU *pSPUJob, mstudioseqdesc_t &seqdesc, int sequence, float cycle, float flWeight, CIKContext *pIKContext, int pqStackLevel ); int AddLocalLayers( bonejob_SPU *pSPUJob, mstudioseqdesc_t &seqdesc, int sequence, float cycle, float flWeight, CIKContext *pIKContext, int pqStackLevel );
public:
const CStudioHdr *m_pStudioHdr; int m_boneMask; const float *m_flPoseParameter;
bonejob_SPU *m_pBoneJobSPU;
int m_errorFlags; // accpose call failure flags (if so do not run on SPU, could be for a number of reasons, right now => exceeded PQ stack, or an anim uses the local hierarchy path
};
#endif // #if !defined(__SPU__)
//-------------------------------------------------------------------------------------------------------------
// SPU dummy funcs
//-------------------------------------------------------------------------------------------------------------
#define DMATAG_ANIM_SYNC_BONEMAPWEIGHT (DMATAG_ANIM+1)
#define DMATAG_ANIM_SYNC_POSQ (DMATAG_ANIM+2)
FORCEINLINE void *SPUmemcpy_UnalignedGet( void *ls, uint32 ea, uint32_t size ) { void *aligned_ls;
aligned_ls = (void *)((uint32)ls | (ea & 0xf)); // + 0xf in case ls not 16B aligned
#if defined(__SPU__)
//spu_printf("GET ls:0x%x, ea:0x%x, size:%d\n", (uint32_t)aligned_ls, ea, size);
// SPU
cellDmaUnalignedGet( aligned_ls, ea, size, DMATAG_SYNC, 0, 0 ); cellDmaWaitTagStatusAny( 1 << DMATAG_SYNC ); #else
// PPU
memcpy( aligned_ls, (void *)ea, size ); #endif
return aligned_ls; }
FORCEINLINE void *SPUmemcpy_UnalignedGet_MustSync( void *ls, uint32 ea, uint32_t size, uint32_t dmatag ) { void *aligned_ls;
aligned_ls = (void *)((uint32)ls | (ea & 0xf)); // + 0xf in case ls not 16B aligned
#if defined(__SPU__)
//spu_printf("GET ls:0x%x, ea:0x%x, size:%d\n", (uint32_t)aligned_ls, ea, size);
// SPU
cellDmaUnalignedGet( aligned_ls, ea, size, dmatag, 0, 0 ); #else
// PPU
memcpy( aligned_ls, (void *)ea, size ); #endif
return aligned_ls; }
FORCEINLINE void SPUmemcpy_Sync( uint32_t dmatag ) { #if defined(__SPU__)
// cellDmaWaitTagStatusAll( 1 << dmatag );
cellDmaWaitTagStatusAll( dmatag ); #endif
}
FORCEINLINE void SPUmemcpy_UnalignedPut( void *ls, uint32 ea, uint32_t size ) { #if defined(__SPU__)
//spu_printf("PUT ls:0x%x, ea:0x%x, size:%d\n", (uint32_t)ls, ea, size);
// SPU
cellDmaUnalignedPut( ls, ea, size, DMATAG_SYNC, 0, 0 ); cellDmaWaitTagStatusAny( 1 << DMATAG_SYNC ); #else
Assert(((uint32)ls&0xf) == ea&0xf);
// PPU
memcpy( (void *)ea, ls, size ); #endif
}
//=============================================================================//
//
//
//
//
//
//=============================================================================//
#endif
|