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.

969 lines
29 KiB

  1. //===== Copyright (c) 1996-2009, Valve Corporation, All rights reserved. ====
  2. //
  3. // Animation commands
  4. //
  5. //==========================================================================
  6. // Valve includes
  7. #include "datamodel/dmelementfactoryhelper.h"
  8. #include "mdlobjects/dmeanimationassemblycommand.h"
  9. #include "mdlobjects/dmebonemask.h"
  10. #include "mdlobjects/dmesequence.h"
  11. #include "mdlobjects/mpp_utils.h"
  12. #include "bone_setup.h"
  13. // memdbgon must be the last include file in a .cpp file!!!
  14. #include "tier0/memdbgon.h"
  15. //-----------------------------------------------------------------------------
  16. //
  17. //-----------------------------------------------------------------------------
  18. DEFINE_LOGGING_CHANNEL_NO_TAGS( LOG_DME_AAC, "DmeAnimationAssemblyCommand" );
  19. //-----------------------------------------------------------------------------
  20. // Get the CDmeSequence & CDmeChannelsClip from the specified CDmElement
  21. //-----------------------------------------------------------------------------
  22. static bool ConvertToDmeSequenceAndDmeChannelsClip(
  23. CDmeSequence *&pDmeSequence,
  24. CDmeChannelsClip *&pDmeChannelsClip,
  25. CDmElement *pDmElement,
  26. const CUtlString &sDmElementId )
  27. {
  28. if ( !pDmElement )
  29. {
  30. Log_Error( LOG_DME_AAC, "%s: No DmElement Specified specified\n", sDmElementId.Get() );
  31. return false;
  32. }
  33. CDmeSequence *pDmeSequenceTmp = CastElement< CDmeSequence >( pDmElement );
  34. if ( !pDmeSequenceTmp )
  35. {
  36. Log_Error( LOG_DME_AAC, "%s: No DmeSequence Specified specified\n", sDmElementId.Get() );
  37. return false;
  38. }
  39. CDmeChannelsClip *pDmeChannelsClipTmp = pDmeSequenceTmp->GetDmeChannelsClip();
  40. if ( !pDmeChannelsClipTmp )
  41. {
  42. Log_Error( LOG_DME_AAC, "%s: Specified Sequence %s Has No DmeChannelsClip\n", sDmElementId.Get(), ComputeDmElementIdStr( pDmeSequenceTmp ).Get() );
  43. return false;
  44. }
  45. pDmeSequence = pDmeSequenceTmp;
  46. pDmeChannelsClip = pDmeChannelsClipTmp;
  47. return true;
  48. }
  49. //-----------------------------------------------------------------------------
  50. // Expose this class to the scene database
  51. //-----------------------------------------------------------------------------
  52. IMPLEMENT_ELEMENT_FACTORY( DmeAnimationAssemblyCommand, CDmeAnimationAssemblyCommand );
  53. //-----------------------------------------------------------------------------
  54. //
  55. //-----------------------------------------------------------------------------
  56. void CDmeAnimationAssemblyCommand::OnConstruction()
  57. {
  58. }
  59. //-----------------------------------------------------------------------------
  60. //
  61. //-----------------------------------------------------------------------------
  62. void CDmeAnimationAssemblyCommand::OnDestruction()
  63. {
  64. }
  65. //-----------------------------------------------------------------------------
  66. // Expose this class to the scene database
  67. //-----------------------------------------------------------------------------
  68. IMPLEMENT_ELEMENT_FACTORY( DmeFixupLoop, CDmeFixupLoop );
  69. //-----------------------------------------------------------------------------
  70. //
  71. //-----------------------------------------------------------------------------
  72. void CDmeFixupLoop::OnConstruction()
  73. {
  74. m_nStartFrame.Init( this, "startFrame" );
  75. m_nEndFrame.Init( this, "endFrame" );
  76. }
  77. //-----------------------------------------------------------------------------
  78. //
  79. //-----------------------------------------------------------------------------
  80. void CDmeFixupLoop::OnDestruction()
  81. {
  82. }
  83. //-----------------------------------------------------------------------------
  84. //
  85. //-----------------------------------------------------------------------------
  86. bool CDmeFixupLoop::Apply( CDmElement *pDmElement )
  87. {
  88. CDmeSequence *pDmeSequenceDst = NULL;
  89. CDmeChannelsClip *pDmeChannelsClipDst = NULL;
  90. if ( !ConvertToDmeSequenceAndDmeChannelsClip( pDmeSequenceDst, pDmeChannelsClipDst, pDmElement, ComputeDmElementIdStr( this ) ) )
  91. return false;
  92. const DmeFramerate_t dmeFrameRateDst = pDmeSequenceDst->GetFrameRate();
  93. const int nFrameCountDst = pDmeSequenceDst->GetFrameCount();
  94. int nStartFrame = m_nStartFrame.Get();
  95. int nEndFrame = m_nEndFrame.Get();
  96. // Make sure loop doesn't exceed animation length
  97. if ( nEndFrame - nStartFrame > nFrameCountDst )
  98. {
  99. nEndFrame = nFrameCountDst + nStartFrame;
  100. if ( nEndFrame < 0 )
  101. {
  102. nEndFrame = 0;
  103. nStartFrame = -( nFrameCountDst - 1 );
  104. }
  105. }
  106. DmeTime_t nStartTime( nStartFrame, dmeFrameRateDst );
  107. DmeTime_t nEndTime( nEndFrame, dmeFrameRateDst );
  108. for ( int i = 0; i < pDmeChannelsClipDst->m_Channels.Count(); ++i )
  109. {
  110. CDmeChannel *pDmeChannelDst = pDmeChannelsClipDst->m_Channels[i];
  111. if ( !pDmeChannelDst )
  112. continue;
  113. CDmeLog *pDmeLogDst = pDmeChannelDst->GetLog();
  114. if ( !pDmeLogDst )
  115. continue;
  116. CDmeVector3Log *pDmeVector3LogDst = CastElement< CDmeVector3Log >( pDmeLogDst );
  117. if ( pDmeVector3LogDst )
  118. {
  119. Apply( pDmeVector3LogDst, nStartTime, nEndTime );
  120. continue;
  121. }
  122. CDmeQuaternionLog *pDmeQuaternionLogDst = CastElement< CDmeQuaternionLog >( pDmeLogDst );
  123. if ( pDmeQuaternionLogDst )
  124. {
  125. Apply( pDmeQuaternionLogDst, nStartTime, nEndTime );
  126. continue;
  127. }
  128. // ERROR - Unsupported log type
  129. Log_Warning( LOG_DME_AAC, "%s: Unsupported DmeLog Type: \"%s\"\n", ComputeDmElementIdStr( this ).Get(), ComputeDmElementIdStr( pDmeSequenceDst ).Get() );
  130. }
  131. return true;
  132. }
  133. //-----------------------------------------------------------------------------
  134. //
  135. //-----------------------------------------------------------------------------
  136. template < class T >
  137. void ComputeDelta( T &result, const T &a, const T &b );
  138. //-----------------------------------------------------------------------------
  139. //
  140. //-----------------------------------------------------------------------------
  141. template<> void ComputeDelta< Vector >( Vector &vResult, const Vector &vA, const Vector &vB )
  142. {
  143. VectorSubtract( vA, vB, vResult );
  144. }
  145. //-----------------------------------------------------------------------------
  146. //
  147. //-----------------------------------------------------------------------------
  148. template<> void ComputeDelta< Quaternion >( Quaternion &qResult, const Quaternion &qA, const Quaternion &qB )
  149. {
  150. QuaternionMA( qA, -1.0f, qB, qResult );
  151. }
  152. //-----------------------------------------------------------------------------
  153. //
  154. //-----------------------------------------------------------------------------
  155. template < class T >
  156. void AddScaledDelta( T &result, float flScale, const T &a, const T &b );
  157. //-----------------------------------------------------------------------------
  158. //
  159. //-----------------------------------------------------------------------------
  160. template<> void AddScaledDelta< Vector >( Vector &vResult, float flScale, const Vector &vDelta, const Vector &vOrig )
  161. {
  162. VectorMA( vOrig, flScale, vDelta, vResult );
  163. }
  164. //-----------------------------------------------------------------------------
  165. //
  166. //-----------------------------------------------------------------------------
  167. template<> void AddScaledDelta< Quaternion >( Quaternion &qResult, float flScale, const Quaternion &qDelta, const Quaternion &qOrig )
  168. {
  169. QuaternionSM( flScale, qDelta, qOrig, qResult );
  170. }
  171. //-----------------------------------------------------------------------------
  172. //
  173. //-----------------------------------------------------------------------------
  174. template < class T >
  175. void CDmeFixupLoop::Apply(
  176. CDmeTypedLog< T > *pDmeTypedLogDst,
  177. const DmeTime_t &dmeTimeStart,
  178. const DmeTime_t &dmeTimeEnd ) const
  179. {
  180. if ( !pDmeTypedLogDst )
  181. return;
  182. const DmeTime_t dmeTimeRange( dmeTimeEnd - dmeTimeStart );
  183. if ( dmeTimeRange.GetSeconds() <= 0.0 )
  184. return;
  185. if ( dmeTimeStart.GetSeconds() > 0.0f )
  186. return;
  187. const float flTimeRange = dmeTimeRange.GetSeconds();
  188. const int nKeyCount = pDmeTypedLogDst->GetKeyCount();
  189. if ( nKeyCount <= 0 )
  190. return;
  191. CUtlVector< DmeTime_t > times;
  192. CUtlVector< T > values;
  193. for ( int i = 0; i < nKeyCount; ++i )
  194. {
  195. times.AddToTail( pDmeTypedLogDst->GetKeyTime( i ) );
  196. values.AddToTail( pDmeTypedLogDst->GetKeyValue( i ) );
  197. }
  198. Assert( nKeyCount == pDmeTypedLogDst->GetKeyCount() );
  199. T delta;
  200. ComputeDelta< T >( delta, values[ nKeyCount - 1 ], values[ 0 ] );
  201. T newValue;
  202. if ( dmeTimeStart.GetSeconds() < 0.0f )
  203. {
  204. const DmeTime_t dmeTimeBegin = times[ nKeyCount - 1 ] + dmeTimeStart;
  205. for ( int nKeyIndex = 0; nKeyIndex < nKeyCount; ++nKeyIndex )
  206. {
  207. const DmeTime_t &dmeTimeKey = times[ nKeyIndex ];
  208. if ( dmeTimeKey < dmeTimeBegin )
  209. continue;
  210. float flScale = ( dmeTimeKey - dmeTimeBegin ).GetSeconds() / flTimeRange;
  211. flScale = 3.0f * flScale * flScale - 2.0f * flScale * flScale * flScale;
  212. AddScaledDelta( newValue, -flScale, delta, values[ nKeyIndex ] );
  213. values[ nKeyIndex ] = newValue;
  214. }
  215. }
  216. if ( dmeTimeEnd.GetSeconds() > 0.0f )
  217. {
  218. const DmeTime_t dmeTimeBegin = times[ 0 ];
  219. for ( int nKeyIndex = 0; nKeyIndex < nKeyCount; ++nKeyIndex )
  220. {
  221. const DmeTime_t dmeTimeKey = times[ nKeyIndex ];
  222. if ( dmeTimeKey > dmeTimeEnd )
  223. break;
  224. float flScale = ( dmeTimeEnd - ( dmeTimeKey - dmeTimeBegin ) ).GetSeconds() / flTimeRange;
  225. flScale = 3.0f * flScale * flScale - 2.0f * flScale * flScale * flScale;
  226. AddScaledDelta( newValue, flScale, delta, values[ nKeyIndex ] );
  227. values[ nKeyIndex ] = newValue;
  228. }
  229. }
  230. CDmeTypedLogLayer< T > *pDmeTypedLogLayer = CastElement< CDmeTypedLogLayer< T > >( pDmeTypedLogDst->AddNewLayer() );
  231. if ( pDmeTypedLogLayer )
  232. {
  233. pDmeTypedLogLayer->SetAllKeys( times, values );
  234. }
  235. }
  236. //-----------------------------------------------------------------------------
  237. // Expose this class to the scene database
  238. //-----------------------------------------------------------------------------
  239. IMPLEMENT_ELEMENT_FACTORY( DmeSubtract, CDmeSubtract );
  240. //-----------------------------------------------------------------------------
  241. //
  242. //-----------------------------------------------------------------------------
  243. void CDmeSubtract::OnConstruction()
  244. {
  245. m_eSequence.Init( this, "sequence", FATTRIB_NEVERCOPY );
  246. m_nFrame.Init( this, "frame" );
  247. }
  248. //-----------------------------------------------------------------------------
  249. //
  250. //-----------------------------------------------------------------------------
  251. void CDmeSubtract::OnDestruction()
  252. {
  253. }
  254. //-----------------------------------------------------------------------------
  255. //
  256. //-----------------------------------------------------------------------------
  257. bool CDmeSubtract::Apply( CDmElement *pDmElement )
  258. {
  259. CDmeSequence *pDmeSequenceDst = NULL;
  260. CDmeChannelsClip *pDmeChannelsClipDst = NULL;
  261. if ( !ConvertToDmeSequenceAndDmeChannelsClip( pDmeSequenceDst, pDmeChannelsClipDst, pDmElement, ComputeDmElementIdStr( this ) ) )
  262. return false;
  263. CDmeSequence *pDmeSequenceSrc = NULL;
  264. CDmeChannelsClip *pDmeChannelsClipSrc = NULL;
  265. if ( !ConvertToDmeSequenceAndDmeChannelsClip( pDmeSequenceSrc, pDmeChannelsClipSrc, m_eSequence.GetElement(), ComputeDmElementIdStr( this ) ) )
  266. return false;
  267. const DmeFramerate_t dmeFrameRateSrc = pDmeSequenceSrc->GetFrameRate();
  268. const DmeTime_t dmeTimeSrc( m_nFrame.Get(), dmeFrameRateSrc );
  269. if ( dmeTimeSrc < pDmeChannelsClipSrc->GetStartTime() )
  270. {
  271. Log_Warning( LOG_DME_AAC, "%s: .%s %d (%.2fs @ %g fps) < %s Start Time of %.2fs\n",
  272. ComputeDmElementIdStr( this ).Get(),
  273. m_nFrame.GetAttribute()->GetName(),
  274. m_nFrame.Get(),
  275. dmeTimeSrc.GetSeconds(),
  276. dmeFrameRateSrc.GetFramesPerSecond(),
  277. ComputeDmElementIdStr( pDmeSequenceSrc ).Get(),
  278. pDmeChannelsClipSrc->GetStartTime().GetSeconds() );
  279. }
  280. if ( dmeTimeSrc > pDmeChannelsClipSrc->GetEndTime() )
  281. {
  282. Log_Warning( LOG_DME_AAC, "%s: .%s %d (%.2fs @ %g fps) > %s End Time of %.2fs\n",
  283. ComputeDmElementIdStr( this ).Get(),
  284. m_nFrame.GetAttribute()->GetName(),
  285. m_nFrame.Get(),
  286. dmeTimeSrc.GetSeconds(),
  287. dmeFrameRateSrc.GetFramesPerSecond(),
  288. ComputeDmElementIdStr( pDmeSequenceSrc ).Get(),
  289. pDmeChannelsClipSrc->GetEndTime().GetSeconds() );
  290. }
  291. // Match up channels by name.
  292. for ( int i = 0; i < pDmeChannelsClipDst->m_Channels.Count(); ++i )
  293. {
  294. CDmeChannel *pDmeChannelDst = pDmeChannelsClipDst->m_Channels[i];
  295. if ( !pDmeChannelDst )
  296. continue;
  297. CDmeLog *pDmeLogDst = pDmeChannelDst->GetLog();
  298. if ( !pDmeLogDst )
  299. continue;
  300. const char *pszDmeChannelName = pDmeChannelDst->GetName();
  301. CDmeVector3Log *pDmeVector3LogDst = CastElement< CDmeVector3Log >( pDmeLogDst );
  302. CDmeQuaternionLog *pDmeQuaternionLogDst = CastElement< CDmeQuaternionLog >( pDmeLogDst );
  303. bool bFound = false;
  304. for ( int j = 0; j < pDmeChannelsClipSrc->m_Channels.Count(); ++j )
  305. {
  306. CDmeChannel *pDmeChannelSrc = pDmeChannelsClipSrc->m_Channels[j];
  307. if ( !pDmeChannelSrc || Q_stricmp( pszDmeChannelName, pDmeChannelSrc->GetName() ) )
  308. continue;
  309. CDmeLog *pDmeLogSrc = pDmeChannelSrc->GetLog();
  310. if ( !pDmeLogDst )
  311. continue;
  312. CDmeVector3Log *pDmeVector3LogSrc = CastElement< CDmeVector3Log >( pDmeLogSrc );
  313. if ( pDmeVector3LogSrc && pDmeVector3LogDst )
  314. {
  315. Subtract( pDmeVector3LogDst, pDmeVector3LogSrc, dmeTimeSrc );
  316. bFound = true;
  317. continue;
  318. }
  319. CDmeQuaternionLog *pDmeQuaternionLogSrc = CastElement< CDmeQuaternionLog >( pDmeLogSrc );
  320. if ( pDmeQuaternionLogSrc && pDmeQuaternionLogDst )
  321. {
  322. Subtract( pDmeQuaternionLogDst, pDmeQuaternionLogSrc, dmeTimeSrc );
  323. bFound = true;
  324. continue;
  325. }
  326. }
  327. if ( !bFound )
  328. {
  329. Log_Warning( LOG_DME_AAC, "%s: No Channel Found To Subtract From %s\n",
  330. ComputeDmElementIdStr( this ).Get(),
  331. ComputeDmElementIdStr( pDmeChannelDst ).Get() );
  332. }
  333. }
  334. return true;
  335. }
  336. //-----------------------------------------------------------------------------
  337. //
  338. //-----------------------------------------------------------------------------
  339. template< class T > void CDmeSubtract::Subtract(
  340. CDmeTypedLog< T > *pDmeTypedLogDst,
  341. const CDmeTypedLog< T > *pDmeTypedLogSrc,
  342. const DmeTime_t &dmeTimeSrc ) const
  343. {
  344. const T valueSrc = pDmeTypedLogSrc->GetValue( dmeTimeSrc );
  345. CUtlVector< DmeTime_t > times;
  346. CUtlVector< T > values;
  347. T valueDst;
  348. for ( int i = 0; i < pDmeTypedLogDst->GetKeyCount(); ++i )
  349. {
  350. times.AddToTail( pDmeTypedLogDst->GetKeyTime( i ) );
  351. Subtract( valueDst, pDmeTypedLogDst->GetKeyValue( i ), valueSrc );
  352. values.AddToTail( valueDst );
  353. }
  354. CDmeTypedLogLayer< T > *pDmeTypedLogLayer = CastElement< CDmeTypedLogLayer< T > >( pDmeTypedLogDst->AddNewLayer() );
  355. if ( pDmeTypedLogLayer )
  356. {
  357. pDmeTypedLogLayer->SetAllKeys( times, values );
  358. }
  359. }
  360. //-----------------------------------------------------------------------------
  361. //
  362. //-----------------------------------------------------------------------------
  363. void CDmeSubtract::Subtract( Vector &vResult, const Vector &vDst, const Vector &vSrc ) const
  364. {
  365. VectorSubtract( vDst, vSrc, vResult );
  366. }
  367. //-----------------------------------------------------------------------------
  368. //
  369. //-----------------------------------------------------------------------------
  370. void CDmeSubtract::Subtract( Quaternion &qResult, const Quaternion &qDst, const Quaternion &qSrc ) const
  371. {
  372. QuaternionSM( -1, qSrc, qDst, qResult );
  373. }
  374. //-----------------------------------------------------------------------------
  375. // Expose this class to the scene database
  376. //-----------------------------------------------------------------------------
  377. IMPLEMENT_ELEMENT_FACTORY( DmePreSubtract, CDmePreSubtract );
  378. //-----------------------------------------------------------------------------
  379. //
  380. //-----------------------------------------------------------------------------
  381. void CDmePreSubtract::OnConstruction()
  382. {
  383. }
  384. //-----------------------------------------------------------------------------
  385. //
  386. //-----------------------------------------------------------------------------
  387. void CDmePreSubtract::OnDestruction()
  388. {
  389. }
  390. //-----------------------------------------------------------------------------
  391. //
  392. //-----------------------------------------------------------------------------
  393. void CDmePreSubtract::Subtract( Vector &vResult, const Vector &vDst, const Vector &vSrc ) const
  394. {
  395. VectorSubtract( vSrc, vDst, vResult );
  396. }
  397. //-----------------------------------------------------------------------------
  398. //
  399. //-----------------------------------------------------------------------------
  400. void CDmePreSubtract::Subtract( Quaternion &qResult, const Quaternion &qDst, const Quaternion &qSrc ) const
  401. {
  402. QuaternionMA( qDst, -1, qSrc, qResult );
  403. }
  404. //-----------------------------------------------------------------------------
  405. // Expose this class to the scene database
  406. //-----------------------------------------------------------------------------
  407. IMPLEMENT_ELEMENT_FACTORY( DmeRotateTo, CDmeRotateTo );
  408. //-----------------------------------------------------------------------------
  409. //
  410. //-----------------------------------------------------------------------------
  411. void CDmeRotateTo::OnConstruction()
  412. {
  413. }
  414. //-----------------------------------------------------------------------------
  415. //
  416. //-----------------------------------------------------------------------------
  417. void CDmeRotateTo::OnDestruction()
  418. {
  419. }
  420. //-----------------------------------------------------------------------------
  421. //
  422. //-----------------------------------------------------------------------------
  423. bool CDmeRotateTo::Apply( CDmElement *pDmElement )
  424. {
  425. CDmeSequence *pDmeSequenceDst = NULL;
  426. CDmeChannelsClip *pDmeChannelsClipDst = NULL;
  427. if ( !ConvertToDmeSequenceAndDmeChannelsClip( pDmeSequenceDst, pDmeChannelsClipDst, pDmElement, ComputeDmElementIdStr( this ) ) )
  428. return false;
  429. CDmeDag *pDmeDag = pDmeSequenceDst->m_eSkeleton.GetElement();
  430. if ( !pDmeDag )
  431. {
  432. Log_Error( LOG_DME_AAC, "%s: Specified Sequence %s Has No Skeleton\n", ComputeDmElementIdStr( this ).Get(), ComputeDmElementIdStr( pDmeSequenceDst ).Get() );
  433. return false;
  434. }
  435. // If the skeleton is a CDmeModel then all children of the skeleton
  436. // are nodes that have no parent, i.e. root nodes which must be
  437. // adjusted, otherwise if it's a normal DmeDag assume it's the only
  438. // root node of the skeleton
  439. CDmeModel *pDmeModel = CastElement< CDmeModel >( pDmeDag );
  440. if ( pDmeModel )
  441. {
  442. for ( int i = 0; i < pDmeModel->GetChildCount(); ++i )
  443. {
  444. SubApply( pDmeModel->GetChild( i ), pDmeChannelsClipDst, pDmeModel->IsZUp() );
  445. }
  446. }
  447. else
  448. {
  449. Log_Warning( LOG_DME_AAC, "%s: Cannot Determine If Sequence %s Is Y Or Z Up, Assuming Z Up\n", ComputeDmElementIdStr( this ).Get(), ComputeDmElementIdStr( pDmeSequenceDst ).Get() );
  450. SubApply( pDmeDag, pDmeChannelsClipDst, true );
  451. }
  452. return true;
  453. }
  454. //-----------------------------------------------------------------------------
  455. // Find the translate & rotate channels and logs which refer to the specified
  456. // DmeDag
  457. //-----------------------------------------------------------------------------
  458. static bool GetDmeChannelsForDag(
  459. CDmeTypedLog< Vector > *&pDmeTranslateLog,
  460. CDmeTypedLog< Quaternion > *&pDmeRotateLog,
  461. CDmeDag *pDmeDag,
  462. CDmeChannelsClip *pDmeChannelsClip )
  463. {
  464. pDmeTranslateLog = NULL;
  465. pDmeRotateLog = NULL;
  466. if ( !pDmeDag || !pDmeChannelsClip )
  467. return false;
  468. CDmeTransform *pDmeTransform = pDmeDag->GetTransform();
  469. if ( !pDmeTransform )
  470. return false;
  471. for ( int i = 0; pDmeChannelsClip->m_Channels.Count(); ++i )
  472. {
  473. CDmeChannel *pDmeChannel = pDmeChannelsClip->m_Channels[i];
  474. if ( !pDmeChannel )
  475. continue;
  476. if ( pDmeChannel->GetToElement() != pDmeTransform )
  477. continue;
  478. CDmeLog *pDmeLog = pDmeChannel->GetLog();
  479. if ( !pDmeLog )
  480. continue;
  481. CDmeTypedLog< Vector > *pDmeTranslateLogTmp = CastElement< CDmeTypedLog< Vector > >( pDmeLog );
  482. if ( pDmeTranslateLogTmp )
  483. {
  484. if ( pDmeTranslateLog == NULL )
  485. {
  486. pDmeTranslateLog = pDmeTranslateLogTmp;
  487. // Quit if we've found both translate & rotate
  488. if ( pDmeRotateLog )
  489. break;
  490. }
  491. else
  492. {
  493. Log_Warning( LOG_DME_AAC, "%s: Multiple Translate Channels Found For Dag, Using %s, Ignoring %s\n",
  494. ComputeDmElementIdStr( pDmeDag ).Get(),
  495. ComputeDmElementIdStr( pDmeTranslateLog ).Get(),
  496. ComputeDmElementIdStr( pDmeChannel ).Get() );
  497. }
  498. continue;
  499. }
  500. CDmeTypedLog< Quaternion > *pDmeRotateLogTmp = CastElement< CDmeTypedLog< Quaternion > >( pDmeLog );
  501. if ( pDmeRotateLogTmp )
  502. {
  503. if ( pDmeRotateLog == NULL )
  504. {
  505. pDmeRotateLog = pDmeRotateLogTmp;
  506. // Quit if we've found both translate & rotate
  507. if ( pDmeTranslateLog )
  508. break;
  509. }
  510. else
  511. {
  512. Log_Warning( LOG_DME_AAC, "%s: Multiple Rotate Channels Found For Dag, Using %s, Ignoring %s\n",
  513. ComputeDmElementIdStr( pDmeDag ).Get(),
  514. ComputeDmElementIdStr( pDmeRotateLog ).Get(),
  515. ComputeDmElementIdStr( pDmeChannel ).Get() );
  516. }
  517. continue;
  518. }
  519. }
  520. return pDmeTranslateLog != NULL && pDmeRotateLog != NULL;
  521. }
  522. //-----------------------------------------------------------------------------
  523. //
  524. //-----------------------------------------------------------------------------
  525. static void ComputeMergedKeyTimes(
  526. CUtlVector< DmeTime_t > &mergedTimes,
  527. CDmeLog *pDmeLogA,
  528. CDmeLog *pDmeLogB )
  529. {
  530. mergedTimes.RemoveAll();
  531. CUtlRBTree< DmeTime_t > timesTree( CDefOps< DmeTime_t >::LessFunc );
  532. for ( int i = 0; i < 2; ++i )
  533. {
  534. CDmeLog *pDmeLog = ( i == 0 ) ? pDmeLogA : pDmeLogB;
  535. if ( !pDmeLog )
  536. continue;
  537. for ( int j = 0; j < pDmeLog->GetKeyCount(); ++j )
  538. {
  539. timesTree.InsertIfNotFound( pDmeLog->GetKeyTime( j ) );
  540. }
  541. }
  542. for ( CUtlRBTree< DmeTime_t >::IndexType_t i = timesTree.FirstInorder(); timesTree.IsValidIndex( i ); i = timesTree.NextInorder( i ) )
  543. {
  544. mergedTimes.AddToTail( timesTree.Element( i ) );
  545. }
  546. }
  547. //-----------------------------------------------------------------------------
  548. //
  549. //-----------------------------------------------------------------------------
  550. template < class T >
  551. static void GetAllKeys(
  552. CUtlVector< DmeTime_t > &keyTimes,
  553. CUtlVector< T > &keyValues,
  554. CDmeTypedLog< T > *pDmeTypedLog )
  555. {
  556. keyTimes.RemoveAll();
  557. keyValues.RemoveAll();
  558. const int nKeyCount = pDmeTypedLog->GetKeyCount();
  559. if ( nKeyCount <= 0 )
  560. return;
  561. keyTimes.EnsureCapacity( nKeyCount );
  562. keyValues.EnsureCapacity( nKeyCount );
  563. Assert( keyTimes.Count() == 0 );
  564. Assert( keyValues.Count() == 0 );
  565. for ( int i = 0; i < nKeyCount; ++i )
  566. {
  567. keyTimes.AddToTail( pDmeTypedLog->GetKeyTime( i ) );
  568. keyValues.AddToTail( pDmeTypedLog->GetKeyValue( i ) );
  569. }
  570. }
  571. //-----------------------------------------------------------------------------
  572. //
  573. //-----------------------------------------------------------------------------
  574. void CDmeRotateTo::SubApply( CDmeDag *pDmeDag, CDmeChannelsClip *pDmeChannelsClip, bool bZUp )
  575. {
  576. if ( !pDmeDag || !pDmeChannelsClip )
  577. return;
  578. CDmeTransform *pDmeTransform = pDmeDag->GetTransform();
  579. if ( !pDmeTransform )
  580. return;
  581. CDmeTypedLog< Vector > *pDmeTranslateLog = NULL;
  582. CDmeTypedLog< Quaternion > *pDmeRotateLog = NULL;
  583. if ( !GetDmeChannelsForDag( pDmeTranslateLog, pDmeRotateLog, pDmeDag, pDmeChannelsClip ) )
  584. {
  585. Log_Error( LOG_DME_AAC, "%s: Couldn't Find Translate & Rotate channels for DmeDag %s\n",
  586. ComputeDmElementIdStr( this ).Get(),
  587. ComputeDmElementIdStr( pDmeDag ).Get() );
  588. return;
  589. }
  590. Assert( pDmeTranslateLog && pDmeRotateLog );
  591. matrix3x4_t mRoot;
  592. {
  593. float flDeltaAngle = 0.0f;
  594. const DmeTime_t dmeTimeBegin = pDmeTranslateLog->GetBeginTime();
  595. const DmeTime_t dmeTimeEnd = pDmeTranslateLog->GetEndTime();
  596. const Vector vPos( pDmeTranslateLog->GetValue( dmeTimeEnd ) - pDmeTranslateLog->GetValue( dmeTimeBegin ) );
  597. // TODO: Handle Y/Z Up
  598. if ( bZUp )
  599. {
  600. // ZUp
  601. if ( vPos.x != 0.0f || vPos.y != 0.0f )
  602. {
  603. const float flAngle = atan2( vPos.y, vPos.x ) * ( 180.0f / M_PI );
  604. flDeltaAngle = m_flAngle.Get() - flAngle;
  605. }
  606. AngleMatrix( QAngle( 0.0f, flDeltaAngle, 0.0f ), mRoot );
  607. }
  608. else
  609. {
  610. // YUp
  611. if ( vPos.x != 0.0f || vPos.z != 0.0f )
  612. {
  613. const float flAngle = atan2( vPos.x, vPos.z ) * ( 180.0f / M_PI );
  614. flDeltaAngle = m_flAngle.Get() - flAngle;
  615. }
  616. AngleMatrix( QAngle( flDeltaAngle, 0.0f, 0.0f ), mRoot );
  617. }
  618. }
  619. matrix3x4_t mSrc;
  620. matrix3x4_t mDst;
  621. CUtlVector< DmeTime_t > mergedKeyTimes;
  622. ComputeMergedKeyTimes( mergedKeyTimes, pDmeTranslateLog, pDmeRotateLog );
  623. Vector vTmp;
  624. CUtlVector< Vector > vValues;
  625. Quaternion qTmp;
  626. CUtlVector< Quaternion > qValues;
  627. for ( int i = 0; i < mergedKeyTimes.Count(); ++i )
  628. {
  629. const DmeTime_t &dmeTime = mergedKeyTimes[i];
  630. AngleMatrix( RadianEuler( pDmeRotateLog->GetValue( dmeTime ) ), pDmeTranslateLog->GetValue( dmeTime ), mSrc );
  631. ConcatTransforms( mRoot, mSrc, mDst );
  632. MatrixAngles( mDst, qTmp, vTmp );
  633. vValues.AddToTail( vTmp );
  634. qValues.AddToTail( qTmp );
  635. }
  636. CDmeTypedLogLayer< Vector > *pDmeTranslateLayer = CastElement< CDmeTypedLogLayer< Vector > >( pDmeTranslateLog->AddNewLayer() );
  637. if ( pDmeTranslateLayer )
  638. {
  639. pDmeTranslateLayer->SetAllKeys( mergedKeyTimes, vValues );
  640. pDmeTranslateLayer->RemoveRedundantKeys( true );
  641. }
  642. else
  643. {
  644. Log_Error( LOG_DME_AAC, "%s: Couldn't Create Translate Layer\n", ComputeDmElementIdStr( this ).Get() );
  645. }
  646. CDmeTypedLogLayer< Quaternion > *pDmeRotateLayer = CastElement< CDmeTypedLogLayer< Quaternion > >( pDmeRotateLog->AddNewLayer() );
  647. if ( pDmeRotateLayer )
  648. {
  649. pDmeRotateLayer->SetAllKeys( mergedKeyTimes, qValues );
  650. pDmeRotateLayer->RemoveRedundantKeys( true );
  651. }
  652. else
  653. {
  654. Log_Error( LOG_DME_AAC, "%s: Couldn't Create Rotate Layer\n", ComputeDmElementIdStr( this ).Get() );
  655. }
  656. }
  657. //-----------------------------------------------------------------------------
  658. // Expose this class to the scene database
  659. //-----------------------------------------------------------------------------
  660. IMPLEMENT_ELEMENT_FACTORY( DmeBoneMaskCmd, CDmeBoneMaskCmd );
  661. //-----------------------------------------------------------------------------
  662. //
  663. //-----------------------------------------------------------------------------
  664. void CDmeBoneMaskCmd::OnConstruction()
  665. {
  666. }
  667. //-----------------------------------------------------------------------------
  668. //
  669. //-----------------------------------------------------------------------------
  670. void CDmeBoneMaskCmd::OnDestruction()
  671. {
  672. }
  673. //-----------------------------------------------------------------------------
  674. //
  675. //-----------------------------------------------------------------------------
  676. bool CDmeBoneMaskCmd::Apply( CDmElement *pDmElement )
  677. {
  678. CDmeSequence *pDmeSequenceDst = NULL;
  679. CDmeChannelsClip *pDmeChannelsClipDst = NULL;
  680. if ( !ConvertToDmeSequenceAndDmeChannelsClip( pDmeSequenceDst, pDmeChannelsClipDst, pDmElement, ComputeDmElementIdStr( this ) ) )
  681. return false;
  682. CDmeDag *pDmeDag = pDmeSequenceDst->m_eSkeleton.GetElement();
  683. if ( !pDmeDag )
  684. {
  685. Log_Error( LOG_DME_AAC, "%s: Specified Sequence %s Has No Skeleton\n", ComputeDmElementIdStr( this ).Get(), ComputeDmElementIdStr( pDmeSequenceDst ).Get() );
  686. return false;
  687. }
  688. CDmeBoneMask *pDmeBoneMask = pDmeSequenceDst->m_eBoneMask.GetElement();
  689. if ( !pDmeBoneMask )
  690. {
  691. Log_Error( LOG_DME_AAC, "%s: Specified Sequence %s Has No Bone Mask\n", ComputeDmElementIdStr( this ).Get(), ComputeDmElementIdStr( pDmeSequenceDst ).Get() );
  692. return false;
  693. }
  694. CUtlStack< CDmeDag * > depthFirstStack;
  695. depthFirstStack.Push( pDmeDag );
  696. while ( depthFirstStack.Count() )
  697. {
  698. depthFirstStack.Pop( pDmeDag );
  699. if ( !pDmeDag )
  700. continue;
  701. for ( int i = pDmeDag->GetChildCount() - 1; i >= 0; --i )
  702. {
  703. depthFirstStack.Push( pDmeDag->GetChild( i ) );
  704. }
  705. SubApply( pDmeChannelsClipDst, pDmeDag, pDmeBoneMask );
  706. }
  707. return true;
  708. }
  709. //-----------------------------------------------------------------------------
  710. //
  711. //-----------------------------------------------------------------------------
  712. void CDmeBoneMaskCmd::SubApply( CDmeChannelsClip *pDmeChannelsClip, CDmeDag *pDmeDag, CDmeBoneMask *pDmeBoneMask )
  713. {
  714. if ( !pDmeChannelsClip || !pDmeDag || !pDmeBoneMask )
  715. return;
  716. const float flWeight = pDmeBoneMask->GetBoneWeight( pDmeDag->GetName() );
  717. // Nothing to do if full weight
  718. if ( flWeight == 1.0f )
  719. return;
  720. CDmeTransform *pDmeTransform = pDmeDag->GetTransform();
  721. if ( !pDmeTransform )
  722. return;
  723. CDmeTypedLog< Vector > *pDmeTranslateLog = NULL;
  724. CDmeTypedLog< Quaternion > *pDmeRotateLog = NULL;
  725. if ( !GetDmeChannelsForDag( pDmeTranslateLog, pDmeRotateLog, pDmeDag, pDmeChannelsClip ) )
  726. {
  727. Log_Error( LOG_DME_AAC, "%s: Couldn't Find Translate & Rotate channels for DmeDag %s\n",
  728. ComputeDmElementIdStr( this ).Get(),
  729. ComputeDmElementIdStr( pDmeDag ).Get() );
  730. return;
  731. }
  732. Vector vTmp;
  733. CUtlVector< DmeTime_t > vTimes;
  734. CUtlVector< Vector > vValues;
  735. GetAllKeys( vTimes, vValues, pDmeTranslateLog );
  736. for ( int i = 0; i < vValues.Count(); ++i )
  737. {
  738. VectorScale( vValues[i], flWeight, vTmp );
  739. vValues[i] = vTmp;
  740. }
  741. Quaternion qTmp;
  742. CUtlVector< DmeTime_t > qTimes;
  743. CUtlVector< Quaternion > qValues;
  744. GetAllKeys( qTimes, qValues, pDmeRotateLog );
  745. for ( int i = 0; i < qValues.Count(); ++i )
  746. {
  747. QuaternionScale( qValues[i], flWeight, qTmp );
  748. qValues[i] = qTmp;
  749. }
  750. CDmeTypedLogLayer< Vector > *pDmeTranslateLayer = CastElement< CDmeTypedLogLayer< Vector > >( pDmeTranslateLog->AddNewLayer() );
  751. if ( pDmeTranslateLayer )
  752. {
  753. pDmeTranslateLayer->SetAllKeys( vTimes, vValues );
  754. pDmeTranslateLayer->RemoveRedundantKeys( true );
  755. }
  756. else
  757. {
  758. Log_Error( LOG_DME_AAC, "%s: Couldn't Create Translate Layer\n", ComputeDmElementIdStr( this ).Get() );
  759. }
  760. CDmeTypedLogLayer< Quaternion > *pDmeRotateLayer = CastElement< CDmeTypedLogLayer< Quaternion > >( pDmeRotateLog->AddNewLayer() );
  761. if ( pDmeRotateLayer )
  762. {
  763. pDmeRotateLayer->SetAllKeys( qTimes, qValues );
  764. pDmeRotateLayer->RemoveRedundantKeys( true );
  765. }
  766. else
  767. {
  768. Log_Error( LOG_DME_AAC, "%s: Couldn't Create Rotate Layer\n", ComputeDmElementIdStr( this ).Get() );
  769. }
  770. }