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.

1721 lines
51 KiB

  1. //====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "movieobjects/dmeanimationset.h"
  7. #include "movieobjects/dmeclip.h"
  8. #include "movieobjects/dmegamemodel.h"
  9. #include "movieobjects/dmecombinationoperator.h"
  10. #include "movieobjects/dmetransformcontrol.h"
  11. #include "movieobjects/dmechannel.h"
  12. #include "movieobjects/dmerighandle.h"
  13. #include "movieobjects/dmerigconstraintoperators.h"
  14. #include "movieobjects/dmerig.h"
  15. #include "datamodel/dmelementfactoryhelper.h"
  16. #include "datamodel/dmehandle.h"
  17. #include "phonemeconverter.h"
  18. #include "tier1/utlstringmap.h"
  19. #include "tier2/tier2.h"
  20. #include "filesystem.h"
  21. #include "studio.h"
  22. #include "tier3/tier3.h"
  23. #include "tier1/utlbuffer.h"
  24. #include "tier1/fmtstr.h"
  25. // memdbgon must be the last include file in a .cpp file!!!
  26. #include "tier0/memdbgon.h"
  27. //-----------------------------------------------------------------------------
  28. // CDmePreset - container for preset control values
  29. //-----------------------------------------------------------------------------
  30. IMPLEMENT_ELEMENT_FACTORY( DmePreset, CDmePreset );
  31. void CDmePreset::OnConstruction()
  32. {
  33. m_ControlValues.Init( this, "controlValues" );
  34. }
  35. void CDmePreset::OnDestruction()
  36. {
  37. }
  38. CDmaElementArray< CDmElement > &CDmePreset::GetControlValues()
  39. {
  40. return m_ControlValues;
  41. }
  42. const CDmaElementArray< CDmElement > &CDmePreset::GetControlValues() const
  43. {
  44. return m_ControlValues;
  45. }
  46. int CDmePreset::FindControlValueIndex( const char *pControlName )
  47. {
  48. int c = m_ControlValues.Count();
  49. for ( int i = 0; i < c; ++i )
  50. {
  51. CDmElement *e = m_ControlValues.Get( i );
  52. if ( !Q_stricmp( e->GetName(), pControlName ) )
  53. return i;
  54. }
  55. return -1;
  56. }
  57. CDmElement *CDmePreset::FindControlValue( const char *pControlName )
  58. {
  59. int i = FindControlValueIndex( pControlName );
  60. if ( i >= 0 )
  61. return m_ControlValues.Get(i);
  62. return NULL;
  63. }
  64. CDmElement *CDmePreset::FindOrAddControlValue( const char *pControlName )
  65. {
  66. CDmElement *pControlValues = FindControlValue( pControlName );
  67. if ( !pControlValues )
  68. {
  69. // Create the default groups in order
  70. pControlValues = CreateElement< CDmElement >( pControlName, GetFileId() );
  71. m_ControlValues.AddToTail( pControlValues );
  72. }
  73. return pControlValues;
  74. }
  75. void CDmePreset::RemoveControlValue( const char *pControlName )
  76. {
  77. int i = FindControlValueIndex( pControlName );
  78. if ( i >= 0 )
  79. {
  80. m_ControlValues.Remove( i );
  81. }
  82. }
  83. //-----------------------------------------------------------------------------
  84. // Is the preset read-only?
  85. //-----------------------------------------------------------------------------
  86. bool CDmePreset::IsReadOnly()
  87. {
  88. DmAttributeReferenceIterator_t h = g_pDataModel->FirstAttributeReferencingElement( GetHandle() );
  89. while ( h != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID )
  90. {
  91. CDmAttribute *pAttribute = g_pDataModel->GetAttribute( h );
  92. CDmePresetGroup *pOwner = CastElement<CDmePresetGroup>( pAttribute->GetOwner() );
  93. if ( pOwner && pOwner->m_bIsReadOnly )
  94. return true;
  95. h = g_pDataModel->NextAttributeReferencingElement( h );
  96. }
  97. return false;
  98. }
  99. bool CDmePreset::IsAnimated()
  100. {
  101. return GetValue< bool >( "animated", false );
  102. }
  103. //-----------------------------------------------------------------------------
  104. // Copies control values
  105. //-----------------------------------------------------------------------------
  106. void CDmePreset::CopyControlValuesFrom( CDmePreset *pSource )
  107. {
  108. m_ControlValues.RemoveAll();
  109. const CDmaElementArray< CDmElement > &sourceValues = pSource->GetControlValues();
  110. int nCount = sourceValues.Count();
  111. for ( int i = 0; i < nCount; ++i )
  112. {
  113. CDmElement *pCopy = sourceValues[i]->Copy( );
  114. m_ControlValues.AddToTail( pCopy );
  115. }
  116. }
  117. IMPLEMENT_ELEMENT_FACTORY( DmeProceduralPresetSettings, CDmeProceduralPresetSettings );
  118. void CDmeProceduralPresetSettings::OnConstruction()
  119. {
  120. m_flJitterScale.InitAndSet( this, "jitterscale", 1.0f );
  121. m_flSmoothScale.InitAndSet( this, "smoothscale", 1.0f );
  122. m_flSharpenScale.InitAndSet( this, "sharpenscale", 1.0f );
  123. m_flSoftenScale.InitAndSet( this, "softenscale", 1.0f );
  124. m_flJitterScaleVector.InitAndSet( this, "jitterscale_vector", 2.5f );
  125. m_flSmoothScaleVector.InitAndSet( this, "smoothscale_vector", 2.5f );
  126. m_flSharpenScaleVector.InitAndSet( this, "sharpenscale_vector", 2.5f );
  127. m_flSoftenScaleVector.InitAndSet( this, "softenscale_vector", 2.5f );
  128. m_nJitterIterations.InitAndSet( this, "jitteriterations", 5 );
  129. m_nSmoothIterations.InitAndSet( this, "smoothiterations", 5 );
  130. m_nSharpenIterations.InitAndSet( this, "sharpeniterations", 1 );
  131. m_nSoftenIterations.InitAndSet( this, "softeniterations", 1 );
  132. // 1/12 second now ( 833 ten thousandths )
  133. m_staggerInterval.InitAndSet( this, "staggerinterval", DmeTime_t( 1.0f / 12.0f ) );
  134. }
  135. void CDmeProceduralPresetSettings::OnDestruction()
  136. {
  137. }
  138. float CDmeProceduralPresetSettings::GetJitterScale( DmAttributeType_t attType ) const
  139. {
  140. if ( attType == AT_VECTOR3 )
  141. return m_flJitterScaleVector;
  142. return m_flJitterScale;
  143. }
  144. float CDmeProceduralPresetSettings::GetSmoothScale( DmAttributeType_t attType ) const
  145. {
  146. if ( attType == AT_VECTOR3 )
  147. return m_flSmoothScaleVector;
  148. return m_flSmoothScale;
  149. }
  150. float CDmeProceduralPresetSettings::GetSharpenScale( DmAttributeType_t attType ) const
  151. {
  152. if ( attType == AT_VECTOR3 )
  153. return m_flSharpenScaleVector;
  154. return m_flSharpenScale;
  155. }
  156. float CDmeProceduralPresetSettings::GetSoftenScale( DmAttributeType_t attType ) const
  157. {
  158. if ( attType == AT_VECTOR3 )
  159. return m_flSoftenScaleVector;
  160. return m_flSoftenScale;
  161. }
  162. //-----------------------------------------------------------------------------
  163. // CDmePresetGroup - container for animation set info
  164. //-----------------------------------------------------------------------------
  165. IMPLEMENT_ELEMENT_FACTORY( DmePresetGroup, CDmePresetGroup );
  166. void CDmePresetGroup::OnConstruction()
  167. {
  168. m_Presets.Init( this, "presets" );
  169. m_bIsVisible.InitAndSet( this, "visible", true );
  170. m_bIsReadOnly.Init( this, "readonly" );
  171. }
  172. void CDmePresetGroup::OnDestruction()
  173. {
  174. }
  175. CDmaElementArray< CDmePreset > &CDmePresetGroup::GetPresets()
  176. {
  177. return m_Presets;
  178. }
  179. const CDmaElementArray< CDmePreset > &CDmePresetGroup::GetPresets() const
  180. {
  181. return m_Presets;
  182. }
  183. //-----------------------------------------------------------------------------
  184. // Finds the index of a particular preset group
  185. //-----------------------------------------------------------------------------
  186. int CDmePresetGroup::FindPresetIndex( CDmePreset *pPreset )
  187. {
  188. int c = m_Presets.Count();
  189. for ( int i = 0; i < c; ++i )
  190. {
  191. CDmePreset *e = m_Presets.Get( i );
  192. if ( pPreset == e )
  193. return i;
  194. }
  195. return -1;
  196. }
  197. int CDmePresetGroup::FindPresetIndex( const char *pPresetName )
  198. {
  199. int c = m_Presets.Count();
  200. for ( int i = 0; i < c; ++i )
  201. {
  202. CDmePreset *e = m_Presets.Get( i );
  203. if ( !Q_stricmp( e->GetName(), pPresetName ) )
  204. return i;
  205. }
  206. return -1;
  207. }
  208. CDmePreset *CDmePresetGroup::FindPreset( const char *pPresetName )
  209. {
  210. int i;
  211. int c = m_Presets.Count();
  212. for ( i = 0; i < c; ++i )
  213. {
  214. CDmePreset *e = m_Presets.Get( i );
  215. if ( !Q_stricmp( e->GetName(), pPresetName ) )
  216. return e;
  217. }
  218. return NULL;
  219. }
  220. CDmePreset *CDmePresetGroup::FindOrAddPreset( const char *pPresetName )
  221. {
  222. CDmePreset *pPreset = FindPreset( pPresetName );
  223. if ( !pPreset )
  224. {
  225. // Create the default groups in order
  226. pPreset = CreateElement< CDmePreset >( pPresetName, GetFileId() );
  227. m_Presets.AddToTail( pPreset );
  228. }
  229. return pPreset;
  230. }
  231. bool CDmePresetGroup::RemovePreset( CDmePreset *pPreset )
  232. {
  233. int i = FindPresetIndex( pPreset );
  234. if ( i >= 0 )
  235. {
  236. m_Presets.Remove( i );
  237. return true;
  238. }
  239. return false;
  240. }
  241. bool CDmePresetGroup::RemovePreset( const char *pPresetName )
  242. {
  243. int i = FindPresetIndex( pPresetName );
  244. if ( i >= 0 )
  245. {
  246. m_Presets.Remove( i );
  247. return true;
  248. }
  249. return false;
  250. }
  251. //-----------------------------------------------------------------------------
  252. // Reorder presets
  253. //-----------------------------------------------------------------------------
  254. void CDmePresetGroup::MovePresetInFrontOf( CDmePreset *pPreset, CDmePreset *pInFrontOf )
  255. {
  256. if ( pPreset == pInFrontOf )
  257. return;
  258. int nEnd = pInFrontOf ? FindPresetIndex( pInFrontOf ) : m_Presets.Count();
  259. Assert( nEnd >= 0 );
  260. RemovePreset( pPreset );
  261. if ( nEnd > m_Presets.Count() )
  262. {
  263. nEnd = m_Presets.Count();
  264. }
  265. m_Presets.InsertBefore( nEnd, pPreset );
  266. }
  267. //-----------------------------------------------------------------------------
  268. // Finds a control index
  269. //-----------------------------------------------------------------------------
  270. struct ExportedControl_t
  271. {
  272. CUtlString m_Name;
  273. bool m_bIsStereo;
  274. int m_nFirstIndex;
  275. };
  276. //-----------------------------------------------------------------------------
  277. // Builds a unique list of controls found in the presets
  278. //-----------------------------------------------------------------------------
  279. static int FindExportedControlIndex( const char *pControlName, CUtlVector< ExportedControl_t > &uniqueControls )
  280. {
  281. int nCount = uniqueControls.Count();
  282. for ( int i = 0; i < nCount; ++i )
  283. {
  284. if ( !Q_stricmp( pControlName, uniqueControls[i].m_Name ) )
  285. return i;
  286. }
  287. return -1;
  288. }
  289. //-----------------------------------------------------------------------------
  290. // Builds a unique list of controls found in the presets
  291. //-----------------------------------------------------------------------------
  292. static int BuildExportedControlList( CDmeAnimationSet *pAnimationSet, const CDmePresetGroup *pPresetGroup, CUtlVector< ExportedControl_t > &uniqueControls )
  293. {
  294. int nGlobalIndex = 0;
  295. const CDmrElementArrayConst< CDmePreset > &presets = pPresetGroup->GetPresets();
  296. int nPresetCount = presets.Count();
  297. for ( int i = 0; i < nPresetCount; ++i )
  298. {
  299. CDmePreset *pPreset = presets[i];
  300. Assert( !pPreset->IsAnimated() ); // deal with this after GDC
  301. if ( pPreset->IsAnimated() )
  302. continue;
  303. const CDmrElementArray< CDmElement > &controls = pPreset->GetControlValues();
  304. int nControlCount = controls.Count();
  305. for ( int i = 0; i < nControlCount; ++i )
  306. {
  307. CDmElement *pControlValue = controls[ i ];
  308. if ( !pControlValue )
  309. continue;
  310. const char *pControlName = pControlValue->GetName();
  311. int nIndex = FindExportedControlIndex( pControlName, uniqueControls );
  312. if ( nIndex >= 0 )
  313. continue;
  314. CDmAttribute *pValueAttribute = pControlValue->GetAttribute( "value" );
  315. if ( !pValueAttribute || pValueAttribute->GetType() != AT_FLOAT )
  316. continue;
  317. if ( pAnimationSet )
  318. {
  319. CDmElement *pControl = pAnimationSet->FindControl( pControlName );
  320. if ( !pControl )
  321. continue;
  322. int j = uniqueControls.AddToTail();
  323. ExportedControl_t &control = uniqueControls[j];
  324. control.m_Name = pControlName;
  325. control.m_bIsStereo = IsStereoControl( pControl );
  326. control.m_nFirstIndex = nGlobalIndex;
  327. nGlobalIndex += 1 + control.m_bIsStereo;
  328. }
  329. else
  330. {
  331. int j = uniqueControls.AddToTail();
  332. ExportedControl_t &control = uniqueControls[j];
  333. control.m_Name = pControlName;
  334. // this isn't quite as reliable as querying the animation set but if we don't have one...
  335. control.m_bIsStereo = pControlValue->HasAttribute( "leftValue" );
  336. control.m_nFirstIndex = nGlobalIndex;
  337. nGlobalIndex += 1 + control.m_bIsStereo;
  338. }
  339. }
  340. }
  341. return nGlobalIndex;
  342. }
  343. //-----------------------------------------------------------------------------
  344. // Exports this preset group to a faceposer .txt expression file
  345. // Either an animation set or a combination operator are required so that
  346. // the default value for unspecified
  347. //-----------------------------------------------------------------------------
  348. bool CDmePresetGroup::ExportToTXT( const char *pFileName, CDmeAnimationSet *pAnimationSet /* = NULL */, CDmeCombinationOperator *pComboOp /* = NULL */ ) const
  349. {
  350. const CDmePresetGroup *pPresetGroup = this;
  351. // find all used controls
  352. CUtlVector< ExportedControl_t > exportedControls;
  353. BuildExportedControlList( pAnimationSet, pPresetGroup, exportedControls );
  354. CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
  355. // Output the unique keys
  356. buf.Printf( "$keys " );
  357. int nExportedControlCount = exportedControls.Count();
  358. for ( int i = 0; i < nExportedControlCount; ++i )
  359. {
  360. char pTempBuf[MAX_PATH];
  361. ExportedControl_t &control = exportedControls[i];
  362. if ( !control.m_bIsStereo )
  363. {
  364. buf.Printf("%s ", control.m_Name.String() );
  365. }
  366. else
  367. {
  368. V_sprintf_safe( pTempBuf, "right_%s", control.m_Name.String() );
  369. buf.Printf("%s ", pTempBuf );
  370. V_sprintf_safe( pTempBuf, "left_%s", control.m_Name.String() );
  371. buf.Printf("%s ", pTempBuf );
  372. }
  373. }
  374. buf.Printf( "\n" );
  375. buf.Printf( "$hasweighting\n" );
  376. buf.Printf( "$normalized\n" );
  377. // Output all presets
  378. const CDmrElementArrayConst< CDmePreset > &presets = pPresetGroup->GetPresets();
  379. int nPresetCount = presets.Count();
  380. for ( int i = 0; i < nPresetCount; ++i )
  381. {
  382. CDmePreset *pPreset = presets[i];
  383. Assert( !pPreset->IsAnimated() ); // deal with this after GDC
  384. if ( pPreset->IsAnimated() )
  385. continue;
  386. const char *pPresetName = pPreset->GetName();
  387. // Hack for 'silence' and for p_ naming scheme
  388. if ( !Q_stricmp( pPresetName, "p_silence" ) )
  389. {
  390. pPresetName = "<sil>";
  391. }
  392. if ( pPresetName[0] == 'p' && pPresetName[1] == '_' )
  393. {
  394. pPresetName = &pPresetName[2];
  395. }
  396. buf.Printf( "\"%s\" \t", pPresetName );
  397. int nPhonemeIndex = TextToPhonemeIndex( pPresetName );
  398. int nCode = CodeForPhonemeByIndex( nPhonemeIndex );
  399. if ( nCode < 128 )
  400. {
  401. buf.Printf( "\"%c\" \t", nCode );
  402. }
  403. else
  404. {
  405. buf.Printf( "\"0x%x\"\t", nCode );
  406. }
  407. for ( int i = 0; i < nExportedControlCount; ++i )
  408. {
  409. ExportedControl_t &control = exportedControls[i];
  410. CDmElement *pControlValue = pPreset->FindControlValue( control.m_Name );
  411. if ( !pControlValue )
  412. {
  413. CDmElement *pControl = pAnimationSet ? pAnimationSet->FindControl( control.m_Name ) : NULL;
  414. if ( !pControl )
  415. {
  416. bool bIsMulti;
  417. const ControlIndex_t nIndex = FindComboOpControlIndexForAnimSetControl( pComboOp, control.m_Name, &bIsMulti );
  418. if ( nIndex >= 0 )
  419. {
  420. float flDefaultValue = bIsMulti ? 0.5f : pComboOp->GetControlDefaultValue( nIndex );
  421. buf.Printf( "%.5f\t0.000\t", flDefaultValue );
  422. if ( control.m_bIsStereo )
  423. {
  424. buf.Printf( "%.5f\t0.000\t", flDefaultValue );
  425. }
  426. }
  427. else
  428. {
  429. buf.Printf( "0.000\t0.000\t" );
  430. if ( control.m_bIsStereo )
  431. {
  432. buf.Printf( "0.000\t0.000\t" );
  433. }
  434. }
  435. continue;
  436. }
  437. float flDefaultValue = pControl->GetValue< float >( "defaultValue" );
  438. if ( !control.m_bIsStereo )
  439. {
  440. buf.Printf( "%.5f\t1.000\t", flDefaultValue );
  441. }
  442. else
  443. {
  444. buf.Printf( "%.5f\t1.000\t", flDefaultValue );
  445. buf.Printf( "%.5f\t1.000\t", flDefaultValue );
  446. }
  447. continue;
  448. }
  449. if ( !control.m_bIsStereo )
  450. {
  451. buf.Printf( "%.5f\t1.000\t", pControlValue->GetValue<float>( "value" ) );
  452. }
  453. else
  454. {
  455. buf.Printf( "%.5f\t1.000\t", pControlValue->GetValue<float>( "rightValue" ) );
  456. buf.Printf( "%.5f\t1.000\t", pControlValue->GetValue<float>( "leftValue" ) );
  457. }
  458. }
  459. const char *pDesc = DescForPhonemeByIndex( nPhonemeIndex );
  460. buf.Printf( "\"%s\"\n", pDesc ? pDesc : pPresetName );
  461. }
  462. return g_pFullFileSystem->WriteFile( pFileName, NULL, buf );
  463. }
  464. #undef ALIGN4
  465. #define ALIGN4( a ) a = (byte *)((int)((byte *)a + 3) & ~ 3)
  466. //-----------------------------------------------------------------------------
  467. // Exports this preset group to a faceposer .vfe expression file
  468. //-----------------------------------------------------------------------------
  469. bool CDmePresetGroup::ExportToVFE( const char *pFileName, CDmeAnimationSet *pAnimationSet /* = NULL */, CDmeCombinationOperator *pComboOp /* = NULL */ ) const
  470. {
  471. const CDmePresetGroup *pPresetGroup = this;
  472. int i;
  473. const CDmrElementArrayConst< CDmePreset > &presets = pPresetGroup->GetPresets();
  474. // find all used controls
  475. CUtlVector< ExportedControl_t > exportedControls;
  476. int nTotalControlCount = BuildExportedControlList( pAnimationSet, pPresetGroup, exportedControls );
  477. const int nExportedControlCount = exportedControls.Count();
  478. byte *pData = (byte *)calloc( 1024 * 1024, 1 );
  479. byte *pDataStart = pData;
  480. flexsettinghdr_t *fhdr = (flexsettinghdr_t *)pData;
  481. fhdr->id = ('V' << 16) + ('F' << 8) + ('E');
  482. fhdr->version = 0;
  483. if ( !g_pFullFileSystem->FullPathToRelativePathEx( pFileName, "GAME", fhdr->name, sizeof(fhdr->name) ) )
  484. {
  485. Q_strncpy( fhdr->name, pFileName, sizeof(fhdr->name) );
  486. }
  487. // allocate room for header
  488. pData += sizeof( flexsettinghdr_t );
  489. ALIGN4( pData );
  490. // store flex settings
  491. flexsetting_t *pSetting = (flexsetting_t *)pData;
  492. fhdr->numflexsettings = presets.Count();
  493. fhdr->flexsettingindex = pData - pDataStart;
  494. pData += sizeof( flexsetting_t ) * fhdr->numflexsettings;
  495. ALIGN4( pData );
  496. for ( i = 0; i < fhdr->numflexsettings; i++ )
  497. {
  498. CDmePreset *pPreset = presets[i];
  499. Assert( pPreset );
  500. Assert( !pPreset->IsAnimated() ); // deal with this after GDC
  501. if ( pPreset->IsAnimated() )
  502. continue;
  503. pSetting[i].index = i;
  504. pSetting[i].settingindex = pData - (byte *)(&pSetting[i]);
  505. flexweight_t *pFlexWeights = (flexweight_t *)pData;
  506. for ( int j = 0; j < nExportedControlCount; j++ )
  507. {
  508. ExportedControl_t &control = exportedControls[ j ];
  509. CDmElement *pControlValue = pPreset->FindControlValue( control.m_Name );
  510. if ( !pControlValue )
  511. {
  512. bool bIsMulti;
  513. const ControlIndex_t nIndex = FindComboOpControlIndexForAnimSetControl( pComboOp, control.m_Name, &bIsMulti );
  514. if ( nIndex >= 0 )
  515. {
  516. float flDefaultValue = bIsMulti ? 0.5f : pComboOp->GetControlDefaultValue( nIndex );
  517. if ( !control.m_bIsStereo )
  518. {
  519. pSetting[i].numsettings++;
  520. pFlexWeights->key = control.m_nFirstIndex;
  521. pFlexWeights->weight = flDefaultValue;
  522. pFlexWeights->influence = 1.0f;
  523. pFlexWeights++;
  524. }
  525. else
  526. {
  527. pSetting[i].numsettings += 2;
  528. pFlexWeights->key = control.m_nFirstIndex;
  529. pFlexWeights->weight = flDefaultValue;
  530. pFlexWeights->influence = 1.0f;
  531. pFlexWeights++;
  532. pFlexWeights->key = control.m_nFirstIndex + 1;
  533. pFlexWeights->weight = flDefaultValue;
  534. pFlexWeights->influence = 1.0f;
  535. pFlexWeights++;
  536. }
  537. }
  538. else
  539. {
  540. pSetting[i].numsettings++;
  541. pFlexWeights->key = control.m_nFirstIndex;
  542. pFlexWeights->weight = bIsMulti ? 0.5f : 0.0f;
  543. pFlexWeights->influence = 0.0f;
  544. pFlexWeights++;
  545. if ( control.m_bIsStereo )
  546. {
  547. pSetting[i].numsettings++;
  548. pFlexWeights->key = control.m_nFirstIndex + 1;
  549. pFlexWeights->weight = 0.0f;
  550. pFlexWeights->influence = 0.0f;
  551. pFlexWeights++;
  552. }
  553. }
  554. continue;
  555. }
  556. if ( !control.m_bIsStereo )
  557. {
  558. pSetting[i].numsettings++;
  559. pFlexWeights->key = control.m_nFirstIndex;
  560. pFlexWeights->weight = pControlValue->GetValue<float>( "value" );
  561. pFlexWeights->influence = 1.0f;
  562. pFlexWeights++;
  563. }
  564. else
  565. {
  566. pSetting[i].numsettings += 2;
  567. pFlexWeights->key = control.m_nFirstIndex;
  568. pFlexWeights->weight = pControlValue->GetValue<float>( "rightValue" );
  569. pFlexWeights->influence = 1.0f;
  570. pFlexWeights++;
  571. pFlexWeights->key = control.m_nFirstIndex + 1;
  572. pFlexWeights->weight = pControlValue->GetValue<float>( "leftValue" );
  573. pFlexWeights->influence = 1.0f;
  574. pFlexWeights++;
  575. }
  576. }
  577. pData = (byte *)pFlexWeights;
  578. ALIGN4( pData );
  579. }
  580. int numindexes = 1;
  581. for (i = 0; i < fhdr->numflexsettings; i++)
  582. {
  583. if ( pSetting[i].index >= numindexes )
  584. {
  585. numindexes = pSetting[i].index + 1;
  586. }
  587. }
  588. // store indexed table
  589. int *pIndex = (int *)pData;
  590. fhdr->numindexes = numindexes;
  591. fhdr->indexindex = pData - pDataStart;
  592. pData += sizeof( int ) * numindexes;
  593. ALIGN4( pData );
  594. for (i = 0; i < numindexes; i++)
  595. {
  596. pIndex[i] = -1;
  597. }
  598. for (i = 0; i < fhdr->numflexsettings; i++)
  599. {
  600. pIndex[pSetting[i].index] = i;
  601. }
  602. // store flex setting names
  603. for (i = 0; i < fhdr->numflexsettings; i++)
  604. {
  605. CDmePreset *pPreset = presets[i];
  606. const char *pPresetName = pPreset->GetName();
  607. // Hack for 'silence' and for p_ naming scheme
  608. if ( pPresetName[0] == 'p' && pPresetName[1] == '_' )
  609. {
  610. pPresetName = &pPresetName[2];
  611. }
  612. if ( !Q_stricmp( pPresetName, "silence" ) )
  613. {
  614. pPresetName = "<sil>";
  615. }
  616. pSetting[i].nameindex = pData - (byte *)(&pSetting[i]);
  617. strcpy( (char *)pData, pPresetName );
  618. pData += Q_strlen( pPresetName ) + 1;
  619. }
  620. ALIGN4( pData );
  621. // store key names
  622. char **pKeynames = (char **)pData;
  623. fhdr->numkeys = nTotalControlCount;
  624. fhdr->keynameindex = pData - pDataStart;
  625. pData += sizeof(char *) * nTotalControlCount;
  626. int j = 0;
  627. for ( i = 0; i < nExportedControlCount; ++i )
  628. {
  629. char pTempBuf[MAX_PATH];
  630. ExportedControl_t &control = exportedControls[i];
  631. if ( !control.m_bIsStereo )
  632. {
  633. pKeynames[j++] = (char *)(pData - pDataStart);
  634. strcpy( (char *)pData, control.m_Name );
  635. pData += Q_strlen( control.m_Name ) + 1;
  636. }
  637. else
  638. {
  639. pKeynames[j++] = (char *)(pData - pDataStart);
  640. V_sprintf_safe( pTempBuf, "right_%s", control.m_Name.String() );
  641. strcpy( (char *)pData, pTempBuf );
  642. pData += Q_strlen( pTempBuf ) + 1;
  643. pKeynames[j++] = (char *)(pData - pDataStart);
  644. V_sprintf_safe( pTempBuf, "left_%s", control.m_Name.String() );
  645. strcpy( (char *)pData, pTempBuf );
  646. pData += Q_strlen( pTempBuf ) + 1;
  647. }
  648. }
  649. Assert( j == nTotalControlCount );
  650. ALIGN4( pData );
  651. // allocate room for remapping
  652. int *keymapping = (int *)pData;
  653. fhdr->keymappingindex = pData - pDataStart;
  654. pData += sizeof( int ) * nTotalControlCount;
  655. for (i = 0; i < nTotalControlCount; i++)
  656. {
  657. keymapping[i] = -1;
  658. }
  659. ALIGN4( pData );
  660. fhdr->length = pData - pDataStart;
  661. FileHandle_t fh = g_pFullFileSystem->Open( pFileName, "wb" );
  662. if ( !fh )
  663. {
  664. Warning( "Unable to write to %s (read-only?)\n", pFileName );
  665. free( pDataStart );
  666. return false;
  667. }
  668. g_pFullFileSystem->Write( pDataStart, fhdr->length, fh );
  669. g_pFullFileSystem->Close( fh );
  670. free( pDataStart );
  671. return true;
  672. }
  673. //-----------------------------------------------------------------------------
  674. // Constructor, destructor
  675. //-----------------------------------------------------------------------------
  676. //-----------------------------------------------------------------------------
  677. // CDmeAnimationSet - container for animation set info
  678. //-----------------------------------------------------------------------------
  679. IMPLEMENT_ELEMENT_FACTORY( DmeAnimationSet, CDmeAnimationSet );
  680. void CDmeAnimationSet::OnConstruction()
  681. {
  682. m_Controls.Init( this, "controls", FATTRIB_HAS_CALLBACK );
  683. m_PresetGroups.Init( this, "presetGroups" );
  684. m_PhonemeMap.Init( this, "phonememap" );
  685. m_Operators.Init( this, "operators" );
  686. m_RootControlGroup.InitAndCreate( this, "rootControlGroup" );
  687. }
  688. void CDmeAnimationSet::OnDestruction()
  689. {
  690. m_ControlNameMap.RemoveAll();
  691. }
  692. void CDmeAnimationSet::OnAttributeArrayElementAdded( CDmAttribute *pAttribute, int nFirstElem, int nLastElem )
  693. {
  694. if ( pAttribute != m_Controls.GetAttribute() )
  695. return;
  696. for ( int i = nFirstElem; i <= nLastElem; ++i )
  697. {
  698. CDmElement *pControl = m_Controls[ i ];
  699. if ( !pControl )
  700. continue;
  701. int slot = m_ControlNameMap.Find( pControl->GetName() );
  702. if ( slot == m_ControlNameMap.InvalidIndex() )
  703. {
  704. m_ControlNameMap.Insert( pControl->GetName(), pControl->GetHandle() );
  705. }
  706. }
  707. }
  708. void CDmeAnimationSet::OnAttributeArrayElementRemoved( CDmAttribute *pAttribute, int nFirstElem, int nLastElem )
  709. {
  710. if ( pAttribute != m_Controls.GetAttribute() )
  711. return;
  712. for ( int i = nFirstElem; i <= nLastElem; ++i )
  713. {
  714. CDmElement *pControl = m_Controls[ i ];
  715. if ( !pControl )
  716. continue;
  717. m_ControlNameMap.Remove( pControl->GetName() );
  718. }
  719. }
  720. CDmaElementArray< CDmElement > &CDmeAnimationSet::GetControls()
  721. {
  722. return m_Controls;
  723. }
  724. CDmaElementArray< CDmePresetGroup > &CDmeAnimationSet::GetPresetGroups()
  725. {
  726. return m_PresetGroups;
  727. }
  728. CDmaElementArray< CDmeOperator > &CDmeAnimationSet::GetOperators()
  729. {
  730. return m_Operators;
  731. }
  732. void CDmeAnimationSet::AddOperator( CDmeOperator *pOperator )
  733. {
  734. m_Operators.AddToTail( pOperator );
  735. }
  736. void CDmeAnimationSet::RemoveOperator( CDmeOperator *pOperator )
  737. {
  738. int nCount = m_Operators.Count();
  739. for ( int i = 0; i < nCount; ++i )
  740. {
  741. if ( m_Operators[i] == pOperator )
  742. {
  743. m_Operators.Remove(i);
  744. break;
  745. }
  746. }
  747. }
  748. //-----------------------------------------------------------------------------
  749. // Finds the index of a particular preset group
  750. //-----------------------------------------------------------------------------
  751. void CDmeAnimationSet::OnElementUnserialized()
  752. {
  753. BaseClass::OnElementUnserialized();
  754. // Build control dictionary
  755. for ( int i = 0; i < m_Controls.Count(); ++i )
  756. {
  757. CDmElement *pControl = m_Controls[ i ];
  758. if ( !pControl )
  759. return;
  760. int slot = m_ControlNameMap.Find( pControl->GetName() );
  761. if ( slot == m_ControlNameMap.InvalidIndex() )
  762. {
  763. m_ControlNameMap.Insert( pControl->GetName(), pControl->GetHandle() );
  764. }
  765. }
  766. }
  767. //-----------------------------------------------------------------------------
  768. // Finds the index of a particular preset group
  769. //-----------------------------------------------------------------------------
  770. int CDmeAnimationSet::FindPresetGroupIndex( CDmePresetGroup *pPresetGroup )
  771. {
  772. int c = m_PresetGroups.Count();
  773. for ( int i = 0; i < c; ++i )
  774. {
  775. CDmePresetGroup *e = m_PresetGroups.Get( i );
  776. if ( pPresetGroup == e )
  777. return i;
  778. }
  779. return -1;
  780. }
  781. int CDmeAnimationSet::FindPresetGroupIndex( const char *pGroupName )
  782. {
  783. int c = m_PresetGroups.Count();
  784. for ( int i = 0; i < c; ++i )
  785. {
  786. CDmePresetGroup *e = m_PresetGroups.Get( i );
  787. if ( e && !Q_stricmp( e->GetName(), pGroupName ) )
  788. return i;
  789. }
  790. return -1;
  791. }
  792. //-----------------------------------------------------------------------------
  793. // Find by name
  794. //-----------------------------------------------------------------------------
  795. CDmePresetGroup *CDmeAnimationSet::FindPresetGroup( const char *pGroupName )
  796. {
  797. int nIndex = FindPresetGroupIndex( pGroupName );
  798. if ( nIndex >= 0 )
  799. return m_PresetGroups[nIndex];
  800. return NULL;
  801. }
  802. //-----------------------------------------------------------------------------
  803. // Find or add by name
  804. //-----------------------------------------------------------------------------
  805. CDmePresetGroup *CDmeAnimationSet::FindOrAddPresetGroup( const char *pGroupName )
  806. {
  807. CDmePresetGroup *pPresetGroup = FindPresetGroup( pGroupName );
  808. if ( !pPresetGroup )
  809. {
  810. // Create the default groups in order
  811. pPresetGroup = CreateElement< CDmePresetGroup >( pGroupName, GetFileId() );
  812. m_PresetGroups.AddToTail( pPresetGroup );
  813. }
  814. return pPresetGroup;
  815. }
  816. void CDmeAnimationSet::AddPresetGroup( CDmePresetGroup *pPresetGroup )
  817. {
  818. m_PresetGroups.AddToTail( pPresetGroup );
  819. }
  820. //-----------------------------------------------------------------------------
  821. // Remove preset group
  822. //-----------------------------------------------------------------------------
  823. bool CDmeAnimationSet::RemovePresetGroup( CDmePresetGroup *pPresetGroup )
  824. {
  825. int i = FindPresetGroupIndex( pPresetGroup );
  826. if ( i >= 0 )
  827. {
  828. m_PresetGroups.Remove( i );
  829. return true;
  830. }
  831. return false;
  832. }
  833. bool CDmeAnimationSet::RemovePresetGroup( const char *pPresetGroupName )
  834. {
  835. int i = FindPresetGroupIndex( pPresetGroupName );
  836. if ( i >= 0 )
  837. {
  838. m_PresetGroups.Remove( i );
  839. return true;
  840. }
  841. return false;
  842. }
  843. //-----------------------------------------------------------------------------
  844. // Reorder preset groups
  845. //-----------------------------------------------------------------------------
  846. void CDmeAnimationSet::MovePresetGroupInFrontOf( CDmePresetGroup *pPresetGroup, CDmePresetGroup *pInFrontOf )
  847. {
  848. if ( pPresetGroup == pInFrontOf )
  849. return;
  850. #ifdef _DEBUG
  851. int nStart = FindPresetGroupIndex( pPresetGroup );
  852. #endif
  853. int nEnd = pInFrontOf ? FindPresetGroupIndex( pInFrontOf ) : m_PresetGroups.Count();
  854. Assert( nStart >= 0 && nEnd >= 0 );
  855. RemovePresetGroup( pPresetGroup );
  856. if ( nEnd > m_PresetGroups.Count() )
  857. {
  858. nEnd = m_PresetGroups.Count();
  859. }
  860. m_PresetGroups.InsertBefore( nEnd, pPresetGroup );
  861. }
  862. CDmePreset *CDmeAnimationSet::FindOrAddPreset( const char *pGroupName, const char *pPresetName )
  863. {
  864. CDmePresetGroup *pPresetGroup = FindOrAddPresetGroup( pGroupName );
  865. return pPresetGroup->FindOrAddPreset( pPresetName );
  866. }
  867. bool CDmeAnimationSet::RemovePreset( const char *pPresetName )
  868. {
  869. int c = m_PresetGroups.Count();
  870. for ( int i = 0; i < c; ++i )
  871. {
  872. if ( m_PresetGroups[i]->RemovePreset( pPresetName ) )
  873. return true;
  874. }
  875. return false;
  876. }
  877. bool CDmeAnimationSet::RemovePreset( CDmePreset *pPreset )
  878. {
  879. int c = m_PresetGroups.Count();
  880. for ( int i = 0; i < c; ++i )
  881. {
  882. if ( m_PresetGroups[i]->RemovePreset( pPreset ) )
  883. return true;
  884. }
  885. return false;
  886. }
  887. CDmaElementArray< CDmePhonemeMapping > &CDmeAnimationSet::GetPhonemeMap()
  888. {
  889. return m_PhonemeMap;
  890. }
  891. void CDmeAnimationSet::RestoreDefaultPhonemeMap()
  892. {
  893. CUndoScopeGuard guard( "RestoreDefaultPhonemeMap" );
  894. int i;
  895. int c = m_PhonemeMap.Count();
  896. for ( i = 0; i < c; ++i )
  897. {
  898. g_pDataModel->DestroyElement( m_PhonemeMap[ i ]->GetHandle() );
  899. }
  900. m_PhonemeMap.Purge();
  901. int phonemeCount = NumPhonemes();
  902. for ( i = 0; i < phonemeCount; ++i )
  903. {
  904. const char *pName = NameForPhonemeByIndex( i );
  905. CDmePhonemeMapping *mapping = CreateElement< CDmePhonemeMapping >( pName, GetFileId() );
  906. char presetName[ 256 ];
  907. Q_snprintf( presetName, sizeof( presetName ), "p_%s", pName );
  908. mapping->m_Preset = presetName;
  909. mapping->m_Weight = 1.0f;
  910. m_PhonemeMap.AddToTail( mapping );
  911. }
  912. }
  913. CDmePhonemeMapping *CDmeAnimationSet::FindMapping( const char *pRawPhoneme )
  914. {
  915. int c = m_PhonemeMap.Count();
  916. for ( int i = 0; i < c; ++i )
  917. {
  918. CDmePhonemeMapping *e = m_PhonemeMap.Get( i );
  919. Assert( e );
  920. if ( !e )
  921. continue;
  922. if ( !Q_stricmp( e->GetName(), pRawPhoneme ) )
  923. return e;
  924. }
  925. return NULL;
  926. }
  927. //-----------------------------------------------------------------------------
  928. // Purpose: Add the specified control to the animation set's list of controls
  929. //-----------------------------------------------------------------------------
  930. void CDmeAnimationSet::AddControl( CDmElement *pControl )
  931. {
  932. m_Controls.AddToTail( pControl );
  933. if ( pControl )
  934. {
  935. int slot = m_ControlNameMap.Find( pControl->GetName() );
  936. if ( slot == m_ControlNameMap.InvalidIndex() )
  937. {
  938. m_ControlNameMap.Insert( pControl->GetName(), pControl->GetHandle() );
  939. }
  940. }
  941. }
  942. //-----------------------------------------------------------------------------
  943. // Purpose: Remove the specified control from the animation set's list of
  944. // controls and remove any selection elements referring to the control.
  945. //-----------------------------------------------------------------------------
  946. void CDmeAnimationSet::RemoveControl( CDmElement *pControl )
  947. {
  948. // Search the for the control in the list and remove
  949. // the corresponding element from the list if found.
  950. int index = m_Controls.Find( pControl );
  951. if ( index != m_Controls.InvalidIndex() )
  952. {
  953. // Remove the control from any selection groups it may be in.
  954. RemoveControlFromGroups( pControl->GetName(), true );
  955. // Remove the control from the list
  956. m_Controls.Remove( index );
  957. // Remove from name mapping
  958. m_ControlNameMap.Remove( pControl->GetName() );
  959. }
  960. }
  961. //-----------------------------------------------------------------------------
  962. // Finds a control
  963. //-----------------------------------------------------------------------------
  964. CDmElement *CDmeAnimationSet::FindControl( const char *pControlName ) const
  965. {
  966. int idx = m_ControlNameMap.Find( pControlName );
  967. if ( idx == m_ControlNameMap.InvalidIndex() )
  968. return NULL;
  969. return g_pDataModel->GetElement( m_ControlNameMap[ idx ] );
  970. }
  971. //-----------------------------------------------------------------------------
  972. // Finds or adds a control
  973. //-----------------------------------------------------------------------------
  974. CDmElement *CDmeAnimationSet::FindOrAddControl( const char *pControlName, bool transformControl, bool bMustBeNew )
  975. {
  976. CDmElement *pControl = FindControl( pControlName );
  977. if ( bMustBeNew && ( pControl != NULL ) )
  978. return NULL;
  979. if ( !pControl )
  980. {
  981. // If not, then create one
  982. if ( transformControl )
  983. {
  984. pControl = CreateElement< CDmeTransformControl >( pControlName, GetFileId() );
  985. }
  986. else
  987. {
  988. pControl = CreateElement< CDmElement >( pControlName, GetFileId() );
  989. }
  990. AddControl( pControl );
  991. }
  992. return pControl;
  993. }
  994. //-----------------------------------------------------------------------------
  995. // Create a new control with the specified name, if a control with the
  996. // specified name already exists returns NULL.
  997. //-----------------------------------------------------------------------------
  998. CDmElement *CDmeAnimationSet::CreateNewControl( const char *pControlName, bool bTransformControl )
  999. {
  1000. return FindOrAddControl( pControlName, bTransformControl, true );
  1001. }
  1002. //-----------------------------------------------------------------------------
  1003. // Purpose: Get the root control group
  1004. //-----------------------------------------------------------------------------
  1005. CDmeControlGroup *CDmeAnimationSet::GetRootControlGroup() const
  1006. {
  1007. return m_RootControlGroup;
  1008. }
  1009. //-----------------------------------------------------------------------------
  1010. // Purpose: Find the control group with the specified name.
  1011. //-----------------------------------------------------------------------------
  1012. CDmeControlGroup *CDmeAnimationSet::FindControlGroup( const char *pControlGroupName ) const
  1013. {
  1014. return m_RootControlGroup->FindChildByName( pControlGroupName, true );
  1015. }
  1016. //-----------------------------------------------------------------------------
  1017. // Purpose: Find the control group with the specified name or add it if does
  1018. // not exist.
  1019. //-----------------------------------------------------------------------------
  1020. CDmeControlGroup *CDmeAnimationSet::FindOrAddControlGroup( CDmeControlGroup *pParentGroup, const char *pControlGroupName )
  1021. {
  1022. CDmeControlGroup *pRootGroup = ( pParentGroup != NULL ) ? pParentGroup : m_RootControlGroup;
  1023. // Search for the group to see if it already exists.
  1024. CDmeControlGroup *pControlGroup = pRootGroup->FindChildByName( pControlGroupName, true );
  1025. // If the selection group was not found, create it.
  1026. if ( pControlGroup == NULL )
  1027. {
  1028. pControlGroup = pRootGroup->CreateControlGroup( pControlGroupName );
  1029. }
  1030. return pControlGroup;
  1031. }
  1032. //-----------------------------------------------------------------------------
  1033. // Purpose: Find the control with the specified name, remove it from the group
  1034. // it belongs to and destroy it
  1035. //-----------------------------------------------------------------------------
  1036. void CDmeAnimationSet::RemoveControlFromGroups( char const *pchControlName, bool bRemoveEmpty )
  1037. {
  1038. CDmeControlGroup *pGroup = NULL;
  1039. CDmElement *pControl = m_RootControlGroup->FindControlByName( pchControlName, true, &pGroup );
  1040. if ( pGroup )
  1041. {
  1042. // Remove the control from the group
  1043. pGroup->RemoveControl( pControl );
  1044. // If the flag is set to remove empty groups and the group is empty, remove it.
  1045. if ( bRemoveEmpty && pGroup->IsEmpty() && ( pGroup != m_RootControlGroup ) )
  1046. {
  1047. CDmeControlGroup::DestroyGroup( pGroup, NULL, false );
  1048. }
  1049. }
  1050. }
  1051. //-----------------------------------------------------------------------------
  1052. // Build a list of the root dag nodes of the animation set
  1053. //-----------------------------------------------------------------------------
  1054. void CDmeAnimationSet::FindRootDagNodes( CUtlVector< CDmeDag* > &rootDagNodeList ) const
  1055. {
  1056. rootDagNodeList.EnsureCapacity( rootDagNodeList.Count() + 4 );
  1057. int nControls = m_Controls.Count();
  1058. for ( int iControl = 0; iControl < nControls; ++iControl )
  1059. {
  1060. // Check to see if the control is a transform control
  1061. CDmeTransformControl *pTransformControl = CastElement< CDmeTransformControl >( m_Controls[ iControl ] );
  1062. if ( pTransformControl == NULL )
  1063. continue;
  1064. // Get the dag node associated with the transform control
  1065. CDmeDag *pDagNode = pTransformControl->GetDag();
  1066. if ( pDagNode == NULL )
  1067. continue;
  1068. // Check to see if the parent of the dag is also in the animation set.
  1069. CDmeDag *pParent = pDagNode->GetParent();
  1070. if ( pParent )
  1071. {
  1072. CDmeTransformControl *pTransformControl = pParent->FindTransformControl();
  1073. if ( pTransformControl )
  1074. {
  1075. if ( FindReferringElement< CDmeAnimationSet >( pTransformControl, "controls" ) == this )
  1076. continue;
  1077. }
  1078. }
  1079. // If the dag node has no parent or the parent is not in the
  1080. // animation set add the dag node to the list of root nodes.
  1081. if ( rootDagNodeList.Find( pDagNode ) == rootDagNodeList.InvalidIndex() )
  1082. {
  1083. rootDagNodeList.AddToTail( pDagNode );
  1084. }
  1085. }
  1086. }
  1087. //-----------------------------------------------------------------------------
  1088. // Purpose: Find all of the dag nodes within the animation set.
  1089. //-----------------------------------------------------------------------------
  1090. void CDmeAnimationSet::CollectDagNodes( CUtlVector< CDmeDag* > &dagNodeList ) const
  1091. {
  1092. // Reserve space for the maximum number of dag nodes that may be added to the list.
  1093. int nControls = m_Controls.Count();
  1094. dagNodeList.EnsureCapacity( dagNodeList.Count() + nControls );
  1095. // Iterate through all of the controls in the animation set. For the
  1096. // controls which are transform controls get the associated dag node and
  1097. // add it to the dag node list if it is not already in the dag node list.
  1098. for ( int iControl = 0; iControl < nControls; ++iControl )
  1099. {
  1100. // Check to see if the control is a transform control
  1101. CDmeTransformControl *pTransformControl = CastElement< CDmeTransformControl >( m_Controls[ iControl ] );
  1102. if ( pTransformControl )
  1103. {
  1104. // Get the dag node associated with the transform control
  1105. CDmeDag *pDagNode = pTransformControl->GetDag();
  1106. if ( pDagNode )
  1107. {
  1108. // Check to see if the dag node is already in the list, if not add it.
  1109. if ( dagNodeList.Find( pDagNode ) == dagNodeList.InvalidIndex() )
  1110. {
  1111. dagNodeList.AddToTail( pDagNode );
  1112. }
  1113. }
  1114. }
  1115. }
  1116. }
  1117. void CDmeAnimationSet::CollectOperators( CUtlVector< DmElementHandle_t > &operators )
  1118. {
  1119. int numOperators = m_Operators.Count();
  1120. for ( int i = 0; i < numOperators; ++i )
  1121. {
  1122. DmElementHandle_t h = m_Operators.GetHandle( i );
  1123. if ( h != DMELEMENT_HANDLE_INVALID )
  1124. {
  1125. operators.AddToTail( h );
  1126. }
  1127. }
  1128. }
  1129. //-----------------------------------------------------------------------------
  1130. // Purpose: Make sure all of the transform controls of the animation set have
  1131. // an appropriate default attribute.
  1132. //-----------------------------------------------------------------------------
  1133. void CDmeAnimationSet::UpdateTransformDefaults() const
  1134. {
  1135. // Get the game model associated with the animation set, this will be used to determine the default
  1136. // values for each of the controls, if it is not specified then the defaults cannot be set.
  1137. CDmeGameModel *pGameModel = GetValueElement< CDmeGameModel >( "gameModel" );
  1138. if ( pGameModel == NULL )
  1139. return;
  1140. // Iterate through each of the controls in the animation set, if it is a transform control see if
  1141. // it has a default value, if it does not have a default value, find the bone associated with the
  1142. // transform and get the default position or rotation for that bone from the model.
  1143. int nControls = m_Controls.Count();
  1144. for ( int iControl = 0; iControl < nControls; ++iControl )
  1145. {
  1146. CDmElement *pControl = m_Controls[ iControl ];
  1147. if ( pControl == NULL )
  1148. continue;
  1149. // Determine if the control is a transform control and if it has a default value.
  1150. CDmeTransformControl *pTransformControl = CastElement< CDmeTransformControl >( pControl );
  1151. if ( pTransformControl == NULL )
  1152. continue;
  1153. CDmeTransform *pTransform = pTransformControl->GetTransform();
  1154. if ( pTransform == NULL )
  1155. continue;
  1156. // Find the bone associated with the transform and get the default position of the bone.
  1157. if ( !pTransformControl->HasDefaultPosition() )
  1158. {
  1159. Vector position = vec3_origin;
  1160. int boneIndex = pGameModel->FindBone( pTransform );
  1161. if ( pGameModel->GetBoneDefaultPosition( boneIndex, position ) )
  1162. {
  1163. pTransformControl->SetDefaultPosition( position );
  1164. }
  1165. }
  1166. // Find the bone associated with the transform and get the default rotation of the bone.
  1167. if ( !pTransformControl->HasDefaultOrientation() )
  1168. {
  1169. Quaternion orientation;
  1170. int boneIndex = pGameModel->FindBone( pTransform );
  1171. if ( pGameModel->GetBoneDefaultOrientation( boneIndex, orientation) )
  1172. {
  1173. pTransformControl->SetDefaultOrientation( orientation );
  1174. }
  1175. }
  1176. }
  1177. }
  1178. //-----------------------------------------------------------------------------
  1179. // Find the animation set to which the dag belongs, if any. This function
  1180. // operates by checking to see of the dag node is referenced by an animation
  1181. // set either directly or by a control. If the specified dag node is not
  1182. // immediately referenced by an animation set the function checks the
  1183. // hierarchical ancestors of the dag node to see if they are referenced by
  1184. // an animation set. If the node is somehow referenced by multiple animation
  1185. // sets this function will simply return the first one it encounters as the
  1186. // assumption is that a dag node will only be referenced by one animation set.
  1187. //-----------------------------------------------------------------------------
  1188. CDmeAnimationSet *FindAnimationSetForDag( CDmeDag *pDagNode )
  1189. {
  1190. while ( pDagNode )
  1191. {
  1192. // Check to see if an animation set directly references this dag node
  1193. CDmeAnimationSet *pAnimationSet = FindAncestorReferencingElement< CDmeAnimationSet >( pDagNode );
  1194. if ( pAnimationSet != NULL )
  1195. return pAnimationSet;
  1196. // Check to see if an animation set references the dag node through a control
  1197. CDmeTransformControl *pTransformControl = pDagNode->FindTransformControl();
  1198. if ( pTransformControl )
  1199. {
  1200. CDmeAnimationSet *pAnimationSet = FindAncestorReferencingElement< CDmeAnimationSet >( pTransformControl );
  1201. if ( pAnimationSet != NULL )
  1202. return pAnimationSet;
  1203. }
  1204. // Failed to find the animation set, go on to the parent of the dag node and
  1205. // try again, repeat until an animation set is found or the root is reached.
  1206. pDagNode = pDagNode->GetParent();
  1207. }
  1208. return NULL;
  1209. }
  1210. //-----------------------------------------------------------------------------
  1211. //
  1212. // CAnimSetControlDependencyMpa implementation, a utility class for finding the
  1213. // dependencies of a control with in the animation set.
  1214. //
  1215. //-----------------------------------------------------------------------------
  1216. //-----------------------------------------------------------------------------
  1217. // Add the controls of the specified animation set to the dependency map
  1218. //-----------------------------------------------------------------------------
  1219. void CAnimSetControlDependencyMap::AddAnimationSet( const CDmeAnimationSet* pAnimSet )
  1220. {
  1221. if ( pAnimSet == NULL )
  1222. return;
  1223. CDmeGameModel *pGameModel = pAnimSet->GetValueElement< CDmeGameModel >( "gameModel" );
  1224. if ( pGameModel == NULL )
  1225. return;
  1226. // Construct a table which maps the global flex controllers to the control elements that are driving them.
  1227. int numFlexControllers = pGameModel->NumGlobalFlexControllers();
  1228. CUtlVector< CDmElement* > controlMap;
  1229. controlMap.EnsureCount( numFlexControllers );
  1230. for ( int iFlex = 0; iFlex < numFlexControllers; ++iFlex )
  1231. {
  1232. controlMap[ iFlex ] = NULL;
  1233. CDmeGlobalFlexControllerOperator* pFlexOp = pGameModel->GetGlobalFlexController( iFlex );
  1234. if ( pFlexOp )
  1235. {
  1236. CUtlVector< CDmeChannel* > channels( 0, 4 );
  1237. FindAncestorsReferencingElement( pFlexOp, channels );
  1238. int nChannels = channels.Count();
  1239. for ( int iChannel = 0; iChannel < nChannels; ++iChannel )
  1240. {
  1241. CDmeChannel *pChannel = channels[ iChannel ];
  1242. if ( pChannel && pChannel->GetToElement() == pFlexOp )
  1243. {
  1244. CDmElement* pElement = pChannel->GetFromElement();
  1245. controlMap[ iFlex ] = pElement;
  1246. break;
  1247. }
  1248. }
  1249. }
  1250. }
  1251. // Get a list of the flex controllers that each flex controller is dependent on.
  1252. CUtlVector < CUtlVector< int > > flexDependencyList;
  1253. pGameModel->FindFlexControllerDependencies( flexDependencyList );
  1254. int nLists = flexDependencyList.Count();
  1255. for ( int iList = 0; iList < nLists; ++iList )
  1256. {
  1257. CUtlVector< int > &dependencyList = flexDependencyList[ iList ];
  1258. int listCount = dependencyList.Count();
  1259. if ( listCount > 0 )
  1260. {
  1261. // Construct the control dependency list from the flex controller dependency
  1262. // list. The first element in flex controller list is the dependent element,
  1263. // the following elements are the dependencies.
  1264. CDmElement *pElement = controlMap[ dependencyList[ 0 ] ];
  1265. if ( pElement )
  1266. {
  1267. DependencyList_t *pDependencySet = FindDependencyList( pElement );
  1268. if ( pDependencySet == NULL)
  1269. {
  1270. int arrayIndex = m_DependencyData.AddToTail();
  1271. pDependencySet = &m_DependencyData[ arrayIndex ];
  1272. pDependencySet->m_pElement = pElement;
  1273. pDependencySet->m_Dependencies.EnsureCapacity( listCount );
  1274. }
  1275. for ( int iDep = 1; iDep < listCount; ++iDep )
  1276. {
  1277. CDmElement* pDependency = controlMap[ dependencyList[ iDep ] ];
  1278. if ( pDependency != pElement )
  1279. {
  1280. if ( pDependencySet->m_Dependencies.Find( pDependency ) == pDependencySet->m_Dependencies.InvalidIndex() )
  1281. {
  1282. pDependencySet->m_Dependencies.AddToTail( pDependency );
  1283. }
  1284. }
  1285. }
  1286. }
  1287. }
  1288. }
  1289. }
  1290. //-----------------------------------------------------------------------------
  1291. // Get the list of controls which the specified control is dependent on.
  1292. //-----------------------------------------------------------------------------
  1293. const CUtlVector< const CDmElement * > *CAnimSetControlDependencyMap::GetControlDepndencies( const CDmElement *pControl ) const
  1294. {
  1295. if ( pControl == NULL )
  1296. return NULL;
  1297. const DependencyList_t *pDependencyList = NULL;
  1298. int nSets = m_DependencyData.Count();
  1299. for ( int i = 0; i < nSets; ++i )
  1300. {
  1301. if ( m_DependencyData[ i ].m_pElement == pControl )
  1302. {
  1303. pDependencyList = &m_DependencyData[ i ];
  1304. break;
  1305. }
  1306. }
  1307. if ( pDependencyList == NULL )
  1308. return NULL;
  1309. if ( pDependencyList->m_pElement != pControl )
  1310. {
  1311. // If this assert is hit, something has gone wrong with the control look up.
  1312. Assert( pDependencyList->m_pElement == pControl );
  1313. return NULL;
  1314. }
  1315. return &pDependencyList->m_Dependencies;
  1316. }
  1317. //-----------------------------------------------------------------------------
  1318. // Purpose: Find the dependency list for the specified control
  1319. //-----------------------------------------------------------------------------
  1320. CAnimSetControlDependencyMap::DependencyList_t *CAnimSetControlDependencyMap::FindDependencyList( const CDmElement* pControl )
  1321. {
  1322. DependencyList_t *pDependencyList = NULL;
  1323. int nSets = m_DependencyData.Count();
  1324. for ( int i = 0; i < nSets; ++i )
  1325. {
  1326. if ( m_DependencyData[ i ].m_pElement == pControl )
  1327. {
  1328. pDependencyList = &m_DependencyData[ i ];
  1329. break;
  1330. }
  1331. }
  1332. return pDependencyList;
  1333. }
  1334. //-----------------------------------------------------------------------------
  1335. // CDmePresetGroupInfo - container for shared preset groups
  1336. //-----------------------------------------------------------------------------
  1337. IMPLEMENT_ELEMENT_FACTORY( DmePresetGroupInfo, CDmePresetGroupInfo );
  1338. void CDmePresetGroupInfo::OnConstruction()
  1339. {
  1340. m_filenameBase.Init( this, "filenameBase" );
  1341. m_presetGroups.Init( this, "presetGroups" );
  1342. }
  1343. void CDmePresetGroupInfo::OnDestruction()
  1344. {
  1345. }
  1346. //-----------------------------------------------------------------------------
  1347. // Loads model presets from .pre files matching the filename base
  1348. //-----------------------------------------------------------------------------
  1349. void CDmePresetGroupInfo::LoadPresetGroups()
  1350. {
  1351. LoadPresetGroups( m_filenameBase, m_presetGroups );
  1352. }
  1353. void CDmePresetGroupInfo::FilenameBaseForModelName( const char *pModelName, char *pFileNameBase, int nFileNameBaseLen )
  1354. {
  1355. V_FixupPathName( pFileNameBase, nFileNameBaseLen, pModelName );
  1356. V_StripExtension( pFileNameBase, pFileNameBase, nFileNameBaseLen );
  1357. }
  1358. CDmePresetGroupInfo *CDmePresetGroupInfo::FindPresetGroupInfo( const char *pFilenameBase, CDmrElementArray< CDmePresetGroupInfo > &presetGroupInfos )
  1359. {
  1360. // find an existing CDmePresetGroupInfo
  1361. int nPresetGroupInfos = presetGroupInfos.Count();
  1362. for ( int i = 0; i < nPresetGroupInfos; ++i )
  1363. {
  1364. CDmePresetGroupInfo *pPresetGroupInfo = presetGroupInfos[ i ];
  1365. if ( !pPresetGroupInfo )
  1366. continue;
  1367. if ( V_stricmp( pFilenameBase, pPresetGroupInfo->GetFilenameBase() ) == 0 )
  1368. return pPresetGroupInfo;
  1369. }
  1370. return NULL;
  1371. }
  1372. CDmePresetGroupInfo *CDmePresetGroupInfo::FindOrCreatePresetGroupInfo( const char *pFilenameBase, CDmrElementArray< CDmePresetGroupInfo > &presetGroupInfos )
  1373. {
  1374. // find or create an CDmePresetGroupInfo
  1375. CDmePresetGroupInfo *pPresetGroupInfo = CDmePresetGroupInfo::FindPresetGroupInfo( pFilenameBase, presetGroupInfos );
  1376. if ( !pPresetGroupInfo )
  1377. {
  1378. pPresetGroupInfo = CreatePresetGroupInfo( pFilenameBase, presetGroupInfos.GetOwner()->GetFileId() );
  1379. presetGroupInfos.AddToTail( pPresetGroupInfo );
  1380. }
  1381. return pPresetGroupInfo;
  1382. }
  1383. CDmePresetGroupInfo *CDmePresetGroupInfo::CreatePresetGroupInfo( const char *pFilenameBase, DmFileId_t fileid )
  1384. {
  1385. char presetGroupInfoName[ MAX_PATH ];
  1386. V_FileBase( pFilenameBase, presetGroupInfoName, sizeof( presetGroupInfoName ) );
  1387. CDmePresetGroupInfo *pPresetGroupInfo = CreateElement< CDmePresetGroupInfo >( presetGroupInfoName, fileid );
  1388. pPresetGroupInfo->SetFilenameBase( pFilenameBase );
  1389. pPresetGroupInfo->LoadPresetGroups();
  1390. return pPresetGroupInfo;
  1391. }
  1392. void CDmePresetGroupInfo::LoadPresetGroups( const char *pFilenameBase, CDmaElementArray< CDmePresetGroup > &presetGroups )
  1393. {
  1394. char presetPath[MAX_PATH];
  1395. Q_ExtractFilePath( pFilenameBase, presetPath, sizeof( presetPath ) );
  1396. char presetNameFilter[MAX_PATH];
  1397. V_strncpy( presetNameFilter, pFilenameBase, sizeof( presetNameFilter ) );
  1398. int nLen = Q_strlen( presetNameFilter );
  1399. Q_snprintf( &presetNameFilter[ nLen ], MAX_PATH - nLen, "*.pre" );
  1400. DmFileId_t parentFileId = presetGroups.GetOwner()->GetFileId();
  1401. FileFindHandle_t fh;
  1402. const char *pFileName = g_pFullFileSystem->FindFirstEx( presetNameFilter, "GAME", &fh );
  1403. for ( ; pFileName; pFileName = g_pFullFileSystem->FindNext( fh ) )
  1404. {
  1405. char relativePresetPath[MAX_PATH];
  1406. Q_ComposeFileName( presetPath, pFileName, relativePresetPath, sizeof( relativePresetPath ) );
  1407. CDmElement* pRoot = NULL;
  1408. DmFileId_t fileid = g_pDataModel->RestoreFromFile( relativePresetPath, "GAME", NULL, &pRoot, CR_FORCE_COPY ); // TODO - change this to CR_DELETE_OLD, since we'll want the loaded presets to replace the existing ones
  1409. if ( fileid == DMFILEID_INVALID || !pRoot )
  1410. continue;
  1411. CDmePresetGroup *pPresetGroup = CastElement<CDmePresetGroup>( pRoot );
  1412. if ( !pPresetGroup )
  1413. {
  1414. if ( pRoot )
  1415. {
  1416. g_pDataModel->RemoveFileId( pRoot->GetFileId() );
  1417. }
  1418. continue;
  1419. }
  1420. pPresetGroup->SetFileId( parentFileId, TD_DEEP );
  1421. // Presets used through the model preset manager must be read only + shared
  1422. pPresetGroup->m_bIsReadOnly = true;
  1423. pPresetGroup->SetShared( true );
  1424. presetGroups.AddToTail( pPresetGroup );
  1425. }
  1426. g_pFullFileSystem->FindClose( fh );
  1427. }
  1428. ControlIndex_t FindComboOpControlIndexForAnimSetControl( CDmeCombinationOperator *pComboOp, const char *pControlName, bool *pIsMulti /*= NULL*/ )
  1429. {
  1430. const char *pMultiControlBaseName = pControlName ? StringAfterPrefix( pControlName, "multi_" ) : NULL;
  1431. if ( pIsMulti )
  1432. {
  1433. *pIsMulti = pMultiControlBaseName != NULL;
  1434. }
  1435. if ( !pComboOp || !pControlName )
  1436. return -1;
  1437. ControlIndex_t index = pComboOp->FindControlIndex( pControlName );
  1438. if ( index >= 0 )
  1439. return index;
  1440. if ( !pMultiControlBaseName )
  1441. return -1;
  1442. index = pComboOp->FindControlIndex( pMultiControlBaseName );
  1443. if ( index < 0 )
  1444. return -1;
  1445. Assert( pComboOp->IsMultiControl( index ) );
  1446. return index;
  1447. }
  1448. //-----------------------------------------------------------------------------
  1449. // Utility class to migrate from traversing all animationsets within an animationsetgroup to a filmclip
  1450. //-----------------------------------------------------------------------------
  1451. bool CAnimSetGroupAnimSetTraversal::IsValid()
  1452. {
  1453. return m_pFilmClip && m_nIndex < m_pFilmClip->GetAnimationSets().Count();
  1454. }
  1455. CDmeAnimationSet *CAnimSetGroupAnimSetTraversal::Next()
  1456. {
  1457. CDmeAnimationSet *pAnimSet = NULL;
  1458. while ( pAnimSet == NULL && IsValid() )
  1459. {
  1460. pAnimSet = m_pFilmClip->GetAnimationSets()[ m_nIndex++ ];
  1461. }
  1462. return pAnimSet;
  1463. }