Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1556 lines
45 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #include "mathlib/mathlib.h"
  9. #include "bone_setup_PS3.h"
  10. #include "bone_utils_PS3.h"
  11. //--------------------------------------------------------------------------------------------------------------------
  12. //
  13. // local data for a bone job
  14. //
  15. //--------------------------------------------------------------------------------------------------------------------
  16. #define CPSPATH_FALSE 0
  17. #define CPSPATH_CALCANIM1 1
  18. #define CPSPATH_CALCANIM1_SCALE1MINUSS0 2
  19. #define CPSPATH_CALCANIM1_SCALES0 3
  20. #define CPSPATH_CALCANIM2_S0 4
  21. #define CPSPATH_CALCANIM2_S1 5
  22. #define CPSPATH_CALCANIM3 6
  23. #define CPSPATH_CALCANIM4 7
  24. ALIGN16 byte g_ls_Stack[ (LS_FLOATSTACK_SIZE * sizeof(float)) + (LS_INTSTACK_SIZE * sizeof(int)) ];
  25. byte *g_ls_StackPtr;
  26. byte *g_ls_StackPtr_MAX;
  27. #if defined(__SPU__)
  28. BoneVector *g_posInit;
  29. BoneQuaternion *g_qInit;
  30. ikcontextikrule_t_PS3 *g_addDep_IKRules;
  31. int g_addDep_numIKRules;
  32. #else
  33. BoneVector g_posInit[ MAXSTUDIOBONES_PS3 ]; // 2k
  34. BoneQuaternion g_qInit[ MAXSTUDIOBONES_PS3 ]; // 2k
  35. ikcontextikrule_t_PS3 g_addDep_IKRules[ MAX_IKRULES ] ALIGN16;
  36. int g_addDep_numIKRules;
  37. #endif
  38. //static int g_accumPoseCount;
  39. #if !defined(__SPU__)
  40. #include <string.h>
  41. #include "tier0/vprof.h"
  42. //-----------------------------------------------------------------------------
  43. //
  44. //-----------------------------------------------------------------------------
  45. extern IVJobs * g_pVJobs;
  46. CBoneJobs g_BoneJobs;
  47. CBoneJobs* g_pBoneJobs = &g_BoneJobs;
  48. job_accumpose::JobDescriptor_t g_AccumPoseJobDescriptor ALIGN128;
  49. //-----------------------------------------------------------------------------
  50. //
  51. //-----------------------------------------------------------------------------
  52. void CBoneJobs::Init( void )
  53. {
  54. m_bEnabled = false;
  55. m_boneJobCount = 0;
  56. m_boneJobData.EnsureCapacity( 96 );
  57. // requires a SPURS instance, so register with VJobs
  58. if( g_pVJobs )
  59. {
  60. g_pVJobs->Register( this );
  61. }
  62. }
  63. void CBoneJobs::Shutdown()
  64. {
  65. g_pVJobs->Unregister( this );
  66. }
  67. void CBoneJobs::OnVjobsInit()
  68. {
  69. m_bEnabled = true;
  70. g_AccumPoseJobDescriptor.header = *m_pRoot->m_pJobAccumPose;
  71. g_AccumPoseJobDescriptor.header.useInOutBuffer = 1;
  72. g_AccumPoseJobDescriptor.header.sizeStack = (12*1024)/8;
  73. g_AccumPoseJobDescriptor.header.sizeInOrInOut = 0;
  74. }
  75. void CBoneJobs::OnVjobsShutdown()
  76. {
  77. m_bEnabled = false;
  78. }
  79. void CBoneJobs::StartFrame( int maxBoneJobs )
  80. {
  81. m_boneJobData.EnsureCapacity( maxBoneJobs );
  82. }
  83. void CBoneJobs::EndFrame( void )
  84. {
  85. m_boneJobData.RemoveAll();
  86. }
  87. void CBoneJobs::ResetBoneJobs( void )
  88. {
  89. m_boneJobCount = 0;
  90. m_boneJobNextSPURSPort = 0;
  91. }
  92. int CBoneJobs::AddBoneJob( void )
  93. {
  94. return m_boneJobCount++;
  95. }
  96. int CBoneJobs::GetNumBoneJobs( void )
  97. {
  98. return m_boneJobCount;
  99. }
  100. PS3BoneJobData *CBoneJobs::GetJobData( int job )
  101. {
  102. return &m_boneJobData[ job ];
  103. }
  104. int CBoneJobs::GetNextFreeSPURSPort( void )
  105. {
  106. m_boneJobNextSPURSPort = (m_boneJobNextSPURSPort + 1) % VJobsRoot::MAXPORTS_ANIM;
  107. return m_boneJobNextSPURSPort;
  108. }
  109. //-----------------------------------------------------------------------------
  110. // Contains support for running BoneJobs on SPU
  111. //
  112. // each bonejob contains a number of AccumulatePose calls that were 'discovered'
  113. // in the 1st pass on PPU - this pass filled the bonejob packet with data for all
  114. // AccumulatePose calls that take place on C_BaseAnimating
  115. //
  116. //-----------------------------------------------------------------------------
  117. //-----------------------------------------------------------------------------
  118. // Purpose: calculate a pose for a single sequence
  119. //-----------------------------------------------------------------------------
  120. void InitPose_PS3(
  121. const CStudioHdr *pStudioHdr,
  122. BoneVector pos[],
  123. BoneQuaternion q[],
  124. int boneMask
  125. )
  126. {
  127. // const fltx4 zeroQ = Four_Origin;
  128. SNPROF_ANIM("InitPose_PS3");
  129. if ( mstudiolinearbone_t *pLinearBones = pStudioHdr->pLinearBones() )
  130. {
  131. int numBones = pStudioHdr->numbones();
  132. AssertFatal( sizeof(BoneQuaternion) == sizeof(Quaternion) );
  133. memcpy( q, (((byte *)pLinearBones) + pLinearBones->quatindex), sizeof( Quaternion ) * numBones );
  134. // want to align pos entries to 16B
  135. // memcpy( pos, (((byte *)pLinearBones) + pLinearBones->posindex), sizeof( Vector ) * numBones );
  136. Vector *pSrcBones = (Vector *)(((byte *)pLinearBones) + pLinearBones->posindex);
  137. for( int i = 0; i < pStudioHdr->numbones(); i++ )
  138. {
  139. pos[i] = pSrcBones[i];
  140. }
  141. }
  142. else
  143. {
  144. for( int i = 0; i < pStudioHdr->numbones(); i++ )
  145. {
  146. if( pStudioHdr->boneFlags( i ) & boneMask )
  147. {
  148. const mstudiobone_t *pbone = pStudioHdr->pBone( i );
  149. pos[i] = pbone->pos;
  150. q[i] = pbone->quat;
  151. }
  152. /* // unnecessary to initialize unused bones since they are ignored downstream.
  153. else
  154. {
  155. pos[i].Zero();
  156. // q[i] = zeroQ;
  157. StoreAlignedSIMD(q[i].Base(), zeroQ);
  158. }
  159. */
  160. }
  161. }
  162. }
  163. //-----------------------------------------------------------------------------
  164. //
  165. //-----------------------------------------------------------------------------
  166. inline bool PoseIsAllZeros_PS3(
  167. const CStudioHdr *pStudioHdr,
  168. int sequence,
  169. mstudioseqdesc_t &seqdesc,
  170. int i0,
  171. int i1
  172. )
  173. {
  174. int baseanim;
  175. // remove "zero" positional blends
  176. baseanim = pStudioHdr->iRelativeAnim( sequence, seqdesc.anim(i0 ,i1 ) );
  177. mstudioanimdesc_t &anim = ((CStudioHdr *)pStudioHdr)->pAnimdesc( baseanim );
  178. return (anim.flags & STUDIO_ALLZEROS) != 0;
  179. }
  180. //-----------------------------------------------------------------------------
  181. // fill animdata_SPU struct
  182. //-----------------------------------------------------------------------------
  183. static void SetAnimData_AnimDesc( animData_SPU *pAnim, accumposeentry_SPU *pPoseEntry, mstudioanimdesc_t &animdesc, int animIndex )
  184. {
  185. SNPROF_ANIM("SetAnimData_AnimDesc");
  186. int iFrame;
  187. float s;
  188. float flStall;
  189. pAnim->pEA_animdesc = &animdesc;
  190. float fFrame = pPoseEntry->cycle * (animdesc.numframes - 1);
  191. iFrame = (int)fFrame;
  192. s = (fFrame - iFrame);
  193. int iLocalFrame = iFrame;
  194. pAnim->pEA_animdesc_pFrameanim = NULL;
  195. pAnim->pEA_animdesc_panim = NULL;
  196. if( animdesc.flags & STUDIO_FRAMEANIM )
  197. {
  198. const mstudio_frame_anim_t *pFrameanim = (mstudio_frame_anim_t *)animdesc.pAnim( &iLocalFrame, flStall );
  199. pAnim->animdesc_iLocalFrame = iLocalFrame;
  200. pAnim->pEA_animdesc_pFrameanim = (void *)pFrameanim;
  201. }
  202. else
  203. {
  204. pAnim->pEA_animdesc_panim = (void *)animdesc.pAnim( &iLocalFrame, flStall );
  205. pAnim->animdesc_iLocalFrame = iLocalFrame;
  206. }
  207. pAnim->pEA_animdesc_ikrule = NULL;
  208. pAnim->pEA_animdesc_ikrulezeroframe = NULL;
  209. mstudioikrule_t *pIKRule = animdesc.pIKRule( 0 );
  210. if( pIKRule )
  211. {
  212. pAnim->pEA_animdesc_ikrule = pIKRule;
  213. }
  214. else
  215. {
  216. mstudioikrulezeroframe_t *pZeroFrameRule = animdesc.pIKRuleZeroFrame( 0 );
  217. pAnim->pEA_animdesc_ikrulezeroframe = pZeroFrameRule;
  218. }
  219. pAnim->flStall = flStall;
  220. }
  221. //-----------------------------------------------------------------------------
  222. // Fill PoseEntry anim data
  223. //-----------------------------------------------------------------------------
  224. bool CBoneSetup_PS3::SetAnimData( accumposeentry_SPU *pPoseEntry, const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int sequence, int x, int y, int animIndex, float weight )
  225. {
  226. SNPROF_ANIM("CBoneSetup_PS3::SetAnimData");
  227. animData_SPU *pAnim = &pPoseEntry->anims[ animIndex ];
  228. pAnim->seqdesc_anim = seqdesc.anim( x, y );
  229. pAnim->seqdesc_weight = weight;
  230. virtualmodel_t *pVModel = pStudioHdr->GetVirtualModel();
  231. if( pVModel )
  232. {
  233. int baseanimation = pStudioHdr->iRelativeAnim( sequence, pAnim->seqdesc_anim );
  234. mstudioanimdesc_t &animdesc = ((CStudioHdr *)pStudioHdr)->pAnimdesc( baseanimation );
  235. if( animdesc.numlocalhierarchy )
  236. {
  237. // don't take SPU path
  238. m_errorFlags = BONEJOB_ERROR_LOCALHIER;
  239. // TODO: follow this path out quickly
  240. return false;
  241. }
  242. SetAnimData_AnimDesc( pAnim, pPoseEntry, animdesc, animIndex );
  243. pAnim->pEA_animgroup_masterbone = pVModel->pAnimGroup( baseanimation )->masterBone.Base();
  244. const studiohdr_t *pAnimStudioHdr;
  245. pAnimStudioHdr = ((CStudioHdr *)pStudioHdr)->pAnimStudioHdr( baseanimation );
  246. pAnim->animstudiohdr_numbones = pAnimStudioHdr->numbones;
  247. mstudiolinearbone_t *pLinearBones = pAnimStudioHdr->pLinearBones();
  248. pAnim->pEA_anim_linearBones = pLinearBones;
  249. pAnim->pEA_anim_bones_pos = &pAnimStudioHdr->pBone(0)->pos;
  250. pAnim->pEA_anim_bones_flags = &pAnimStudioHdr->pBone(0)->flags;
  251. }
  252. else
  253. {
  254. mstudioanimdesc_t &animdesc = ((CStudioHdr *)pStudioHdr)->pAnimdesc( pAnim->seqdesc_anim );
  255. if( animdesc.numlocalhierarchy )
  256. {
  257. // don't take SPU path
  258. m_errorFlags = BONEJOB_ERROR_LOCALHIER;
  259. // TODO: follow this path out quickly
  260. return false;
  261. }
  262. SetAnimData_AnimDesc( pAnim, pPoseEntry, animdesc, animIndex );
  263. pAnim->animstudiohdr_numbones = pStudioHdr->GetRenderHdr()->numbones;
  264. }
  265. return true;
  266. }
  267. //-----------------------------------------------------------------------------
  268. // CalcPoseSingle PPU pass - fill PoseEntry
  269. // Get this working first before moving more to SPU
  270. //-----------------------------------------------------------------------------
  271. bool CBoneSetup_PS3::CalcPoseSingle(
  272. accumposeentry_SPU *pPoseEntry,
  273. const CStudioHdr *pStudioHdr,
  274. mstudioseqdesc_t &seqdesc,
  275. int sequence,
  276. float cycle,
  277. const float poseParameter[],
  278. float flTime )
  279. {
  280. SNPROF_ANIM( "CBoneSetup_PS3::CalcPoseSingle" );
  281. ConVarRef anim_3wayblend( "anim_3wayblend" );
  282. bool bResult = true;
  283. float s0, s1;
  284. int i0, i1;
  285. s0 = 0.0f; s1 = 0.0f;
  286. i0 = Studio_LocalPoseParameter( pStudioHdr, poseParameter, seqdesc, sequence, 0, s0 );
  287. i1 = Studio_LocalPoseParameter( pStudioHdr, poseParameter, seqdesc, sequence, 1, s1 );
  288. //pPoseEntry->cps = Studio_CPS( pStudioHdr, seqdesc, sequence, poseParameter );
  289. if( seqdesc.flags & STUDIO_REALTIME )
  290. {
  291. float cps = Studio_CPS( pStudioHdr, seqdesc, sequence, poseParameter );
  292. cycle = flTime * cps;
  293. cycle = cycle - (int)cycle;
  294. }
  295. else if( seqdesc.flags & STUDIO_CYCLEPOSE )
  296. {
  297. int iPose = pStudioHdr->GetSharedPoseParameter( sequence, seqdesc.cycleposeindex );
  298. if( iPose != -1 )
  299. {
  300. /*
  301. const mstudioposeparamdesc_t &Pose = pStudioHdr->pPoseParameter( iPose );
  302. cycle = poseParameter[ iPose ] * (Pose.end - Pose.start) + Pose.start;
  303. */
  304. cycle = poseParameter[ iPose ];
  305. }
  306. else
  307. {
  308. cycle = 0.0f;
  309. }
  310. }
  311. else if( cycle < 0.0f || cycle >= 1.0f )
  312. {
  313. if( seqdesc.flags & STUDIO_LOOPING )
  314. {
  315. cycle = cycle - (int)cycle;
  316. if( cycle < 0 ) cycle += 1.0f;
  317. }
  318. else
  319. {
  320. cycle = clamp( cycle, 0.0f, 1.0f );
  321. }
  322. }
  323. pPoseEntry->cyclePoseSingle = cycle;
  324. pPoseEntry->i0 = i0;
  325. pPoseEntry->i1 = i1;
  326. pPoseEntry->s0 = s0;
  327. pPoseEntry->s1 = s1;
  328. pPoseEntry->animIndices[0] = -1;
  329. pPoseEntry->animIndices[1] = -1;
  330. pPoseEntry->animIndices[2] = -1;
  331. pPoseEntry->animIndices[3] = -1;
  332. pPoseEntry->anims[0].seqdesc_weight = 0.0f;
  333. pPoseEntry->anims[1].seqdesc_weight = 0.0f;
  334. pPoseEntry->anims[2].seqdesc_weight = 0.0f;
  335. pPoseEntry->anims[3].seqdesc_weight = 0.0f;
  336. pPoseEntry->anims[0].animstudiohdr_numbones = 0;
  337. pPoseEntry->anims[1].animstudiohdr_numbones = 0;
  338. pPoseEntry->anims[2].animstudiohdr_numbones = 0;
  339. pPoseEntry->anims[3].animstudiohdr_numbones = 0;
  340. if( s0 < 0.001f )
  341. {
  342. if( s1 < 0.001f )
  343. {
  344. if( PoseIsAllZeros_PS3( pStudioHdr, sequence, seqdesc, i0, i1 ) )
  345. {
  346. pPoseEntry->cpsPath = CPSPATH_FALSE;
  347. bResult = false;
  348. }
  349. else
  350. {
  351. pPoseEntry->cpsPath = CPSPATH_CALCANIM1;
  352. pPoseEntry->animIndices[0] = 0;
  353. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0, i1, 0, 1.0f );
  354. }
  355. }
  356. else if( s1 > 0.999f )
  357. {
  358. pPoseEntry->cpsPath = CPSPATH_CALCANIM1;
  359. pPoseEntry->animIndices[0] = 2;
  360. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0, i1+1, 2, 1.0f );
  361. }
  362. else
  363. {
  364. pPoseEntry->cpsPath = CPSPATH_CALCANIM2_S1;
  365. pPoseEntry->animIndices[0] = 0;
  366. pPoseEntry->animIndices[1] = 2;
  367. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0, i1, 0, 1.0f - s1 );
  368. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0, i1+1, 2, s1 );
  369. }
  370. }
  371. else if( s0 > 0.999f )
  372. {
  373. if( s1 < 0.001f )
  374. {
  375. if( PoseIsAllZeros_PS3( pStudioHdr, sequence, seqdesc, i0+1, i1 ) )
  376. {
  377. pPoseEntry->cpsPath = CPSPATH_FALSE;
  378. bResult = false;
  379. }
  380. else
  381. {
  382. pPoseEntry->cpsPath = CPSPATH_CALCANIM1;
  383. pPoseEntry->animIndices[0] = 1;
  384. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0+1, i1, 1, 1.0f );
  385. }
  386. }
  387. else if( s1 > 0.999f )
  388. {
  389. pPoseEntry->cpsPath = CPSPATH_CALCANIM1;
  390. pPoseEntry->animIndices[0] = 3;
  391. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0+1, i1+1, 3, 1.0f );
  392. }
  393. else
  394. {
  395. pPoseEntry->cpsPath = CPSPATH_CALCANIM2_S1;
  396. pPoseEntry->animIndices[0] = 1;
  397. pPoseEntry->animIndices[1] = 3;
  398. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0+1, i1, 1, 1.0f - s1 );
  399. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0+1, i1+1, 3, s1 );
  400. }
  401. }
  402. else
  403. {
  404. if( s1 < 0.001f )
  405. {
  406. pPoseEntry->animIndices[0] = 0;
  407. pPoseEntry->animIndices[1] = 1;
  408. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0, i1, 0, 1.0f - s0 );
  409. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0+1, i1, 1, s0 );
  410. if( PoseIsAllZeros_PS3( pStudioHdr, sequence, seqdesc, i0+1, i1 ) )
  411. {
  412. pPoseEntry->cpsPath = CPSPATH_CALCANIM1_SCALE1MINUSS0;
  413. }
  414. else if( PoseIsAllZeros_PS3( pStudioHdr, sequence, seqdesc, i0, i1 ) )
  415. {
  416. pPoseEntry->cpsPath = CPSPATH_CALCANIM1_SCALES0;
  417. }
  418. else
  419. {
  420. pPoseEntry->cpsPath = CPSPATH_CALCANIM2_S0;
  421. }
  422. }
  423. else if( s1 > 0.999f )
  424. {
  425. pPoseEntry->cpsPath = CPSPATH_CALCANIM2_S0;
  426. pPoseEntry->animIndices[0] = 2;
  427. pPoseEntry->animIndices[1] = 3;
  428. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0, i1+1, 2, 1.0f - s0 );
  429. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0+1, i1+1, 3, s0 );
  430. }
  431. else if( !anim_3wayblend.GetBool() )
  432. {
  433. pPoseEntry->cpsPath = CPSPATH_CALCANIM4;
  434. pPoseEntry->animIndices[0] = 0;
  435. pPoseEntry->animIndices[1] = 1;
  436. pPoseEntry->animIndices[2] = 2;
  437. pPoseEntry->animIndices[3] = 3;
  438. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0, i1, 0, (1.0f - s0) * (1.0f - s1) );
  439. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0+1, i1, 1, (s0) * (1.0f - s1) );
  440. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0, i1+1, 2, (1.0f - s0) * (s1) );
  441. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0+1, i1+1, 3, (s0) * (s1) );
  442. }
  443. else
  444. {
  445. pPoseEntry->cpsPath = CPSPATH_CALCANIM3;
  446. pPoseEntry->animIndices[0] = 0;
  447. pPoseEntry->animIndices[1] = 1;
  448. pPoseEntry->animIndices[2] = 2;
  449. pPoseEntry->animIndices[3] = 3;
  450. // weights get fixed up later
  451. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0, i1, 0, 0.0f );
  452. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0+1, i1, 1, 0.0f );
  453. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0, i1+1, 2, 0.0f );
  454. SetAnimData( pPoseEntry, pStudioHdr, seqdesc, sequence, i0+1, i1+1, 3, 0.0f );
  455. }
  456. }
  457. if( pPoseEntry->animIndices[0] == -1 )
  458. {
  459. // ik may use the zeroth entry - why?
  460. virtualmodel_t *pVModel = pStudioHdr->GetVirtualModel();
  461. if( pVModel )
  462. {
  463. int baseanimation = pStudioHdr->iRelativeAnim( sequence, seqdesc.anim( i0, i1 ) );
  464. mstudioanimdesc_t &animdesc = ((CStudioHdr *)pStudioHdr)->pAnimdesc( baseanimation );
  465. pPoseEntry->anims[ 0 ].pEA_animdesc = &animdesc;
  466. }
  467. else
  468. {
  469. mstudioanimdesc_t &animdesc = ((CStudioHdr *)pStudioHdr)->pAnimdesc( seqdesc.anim( i0, i1 ) );
  470. pPoseEntry->anims[ 0 ].pEA_animdesc = &animdesc;
  471. }
  472. }
  473. // Real IK weights
  474. // 0 : (1.0f - s0) * (1.0f - s1);
  475. // 1 : (s0) * (1.0f - s1);
  476. // 2 : (1.0f - s0) * (s1);
  477. // 3 : (s0) * (s1);
  478. return bResult;
  479. }
  480. //-----------------------------------------------------------------------------
  481. //
  482. //-----------------------------------------------------------------------------
  483. void AddSequenceLocks_PS3( accumposeentry_SPU* pPoseEntry, const CStudioHdr* pStudioHdr, mstudioseqdesc_t &seqdesc )
  484. {
  485. pPoseEntry->pEA_seqdesc_iklocks = NULL;
  486. if( pStudioHdr->numikchains() == 0)
  487. {
  488. return;
  489. }
  490. if( seqdesc.numiklocks == 0 )
  491. {
  492. return;
  493. }
  494. pPoseEntry->pEA_seqdesc_iklocks = seqdesc.pIKLock( 0 );
  495. }
  496. //-----------------------------------------------------------------------------
  497. //
  498. //-----------------------------------------------------------------------------
  499. void AddAutoLocks_PS3( bonejob_SPU *pBonejob, const CStudioHdr* pStudioHdr )
  500. {
  501. SNPROF_ANIM("AddAutoLocks_PS3");
  502. if( pStudioHdr->GetNumIKAutoplayLocks() == 0 )
  503. {
  504. return;
  505. }
  506. AssertFatal( pStudioHdr->GetNumIKAutoplayLocks() < MAX_IKLOCKS );
  507. for( int i = 0; i < pStudioHdr->GetNumIKAutoplayLocks(); i++ )
  508. {
  509. const mstudioiklock_t &lock = ((CStudioHdr *)pStudioHdr)->pIKAutoplayLock( i );
  510. pBonejob->pEA_IKAutoplayLocks[ i ] = (void *)&lock;
  511. }
  512. }
  513. //-----------------------------------------------------------------------------
  514. // Add an AccumulatePose call to the bonejob
  515. //-----------------------------------------------------------------------------
  516. void CBoneSetup_PS3::AccumulatePose_AddToBoneJob( bonejob_SPU* pSPUJob,
  517. int sequence,
  518. float cycle,
  519. float flWeight,
  520. CIKContext *pIKContext,
  521. int pqStackLevel )
  522. {
  523. SNPROF_ANIM( "CBoneSetup_PS3::AccumulatePose_AddToBoneJob" );
  524. if( pSPUJob->numTotalPoses >= MAX_ACCUMPOSECALLS )
  525. {
  526. m_errorFlags = BONEJOB_ERROR_EXCEEDEDMAXCALLS;
  527. return;
  528. }
  529. if( ( pqStackLevel+1 ) >= MAX_PQSTACKLEVEL )
  530. {
  531. // pq stack depth exceeded, early out of job, run from scratch on PPU
  532. m_errorFlags = BONEJOB_ERROR_EXCEEDEDPQSTACK;
  533. return;
  534. }
  535. flWeight = clamp( flWeight, 0.0f, 1.0f );
  536. if( sequence < 0 )
  537. {
  538. // just skip, no error flags?
  539. return;
  540. }
  541. if( sequence >= m_pStudioHdr->GetNumSeq() )
  542. {
  543. sequence = 0;
  544. }
  545. //-------------------------------------------------------------------------------------
  546. // get stack entry
  547. accumposeentry_SPU *pPoseEntry = &pSPUJob->accumPoseEntry[ pSPUJob->numTotalPoses++ ];
  548. //-------------------------------------------------------------------------------------
  549. //-------------------------------------------------------------------------------------
  550. // copy call params and grab common data and ptrs for SPU path
  551. mstudioseqdesc_t &seqdesc = ((CStudioHdr *)m_pStudioHdr)->pSeqdesc( sequence );
  552. pPoseEntry->pEA_seqdesc = &seqdesc;
  553. pPoseEntry->iSeq = sequence;
  554. pPoseEntry->cycle = cycle;
  555. pPoseEntry->weight = flWeight;
  556. pPoseEntry->pqStackLevel = pqStackLevel;
  557. pPoseEntry->seqdesc_numiklocks = seqdesc.numiklocks;
  558. pPoseEntry->seqdesc_numikrules = seqdesc.numikrules;
  559. pPoseEntry->seqdesc_flags = seqdesc.flags;
  560. virtualmodel_t *pVModel = m_pStudioHdr->GetVirtualModel();
  561. const virtualgroup_t *pSeqGroup = NULL;
  562. pPoseEntry->pEA_seqgroup_boneMap = NULL;
  563. pPoseEntry->pEA_seqgroup_masterBone = NULL;
  564. if( pVModel )
  565. {
  566. const studiohdr_t *pSeqStudioHdr;
  567. pSeqGroup = pVModel->pSeqGroup( sequence );
  568. if( pSeqGroup )
  569. {
  570. pPoseEntry->pEA_seqgroup_boneMap = (void *)pSeqGroup->boneMap.Base();
  571. pPoseEntry->pEA_seqgroup_masterBone = (void *)pSeqGroup->masterBone.Base();
  572. }
  573. pSeqStudioHdr = ((CStudioHdr *)m_pStudioHdr)->pSeqStudioHdr( sequence );
  574. mstudiolinearbone_t *pLinearBones = pSeqStudioHdr->pLinearBones();
  575. pPoseEntry->pEA_seq_linearBones = pLinearBones;
  576. if( pLinearBones )
  577. {
  578. pPoseEntry->pEA_seq_linearbones_pos = (void *)(((byte *)pLinearBones) + pLinearBones->posindex);
  579. pPoseEntry->pEA_seq_linearbones_quat = (void *)(((byte *)pLinearBones) + pLinearBones->quatindex);
  580. }
  581. pPoseEntry->pEA_seq_bones_pos = &pSeqStudioHdr->pBone(0)->pos;
  582. }
  583. pPoseEntry->pEA_seqdesc_boneWeight = (void *)seqdesc.pBoneweight( 0 );
  584. //-------------------------------------------------------------------------------------
  585. if( seqdesc.numiklocks )
  586. {
  587. AddSequenceLocks_PS3( pPoseEntry, m_pStudioHdr, seqdesc );
  588. }
  589. // potentially recurse
  590. if( CalcPoseSingle( pPoseEntry, m_pStudioHdr, seqdesc, sequence, cycle, m_flPoseParameter, pSPUJob->currentTime ) )
  591. {
  592. pPoseEntry->numLocalLayers = AddLocalLayers( pSPUJob, seqdesc, sequence, cycle, 1.0f, pIKContext, pqStackLevel+1 );
  593. }
  594. pPoseEntry->numSequenceLayers = AddSequenceLayers( pSPUJob, seqdesc, sequence, cycle, flWeight, pIKContext, pqStackLevel+1 );
  595. // update bonejob max bones
  596. for( int lp = 0; lp < MAX_BLENDANIMS; lp++ )
  597. {
  598. pSPUJob->maxBones = MAX( pPoseEntry->anims[lp].animstudiohdr_numbones, pSPUJob->maxBones );
  599. }
  600. }
  601. //-----------------------------------------------------------------------------
  602. // Purpose: calculate a pose for a single sequence
  603. // adds autolayers, runs local ik rukes
  604. //-----------------------------------------------------------------------------
  605. int CBoneSetup_PS3::AddSequenceLayers(
  606. bonejob_SPU *pSPUJob,
  607. mstudioseqdesc_t &seqdesc,
  608. int sequence,
  609. float cycle,
  610. float flWeight,
  611. CIKContext *pIKContext,
  612. int pqStackLevel
  613. )
  614. {
  615. SNPROF_ANIM("CBoneSetup_PS3::AddSequenceLayers");
  616. int ret = 0;
  617. for (int i = 0; i < seqdesc.numautolayers; i++)
  618. {
  619. mstudioautolayer_t *pLayer = seqdesc.pAutolayer( i );
  620. if (pLayer->flags & STUDIO_AL_LOCAL)
  621. continue;
  622. float layerCycle = cycle;
  623. float layerWeight = flWeight;
  624. if (pLayer->start != pLayer->end)
  625. {
  626. float s = 1.0f;
  627. float index;
  628. if (!(pLayer->flags & STUDIO_AL_POSE))
  629. {
  630. index = cycle;
  631. }
  632. else
  633. {
  634. int iSequence = m_pStudioHdr->iRelativeSeq( sequence, pLayer->iSequence );
  635. int iPose = m_pStudioHdr->GetSharedPoseParameter( iSequence, pLayer->iPose );
  636. if (iPose != -1)
  637. {
  638. const mstudioposeparamdesc_t &Pose = ((CStudioHdr *)m_pStudioHdr)->pPoseParameter( iPose );
  639. index = m_flPoseParameter[ iPose ] * (Pose.end - Pose.start) + Pose.start;
  640. }
  641. else
  642. {
  643. index = 0;
  644. }
  645. }
  646. if (index < pLayer->start)
  647. continue;
  648. if (index >= pLayer->end)
  649. continue;
  650. if (index < pLayer->peak && pLayer->start != pLayer->peak)
  651. {
  652. s = (index - pLayer->start) / (pLayer->peak - pLayer->start);
  653. }
  654. else if (index > pLayer->tail && pLayer->end != pLayer->tail)
  655. {
  656. s = (pLayer->end - index) / (pLayer->end - pLayer->tail);
  657. }
  658. if (pLayer->flags & STUDIO_AL_SPLINE)
  659. {
  660. s = SimpleSpline( s );
  661. }
  662. if ((pLayer->flags & STUDIO_AL_XFADE) && (index > pLayer->tail))
  663. {
  664. layerWeight = ( s * flWeight ) / ( 1.0f - flWeight + s * flWeight );
  665. }
  666. else if (pLayer->flags & STUDIO_AL_NOBLEND)
  667. {
  668. layerWeight = s;
  669. }
  670. else
  671. {
  672. layerWeight = flWeight * s;
  673. }
  674. if (!(pLayer->flags & STUDIO_AL_POSE))
  675. {
  676. layerCycle = (cycle - pLayer->start) / (pLayer->end - pLayer->start);
  677. }
  678. }
  679. ret++;
  680. int iSequence = m_pStudioHdr->iRelativeSeq( sequence, pLayer->iSequence );
  681. AccumulatePose_AddToBoneJob( pSPUJob, iSequence, layerCycle, layerWeight, pIKContext, pqStackLevel );
  682. }
  683. return ret;
  684. }
  685. //-----------------------------------------------------------------------------
  686. // Purpose: calculate a pose for a single sequence
  687. // adds autolayers, runs local ik rukes
  688. //-----------------------------------------------------------------------------
  689. int CBoneSetup_PS3::AddLocalLayers(
  690. bonejob_SPU *pSPUJob,
  691. mstudioseqdesc_t &seqdesc,
  692. int sequence,
  693. float cycle,
  694. float flWeight,
  695. CIKContext *pIKContext,
  696. int pqStackLevel
  697. )
  698. {
  699. SNPROF_ANIM("CBoneSetup_PS3::AddLocalLayers");
  700. int ret = 0;
  701. if (!(seqdesc.flags & STUDIO_LOCAL))
  702. {
  703. return ret;
  704. }
  705. for (int i = 0; i < seqdesc.numautolayers; i++)
  706. {
  707. mstudioautolayer_t *pLayer = seqdesc.pAutolayer( i );
  708. if (!(pLayer->flags & STUDIO_AL_LOCAL))
  709. continue;
  710. float layerCycle = cycle;
  711. float layerWeight = flWeight;
  712. if (pLayer->start != pLayer->end)
  713. {
  714. float s = 1.0f;
  715. if (cycle < pLayer->start)
  716. continue;
  717. if (cycle >= pLayer->end)
  718. continue;
  719. if (cycle < pLayer->peak && pLayer->start != pLayer->peak)
  720. {
  721. s = (cycle - pLayer->start) / (pLayer->peak - pLayer->start);
  722. }
  723. else if (cycle > pLayer->tail && pLayer->end != pLayer->tail)
  724. {
  725. s = (pLayer->end - cycle) / (pLayer->end - pLayer->tail);
  726. }
  727. if (pLayer->flags & STUDIO_AL_SPLINE)
  728. {
  729. s = SimpleSpline( s );
  730. }
  731. if ((pLayer->flags & STUDIO_AL_XFADE) && (cycle > pLayer->tail))
  732. {
  733. layerWeight = ( s * flWeight ) / ( 1.0f - flWeight + s * flWeight );
  734. }
  735. else if (pLayer->flags & STUDIO_AL_NOBLEND)
  736. {
  737. layerWeight = s;
  738. }
  739. else
  740. {
  741. layerWeight = flWeight * s;
  742. }
  743. layerCycle = (cycle - pLayer->start) / (pLayer->end - pLayer->start);
  744. }
  745. ret++;
  746. int iSequence = m_pStudioHdr->iRelativeSeq( sequence, pLayer->iSequence );
  747. AccumulatePose_AddToBoneJob( pSPUJob, iSequence, layerCycle, layerWeight, pIKContext, pqStackLevel );
  748. }
  749. return ret;
  750. }
  751. //-----------------------------------------------------------------------------
  752. //
  753. //-----------------------------------------------------------------------------
  754. IBoneSetup_PS3::IBoneSetup_PS3( const CStudioHdr *pStudioHdr, int boneMask, const float poseParameter[], bonejob_SPU *pBoneJobSPU )
  755. {
  756. m_pBoneSetup = new CBoneSetup_PS3( pStudioHdr, boneMask, poseParameter, pBoneJobSPU );
  757. }
  758. IBoneSetup_PS3::~IBoneSetup_PS3( void )
  759. {
  760. if ( m_pBoneSetup )
  761. {
  762. delete m_pBoneSetup;
  763. }
  764. }
  765. void IBoneSetup_PS3::InitPose_PS3( BoneVector pos[], BoneQuaternion q[] )
  766. {
  767. ::InitPose_PS3( m_pBoneSetup->m_pStudioHdr, pos, q, m_pBoneSetup->m_boneMask );
  768. }
  769. void IBoneSetup_PS3::CalcAutoplaySequences_AddPoseCalls( float flRealTime )
  770. {
  771. m_pBoneSetup->CalcAutoplaySequences_AddPoseCalls( flRealTime );
  772. }
  773. void IBoneSetup_PS3::AccumulatePose_AddToBoneJob( bonejob_SPU* pBonejobSPU, int sequence, float cycle, float flWeight, CIKContext *pIKContext, int pqStackLevel )
  774. {
  775. m_pBoneSetup->AccumulatePose_AddToBoneJob( pBonejobSPU, sequence, cycle, flWeight, pIKContext, pqStackLevel );
  776. }
  777. CStudioHdr *IBoneSetup_PS3::GetStudioHdr()
  778. {
  779. return (CStudioHdr *)m_pBoneSetup->m_pStudioHdr;
  780. }
  781. void IBoneSetup_PS3::ResetErrorFlags()
  782. {
  783. m_pBoneSetup->m_errorFlags = 0;
  784. }
  785. int IBoneSetup_PS3::ErrorFlags()
  786. {
  787. return m_pBoneSetup->m_errorFlags;
  788. }
  789. bonejob_SPU *IBoneSetup_PS3::GetBoneJobSPU()
  790. {
  791. return m_pBoneSetup->m_pBoneJobSPU;
  792. }
  793. int IBoneSetup_PS3::RunAccumulatePoseJobs_PPU( bonejob_SPU *pBonejobSPU )
  794. {
  795. return m_pBoneSetup->RunAccumulatePoseJobs_PPU( pBonejobSPU );
  796. }
  797. int IBoneSetup_PS3::RunAccumulatePoseJobs_SPU( bonejob_SPU *pBoneJobSPU, job_accumpose::JobDescriptor_t *pJobDescriptor )
  798. {
  799. return m_pBoneSetup->RunAccumulatePoseJobs_SPU( pBoneJobSPU, pJobDescriptor );
  800. }
  801. CBoneSetup_PS3::CBoneSetup_PS3( const CStudioHdr *pStudioHdr, int boneMask, const float poseParameter[], bonejob_SPU *pBoneJobSPU )
  802. {
  803. m_pStudioHdr = pStudioHdr;
  804. m_boneMask = boneMask;
  805. m_flPoseParameter = poseParameter;
  806. m_pBoneJobSPU = pBoneJobSPU;
  807. m_errorFlags = 0;
  808. }
  809. //-----------------------------------------------------------------------------
  810. // Purpose: run all animations that automatically play and are driven off of poseParameters
  811. // This version adds AccumulatePose calls to the current bonejob
  812. //-----------------------------------------------------------------------------
  813. void CBoneSetup_PS3::CalcAutoplaySequences_AddPoseCalls( float flRealTime )
  814. {
  815. SNPROF_ANIM( "CBoneSetup_PS3::CalcAutoplaySequences_AddPoseCalls" );
  816. int i;
  817. AddAutoLocks_PS3( m_pBoneJobSPU, m_pStudioHdr );
  818. unsigned short *pList = NULL;
  819. int count = m_pStudioHdr->GetAutoplayList( &pList );
  820. for( i = 0; i < count; i++ )
  821. {
  822. int sequenceIndex = pList[i];
  823. mstudioseqdesc_t &seqdesc = ((CStudioHdr *)m_pStudioHdr)->pSeqdesc( sequenceIndex );
  824. if( seqdesc.flags & STUDIO_AUTOPLAY )
  825. {
  826. float cycle = 0.0f;
  827. float cps = Studio_CPS( m_pStudioHdr, seqdesc, sequenceIndex, m_flPoseParameter );
  828. cycle = flRealTime * cps;
  829. cycle = cycle - (int)cycle;
  830. // AccumulatePose( pos, q, sequenceIndex, cycle, 1.0, flRealTime, pIKContext );
  831. // null ik context since dependencies are added but not used
  832. // still need autoplaylocks added/solved
  833. AccumulatePose_AddToBoneJob( m_pBoneJobSPU, sequenceIndex, cycle, 1.0f, NULL, 0 );
  834. }
  835. }
  836. }
  837. void MsgJobData( bonejob_SPU *pBoneJob )
  838. {
  839. int lp;
  840. Msg("**********************************************************\n");
  841. Msg(" BoneJob Data Start\n");
  842. Msg("**********************************************************\n");
  843. Msg("numikAutoplayLocks: %d\n", pBoneJob->numikAutoplayLocks);
  844. for(lp = 0; lp< pBoneJob->numikAutoplayLocks; lp++)
  845. {
  846. Msg("pEA_IKAutoplayLocks[%d] = 0x%x\n", lp, (unsigned int)pBoneJob->pEA_IKAutoplayLocks[lp]);
  847. }
  848. Msg("numTotalPoses: %d\n", pBoneJob->numTotalPoses );
  849. for(lp = 0; lp< pBoneJob->numTotalPoses; lp++)
  850. {
  851. accumposeentry_SPU *pPoseEntry = &pBoneJob->accumPoseEntry[lp];
  852. Msg("PoseEntry[%d]\n",lp);
  853. Msg("--------------\n");
  854. Msg("pEA_seqdesc = 0x%x\n", (unsigned int)pPoseEntry->pEA_seqdesc);
  855. Msg("pEA_seqgroup_boneMap = 0x%x\n", (unsigned int)pPoseEntry->pEA_seqgroup_boneMap);
  856. Msg("pEA_seqgroup_masterBone = 0x%x\n", (unsigned int)pPoseEntry->pEA_seqgroup_masterBone);
  857. Msg("pEA_seqdesc_boneWeight = 0x%x\n", (unsigned int)pPoseEntry->pEA_seqdesc_boneWeight);
  858. Msg("pEA_seqdesc_iklocks = 0x%x\n", (unsigned int)pPoseEntry->pEA_seqdesc_iklocks);
  859. Msg("pEA_seq_linearBones = 0x%x\n", (unsigned int)pPoseEntry->pEA_seq_linearBones);
  860. Msg("pEA_seq_linearbones_pos = 0x%x\n", (unsigned int)pPoseEntry->pEA_seq_linearbones_pos);
  861. Msg("pEA_seq_linearbones_quat = 0x%x\n", (unsigned int)pPoseEntry->pEA_seq_linearbones_quat);
  862. Msg("pEA_seq_bones_pos = 0x%x\n", (unsigned int)pPoseEntry->pEA_seq_bones_pos);
  863. switch( pPoseEntry->cpsPath )
  864. {
  865. case CPSPATH_FALSE:
  866. break;
  867. case CPSPATH_CALCANIM1:
  868. case CPSPATH_CALCANIM1_SCALE1MINUSS0:
  869. case CPSPATH_CALCANIM1_SCALES0:
  870. break;
  871. case CPSPATH_CALCANIM2_S0:
  872. case CPSPATH_CALCANIM2_S1:
  873. break;
  874. case CPSPATH_CALCANIM3:
  875. case CPSPATH_CALCANIM4:
  876. break;
  877. default:
  878. break;
  879. }
  880. }
  881. Msg("**********************************************************\n");
  882. Msg(" BoneJob Data End\n");
  883. Msg("**********************************************************\n");
  884. }
  885. //--------------------------------------------------------------------------------------------------------------------
  886. // Entry point for running bone jobs, spu jobs pushed from here
  887. //
  888. //--------------------------------------------------------------------------------------------------------------------
  889. int CBoneSetup_PS3::RunAccumulatePoseJobs_SPU( bonejob_SPU *pBoneJob, job_accumpose::JobDescriptor_t *pJobDescriptor )
  890. {
  891. SNPROF_ANIM("CBoneSetup_PS3::RunAccumulatePoseJobs_SPU");
  892. ConVarRef cl_PS3_SPU_bones_debug( "cl_PS3_SPU_bones_debug" );
  893. ConVarRef cl_PS3_SPU_bones_minbonecount( "cl_PS3_SPU_bones_minbonecount" );
  894. int numBones = pBoneJob->numBones;
  895. // don't push jobs with less than minbonecount bones to SPU, just perform the job inline on PPU, need to find a sweet spot for minbonecount
  896. if( numBones < cl_PS3_SPU_bones_minbonecount.GetInt() )
  897. {
  898. return RunAccumulatePoseJobs_PPU( pBoneJob );
  899. }
  900. BoneVector *pos = (BoneVector *)pBoneJob->pEA_pos;
  901. BoneQuaternion *q = (BoneQuaternion *)pBoneJob->pEA_q;
  902. if( cl_PS3_SPU_bones_debug.GetInt() == 2 )
  903. {
  904. memcpy( g_posInit, pos, sizeof(BoneVector) * numBones );
  905. memcpy( g_qInit, q, sizeof(BoneQuaternion) * numBones );
  906. }
  907. // initialise header
  908. pJobDescriptor->header = g_AccumPoseJobDescriptor.header;
  909. pJobDescriptor->header.useInOutBuffer = 1;
  910. pJobDescriptor->header.sizeStack = (16*1024)/8;
  911. pJobDescriptor->header.sizeInOrInOut = 0;
  912. pJobDescriptor->header.sizeDmaList = 0;
  913. // add dma's
  914. AddInputDma( pJobDescriptor, sizeof(bonejob_SPU), pBoneJob );
  915. AddInputDma( pJobDescriptor, sizeof(BoneVector) * pBoneJob->numBones, pBoneJob->pEA_pos );
  916. AddInputDma( pJobDescriptor, sizeof(BoneQuaternion) * pBoneJob->numBones, pBoneJob->pEA_q );
  917. pJobDescriptor->header.sizeInOrInOut += (sizeof(ikcontextikrule_t) * MAX_IKRULES) + (sizeof(int) * 4);
  918. int jobPort = g_pBoneJobs->GetNextFreeSPURSPort();
  919. // kick off job
  920. //Msg("push job port %d, numbones %d\n", jobPort, pBoneJob->numBones );
  921. CELL_VERIFY( g_pBoneJobs->m_pRoot->m_queuePortAnim[ jobPort ].pushJob( &pJobDescriptor->header, sizeof(*pJobDescriptor), 0, CELL_SPURS_JOBQUEUE_FLAG_SYNC_JOB ) );
  922. if( cl_PS3_SPU_bones_debug.GetInt() )
  923. {
  924. //Msg("_DEBUG_ACCUMPOSE sync job %d\n", jobPort);
  925. CELL_VERIFY( g_pBoneJobs->m_pRoot->m_queuePortAnim[ jobPort ].sync( 0 ) );
  926. if( cl_PS3_SPU_bones_debug.GetInt() > 1 )
  927. {
  928. // reset pos, q
  929. memcpy( pos, g_posInit, sizeof(BoneVector) * numBones );
  930. memcpy( q, g_qInit, sizeof(BoneQuaternion) * numBones );
  931. RunAccumulatePoseJobs_PPU( pBoneJob );
  932. }
  933. }
  934. return jobPort;
  935. }
  936. //--------------------------------------------------------------------------------------------------------------------
  937. // Entry point for running bone jobs
  938. // This is the PPU version
  939. //
  940. //--------------------------------------------------------------------------------------------------------------------
  941. int CBoneSetup_PS3::RunAccumulatePoseJobs_PPU( bonejob_SPU *pBoneJob )
  942. {
  943. SNPROF_ANIM("CBoneSetup_PS3::RunAccumulatePoseJobs_PPU");
  944. InitLSStack();
  945. BoneVector *pos = (BoneVector *)pBoneJob->pEA_pos;
  946. BoneQuaternion *q = (BoneQuaternion *)pBoneJob->pEA_q;
  947. g_addDep_numIKRules = 0;
  948. // pos and q already contain result of initial ::init, which all subsequent calls of ::init take a copy of
  949. // don't write over until the end when it should contain the final pos, q data
  950. C_AccumulatePose_SPU cAccumPose( pBoneJob );
  951. int numBones = pBoneJob->numBones;
  952. // backup
  953. memcpy( g_posInit, pos, sizeof(BoneVector) * numBones );
  954. memcpy( g_qInit, q, sizeof(BoneQuaternion) * numBones );
  955. // into pq stack which we work on
  956. BoneVector *pos0 = (BoneVector *)PushLSStack( sizeof(BoneVector) * numBones );
  957. BoneQuaternion *q0 = (BoneQuaternion *)PushLSStack( sizeof(BoneQuaternion) * numBones );
  958. memcpy( pos0, pos, sizeof(BoneVector) * numBones );
  959. memcpy( q0, q, sizeof(BoneQuaternion) * numBones );
  960. cAccumPose.ResetCount();
  961. cAccumPose.SetIKContext( pBoneJob->pEA_IKContext );
  962. while( cAccumPose.GetCount() < pBoneJob->numPoses_PreAutoSeq )
  963. {
  964. cAccumPose.AccumulatePose( pos0, q0 );
  965. }
  966. CIKContext_PS3 auto_ik;
  967. auto_ik.Init( pBoneJob, pBoneJob->autoikAngles, pBoneJob->autoikOrigin, pBoneJob->currentTime, pBoneJob->autoikFramecount, pBoneJob->boneMask );
  968. auto_ik.AddAutoplayLocks( pBoneJob, pos0, q0 );
  969. while( cAccumPose.GetCount() < pBoneJob->numTotalPoses )
  970. {
  971. cAccumPose.AccumulatePose( pos0, q0 );
  972. }
  973. auto_ik.SolveAutoplayLocks( pBoneJob, pos0, q0 );
  974. // write results to pos, q
  975. memcpy( pos, pos0, sizeof( BoneVector ) * numBones );
  976. memcpy( q, q0, sizeof( BoneQuaternion ) * numBones );
  977. // write AddDependencies() potential IK rules
  978. if( g_addDep_numIKRules )
  979. {
  980. memcpy( pBoneJob->pEA_addDep_numIKRules, &g_addDep_numIKRules, sizeof(int) );
  981. memcpy( pBoneJob->pEA_addDep_IKRules, g_addDep_IKRules, g_addDep_numIKRules * sizeof(ikcontextikrule_t_PS3) );
  982. }
  983. PopLSStack( sizeof(BoneQuaternion) * numBones );
  984. PopLSStack( sizeof(BoneVector) * numBones );
  985. TermLSStack();
  986. return VJobsRoot::MAXPORTS_ANIM; // => can only be a ppu job
  987. }
  988. #endif // #if !defined(__SPU__)
  989. //--------------------------------------------------------------------------------------------------------------------
  990. //
  991. // Below this point needs to go to SPU, above this point PPU only (prep pass for SPU)
  992. //
  993. //--------------------------------------------------------------------------------------------------------------------
  994. //-----------------------------------------------------------------------------
  995. // Purpose: turn a 2x2 blend into a 3 way triangle blend
  996. // Returns: returns the animation indices and barycentric coordinates of a triangle
  997. // the triangle is a right triangle, and the diagonal is between elements [0] and [2]
  998. //-----------------------------------------------------------------------------
  999. void Calc3WayBlendIndices_SPU( accumposeentry_SPU *pPoseEntry, int i0, int i1, float s0, float s1, int *pAnimIndices, float *pWeight )
  1000. {
  1001. // Figure out which bi-section direction we are using to make triangles.
  1002. bool bEven = ( ( ( i0 + i1 ) & 0x1 ) == 0 );
  1003. // diagonal is between elements 1 & 3
  1004. // TL to BR
  1005. if ( bEven )
  1006. {
  1007. if ( s0 > s1 )
  1008. {
  1009. // B
  1010. pAnimIndices[0] = pPoseEntry->animIndices[0];//0;
  1011. pAnimIndices[1] = pPoseEntry->animIndices[1];//1;
  1012. pAnimIndices[2] = pPoseEntry->animIndices[3];//3;
  1013. pWeight[0] = (1.0f - s0);
  1014. pWeight[1] = s0 - s1;
  1015. }
  1016. else
  1017. {
  1018. // C
  1019. pAnimIndices[0] = pPoseEntry->animIndices[3];//3;
  1020. pAnimIndices[1] = pPoseEntry->animIndices[2];//2;
  1021. pAnimIndices[2] = pPoseEntry->animIndices[0];//0;
  1022. pWeight[0] = s0;
  1023. pWeight[1] = s1 - s0;
  1024. }
  1025. }
  1026. // BL to TR
  1027. else
  1028. {
  1029. float flTotal = s0 + s1;
  1030. if( flTotal > 1.0f )
  1031. {
  1032. // D
  1033. pAnimIndices[0] = pPoseEntry->animIndices[1];//1;
  1034. pAnimIndices[1] = pPoseEntry->animIndices[3];//3;
  1035. pAnimIndices[2] = pPoseEntry->animIndices[2];//2;
  1036. pWeight[0] = (1.0f - s1);
  1037. pWeight[1] = s0 - 1.0f + s1;
  1038. }
  1039. else
  1040. {
  1041. // A
  1042. pAnimIndices[0] = pPoseEntry->animIndices[2];//2;
  1043. pAnimIndices[1] = pPoseEntry->animIndices[0];//0;
  1044. pAnimIndices[2] = pPoseEntry->animIndices[1];//1;
  1045. pWeight[0] = s1;
  1046. pWeight[1] = 1.0f - s0 - s1;
  1047. }
  1048. }
  1049. // clamp the diagonal
  1050. if( pWeight[1] < 0.001f )
  1051. pWeight[1] = 0.0f;
  1052. pWeight[2] = 1.0f - pWeight[0] - pWeight[1];
  1053. Assert( pWeight[0] >= 0.0f && pWeight[0] <= 1.0f );
  1054. Assert( pWeight[1] >= 0.0f && pWeight[1] <= 1.0f );
  1055. Assert( pWeight[2] >= 0.0f && pWeight[2] <= 1.0f );
  1056. // fix up pose entry weights so that IK rules are blended correctly (assume they all come in as zero for the 3 way blend case)
  1057. pPoseEntry->anims[ pAnimIndices[0] ].seqdesc_weight = pWeight[0];
  1058. pPoseEntry->anims[ pAnimIndices[1] ].seqdesc_weight = pWeight[1];
  1059. pPoseEntry->anims[ pAnimIndices[2] ].seqdesc_weight = pWeight[2];
  1060. }
  1061. void C_AccumulatePose_SPU::AddLocalLayers( accumposeentry_SPU *pAccPoseEntry, BoneVector pos[], BoneQuaternion q[] )
  1062. {
  1063. for( int lp = 0; lp < pAccPoseEntry->numLocalLayers; lp++ )
  1064. {
  1065. AccumulatePose( pos, q );
  1066. }
  1067. }
  1068. void C_AccumulatePose_SPU::AddSequenceLayers( accumposeentry_SPU *pAccPoseEntry, BoneVector pos[], BoneQuaternion q[] )
  1069. {
  1070. for( int lp = 0; lp < pAccPoseEntry->numSequenceLayers; lp++ )
  1071. {
  1072. AccumulatePose( pos, q );
  1073. }
  1074. }
  1075. //-----------------------------------------------------------------------------
  1076. // Purpose: calculate a pose for a single sequence
  1077. // SPU pass
  1078. //-----------------------------------------------------------------------------
  1079. bool C_AccumulatePose_SPU::CalcPoseSingle(
  1080. const bonejob_SPU *pBonejob,
  1081. accumposeentry_SPU *pPoseEntry,
  1082. BoneVector *pos,
  1083. BoneQuaternion *q,
  1084. int *boneMap,
  1085. float *boneWeight,
  1086. int sequence,
  1087. const float poseParameter[],
  1088. int boneMask,
  1089. float flTime
  1090. )
  1091. {
  1092. SNPROF_ANIM("C_AccumulatePose_SPU::CalcPoseSingle");
  1093. bool bResult = true;
  1094. BoneVector *pos2 = (BoneVector *)PushLSStack( sizeof(BoneVector) * pBonejob->numBones );
  1095. BoneQuaternion *q2 = (BoneQuaternion *)PushLSStack( sizeof(BoneQuaternion) * pBonejob->numBones );
  1096. BoneVector *pos3 = (BoneVector *)PushLSStack( sizeof(BoneVector) * pBonejob->numBones );
  1097. BoneQuaternion *q3 = (BoneQuaternion *)PushLSStack( sizeof(BoneQuaternion) * pBonejob->numBones );
  1098. float s0 = pPoseEntry->s0;
  1099. float s1 = pPoseEntry->s1;
  1100. int i0 = pPoseEntry->i0;
  1101. int i1 = pPoseEntry->i1;
  1102. float cycle = pPoseEntry->cyclePoseSingle;
  1103. switch( pPoseEntry->cpsPath )
  1104. {
  1105. case CPSPATH_FALSE:
  1106. bResult = false;
  1107. break;
  1108. case CPSPATH_CALCANIM1:
  1109. CalcAnimation_PS3( pBonejob, pPoseEntry, pos, q, boneMap, boneWeight, pPoseEntry->animIndices[0], cycle, boneMask );
  1110. break;
  1111. case CPSPATH_CALCANIM1_SCALE1MINUSS0:
  1112. CalcAnimation_PS3( pBonejob, pPoseEntry, pos, q, boneMap, boneWeight, pPoseEntry->animIndices[0], cycle, boneMask );
  1113. ScaleBones_PS3( pBonejob, pPoseEntry, q, pos, boneMap, boneWeight, 1.0f - s0, boneMask );
  1114. break;
  1115. case CPSPATH_CALCANIM1_SCALES0:
  1116. CalcAnimation_PS3( pBonejob, pPoseEntry, pos, q, boneMap, boneWeight, pPoseEntry->animIndices[0], cycle, boneMask );
  1117. ScaleBones_PS3( pBonejob, pPoseEntry, q, pos, boneMap, boneWeight, s0, boneMask );
  1118. break;
  1119. case CPSPATH_CALCANIM2_S0:
  1120. CalcAnimation_PS3( pBonejob, pPoseEntry, pos, q, boneMap, boneWeight, pPoseEntry->animIndices[0], cycle, boneMask );
  1121. CalcAnimation_PS3( pBonejob, pPoseEntry, pos2, q2, boneMap, boneWeight, pPoseEntry->animIndices[1], cycle, boneMask );
  1122. BlendBones_PS3( pBonejob, pPoseEntry, q, pos, boneMap, boneWeight, q2, pos2, s0, boneMask );
  1123. break;
  1124. case CPSPATH_CALCANIM2_S1:
  1125. CalcAnimation_PS3( pBonejob, pPoseEntry, pos, q, boneMap, boneWeight, pPoseEntry->animIndices[0], cycle, boneMask );
  1126. CalcAnimation_PS3( pBonejob, pPoseEntry, pos2, q2, boneMap, boneWeight, pPoseEntry->animIndices[1], cycle, boneMask );
  1127. BlendBones_PS3( pBonejob, pPoseEntry, q, pos, boneMap, boneWeight, q2, pos2, s1, boneMask );
  1128. break;
  1129. case CPSPATH_CALCANIM3:
  1130. int iAnimIndices[3];
  1131. float weight[3];
  1132. Calc3WayBlendIndices_SPU( pPoseEntry, i0, i1, s0, s1, iAnimIndices, weight );
  1133. if( weight[1] < 0.001f )
  1134. {
  1135. // on diagonal
  1136. CalcAnimation_PS3( pBonejob, pPoseEntry, pos, q, boneMap, boneWeight, iAnimIndices[0], cycle, boneMask );
  1137. CalcAnimation_PS3( pBonejob, pPoseEntry, pos2, q2, boneMap, boneWeight, iAnimIndices[2], cycle, boneMask );
  1138. BlendBones_PS3( pBonejob, pPoseEntry, q, pos, boneMap, boneWeight, q2, pos2, weight[2] / (weight[0] + weight[2]), boneMask );
  1139. }
  1140. else
  1141. {
  1142. CalcAnimation_PS3( pBonejob, pPoseEntry, pos, q, boneMap, boneWeight, iAnimIndices[0], cycle, boneMask );
  1143. CalcAnimation_PS3( pBonejob, pPoseEntry, pos2, q2, boneMap, boneWeight, iAnimIndices[1], cycle, boneMask );
  1144. BlendBones_PS3( pBonejob, pPoseEntry, q, pos, boneMap, boneWeight, q2, pos2, weight[1] / (weight[0] + weight[1]), boneMask );
  1145. CalcAnimation_PS3( pBonejob, pPoseEntry, pos3, q3, boneMap, boneWeight, iAnimIndices[2], cycle, boneMask );
  1146. BlendBones_PS3( pBonejob, pPoseEntry, q, pos, boneMap, boneWeight, q3, pos3, weight[2], boneMask );
  1147. }
  1148. break;
  1149. case CPSPATH_CALCANIM4:
  1150. CalcAnimation_PS3( pBonejob, pPoseEntry, pos, q, boneMap, boneWeight, pPoseEntry->animIndices[0], cycle, boneMask );
  1151. CalcAnimation_PS3( pBonejob, pPoseEntry, pos2, q2, boneMap, boneWeight, pPoseEntry->animIndices[1], cycle, boneMask );
  1152. BlendBones_PS3( pBonejob, pPoseEntry, q, pos, boneMap, boneWeight, q2, pos2, s0, boneMask );
  1153. CalcAnimation_PS3( pBonejob, pPoseEntry, pos2, q2, boneMap, boneWeight, pPoseEntry->animIndices[2], cycle, boneMask );
  1154. CalcAnimation_PS3( pBonejob, pPoseEntry, pos3, q3, boneMap, boneWeight, pPoseEntry->animIndices[3], cycle, boneMask );
  1155. BlendBones_PS3( pBonejob, pPoseEntry, q2, pos2, boneMap, boneWeight, q3, pos3, s0, boneMask );
  1156. BlendBones_PS3( pBonejob, pPoseEntry, q, pos, boneMap, boneWeight, q2, pos2, s1, boneMask );
  1157. break;
  1158. default:
  1159. bResult = false;
  1160. break;
  1161. }
  1162. PopLSStack( sizeof(BoneQuaternion) * pBonejob->numBones );
  1163. PopLSStack( sizeof(BoneVector) * pBonejob->numBones );
  1164. PopLSStack( sizeof(BoneQuaternion) * pBonejob->numBones );
  1165. PopLSStack( sizeof(BoneVector) * pBonejob->numBones );
  1166. return bResult;
  1167. }
  1168. //-----------------------------------------------------------------------------
  1169. // SPU/bonejob version of AccumulatePose
  1170. // Assumes bonejob calls to this happen in the correct order (recursion has happened during the 1st/prep pass on PPU)
  1171. // individual AccumulatePose call data is stored in bonejob->accumPoseEntry
  1172. //-----------------------------------------------------------------------------
  1173. void C_AccumulatePose_SPU::AccumulatePose( BoneVector pos[], BoneQuaternion q[] )
  1174. {
  1175. SNPROF_ANIM("C_AccumulatePose_SPU::AccumulatePose");
  1176. accumposeentry_SPU *pPoseEntry = &m_pBoneJob->accumPoseEntry[ m_iCount++ ];
  1177. int boneMask = m_pBoneJob->boneMask;
  1178. int numBones = m_pBoneJob->numBones;
  1179. float time = m_pBoneJob->currentTime;
  1180. float *pPoseParam = m_pBoneJob->poseparam;
  1181. float weight = pPoseEntry->weight;
  1182. int sequence = pPoseEntry->iSeq;
  1183. void *pIKContext = GetIKContext();
  1184. CIKContext_PS3 seq_ik;
  1185. if( pPoseEntry->seqdesc_numiklocks )
  1186. {
  1187. //IKOFF
  1188. seq_ik.Init( m_pBoneJob, vec3_angle, vec3_origin, 0.0f, 0, boneMask );
  1189. //IKOFF
  1190. seq_ik.AddSequenceLocks( m_pBoneJob, pPoseEntry, pos, q );
  1191. }
  1192. {
  1193. BoneVector *pos2 = (BoneVector *)PushLSStack( sizeof(BoneVector) * m_pBoneJob->maxBones );
  1194. BoneQuaternion *q2 = (BoneQuaternion *)PushLSStack( sizeof(BoneQuaternion) * m_pBoneJob->maxBones );
  1195. int *pBoneMap = (int *)PushLSStack( sizeof(int) * m_pBoneJob->maxBones );
  1196. float *pBoneWeight = (float *)PushLSStack( sizeof(float) * m_pBoneJob->maxBones );
  1197. // used in calcposesingle (calcanim/calcvirtualanim) & SlerpBones
  1198. // needs to be stack based, as AddLocalLayers may recurse AccumulatePose...
  1199. GetBoneMapBoneWeight_SPU( m_pBoneJob, pPoseEntry, pBoneMap, pBoneWeight );
  1200. if( pPoseEntry->seqdesc_flags & STUDIO_LOCAL )
  1201. {
  1202. // ::init
  1203. memcpy( pos2, g_posInit, sizeof( BoneVector ) * numBones );
  1204. memcpy( q2, g_qInit, sizeof( BoneQuaternion ) * numBones );
  1205. }
  1206. if( CalcPoseSingle( m_pBoneJob, pPoseEntry, pos2, q2, pBoneMap, pBoneWeight, sequence, pPoseParam, boneMask, time ) )
  1207. {
  1208. AddLocalLayers( pPoseEntry, pos2, q2 );
  1209. SlerpBones_SPU( m_pBoneJob, pPoseEntry, q, pos, q2, pos2, pBoneMap, pBoneWeight, weight, boneMask );
  1210. }
  1211. PopLSStack( sizeof(float) * m_pBoneJob->maxBones );
  1212. PopLSStack( sizeof(int) * m_pBoneJob->maxBones );
  1213. PopLSStack( sizeof(BoneQuaternion) * m_pBoneJob->maxBones );
  1214. PopLSStack( sizeof(BoneVector) * m_pBoneJob->maxBones );
  1215. }
  1216. if( pIKContext )
  1217. {
  1218. //IKOFF
  1219. AddDependencies_SPU( m_pBoneJob, pPoseEntry, weight );
  1220. }
  1221. AddSequenceLayers( pPoseEntry, pos, q );
  1222. if( pPoseEntry->seqdesc_numiklocks )
  1223. {
  1224. //IKOFF
  1225. seq_ik.SolveSequenceLocks( m_pBoneJob, pPoseEntry, pos, q );
  1226. }
  1227. }