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.

1148 lines
36 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //===========================================================================//
  7. #include "cbase.h"
  8. #include "c_baseanimatingoverlay.h"
  9. #include "animation.h"
  10. #include "bone_setup.h"
  11. #if defined( _PS3 )
  12. #include "bone_setup_PS3.h"
  13. #endif
  14. #include "tier0/vprof.h"
  15. #include "engine/ivdebugoverlay.h"
  16. #include "datacache/imdlcache.h"
  17. #include "eventlist.h"
  18. #include "toolframework_client.h"
  19. #include "dt_utlvector_recv.h"
  20. // memdbgon must be the last include file in a .cpp file!!!
  21. #include "tier0/memdbgon.h"
  22. extern ConVar r_sequence_debug;
  23. template class CInterpolatedVar<CAnimationLayer>;
  24. mstudioevent_for_client_server_t *GetEventIndexForSequence( mstudioseqdesc_t &seqdesc );
  25. void C_AnimationLayer::SetOwner( C_BaseAnimatingOverlay *pOverlay )
  26. {
  27. m_pOwner = pOverlay;
  28. }
  29. C_BaseAnimatingOverlay *C_AnimationLayer::GetOwner() const
  30. {
  31. return m_pOwner;
  32. }
  33. void C_AnimationLayer::Reset()
  34. {
  35. if ( m_pOwner )
  36. {
  37. int nFlags = 0;
  38. if ( m_nSequence != 0 || m_flWeight != 0.0f )
  39. {
  40. nFlags |= BOUNDS_CHANGED;
  41. }
  42. if ( m_flCycle != 0.0f )
  43. {
  44. nFlags |= ANIMATION_CHANGED;
  45. }
  46. if ( nFlags )
  47. {
  48. m_pOwner->InvalidatePhysicsRecursive( nFlags );
  49. }
  50. }
  51. m_nSequence = 0;
  52. m_flPrevCycle = 0;
  53. m_flWeight = 0;
  54. m_flWeightDeltaRate = 0;
  55. m_flPlaybackRate = 0;
  56. m_flCycle = 0;
  57. m_flLayerAnimtime = 0;
  58. m_flLayerFadeOuttime = 0;
  59. }
  60. void C_AnimationLayer::SetSequence( int nSequence )
  61. {
  62. if ( m_pOwner && m_nSequence != nSequence )
  63. {
  64. m_pOwner->InvalidatePhysicsRecursive( BOUNDS_CHANGED );
  65. }
  66. m_nSequence = nSequence;
  67. }
  68. void C_AnimationLayer::SetCycle( float flCycle )
  69. {
  70. if ( m_pOwner && m_flCycle != flCycle )
  71. {
  72. m_pOwner->InvalidatePhysicsRecursive( ANIMATION_CHANGED );
  73. }
  74. m_flCycle = flCycle;
  75. }
  76. void C_AnimationLayer::SetOrder( int order )
  77. {
  78. if ( m_pOwner && ( m_nOrder != order ) )
  79. {
  80. if ( m_nOrder == C_BaseAnimatingOverlay::MAX_OVERLAYS || order == C_BaseAnimatingOverlay::MAX_OVERLAYS )
  81. {
  82. m_pOwner->InvalidatePhysicsRecursive( BOUNDS_CHANGED );
  83. }
  84. }
  85. m_nOrder = order;
  86. }
  87. void C_AnimationLayer::SetWeight( float flWeight )
  88. {
  89. if ( m_pOwner && m_flWeight != flWeight )
  90. {
  91. if ( m_flWeight == 0.0f || flWeight == 0.0f )
  92. {
  93. m_pOwner->InvalidatePhysicsRecursive( BOUNDS_CHANGED );
  94. }
  95. }
  96. m_flWeight = flWeight;
  97. }
  98. C_BaseAnimatingOverlay::C_BaseAnimatingOverlay()
  99. {
  100. // NOTE: We zero the memory in the max capacity m_Layer vector in dt_ultvector_common.h
  101. // FIXME: where does this initialization go now?
  102. // AddVar( m_Layer, &m_iv_AnimOverlay, LATCH_ANIMATION_VAR );
  103. }
  104. #undef CBaseAnimatingOverlay
  105. void RecvProxy_SequenceChanged( const CRecvProxyData *pData, void *pStruct, void *pOut )
  106. {
  107. CAnimationLayer *pLayer = (CAnimationLayer *)pStruct;
  108. if ( pLayer->GetOwner() )
  109. pLayer->GetOwner()->NotifyOnLayerChangeSequence( pLayer, pData->m_Value.m_Int );
  110. pLayer->SetSequence( pData->m_Value.m_Int );
  111. }
  112. void RecvProxy_WeightChanged( const CRecvProxyData *pData, void *pStruct, void *pOut )
  113. {
  114. CAnimationLayer *pLayer = (CAnimationLayer *)pStruct;
  115. if ( pLayer->GetOwner() )
  116. pLayer->GetOwner()->NotifyOnLayerChangeWeight( pLayer, pData->m_Value.m_Float );
  117. pLayer->SetWeight( pData->m_Value.m_Float );
  118. }
  119. void RecvProxy_WeightDeltaRateChanged( const CRecvProxyData *pData, void *pStruct, void *pOut )
  120. {
  121. CAnimationLayer *pLayer = (CAnimationLayer *)pStruct;
  122. pLayer->SetWeightDeltaRate( pData->m_Value.m_Float );
  123. }
  124. void RecvProxy_CycleChanged( const CRecvProxyData *pData, void *pStruct, void *pOut )
  125. {
  126. CAnimationLayer *pLayer = (CAnimationLayer *)pStruct;
  127. if ( pLayer->GetOwner() )
  128. pLayer->GetOwner()->NotifyOnLayerChangeCycle( pLayer, pData->m_Value.m_Float );
  129. pLayer->SetCycle( pData->m_Value.m_Float );
  130. }
  131. void RecvProxy_PlaybackRateChanged( const CRecvProxyData *pData, void *pStruct, void *pOut )
  132. {
  133. CAnimationLayer *pLayer = (CAnimationLayer *)pStruct;
  134. pLayer->SetPlaybackRate( pData->m_Value.m_Float );
  135. }
  136. void RecvProxy_OrderChanged( const CRecvProxyData *pData, void *pStruct, void *pOut )
  137. {
  138. CAnimationLayer *pLayer = (CAnimationLayer *)pStruct;
  139. pLayer->SetOrder( pData->m_Value.m_Int );
  140. }
  141. BEGIN_RECV_TABLE_NOBASE(CAnimationLayer, DT_Animationlayer)
  142. RecvPropInt( RECVINFO_NAME(m_nSequence, m_nSequence), 0, RecvProxy_SequenceChanged ),
  143. RecvPropFloat( RECVINFO_NAME(m_flCycle, m_flCycle), 0, RecvProxy_CycleChanged ),
  144. RecvPropFloat( RECVINFO_NAME(m_flPlaybackRate, m_flPlaybackRate), 0, RecvProxy_PlaybackRateChanged ),
  145. RecvPropFloat( RECVINFO_NAME(m_flPrevCycle, m_flPrevCycle)),
  146. RecvPropFloat( RECVINFO_NAME(m_flWeight, m_flWeight), 0, RecvProxy_WeightChanged ),
  147. RecvPropFloat( RECVINFO_NAME(m_flWeightDeltaRate, m_flWeightDeltaRate), 0, RecvProxy_WeightDeltaRateChanged ),
  148. RecvPropInt( RECVINFO_NAME(m_nOrder, m_nOrder), 0, RecvProxy_OrderChanged )
  149. END_RECV_TABLE()
  150. const char *s_m_iv_AnimOverlayNames[C_BaseAnimatingOverlay::MAX_OVERLAYS] =
  151. {
  152. "C_BaseAnimatingOverlay::m_iv_AnimOverlay00",
  153. "C_BaseAnimatingOverlay::m_iv_AnimOverlay01",
  154. "C_BaseAnimatingOverlay::m_iv_AnimOverlay02",
  155. "C_BaseAnimatingOverlay::m_iv_AnimOverlay03",
  156. "C_BaseAnimatingOverlay::m_iv_AnimOverlay04",
  157. "C_BaseAnimatingOverlay::m_iv_AnimOverlay05",
  158. "C_BaseAnimatingOverlay::m_iv_AnimOverlay06",
  159. "C_BaseAnimatingOverlay::m_iv_AnimOverlay07",
  160. "C_BaseAnimatingOverlay::m_iv_AnimOverlay08",
  161. "C_BaseAnimatingOverlay::m_iv_AnimOverlay09",
  162. "C_BaseAnimatingOverlay::m_iv_AnimOverlay10",
  163. "C_BaseAnimatingOverlay::m_iv_AnimOverlay11",
  164. "C_BaseAnimatingOverlay::m_iv_AnimOverlay12",
  165. "C_BaseAnimatingOverlay::m_iv_AnimOverlay13",
  166. "C_BaseAnimatingOverlay::m_iv_AnimOverlay14"
  167. };
  168. void ResizeAnimationLayerCallback( void *pStruct, int offsetToUtlVector, int len )
  169. {
  170. C_BaseAnimatingOverlay *pEnt = (C_BaseAnimatingOverlay*)pStruct;
  171. CUtlVector < CAnimationLayer > *pVec = &pEnt->m_AnimOverlay;
  172. CUtlVector< CInterpolatedVar< CAnimationLayer > > *pVecIV = &pEnt->m_iv_AnimOverlay;
  173. Assert( (char*)pVec - (char*)pEnt == offsetToUtlVector );
  174. Assert( pVec->Count() == pVecIV->Count() || pVecIV->Count() == 0 );
  175. Assert( pVec->Count() <= C_BaseAnimatingOverlay::MAX_OVERLAYS );
  176. int diff = len - pVec->Count();
  177. if ( diff != 0 )
  178. {
  179. // remove all entries
  180. for ( int i=0; i < pVec->Count(); i++ )
  181. {
  182. pEnt->RemoveVar( &pVec->Element( i ) );
  183. }
  184. pEnt->InvalidatePhysicsRecursive( BOUNDS_CHANGED );
  185. // adjust vector sizes
  186. if ( diff > 0 )
  187. {
  188. for ( int i = 0; i < diff; ++i )
  189. {
  190. int j = pVec->AddToTail( );
  191. (*pVec)[j].SetOwner( pEnt );
  192. }
  193. pVecIV->AddMultipleToTail( diff );
  194. }
  195. else
  196. {
  197. pVec->RemoveMultiple( len, -diff );
  198. pVecIV->RemoveMultiple( len, -diff );
  199. }
  200. // Rebind all the variables in the ent's list.
  201. for ( int i=0; i < len; i++ )
  202. {
  203. IInterpolatedVar *pWatcher = &pVecIV->Element( i );
  204. pWatcher->SetDebugName( s_m_iv_AnimOverlayNames[i] );
  205. pEnt->AddVar( &pVec->Element( i ), pWatcher, LATCH_ANIMATION_VAR, true );
  206. }
  207. }
  208. // FIXME: need to set historical values of nOrder in pVecIV to MAX_OVERLAY
  209. // Ensure capacity
  210. pVec->EnsureCapacity( len );
  211. int nNumAllocated = pVec->NumAllocated();
  212. // This is important to do because EnsureCapacity doesn't actually call the constructors
  213. // on the elements, but we need them to be initialized, otherwise it'll have out-of-range
  214. // values which will piss off the datatable encoder.
  215. UtlVector_InitializeAllocatedElements( pVec->Base() + pVec->Count(), nNumAllocated - pVec->Count() );
  216. }
  217. BEGIN_RECV_TABLE_NOBASE( C_BaseAnimatingOverlay, DT_OverlayVars )
  218. RecvPropUtlVector(
  219. RECVINFO_UTLVECTOR_SIZEFN( m_AnimOverlay, ResizeAnimationLayerCallback ),
  220. C_BaseAnimatingOverlay::MAX_OVERLAYS,
  221. RecvPropDataTable(NULL, 0, 0, &REFERENCE_RECV_TABLE( DT_Animationlayer ) ) )
  222. END_RECV_TABLE()
  223. IMPLEMENT_CLIENTCLASS_DT( C_BaseAnimatingOverlay, DT_BaseAnimatingOverlay, CBaseAnimatingOverlay )
  224. RecvPropDataTable( "overlay_vars", 0, 0, &REFERENCE_RECV_TABLE( DT_OverlayVars ) )
  225. END_RECV_TABLE()
  226. BEGIN_PREDICTION_DATA( C_BaseAnimatingOverlay )
  227. /*
  228. DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[0][2].m_nSequence, FIELD_INTEGER ),
  229. DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[0][2].m_flCycle, FIELD_FLOAT ),
  230. DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[0][2].m_flPlaybackRate, FIELD_FLOAT),
  231. DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[0][2].m_flWeight, FIELD_FLOAT),
  232. DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[1][2].m_nSequence, FIELD_INTEGER ),
  233. DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[1][2].m_flCycle, FIELD_FLOAT ),
  234. DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[1][2].m_flPlaybackRate, FIELD_FLOAT),
  235. DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[1][2].m_flWeight, FIELD_FLOAT),
  236. DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[2][2].m_nSequence, FIELD_INTEGER ),
  237. DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[2][2].m_flCycle, FIELD_FLOAT ),
  238. DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[2][2].m_flPlaybackRate, FIELD_FLOAT),
  239. DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[2][2].m_flWeight, FIELD_FLOAT),
  240. DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[3][2].m_nSequence, FIELD_INTEGER ),
  241. DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[3][2].m_flCycle, FIELD_FLOAT ),
  242. DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[3][2].m_flPlaybackRate, FIELD_FLOAT),
  243. DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[3][2].m_flWeight, FIELD_FLOAT),
  244. */
  245. END_PREDICTION_DATA()
  246. CAnimationLayer* C_BaseAnimatingOverlay::GetAnimOverlay( int i, bool bUseOrder )
  247. {
  248. Assert( i >= 0 && i < MAX_OVERLAYS );
  249. if ( !m_AnimOverlay.Count() )
  250. return NULL;
  251. if ( bUseOrder )
  252. {
  253. FOR_EACH_VEC( m_AnimOverlay, j )
  254. {
  255. if ( m_AnimOverlay[j].GetOrder() == i )
  256. return &m_AnimOverlay[j];
  257. }
  258. }
  259. return &m_AnimOverlay[i];
  260. }
  261. void C_BaseAnimatingOverlay::SetNumAnimOverlays( int num )
  262. {
  263. if ( m_AnimOverlay.Count() < num )
  264. {
  265. int nCountToAdd = num - m_AnimOverlay.Count();
  266. for ( int i = 0; i < nCountToAdd; ++i )
  267. {
  268. int j = m_AnimOverlay.AddToTail( );
  269. m_AnimOverlay[j].SetOwner( this );
  270. }
  271. }
  272. else if ( m_AnimOverlay.Count() > num )
  273. {
  274. m_AnimOverlay.RemoveMultiple( num, m_AnimOverlay.Count() - num );
  275. InvalidatePhysicsRecursive( BOUNDS_CHANGED );
  276. }
  277. // Ensure capacity
  278. m_AnimOverlay.EnsureCapacity( C_BaseAnimatingOverlay::MAX_OVERLAYS );
  279. int nNumAllocated = m_AnimOverlay.NumAllocated();
  280. // This is important to do because EnsureCapacity doesn't actually call the constructors
  281. // on the elements, but we need them to be initialized, otherwise it'll have out-of-range
  282. // values which will piss off the datatable encoder.
  283. UtlVector_InitializeAllocatedElements( m_AnimOverlay.Base() + m_AnimOverlay.Count(), nNumAllocated - m_AnimOverlay.Count() );
  284. }
  285. int C_BaseAnimatingOverlay::GetNumAnimOverlays() const
  286. {
  287. return m_AnimOverlay.Count();
  288. }
  289. void C_BaseAnimatingOverlay::GetRenderBounds( Vector& theMins, Vector& theMaxs )
  290. {
  291. BaseClass::GetRenderBounds( theMins, theMaxs );
  292. if ( IsRagdoll() )
  293. return;
  294. MDLCACHE_CRITICAL_SECTION();
  295. CStudioHdr *pStudioHdr = GetModelPtr();
  296. if ( !pStudioHdr || !pStudioHdr->SequencesAvailable() )
  297. return;
  298. int nSequences = pStudioHdr->GetNumSeq();
  299. int i;
  300. for (i = 0; i < m_AnimOverlay.Count(); i++)
  301. {
  302. if ( m_AnimOverlay[i].m_flWeight > 0.0 && m_AnimOverlay[i].m_nOrder != MAX_OVERLAYS )
  303. {
  304. if ( m_AnimOverlay[i].m_nSequence >= nSequences )
  305. continue;
  306. mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( m_AnimOverlay[i].m_nSequence );
  307. VectorMin( seqdesc.bbmin, theMins, theMins );
  308. VectorMax( seqdesc.bbmax, theMaxs, theMaxs );
  309. }
  310. }
  311. }
  312. bool C_BaseAnimatingOverlay::Interpolate( float flCurrentTime )
  313. {
  314. bool bOk = BaseClass::Interpolate( flCurrentTime );
  315. CheckForLayerPhysicsInvalidate();
  316. return bOk;
  317. }
  318. void C_BaseAnimatingOverlay::CheckForLayerChanges( CStudioHdr *hdr, float currentTime )
  319. {
  320. CDisableRangeChecks disableRangeChecks;
  321. // FIXME: damn, there has to be a better way than this.
  322. int i;
  323. for (i = 0; i < m_iv_AnimOverlay.Count(); i++)
  324. {
  325. CDisableRangeChecks disableRangeChecks;
  326. int iHead, iPrev1, iPrev2;
  327. m_iv_AnimOverlay[i].GetInterpolationInfo( currentTime, &iHead, &iPrev1, &iPrev2 );
  328. // fake up previous cycle values.
  329. float t0;
  330. CAnimationLayer *pHead = m_iv_AnimOverlay[i].GetHistoryValue( iHead, t0 );
  331. // reset previous
  332. float t1;
  333. CAnimationLayer *pPrev1 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev1, t1 );
  334. // reset previous previous
  335. float t2;
  336. CAnimationLayer *pPrev2 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev2, t2 );
  337. if ( !pHead || !pPrev1 || pHead->m_nSequence == pPrev1->m_nSequence )
  338. continue;
  339. #if 1 // _DEBUG
  340. if (r_sequence_debug.GetInt() == entindex())
  341. {
  342. DevMsgRT( "(%7.4f : %30s : %5.3f : %4.2f : %1d)\n", t0, hdr->pSeqdesc( pHead->m_nSequence ).pszLabel(), (float)pHead->m_flCycle, (float)pHead->m_flWeight, i );
  343. DevMsgRT( "(%7.4f : %30s : %5.3f : %4.2f : %1d)\n", t1, hdr->pSeqdesc( pPrev1->m_nSequence ).pszLabel(), (float)pPrev1->m_flCycle, (float)pPrev1->m_flWeight, i );
  344. if (pPrev2)
  345. DevMsgRT( "(%7.4f : %30s : %5.3f : %4.2f : %1d)\n", t2, hdr->pSeqdesc( pPrev2->m_nSequence ).pszLabel(), (float)pPrev2->m_flCycle, (float)pPrev2->m_flWeight, i );
  346. }
  347. #endif
  348. pPrev1->m_nSequence = pHead->m_nSequence;
  349. pPrev1->m_flCycle = pHead->m_flPrevCycle;
  350. pPrev1->m_flWeight = pHead->m_flWeight;
  351. if (pPrev2)
  352. {
  353. float num = 0;
  354. if ( fabs( t0 - t1 ) > 0.001f )
  355. num = (t2 - t1) / (t0 - t1);
  356. pPrev2->m_nSequence = pHead->m_nSequence;
  357. float flTemp;
  358. if (IsSequenceLooping( hdr, pHead->m_nSequence ))
  359. {
  360. flTemp = LoopingLerp( num, (float)pHead->m_flPrevCycle, (float)pHead->m_flCycle );
  361. }
  362. else
  363. {
  364. flTemp = Lerp( num, (float)pHead->m_flPrevCycle, (float)pHead->m_flCycle );
  365. }
  366. pPrev2->m_flCycle = flTemp;
  367. pPrev2->m_flWeight = pHead->m_flWeight;
  368. }
  369. /*
  370. if (stricmp( r_seq_overlay_debug.GetString(), hdr->name ) == 0)
  371. {
  372. DevMsgRT( "(%30s %6.2f : %6.2f : %6.2f)\n", hdr->pSeqdesc( pHead->nSequence ).pszLabel(), (float)pPrev2->m_flCycle, (float)pPrev1->m_flCycle, (float)pHead->m_flCycle );
  373. }
  374. */
  375. m_iv_AnimOverlay[i].SetLooping( IsSequenceLooping( hdr, pHead->m_nSequence ) );
  376. m_iv_AnimOverlay[i].Interpolate( currentTime );
  377. // reset event indexes
  378. m_flOverlayPrevEventCycle[i] = pHead->m_flPrevCycle - 0.01;
  379. }
  380. }
  381. //#define DEBUG_TF2_OVERLAYS
  382. void C_BaseAnimatingOverlay::AccumulateLayers( IBoneSetup &boneSetup, BoneVector pos[], BoneQuaternion q[], float currentTime )
  383. {
  384. BaseClass::AccumulateLayers( boneSetup, pos, q, currentTime );
  385. int i;
  386. // resort the layers
  387. int layer[MAX_OVERLAYS];
  388. for (i = 0; i < MAX_OVERLAYS; i++)
  389. {
  390. layer[i] = MAX_OVERLAYS;
  391. }
  392. for (i = 0; i < m_AnimOverlay.Count(); i++)
  393. {
  394. CAnimationLayer *pLayer = GetAnimOverlay( i );
  395. if ( pLayer )
  396. {
  397. layer[i] = clamp( pLayer->GetOrder(), 0, MAX_OVERLAYS - 1 );
  398. }
  399. }
  400. CheckForLayerChanges( boneSetup.GetStudioHdr(), currentTime );
  401. int nSequences = boneSetup.GetStudioHdr()->GetNumSeq();
  402. // add in the overlay layers
  403. int j;
  404. for (j = 0; j < MAX_OVERLAYS; j++)
  405. {
  406. i = layer[ j ];
  407. if ( i >= m_AnimOverlay.Count() )
  408. {
  409. #if defined( DEBUG_TF2_OVERLAYS )
  410. engine->Con_NPrintf( 10 + j, "%30s %6.2f : %6.2f : %1d", " ", 0.f, 0.f, i );
  411. #endif
  412. continue;
  413. }
  414. if ( m_AnimOverlay[i].m_nSequence >= nSequences )
  415. continue;
  416. /*
  417. DevMsgRT( 1 , "%.3f %.3f %.3f\n", currentTime, fWeight, dadt );
  418. debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), -j - 1, 0,
  419. "%2d(%s) : %6.2f : %6.2f",
  420. m_AnimOverlay[i].m_nSequence,
  421. boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence )->pszLabel(),
  422. m_AnimOverlay[i].m_flCycle,
  423. m_AnimOverlay[i].m_flWeight
  424. );
  425. */
  426. float fWeight = m_AnimOverlay[i].m_flWeight;
  427. if ( fWeight <= 0.0f )
  428. {
  429. #if defined( DEBUG_TF2_OVERLAYS )
  430. engine->Con_NPrintf( 10 + j, "%30s %6.2f : %6.2f : %1d", " ", 0.f, 0.f, i );
  431. #endif
  432. continue;
  433. }
  434. // check to see if the sequence changed
  435. // FIXME: move this to somewhere more reasonable
  436. // do a nice spline interpolation of the values
  437. // if ( m_AnimOverlay[i].m_nSequence != m_iv_AnimOverlay.GetPrev( i )->nSequence )
  438. float fCycle = m_AnimOverlay[ i ].m_flCycle;
  439. fCycle = ClampCycle( fCycle, IsSequenceLooping( m_AnimOverlay[i].m_nSequence ) );
  440. if ( !IsFinite( fCycle ) )
  441. {
  442. AssertMsg( false, "fCycle is nan!" );
  443. fCycle = 0;
  444. }
  445. if (fWeight > 1.0f)
  446. {
  447. fWeight = 1.0f;
  448. }
  449. boneSetup.AccumulatePose( pos, q, m_AnimOverlay[i].m_nSequence, fCycle, fWeight, currentTime, m_pIk );
  450. #if defined( DEBUG_TF2_OVERLAYS )
  451. engine->Con_NPrintf( 10 + j, "%30s %6.2f : %6.2f : %1d", boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i );
  452. #endif
  453. #if 1 // _DEBUG
  454. if (r_sequence_debug.GetInt() == entindex())
  455. {
  456. if (1)
  457. {
  458. DevMsgRT( "%8.4f : %30s : %5.3f : %4.2f : %1d\n", currentTime, boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i );
  459. }
  460. else
  461. {
  462. int iHead, iPrev1, iPrev2;
  463. m_iv_AnimOverlay[i].GetInterpolationInfo( currentTime, &iHead, &iPrev1, &iPrev2 );
  464. // fake up previous cycle values.
  465. float t0;
  466. CAnimationLayer *pHead = m_iv_AnimOverlay[i].GetHistoryValue( iHead, t0 );
  467. // reset previous
  468. float t1;
  469. CAnimationLayer *pPrev1 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev1, t1 );
  470. // reset previous previous
  471. float t2;
  472. CAnimationLayer *pPrev2 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev2, t2 );
  473. if ( pHead && pPrev1 && pPrev2 )
  474. {
  475. DevMsgRT( "%6.2f : %30s %6.2f (%6.2f:%6.2f:%6.2f) : %6.2f (%6.2f:%6.2f:%6.2f) : %1d\n", currentTime, boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(),
  476. fCycle, (float)pPrev2->m_flCycle, (float)pPrev1->m_flCycle, (float)pHead->m_flCycle,
  477. fWeight, (float)pPrev2->m_flWeight, (float)pPrev1->m_flWeight, (float)pHead->m_flWeight,
  478. i );
  479. }
  480. else
  481. {
  482. DevMsgRT( "%6.2f : %30s %6.2f : %6.2f : %1d\n", currentTime, boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i );
  483. }
  484. }
  485. }
  486. #endif
  487. }
  488. //RegenerateDispatchedLayers( boneSetup, pos, q, currentTime );
  489. }
  490. //-----------------------------------------------------------------------------
  491. // Purpose: Check to see if the sequence or weapon changed, if so find a matching sequence or clear the dispatch
  492. //-----------------------------------------------------------------------------
  493. bool C_BaseAnimatingOverlay::UpdateDispatchLayer( CAnimationLayer *pLayer, CStudioHdr *pWeaponStudioHdr, int iSequence )
  494. {
  495. if ( !pWeaponStudioHdr || !pLayer )
  496. {
  497. if ( pLayer )
  498. pLayer->m_nDispatchedDst = ACT_INVALID;
  499. return false;
  500. }
  501. if ( pLayer->m_pDispatchedStudioHdr != pWeaponStudioHdr || pLayer->m_nDispatchedSrc != iSequence || pLayer->m_nDispatchedDst >= pWeaponStudioHdr->GetNumSeq() )
  502. {
  503. pLayer->m_pDispatchedStudioHdr = pWeaponStudioHdr;
  504. pLayer->m_nDispatchedSrc = iSequence;
  505. if ( pWeaponStudioHdr )
  506. {
  507. const char *pszLayerName = GetSequenceName( iSequence );
  508. pLayer->m_nDispatchedDst = pWeaponStudioHdr->LookupSequence( pszLayerName );
  509. }
  510. else
  511. {
  512. pLayer->m_nDispatchedDst = ACT_INVALID;
  513. }
  514. }
  515. return (pLayer->m_nDispatchedDst != ACT_INVALID );
  516. }
  517. //-----------------------------------------------------------------------------
  518. // Purpose: Play overlay sequences on dispatched model, merge results back to parent model
  519. //-----------------------------------------------------------------------------
  520. void C_BaseAnimatingOverlay::AccumulateInterleavedDispatchedLayers( C_BaseAnimatingOverlay *pWeapon, IBoneSetup &boneSetup, BoneVector pos[], BoneQuaternion q[], float currentTime, bool bSetupInvisibleWeapon /* = false */ )
  521. {
  522. bool bSetupWeapon = pWeapon != NULL && pWeapon->m_pBoneMergeCache != NULL && (pWeapon->IsVisible() || bSetupInvisibleWeapon) ;
  523. // reset event frame indices, etc
  524. CheckForLayerChanges( boneSetup.GetStudioHdr(), currentTime );
  525. if ( bSetupWeapon )
  526. {
  527. CStudioHdr *pWeaponStudioHdr = pWeapon->GetModelPtr();
  528. // copy matching player pose params to weapon pose params
  529. pWeapon->m_pBoneMergeCache->MergeMatchingPoseParams();
  530. float poseparam[MAXSTUDIOPOSEPARAM];
  531. pWeapon->GetPoseParameters( pWeaponStudioHdr, poseparam );
  532. // build a temporary setup for the weapon
  533. CIKContext weaponIK;
  534. weaponIK.Init( pWeaponStudioHdr, GetAbsAngles(), GetAbsOrigin(), gpGlobals->curtime, 0, BONE_USED_BY_BONE_MERGE );
  535. IBoneSetup weaponSetup( pWeaponStudioHdr, BONE_USED_BY_BONE_MERGE, poseparam );
  536. BoneVector weaponPos[MAXSTUDIOBONES];
  537. BoneQuaternionAligned weaponQ[MAXSTUDIOBONES];
  538. int nSequences = boneSetup.GetStudioHdr()->GetNumSeq();
  539. for ( int nLayerIdx = 0; nLayerIdx < GetNumAnimOverlays(); nLayerIdx++ )
  540. {
  541. CAnimationLayer *pLayer = GetAnimOverlay(nLayerIdx);
  542. if ( pLayer->GetSequence() <= 1 || pLayer->GetSequence() >= nSequences || pLayer->GetWeight() <= 0 )
  543. continue;
  544. float fCycle = pLayer->GetCycle();
  545. fCycle = ClampCycle( fCycle, IsSequenceLooping( pLayer->GetSequence() ) );
  546. UpdateDispatchLayer( pLayer, pWeaponStudioHdr, pLayer->GetSequence() );
  547. if ( pLayer->m_nDispatchedDst > 0 && pLayer->m_nDispatchedDst < pWeaponStudioHdr->GetNumSeq() )
  548. {
  549. // copy player bones to weapon setup bones
  550. pWeapon->m_pBoneMergeCache->CopyFromFollow( pos, q, BONE_USED_BY_BONE_MERGE, weaponPos, weaponQ );
  551. // respect ik rules on archetypal sequence, even if we're not playing it
  552. //mstudioseqdesc_t &seqdesc = ((CStudioHdr *)m_pStudioHdr)->pSeqdesc( pLayer->GetSequence() );
  553. //m_pIk->AddDependencies( seqdesc, pLayer->GetSequence(), pLayer->GetCycle(), m_flPoseParameter, pLayer->GetWeight() );
  554. // now that the weapon bones are in the position of the current player bones, set up the weapon animation onto that
  555. weaponSetup.AccumulatePose( weaponPos, weaponQ, pLayer->m_nDispatchedDst, pLayer->GetCycle(), pLayer->GetWeight(), currentTime, &weaponIK );
  556. //DrawSkeleton( this->GetModelPtr(), BONE_USED_BY_ANYTHING );
  557. //pWeapon->DrawSkeleton( pWeaponStudioHdr, BONE_USED_BY_ANYTHING );
  558. // merge weapon bones back
  559. pWeapon->m_pBoneMergeCache->CopyToFollow( weaponPos, weaponQ, BONE_USED_BY_BONE_MERGE, pos, q );
  560. weaponIK.CopyTo( m_pIk, pWeapon->m_pBoneMergeCache->GetRawIndexMapping() );
  561. }
  562. else
  563. {
  564. boneSetup.AccumulatePose( pos, q, pLayer->GetSequence(), fCycle, pLayer->GetWeight(), currentTime, m_pIk );
  565. }
  566. }
  567. //if ( bRanAnyWeaponLayers )
  568. //{
  569. //
  570. //
  571. // CBoneBitList boneComputed;
  572. //
  573. // pWeapon->UpdateIKLocks( currentTime );
  574. // weaponIK.UpdateTargets( pos, q, pWeapon->m_BoneAccessor.GetBoneArrayForWrite(), boneComputed );
  575. //
  576. // pWeapon->CalculateIKLocks( currentTime );
  577. // weaponIK.SolveDependencies( pos, q, pWeapon->m_BoneAccessor.GetBoneArrayForWrite(), boneComputed );
  578. //
  579. //}
  580. }
  581. else
  582. {
  583. int nSequences = boneSetup.GetStudioHdr()->GetNumSeq();
  584. for ( int nLayerIdx = 0; nLayerIdx < GetNumAnimOverlays(); nLayerIdx++ )
  585. {
  586. CAnimationLayer *pLayer = GetAnimOverlay(nLayerIdx);
  587. if ( pLayer->GetSequence() < 0 || pLayer->GetSequence() >= nSequences || pLayer->GetWeight() <= 0 )
  588. continue;
  589. float fCycle = pLayer->GetCycle();
  590. fCycle = ClampCycle( fCycle, IsSequenceLooping( pLayer->GetSequence() ) );
  591. boneSetup.AccumulatePose( pos, q, pLayer->GetSequence(), fCycle, pLayer->GetWeight(), currentTime, m_pIk );
  592. }
  593. }
  594. }
  595. void C_BaseAnimatingOverlay::AccumulateDispatchedLayers( C_BaseAnimatingOverlay *pWeapon, CStudioHdr *pWeaponStudioHdr, IBoneSetup &boneSetup, BoneVector pos[], BoneQuaternion q[], float currentTime )
  596. {
  597. if ( !pWeapon->m_pBoneMergeCache )
  598. return;
  599. if ( !pWeapon->IsVisible() )
  600. return;
  601. // copy matching player pose params to weapon pose params
  602. pWeapon->m_pBoneMergeCache->MergeMatchingPoseParams();
  603. float poseparam[MAXSTUDIOPOSEPARAM];
  604. pWeapon->GetPoseParameters( pWeaponStudioHdr, poseparam );
  605. // build a temporary setup for the weapon
  606. CIKContext weaponIK;
  607. weaponIK.Init( pWeaponStudioHdr, GetAbsAngles(), GetAbsOrigin(), gpGlobals->curtime, 0, BONE_USED_BY_BONE_MERGE );
  608. IBoneSetup weaponSetup( pWeaponStudioHdr, BONE_USED_BY_BONE_MERGE, poseparam );
  609. BoneVector weaponPos[MAXSTUDIOBONES];
  610. BoneQuaternionAligned weaponQ[MAXSTUDIOBONES];
  611. // copy player bones to weapon setup bones
  612. pWeapon->m_pBoneMergeCache->CopyFromFollow( pos, q, BONE_USED_BY_BONE_MERGE, weaponPos, weaponQ );
  613. // do layer animations
  614. // FIXME: some of the layers are player layers, not weapon layers
  615. // FIXME: how to interleave?
  616. for ( int i=0; i < GetNumAnimOverlays(); i++ )
  617. {
  618. CAnimationLayer *pLayer = GetAnimOverlay( i );
  619. if ( pLayer->GetOrder() >= MAX_OVERLAYS || pLayer->GetSequence() <= 1 || pLayer->GetWeight() <= 0.0f )
  620. continue;
  621. UpdateDispatchLayer( pLayer, pWeaponStudioHdr, pLayer->GetSequence() );
  622. if ( pLayer->m_nDispatchedDst > 0 && pLayer->m_nDispatchedDst < pWeaponStudioHdr->GetNumSeq() )
  623. {
  624. weaponSetup.AccumulatePose( weaponPos, weaponQ, pLayer->m_nDispatchedDst, pLayer->GetCycle(), pLayer->GetWeight(), currentTime, &weaponIK );
  625. }
  626. }
  627. // FIXME: merge weaponIK into m_pIK
  628. CBoneBitList boneComputed;
  629. pWeapon->UpdateIKLocks( currentTime );
  630. weaponIK.UpdateTargets( weaponPos, weaponQ, pWeapon->m_BoneAccessor.GetBoneArrayForWrite(), boneComputed );
  631. pWeapon->CalculateIKLocks( currentTime );
  632. weaponIK.SolveDependencies( weaponPos, weaponQ, pWeapon->m_BoneAccessor.GetBoneArrayForWrite(), boneComputed );
  633. // merge weapon bones back
  634. pWeapon->m_pBoneMergeCache->CopyToFollow( weaponPos, weaponQ, BONE_USED_BY_BONE_MERGE, pos, q );
  635. }
  636. //-----------------------------------------------------------------------------
  637. // Purpose: Duplicate parent models dispatched overlay sequences so that any local bones get animated
  638. //-----------------------------------------------------------------------------
  639. void C_BaseAnimatingOverlay::RegenerateDispatchedLayers( IBoneSetup &boneSetup, BoneVector pos[], BoneQuaternion q[], float currentTime )
  640. {
  641. // find who I'm following and see if I'm their dispatched model
  642. if ( m_pBoneMergeCache && m_pBoneMergeCache->IsCopied() )
  643. {
  644. C_BaseEntity *pFollowEnt = GetFollowedEntity();
  645. if ( pFollowEnt )
  646. {
  647. C_BaseAnimatingOverlay *pFollow = pFollowEnt->GetBaseAnimatingOverlay();
  648. if ( pFollow )
  649. {
  650. for ( int i=0; i < pFollow->GetNumAnimOverlays(); i++ )
  651. {
  652. CAnimationLayer *pLayer = pFollow->GetAnimOverlay( i );
  653. if ( pLayer->m_pDispatchedStudioHdr == NULL || pLayer->GetOrder() >= MAX_OVERLAYS || pLayer->GetSequence() == -1 || pLayer->GetWeight() <= 0.0f )
  654. continue;
  655. // FIXME: why do the CStudioHdr's not match?
  656. if ( pLayer->m_pDispatchedStudioHdr->GetRenderHdr() == boneSetup.GetStudioHdr()->GetRenderHdr() )
  657. {
  658. if ( pLayer->m_nDispatchedDst != ACT_INVALID )
  659. {
  660. boneSetup.AccumulatePose( pos, q, pLayer->m_nDispatchedDst, pLayer->m_flCycle, pLayer->m_flWeight, currentTime, m_pIk );
  661. }
  662. }
  663. }
  664. }
  665. }
  666. }
  667. }
  668. #if defined( _PS3 )
  669. void C_BaseAnimatingOverlay::AccumulateLayers_AddPoseCalls( IBoneSetup_PS3 &boneSetup, BoneVector pos[], BoneQuaternion q[], float currentTime )
  670. {
  671. BaseClass::AccumulateLayers_AddPoseCalls( boneSetup, pos, q, currentTime );
  672. int i;
  673. // resort the layers
  674. int layer[MAX_OVERLAYS];
  675. for (i = 0; i < MAX_OVERLAYS; i++)
  676. {
  677. layer[i] = MAX_OVERLAYS;
  678. }
  679. for (i = 0; i < m_AnimOverlay.Count(); i++)
  680. {
  681. if (m_AnimOverlay[i].m_nOrder < MAX_OVERLAYS)
  682. {
  683. /*
  684. Assert( layer[m_AnimOverlay[i].m_nOrder] == MAX_OVERLAYS );
  685. layer[m_AnimOverlay[i].m_nOrder] = i;
  686. */
  687. // hacky code until initialization of new layers is finished
  688. if ( layer[m_AnimOverlay[i].m_nOrder] != MAX_OVERLAYS )
  689. {
  690. m_AnimOverlay[i].SetOrder( MAX_OVERLAYS );
  691. }
  692. else
  693. {
  694. layer[m_AnimOverlay[i].m_nOrder] = i;
  695. }
  696. }
  697. }
  698. CheckForLayerChanges( boneSetup.GetStudioHdr(), currentTime );
  699. int nSequences = boneSetup.GetStudioHdr()->GetNumSeq();
  700. // add in the overlay layers
  701. int j;
  702. for (j = 0; j < MAX_OVERLAYS; j++)
  703. {
  704. i = layer[ j ];
  705. if ( i >= m_AnimOverlay.Count() )
  706. {
  707. #if defined( DEBUG_TF2_OVERLAYS )
  708. engine->Con_NPrintf( 10 + j, "%30s %6.2f : %6.2f : %1d", " ", 0.f, 0.f, i );
  709. #endif
  710. continue;
  711. }
  712. if ( m_AnimOverlay[i].m_nSequence >= nSequences )
  713. continue;
  714. /*
  715. DevMsgRT( 1 , "%.3f %.3f %.3f\n", currentTime, fWeight, dadt );
  716. debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), -j - 1, 0,
  717. "%2d(%s) : %6.2f : %6.2f",
  718. m_AnimOverlay[i].m_nSequence,
  719. boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence )->pszLabel(),
  720. m_AnimOverlay[i].m_flCycle,
  721. m_AnimOverlay[i].m_flWeight
  722. );
  723. */
  724. float fWeight = m_AnimOverlay[i].m_flWeight;
  725. if ( fWeight <= 0.0f )
  726. {
  727. #if defined( DEBUG_TF2_OVERLAYS )
  728. engine->Con_NPrintf( 10 + j, "%30s %6.2f : %6.2f : %1d", " ", 0.f, 0.f, i );
  729. #endif
  730. continue;
  731. }
  732. // check to see if the sequence changed
  733. // FIXME: move this to somewhere more reasonable
  734. // do a nice spline interpolation of the values
  735. // if ( m_AnimOverlay[i].m_nSequence != m_iv_AnimOverlay.GetPrev( i )->nSequence )
  736. float fCycle = m_AnimOverlay[ i ].m_flCycle;
  737. fCycle = ClampCycle( fCycle, IsSequenceLooping( m_AnimOverlay[i].m_nSequence ) );
  738. if (fWeight > 1.0f)
  739. {
  740. fWeight = 1.0f;
  741. }
  742. // boneSetup.AccumulatePose( pos, q, m_AnimOverlay[i].m_nSequence, fCycle, fWeight, currentTime, m_pIk );
  743. boneSetup.AccumulatePose_AddToBoneJob( boneSetup.GetBoneJobSPU(), m_AnimOverlay[i].m_nSequence, fCycle, fWeight, m_pIk, 0 );
  744. #if defined( DEBUG_TF2_OVERLAYS )
  745. engine->Con_NPrintf( 10 + j, "%30s %6.2f : %6.2f : %1d", boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i );
  746. #endif
  747. #if 1 // _DEBUG
  748. if (r_sequence_debug.GetInt() == entindex())
  749. {
  750. if (1)
  751. {
  752. DevMsgRT( "%8.4f : %30s : %5.3f : %4.2f : %1d\n", currentTime, boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i );
  753. }
  754. else
  755. {
  756. int iHead, iPrev1, iPrev2;
  757. m_iv_AnimOverlay[i].GetInterpolationInfo( currentTime, &iHead, &iPrev1, &iPrev2 );
  758. // fake up previous cycle values.
  759. float t0;
  760. CAnimationLayer *pHead = m_iv_AnimOverlay[i].GetHistoryValue( iHead, t0 );
  761. // reset previous
  762. float t1;
  763. CAnimationLayer *pPrev1 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev1, t1 );
  764. // reset previous previous
  765. float t2;
  766. CAnimationLayer *pPrev2 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev2, t2 );
  767. if ( pHead && pPrev1 && pPrev2 )
  768. {
  769. DevMsgRT( "%6.2f : %30s %6.2f (%6.2f:%6.2f:%6.2f) : %6.2f (%6.2f:%6.2f:%6.2f) : %1d\n", currentTime, boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(),
  770. fCycle, (float)pPrev2->m_flCycle, (float)pPrev1->m_flCycle, (float)pHead->m_flCycle,
  771. fWeight, (float)pPrev2->m_flWeight, (float)pPrev1->m_flWeight, (float)pHead->m_flWeight,
  772. i );
  773. }
  774. else
  775. {
  776. DevMsgRT( "%6.2f : %30s %6.2f : %6.2f : %1d\n", currentTime, boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i );
  777. }
  778. }
  779. }
  780. #endif
  781. }
  782. }
  783. #endif // _PS3
  784. void C_BaseAnimatingOverlay::DoAnimationEvents( CStudioHdr *pStudioHdr )
  785. {
  786. MDLCACHE_CRITICAL_SECTION();
  787. if ( !pStudioHdr || !pStudioHdr->SequencesAvailable() )
  788. return;
  789. int nSequences = pStudioHdr->GetNumSeq();
  790. BaseClass::DoAnimationEvents( pStudioHdr );
  791. bool watch = false; // Q_strstr( hdr->name, "rifle" ) ? true : false;
  792. CheckForLayerChanges( pStudioHdr, gpGlobals->curtime ); // !!!
  793. int j;
  794. for (j = 0; j < m_AnimOverlay.Count(); j++)
  795. {
  796. if ( m_AnimOverlay[j].m_nSequence < 0 || m_AnimOverlay[j].m_nSequence >= nSequences )
  797. {
  798. continue;
  799. }
  800. // Don't bother with 0-weight layers
  801. if ( m_AnimOverlay[j].m_flWeight == 0.0f || m_AnimOverlay[j].m_nOrder == MAX_OVERLAYS )
  802. {
  803. continue;
  804. }
  805. mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( m_AnimOverlay[j].m_nSequence );
  806. if ( seqdesc.numevents == 0 )
  807. continue;
  808. // stalled?
  809. if (m_AnimOverlay[j].m_flCycle == m_flOverlayPrevEventCycle[j])
  810. continue;
  811. bool bLoopingSequence = IsSequenceLooping( m_AnimOverlay[j].m_nSequence );
  812. bool bLooped = false;
  813. //in client code, m_flOverlayPrevEventCycle is set to -1 when we first start an overlay, looping or not
  814. if ( bLoopingSequence &&
  815. m_flOverlayPrevEventCycle[j] > 0.0f &&
  816. m_AnimOverlay[j].m_flCycle <= m_flOverlayPrevEventCycle[j] )
  817. {
  818. if (m_flOverlayPrevEventCycle[j] - m_AnimOverlay[j].m_flCycle > 0.5)
  819. {
  820. bLooped = true;
  821. }
  822. else
  823. {
  824. // things have backed up, which is bad since it'll probably result in a hitch in the animation playback
  825. // but, don't play events again for the same time slice
  826. return;
  827. }
  828. }
  829. mstudioevent_t *pevent = GetEventIndexForSequence( seqdesc );
  830. // This makes sure events that occur at the end of a sequence occur are
  831. // sent before events that occur at the beginning of a sequence.
  832. if (bLooped)
  833. {
  834. for (int i = 0; i < (int)seqdesc.numevents; i++)
  835. {
  836. // ignore all non-client-side events
  837. if ( pevent[i].type & AE_TYPE_NEWEVENTSYSTEM )
  838. {
  839. if ( !(pevent[i].type & AE_TYPE_CLIENT) )
  840. continue;
  841. }
  842. else if ( pevent[i].Event_OldSystem() < EVENT_CLIENT ) //Adrian - Support the old event system
  843. continue;
  844. if ( pevent[i].cycle <= m_flOverlayPrevEventCycle[j] )
  845. continue;
  846. if ( watch )
  847. {
  848. Msg( "%i FE %i Looped cycle %f, prev %f ev %f (time %.3f)\n",
  849. gpGlobals->tickcount,
  850. pevent[i].Event(),
  851. pevent[i].cycle,
  852. (float)m_flOverlayPrevEventCycle[j],
  853. (float)m_AnimOverlay[j].m_flCycle,
  854. gpGlobals->curtime );
  855. }
  856. FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].Event(), pevent[ i ].pszOptions() );
  857. }
  858. // Necessary to get the next loop working
  859. m_flOverlayPrevEventCycle[j] = -0.01;
  860. }
  861. for (int i = 0; i < (int)seqdesc.numevents; i++)
  862. {
  863. if ( pevent[i].type & AE_TYPE_NEWEVENTSYSTEM )
  864. {
  865. if ( !(pevent[i].type & AE_TYPE_CLIENT) )
  866. continue;
  867. }
  868. else if ( pevent[i].Event_OldSystem() < EVENT_CLIENT ) //Adrian - Support the old event system
  869. continue;
  870. bool bStartedSequence = ( m_flOverlayPrevEventCycle[j] > m_AnimOverlay[j].m_flCycle || m_flOverlayPrevEventCycle[j] == 0 );
  871. if ( ( ( pevent[i].cycle > m_flOverlayPrevEventCycle[j] || bStartedSequence && pevent[i].cycle == 0 ) && pevent[i].cycle <= m_AnimOverlay[j].m_flCycle) )
  872. {
  873. if ( watch )
  874. {
  875. Msg( "%i (seq: %d) FE %i Normal cycle %f, prev %f ev %f (time %.3f)\n",
  876. gpGlobals->tickcount,
  877. (int)m_AnimOverlay[j].m_nSequence,
  878. (int)pevent[i].Event(),
  879. (float)pevent[i].cycle,
  880. (float)m_flOverlayPrevEventCycle[j],
  881. (float)m_AnimOverlay[j].m_flCycle,
  882. gpGlobals->curtime );
  883. }
  884. FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].Event(), pevent[ i ].pszOptions() );
  885. }
  886. }
  887. m_flOverlayPrevEventCycle[j] = m_AnimOverlay[j].m_flCycle;
  888. }
  889. }
  890. //-----------------------------------------------------------------------------
  891. // Purpose:
  892. //-----------------------------------------------------------------------------
  893. CStudioHdr *C_BaseAnimatingOverlay::OnNewModel()
  894. {
  895. CStudioHdr *hdr = BaseClass::OnNewModel();
  896. //// Clear out animation layers
  897. //for ( int i=0; i < m_AnimOverlay.Count(); i++ )
  898. //{
  899. // m_AnimOverlay[i].Reset();
  900. // m_AnimOverlay[i].m_nOrder = MAX_OVERLAYS;
  901. //}
  902. return hdr;
  903. }
  904. //-----------------------------------------------------------------------------
  905. // Purpose:
  906. //-----------------------------------------------------------------------------
  907. void C_BaseAnimatingOverlay::CheckInterpChanges( void )
  908. {
  909. CDisableRangeChecks disableRangeChecks;
  910. for (int i = 0; i < m_AnimOverlay.Count(); i++)
  911. {
  912. int iHead, iPrev1, iPrev2;
  913. m_iv_AnimOverlay[i].GetInterpolationInfo( gpGlobals->curtime, &iHead, &iPrev1, &iPrev2 );
  914. float t0;
  915. CAnimationLayer *pHead = m_iv_AnimOverlay[i].GetHistoryValue( iHead, t0 );
  916. float t1;
  917. CAnimationLayer *pPrev = m_iv_AnimOverlay[i].GetHistoryValue( iPrev1, t1 );
  918. if ( !pHead || !pPrev )
  919. continue;
  920. m_AnimOverlay[ i ].m_nInvalidatePhysicsBits = CheckForSequenceBoxChanges( *pHead, *pPrev );
  921. }
  922. CheckForLayerPhysicsInvalidate();
  923. }
  924. void C_BaseAnimatingOverlay::CheckForLayerPhysicsInvalidate( void )
  925. {
  926. // When the layers interpolate they may change the animation or bbox so we
  927. // have them accumulate the changes and call InvalidatePhysicsRecursive if any
  928. // changes are needed.
  929. int nInvalidatePhysicsChangeBits = 0;
  930. int nLayerCount = m_AnimOverlay.Count();
  931. for ( int i = 0; i < nLayerCount; ++i )
  932. {
  933. int nChangeBits = m_AnimOverlay[ i ].m_nInvalidatePhysicsBits;
  934. if ( nChangeBits )
  935. {
  936. nInvalidatePhysicsChangeBits |= nChangeBits;
  937. continue;
  938. }
  939. }
  940. if ( nInvalidatePhysicsChangeBits )
  941. {
  942. InvalidatePhysicsRecursive( nInvalidatePhysicsChangeBits );
  943. }
  944. }