Team Fortress 2 Source Code as on 22/4/2020
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.

2184 lines
68 KiB

  1. //========= Copyright 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 | FATTRIB_HAS_ARRAY_CALLBACK );
  220. m_Suppressed.Init( this, "suppressed", FATTRIB_HAS_CALLBACK | FATTRIB_HAS_ARRAY_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( "Attemped 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( "Attemped 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 | FATTRIB_HAS_ARRAY_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.5f, 0.5f ) );
  399. m_ControlValues[COMBO_CONTROL_LAGGED].AddToTail( Vector( 0.0f, 0.5f, 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, vec.y, vec.z ) );
  482. const Vector& vec2 = m_ControlValues[COMBO_CONTROL_LAGGED][nControlIndex];
  483. m_ControlValues[COMBO_CONTROL_LAGGED].Set( nControlIndex, Vector( flDefaultValue, vec2.y, 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. pInputControl->SetWrinkleScale( pRawControlName, flWrinkleScale );
  598. RebuildRawControlList();
  599. }
  600. //-----------------------------------------------------------------------------
  601. // Reordering controls
  602. //-----------------------------------------------------------------------------
  603. void CDmeCombinationOperator::MoveControlUp( const char *pControlName )
  604. {
  605. int nIndex = FindControlIndex( pControlName );
  606. if ( nIndex > 0 )
  607. {
  608. m_InputControls.Swap( nIndex, nIndex - 1 );
  609. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  610. {
  611. m_ControlValues[ i ].Swap( nIndex, nIndex - 1 );
  612. }
  613. RebuildRawControlList();
  614. }
  615. }
  616. //-----------------------------------------------------------------------------
  617. // Reordering controls
  618. //-----------------------------------------------------------------------------
  619. void CDmeCombinationOperator::MoveControlDown( const char *pControlName )
  620. {
  621. int nIndex = FindControlIndex( pControlName );
  622. int nLastIndex = m_InputControls.Count() - 1;
  623. if ( nIndex >= 0 && nIndex < nLastIndex )
  624. {
  625. m_InputControls.Swap( nIndex, nIndex + 1 );
  626. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  627. {
  628. m_ControlValues[ i ].Swap( nIndex, nIndex + 1 );
  629. }
  630. RebuildRawControlList();
  631. }
  632. }
  633. //-----------------------------------------------------------------------------
  634. // Reordering controls
  635. //-----------------------------------------------------------------------------
  636. void CDmeCombinationOperator::MoveControlBefore( const char *pDragControlName, const char *pDropControlName )
  637. {
  638. int pDragIndex( FindControlIndex( pDragControlName ) );
  639. int pDropIndex( FindControlIndex( pDropControlName ) );
  640. // Have to copy because InsertAfter may reallocate memory before doing the copy and therefore might be referencing garabage
  641. CDmeCombinationInputControl *inputControlCopy( m_InputControls[ pDragIndex ] );
  642. m_InputControls.InsertBefore( pDropIndex, inputControlCopy );
  643. if ( pDragIndex <= pDropIndex )
  644. {
  645. m_InputControls.Remove( pDragIndex );
  646. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  647. {
  648. const Vector controlValueCopy( m_ControlValues[ i ][ pDragIndex ] );
  649. m_ControlValues[ i ].InsertBefore( pDropIndex, controlValueCopy );
  650. m_ControlValues[ i ].Remove( pDragIndex );
  651. }
  652. }
  653. else
  654. {
  655. m_InputControls.Remove( pDragIndex + 1 );
  656. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  657. {
  658. const Vector controlValueCopy( m_ControlValues[ i ][ pDragIndex ] );
  659. m_ControlValues[ i ].InsertBefore( pDropIndex, controlValueCopy );
  660. m_ControlValues[ i ].Remove( pDragIndex + 1 );
  661. }
  662. }
  663. }
  664. //-----------------------------------------------------------------------------
  665. // Reordering controls
  666. //-----------------------------------------------------------------------------
  667. void CDmeCombinationOperator::MoveControlAfter( const char *pDragControlName, const char *pDropControlName )
  668. {
  669. int nDragIndex = FindControlIndex( pDragControlName );
  670. int nDropIndex = FindControlIndex( pDropControlName );
  671. // Have to copy because InsertAfter may reallocate memory before doing the copy and therefore might be referencing garabage
  672. CDmeCombinationInputControl *inputControlCopy( m_InputControls[ nDragIndex ] );
  673. m_InputControls.InsertBefore( nDropIndex + 1, inputControlCopy );
  674. if ( nDragIndex < nDropIndex )
  675. {
  676. m_InputControls.Remove( nDragIndex );
  677. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  678. {
  679. const Vector controlValueCopy( m_ControlValues[ i ][ nDragIndex ] );
  680. m_ControlValues[ i ].InsertBefore( nDropIndex + 1, controlValueCopy );
  681. m_ControlValues[ i ].Remove( nDragIndex );
  682. }
  683. }
  684. else
  685. {
  686. m_InputControls.Remove( nDragIndex + 1 );
  687. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  688. {
  689. const Vector controlValueCopy( m_ControlValues[ i ][ nDragIndex ] );
  690. m_ControlValues[ i ].InsertBefore( nDropIndex + 1, controlValueCopy );
  691. m_ControlValues[ i ].Remove( nDragIndex + 1 );
  692. }
  693. }
  694. }
  695. //-----------------------------------------------------------------------------
  696. // Reordering controls
  697. //-----------------------------------------------------------------------------
  698. void CDmeCombinationOperator::MoveRawControlUp( ControlIndex_t nControlIndex, const char *pRawControlName )
  699. {
  700. m_InputControls[nControlIndex]->MoveRawControlUp( pRawControlName );
  701. }
  702. //-----------------------------------------------------------------------------
  703. // Reordering controls
  704. //-----------------------------------------------------------------------------
  705. void CDmeCombinationOperator::MoveRawControlDown( ControlIndex_t nControlIndex, const char *pRawControlName )
  706. {
  707. m_InputControls[nControlIndex]->MoveRawControlDown( pRawControlName );
  708. }
  709. //-----------------------------------------------------------------------------
  710. // Returns true if a control is a stereo control
  711. //-----------------------------------------------------------------------------
  712. void CDmeCombinationOperator::SetStereoControl( ControlIndex_t nControlIndex, bool bIsStereo )
  713. {
  714. m_InputControls[nControlIndex]->SetStereo( bIsStereo );
  715. }
  716. bool CDmeCombinationOperator::IsStereoControl( ControlIndex_t nControlIndex ) const
  717. {
  718. return m_InputControls[nControlIndex]->IsStereo();
  719. }
  720. bool CDmeCombinationOperator::IsStereoRawControl( int nIndex ) const
  721. {
  722. return IsStereoControl( m_RawControlInfo[nIndex].m_InputControl );
  723. }
  724. void CDmeCombinationOperator::SetEyelidControl( ControlIndex_t nControlIndex, bool bIsEyelid )
  725. {
  726. m_InputControls[nControlIndex]->SetEyelid( bIsEyelid );
  727. }
  728. bool CDmeCombinationOperator::IsEyelidControl( ControlIndex_t nControlIndex ) const
  729. {
  730. return m_InputControls[nControlIndex]->IsEyelid();
  731. }
  732. bool CDmeCombinationOperator::IsEyelidRawControl( int nIndex ) const
  733. {
  734. return IsEyelidControl( m_RawControlInfo[nIndex].m_InputControl );
  735. }
  736. //-----------------------------------------------------------------------------
  737. //
  738. //-----------------------------------------------------------------------------
  739. const char *CDmeCombinationOperator::GetEyesUpDownFlexName( ControlIndex_t nControlIndex ) const
  740. {
  741. return m_InputControls[ nControlIndex ]->GetEyesUpDownFlexName();
  742. }
  743. //-----------------------------------------------------------------------------
  744. // Sets the value of a control
  745. //-----------------------------------------------------------------------------
  746. void CDmeCombinationOperator::SetControlValue( ControlIndex_t nControlIndex, float flValue, CombinationControlType_t type )
  747. {
  748. m_IsDefaultValue[ nControlIndex ] = false;
  749. float flMultiLevel = m_ControlValues[type][nControlIndex].z;
  750. m_ControlValues[type].Set( nControlIndex, Vector( flValue, flValue, flMultiLevel ) );
  751. }
  752. void CDmeCombinationOperator::SetControlValue( ControlIndex_t nControlIndex, float flLevel, float flBalance, CombinationControlType_t type )
  753. {
  754. Assert( IsStereoControl( nControlIndex ) );
  755. m_IsDefaultValue[ nControlIndex ] = false;
  756. float flMultiLevel = m_ControlValues[type][nControlIndex].z;
  757. m_ControlValues[type].Set( nControlIndex, Vector( flLevel, flBalance, flMultiLevel ) );
  758. }
  759. void CDmeCombinationOperator::SetControlValue( ControlIndex_t nControlIndex, const Vector2D& vec, CombinationControlType_t type )
  760. {
  761. Assert( IsStereoControl( nControlIndex ) );
  762. m_IsDefaultValue[ nControlIndex ] = false;
  763. float flMultiLevel = m_ControlValues[type][nControlIndex].z;
  764. m_ControlValues[type].Set( nControlIndex, Vector( vec.x, vec.y, flMultiLevel ) );
  765. }
  766. //-----------------------------------------------------------------------------
  767. // Sets the value of a control
  768. //-----------------------------------------------------------------------------
  769. float CDmeCombinationOperator::GetControlValue( ControlIndex_t nControlIndex, CombinationControlType_t type ) const
  770. {
  771. Assert( !IsStereoControl( nControlIndex ) );
  772. return m_ControlValues[type].Get( nControlIndex ).x;
  773. }
  774. //-----------------------------------------------------------------------------
  775. // Sets the value of a control
  776. //-----------------------------------------------------------------------------
  777. const Vector2D& CDmeCombinationOperator::GetStereoControlValue( ControlIndex_t nControlIndex, CombinationControlType_t type ) const
  778. {
  779. return m_ControlValues[type].Get( nControlIndex ).AsVector2D();
  780. }
  781. //-----------------------------------------------------------------------------
  782. // Sets the level of a control (only used by controls w/ 3 or more remappings)
  783. //-----------------------------------------------------------------------------
  784. void CDmeCombinationOperator::SetMultiControlLevel( ControlIndex_t nControlIndex, float flMultiLevel, CombinationControlType_t type )
  785. {
  786. m_IsDefaultValue[ nControlIndex ] = false;
  787. const Vector2D &value = m_ControlValues[type][nControlIndex].AsVector2D();
  788. m_ControlValues[type].Set( nControlIndex, Vector( value.x, value.y, flMultiLevel ) );
  789. }
  790. float CDmeCombinationOperator::GetMultiControlLevel( ControlIndex_t nControlIndex, CombinationControlType_t type ) const
  791. {
  792. Assert( IsMultiControl( nControlIndex ) );
  793. return m_ControlValues[type][nControlIndex].z;
  794. }
  795. //-----------------------------------------------------------------------------
  796. // Returns true if a control is a multi control (a control w/ 3 or more remappings)
  797. //-----------------------------------------------------------------------------
  798. bool CDmeCombinationOperator::IsMultiControl( ControlIndex_t nControlIndex ) const
  799. {
  800. return m_InputControls[nControlIndex]->RawControlCount() >= 3 || IsEyelidControl( nControlIndex );
  801. }
  802. //-----------------------------------------------------------------------------
  803. // Iterates controls
  804. //-----------------------------------------------------------------------------
  805. int CDmeCombinationOperator::GetControlCount() const
  806. {
  807. return m_InputControls.Count();
  808. }
  809. const char *CDmeCombinationOperator::GetControlName( ControlIndex_t i ) const
  810. {
  811. return m_InputControls[i]->GetName();
  812. }
  813. //-----------------------------------------------------------------------------
  814. // Do we have a raw control?
  815. //-----------------------------------------------------------------------------
  816. bool CDmeCombinationOperator::HasRawControl( const char *pRawControlName ) const
  817. {
  818. return FindRawControlIndex( pRawControlName ) >= 0;
  819. }
  820. //-----------------------------------------------------------------------------
  821. // Finds the index of the remapped control with the specified name
  822. //-----------------------------------------------------------------------------
  823. CDmeCombinationOperator::RawControlIndex_t CDmeCombinationOperator::FindRawControlIndex( const char *pControlName, bool bIgnoreDefaultControls ) const
  824. {
  825. int nRawControlCount = m_RawControlInfo.Count();
  826. for ( int i = 0; i < nRawControlCount; ++i )
  827. {
  828. if ( bIgnoreDefaultControls && m_RawControlInfo[i].m_bIsDefaultControl )
  829. continue;
  830. if ( !Q_stricmp( pControlName, m_RawControlInfo[i].m_Name ) )
  831. return i;
  832. }
  833. return -1;
  834. }
  835. //-----------------------------------------------------------------------------
  836. // Is a particular remapped control stereo?
  837. //-----------------------------------------------------------------------------
  838. bool CDmeCombinationOperator::IsRawControlStereo( const char *pRawControlName )
  839. {
  840. RawControlIndex_t nIndex = FindRawControlIndex( pRawControlName );
  841. if ( nIndex < 0 )
  842. return false;
  843. CDmeCombinationInputControl *pInputControl = m_InputControls[ m_RawControlInfo[nIndex].m_InputControl ];
  844. return pInputControl->IsStereo();
  845. }
  846. //-----------------------------------------------------------------------------
  847. // Would a particular delta state attached to this combination operator end up stereo?
  848. //-----------------------------------------------------------------------------
  849. bool CDmeCombinationOperator::IsDeltaStateStereo( const char *pDeltaStateName )
  850. {
  851. int *pTemp = (int*)_alloca( m_RawControlInfo.Count() * sizeof(int) );
  852. int nCount = ParseDeltaName( pDeltaStateName, pTemp );
  853. for ( int i = 0; i < nCount; ++i )
  854. {
  855. CDmeCombinationInputControl *pInputControl = m_InputControls[ m_RawControlInfo[ pTemp[i] ].m_InputControl ];
  856. if ( pInputControl->IsStereo() )
  857. return true;
  858. }
  859. return false;
  860. }
  861. //-----------------------------------------------------------------------------
  862. // Does one of the targets we refer to contain a particular delta state?
  863. //-----------------------------------------------------------------------------
  864. bool CDmeCombinationOperator::DoesTargetContainDeltaState( const char *pSearchName )
  865. {
  866. int nTargetCount = m_Targets.Count();
  867. for ( int i = 0; i < nTargetCount; ++i )
  868. {
  869. const CDmrElementArray<> deltaArray( m_Targets[i], "deltaStates" );
  870. if ( !deltaArray.IsValid() )
  871. continue;
  872. int nDeltaCount = deltaArray.Count();
  873. for ( int j = 0; j < nDeltaCount; ++j )
  874. {
  875. if ( !deltaArray[j] )
  876. continue;
  877. char pBuf[512];
  878. Q_strncpy( pBuf, deltaArray[j]->GetName(), sizeof(pBuf) );
  879. char *pEnd;
  880. for ( char *pName = pBuf; *pName; pName = pEnd )
  881. {
  882. pEnd = strchr( pName, '_' );
  883. if ( !pEnd )
  884. {
  885. pEnd = pName + Q_strlen( pName );
  886. }
  887. else
  888. {
  889. // Null-terminate
  890. *pEnd = 0;
  891. ++pEnd;
  892. }
  893. if ( !Q_stricmp( pSearchName, pName ) )
  894. return true;
  895. }
  896. }
  897. }
  898. return false;
  899. }
  900. //-----------------------------------------------------------------------------
  901. // Computes list of all remapped controls
  902. //-----------------------------------------------------------------------------
  903. void CDmeCombinationOperator::RebuildRawControlList()
  904. {
  905. m_RawControlInfo.RemoveAll();
  906. int nControlCount = m_InputControls.Count();
  907. for ( int i = 0; i < nControlCount; ++i )
  908. {
  909. CDmeCombinationInputControl *pInputControl = m_InputControls[i];
  910. Assert( pInputControl );
  911. int nRemapCount = pInputControl->RawControlCount();
  912. const bool bIsEyelid = pInputControl->IsEyelid();
  913. float flStep = ( nRemapCount > 2 ) ? 1.0f / ( nRemapCount - 1 ) : 0.0f;
  914. for ( int j = 0; j < nRemapCount; ++j )
  915. {
  916. int k = m_RawControlInfo.AddToTail( );
  917. RawControlInfo_t &info = m_RawControlInfo[k];
  918. info.m_Name = pInputControl->RawControlName( j );
  919. info.m_InputControl = i;
  920. info.m_bIsDefaultControl = false;
  921. info.m_flWrinkleScale = pInputControl->WrinkleScale( j );
  922. info.m_bLowerEyelid = false;
  923. if ( bIsEyelid )
  924. {
  925. info.m_FilterRamp.Init( 0.0f, 1.0f, 10.0f, 11.0f );
  926. // TODO: Right now it's implicit that the lower eyelid is first...
  927. if ( j == 0 )
  928. {
  929. // Close Lower Lid
  930. info.m_bLowerEyelid = true;
  931. }
  932. continue;
  933. }
  934. switch( nRemapCount )
  935. {
  936. case 1:
  937. info.m_FilterRamp.Init( 0.0f, 1.0f, 10.0f, 11.0f );
  938. break;
  939. case 2:
  940. if ( j == 0 )
  941. {
  942. info.m_FilterRamp.Init( -11.0f, -10.0f, 0.0f, 0.5f );
  943. }
  944. else
  945. {
  946. info.m_FilterRamp.Init( 0.5f, 1.0f, 10.0f, 11.0f );
  947. }
  948. break;
  949. default:
  950. {
  951. if ( j == 0 )
  952. {
  953. info.m_FilterRamp.Init( -11.0f, -10.0f, 0, flStep );
  954. }
  955. else if ( j == nRemapCount-1 )
  956. {
  957. info.m_FilterRamp.Init( 1.0f - flStep, 1.0f, 10.0f, 11.0f );
  958. }
  959. else
  960. {
  961. float flPeak = j * flStep;
  962. info.m_FilterRamp.Init( flPeak - flStep, flPeak, flPeak, flPeak + flStep );
  963. }
  964. }
  965. break;
  966. }
  967. }
  968. }
  969. RebuildDominatorInfo();
  970. }
  971. //-----------------------------------------------------------------------------
  972. // Computes lists of dominators and suppressors
  973. //-----------------------------------------------------------------------------
  974. void CDmeCombinationOperator::RebuildDominatorInfo()
  975. {
  976. m_DominatorInfo.RemoveAll();
  977. int nCount = m_Dominators.Count();
  978. int *pDominators = (int*)_alloca( m_RawControlInfo.Count() * sizeof(int) );
  979. int *pSuppressed = (int*)_alloca( m_RawControlInfo.Count() * sizeof(int) );
  980. for ( int i = 0; i < nCount; ++i )
  981. {
  982. CDmeCombinationDominationRule *pRule = m_Dominators[i];
  983. bool bRuleOk = true;
  984. int nDominatorCount = pRule->DominatorCount();
  985. int nSuppressedCount = pRule->SuppressedCount();
  986. if ( ( nDominatorCount == 0 ) || ( nSuppressedCount == 0 ) )
  987. continue;
  988. for ( int j = 0; j < nDominatorCount; ++j )
  989. {
  990. int nControlIndex = FindRawControlIndex( pRule->GetDominator(j) );
  991. if ( nControlIndex < 0 )
  992. {
  993. bRuleOk = false;
  994. break;
  995. }
  996. pDominators[j] = nControlIndex;
  997. }
  998. for ( int j = 0; j < nSuppressedCount; ++j )
  999. {
  1000. int nControlIndex = FindRawControlIndex( pRule->GetSuppressed(j) );
  1001. if ( nControlIndex < 0 )
  1002. {
  1003. bRuleOk = false;
  1004. break;
  1005. }
  1006. pSuppressed[j] = nControlIndex;
  1007. }
  1008. if ( !bRuleOk )
  1009. continue;
  1010. int k = m_DominatorInfo.AddToTail();
  1011. m_DominatorInfo[k].m_DominantIndices.AddMultipleToTail( nDominatorCount, pDominators );
  1012. m_DominatorInfo[k].m_SuppressedIndices.AddMultipleToTail( nSuppressedCount, pSuppressed );
  1013. }
  1014. }
  1015. //-----------------------------------------------------------------------------
  1016. // Adds a dominator. Dominators are specified using raw control names
  1017. //-----------------------------------------------------------------------------
  1018. CDmeCombinationDominationRule *CDmeCombinationOperator::AddDominationRule( )
  1019. {
  1020. CDmeCombinationDominationRule *pDominationRule = CreateElement< CDmeCombinationDominationRule >( "rule", GetFileId() );
  1021. m_Dominators.AddToTail( pDominationRule );
  1022. return pDominationRule;
  1023. }
  1024. //-----------------------------------------------------------------------------
  1025. // Adds a dominator. Dominators are specified using raw control names
  1026. //-----------------------------------------------------------------------------
  1027. CDmeCombinationDominationRule *CDmeCombinationOperator::AddDominationRule( CDmeCombinationDominationRule *pSrcRule )
  1028. {
  1029. CDmeCombinationDominationRule *pDestRule = pSrcRule->Copy( );
  1030. pDestRule->SetFileId( GetFileId(), TD_DEEP );
  1031. m_Dominators.AddToTail( pDestRule );
  1032. return pDestRule;
  1033. }
  1034. //-----------------------------------------------------------------------------
  1035. // Adds a dominator. Dominators are specified using raw control names
  1036. //-----------------------------------------------------------------------------
  1037. CDmeCombinationDominationRule *CDmeCombinationOperator::AddDominationRule( int nDominatorCount, const char **ppDominatorControlNames, int nSuppressedCount, const char **ppSuppressedControlNames )
  1038. {
  1039. CDmeCombinationDominationRule *pDominationRule = AddDominationRule();
  1040. for ( int i = 0; i < nDominatorCount; ++i )
  1041. {
  1042. pDominationRule->AddDominator( ppDominatorControlNames[i] );
  1043. }
  1044. for ( int i = 0; i < nSuppressedCount; ++i )
  1045. {
  1046. pDominationRule->AddSuppressed( ppSuppressedControlNames[i] );
  1047. }
  1048. return pDominationRule;
  1049. }
  1050. //-----------------------------------------------------------------------------
  1051. // Adds a dominator. Dominators are specified using raw control names
  1052. //-----------------------------------------------------------------------------
  1053. CDmeCombinationDominationRule *CDmeCombinationOperator::AddDominationRule( const CUtlVector< const char * > dominators, const CUtlVector< const char * > suppressed )
  1054. {
  1055. return AddDominationRule( dominators.Count(), (const char **)dominators.Base(), suppressed.Count(), (const char **)suppressed.Base() );
  1056. }
  1057. //-----------------------------------------------------------------------------
  1058. // Removes a domination rule
  1059. //-----------------------------------------------------------------------------
  1060. void CDmeCombinationOperator::RemoveDominationRule( int nIndex )
  1061. {
  1062. CDmeCombinationDominationRule *pRule = m_Dominators[nIndex];
  1063. m_Dominators.Remove( nIndex );
  1064. DestroyElement( pRule );
  1065. }
  1066. void CDmeCombinationOperator::RemoveDominationRule( CDmeCombinationDominationRule *pRule )
  1067. {
  1068. int nCount = m_Dominators.Count();
  1069. for ( int i = 0; i < nCount; ++i )
  1070. {
  1071. if ( m_Dominators[i] == pRule )
  1072. {
  1073. RemoveDominationRule( i );
  1074. break;
  1075. }
  1076. }
  1077. }
  1078. void CDmeCombinationOperator::RemoveAllDominationRules()
  1079. {
  1080. int nCount = m_Dominators.Count();
  1081. for ( int i = nCount; --i >= 0; )
  1082. {
  1083. RemoveDominationRule( i );
  1084. }
  1085. }
  1086. //-----------------------------------------------------------------------------
  1087. // Iteration
  1088. //-----------------------------------------------------------------------------
  1089. int CDmeCombinationOperator::DominationRuleCount() const
  1090. {
  1091. return m_Dominators.Count();
  1092. }
  1093. CDmeCombinationDominationRule *CDmeCombinationOperator::GetDominationRule( int i )
  1094. {
  1095. return m_Dominators[i];
  1096. }
  1097. //-----------------------------------------------------------------------------
  1098. // Finds a domination rule
  1099. //-----------------------------------------------------------------------------
  1100. int CDmeCombinationOperator::FindDominationRule( CDmeCombinationDominationRule *pRule )
  1101. {
  1102. int nCount = m_Dominators.Count();
  1103. for ( int i = 0; i < nCount; ++i )
  1104. {
  1105. if ( m_Dominators[i] == pRule )
  1106. return i;
  1107. }
  1108. return -1;
  1109. }
  1110. //-----------------------------------------------------------------------------
  1111. // Rule reordering
  1112. //-----------------------------------------------------------------------------
  1113. void CDmeCombinationOperator::MoveDominationRuleUp( CDmeCombinationDominationRule* pRule )
  1114. {
  1115. int nIndex = FindDominationRule( pRule );
  1116. if ( nIndex > 0 )
  1117. {
  1118. m_Dominators.Swap( nIndex, nIndex - 1 );
  1119. return;
  1120. }
  1121. }
  1122. void CDmeCombinationOperator::MoveDominationRuleDown( CDmeCombinationDominationRule* pRule )
  1123. {
  1124. int nIndex = FindDominationRule( pRule );
  1125. if ( nIndex >= 0 && nIndex < m_Dominators.Count() - 1 )
  1126. {
  1127. m_Dominators.Swap( nIndex, nIndex + 1 );
  1128. return;
  1129. }
  1130. }
  1131. //-----------------------------------------------------------------------------
  1132. // Attaches a channel to an input
  1133. //-----------------------------------------------------------------------------
  1134. void CDmeCombinationOperator::AttachChannelToControlValue( ControlIndex_t nControlIndex, CombinationControlType_t type, CDmeChannel *pChannel )
  1135. {
  1136. pChannel->SetOutput( m_ControlValues[type].GetAttribute(), nControlIndex );
  1137. }
  1138. //-----------------------------------------------------------------------------
  1139. // Determines the weighting of input controls based on the deltaState name
  1140. //-----------------------------------------------------------------------------
  1141. int CDmeCombinationOperator::FindDeltaStateIndex( CDmAttribute *pDeltaArray, const char *pDeltaStateName )
  1142. {
  1143. const CDmrElementArray<> deltas( pDeltaArray );
  1144. int nDeltaArrayCount = deltas.Count();
  1145. for ( int i = 0; i < nDeltaArrayCount; ++i )
  1146. {
  1147. CDmElement *pDeltaElement = deltas[i];
  1148. if ( pDeltaElement && !Q_stricmp( pDeltaElement->GetName(), pDeltaStateName ) )
  1149. return i;
  1150. }
  1151. return -1;
  1152. }
  1153. //-----------------------------------------------------------------------------
  1154. // Determines which combination to use based on the deltaState name
  1155. //-----------------------------------------------------------------------------
  1156. int CDmeCombinationOperator::ParseDeltaName(const char *pDeltaStateName, int *pControlIndices )
  1157. {
  1158. char pBuf[512];
  1159. Q_strncpy( pBuf, pDeltaStateName, sizeof(pBuf) );
  1160. int nComboCount = 0;
  1161. char *pEnd;
  1162. for ( char *pName = pBuf; *pName; pName = pEnd )
  1163. {
  1164. pEnd = strchr( pName, '_' );
  1165. if ( !pEnd )
  1166. {
  1167. pEnd = pName + Q_strlen( pName );
  1168. }
  1169. else
  1170. {
  1171. // Null-terminate
  1172. *pEnd = 0;
  1173. ++pEnd;
  1174. }
  1175. int nControlIndex = FindRawControlIndex( pName );
  1176. if ( nControlIndex < 0 )
  1177. return 0;
  1178. pControlIndices[ nComboCount++ ] = nControlIndex;
  1179. }
  1180. return nComboCount;
  1181. }
  1182. //-----------------------------------------------------------------------------
  1183. // Finds dominators
  1184. //-----------------------------------------------------------------------------
  1185. void CDmeCombinationOperator::FindDominators( CombinationOperation_t& op )
  1186. {
  1187. // Dominators are sets of inputs, which, when set to 1, will
  1188. // supress another set of inputs. Only combinations which contain *all*
  1189. // dominators will suppress any combinatation that contains *all* suppressors
  1190. int nDominatorCount = m_DominatorInfo.Count();
  1191. for ( int i = 0; i < nDominatorCount; ++i )
  1192. {
  1193. DominatorInfo_t &info = m_DominatorInfo[i];
  1194. // Look for suppressor indices in the control indices list
  1195. int nCount = info.m_SuppressedIndices.Count();
  1196. int j;
  1197. for ( j = 0; j < nCount; ++j )
  1198. {
  1199. if ( op.m_ControlIndices.Find( info.m_SuppressedIndices[j] ) < 0 )
  1200. break;
  1201. }
  1202. if ( j != nCount )
  1203. continue;
  1204. op.m_DominatorIndices.AddToTail( i );
  1205. }
  1206. }
  1207. //-----------------------------------------------------------------------------
  1208. // Purpose:
  1209. //-----------------------------------------------------------------------------
  1210. void CDmeCombinationOperator::ComputeCombinationInfo( int nIndex )
  1211. {
  1212. CleanUpCombinationInfo( nIndex );
  1213. int nCurrentCount = m_CombinationInfo.Count();
  1214. while ( nIndex >= nCurrentCount )
  1215. {
  1216. int j = m_CombinationInfo.AddToTail();
  1217. CombinationInfo_t &info = m_CombinationInfo[j];
  1218. for ( int k = 0; k < COMBO_CONTROL_TYPE_COUNT; ++k )
  1219. {
  1220. info.m_hDestAttribute[k] = DMATTRIBUTE_HANDLE_INVALID;
  1221. }
  1222. ++nCurrentCount;
  1223. }
  1224. CombinationInfo_t &info = m_CombinationInfo[nIndex];
  1225. CDmElement *pSource = m_Targets[ nIndex ];
  1226. if ( !pSource )
  1227. return;
  1228. CDmrElementArray<> deltas( pSource, "deltaStates" );
  1229. if ( !deltas.IsValid() )
  1230. return;
  1231. CDmrArray<Vector2D> weights( pSource, "deltaStateWeights" );
  1232. if ( !weights.IsValid() )
  1233. return;
  1234. CDmrArray<Vector2D> weightsLagged( pSource, "deltaStateWeightsLagged" );
  1235. // This is an error state
  1236. if ( deltas.Count() > weights.Count() )
  1237. return;
  1238. // This is an error state
  1239. if ( weightsLagged.IsValid() && deltas.Count() > weightsLagged.Count() )
  1240. return;
  1241. info.m_hDestAttribute[COMBO_CONTROL_NORMAL] = weights.GetAttribute()->GetHandle();
  1242. info.m_hDestAttribute[COMBO_CONTROL_LAGGED] = weightsLagged.IsValid() ? weightsLagged.GetAttribute()->GetHandle() : DMATTRIBUTE_HANDLE_INVALID;
  1243. int *pTemp = (int*)_alloca( m_RawControlInfo.Count() * sizeof(int) );
  1244. int nDeltaCount = deltas.Count();
  1245. for ( int i = 0; i < nDeltaCount; ++i )
  1246. {
  1247. CDmElement *pDeltaElement = deltas[i];
  1248. if ( !pDeltaElement )
  1249. continue;
  1250. int nControlCount = ParseDeltaName( pDeltaElement->GetName(), pTemp );
  1251. if ( nControlCount == 0 )
  1252. continue;
  1253. int j = info.m_Outputs.AddToTail();
  1254. CombinationOperation_t &op = info.m_Outputs[j];
  1255. op.m_nDeltaStateIndex = i;
  1256. op.m_ControlIndices.AddMultipleToTail( nControlCount, pTemp );
  1257. // Find dominators
  1258. FindDominators( op );
  1259. }
  1260. }
  1261. //-----------------------------------------------------------------------------
  1262. // Purpose:
  1263. //-----------------------------------------------------------------------------
  1264. void CDmeCombinationOperator::ComputeCombinationInfo()
  1265. {
  1266. int nTargetCount = m_Targets.Count();
  1267. for ( int i = 0; i < nTargetCount; ++i )
  1268. {
  1269. ComputeCombinationInfo( i );
  1270. }
  1271. }
  1272. //-----------------------------------------------------------------------------
  1273. // Purpose:
  1274. //-----------------------------------------------------------------------------
  1275. void CDmeCombinationOperator::CleanUpCombinationInfo( int nIndex )
  1276. {
  1277. if ( nIndex >= m_CombinationInfo.Count() )
  1278. return;
  1279. CombinationInfo_t &info = m_CombinationInfo[ nIndex ];
  1280. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  1281. {
  1282. info.m_hDestAttribute[i] = DMATTRIBUTE_HANDLE_INVALID;
  1283. }
  1284. info.m_Outputs.RemoveAll();
  1285. }
  1286. void CDmeCombinationOperator::CleanUpCombinationInfo( )
  1287. {
  1288. int nCount = m_CombinationInfo.Count();
  1289. for ( int i = 0; i < nCount; ++i )
  1290. {
  1291. CleanUpCombinationInfo( i );
  1292. }
  1293. m_CombinationInfo.RemoveAll();
  1294. }
  1295. //-----------------------------------------------------------------------------
  1296. // helpers for finding corrector names
  1297. //-----------------------------------------------------------------------------
  1298. void CDmeCombinationOperator::Resolve()
  1299. {
  1300. BaseClass::Resolve();
  1301. if ( m_InputControls.IsDirty() || m_Dominators.IsDirty() )
  1302. {
  1303. RebuildRawControlList();
  1304. ComputeCombinationInfo();
  1305. }
  1306. }
  1307. //-----------------------------------------------------------------------------
  1308. // Adds a target for the combination operator
  1309. //-----------------------------------------------------------------------------
  1310. void CDmeCombinationOperator::AddTarget( CDmElement *pElement )
  1311. {
  1312. if ( !pElement )
  1313. return;
  1314. int i = m_Targets.AddToTail( pElement );
  1315. ComputeCombinationInfo( i );
  1316. }
  1317. //-----------------------------------------------------------------------------
  1318. // Sets targets
  1319. //-----------------------------------------------------------------------------
  1320. void CDmeCombinationOperator::AddTarget( CDmeDag *pDag )
  1321. {
  1322. if ( !pDag )
  1323. return;
  1324. CDmeShape *pShape = pDag->GetShape();
  1325. AddTarget( pShape );
  1326. int nChildCount = pDag->GetChildCount();
  1327. for ( int i = 0; i < nChildCount; ++i )
  1328. {
  1329. CDmeDag *pChild = pDag->GetChild(i);
  1330. // Do not traverse into models
  1331. if ( CastElement< CDmeModel >( pChild ) )
  1332. continue;
  1333. AddTarget( pChild );
  1334. }
  1335. }
  1336. //-----------------------------------------------------------------------------
  1337. // Remaps non-stereo -> stereo, stereo ->left/right, also adds multilevel + filter
  1338. //-----------------------------------------------------------------------------
  1339. void CDmeCombinationOperator::ComputeInternalControlValue( RawControlIndex_t nRawControlIndex, CombinationControlType_t type, Vector2D &value )
  1340. {
  1341. const RawControlInfo_t &info = m_RawControlInfo[nRawControlIndex];
  1342. const Vector &vecControlValue = m_ControlValues[ type ][ info.m_InputControl ];
  1343. const bool bMultiControl = IsMultiControl( info.m_InputControl );
  1344. float flValue = bMultiControl ? vecControlValue.z : vecControlValue.x;
  1345. // Apply multicontrol remapping
  1346. if ( flValue <= info.m_FilterRamp.x || flValue >= info.m_FilterRamp.w )
  1347. {
  1348. flValue = 0.0f;
  1349. }
  1350. else if ( flValue < info.m_FilterRamp.y )
  1351. {
  1352. flValue = RemapVal( flValue, info.m_FilterRamp.x, info.m_FilterRamp.y, 0.0f, 1.0f );
  1353. }
  1354. else if ( flValue > info.m_FilterRamp.z )
  1355. {
  1356. flValue = RemapVal( flValue, info.m_FilterRamp.z, info.m_FilterRamp.w, 1.0f, 0.0f );
  1357. }
  1358. else
  1359. {
  1360. flValue = 1.0f;
  1361. }
  1362. if ( IsEyelidControl( info.m_InputControl ) )
  1363. {
  1364. if ( info.m_bLowerEyelid )
  1365. {
  1366. flValue = ( 1.0f - flValue ) * vecControlValue.x;
  1367. }
  1368. else
  1369. {
  1370. flValue *= vecControlValue.x;
  1371. }
  1372. }
  1373. else if ( bMultiControl )
  1374. {
  1375. flValue *= vecControlValue.x;
  1376. }
  1377. value.x = value.y = flValue;
  1378. if ( IsStereoControl( info.m_InputControl ) )
  1379. {
  1380. if ( vecControlValue.y < 0.5f )
  1381. {
  1382. float flRightAmount = RemapVal( vecControlValue.y, 0.0f, 0.5f, 0.0f, 1.0f );
  1383. value.y *= flRightAmount;
  1384. }
  1385. else
  1386. {
  1387. float flLeftAmount = RemapVal( vecControlValue.y, 0.5f, 1.0f, 1.0f, 0.0f );
  1388. value.x *= flLeftAmount;
  1389. }
  1390. }
  1391. }
  1392. //-----------------------------------------------------------------------------
  1393. // Computes lagged input values from non-lagged input
  1394. //-----------------------------------------------------------------------------
  1395. void CDmeCombinationOperator::ComputeLaggedInputValues()
  1396. {
  1397. if ( !m_bSpecifyingLaggedData )
  1398. return;
  1399. float t = Plat_FloatTime();
  1400. if ( m_flLastLaggedComputationTime == FLT_MIN )
  1401. {
  1402. m_flLastLaggedComputationTime = t;
  1403. }
  1404. float dt = t - m_flLastLaggedComputationTime;
  1405. m_flLastLaggedComputationTime = t;
  1406. float flFactor = ExponentialDecay( 0.8, 0.033, dt );
  1407. int nCount = m_ControlValues[COMBO_CONTROL_NORMAL].Count();
  1408. for ( int i = 0; i < nCount; ++i )
  1409. {
  1410. Vector vecLerp;
  1411. VectorLerp( m_ControlValues[COMBO_CONTROL_NORMAL][i], m_ControlValues[COMBO_CONTROL_LAGGED][i], flFactor, vecLerp );
  1412. m_ControlValues[COMBO_CONTROL_LAGGED].Set( i, vecLerp );
  1413. }
  1414. }
  1415. //-----------------------------------------------------------------------------
  1416. // Purpose:
  1417. //-----------------------------------------------------------------------------
  1418. void CDmeCombinationOperator::Operate()
  1419. {
  1420. ComputeLaggedInputValues();
  1421. int nCount = m_CombinationInfo.Count();
  1422. for ( int i = 0; i < nCount; ++i )
  1423. {
  1424. CombinationInfo_t &info = m_CombinationInfo[i];
  1425. for ( CombinationControlType_t type = COMBO_CONTROL_FIRST; type < COMBO_CONTROL_TYPE_COUNT; type = (CombinationControlType_t)(type+1) )
  1426. {
  1427. if ( ( info.m_hDestAttribute[type] == DMATTRIBUTE_HANDLE_INVALID ) || !g_pDataModel->IsAttributeHandleValid( info.m_hDestAttribute[type] ) )
  1428. continue;
  1429. CDmAttribute* pAttribute = g_pDataModel->GetAttribute( info.m_hDestAttribute[type] );
  1430. if ( !pAttribute || pAttribute->GetType() != AT_VECTOR2_ARRAY )
  1431. continue;
  1432. CDmrArray< Vector2D > vec2D( pAttribute );
  1433. CombinationControlType_t useType = m_bSpecifyingLaggedData ? type : COMBO_CONTROL_NORMAL;
  1434. int nOutputCount = info.m_Outputs.Count();
  1435. for ( int j = 0; j < nOutputCount; ++j )
  1436. {
  1437. CombinationOperation_t &op = info.m_Outputs[j];
  1438. // Compute the core combination
  1439. Vector2D vecValue( 1.0f, 1.0f );
  1440. int nCombinationCount = op.m_ControlIndices.Count();
  1441. for ( int k = 0; k < nCombinationCount; ++k )
  1442. {
  1443. Vector2D v;
  1444. ComputeInternalControlValue( op.m_ControlIndices[k], useType, v );
  1445. vecValue *= v;
  1446. }
  1447. // Compute the dominators
  1448. int nDominatorCount = op.m_DominatorIndices.Count();
  1449. for ( int k = 0; k < nDominatorCount; ++k )
  1450. {
  1451. const CUtlVector< int > &dominantIndices = m_DominatorInfo[ op.m_DominatorIndices[k] ].m_DominantIndices;
  1452. int nDominantCount = dominantIndices.Count();
  1453. Vector2D suppressor( -1.0f, -1.0f );
  1454. for ( int l = 0; l < nDominantCount; ++l )
  1455. {
  1456. Vector2D v;
  1457. ComputeInternalControlValue( dominantIndices[l], useType, v );
  1458. suppressor *= v;
  1459. }
  1460. suppressor.x += 1.0f; suppressor.y += 1.0f;
  1461. vecValue *= suppressor;
  1462. }
  1463. vec2D.Set( op.m_nDeltaStateIndex, vecValue );
  1464. }
  1465. }
  1466. }
  1467. }
  1468. void CDmeCombinationOperator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
  1469. {
  1470. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  1471. {
  1472. attrs.AddToTail( m_ControlValues[i].GetAttribute() );
  1473. }
  1474. }
  1475. void CDmeCombinationOperator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
  1476. {
  1477. int nCount = m_CombinationInfo.Count();
  1478. for ( int i = 0; i < nCount; ++i )
  1479. {
  1480. CombinationInfo_t &info = m_CombinationInfo[i];
  1481. for ( int j = 0; j < COMBO_CONTROL_TYPE_COUNT; ++j )
  1482. {
  1483. if ( ( info.m_hDestAttribute[j] == DMATTRIBUTE_HANDLE_INVALID ) || !g_pDataModel->IsAttributeHandleValid( info.m_hDestAttribute[j] ) )
  1484. continue;
  1485. CDmAttribute* pAttribute = g_pDataModel->GetAttribute( info.m_hDestAttribute[j] );
  1486. if ( !pAttribute || pAttribute->GetType() != AT_VECTOR2_ARRAY )
  1487. continue;
  1488. attrs.AddToTail( pAttribute );
  1489. }
  1490. }
  1491. }
  1492. //-----------------------------------------------------------------------------
  1493. // Used by studiomdl to discover the various combination rules
  1494. //-----------------------------------------------------------------------------
  1495. int CDmeCombinationOperator::GetOperationTargetCount() const
  1496. {
  1497. return m_Targets.Count();
  1498. }
  1499. CDmElement *CDmeCombinationOperator::GetOperationTarget( int nTargetIndex )
  1500. {
  1501. return m_Targets[ nTargetIndex ];
  1502. }
  1503. int CDmeCombinationOperator::GetOperationCount( int nTargetIndex ) const
  1504. {
  1505. return m_CombinationInfo[ nTargetIndex ].m_Outputs.Count();
  1506. }
  1507. CDmElement *CDmeCombinationOperator::GetOperationDeltaState( int nTargetIndex, int nOpIndex )
  1508. {
  1509. CDmElement *pElement = GetOperationTarget( nTargetIndex );
  1510. const CDmrElementArray<> deltaArray( pElement, "deltaStates" );
  1511. if ( !deltaArray.IsValid() )
  1512. return NULL;
  1513. int nDeltaStateIndex = m_CombinationInfo[ nTargetIndex ].m_Outputs[ nOpIndex ].m_nDeltaStateIndex;
  1514. return deltaArray[ nDeltaStateIndex ];
  1515. }
  1516. const CUtlVector< int > &CDmeCombinationOperator::GetOperationControls( int nTargetIndex, int nOpIndex ) const
  1517. {
  1518. return m_CombinationInfo[ nTargetIndex ].m_Outputs[ nOpIndex ].m_ControlIndices;
  1519. }
  1520. int CDmeCombinationOperator::GetOperationDominatorCount( int nTargetIndex, int nOpIndex ) const
  1521. {
  1522. return m_CombinationInfo[ nTargetIndex ].m_Outputs[ nOpIndex ].m_DominatorIndices.Count();
  1523. }
  1524. const CUtlVector< int > &CDmeCombinationOperator::GetOperationDominator( int nTargetIndex, int nOpIndex, int nDominatorIndex ) const
  1525. {
  1526. int nIndex = m_CombinationInfo[ nTargetIndex ].m_Outputs[ nOpIndex ].m_DominatorIndices[ nDominatorIndex ];
  1527. return m_DominatorInfo[ nIndex ].m_DominantIndices;
  1528. }
  1529. void CDmeCombinationOperator::CopyControls( CDmeCombinationOperator *pSrc )
  1530. {
  1531. // Clean Me Out!
  1532. RemoveAllControls();
  1533. // Copy The Source Controls
  1534. for ( int i = 0; i < pSrc->m_InputControls.Count(); ++i )
  1535. {
  1536. CDmeCombinationInputControl *pSrcInput = pSrc->m_InputControls[ i ];
  1537. if ( pSrcInput )
  1538. {
  1539. CDmeCombinationInputControl *pDstInput = pSrcInput->Copy( );
  1540. pDstInput->SetFileId( GetFileId(), TD_DEEP );
  1541. m_InputControls.AddToTail( pDstInput );
  1542. }
  1543. }
  1544. // Copy The Control Values
  1545. m_ControlValues[ COMBO_CONTROL_NORMAL ].CopyArray(
  1546. pSrc->m_ControlValues[ COMBO_CONTROL_NORMAL ].Base(),
  1547. pSrc->m_ControlValues[ COMBO_CONTROL_NORMAL ].Count() );
  1548. m_ControlValues[ COMBO_CONTROL_LAGGED ].CopyArray(
  1549. pSrc->m_ControlValues[ COMBO_CONTROL_LAGGED ].Base(),
  1550. pSrc->m_ControlValues[ COMBO_CONTROL_LAGGED ].Count() );
  1551. RebuildRawControlList();
  1552. m_Dominators.Purge();
  1553. // Copy The Source Controls
  1554. for ( int i = 0; i < pSrc->m_Dominators.Count(); ++i )
  1555. {
  1556. CDmeCombinationDominationRule *pSrcDom = pSrc->m_Dominators[ i ];
  1557. if ( pSrcDom )
  1558. {
  1559. CDmeCombinationDominationRule *pDstDom = pSrcDom->Copy( );
  1560. pDstDom->SetFileId( GetFileId(), TD_DEEP );
  1561. m_Dominators.AddToTail( pDstDom );
  1562. }
  1563. }
  1564. RebuildRawControlList();
  1565. }
  1566. //-----------------------------------------------------------------------------
  1567. // Generates wrinkle deltas for the uncorrected controls
  1568. // NOTE: This is only being used because we have no authoring path for wrinkle data yet
  1569. //-----------------------------------------------------------------------------
  1570. void CDmeCombinationOperator::GenerateWrinkleDeltas( CDmeShape *pShape, bool bOverwrite )
  1571. {
  1572. CDmeMesh* pMesh = CastElement< CDmeMesh >( pShape );
  1573. CDmeVertexData *pBindState = pMesh ? pMesh->FindBaseState( "bind" ) : NULL;
  1574. if ( pBindState )
  1575. {
  1576. int nRawControlCount = m_RawControlInfo.Count();
  1577. for ( int i = 0; i < nRawControlCount; ++i )
  1578. {
  1579. CDmeVertexDeltaData* pDelta = pMesh->FindDeltaState( m_RawControlInfo[i].m_Name );
  1580. if ( pDelta )
  1581. {
  1582. pDelta->GenerateWrinkleDelta( pBindState, m_RawControlInfo[i].m_flWrinkleScale, bOverwrite );
  1583. }
  1584. }
  1585. }
  1586. }
  1587. void CDmeCombinationOperator::GenerateWrinkleDeltas( bool bOverwrite /* = true */ )
  1588. {
  1589. int nTargetCount = m_Targets.Count();
  1590. for ( int i = 0; i < nTargetCount; ++i )
  1591. {
  1592. GenerateWrinkleDeltas( CastElement< CDmeShape >( m_Targets[i] ), bOverwrite );
  1593. }
  1594. }
  1595. //-----------------------------------------------------------------------------
  1596. //
  1597. //-----------------------------------------------------------------------------
  1598. void CDmeCombinationOperator::RemoveAllTargets()
  1599. {
  1600. m_Targets.RemoveAll();
  1601. CleanUpCombinationInfo();
  1602. }
  1603. //-----------------------------------------------------------------------------
  1604. //
  1605. //-----------------------------------------------------------------------------
  1606. void CDmeCombinationOperator::SetToDefault()
  1607. {
  1608. const int nControlsCount = m_InputControls.Count();
  1609. for ( int i = 0; i < nControlsCount; ++i )
  1610. {
  1611. m_IsDefaultValue[ i ] = true;
  1612. UpdateDefaultValue( i );
  1613. }
  1614. }
  1615. //-----------------------------------------------------------------------------
  1616. //
  1617. //-----------------------------------------------------------------------------
  1618. void CDmeCombinationOperator::SetToBase()
  1619. {
  1620. const int nControlsCount = m_InputControls.Count();
  1621. for ( int i = 0; i < nControlsCount; ++i )
  1622. {
  1623. const float flBaseValue = GetControlBaseValue( i );
  1624. for ( int j = 0; j < COMBO_CONTROL_TYPE_COUNT; ++j )
  1625. {
  1626. const Vector &v = m_ControlValues[ j ][ i ];
  1627. m_ControlValues[ j ].Set( i, Vector( flBaseValue, v.y, v.z ) );
  1628. }
  1629. }
  1630. }
  1631. //-----------------------------------------------------------------------------
  1632. // * Remove all controls which refer to raw controls which refer to delta
  1633. // states which do not exist in any target
  1634. // * Remove all dominators which refer to states which no longer exist
  1635. //-----------------------------------------------------------------------------
  1636. void CDmeCombinationOperator::Purge()
  1637. {
  1638. bool bDelete = true;
  1639. const int nTargetCount = m_Targets.Count();
  1640. for ( int i = 0; i < nTargetCount; ++i )
  1641. {
  1642. CDmElement *pSource = m_Targets[ i ];
  1643. if ( !pSource )
  1644. continue;
  1645. CDmrElementArray<> deltas( pSource, "deltaStates" );
  1646. if ( !deltas.IsValid() )
  1647. continue;
  1648. const int nDeltaCount = deltas.Count();
  1649. do
  1650. {
  1651. bDelete = false;
  1652. const int nControlCount = GetControlCount();
  1653. for ( int j = 0; j < nControlCount; ++j )
  1654. {
  1655. bDelete = true;
  1656. const int nRawControlCount = GetRawControlCount( j );
  1657. for ( int k = 0; bDelete && k < nRawControlCount; ++k )
  1658. {
  1659. for ( int l = 0; l < nDeltaCount; ++l )
  1660. {
  1661. if ( !Q_strcmp( GetRawControlName( j, k ), deltas[ l ]->GetName() ) )
  1662. {
  1663. bDelete = false;
  1664. break;
  1665. }
  1666. }
  1667. }
  1668. if ( bDelete )
  1669. {
  1670. RemoveControl( GetControlName( j ) );
  1671. break;
  1672. }
  1673. }
  1674. } while ( bDelete );
  1675. }
  1676. do
  1677. {
  1678. bDelete = false;
  1679. const int nDomCount = DominationRuleCount();
  1680. for ( int i = 0; i < nDomCount; ++i )
  1681. {
  1682. bDelete = true;
  1683. CDmeCombinationDominationRule *pDom = GetDominationRule( i );
  1684. const int nDCount = pDom->DominatorCount();
  1685. for ( int j = 0; j < nDCount; ++j )
  1686. {
  1687. if ( HasRawControl( pDom->GetDominator( j ) ) )
  1688. {
  1689. bDelete = false;
  1690. break;
  1691. }
  1692. }
  1693. if ( !bDelete )
  1694. {
  1695. const int nSCount = pDom->SuppressedCount();
  1696. for ( int j = 0; j < nSCount; ++j )
  1697. {
  1698. if ( HasRawControl( pDom->GetSuppressed( j ) ) )
  1699. {
  1700. bDelete = false;
  1701. break;
  1702. }
  1703. }
  1704. }
  1705. if ( bDelete )
  1706. {
  1707. RemoveDominationRule( i );
  1708. break;
  1709. }
  1710. }
  1711. } while ( bDelete );
  1712. }
  1713. //-----------------------------------------------------------------------------
  1714. // Creates lagged log data from an input log
  1715. //-----------------------------------------------------------------------------
  1716. static void CreateLaggedLog( CDmeVector2Log *pLog, CDmeVector2Log *pLaggedLog, int nSamplesPerSec )
  1717. {
  1718. }
  1719. //-----------------------------------------------------------------------------
  1720. // Helper method to create a lagged version of channel data from source data
  1721. //-----------------------------------------------------------------------------
  1722. void CreateLaggedVertexAnimation( CDmeChannelsClip *pClip, int nSamplesPerSec )
  1723. {
  1724. if ( !pClip )
  1725. return;
  1726. int nChannelCount = pClip->m_Channels.Count();
  1727. for ( int i = 0; i < nChannelCount; ++i )
  1728. {
  1729. CDmeChannel *pChannel = pClip->m_Channels[i];
  1730. CDmElement *pDest = pChannel->GetToElement();
  1731. CDmAttribute *pDestAttr = pChannel->GetToAttribute();
  1732. int nArrayIndex = pChannel->GetToArrayIndex();
  1733. if ( pChannel->GetLog()->GetDataType() != AT_VECTOR2 )
  1734. continue;
  1735. if ( Q_stricmp( pDestAttr->GetName(), "controlValues" ) )
  1736. continue;
  1737. if ( !pDest->GetValue<bool>( "usesLaggedValues" ) )
  1738. continue;
  1739. CDmAttribute *pLaggedAttr = pDest->GetAttribute( "controlValuesLagged" );
  1740. if ( !pLaggedAttr || pLaggedAttr->GetType() != AT_VECTOR2_ARRAY )
  1741. continue;
  1742. int nLen = Q_strlen( pChannel->GetName() );
  1743. char *pNewChannelName = (char*)_alloca( nLen + 10 );
  1744. memcpy( pNewChannelName, pChannel->GetName(), nLen+1 );
  1745. Q_strncpy( &pNewChannelName[nLen], "_lagged", 10 );
  1746. CDmeChannel *pNewChannel = CreateElement< CDmeChannel >( pNewChannelName, pClip->GetFileId() );
  1747. pNewChannel->SetOutput( pLaggedAttr, nArrayIndex );
  1748. CDmeVector2Log *pNewLog = pNewChannel->CreateLog< Vector2D >( );
  1749. pClip->m_Channels.AddToTail( pNewChannel );
  1750. CreateLaggedLog( static_cast<CDmeVector2Log*>( pChannel->GetLog() ), pNewLog, nSamplesPerSec );
  1751. }
  1752. }
  1753. //-----------------------------------------------------------------------------
  1754. //
  1755. // A class used to edit combination operators in Maya.. doesn't connect to targets
  1756. //
  1757. //-----------------------------------------------------------------------------
  1758. IMPLEMENT_ELEMENT_FACTORY( DmeMayaCombinationOperator, CDmeMayaCombinationOperator );
  1759. //-----------------------------------------------------------------------------
  1760. // Purpose:
  1761. //-----------------------------------------------------------------------------
  1762. void CDmeMayaCombinationOperator::OnConstruction()
  1763. {
  1764. m_DeltaStates.Init( this, "deltaStates" );
  1765. m_DeltaStateWeights[COMBO_CONTROL_NORMAL].Init( this, "deltaStateWeights" );
  1766. m_DeltaStateWeights[COMBO_CONTROL_LAGGED].Init( this, "deltaStateWeightsLagged" );
  1767. AddTarget( this );
  1768. }
  1769. void CDmeMayaCombinationOperator::OnDestruction()
  1770. {
  1771. }
  1772. //-----------------------------------------------------------------------------
  1773. // Add, remove delta states
  1774. //-----------------------------------------------------------------------------
  1775. void CDmeMayaCombinationOperator::AddDeltaState( const char *pDeltaStateName )
  1776. {
  1777. m_DeltaStates.AddToTail( CreateElement<CDmElement>( pDeltaStateName ) );
  1778. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  1779. {
  1780. m_DeltaStateWeights[i].AddToTail( Vector2D( 1.0f, 1.0f ) );
  1781. }
  1782. ComputeCombinationInfo( 0 );
  1783. }
  1784. void CDmeMayaCombinationOperator::RemoveDeltaState( const char *pDeltaStateName )
  1785. {
  1786. int nIndex = FindDeltaState( pDeltaStateName );
  1787. if ( nIndex >= 0 )
  1788. {
  1789. m_DeltaStates.Remove( nIndex );
  1790. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  1791. {
  1792. m_DeltaStateWeights[i].Remove( nIndex );
  1793. }
  1794. }
  1795. ComputeCombinationInfo( 0 );
  1796. }
  1797. void CDmeMayaCombinationOperator::RemoveAllDeltaStates()
  1798. {
  1799. m_DeltaStates.RemoveAll( );
  1800. for ( int i = 0; i < COMBO_CONTROL_TYPE_COUNT; ++i )
  1801. {
  1802. m_DeltaStateWeights[i].RemoveAll();
  1803. }
  1804. ComputeCombinationInfo( 0 );
  1805. }
  1806. int CDmeMayaCombinationOperator::FindDeltaState( const char *pDeltaStateName )
  1807. {
  1808. int nCount = m_DeltaStates.Count();
  1809. for ( int i = 0; i < nCount; ++i )
  1810. {
  1811. if ( !Q_stricmp( pDeltaStateName, m_DeltaStates[i]->GetName() ) )
  1812. return i;
  1813. }
  1814. return -1;
  1815. }
  1816. int CDmeMayaCombinationOperator::DeltaStateCount() const
  1817. {
  1818. return m_DeltaStates.Count();
  1819. }
  1820. const char *CDmeMayaCombinationOperator::GetDeltaState( int nIndex ) const
  1821. {
  1822. return m_DeltaStates[nIndex]->GetName();
  1823. }
  1824. const Vector2D& CDmeMayaCombinationOperator::GetDeltaStateWeight( int nIndex, CombinationControlType_t type ) const
  1825. {
  1826. return m_DeltaStateWeights[type][nIndex];
  1827. }