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.

2207 lines
69 KiB

  1. //====== Copyright � 1996-2004, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "movieobjects/dmecombinationoperator.h"
  7. #include "movieobjects_interfaces.h"
  8. #include "datamodel/dmelementfactoryhelper.h"
  9. #include "datamodel/dmattribute.h"
  10. #include "movieobjects/dmechannel.h"
  11. #include "movieobjects/dmemodel.h"
  12. #include "movieobjects/dmeshape.h"
  13. #include "movieobjects/dmedag.h"
  14. #include "movieobjects/dmeclip.h"
  15. #include "movieobjects/dmelog.h"
  16. #include "movieobjects/dmevertexdata.h"
  17. #include "movieobjects/dmemesh.h"
  18. // memdbgon must be the last include file in a .cpp file!!!
  19. #include "tier0/memdbgon.h"
  20. //-----------------------------------------------------------------------------
  21. // Expose this class to the scene database
  22. //-----------------------------------------------------------------------------
  23. IMPLEMENT_ELEMENT_FACTORY( DmeCombinationInputControl, CDmeCombinationInputControl );
  24. //-----------------------------------------------------------------------------
  25. // Purpose:
  26. //-----------------------------------------------------------------------------
  27. void CDmeCombinationInputControl::OnConstruction()
  28. {
  29. m_RawControlNames.Init( this, "rawControlNames" );
  30. m_bIsStereo.Init( this, "stereo" );
  31. m_bIsEyelid.InitAndSet( this, "eyelid", false );
  32. m_WrinkleScales.Init( this, "wrinkleScales" );
  33. }
  34. void CDmeCombinationInputControl::OnDestruction()
  35. {
  36. }
  37. //-----------------------------------------------------------------------------
  38. // Backward compat
  39. //-----------------------------------------------------------------------------
  40. void CDmeCombinationInputControl::OnElementUnserialized()
  41. {
  42. BaseClass::OnElementUnserialized();
  43. int nWrinkleCount = m_WrinkleScales.Count();
  44. int nControlCount = m_RawControlNames.Count();
  45. if ( nWrinkleCount < nControlCount )
  46. {
  47. for ( int i = nWrinkleCount; i < nControlCount; ++i )
  48. {
  49. m_WrinkleScales.AddToTail( 0.0f );
  50. }
  51. }
  52. else if ( nWrinkleCount > nControlCount )
  53. {
  54. m_WrinkleScales.RemoveMultiple( nControlCount, nWrinkleCount - nControlCount );
  55. }
  56. }
  57. //-----------------------------------------------------------------------------
  58. // Adds a control, returns the control index
  59. //-----------------------------------------------------------------------------
  60. bool CDmeCombinationInputControl::AddRawControl( const char *pRawControlName )
  61. {
  62. Assert( !strchr( pRawControlName, '_' ) && !strchr( pRawControlName, ' ' ) );
  63. int nCount = m_RawControlNames.Count();
  64. for ( int i = 0; i < nCount; ++i )
  65. {
  66. if ( !Q_stricmp( pRawControlName, m_RawControlNames[i] ) )
  67. return false;
  68. }
  69. m_RawControlNames.AddToTail( pRawControlName );
  70. m_WrinkleScales.AddToTail( 0.0f );
  71. return true;
  72. }
  73. //-----------------------------------------------------------------------------
  74. // Finds a raw control by name
  75. //-----------------------------------------------------------------------------
  76. int CDmeCombinationInputControl::FindRawControl( const char *pRawControlName )
  77. {
  78. Assert( !strchr( pRawControlName, '_' ) && !strchr( pRawControlName, ' ' ) );
  79. int nCount = m_RawControlNames.Count();
  80. for ( int i = 0; i < nCount; ++i )
  81. {
  82. if ( !Q_stricmp( pRawControlName, m_RawControlNames[i] ) )
  83. return i;
  84. }
  85. return -1;
  86. }
  87. //-----------------------------------------------------------------------------
  88. // Removes controls
  89. //-----------------------------------------------------------------------------
  90. bool CDmeCombinationInputControl::RemoveRawControl( const char *pRawControlName )
  91. {
  92. int i = FindRawControl( pRawControlName );
  93. if ( i >= 0 )
  94. {
  95. m_RawControlNames.FastRemove( i );
  96. m_WrinkleScales.FastRemove( i );
  97. return true;
  98. }
  99. return false;
  100. }
  101. void CDmeCombinationInputControl::RemoveAllRawControls()
  102. {
  103. m_RawControlNames.RemoveAll();
  104. m_WrinkleScales.RemoveAll( );
  105. }
  106. //-----------------------------------------------------------------------------
  107. // Iterates remapped controls
  108. //-----------------------------------------------------------------------------
  109. int CDmeCombinationInputControl::RawControlCount() const
  110. {
  111. return m_RawControlNames.Count();
  112. }
  113. const char *CDmeCombinationInputControl::RawControlName( int nIndex ) const
  114. {
  115. return m_RawControlNames[ nIndex ];
  116. }
  117. //-----------------------------------------------------------------------------
  118. // Is this control a stereo control?
  119. //-----------------------------------------------------------------------------
  120. bool CDmeCombinationInputControl::IsStereo() const
  121. {
  122. return m_bIsStereo;
  123. }
  124. void CDmeCombinationInputControl::SetStereo( bool bStereo )
  125. {
  126. m_bIsStereo = bStereo;
  127. }
  128. //-----------------------------------------------------------------------------
  129. // Is this control an eyelid control?
  130. //-----------------------------------------------------------------------------
  131. bool CDmeCombinationInputControl::IsEyelid() const
  132. {
  133. return m_bIsEyelid;
  134. }
  135. void CDmeCombinationInputControl::SetEyelid( bool bEyelid )
  136. {
  137. m_bIsEyelid = bEyelid;
  138. }
  139. //-----------------------------------------------------------------------------
  140. // Reordering controls
  141. //-----------------------------------------------------------------------------
  142. void CDmeCombinationInputControl::MoveRawControlUp( const char *pRawControlName )
  143. {
  144. int nIndex = FindRawControl( pRawControlName );
  145. if ( nIndex > 0 )
  146. {
  147. m_RawControlNames.Swap( nIndex, nIndex - 1 );
  148. m_WrinkleScales.Swap( nIndex, nIndex - 1 );
  149. }
  150. }
  151. void CDmeCombinationInputControl::MoveRawControlDown( const char *pRawControlName )
  152. {
  153. int nIndex = FindRawControl( pRawControlName );
  154. int nLastIndex = m_RawControlNames.Count() - 1;
  155. if ( nIndex >= 0 && nIndex < nLastIndex )
  156. {
  157. m_RawControlNames.Swap( nIndex, nIndex + 1 );
  158. m_WrinkleScales.Swap( nIndex, nIndex + 1 );
  159. }
  160. }
  161. //-----------------------------------------------------------------------------
  162. // Returns the wrinkle scale for a particular control
  163. //-----------------------------------------------------------------------------
  164. float CDmeCombinationInputControl::WrinkleScale( const char *pRawControlName )
  165. {
  166. int nIndex = FindRawControl( pRawControlName );
  167. return WrinkleScale( nIndex );
  168. }
  169. float CDmeCombinationInputControl::WrinkleScale( int nIndex )
  170. {
  171. if ( nIndex < 0 || ( nIndex >= m_WrinkleScales.Count() ) )
  172. return 0.0f;
  173. return m_WrinkleScales[ nIndex ];
  174. }
  175. void CDmeCombinationInputControl::SetWrinkleScale( const char *pRawControlName, float flWrinkleScale )
  176. {
  177. int nIndex = FindRawControl( pRawControlName );
  178. if ( nIndex < 0 || ( nIndex >= m_WrinkleScales.Count() ) )
  179. return;
  180. m_WrinkleScales.Set( nIndex, flWrinkleScale );
  181. }
  182. //-----------------------------------------------------------------------------
  183. // The default value of an input control is the value the UI has by default
  184. //-----------------------------------------------------------------------------
  185. float CDmeCombinationInputControl::GetDefaultValue() const
  186. {
  187. return RawControlCount() == 2 ? 0.5f : 0.0f;
  188. }
  189. //-----------------------------------------------------------------------------
  190. // The base value of an input control will set the data to the base state
  191. // i.e. The state upon which the deltas are relative. Normally this is the
  192. // same as GetDefaultValue() except for EyeLid controls
  193. //-----------------------------------------------------------------------------
  194. float CDmeCombinationInputControl::GetBaseValue() const
  195. {
  196. if ( IsEyelid() )
  197. return 0.0f;
  198. return GetDefaultValue();
  199. }
  200. //-----------------------------------------------------------------------------
  201. //
  202. //-----------------------------------------------------------------------------
  203. const char *CDmeCombinationInputControl::GetEyesUpDownFlexName() const
  204. {
  205. const CDmAttribute *pEyesUpDownFlexAttr = GetAttribute( "eyesUpDownFlex", AT_STRING );
  206. if ( pEyesUpDownFlexAttr )
  207. return pEyesUpDownFlexAttr->GetValueString();
  208. return NULL;
  209. }
  210. //-----------------------------------------------------------------------------
  211. // Expose this class to the scene database
  212. //-----------------------------------------------------------------------------
  213. IMPLEMENT_ELEMENT_FACTORY( DmeCombinationDominationRule, CDmeCombinationDominationRule );
  214. //-----------------------------------------------------------------------------
  215. // Purpose:
  216. //-----------------------------------------------------------------------------
  217. void CDmeCombinationDominationRule::OnConstruction()
  218. {
  219. m_Dominators.Init( this, "dominators", FATTRIB_HAS_CALLBACK );
  220. m_Suppressed.Init( this, "suppressed", FATTRIB_HAS_CALLBACK );
  221. }
  222. void CDmeCombinationDominationRule::OnDestruction()
  223. {
  224. }
  225. //-----------------------------------------------------------------------------
  226. // Notify parent that one of our attributes has changed
  227. //-----------------------------------------------------------------------------
  228. void CDmeCombinationDominationRule::OnAttributeChanged( CDmAttribute *pAttribute )
  229. {
  230. BaseClass::OnAttributeChanged( pAttribute );
  231. if ( pAttribute == m_Dominators.GetAttribute() || pAttribute == m_Suppressed.GetAttribute() )
  232. {
  233. InvokeOnAttributeChangedOnReferrers( GetHandle(), pAttribute );
  234. }
  235. }
  236. //-----------------------------------------------------------------------------
  237. // Do we have this string already?
  238. //-----------------------------------------------------------------------------
  239. bool CDmeCombinationDominationRule::HasString( const char *pString, const CDmaStringArray& attr )
  240. {
  241. int nCount = attr.Count();
  242. for ( int i = 0; i < nCount; ++i )
  243. {
  244. if ( !Q_stricmp( pString, attr[i] ) )
  245. return true;
  246. }
  247. return false;
  248. }
  249. //-----------------------------------------------------------------------------
  250. // Adds a dominating control
  251. //-----------------------------------------------------------------------------
  252. void CDmeCombinationDominationRule::AddDominator( const char *pDominatorControl )
  253. {
  254. if ( HasString( pDominatorControl, m_Dominators ) )
  255. {
  256. Warning( "Domination rule already contains dominating control %s\n", pDominatorControl );
  257. return;
  258. }
  259. if ( HasString( pDominatorControl, m_Suppressed ) )
  260. {
  261. Warning( "Attempted to add a control as both dominator + suppressed %s\n", pDominatorControl );
  262. return;
  263. }
  264. m_Dominators.AddToTail( pDominatorControl );
  265. }
  266. //-----------------------------------------------------------------------------
  267. // Add a suppressed control
  268. //-----------------------------------------------------------------------------
  269. void CDmeCombinationDominationRule::AddSuppressed( const char *pSuppressedControl )
  270. {
  271. if ( HasString( pSuppressedControl, m_Suppressed ) )
  272. {
  273. Warning( "Domination rule already contains suppressed control %s\n", pSuppressedControl );
  274. return;
  275. }
  276. if ( HasString( pSuppressedControl, m_Dominators ) )
  277. {
  278. Warning( "Attempted to add a control as both dominator + suppressed %s\n", pSuppressedControl );
  279. return;
  280. }
  281. m_Suppressed.AddToTail( pSuppressedControl );
  282. }
  283. //-----------------------------------------------------------------------------
  284. // Remove all dominatior + suppressed controls
  285. //-----------------------------------------------------------------------------
  286. void CDmeCombinationDominationRule::RemoveAllDominators()
  287. {
  288. m_Dominators.RemoveAll();
  289. }
  290. void CDmeCombinationDominationRule::RemoveAllSuppressed()
  291. {
  292. m_Suppressed.RemoveAll();
  293. }
  294. //-----------------------------------------------------------------------------
  295. // Iteration
  296. //-----------------------------------------------------------------------------
  297. int CDmeCombinationDominationRule::DominatorCount() const
  298. {
  299. return m_Dominators.Count();
  300. }
  301. const char *CDmeCombinationDominationRule::GetDominator( int i ) const
  302. {
  303. return m_Dominators[i];
  304. }
  305. int CDmeCombinationDominationRule::SuppressedCount() const
  306. {
  307. return m_Suppressed.Count();
  308. }
  309. const char *CDmeCombinationDominationRule::GetSuppressed( int i ) const
  310. {
  311. return m_Suppressed[i];
  312. }
  313. //-----------------------------------------------------------------------------
  314. // Search
  315. //-----------------------------------------------------------------------------
  316. bool CDmeCombinationDominationRule::HasDominatorControl( const char *pDominatorControl ) const
  317. {
  318. int nCount = DominatorCount();
  319. for ( int i = 0; i < nCount; ++i )
  320. {
  321. if ( !Q_stricmp( GetDominator(i), pDominatorControl ) )
  322. return true;
  323. }
  324. return false;
  325. }
  326. bool CDmeCombinationDominationRule::HasSuppressedControl( const char *pSuppressedControl ) const
  327. {
  328. int nCount = SuppressedCount();
  329. for ( int i = 0; i < nCount; ++i )
  330. {
  331. if ( !Q_stricmp( GetSuppressed(i), pSuppressedControl ) )
  332. return true;
  333. }
  334. return false;
  335. }
  336. //-----------------------------------------------------------------------------
  337. // Expose this class to the scene database
  338. //-----------------------------------------------------------------------------
  339. IMPLEMENT_ELEMENT_FACTORY( DmeCombinationOperator, CDmeCombinationOperator );
  340. //-----------------------------------------------------------------------------
  341. // Purpose:
  342. //-----------------------------------------------------------------------------
  343. void CDmeCombinationOperator::OnConstruction()
  344. {
  345. m_InputControls.Init( this, "controls" );
  346. m_ControlValues[COMBO_CONTROL_NORMAL].Init( this, "controlValues" );
  347. m_ControlValues[COMBO_CONTROL_LAGGED].Init( this, "controlValuesLagged" );
  348. m_bSpecifyingLaggedData.Init( this, "usesLaggedValues" );
  349. m_Dominators.Init( this, "dominators", FATTRIB_HAS_CALLBACK );
  350. m_Targets.Init( this, "targets" );
  351. m_flLastLaggedComputationTime = FLT_MIN;
  352. }
  353. void CDmeCombinationOperator::OnDestruction()
  354. {
  355. m_RawControlInfo.RemoveAll();
  356. m_CombinationInfo.RemoveAll();
  357. m_DominatorInfo.RemoveAll();
  358. }
  359. //-----------------------------------------------------------------------------
  360. //
  361. //-----------------------------------------------------------------------------
  362. void CDmeCombinationOperator::OnAttributeChanged( CDmAttribute *pAttribute )
  363. {
  364. m_Dominators.GetAttribute()->AddFlag( FATTRIB_DIRTY );
  365. }
  366. //-----------------------------------------------------------------------------
  367. // Finds the index of the input control with the specified name (and creates one if necessary)
  368. //-----------------------------------------------------------------------------
  369. void CDmeCombinationOperator::OnElementUnserialized()
  370. {
  371. BaseClass::OnElementUnserialized();
  372. // Mark all of the input as not being in their default state since we read it from a file
  373. int nCount = m_InputControls.Count();
  374. m_IsDefaultValue.SetCount( nCount );
  375. for ( int i = 0; i < nCount; ++i )
  376. {
  377. m_IsDefaultValue[i] = false;
  378. }
  379. }
  380. //-----------------------------------------------------------------------------
  381. // Finds the index of the input control with the specified name (and creates one if necessary)
  382. //-----------------------------------------------------------------------------
  383. ControlIndex_t CDmeCombinationOperator::FindOrCreateControl( const char *pControlName, bool bStereo, bool bAutoAddRawControl )
  384. {
  385. Assert( !strchr( pControlName, '_' ) && !strchr( pControlName, ' ' ) );
  386. int nCount = m_InputControls.Count();
  387. for ( int i = 0; i < nCount; ++i )
  388. {
  389. if ( !m_InputControls[i] )
  390. continue;
  391. if ( !Q_stricmp( pControlName, m_InputControls[i]->GetName() ) )
  392. return i;
  393. }
  394. // NOTE: the y coordinate of the control value is -1 if it's not a stereo control
  395. CDmeCombinationInputControl *pInputControl = CreateElement< CDmeCombinationInputControl >( pControlName, GetFileId() );
  396. pInputControl->SetStereo( bStereo );
  397. int nIndex = m_InputControls.AddToTail( pInputControl );
  398. m_ControlValues[COMBO_CONTROL_NORMAL].AddToTail( Vector( 0.0f, 0.0f, 0.5f ) );
  399. m_ControlValues[COMBO_CONTROL_LAGGED].AddToTail( Vector( 0.0f, 0.0f, 0.5f ) );
  400. m_IsDefaultValue.AddToTail( true );
  401. Assert( m_InputControls.Count() == m_ControlValues[COMBO_CONTROL_NORMAL].Count() );
  402. Assert( m_InputControls.Count() == m_ControlValues[COMBO_CONTROL_LAGGED].Count() );
  403. Assert( m_InputControls.Count() == m_IsDefaultValue.Count() );
  404. if ( bAutoAddRawControl )
  405. {
  406. AddRawControl( nIndex, pControlName );
  407. }
  408. return nIndex;
  409. }
  410. //-----------------------------------------------------------------------------
  411. // Finds the index of the input control with the specified name
  412. //-----------------------------------------------------------------------------
  413. ControlIndex_t CDmeCombinationOperator::FindControlIndex( const char *pControlName )
  414. {
  415. int nCount = m_InputControls.Count();
  416. for ( int i = 0; i < nCount; ++i )
  417. {
  418. if ( !m_InputControls[i] )
  419. continue;
  420. if ( !Q_stricmp( pControlName, m_InputControls[i]->GetName() ) )
  421. return i;
  422. }
  423. return -1;
  424. }
  425. //-----------------------------------------------------------------------------
  426. // Removes a control
  427. //-----------------------------------------------------------------------------
  428. void CDmeCombinationOperator::RemoveControl( const char *pControlName )
  429. {
  430. ControlIndex_t nIndex = FindControlIndex( pControlName );
  431. if ( nIndex >= 0 )
  432. {
  433. DestroyElement( m_InputControls[nIndex] );
  434. m_InputControls.FastRemove( nIndex );
  435. m_ControlValues[COMBO_CONTROL_NORMAL].FastRemove( nIndex );
  436. m_ControlValues[COMBO_CONTROL_LAGGED].FastRemove( nIndex );
  437. m_IsDefaultValue.FastRemove( nIndex );
  438. Assert( m_InputControls.Count() == m_ControlValues[COMBO_CONTROL_NORMAL].Count() );
  439. Assert( m_InputControls.Count() == m_ControlValues[COMBO_CONTROL_LAGGED].Count() );
  440. Assert( m_InputControls.Count() == m_IsDefaultValue.Count() );
  441. RebuildRawControlList();
  442. }
  443. }
  444. void CDmeCombinationOperator::RemoveAllControls()
  445. {
  446. int nCount = m_InputControls.Count();
  447. for ( int i = 0; i < nCount; ++i )
  448. {
  449. CDmeCombinationInputControl *pInputControl = m_InputControls[i];
  450. m_InputControls.Set( i, NULL );
  451. DestroyElement( pInputControl );
  452. }
  453. m_InputControls.RemoveAll();
  454. m_ControlValues[COMBO_CONTROL_NORMAL].RemoveAll( );
  455. m_ControlValues[COMBO_CONTROL_LAGGED].RemoveAll( );
  456. m_IsDefaultValue.RemoveAll( );
  457. RebuildRawControlList();
  458. }
  459. //-----------------------------------------------------------------------------
  460. // Changes a control's name
  461. //-----------------------------------------------------------------------------
  462. void CDmeCombinationOperator::SetControlName( ControlIndex_t nControl, const char *pControlName )
  463. {
  464. ControlIndex_t nFoundIndex = FindControlIndex( pControlName );
  465. if ( nFoundIndex >= 0 && nFoundIndex != nControl )
  466. {
  467. Warning( "A control with name \"%s\" already exists!\n", pControlName );
  468. return;
  469. }
  470. m_InputControls[nControl]->SetName( pControlName );
  471. }
  472. //-----------------------------------------------------------------------------
  473. // Updates the default value associated with a control
  474. //-----------------------------------------------------------------------------
  475. void CDmeCombinationOperator::UpdateDefaultValue( ControlIndex_t nControlIndex )
  476. {
  477. if ( m_IsDefaultValue[ nControlIndex ] )
  478. {
  479. float flDefaultValue = GetRawControlCount( nControlIndex ) == 2 ? 0.5f : 0.0f;
  480. const Vector& vec = m_ControlValues[COMBO_CONTROL_NORMAL][nControlIndex];
  481. m_ControlValues[COMBO_CONTROL_NORMAL].Set( nControlIndex, Vector( flDefaultValue, flDefaultValue, vec.z ) );
  482. const Vector& vec2 = m_ControlValues[COMBO_CONTROL_LAGGED][nControlIndex];
  483. m_ControlValues[COMBO_CONTROL_LAGGED].Set( nControlIndex, Vector( flDefaultValue, flDefaultValue, vec2.z ) );
  484. }
  485. }
  486. //-----------------------------------------------------------------------------
  487. // Adds an output control to a input control
  488. // If force is true, removes the raw control from any existing controls
  489. //-----------------------------------------------------------------------------
  490. void CDmeCombinationOperator::AddRawControl( ControlIndex_t nControl, const char *pRawControlName )
  491. {
  492. if ( FindRawControlIndex( pRawControlName, true ) >= 0 )
  493. {
  494. Warning( "Attempted to add the same remapped control \"%s\" twice!\n", pRawControlName );
  495. return;
  496. }
  497. CDmeCombinationInputControl *pInputControl = m_InputControls[nControl];
  498. Assert( pInputControl );
  499. if ( pInputControl->AddRawControl( pRawControlName ) )
  500. {
  501. UpdateDefaultValue( nControl );
  502. RebuildRawControlList();
  503. }
  504. }
  505. //-----------------------------------------------------------------------------
  506. // Removes an output control from an input control
  507. //-----------------------------------------------------------------------------
  508. void CDmeCombinationOperator::RemoveRawControl( ControlIndex_t nControl, const char *pRawControlName )
  509. {
  510. CDmeCombinationInputControl *pInputControl = m_InputControls[nControl];
  511. Assert( pInputControl );
  512. if ( pInputControl->RemoveRawControl( pRawControlName ) )
  513. {
  514. UpdateDefaultValue( nControl );
  515. RebuildRawControlList();
  516. }
  517. }
  518. void CDmeCombinationOperator::RemoveAllRawControls( ControlIndex_t nControl )
  519. {
  520. CDmeCombinationInputControl *pInputControl = m_InputControls[nControl];
  521. Assert( pInputControl );
  522. pInputControl->RemoveAllRawControls( );
  523. int nCount = m_InputControls.Count();
  524. for ( int i = 0; i < nCount; ++i )
  525. {
  526. UpdateDefaultValue( i );
  527. }
  528. RebuildRawControlList();
  529. }
  530. //-----------------------------------------------------------------------------
  531. // Iterates remapped controls
  532. //-----------------------------------------------------------------------------
  533. int CDmeCombinationOperator::GetRawControlCount( ControlIndex_t nControl ) const
  534. {
  535. CDmeCombinationInputControl *pInputControl = m_InputControls[nControl];
  536. Assert( pInputControl );
  537. return pInputControl->RawControlCount();
  538. }
  539. const char *CDmeCombinationOperator::GetRawControlName( ControlIndex_t nControl, int nIndex ) const
  540. {
  541. CDmeCombinationInputControl *pInputControl = m_InputControls[nControl];
  542. Assert( pInputControl );
  543. return pInputControl->RawControlName( nIndex );
  544. }
  545. float CDmeCombinationOperator::GetRawControlWrinkleScale( ControlIndex_t nControl, int nIndex ) const
  546. {
  547. CDmeCombinationInputControl *pInputControl = m_InputControls[nControl];
  548. Assert( pInputControl );
  549. return pInputControl->WrinkleScale( nIndex );
  550. }
  551. float CDmeCombinationOperator::GetRawControlWrinkleScale( ControlIndex_t nControl, const char *pRawControlName ) const
  552. {
  553. CDmeCombinationInputControl *pInputControl = m_InputControls[nControl];
  554. Assert( pInputControl );
  555. return pInputControl->WrinkleScale( pRawControlName );
  556. }
  557. //-----------------------------------------------------------------------------
  558. //
  559. //-----------------------------------------------------------------------------
  560. float CDmeCombinationOperator::GetControlDefaultValue( ControlIndex_t nControl ) const
  561. {
  562. CDmeCombinationInputControl *pInputControl = m_InputControls[nControl];
  563. Assert( pInputControl );
  564. return pInputControl->GetDefaultValue();
  565. }
  566. //-----------------------------------------------------------------------------
  567. //
  568. //-----------------------------------------------------------------------------
  569. float CDmeCombinationOperator::GetControlBaseValue( ControlIndex_t nControl ) const
  570. {
  571. CDmeCombinationInputControl *pInputControl = m_InputControls[nControl];
  572. Assert( pInputControl );
  573. return pInputControl->GetBaseValue();
  574. }
  575. //-----------------------------------------------------------------------------
  576. // Iterates a global list of output controls
  577. //-----------------------------------------------------------------------------
  578. int CDmeCombinationOperator::GetRawControlCount( ) const
  579. {
  580. return m_RawControlInfo.Count();
  581. }
  582. const char *CDmeCombinationOperator::GetRawControlName( int nIndex ) const
  583. {
  584. return m_RawControlInfo[nIndex].m_Name;
  585. }
  586. float CDmeCombinationOperator::GetRawControlWrinkleScale( int nIndex ) const
  587. {
  588. return m_RawControlInfo[nIndex].m_flWrinkleScale;
  589. }
  590. //-----------------------------------------------------------------------------
  591. // Sets the wrinkle scale for a particular raw control
  592. //-----------------------------------------------------------------------------
  593. void CDmeCombinationOperator::SetWrinkleScale( ControlIndex_t nControl, const char *pRawControlName, float flWrinkleScale )
  594. {
  595. CDmeCombinationInputControl *pInputControl = m_InputControls[nControl];
  596. Assert( pInputControl );
  597. const float flOldWrinkleScale = pInputControl->WrinkleScale( pRawControlName );
  598. pInputControl->SetWrinkleScale( pRawControlName, flWrinkleScale );
  599. for ( int nTargetIndex = 0; nTargetIndex < m_Targets.Count(); ++nTargetIndex )
  600. {
  601. CDmeMesh *pDmeMesh = CastElement< CDmeMesh >( m_Targets[ nTargetIndex ] );
  602. if ( !pDmeMesh )
  603. continue;
  604. CDmeVertexData *pDmeBindState = pDmeMesh->GetBindBaseState();
  605. if ( !pDmeBindState )
  606. continue;
  607. CDmeVertexDeltaData *pDmeDelta = pDmeMesh->FindDeltaState( pRawControlName );
  608. if ( !pDmeDelta )
  609. continue;
  610. pDmeDelta->UpdateWrinkleDelta( pDmeBindState, flOldWrinkleScale, flWrinkleScale );
  611. }
  612. RebuildRawControlList();
  613. }
  614. //-----------------------------------------------------------------------------
  615. // Reordering controls
  616. //-----------------------------------------------------------------------------
  617. void CDmeCombinationOperator::MoveControlUp( const char *pControlName )
  618. {
  619. int nIndex = FindControlIndex( pControlName );
  620. if ( nIndex > 0 )
  621. {
  622. m_InputControls.Swap( nIndex, nIndex - 1 );
  623. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  624. {
  625. m_ControlValues[ i ].Swap( nIndex, nIndex - 1 );
  626. }
  627. RebuildRawControlList();
  628. }
  629. }
  630. //-----------------------------------------------------------------------------
  631. // Reordering controls
  632. //-----------------------------------------------------------------------------
  633. void CDmeCombinationOperator::MoveControlDown( const char *pControlName )
  634. {
  635. int nIndex = FindControlIndex( pControlName );
  636. int nLastIndex = m_InputControls.Count() - 1;
  637. if ( nIndex >= 0 && nIndex < nLastIndex )
  638. {
  639. m_InputControls.Swap( nIndex, nIndex + 1 );
  640. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  641. {
  642. m_ControlValues[ i ].Swap( nIndex, nIndex + 1 );
  643. }
  644. RebuildRawControlList();
  645. }
  646. }
  647. //-----------------------------------------------------------------------------
  648. // Reordering controls
  649. //-----------------------------------------------------------------------------
  650. void CDmeCombinationOperator::MoveControlBefore( const char *pDragControlName, const char *pDropControlName )
  651. {
  652. int pDragIndex( FindControlIndex( pDragControlName ) );
  653. int pDropIndex( FindControlIndex( pDropControlName ) );
  654. // Have to copy because InsertAfter may reallocate memory before doing the copy and therefore might be referencing garabage
  655. CDmeCombinationInputControl *inputControlCopy( m_InputControls[ pDragIndex ] );
  656. m_InputControls.InsertBefore( pDropIndex, inputControlCopy );
  657. if ( pDragIndex <= pDropIndex )
  658. {
  659. m_InputControls.Remove( pDragIndex );
  660. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  661. {
  662. const Vector controlValueCopy( m_ControlValues[ i ][ pDragIndex ] );
  663. m_ControlValues[ i ].InsertBefore( pDropIndex, controlValueCopy );
  664. m_ControlValues[ i ].Remove( pDragIndex );
  665. }
  666. }
  667. else
  668. {
  669. m_InputControls.Remove( pDragIndex + 1 );
  670. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  671. {
  672. const Vector controlValueCopy( m_ControlValues[ i ][ pDragIndex ] );
  673. m_ControlValues[ i ].InsertBefore( pDropIndex, controlValueCopy );
  674. m_ControlValues[ i ].Remove( pDragIndex + 1 );
  675. }
  676. }
  677. }
  678. //-----------------------------------------------------------------------------
  679. // Reordering controls
  680. //-----------------------------------------------------------------------------
  681. void CDmeCombinationOperator::MoveControlAfter( const char *pDragControlName, const char *pDropControlName )
  682. {
  683. int nDragIndex = FindControlIndex( pDragControlName );
  684. int nDropIndex = FindControlIndex( pDropControlName );
  685. // Have to copy because InsertAfter may reallocate memory before doing the copy and therefore might be referencing garabage
  686. CDmeCombinationInputControl *inputControlCopy( m_InputControls[ nDragIndex ] );
  687. m_InputControls.InsertBefore( nDropIndex + 1, inputControlCopy );
  688. if ( nDragIndex < nDropIndex )
  689. {
  690. m_InputControls.Remove( nDragIndex );
  691. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  692. {
  693. const Vector controlValueCopy( m_ControlValues[ i ][ nDragIndex ] );
  694. m_ControlValues[ i ].InsertBefore( nDropIndex + 1, controlValueCopy );
  695. m_ControlValues[ i ].Remove( nDragIndex );
  696. }
  697. }
  698. else
  699. {
  700. m_InputControls.Remove( nDragIndex + 1 );
  701. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  702. {
  703. const Vector controlValueCopy( m_ControlValues[ i ][ nDragIndex ] );
  704. m_ControlValues[ i ].InsertBefore( nDropIndex + 1, controlValueCopy );
  705. m_ControlValues[ i ].Remove( nDragIndex + 1 );
  706. }
  707. }
  708. }
  709. //-----------------------------------------------------------------------------
  710. // Reordering controls
  711. //-----------------------------------------------------------------------------
  712. void CDmeCombinationOperator::MoveRawControlUp( ControlIndex_t nControlIndex, const char *pRawControlName )
  713. {
  714. m_InputControls[nControlIndex]->MoveRawControlUp( pRawControlName );
  715. }
  716. //-----------------------------------------------------------------------------
  717. // Reordering controls
  718. //-----------------------------------------------------------------------------
  719. void CDmeCombinationOperator::MoveRawControlDown( ControlIndex_t nControlIndex, const char *pRawControlName )
  720. {
  721. m_InputControls[nControlIndex]->MoveRawControlDown( pRawControlName );
  722. }
  723. //-----------------------------------------------------------------------------
  724. // Returns true if a control is a stereo control
  725. //-----------------------------------------------------------------------------
  726. void CDmeCombinationOperator::SetStereoControl( ControlIndex_t nControlIndex, bool bIsStereo )
  727. {
  728. m_InputControls[nControlIndex]->SetStereo( bIsStereo );
  729. }
  730. bool CDmeCombinationOperator::IsStereoControl( ControlIndex_t nControlIndex ) const
  731. {
  732. return m_InputControls[nControlIndex]->IsStereo();
  733. }
  734. bool CDmeCombinationOperator::IsStereoRawControl( int nIndex ) const
  735. {
  736. return IsStereoControl( m_RawControlInfo[nIndex].m_InputControl );
  737. }
  738. void CDmeCombinationOperator::SetEyelidControl( ControlIndex_t nControlIndex, bool bIsEyelid )
  739. {
  740. m_InputControls[nControlIndex]->SetEyelid( bIsEyelid );
  741. }
  742. bool CDmeCombinationOperator::IsEyelidControl( ControlIndex_t nControlIndex ) const
  743. {
  744. return m_InputControls[nControlIndex]->IsEyelid();
  745. }
  746. bool CDmeCombinationOperator::IsEyelidRawControl( int nIndex ) const
  747. {
  748. return IsEyelidControl( m_RawControlInfo[nIndex].m_InputControl );
  749. }
  750. //-----------------------------------------------------------------------------
  751. //
  752. //-----------------------------------------------------------------------------
  753. const char *CDmeCombinationOperator::GetEyesUpDownFlexName( ControlIndex_t nControlIndex ) const
  754. {
  755. return m_InputControls[ nControlIndex ]->GetEyesUpDownFlexName();
  756. }
  757. //-----------------------------------------------------------------------------
  758. // Sets the value of a control
  759. //-----------------------------------------------------------------------------
  760. void CDmeCombinationOperator::SetControlValue( ControlIndex_t nControlIndex, float flValue, CombinationControlType_t type )
  761. {
  762. m_IsDefaultValue[ nControlIndex ] = false;
  763. float flMultiLevel = m_ControlValues[type][nControlIndex].z;
  764. m_ControlValues[type].Set( nControlIndex, Vector( flValue, flValue, flMultiLevel ) );
  765. }
  766. void CDmeCombinationOperator::SetControlValue( ControlIndex_t nControlIndex, float flLeftValue, float flRightValue, CombinationControlType_t type )
  767. {
  768. Assert( IsStereoControl( nControlIndex ) );
  769. m_IsDefaultValue[ nControlIndex ] = false;
  770. float flMultiLevel = m_ControlValues[type][nControlIndex].z;
  771. m_ControlValues[type].Set( nControlIndex, Vector( flLeftValue, flRightValue, flMultiLevel ) );
  772. }
  773. void CDmeCombinationOperator::SetControlValue( ControlIndex_t nControlIndex, const Vector2D& vec, CombinationControlType_t type )
  774. {
  775. Assert( IsStereoControl( nControlIndex ) );
  776. m_IsDefaultValue[ nControlIndex ] = false;
  777. float flMultiLevel = m_ControlValues[type][nControlIndex].z;
  778. m_ControlValues[type].Set( nControlIndex, Vector( vec.x, vec.y, flMultiLevel ) );
  779. }
  780. //-----------------------------------------------------------------------------
  781. // Sets the value of a control
  782. //-----------------------------------------------------------------------------
  783. float CDmeCombinationOperator::GetControlValue( ControlIndex_t nControlIndex, CombinationControlType_t type ) const
  784. {
  785. Assert( !IsStereoControl( nControlIndex ) );
  786. return m_ControlValues[type].Get( nControlIndex ).x;
  787. }
  788. //-----------------------------------------------------------------------------
  789. // Sets the value of a control
  790. //-----------------------------------------------------------------------------
  791. const Vector2D& CDmeCombinationOperator::GetStereoControlValue( ControlIndex_t nControlIndex, CombinationControlType_t type ) const
  792. {
  793. return m_ControlValues[type].Get( nControlIndex ).AsVector2D();
  794. }
  795. //-----------------------------------------------------------------------------
  796. // Sets the level of a control (only used by controls w/ 3 or more remappings)
  797. //-----------------------------------------------------------------------------
  798. void CDmeCombinationOperator::SetMultiControlLevel( ControlIndex_t nControlIndex, float flMultiLevel, CombinationControlType_t type )
  799. {
  800. m_IsDefaultValue[ nControlIndex ] = false;
  801. const Vector2D &value = m_ControlValues[type][nControlIndex].AsVector2D();
  802. m_ControlValues[type].Set( nControlIndex, Vector( value.x, value.y, flMultiLevel ) );
  803. }
  804. float CDmeCombinationOperator::GetMultiControlLevel( ControlIndex_t nControlIndex, CombinationControlType_t type ) const
  805. {
  806. Assert( IsMultiControl( nControlIndex ) );
  807. return m_ControlValues[type][nControlIndex].z;
  808. }
  809. //-----------------------------------------------------------------------------
  810. // Returns true if a control is a multi control (a control w/ 3 or more remappings)
  811. //-----------------------------------------------------------------------------
  812. bool CDmeCombinationOperator::IsMultiControl( ControlIndex_t nControlIndex ) const
  813. {
  814. return m_InputControls[nControlIndex]->RawControlCount() >= 3 || IsEyelidControl( nControlIndex );
  815. }
  816. //-----------------------------------------------------------------------------
  817. // Iterates controls
  818. //-----------------------------------------------------------------------------
  819. int CDmeCombinationOperator::GetControlCount() const
  820. {
  821. return m_InputControls.Count();
  822. }
  823. const char *CDmeCombinationOperator::GetControlName( ControlIndex_t i ) const
  824. {
  825. return m_InputControls[i]->GetName();
  826. }
  827. //-----------------------------------------------------------------------------
  828. // Do we have a raw control?
  829. //-----------------------------------------------------------------------------
  830. bool CDmeCombinationOperator::HasRawControl( const char *pRawControlName ) const
  831. {
  832. return FindRawControlIndex( pRawControlName ) >= 0;
  833. }
  834. //-----------------------------------------------------------------------------
  835. // Finds the index of the remapped control with the specified name
  836. //-----------------------------------------------------------------------------
  837. CDmeCombinationOperator::RawControlIndex_t CDmeCombinationOperator::FindRawControlIndex( const char *pControlName, bool bIgnoreDefaultControls ) const
  838. {
  839. int nRawControlCount = m_RawControlInfo.Count();
  840. for ( int i = 0; i < nRawControlCount; ++i )
  841. {
  842. if ( bIgnoreDefaultControls && m_RawControlInfo[i].m_bIsDefaultControl )
  843. continue;
  844. if ( !Q_stricmp( pControlName, m_RawControlInfo[i].m_Name ) )
  845. return i;
  846. }
  847. return -1;
  848. }
  849. //-----------------------------------------------------------------------------
  850. // Is a particular remapped control stereo?
  851. //-----------------------------------------------------------------------------
  852. bool CDmeCombinationOperator::IsRawControlStereo( const char *pRawControlName )
  853. {
  854. RawControlIndex_t nIndex = FindRawControlIndex( pRawControlName );
  855. if ( nIndex < 0 )
  856. return false;
  857. CDmeCombinationInputControl *pInputControl = m_InputControls[ m_RawControlInfo[nIndex].m_InputControl ];
  858. return pInputControl->IsStereo();
  859. }
  860. //-----------------------------------------------------------------------------
  861. // Would a particular delta state attached to this combination operator end up stereo?
  862. //-----------------------------------------------------------------------------
  863. bool CDmeCombinationOperator::IsDeltaStateStereo( const char *pDeltaStateName )
  864. {
  865. int *pTemp = (int*)_alloca( m_RawControlInfo.Count() * sizeof(int) );
  866. int nCount = ParseDeltaName( pDeltaStateName, pTemp );
  867. for ( int i = 0; i < nCount; ++i )
  868. {
  869. CDmeCombinationInputControl *pInputControl = m_InputControls[ m_RawControlInfo[ pTemp[i] ].m_InputControl ];
  870. if ( pInputControl->IsStereo() )
  871. return true;
  872. }
  873. return false;
  874. }
  875. //-----------------------------------------------------------------------------
  876. // Does one of the targets we refer to contain a particular delta state?
  877. //-----------------------------------------------------------------------------
  878. bool CDmeCombinationOperator::DoesTargetContainDeltaState( const char *pSearchName )
  879. {
  880. int nTargetCount = m_Targets.Count();
  881. for ( int i = 0; i < nTargetCount; ++i )
  882. {
  883. const CDmrElementArray<> deltaArray( m_Targets[i], "deltaStates" );
  884. if ( !deltaArray.IsValid() )
  885. continue;
  886. int nDeltaCount = deltaArray.Count();
  887. for ( int j = 0; j < nDeltaCount; ++j )
  888. {
  889. if ( !deltaArray[j] )
  890. continue;
  891. char pBuf[512];
  892. Q_strncpy( pBuf, deltaArray[j]->GetName(), sizeof(pBuf) );
  893. char *pEnd;
  894. for ( char *pName = pBuf; *pName; pName = pEnd )
  895. {
  896. pEnd = strchr( pName, '_' );
  897. if ( !pEnd )
  898. {
  899. pEnd = pName + Q_strlen( pName );
  900. }
  901. else
  902. {
  903. // Null-terminate
  904. *pEnd = 0;
  905. ++pEnd;
  906. }
  907. if ( !Q_stricmp( pSearchName, pName ) )
  908. return true;
  909. }
  910. }
  911. }
  912. return false;
  913. }
  914. //-----------------------------------------------------------------------------
  915. // Computes list of all remapped controls
  916. //-----------------------------------------------------------------------------
  917. void CDmeCombinationOperator::RebuildRawControlList()
  918. {
  919. m_RawControlInfo.RemoveAll();
  920. int nControlCount = m_InputControls.Count();
  921. for ( int i = 0; i < nControlCount; ++i )
  922. {
  923. CDmeCombinationInputControl *pInputControl = m_InputControls[i];
  924. Assert( pInputControl );
  925. int nRemapCount = pInputControl->RawControlCount();
  926. const bool bIsEyelid = pInputControl->IsEyelid();
  927. float flStep = ( nRemapCount > 2 ) ? 1.0f / ( nRemapCount - 1 ) : 0.0f;
  928. for ( int j = 0; j < nRemapCount; ++j )
  929. {
  930. int k = m_RawControlInfo.AddToTail( );
  931. RawControlInfo_t &info = m_RawControlInfo[k];
  932. info.m_Name = pInputControl->RawControlName( j );
  933. info.m_InputControl = i;
  934. info.m_bIsDefaultControl = false;
  935. info.m_flWrinkleScale = pInputControl->WrinkleScale( j );
  936. info.m_bLowerEyelid = false;
  937. if ( bIsEyelid )
  938. {
  939. info.m_FilterRamp.Init( 0.0f, 1.0f, 10.0f, 11.0f );
  940. // TODO: Right now it's implicit that the lower eyelid is first...
  941. if ( j == 0 )
  942. {
  943. // Close Lower Lid
  944. info.m_bLowerEyelid = true;
  945. }
  946. continue;
  947. }
  948. switch( nRemapCount )
  949. {
  950. case 1:
  951. info.m_FilterRamp.Init( 0.0f, 1.0f, 10.0f, 11.0f );
  952. break;
  953. case 2:
  954. if ( j == 0 )
  955. {
  956. info.m_FilterRamp.Init( -11.0f, -10.0f, 0.0f, 0.5f );
  957. }
  958. else
  959. {
  960. info.m_FilterRamp.Init( 0.5f, 1.0f, 10.0f, 11.0f );
  961. }
  962. break;
  963. default:
  964. {
  965. if ( j == 0 )
  966. {
  967. info.m_FilterRamp.Init( -11.0f, -10.0f, 0, flStep );
  968. }
  969. else if ( j == nRemapCount-1 )
  970. {
  971. info.m_FilterRamp.Init( 1.0f - flStep, 1.0f, 10.0f, 11.0f );
  972. }
  973. else
  974. {
  975. float flPeak = j * flStep;
  976. info.m_FilterRamp.Init( flPeak - flStep, flPeak, flPeak, flPeak + flStep );
  977. }
  978. }
  979. break;
  980. }
  981. }
  982. }
  983. RebuildDominatorInfo();
  984. }
  985. //-----------------------------------------------------------------------------
  986. // Computes lists of dominators and suppressors
  987. //-----------------------------------------------------------------------------
  988. void CDmeCombinationOperator::RebuildDominatorInfo()
  989. {
  990. m_DominatorInfo.RemoveAll();
  991. int nCount = m_Dominators.Count();
  992. int *pDominators = (int*)_alloca( m_RawControlInfo.Count() * sizeof(int) );
  993. int *pSuppressed = (int*)_alloca( m_RawControlInfo.Count() * sizeof(int) );
  994. for ( int i = 0; i < nCount; ++i )
  995. {
  996. CDmeCombinationDominationRule *pRule = m_Dominators[i];
  997. bool bRuleOk = true;
  998. int nDominatorCount = pRule->DominatorCount();
  999. int nSuppressedCount = pRule->SuppressedCount();
  1000. if ( ( nDominatorCount == 0 ) || ( nSuppressedCount == 0 ) )
  1001. continue;
  1002. for ( int j = 0; j < nDominatorCount; ++j )
  1003. {
  1004. int nControlIndex = FindRawControlIndex( pRule->GetDominator(j) );
  1005. if ( nControlIndex < 0 )
  1006. {
  1007. bRuleOk = false;
  1008. break;
  1009. }
  1010. pDominators[j] = nControlIndex;
  1011. }
  1012. for ( int j = 0; j < nSuppressedCount; ++j )
  1013. {
  1014. int nControlIndex = FindRawControlIndex( pRule->GetSuppressed(j) );
  1015. if ( nControlIndex < 0 )
  1016. {
  1017. bRuleOk = false;
  1018. break;
  1019. }
  1020. pSuppressed[j] = nControlIndex;
  1021. }
  1022. if ( !bRuleOk )
  1023. continue;
  1024. int k = m_DominatorInfo.AddToTail();
  1025. m_DominatorInfo[k].m_DominantIndices.AddMultipleToTail( nDominatorCount, pDominators );
  1026. m_DominatorInfo[k].m_SuppressedIndices.AddMultipleToTail( nSuppressedCount, pSuppressed );
  1027. }
  1028. }
  1029. //-----------------------------------------------------------------------------
  1030. // Adds a dominator. Dominators are specified using raw control names
  1031. //-----------------------------------------------------------------------------
  1032. CDmeCombinationDominationRule *CDmeCombinationOperator::AddDominationRule( )
  1033. {
  1034. CDmeCombinationDominationRule *pDominationRule = CreateElement< CDmeCombinationDominationRule >( "rule", GetFileId() );
  1035. m_Dominators.AddToTail( pDominationRule );
  1036. return pDominationRule;
  1037. }
  1038. //-----------------------------------------------------------------------------
  1039. // Adds a dominator. Dominators are specified using raw control names
  1040. //-----------------------------------------------------------------------------
  1041. CDmeCombinationDominationRule *CDmeCombinationOperator::AddDominationRule( CDmeCombinationDominationRule *pSrcRule )
  1042. {
  1043. CDmeCombinationDominationRule *pDestRule = pSrcRule->Copy( );
  1044. pDestRule->SetFileId( GetFileId(), TD_DEEP );
  1045. m_Dominators.AddToTail( pDestRule );
  1046. return pDestRule;
  1047. }
  1048. //-----------------------------------------------------------------------------
  1049. // Adds a dominator. Dominators are specified using raw control names
  1050. //-----------------------------------------------------------------------------
  1051. CDmeCombinationDominationRule *CDmeCombinationOperator::AddDominationRule( int nDominatorCount, const char **ppDominatorControlNames, int nSuppressedCount, const char **ppSuppressedControlNames )
  1052. {
  1053. CDmeCombinationDominationRule *pDominationRule = AddDominationRule();
  1054. for ( int i = 0; i < nDominatorCount; ++i )
  1055. {
  1056. pDominationRule->AddDominator( ppDominatorControlNames[i] );
  1057. }
  1058. for ( int i = 0; i < nSuppressedCount; ++i )
  1059. {
  1060. pDominationRule->AddSuppressed( ppSuppressedControlNames[i] );
  1061. }
  1062. return pDominationRule;
  1063. }
  1064. //-----------------------------------------------------------------------------
  1065. // Adds a dominator. Dominators are specified using raw control names
  1066. //-----------------------------------------------------------------------------
  1067. CDmeCombinationDominationRule *CDmeCombinationOperator::AddDominationRule( const CUtlVector< const char * > dominators, const CUtlVector< const char * > suppressed )
  1068. {
  1069. return AddDominationRule( dominators.Count(), (const char **)dominators.Base(), suppressed.Count(), (const char **)suppressed.Base() );
  1070. }
  1071. //-----------------------------------------------------------------------------
  1072. // Removes a domination rule
  1073. //-----------------------------------------------------------------------------
  1074. void CDmeCombinationOperator::RemoveDominationRule( int nIndex )
  1075. {
  1076. CDmeCombinationDominationRule *pRule = m_Dominators[nIndex];
  1077. m_Dominators.Remove( nIndex );
  1078. DestroyElement( pRule );
  1079. }
  1080. void CDmeCombinationOperator::RemoveDominationRule( CDmeCombinationDominationRule *pRule )
  1081. {
  1082. int nCount = m_Dominators.Count();
  1083. for ( int i = 0; i < nCount; ++i )
  1084. {
  1085. if ( m_Dominators[i] == pRule )
  1086. {
  1087. RemoveDominationRule( i );
  1088. break;
  1089. }
  1090. }
  1091. }
  1092. void CDmeCombinationOperator::RemoveAllDominationRules()
  1093. {
  1094. int nCount = m_Dominators.Count();
  1095. for ( int i = nCount; --i >= 0; )
  1096. {
  1097. RemoveDominationRule( i );
  1098. }
  1099. }
  1100. //-----------------------------------------------------------------------------
  1101. // Iteration
  1102. //-----------------------------------------------------------------------------
  1103. int CDmeCombinationOperator::DominationRuleCount() const
  1104. {
  1105. return m_Dominators.Count();
  1106. }
  1107. CDmeCombinationDominationRule *CDmeCombinationOperator::GetDominationRule( int i )
  1108. {
  1109. return m_Dominators[i];
  1110. }
  1111. //-----------------------------------------------------------------------------
  1112. // Finds a domination rule
  1113. //-----------------------------------------------------------------------------
  1114. int CDmeCombinationOperator::FindDominationRule( CDmeCombinationDominationRule *pRule )
  1115. {
  1116. int nCount = m_Dominators.Count();
  1117. for ( int i = 0; i < nCount; ++i )
  1118. {
  1119. if ( m_Dominators[i] == pRule )
  1120. return i;
  1121. }
  1122. return -1;
  1123. }
  1124. //-----------------------------------------------------------------------------
  1125. // Rule reordering
  1126. //-----------------------------------------------------------------------------
  1127. void CDmeCombinationOperator::MoveDominationRuleUp( CDmeCombinationDominationRule* pRule )
  1128. {
  1129. int nIndex = FindDominationRule( pRule );
  1130. if ( nIndex > 0 )
  1131. {
  1132. m_Dominators.Swap( nIndex, nIndex - 1 );
  1133. return;
  1134. }
  1135. }
  1136. void CDmeCombinationOperator::MoveDominationRuleDown( CDmeCombinationDominationRule* pRule )
  1137. {
  1138. int nIndex = FindDominationRule( pRule );
  1139. if ( nIndex >= 0 && nIndex < m_Dominators.Count() - 1 )
  1140. {
  1141. m_Dominators.Swap( nIndex, nIndex + 1 );
  1142. return;
  1143. }
  1144. }
  1145. //-----------------------------------------------------------------------------
  1146. // Attaches a channel to an input
  1147. //-----------------------------------------------------------------------------
  1148. void CDmeCombinationOperator::AttachChannelToControlValue( ControlIndex_t nControlIndex, CombinationControlType_t type, CDmeChannel *pChannel )
  1149. {
  1150. pChannel->SetOutput( m_ControlValues[type].GetAttribute(), nControlIndex );
  1151. }
  1152. //-----------------------------------------------------------------------------
  1153. // Determines the weighting of input controls based on the deltaState name
  1154. //-----------------------------------------------------------------------------
  1155. int CDmeCombinationOperator::FindDeltaStateIndex( CDmAttribute *pDeltaArray, const char *pDeltaStateName )
  1156. {
  1157. const CDmrElementArray<> deltas( pDeltaArray );
  1158. int nDeltaArrayCount = deltas.Count();
  1159. for ( int i = 0; i < nDeltaArrayCount; ++i )
  1160. {
  1161. CDmElement *pDeltaElement = deltas[i];
  1162. if ( pDeltaElement && !Q_stricmp( pDeltaElement->GetName(), pDeltaStateName ) )
  1163. return i;
  1164. }
  1165. return -1;
  1166. }
  1167. //-----------------------------------------------------------------------------
  1168. // Determines which combination to use based on the deltaState name
  1169. //-----------------------------------------------------------------------------
  1170. int CDmeCombinationOperator::ParseDeltaName(const char *pDeltaStateName, int *pControlIndices )
  1171. {
  1172. char pBuf[512];
  1173. Q_strncpy( pBuf, pDeltaStateName, sizeof(pBuf) );
  1174. int nComboCount = 0;
  1175. char *pEnd;
  1176. for ( char *pName = pBuf; *pName; pName = pEnd )
  1177. {
  1178. pEnd = strchr( pName, '_' );
  1179. if ( !pEnd )
  1180. {
  1181. pEnd = pName + Q_strlen( pName );
  1182. }
  1183. else
  1184. {
  1185. // Null-terminate
  1186. *pEnd = 0;
  1187. ++pEnd;
  1188. }
  1189. int nControlIndex = FindRawControlIndex( pName );
  1190. if ( nControlIndex < 0 )
  1191. return 0;
  1192. pControlIndices[ nComboCount++ ] = nControlIndex;
  1193. }
  1194. return nComboCount;
  1195. }
  1196. //-----------------------------------------------------------------------------
  1197. // Finds dominators
  1198. //-----------------------------------------------------------------------------
  1199. void CDmeCombinationOperator::FindDominators( CombinationOperation_t& op )
  1200. {
  1201. // Dominators are sets of inputs, which, when set to 1, will
  1202. // supress another set of inputs. Only combinations which contain *all*
  1203. // dominators will suppress any combinatation that contains *all* suppressors
  1204. int nDominatorCount = m_DominatorInfo.Count();
  1205. for ( int i = 0; i < nDominatorCount; ++i )
  1206. {
  1207. DominatorInfo_t &info = m_DominatorInfo[i];
  1208. // Look for suppressor indices in the control indices list
  1209. int nCount = info.m_SuppressedIndices.Count();
  1210. int j;
  1211. for ( j = 0; j < nCount; ++j )
  1212. {
  1213. if ( op.m_ControlIndices.Find( info.m_SuppressedIndices[j] ) < 0 )
  1214. break;
  1215. }
  1216. if ( j != nCount )
  1217. continue;
  1218. op.m_DominatorIndices.AddToTail( i );
  1219. }
  1220. }
  1221. //-----------------------------------------------------------------------------
  1222. // Purpose:
  1223. //-----------------------------------------------------------------------------
  1224. void CDmeCombinationOperator::ComputeCombinationInfo( int nIndex )
  1225. {
  1226. CleanUpCombinationInfo( nIndex );
  1227. int nCurrentCount = m_CombinationInfo.Count();
  1228. while ( nIndex >= nCurrentCount )
  1229. {
  1230. int j = m_CombinationInfo.AddToTail();
  1231. CombinationInfo_t &info = m_CombinationInfo[j];
  1232. for ( int k = 0; k < COMBO_CONTROL_TYPE_COUNT; ++k )
  1233. {
  1234. info.m_hDestAttribute[k] = DMATTRIBUTE_HANDLE_INVALID;
  1235. }
  1236. ++nCurrentCount;
  1237. }
  1238. CombinationInfo_t &info = m_CombinationInfo[nIndex];
  1239. CDmElement *pSource = m_Targets[ nIndex ];
  1240. if ( !pSource )
  1241. return;
  1242. CDmrElementArray<> deltas( pSource, "deltaStates" );
  1243. if ( !deltas.IsValid() )
  1244. return;
  1245. CDmrArray<Vector2D> weights( pSource, "deltaStateWeights" );
  1246. if ( !weights.IsValid() )
  1247. return;
  1248. CDmrArray<Vector2D> weightsLagged( pSource, "deltaStateWeightsLagged" );
  1249. // This is an error state
  1250. if ( deltas.Count() > weights.Count() )
  1251. return;
  1252. // This is an error state
  1253. if ( weightsLagged.IsValid() && deltas.Count() > weightsLagged.Count() )
  1254. return;
  1255. info.m_hDestAttribute[COMBO_CONTROL_NORMAL] = weights.GetAttribute()->GetHandle();
  1256. info.m_hDestAttribute[COMBO_CONTROL_LAGGED] = weightsLagged.IsValid() ? weightsLagged.GetAttribute()->GetHandle() : DMATTRIBUTE_HANDLE_INVALID;
  1257. int *pTemp = (int*)_alloca( m_RawControlInfo.Count() * sizeof(int) );
  1258. int nDeltaCount = deltas.Count();
  1259. for ( int i = 0; i < nDeltaCount; ++i )
  1260. {
  1261. CDmElement *pDeltaElement = deltas[i];
  1262. if ( !pDeltaElement )
  1263. continue;
  1264. int nControlCount = ParseDeltaName( pDeltaElement->GetName(), pTemp );
  1265. if ( nControlCount == 0 )
  1266. continue;
  1267. int j = info.m_Outputs.AddToTail();
  1268. CombinationOperation_t &op = info.m_Outputs[j];
  1269. op.m_nDeltaStateIndex = i;
  1270. op.m_ControlIndices.AddMultipleToTail( nControlCount, pTemp );
  1271. // Find dominators
  1272. FindDominators( op );
  1273. }
  1274. }
  1275. //-----------------------------------------------------------------------------
  1276. // Purpose:
  1277. //-----------------------------------------------------------------------------
  1278. void CDmeCombinationOperator::ComputeCombinationInfo()
  1279. {
  1280. int nTargetCount = m_Targets.Count();
  1281. for ( int i = 0; i < nTargetCount; ++i )
  1282. {
  1283. ComputeCombinationInfo( i );
  1284. }
  1285. }
  1286. //-----------------------------------------------------------------------------
  1287. // Purpose:
  1288. //-----------------------------------------------------------------------------
  1289. void CDmeCombinationOperator::CleanUpCombinationInfo( int nIndex )
  1290. {
  1291. if ( nIndex >= m_CombinationInfo.Count() )
  1292. return;
  1293. CombinationInfo_t &info = m_CombinationInfo[ nIndex ];
  1294. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  1295. {
  1296. info.m_hDestAttribute[i] = DMATTRIBUTE_HANDLE_INVALID;
  1297. }
  1298. info.m_Outputs.RemoveAll();
  1299. }
  1300. void CDmeCombinationOperator::CleanUpCombinationInfo( )
  1301. {
  1302. int nCount = m_CombinationInfo.Count();
  1303. for ( int i = 0; i < nCount; ++i )
  1304. {
  1305. CleanUpCombinationInfo( i );
  1306. }
  1307. m_CombinationInfo.RemoveAll();
  1308. }
  1309. //-----------------------------------------------------------------------------
  1310. // helpers for finding corrector names
  1311. //-----------------------------------------------------------------------------
  1312. void CDmeCombinationOperator::Resolve()
  1313. {
  1314. BaseClass::Resolve();
  1315. if ( m_InputControls.IsDirty() || m_Dominators.IsDirty() )
  1316. {
  1317. RebuildRawControlList();
  1318. ComputeCombinationInfo();
  1319. }
  1320. }
  1321. //-----------------------------------------------------------------------------
  1322. // Adds a target for the combination operator
  1323. //-----------------------------------------------------------------------------
  1324. void CDmeCombinationOperator::AddTarget( CDmElement *pElement )
  1325. {
  1326. if ( !pElement )
  1327. return;
  1328. int i = m_Targets.AddToTail( pElement );
  1329. ComputeCombinationInfo( i );
  1330. }
  1331. //-----------------------------------------------------------------------------
  1332. // Sets targets
  1333. //-----------------------------------------------------------------------------
  1334. void CDmeCombinationOperator::AddTarget( CDmeDag *pDag )
  1335. {
  1336. if ( !pDag )
  1337. return;
  1338. CDmeShape *pShape = pDag->GetShape();
  1339. AddTarget( pShape );
  1340. int nChildCount = pDag->GetChildCount();
  1341. for ( int i = 0; i < nChildCount; ++i )
  1342. {
  1343. CDmeDag *pChild = pDag->GetChild(i);
  1344. // Do not traverse into models
  1345. if ( CastElement< CDmeModel >( pChild ) )
  1346. continue;
  1347. AddTarget( pChild );
  1348. }
  1349. }
  1350. float RemapValue( float flValue, const Vector4D &filterRamp )
  1351. {
  1352. if ( flValue <= filterRamp.x || flValue >= filterRamp.w )
  1353. return 0.0f;
  1354. if ( flValue < filterRamp.y )
  1355. return RemapVal( flValue, filterRamp.x, filterRamp.y, 0.0f, 1.0f );
  1356. if ( flValue > filterRamp.z )
  1357. return RemapVal( flValue, filterRamp.z, filterRamp.w, 1.0f, 0.0f );
  1358. return 1.0f;
  1359. }
  1360. //-----------------------------------------------------------------------------
  1361. // Remaps non-stereo -> stereo, stereo ->left/right, also adds multilevel + filter
  1362. //-----------------------------------------------------------------------------
  1363. void CDmeCombinationOperator::ComputeInternalControlValue( RawControlIndex_t nRawControlIndex, CombinationControlType_t type, Vector2D &value )
  1364. {
  1365. const RawControlInfo_t &info = m_RawControlInfo[nRawControlIndex];
  1366. const Vector &vecControlValue = m_ControlValues[ type ][ info.m_InputControl ];
  1367. const bool bMultiControl = IsMultiControl( info.m_InputControl );
  1368. if ( IsEyelidControl( info.m_InputControl ) )
  1369. {
  1370. float flMultiValue = RemapValue( vecControlValue.z, info.m_FilterRamp );
  1371. if ( info.m_bLowerEyelid )
  1372. {
  1373. value.x = ( 1.0f - flMultiValue ) * vecControlValue.x;
  1374. value.y = ( 1.0f - flMultiValue ) * vecControlValue.y;
  1375. }
  1376. else
  1377. {
  1378. value.x = flMultiValue * vecControlValue.x;
  1379. value.y = flMultiValue * vecControlValue.y;
  1380. }
  1381. }
  1382. else if ( bMultiControl )
  1383. {
  1384. float flMultiValue = RemapValue( vecControlValue.z, info.m_FilterRamp );
  1385. value.x = flMultiValue * vecControlValue.x;
  1386. value.y = flMultiValue * vecControlValue.y;
  1387. }
  1388. else
  1389. {
  1390. value.x = RemapValue( vecControlValue.x, info.m_FilterRamp );
  1391. value.y = RemapValue( vecControlValue.y, info.m_FilterRamp );
  1392. }
  1393. }
  1394. //-----------------------------------------------------------------------------
  1395. // Computes lagged input values from non-lagged input
  1396. //-----------------------------------------------------------------------------
  1397. void CDmeCombinationOperator::ComputeLaggedInputValues()
  1398. {
  1399. if ( !m_bSpecifyingLaggedData )
  1400. return;
  1401. float t = Plat_FloatTime();
  1402. if ( m_flLastLaggedComputationTime == FLT_MIN )
  1403. {
  1404. m_flLastLaggedComputationTime = t;
  1405. }
  1406. float dt = t - m_flLastLaggedComputationTime;
  1407. m_flLastLaggedComputationTime = t;
  1408. float flFactor = ExponentialDecay( 0.8, 0.033, dt );
  1409. int nCount = m_ControlValues[COMBO_CONTROL_NORMAL].Count();
  1410. for ( int i = 0; i < nCount; ++i )
  1411. {
  1412. Vector vecLerp;
  1413. VectorLerp( m_ControlValues[COMBO_CONTROL_NORMAL][i], m_ControlValues[COMBO_CONTROL_LAGGED][i], flFactor, vecLerp );
  1414. m_ControlValues[COMBO_CONTROL_LAGGED].Set( i, vecLerp );
  1415. }
  1416. }
  1417. //-----------------------------------------------------------------------------
  1418. // Purpose:
  1419. //-----------------------------------------------------------------------------
  1420. void CDmeCombinationOperator::Operate()
  1421. {
  1422. ComputeLaggedInputValues();
  1423. int nCount = m_CombinationInfo.Count();
  1424. for ( int i = 0; i < nCount; ++i )
  1425. {
  1426. CombinationInfo_t &info = m_CombinationInfo[i];
  1427. for ( CombinationControlType_t type = COMBO_CONTROL_FIRST; type < COMBO_CONTROL_TYPE_COUNT; type = (CombinationControlType_t)(type+1) )
  1428. {
  1429. if ( ( info.m_hDestAttribute[type] == DMATTRIBUTE_HANDLE_INVALID ) || !g_pDataModel->IsAttributeHandleValid( info.m_hDestAttribute[type] ) )
  1430. continue;
  1431. CDmAttribute* pAttribute = g_pDataModel->GetAttribute( info.m_hDestAttribute[type] );
  1432. if ( !pAttribute || pAttribute->GetType() != AT_VECTOR2_ARRAY )
  1433. continue;
  1434. CDmrArray< Vector2D > vec2D( pAttribute );
  1435. CombinationControlType_t useType = m_bSpecifyingLaggedData ? type : COMBO_CONTROL_NORMAL;
  1436. int nOutputCount = info.m_Outputs.Count();
  1437. for ( int j = 0; j < nOutputCount; ++j )
  1438. {
  1439. CombinationOperation_t &op = info.m_Outputs[j];
  1440. // Compute the core combination
  1441. Vector2D vecValue( 1.0f, 1.0f );
  1442. int nCombinationCount = op.m_ControlIndices.Count();
  1443. for ( int k = 0; k < nCombinationCount; ++k )
  1444. {
  1445. Vector2D v;
  1446. ComputeInternalControlValue( op.m_ControlIndices[k], useType, v );
  1447. vecValue *= v;
  1448. }
  1449. // Compute the dominators
  1450. int nDominatorCount = op.m_DominatorIndices.Count();
  1451. for ( int k = 0; k < nDominatorCount; ++k )
  1452. {
  1453. const CUtlVector< int > &dominantIndices = m_DominatorInfo[ op.m_DominatorIndices[k] ].m_DominantIndices;
  1454. int nDominantCount = dominantIndices.Count();
  1455. Vector2D suppressor( -1.0f, -1.0f );
  1456. for ( int l = 0; l < nDominantCount; ++l )
  1457. {
  1458. Vector2D v;
  1459. ComputeInternalControlValue( dominantIndices[l], useType, v );
  1460. suppressor *= v;
  1461. }
  1462. suppressor.x += 1.0f; suppressor.y += 1.0f;
  1463. vecValue *= suppressor;
  1464. }
  1465. vec2D.Set( op.m_nDeltaStateIndex, vecValue );
  1466. }
  1467. }
  1468. }
  1469. }
  1470. void CDmeCombinationOperator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
  1471. {
  1472. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  1473. {
  1474. attrs.AddToTail( m_ControlValues[i].GetAttribute() );
  1475. }
  1476. }
  1477. void CDmeCombinationOperator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
  1478. {
  1479. int nCount = m_CombinationInfo.Count();
  1480. for ( int i = 0; i < nCount; ++i )
  1481. {
  1482. CombinationInfo_t &info = m_CombinationInfo[i];
  1483. for ( int j = 0; j < COMBO_CONTROL_TYPE_COUNT; ++j )
  1484. {
  1485. if ( ( info.m_hDestAttribute[j] == DMATTRIBUTE_HANDLE_INVALID ) || !g_pDataModel->IsAttributeHandleValid( info.m_hDestAttribute[j] ) )
  1486. continue;
  1487. CDmAttribute* pAttribute = g_pDataModel->GetAttribute( info.m_hDestAttribute[j] );
  1488. if ( !pAttribute || pAttribute->GetType() != AT_VECTOR2_ARRAY )
  1489. continue;
  1490. attrs.AddToTail( pAttribute );
  1491. }
  1492. }
  1493. }
  1494. //-----------------------------------------------------------------------------
  1495. // Used by studiomdl to discover the various combination rules
  1496. //-----------------------------------------------------------------------------
  1497. int CDmeCombinationOperator::GetOperationTargetCount() const
  1498. {
  1499. return m_Targets.Count();
  1500. }
  1501. CDmElement *CDmeCombinationOperator::GetOperationTarget( int nTargetIndex )
  1502. {
  1503. return m_Targets[ nTargetIndex ];
  1504. }
  1505. int CDmeCombinationOperator::GetOperationCount( int nTargetIndex ) const
  1506. {
  1507. return m_CombinationInfo[ nTargetIndex ].m_Outputs.Count();
  1508. }
  1509. CDmElement *CDmeCombinationOperator::GetOperationDeltaState( int nTargetIndex, int nOpIndex )
  1510. {
  1511. CDmElement *pElement = GetOperationTarget( nTargetIndex );
  1512. const CDmrElementArray<> deltaArray( pElement, "deltaStates" );
  1513. if ( !deltaArray.IsValid() )
  1514. return NULL;
  1515. int nDeltaStateIndex = m_CombinationInfo[ nTargetIndex ].m_Outputs[ nOpIndex ].m_nDeltaStateIndex;
  1516. return deltaArray[ nDeltaStateIndex ];
  1517. }
  1518. const CUtlVector< int > &CDmeCombinationOperator::GetOperationControls( int nTargetIndex, int nOpIndex ) const
  1519. {
  1520. return m_CombinationInfo[ nTargetIndex ].m_Outputs[ nOpIndex ].m_ControlIndices;
  1521. }
  1522. int CDmeCombinationOperator::GetOperationDominatorCount( int nTargetIndex, int nOpIndex ) const
  1523. {
  1524. return m_CombinationInfo[ nTargetIndex ].m_Outputs[ nOpIndex ].m_DominatorIndices.Count();
  1525. }
  1526. const CUtlVector< int > &CDmeCombinationOperator::GetOperationDominator( int nTargetIndex, int nOpIndex, int nDominatorIndex ) const
  1527. {
  1528. int nIndex = m_CombinationInfo[ nTargetIndex ].m_Outputs[ nOpIndex ].m_DominatorIndices[ nDominatorIndex ];
  1529. return m_DominatorInfo[ nIndex ].m_DominantIndices;
  1530. }
  1531. void CDmeCombinationOperator::CopyControls( CDmeCombinationOperator *pSrc )
  1532. {
  1533. // Clean Me Out!
  1534. RemoveAllControls();
  1535. // Copy The Source Controls
  1536. for ( int i = 0; i < pSrc->m_InputControls.Count(); ++i )
  1537. {
  1538. CDmeCombinationInputControl *pSrcInput = pSrc->m_InputControls[ i ];
  1539. if ( pSrcInput )
  1540. {
  1541. CDmeCombinationInputControl *pDstInput = pSrcInput->Copy( );
  1542. pDstInput->SetFileId( GetFileId(), TD_DEEP );
  1543. m_InputControls.AddToTail( pDstInput );
  1544. }
  1545. }
  1546. // Copy The Control Values
  1547. m_ControlValues[ COMBO_CONTROL_NORMAL ].CopyArray(
  1548. pSrc->m_ControlValues[ COMBO_CONTROL_NORMAL ].Base(),
  1549. pSrc->m_ControlValues[ COMBO_CONTROL_NORMAL ].Count() );
  1550. m_ControlValues[ COMBO_CONTROL_LAGGED ].CopyArray(
  1551. pSrc->m_ControlValues[ COMBO_CONTROL_LAGGED ].Base(),
  1552. pSrc->m_ControlValues[ COMBO_CONTROL_LAGGED ].Count() );
  1553. RebuildRawControlList();
  1554. m_Dominators.Purge();
  1555. // Copy The Source Controls
  1556. for ( int i = 0; i < pSrc->m_Dominators.Count(); ++i )
  1557. {
  1558. CDmeCombinationDominationRule *pSrcDom = pSrc->m_Dominators[ i ];
  1559. if ( pSrcDom )
  1560. {
  1561. CDmeCombinationDominationRule *pDstDom = pSrcDom->Copy( );
  1562. pDstDom->SetFileId( GetFileId(), TD_DEEP );
  1563. m_Dominators.AddToTail( pDstDom );
  1564. }
  1565. }
  1566. RebuildRawControlList();
  1567. }
  1568. //-----------------------------------------------------------------------------
  1569. // Generates wrinkle deltas for the uncorrected controls
  1570. // NOTE: This is only being used because we have no authoring path for wrinkle data yet
  1571. //-----------------------------------------------------------------------------
  1572. void CDmeCombinationOperator::GenerateWrinkleDeltas(
  1573. CDmeShape *pShape,
  1574. bool bOverwrite,
  1575. bool bUseNormalForSign /* = false */,
  1576. float flScale /* = 1.0f */ )
  1577. {
  1578. CDmeMesh* pMesh = CastElement< CDmeMesh >( pShape );
  1579. CDmeVertexData *pBindState = pMesh ? pMesh->FindBaseState( "bind" ) : NULL;
  1580. if ( pBindState )
  1581. {
  1582. int nRawControlCount = m_RawControlInfo.Count();
  1583. for ( int i = 0; i < nRawControlCount; ++i )
  1584. {
  1585. CDmeVertexDeltaData* pDelta = pMesh->FindDeltaState( m_RawControlInfo[i].m_Name );
  1586. if ( pDelta )
  1587. {
  1588. if ( bUseNormalForSign )
  1589. {
  1590. pDelta->GenerateWrinkleDelta( pBindState, flScale, bOverwrite, bUseNormalForSign );
  1591. }
  1592. else
  1593. {
  1594. pDelta->GenerateWrinkleDelta( pBindState, m_RawControlInfo[i].m_flWrinkleScale, bOverwrite, bUseNormalForSign );
  1595. }
  1596. }
  1597. }
  1598. }
  1599. }
  1600. void CDmeCombinationOperator::GenerateWrinkleDeltas( bool bOverwrite /* = true */, bool bUseNormalForSign /* = false */, float flScale /* = 1.0f */ )
  1601. {
  1602. int nTargetCount = m_Targets.Count();
  1603. for ( int i = 0; i < nTargetCount; ++i )
  1604. {
  1605. GenerateWrinkleDeltas( CastElement< CDmeShape >( m_Targets[i] ), bOverwrite, bUseNormalForSign, flScale );
  1606. }
  1607. }
  1608. //-----------------------------------------------------------------------------
  1609. //
  1610. //-----------------------------------------------------------------------------
  1611. void CDmeCombinationOperator::RemoveAllTargets()
  1612. {
  1613. m_Targets.RemoveAll();
  1614. CleanUpCombinationInfo();
  1615. }
  1616. //-----------------------------------------------------------------------------
  1617. //
  1618. //-----------------------------------------------------------------------------
  1619. void CDmeCombinationOperator::SetToDefault()
  1620. {
  1621. const int nControlsCount = m_InputControls.Count();
  1622. m_IsDefaultValue.SetCount( nControlsCount );
  1623. for ( int i = 0; i < nControlsCount; ++i )
  1624. {
  1625. m_IsDefaultValue[ i ] = true;
  1626. UpdateDefaultValue( i );
  1627. }
  1628. }
  1629. //-----------------------------------------------------------------------------
  1630. //
  1631. //-----------------------------------------------------------------------------
  1632. void CDmeCombinationOperator::SetToBase()
  1633. {
  1634. const int nControlsCount = m_InputControls.Count();
  1635. for ( int i = 0; i < nControlsCount; ++i )
  1636. {
  1637. const float flBaseValue = GetControlBaseValue( i );
  1638. for ( int j = 0; j < COMBO_CONTROL_TYPE_COUNT; ++j )
  1639. {
  1640. const Vector &v = m_ControlValues[ j ][ i ];
  1641. m_ControlValues[ j ].Set( i, Vector( flBaseValue, flBaseValue, v.z ) );
  1642. }
  1643. }
  1644. }
  1645. //-----------------------------------------------------------------------------
  1646. // * Remove all controls which refer to raw controls which refer to delta
  1647. // states which do not exist in any target
  1648. // * Remove all dominators which refer to states which no longer exist
  1649. //-----------------------------------------------------------------------------
  1650. void CDmeCombinationOperator::Purge()
  1651. {
  1652. bool bDelete = true;
  1653. const int nTargetCount = m_Targets.Count();
  1654. for ( int i = 0; i < nTargetCount; ++i )
  1655. {
  1656. CDmElement *pSource = m_Targets[ i ];
  1657. if ( !pSource )
  1658. continue;
  1659. CDmrElementArray<> deltas( pSource, "deltaStates" );
  1660. if ( !deltas.IsValid() )
  1661. continue;
  1662. const int nDeltaCount = deltas.Count();
  1663. do
  1664. {
  1665. bDelete = false;
  1666. const int nControlCount = GetControlCount();
  1667. for ( int j = 0; j < nControlCount; ++j )
  1668. {
  1669. bDelete = true;
  1670. const int nRawControlCount = GetRawControlCount( j );
  1671. for ( int k = 0; bDelete && k < nRawControlCount; ++k )
  1672. {
  1673. for ( int l = 0; l < nDeltaCount; ++l )
  1674. {
  1675. if ( !Q_strcmp( GetRawControlName( j, k ), deltas[ l ]->GetName() ) )
  1676. {
  1677. bDelete = false;
  1678. break;
  1679. }
  1680. }
  1681. }
  1682. if ( bDelete )
  1683. {
  1684. RemoveControl( GetControlName( j ) );
  1685. break;
  1686. }
  1687. }
  1688. } while ( bDelete );
  1689. }
  1690. do
  1691. {
  1692. bDelete = false;
  1693. const int nDomCount = DominationRuleCount();
  1694. for ( int i = 0; i < nDomCount; ++i )
  1695. {
  1696. bDelete = true;
  1697. CDmeCombinationDominationRule *pDom = GetDominationRule( i );
  1698. const int nDCount = pDom->DominatorCount();
  1699. for ( int j = 0; j < nDCount; ++j )
  1700. {
  1701. if ( HasRawControl( pDom->GetDominator( j ) ) )
  1702. {
  1703. bDelete = false;
  1704. break;
  1705. }
  1706. }
  1707. if ( !bDelete )
  1708. {
  1709. const int nSCount = pDom->SuppressedCount();
  1710. for ( int j = 0; j < nSCount; ++j )
  1711. {
  1712. if ( HasRawControl( pDom->GetSuppressed( j ) ) )
  1713. {
  1714. bDelete = false;
  1715. break;
  1716. }
  1717. }
  1718. }
  1719. if ( bDelete )
  1720. {
  1721. RemoveDominationRule( i );
  1722. break;
  1723. }
  1724. }
  1725. } while ( bDelete );
  1726. }
  1727. //-----------------------------------------------------------------------------
  1728. // Creates lagged log data from an input log
  1729. //-----------------------------------------------------------------------------
  1730. static void CreateLaggedLog( CDmeVector2Log *pLog, CDmeVector2Log *pLaggedLog, int nSamplesPerSec )
  1731. {
  1732. }
  1733. //-----------------------------------------------------------------------------
  1734. // Helper method to create a lagged version of channel data from source data
  1735. //-----------------------------------------------------------------------------
  1736. void CreateLaggedVertexAnimation( CDmeChannelsClip *pClip, int nSamplesPerSec )
  1737. {
  1738. if ( !pClip )
  1739. return;
  1740. CUtlVectorFixedGrowable< char, 256 > newChannelName;
  1741. int nChannelCount = pClip->m_Channels.Count();
  1742. for ( int i = 0; i < nChannelCount; ++i )
  1743. {
  1744. CDmeChannel *pChannel = pClip->m_Channels[i];
  1745. CDmElement *pDest = pChannel->GetToElement();
  1746. CDmAttribute *pDestAttr = pChannel->GetToAttribute();
  1747. int nArrayIndex = pChannel->GetToArrayIndex();
  1748. if ( pChannel->GetLog()->GetDataType() != AT_VECTOR2 )
  1749. continue;
  1750. if ( Q_stricmp( pDestAttr->GetName(), "controlValues" ) )
  1751. continue;
  1752. if ( !pDest->GetValue<bool>( "usesLaggedValues" ) )
  1753. continue;
  1754. CDmAttribute *pLaggedAttr = pDest->GetAttribute( "controlValuesLagged" );
  1755. if ( !pLaggedAttr || pLaggedAttr->GetType() != AT_VECTOR2_ARRAY )
  1756. continue;
  1757. int nLen = Q_strlen( pChannel->GetName() );
  1758. newChannelName.EnsureCount( nLen + 10 );
  1759. memcpy( newChannelName.Base(), pChannel->GetName(), nLen+1 );
  1760. Q_strncpy( &newChannelName[nLen], "_lagged", 10 );
  1761. CDmeChannel *pNewChannel = CreateElement< CDmeChannel >( newChannelName.Base(), pClip->GetFileId() );
  1762. pNewChannel->SetOutput( pLaggedAttr, nArrayIndex );
  1763. CDmeVector2Log *pNewLog = pNewChannel->CreateLog< Vector2D >( );
  1764. pClip->m_Channels.AddToTail( pNewChannel );
  1765. CreateLaggedLog( static_cast<CDmeVector2Log*>( pChannel->GetLog() ), pNewLog, nSamplesPerSec );
  1766. }
  1767. }
  1768. //-----------------------------------------------------------------------------
  1769. //
  1770. // A class used to edit combination operators in Maya.. doesn't connect to targets
  1771. //
  1772. //-----------------------------------------------------------------------------
  1773. IMPLEMENT_ELEMENT_FACTORY( DmeMayaCombinationOperator, CDmeMayaCombinationOperator );
  1774. //-----------------------------------------------------------------------------
  1775. // Purpose:
  1776. //-----------------------------------------------------------------------------
  1777. void CDmeMayaCombinationOperator::OnConstruction()
  1778. {
  1779. m_DeltaStates.Init( this, "deltaStates" );
  1780. m_DeltaStateWeights[COMBO_CONTROL_NORMAL].Init( this, "deltaStateWeights" );
  1781. m_DeltaStateWeights[COMBO_CONTROL_LAGGED].Init( this, "deltaStateWeightsLagged" );
  1782. AddTarget( this );
  1783. }
  1784. void CDmeMayaCombinationOperator::OnDestruction()
  1785. {
  1786. }
  1787. //-----------------------------------------------------------------------------
  1788. // Add, remove delta states
  1789. //-----------------------------------------------------------------------------
  1790. void CDmeMayaCombinationOperator::AddDeltaState( const char *pDeltaStateName )
  1791. {
  1792. m_DeltaStates.AddToTail( CreateElement<CDmElement>( pDeltaStateName, DMFILEID_INVALID ) );
  1793. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  1794. {
  1795. m_DeltaStateWeights[i].AddToTail( Vector2D( 1.0f, 1.0f ) );
  1796. }
  1797. ComputeCombinationInfo( 0 );
  1798. }
  1799. void CDmeMayaCombinationOperator::RemoveDeltaState( const char *pDeltaStateName )
  1800. {
  1801. int nIndex = FindDeltaState( pDeltaStateName );
  1802. if ( nIndex >= 0 )
  1803. {
  1804. m_DeltaStates.Remove( nIndex );
  1805. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  1806. {
  1807. m_DeltaStateWeights[i].Remove( nIndex );
  1808. }
  1809. }
  1810. ComputeCombinationInfo( 0 );
  1811. }
  1812. void CDmeMayaCombinationOperator::RemoveAllDeltaStates()
  1813. {
  1814. m_DeltaStates.RemoveAll( );
  1815. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  1816. {
  1817. m_DeltaStateWeights[i].RemoveAll();
  1818. }
  1819. ComputeCombinationInfo( 0 );
  1820. }
  1821. int CDmeMayaCombinationOperator::FindDeltaState( const char *pDeltaStateName )
  1822. {
  1823. int nCount = m_DeltaStates.Count();
  1824. for ( int i = 0; i < nCount; ++i )
  1825. {
  1826. if ( !Q_stricmp( pDeltaStateName, m_DeltaStates[i]->GetName() ) )
  1827. return i;
  1828. }
  1829. return -1;
  1830. }
  1831. int CDmeMayaCombinationOperator::DeltaStateCount() const
  1832. {
  1833. return m_DeltaStates.Count();
  1834. }
  1835. const char *CDmeMayaCombinationOperator::GetDeltaState( int nIndex ) const
  1836. {
  1837. return m_DeltaStates[nIndex]->GetName();
  1838. }
  1839. const Vector2D& CDmeMayaCombinationOperator::GetDeltaStateWeight( int nIndex, CombinationControlType_t type ) const
  1840. {
  1841. return m_DeltaStateWeights[type][nIndex];
  1842. }