360 lines
14 KiB
C++
360 lines
14 KiB
C++
//========= 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
|