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.

1407 lines
39 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "movieobjects/dmeanimationset.h"
  7. #include "movieobjects/dmebookmark.h"
  8. #include "movieobjects/dmegamemodel.h"
  9. #include "movieobjects/dmecombinationoperator.h"
  10. #include "datamodel/dmelementfactoryhelper.h"
  11. #include "datamodel/dmehandle.h"
  12. #include "phonemeconverter.h"
  13. #include "tier1/utlstringmap.h"
  14. #include "tier2/tier2.h"
  15. #include "filesystem.h"
  16. #include "studio.h"
  17. #include "tier3/tier3.h"
  18. #include "tier1/utlbuffer.h"
  19. //-----------------------------------------------------------------------------
  20. // CDmePresetGroup - container for animation set info
  21. //-----------------------------------------------------------------------------
  22. IMPLEMENT_ELEMENT_FACTORY( DmePreset, CDmePreset );
  23. void CDmePreset::OnConstruction()
  24. {
  25. m_ControlValues.Init( this, "controlValues" );
  26. m_nProceduralType.InitAndSet( this, "procedural", PROCEDURAL_PRESET_NOT );
  27. }
  28. void CDmePreset::OnDestruction()
  29. {
  30. }
  31. CDmaElementArray< CDmElement > &CDmePreset::GetControlValues()
  32. {
  33. return m_ControlValues;
  34. }
  35. const CDmaElementArray< CDmElement > &CDmePreset::GetControlValues() const
  36. {
  37. return m_ControlValues;
  38. }
  39. int CDmePreset::FindControlValueIndex( const char *pControlName )
  40. {
  41. int c = m_ControlValues.Count();
  42. for ( int i = 0; i < c; ++i )
  43. {
  44. CDmElement *e = m_ControlValues.Get( i );
  45. if ( !Q_stricmp( e->GetName(), pControlName ) )
  46. return i;
  47. }
  48. return -1;
  49. }
  50. CDmElement *CDmePreset::FindControlValue( const char *pControlName )
  51. {
  52. int i = FindControlValueIndex( pControlName );
  53. if ( i >= 0 )
  54. return m_ControlValues.Get(i);
  55. return NULL;
  56. }
  57. CDmElement *CDmePreset::FindOrAddControlValue( const char *pControlName )
  58. {
  59. CDmElement *pControlValues = FindControlValue( pControlName );
  60. if ( !pControlValues )
  61. {
  62. // Create the default groups in order
  63. pControlValues = CreateElement< CDmElement >( pControlName, GetFileId() );
  64. m_ControlValues.AddToTail( pControlValues );
  65. }
  66. return pControlValues;
  67. }
  68. void CDmePreset::RemoveControlValue( const char *pControlName )
  69. {
  70. int i = FindControlValueIndex( pControlName );
  71. if ( i >= 0 )
  72. {
  73. m_ControlValues.Remove( i );
  74. }
  75. }
  76. //-----------------------------------------------------------------------------
  77. // Is the preset read-only?
  78. //-----------------------------------------------------------------------------
  79. bool CDmePreset::IsReadOnly()
  80. {
  81. DmAttributeReferenceIterator_t h = g_pDataModel->FirstAttributeReferencingElement( GetHandle() );
  82. while ( h != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID )
  83. {
  84. CDmAttribute *pAttribute = g_pDataModel->GetAttribute( h );
  85. CDmePresetGroup *pOwner = CastElement<CDmePresetGroup>( pAttribute->GetOwner() );
  86. if ( pOwner && pOwner->m_bIsReadOnly )
  87. return true;
  88. h = g_pDataModel->NextAttributeReferencingElement( h );
  89. }
  90. return false;
  91. }
  92. //-----------------------------------------------------------------------------
  93. // Copies control values
  94. //-----------------------------------------------------------------------------
  95. void CDmePreset::CopyControlValuesFrom( CDmePreset *pSource )
  96. {
  97. m_ControlValues.RemoveAll();
  98. const CDmaElementArray< CDmElement > &sourceValues = pSource->GetControlValues();
  99. int nCount = sourceValues.Count();
  100. for ( int i = 0; i < nCount; ++i )
  101. {
  102. CDmElement *pCopy = sourceValues[i]->Copy( );
  103. m_ControlValues.AddToTail( pCopy );
  104. }
  105. }
  106. void CDmePreset::SetProceduralPresetType( int nType )
  107. {
  108. Assert( nType >= 0 && nType < NUM_PROCEDURAL_PRESET_TYPES );
  109. m_nProceduralType = nType;
  110. }
  111. bool CDmePreset::IsProcedural() const
  112. {
  113. return m_nProceduralType != PROCEDURAL_PRESET_NOT;
  114. }
  115. int CDmePreset::GetProceduralPresetType() const
  116. {
  117. return m_nProceduralType;
  118. }
  119. IMPLEMENT_ELEMENT_FACTORY( DmeProceduralPresetSettings, CDmeProceduralPresetSettings );
  120. void CDmeProceduralPresetSettings::OnConstruction()
  121. {
  122. m_flJitterScale.InitAndSet( this, "jitterscale", 1.0f );
  123. m_flSmoothScale.InitAndSet( this, "smoothscale", 1.0f );
  124. m_flSharpenScale.InitAndSet( this, "sharpenscale", 1.0f );
  125. m_flSoftenScale.InitAndSet( this, "softenscale", 1.0f );
  126. m_nJitterIterations.InitAndSet( this, "jitteriterations", 5 );
  127. m_nSmoothIterations.InitAndSet( this, "smoothiterations", 5 );
  128. m_nSharpenIterations.InitAndSet( this, "sharpeniterations", 1 );
  129. m_nSoftenIterations.InitAndSet( this, "softeniterations", 1 );
  130. // 1/12 second now ( 833 ten thousandths )
  131. m_nStaggerInterval.InitAndSet( this, "staggerinterval", 10000 / 12 );
  132. }
  133. void CDmeProceduralPresetSettings::OnDestruction()
  134. {
  135. }
  136. //-----------------------------------------------------------------------------
  137. // CDmePresetRemap - copies presets from one group to another
  138. //-----------------------------------------------------------------------------
  139. IMPLEMENT_ELEMENT_FACTORY( DmePresetRemap, CDmePresetRemap );
  140. void CDmePresetRemap::OnConstruction()
  141. {
  142. m_SourcePresetGroup.Init( this, "sourcePresetGroup" );
  143. m_SrcPresets.Init( this, "srcPresets" );
  144. m_DestPresets.Init( this, "destPresets" );
  145. }
  146. void CDmePresetRemap::OnDestruction()
  147. {
  148. }
  149. const char *CDmePresetRemap::FindSourcePreset( const char *pDestPresetName )
  150. {
  151. int nCount = m_DestPresets.Count();
  152. for ( int i = 0; i < nCount; ++i )
  153. {
  154. if ( !Q_stricmp( pDestPresetName, m_DestPresets[i] ) )
  155. return m_SrcPresets[i];
  156. }
  157. return NULL;
  158. }
  159. void CDmePresetRemap::AddRemap( const char *pSourcePresetName, const char *pDestPresetName )
  160. {
  161. m_SrcPresets.AddToTail( pSourcePresetName );
  162. m_DestPresets.AddToTail( pDestPresetName );
  163. }
  164. void CDmePresetRemap::RemoveAll()
  165. {
  166. m_SrcPresets.RemoveAll();
  167. m_DestPresets.RemoveAll();
  168. }
  169. //-----------------------------------------------------------------------------
  170. // Iteration
  171. //-----------------------------------------------------------------------------
  172. int CDmePresetRemap::GetRemapCount()
  173. {
  174. return m_SrcPresets.Count();
  175. }
  176. const char *CDmePresetRemap::GetRemapSource( int i )
  177. {
  178. return m_SrcPresets[i];
  179. }
  180. const char *CDmePresetRemap::GetRemapDest( int i )
  181. {
  182. return m_DestPresets[i];
  183. }
  184. //-----------------------------------------------------------------------------
  185. // CDmePresetGroup - container for animation set info
  186. //-----------------------------------------------------------------------------
  187. IMPLEMENT_ELEMENT_FACTORY( DmePresetGroup, CDmePresetGroup );
  188. void CDmePresetGroup::OnConstruction()
  189. {
  190. m_Presets.Init( this, "presets" );
  191. m_bIsVisible.InitAndSet( this, "visible", true );
  192. m_bIsReadOnly.Init( this, "readonly" );
  193. }
  194. void CDmePresetGroup::OnDestruction()
  195. {
  196. }
  197. CDmaElementArray< CDmePreset > &CDmePresetGroup::GetPresets()
  198. {
  199. return m_Presets;
  200. }
  201. const CDmaElementArray< CDmePreset > &CDmePresetGroup::GetPresets() const
  202. {
  203. return m_Presets;
  204. }
  205. //-----------------------------------------------------------------------------
  206. // Finds the index of a particular preset group
  207. //-----------------------------------------------------------------------------
  208. int CDmePresetGroup::FindPresetIndex( CDmePreset *pPreset )
  209. {
  210. int c = m_Presets.Count();
  211. for ( int i = 0; i < c; ++i )
  212. {
  213. CDmePreset *e = m_Presets.Get( i );
  214. if ( pPreset == e )
  215. return i;
  216. }
  217. return -1;
  218. }
  219. CDmePreset *CDmePresetGroup::FindPreset( const char *pPresetName )
  220. {
  221. int i;
  222. int c = m_Presets.Count();
  223. for ( i = 0; i < c; ++i )
  224. {
  225. CDmePreset *e = m_Presets.Get( i );
  226. if ( !Q_stricmp( e->GetName(), pPresetName ) )
  227. return e;
  228. }
  229. return NULL;
  230. }
  231. CDmePreset *CDmePresetGroup::FindOrAddPreset( const char *pPresetName, int nType /*=PROCEDURAL_PRESET_NOT*/ )
  232. {
  233. CDmePreset *pPreset = FindPreset( pPresetName );
  234. if ( !pPreset )
  235. {
  236. // Create the default groups in order
  237. pPreset = CreateElement< CDmePreset >( pPresetName, GetFileId() );
  238. pPreset->SetProceduralPresetType( nType );
  239. m_Presets.AddToTail( pPreset );
  240. }
  241. return pPreset;
  242. }
  243. bool CDmePresetGroup::RemovePreset( CDmePreset *pPreset )
  244. {
  245. int i = FindPresetIndex( pPreset );
  246. if ( i >= 0 )
  247. {
  248. m_Presets.Remove( i );
  249. return true;
  250. }
  251. return false;
  252. }
  253. void CDmePresetGroup::MovePresetUp( CDmePreset *pPreset )
  254. {
  255. int i = FindPresetIndex( pPreset );
  256. if ( i >= 1 )
  257. {
  258. m_Presets.Swap( i, i-1 );
  259. }
  260. }
  261. void CDmePresetGroup::MovePresetDown( CDmePreset *pPreset )
  262. {
  263. int i = FindPresetIndex( pPreset );
  264. if ( i >= 0 && i < m_Presets.Count() - 1 )
  265. {
  266. m_Presets.Swap( i, i+1 );
  267. }
  268. }
  269. //-----------------------------------------------------------------------------
  270. // Reorder presets
  271. //-----------------------------------------------------------------------------
  272. void CDmePresetGroup::MovePresetInFrontOf( CDmePreset *pPreset, CDmePreset *pInFrontOf )
  273. {
  274. if ( pPreset == pInFrontOf )
  275. return;
  276. int nEnd = pInFrontOf ? FindPresetIndex( pInFrontOf ) : m_Presets.Count();
  277. Assert( nEnd >= 0 );
  278. RemovePreset( pPreset );
  279. if ( nEnd > m_Presets.Count() )
  280. {
  281. nEnd = m_Presets.Count();
  282. }
  283. m_Presets.InsertBefore( nEnd, pPreset );
  284. }
  285. //-----------------------------------------------------------------------------
  286. // The preset remap
  287. //-----------------------------------------------------------------------------
  288. CDmePresetRemap *CDmePresetGroup::GetPresetRemap()
  289. {
  290. return GetValueElement< CDmePresetRemap >( "presetRemap" );
  291. }
  292. CDmePresetRemap *CDmePresetGroup::GetOrAddPresetRemap()
  293. {
  294. CDmePresetRemap *pPresetRemap = GetPresetRemap();
  295. if ( !pPresetRemap )
  296. {
  297. pPresetRemap = CreateElement< CDmePresetRemap >( "PresetRemap", GetFileId() );
  298. SetValue( "presetRemap", pPresetRemap );
  299. }
  300. return pPresetRemap;
  301. }
  302. //-----------------------------------------------------------------------------
  303. // Finds a control index
  304. //-----------------------------------------------------------------------------
  305. struct ExportedControl_t
  306. {
  307. CUtlString m_Name;
  308. bool m_bIsStereo;
  309. bool m_bIsMulti;
  310. int m_nFirstIndex;
  311. };
  312. //-----------------------------------------------------------------------------
  313. // Builds a unique list of controls found in the presets
  314. //-----------------------------------------------------------------------------
  315. static int FindExportedControlIndex( const char *pControlName, CUtlVector< ExportedControl_t > &uniqueControls )
  316. {
  317. int nCount = uniqueControls.Count();
  318. for ( int i = 0; i < nCount; ++i )
  319. {
  320. if ( !Q_stricmp( pControlName, uniqueControls[i].m_Name ) )
  321. return i;
  322. }
  323. return -1;
  324. }
  325. //-----------------------------------------------------------------------------
  326. // Builds a unique list of controls found in the presets
  327. //-----------------------------------------------------------------------------
  328. static int BuildExportedControlList( CDmeAnimationSet *pAnimationSet, const CDmePresetGroup *pPresetGroup, CUtlVector< ExportedControl_t > &uniqueControls )
  329. {
  330. int nGlobalIndex = 0;
  331. const CDmrElementArrayConst< CDmePreset > &presets = pPresetGroup->GetPresets();
  332. int nPresetCount = presets.Count();
  333. for ( int iPreset = 0; iPreset < nPresetCount; ++iPreset )
  334. {
  335. CDmePreset *pPreset = presets[iPreset];
  336. const CDmrElementArray< CDmElement > &controls = pPreset->GetControlValues();
  337. int nControlCount = controls.Count();
  338. for ( int i = 0; i < nControlCount; ++i )
  339. {
  340. const char *pControlName = controls[i]->GetName();
  341. int nIndex = FindExportedControlIndex( pControlName, uniqueControls );
  342. if ( nIndex >= 0 )
  343. continue;
  344. CDmAttribute *pValueAttribute = controls[i]->GetAttribute( "value" );
  345. if ( !pValueAttribute || pValueAttribute->GetType() != AT_FLOAT )
  346. continue;
  347. if ( pAnimationSet )
  348. {
  349. CDmElement *pControl = pAnimationSet->FindControl( pControlName );
  350. if ( !pControl )
  351. continue;
  352. int j = uniqueControls.AddToTail();
  353. ExportedControl_t &control = uniqueControls[j];
  354. control.m_Name = pControlName;
  355. control.m_bIsStereo = pControl->GetValue<bool>( "combo" );
  356. control.m_bIsMulti = pControl->GetValue<bool>( "multi" );
  357. control.m_nFirstIndex = nGlobalIndex;
  358. nGlobalIndex += 1 + control.m_bIsStereo + control.m_bIsMulti;
  359. }
  360. else
  361. {
  362. int j = uniqueControls.AddToTail();
  363. ExportedControl_t &control = uniqueControls[j];
  364. control.m_Name = pControlName;
  365. // this isn't quite as reliable as querying the animation set but if we don't have one...
  366. control.m_bIsStereo = controls[ i ]->GetAttribute( "balance" ) ? true : false;
  367. control.m_bIsMulti = controls[ i ]->GetAttribute( "multilevel" ) ? true : false;
  368. control.m_nFirstIndex = nGlobalIndex;
  369. nGlobalIndex += 1 + control.m_bIsStereo + control.m_bIsMulti;
  370. }
  371. }
  372. }
  373. return nGlobalIndex;
  374. }
  375. //-----------------------------------------------------------------------------
  376. // Exports this preset group to a faceposer .txt expression file
  377. // Either an animation set or a combination operator are required so that
  378. // the default value for unspecified
  379. //-----------------------------------------------------------------------------
  380. bool CDmePresetGroup::ExportToTXT( const char *pFileName, CDmeAnimationSet *pAnimationSet /* = NULL */, CDmeCombinationOperator *pComboOp /* = NULL */ ) const
  381. {
  382. const CDmePresetGroup *pPresetGroup = this;
  383. // find all used controls
  384. CUtlVector< ExportedControl_t > exportedControls;
  385. BuildExportedControlList( pAnimationSet, pPresetGroup, exportedControls );
  386. CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
  387. // Output the unique keys
  388. buf.Printf( "$keys " );
  389. int nExportedControlCount = exportedControls.Count();
  390. for ( int i = 0; i < nExportedControlCount; ++i )
  391. {
  392. char pTempBuf[MAX_PATH];
  393. ExportedControl_t &control = exportedControls[i];
  394. if ( !control.m_bIsStereo )
  395. {
  396. buf.Printf("%s ", control.m_Name.Get() );
  397. }
  398. else
  399. {
  400. Q_snprintf( pTempBuf, sizeof(pTempBuf), "right_%s", control.m_Name.Get() );
  401. buf.Printf("%s ", pTempBuf );
  402. Q_snprintf( pTempBuf, sizeof(pTempBuf), "left_%s", control.m_Name.Get() );
  403. buf.Printf("%s ", pTempBuf );
  404. }
  405. if ( control.m_bIsMulti )
  406. {
  407. Q_snprintf( pTempBuf, sizeof(pTempBuf), "multi_%s", control.m_Name.Get() );
  408. buf.Printf("%s ", pTempBuf );
  409. }
  410. }
  411. buf.Printf( "\n" );
  412. buf.Printf( "$hasweighting\n" );
  413. buf.Printf( "$normalized\n" );
  414. // Output all presets
  415. const CDmrElementArrayConst< CDmePreset > &presets = pPresetGroup->GetPresets();
  416. int nPresetCount = presets.Count();
  417. for ( int iPreset = 0; iPreset < nPresetCount; ++iPreset )
  418. {
  419. CDmePreset *pPreset = presets[iPreset];
  420. const char *pPresetName = pPreset->GetName();
  421. // Hack for 'silence' and for p_ naming scheme
  422. if ( !Q_stricmp( pPresetName, "p_silence" ) )
  423. {
  424. pPresetName = "<sil>";
  425. }
  426. if ( pPresetName[0] == 'p' && pPresetName[1] == '_' )
  427. {
  428. pPresetName = &pPresetName[2];
  429. }
  430. buf.Printf( "\"%s\" \t", pPresetName );
  431. int nPhonemeIndex = TextToPhonemeIndex( pPresetName );
  432. int nCode = CodeForPhonemeByIndex( nPhonemeIndex );
  433. if ( nCode < 128 )
  434. {
  435. buf.Printf( "\"%c\" \t", nCode );
  436. }
  437. else
  438. {
  439. buf.Printf( "\"0x%x\"\t", nCode );
  440. }
  441. for ( int i = 0; i < nExportedControlCount; ++i )
  442. {
  443. ExportedControl_t &control = exportedControls[i];
  444. CDmElement *pControlValue = pPreset->FindControlValue( control.m_Name );
  445. if ( !pControlValue )
  446. {
  447. CDmElement *pControl = pAnimationSet ? pAnimationSet->FindControl( control.m_Name ) : NULL;
  448. if ( !pControl )
  449. {
  450. const ControlIndex_t nIndex = pComboOp ? pComboOp->FindControlIndex( control.m_Name ) : -1;
  451. if ( nIndex >= 0 )
  452. {
  453. buf.Printf( "%.5f\t0.000\t", pComboOp->GetControlDefaultValue( nIndex ) );
  454. if ( control.m_bIsStereo )
  455. {
  456. buf.Printf( "%.5f\t0.000\t", pComboOp->GetControlDefaultValue( nIndex ) );
  457. }
  458. if ( control.m_bIsMulti )
  459. {
  460. buf.Printf( "%.5f\t0.000\t", pComboOp->GetControlDefaultValue( nIndex ) );
  461. }
  462. }
  463. else
  464. {
  465. buf.Printf( "0.000\t0.000\t" );
  466. if ( control.m_bIsStereo )
  467. {
  468. buf.Printf( "0.000\t0.000\t" );
  469. }
  470. if ( control.m_bIsMulti )
  471. {
  472. buf.Printf( "0.000\t0.000\t" );
  473. }
  474. }
  475. continue;
  476. }
  477. if ( !control.m_bIsStereo )
  478. {
  479. buf.Printf( "%.5f\t1.000\t", pControl->GetValue<float>( "defaultValue" ) );
  480. }
  481. else
  482. {
  483. float flValue, flBalance, flLeft, flRight;
  484. flValue = pControl->GetValue<float>( "defaultValue", 0.0f );
  485. flBalance = pControl->GetValue<float>( "defaultBalance", 0.5f );
  486. ValueBalanceToLeftRight( &flLeft, &flRight, flValue, flBalance );
  487. buf.Printf( "%.5f\t1.000\t", flRight );
  488. buf.Printf( "%.5f\t1.000\t", flLeft );
  489. }
  490. if ( control.m_bIsMulti )
  491. {
  492. buf.Printf( "%.5f\t1.000\t", pControl->GetValue<float>( "defaultMultilevel" ) );
  493. }
  494. continue;
  495. }
  496. if ( !control.m_bIsStereo )
  497. {
  498. buf.Printf( "%.5f\t1.000\t", pControlValue->GetValue<float>( "value" ) );
  499. }
  500. else
  501. {
  502. float flValue, flBalance, flLeft, flRight;
  503. flValue = pControlValue->GetValue<float>( "value" );
  504. flBalance = pControlValue->GetValue<float>( "balance" );
  505. ValueBalanceToLeftRight( &flLeft, &flRight, flValue, flBalance );
  506. buf.Printf( "%.5f\t1.000\t", flRight );
  507. buf.Printf( "%.5f\t1.000\t", flLeft );
  508. }
  509. if ( control.m_bIsMulti )
  510. {
  511. buf.Printf( "%.5f\t1.000\t", pControlValue->GetValue<float>( "multilevel" ) );
  512. }
  513. }
  514. const char *pDesc = DescForPhonemeByIndex( nPhonemeIndex );
  515. buf.Printf( "\"%s\"\n", pDesc ? pDesc : pPresetName );
  516. }
  517. return g_pFullFileSystem->WriteFile( pFileName, NULL, buf );
  518. }
  519. #ifdef ALIGN4
  520. #undef ALIGN4
  521. #endif // #ifdef ALIGN4
  522. #define ALIGN4( a ) a = (byte *)((int)((byte *)a + 3) & ~ 3)
  523. //-----------------------------------------------------------------------------
  524. // Exports this preset group to a faceposer .vfe expression file
  525. //-----------------------------------------------------------------------------
  526. bool CDmePresetGroup::ExportToVFE( const char *pFileName, CDmeAnimationSet *pAnimationSet /* = NULL */, CDmeCombinationOperator *pComboOp /* = NULL */ ) const
  527. {
  528. const CDmePresetGroup *pPresetGroup = this;
  529. int i;
  530. const CDmrElementArrayConst< CDmePreset > &presets = pPresetGroup->GetPresets();
  531. // find all used controls
  532. CUtlVector< ExportedControl_t > exportedControls;
  533. int nTotalControlCount = BuildExportedControlList( pAnimationSet, pPresetGroup, exportedControls );
  534. const int nExportedControlCount = exportedControls.Count();
  535. byte *pData = (byte *)calloc( 1024 * 1024, 1 );
  536. byte *pDataStart = pData;
  537. flexsettinghdr_t *fhdr = (flexsettinghdr_t *)pData;
  538. fhdr->id = ('V' << 16) + ('F' << 8) + ('E');
  539. fhdr->version = 0;
  540. if ( !g_pFullFileSystem->FullPathToRelativePathEx( pFileName, "GAME", fhdr->name, sizeof(fhdr->name) ) )
  541. {
  542. Q_strncpy( fhdr->name, pFileName, sizeof(fhdr->name) );
  543. }
  544. // allocate room for header
  545. pData += sizeof( flexsettinghdr_t );
  546. ALIGN4( pData );
  547. // store flex settings
  548. flexsetting_t *pSetting = (flexsetting_t *)pData;
  549. fhdr->numflexsettings = presets.Count();
  550. fhdr->flexsettingindex = pData - pDataStart;
  551. pData += sizeof( flexsetting_t ) * fhdr->numflexsettings;
  552. ALIGN4( pData );
  553. for ( i = 0; i < fhdr->numflexsettings; i++ )
  554. {
  555. CDmePreset *pPreset = presets[i];
  556. Assert( pPreset );
  557. pSetting[i].index = i;
  558. pSetting[i].settingindex = pData - (byte *)(&pSetting[i]);
  559. flexweight_t *pFlexWeights = (flexweight_t *)pData;
  560. for ( int j = 0; j < nExportedControlCount; j++ )
  561. {
  562. ExportedControl_t &control = exportedControls[ j ];
  563. CDmElement *pControlValue = pPreset->FindControlValue( control.m_Name );
  564. if ( !pControlValue )
  565. {
  566. const ControlIndex_t nIndex = pComboOp ? pComboOp->FindControlIndex( control.m_Name ) : -1;
  567. if ( nIndex >= 0 )
  568. {
  569. if ( !control.m_bIsStereo )
  570. {
  571. pSetting[i].numsettings++;
  572. pFlexWeights->key = control.m_nFirstIndex;
  573. pFlexWeights->weight = pComboOp->GetControlDefaultValue( nIndex );
  574. pFlexWeights->influence = 1.0f;
  575. pFlexWeights++;
  576. }
  577. else
  578. {
  579. float flValue, flBalance, flLeft, flRight;
  580. flValue = pComboOp->GetControlDefaultValue( nIndex );
  581. flBalance = 0.5;
  582. ValueBalanceToLeftRight( &flLeft, &flRight, flValue, flBalance );
  583. pSetting[i].numsettings += 2;
  584. pFlexWeights->key = control.m_nFirstIndex;
  585. pFlexWeights->weight = flRight;
  586. pFlexWeights->influence = 1.0f;
  587. pFlexWeights++;
  588. pFlexWeights->key = control.m_nFirstIndex + 1;
  589. pFlexWeights->weight = flLeft;
  590. pFlexWeights->influence = 1.0f;
  591. pFlexWeights++;
  592. }
  593. if ( control.m_bIsMulti )
  594. {
  595. pSetting[i].numsettings++;
  596. pFlexWeights->key = control.m_nFirstIndex + 1 + control.m_bIsStereo;
  597. pFlexWeights->weight = 0.5f;
  598. pFlexWeights->influence = 1.0f;
  599. pFlexWeights++;
  600. }
  601. }
  602. else
  603. {
  604. pSetting[i].numsettings++;
  605. pFlexWeights->key = control.m_nFirstIndex;
  606. pFlexWeights->weight = 0.0f;
  607. pFlexWeights->influence = 0.0f;
  608. pFlexWeights++;
  609. if ( control.m_bIsStereo )
  610. {
  611. pSetting[i].numsettings++;
  612. pFlexWeights->key = control.m_nFirstIndex + 1;
  613. pFlexWeights->weight = 0.0f;
  614. pFlexWeights->influence = 0.0f;
  615. pFlexWeights++;
  616. }
  617. if ( control.m_bIsMulti )
  618. {
  619. pSetting[i].numsettings++;
  620. pFlexWeights->key = control.m_nFirstIndex + 1 + control.m_bIsStereo;
  621. pFlexWeights->weight = 0.5f;
  622. pFlexWeights->influence = 0.0f;
  623. pFlexWeights++;
  624. }
  625. }
  626. continue;
  627. }
  628. if ( !control.m_bIsStereo )
  629. {
  630. pSetting[i].numsettings++;
  631. pFlexWeights->key = control.m_nFirstIndex;
  632. pFlexWeights->weight = pControlValue->GetValue<float>( "value" );
  633. pFlexWeights->influence = 1.0f;
  634. pFlexWeights++;
  635. }
  636. else
  637. {
  638. float flValue, flBalance, flLeft, flRight;
  639. flValue = pControlValue->GetValue<float>( "value" );
  640. flBalance = pControlValue->GetValue<float>( "balance" );
  641. ValueBalanceToLeftRight( &flLeft, &flRight, flValue, flBalance );
  642. pSetting[i].numsettings += 2;
  643. pFlexWeights->key = control.m_nFirstIndex;
  644. pFlexWeights->weight = flRight;
  645. pFlexWeights->influence = 1.0f;
  646. pFlexWeights++;
  647. pFlexWeights->key = control.m_nFirstIndex + 1;
  648. pFlexWeights->weight = flLeft;
  649. pFlexWeights->influence = 1.0f;
  650. pFlexWeights++;
  651. }
  652. if ( control.m_bIsMulti )
  653. {
  654. pSetting[i].numsettings++;
  655. pFlexWeights->key = control.m_nFirstIndex + 1 + control.m_bIsStereo;
  656. pFlexWeights->weight = pControlValue->GetValue<float>( "multilevel" );
  657. pFlexWeights->influence = 1.0f;
  658. pFlexWeights++;
  659. }
  660. }
  661. pData = (byte *)pFlexWeights;
  662. ALIGN4( pData );
  663. }
  664. int numindexes = 1;
  665. for (i = 0; i < fhdr->numflexsettings; i++)
  666. {
  667. if ( pSetting[i].index >= numindexes )
  668. {
  669. numindexes = pSetting[i].index + 1;
  670. }
  671. }
  672. // store indexed table
  673. int *pIndex = (int *)pData;
  674. fhdr->numindexes = numindexes;
  675. fhdr->indexindex = pData - pDataStart;
  676. pData += sizeof( int ) * numindexes;
  677. ALIGN4( pData );
  678. for (i = 0; i < numindexes; i++)
  679. {
  680. pIndex[i] = -1;
  681. }
  682. for (i = 0; i < fhdr->numflexsettings; i++)
  683. {
  684. pIndex[pSetting[i].index] = i;
  685. }
  686. // store flex setting names
  687. for (i = 0; i < fhdr->numflexsettings; i++)
  688. {
  689. CDmePreset *pPreset = presets[i];
  690. const char *pPresetName = pPreset->GetName();
  691. // Hack for 'silence' and for p_ naming scheme
  692. if ( pPresetName[0] == 'p' && pPresetName[1] == '_' )
  693. {
  694. pPresetName = &pPresetName[2];
  695. }
  696. if ( !Q_stricmp( pPresetName, "silence" ) )
  697. {
  698. pPresetName = "<sil>";
  699. }
  700. pSetting[i].nameindex = pData - (byte *)(&pSetting[i]);
  701. strcpy( (char *)pData, pPresetName );
  702. pData += Q_strlen( pPresetName ) + 1;
  703. }
  704. ALIGN4( pData );
  705. // store key names
  706. char **pKeynames = (char **)pData;
  707. fhdr->numkeys = nTotalControlCount;
  708. fhdr->keynameindex = pData - pDataStart;
  709. pData += sizeof(char *) * nTotalControlCount;
  710. int j = 0;
  711. for ( i = 0; i < nExportedControlCount; ++i )
  712. {
  713. char pTempBuf[MAX_PATH];
  714. ExportedControl_t &control = exportedControls[i];
  715. if ( !control.m_bIsStereo )
  716. {
  717. pKeynames[j++] = (char *)(pData - pDataStart);
  718. strcpy( (char *)pData, control.m_Name );
  719. pData += Q_strlen( control.m_Name ) + 1;
  720. }
  721. else
  722. {
  723. pKeynames[j++] = (char *)(pData - pDataStart);
  724. Q_snprintf( pTempBuf, sizeof(pTempBuf), "right_%s", control.m_Name.Get() );
  725. strcpy( (char *)pData, pTempBuf );
  726. pData += Q_strlen( pTempBuf ) + 1;
  727. pKeynames[j++] = (char *)(pData - pDataStart);
  728. Q_snprintf( pTempBuf, sizeof(pTempBuf), "left_%s", control.m_Name.Get() );
  729. strcpy( (char *)pData, pTempBuf );
  730. pData += Q_strlen( pTempBuf ) + 1;
  731. }
  732. if ( control.m_bIsMulti )
  733. {
  734. pKeynames[j++] = (char *)(pData - pDataStart);
  735. Q_snprintf( pTempBuf, sizeof(pTempBuf), "multi_%s", control.m_Name.Get() );
  736. strcpy( (char *)pData, pTempBuf );
  737. pData += Q_strlen( pTempBuf ) + 1;
  738. }
  739. }
  740. Assert( j == nTotalControlCount );
  741. ALIGN4( pData );
  742. // allocate room for remapping
  743. int *keymapping = (int *)pData;
  744. fhdr->keymappingindex = pData - pDataStart;
  745. pData += sizeof( int ) * nTotalControlCount;
  746. for (i = 0; i < nTotalControlCount; i++)
  747. {
  748. keymapping[i] = -1;
  749. }
  750. ALIGN4( pData );
  751. fhdr->length = pData - pDataStart;
  752. FileHandle_t fh = g_pFullFileSystem->Open( pFileName, "wb" );
  753. if ( !fh )
  754. {
  755. ConWarning( "Unable to write to %s (read-only?)\n", pFileName );
  756. free( pDataStart );
  757. return false;
  758. }
  759. g_pFullFileSystem->Write( pDataStart, fhdr->length, fh );
  760. g_pFullFileSystem->Close( fh );
  761. free( pDataStart );
  762. return true;
  763. }
  764. //-----------------------------------------------------------------------------
  765. // Constructor, destructor
  766. //-----------------------------------------------------------------------------
  767. //-----------------------------------------------------------------------------
  768. // CDmeAnimationSet - container for animation set info
  769. //-----------------------------------------------------------------------------
  770. IMPLEMENT_ELEMENT_FACTORY( DmeAnimationSet, CDmeAnimationSet );
  771. void CDmeAnimationSet::OnConstruction()
  772. {
  773. m_Controls.Init( this, "controls" );
  774. m_PresetGroups.Init( this, "presetGroups" );
  775. m_SelectionGroups.Init( this, "selectionGroups" );
  776. m_PhonemeMap.Init( this, "phonememap" );
  777. m_Operators.Init( this, "operators" );
  778. m_Bookmarks.Init( this, "bookmarks" );
  779. }
  780. void CDmeAnimationSet::OnDestruction()
  781. {
  782. }
  783. CDmaElementArray< CDmElement > &CDmeAnimationSet::GetControls()
  784. {
  785. return m_Controls;
  786. }
  787. CDmaElementArray< CDmePresetGroup > &CDmeAnimationSet::GetPresetGroups()
  788. {
  789. return m_PresetGroups;
  790. }
  791. CDmaElementArray< CDmeOperator > &CDmeAnimationSet::GetOperators()
  792. {
  793. return m_Operators;
  794. }
  795. void CDmeAnimationSet::AddOperator( CDmeOperator *pOperator )
  796. {
  797. m_Operators.AddToTail( pOperator );
  798. }
  799. void CDmeAnimationSet::RemoveOperator( CDmeOperator *pOperator )
  800. {
  801. int nCount = m_Operators.Count();
  802. for ( int i = 0; i < nCount; ++i )
  803. {
  804. if ( m_Operators[i] == pOperator )
  805. {
  806. m_Operators.Remove(i);
  807. break;
  808. }
  809. }
  810. }
  811. //-----------------------------------------------------------------------------
  812. // Finds the index of a particular preset group
  813. //-----------------------------------------------------------------------------
  814. void CDmeAnimationSet::OnElementUnserialized()
  815. {
  816. BaseClass::OnElementUnserialized();
  817. CDmeGameModel *pGameModel = GetValueElement< CDmeGameModel >( "gameModel" );
  818. if ( pGameModel )
  819. {
  820. // NOTE: The model preset manager can't possibly have the right
  821. // file id at this point; it's up to the preset group manager to queue
  822. // application requests until it gets one
  823. g_pModelPresetGroupMgr->ApplyModelPresets( pGameModel->GetModelName(), this );
  824. }
  825. }
  826. //-----------------------------------------------------------------------------
  827. // Finds the index of a particular preset group
  828. //-----------------------------------------------------------------------------
  829. int CDmeAnimationSet::FindPresetGroupIndex( CDmePresetGroup *pPresetGroup )
  830. {
  831. int c = m_PresetGroups.Count();
  832. for ( int i = 0; i < c; ++i )
  833. {
  834. CDmePresetGroup *e = m_PresetGroups.Get( i );
  835. if ( pPresetGroup == e )
  836. return i;
  837. }
  838. return -1;
  839. }
  840. int CDmeAnimationSet::FindPresetGroupIndex( const char *pGroupName )
  841. {
  842. int c = m_PresetGroups.Count();
  843. for ( int i = 0; i < c; ++i )
  844. {
  845. CDmePresetGroup *e = m_PresetGroups.Get( i );
  846. if ( e && !Q_stricmp( e->GetName(), pGroupName ) )
  847. return i;
  848. }
  849. return -1;
  850. }
  851. //-----------------------------------------------------------------------------
  852. // Find by name
  853. //-----------------------------------------------------------------------------
  854. CDmePresetGroup *CDmeAnimationSet::FindPresetGroup( const char *pGroupName )
  855. {
  856. int nIndex = FindPresetGroupIndex( pGroupName );
  857. if ( nIndex >= 0 )
  858. return m_PresetGroups[nIndex];
  859. return NULL;
  860. }
  861. //-----------------------------------------------------------------------------
  862. // Find or add by name
  863. //-----------------------------------------------------------------------------
  864. CDmePresetGroup *CDmeAnimationSet::FindOrAddPresetGroup( const char *pGroupName )
  865. {
  866. CDmePresetGroup *pPresetGroup = FindPresetGroup( pGroupName );
  867. if ( !pPresetGroup )
  868. {
  869. // Create the default groups in order
  870. pPresetGroup = CreateElement< CDmePresetGroup >( pGroupName, GetFileId() );
  871. m_PresetGroups.AddToTail( pPresetGroup );
  872. }
  873. return pPresetGroup;
  874. }
  875. //-----------------------------------------------------------------------------
  876. // Remove preset group
  877. //-----------------------------------------------------------------------------
  878. bool CDmeAnimationSet::RemovePresetGroup( CDmePresetGroup *pPresetGroup )
  879. {
  880. int i = FindPresetGroupIndex( pPresetGroup );
  881. if ( i >= 0 )
  882. {
  883. m_PresetGroups.Remove( i );
  884. return true;
  885. }
  886. return false;
  887. }
  888. //-----------------------------------------------------------------------------
  889. // Move preset group up/down in the list
  890. //-----------------------------------------------------------------------------
  891. void CDmeAnimationSet::MovePresetGroupUp( CDmePresetGroup *pPresetGroup )
  892. {
  893. int i = FindPresetGroupIndex( pPresetGroup );
  894. if ( i >= 1 )
  895. {
  896. m_PresetGroups.Swap( i, i-1 );
  897. }
  898. }
  899. void CDmeAnimationSet::MovePresetGroupDown( CDmePresetGroup *pPresetGroup )
  900. {
  901. int i = FindPresetGroupIndex( pPresetGroup );
  902. if ( i >= 0 && i < m_PresetGroups.Count() - 1 )
  903. {
  904. m_PresetGroups.Swap( i, i+1 );
  905. }
  906. }
  907. //-----------------------------------------------------------------------------
  908. // Reorder preset groups
  909. //-----------------------------------------------------------------------------
  910. void CDmeAnimationSet::MovePresetGroupInFrontOf( CDmePresetGroup *pPresetGroup, CDmePresetGroup *pInFrontOf )
  911. {
  912. if ( pPresetGroup == pInFrontOf )
  913. return;
  914. #ifdef DBGFLAG_ASSERT
  915. int nStart = FindPresetGroupIndex( pPresetGroup );
  916. #endif
  917. int nEnd = pInFrontOf ? FindPresetGroupIndex( pInFrontOf ) : m_PresetGroups.Count();
  918. Assert( nStart >= 0 && nEnd >= 0 );
  919. RemovePresetGroup( pPresetGroup );
  920. if ( nEnd > m_PresetGroups.Count() )
  921. {
  922. nEnd = m_PresetGroups.Count();
  923. }
  924. m_PresetGroups.InsertBefore( nEnd, pPresetGroup );
  925. }
  926. CDmePreset *CDmeAnimationSet::FindOrAddPreset( const char *pGroupName, const char *pPresetName, int nType /*=PROCEDURAL_PRESET_NOT*/ )
  927. {
  928. CDmePresetGroup *pPresetGroup = FindOrAddPresetGroup( pGroupName );
  929. return pPresetGroup->FindOrAddPreset( pPresetName, nType );
  930. }
  931. bool CDmeAnimationSet::RemovePreset( CDmePreset *pPreset )
  932. {
  933. int c = m_PresetGroups.Count();
  934. for ( int i = 0; i < c; ++i )
  935. {
  936. if ( m_PresetGroups[i]->RemovePreset( pPreset ) )
  937. return true;
  938. }
  939. return false;
  940. }
  941. const CDmaElementArray< CDmeBookmark > &CDmeAnimationSet::GetBookmarks() const
  942. {
  943. return m_Bookmarks;
  944. }
  945. CDmaElementArray< CDmeBookmark > &CDmeAnimationSet::GetBookmarks()
  946. {
  947. return m_Bookmarks;
  948. }
  949. CDmaElementArray< CDmElement > &CDmeAnimationSet::GetSelectionGroups()
  950. {
  951. return m_SelectionGroups;
  952. }
  953. CDmaElementArray< CDmePhonemeMapping > &CDmeAnimationSet::GetPhonemeMap()
  954. {
  955. return m_PhonemeMap;
  956. }
  957. void CDmeAnimationSet::RestoreDefaultPhonemeMap()
  958. {
  959. CUndoScopeGuard guard( "RestoreDefaultPhonemeMap" );
  960. int i;
  961. int c = m_PhonemeMap.Count();
  962. for ( i = 0; i < c; ++i )
  963. {
  964. g_pDataModel->DestroyElement( m_PhonemeMap[ i ]->GetHandle() );
  965. }
  966. m_PhonemeMap.Purge();
  967. int phonemeCount = NumPhonemes();
  968. for ( i = 0; i < phonemeCount; ++i )
  969. {
  970. const char *pName = NameForPhonemeByIndex( i );
  971. CDmePhonemeMapping *mapping = CreateElement< CDmePhonemeMapping >( pName, GetFileId() );
  972. char presetName[ 256 ];
  973. Q_snprintf( presetName, sizeof( presetName ), "p_%s", pName );
  974. mapping->m_Preset = presetName;
  975. mapping->m_Weight = 1.0f;
  976. m_PhonemeMap.AddToTail( mapping );
  977. }
  978. }
  979. CDmePhonemeMapping *CDmeAnimationSet::FindMapping( const char *pRawPhoneme )
  980. {
  981. int c = m_PhonemeMap.Count();
  982. for ( int i = 0; i < c; ++i )
  983. {
  984. CDmePhonemeMapping *e = m_PhonemeMap.Get( i );
  985. Assert( e );
  986. if ( !e )
  987. continue;
  988. if ( !Q_stricmp( e->GetName(), pRawPhoneme ) )
  989. return e;
  990. }
  991. return NULL;
  992. }
  993. //-----------------------------------------------------------------------------
  994. // Finds a control
  995. //-----------------------------------------------------------------------------
  996. CDmElement *CDmeAnimationSet::FindControl( const char *pControlName )
  997. {
  998. int c = m_Controls.Count();
  999. for ( int i = 0; i < c; ++i )
  1000. {
  1001. CDmElement *e = m_Controls.Get( i );
  1002. if ( !Q_stricmp( e->GetName(), pControlName ) )
  1003. return e;
  1004. }
  1005. return NULL;
  1006. }
  1007. //-----------------------------------------------------------------------------
  1008. // Finds or adds a control
  1009. //-----------------------------------------------------------------------------
  1010. CDmElement *CDmeAnimationSet::FindOrAddControl( const char *pControlName )
  1011. {
  1012. CDmElement *pControl = FindControl( pControlName );
  1013. if ( !pControl )
  1014. {
  1015. // If not, then create one
  1016. pControl = CreateElement< CDmElement >( pControlName, GetFileId() );
  1017. m_Controls.AddToTail( pControl );
  1018. }
  1019. return pControl;
  1020. }
  1021. CDmElement *CDmeAnimationSet::FindSelectionGroup( const char *pSelectionGroupName )
  1022. {
  1023. int c = m_SelectionGroups.Count();
  1024. for ( int i = 0; i < c; ++i )
  1025. {
  1026. CDmElement *e = m_SelectionGroups.Get( i );
  1027. if ( !Q_stricmp( e->GetName(), pSelectionGroupName ) )
  1028. return e;
  1029. }
  1030. return NULL;
  1031. }
  1032. CDmElement *CDmeAnimationSet::FindOrAddSelectionGroup( const char *pSelectionGroupName )
  1033. {
  1034. CDmElement *pSelectionGroup = FindSelectionGroup( pSelectionGroupName );
  1035. if ( !pSelectionGroup )
  1036. {
  1037. // Create the default groups in order
  1038. pSelectionGroup = CreateElement< CDmElement >( pSelectionGroupName, GetFileId() );
  1039. pSelectionGroup->AddAttribute( "selectedControls", AT_STRING_ARRAY );
  1040. m_SelectionGroups.AddToTail( pSelectionGroup );
  1041. }
  1042. return pSelectionGroup;
  1043. }
  1044. void CDmeAnimationSet::CollectOperators( CUtlVector< DmElementHandle_t > &operators )
  1045. {
  1046. int numOperators = m_Operators.Count();
  1047. for ( int i = 0; i < numOperators; ++i )
  1048. {
  1049. DmElementHandle_t h = m_Operators.GetHandle( i );
  1050. if ( h != DMELEMENT_HANDLE_INVALID )
  1051. {
  1052. operators.AddToTail( h );
  1053. }
  1054. }
  1055. }
  1056. struct PPType_t
  1057. {
  1058. int type;
  1059. char const *name;
  1060. };
  1061. static PPType_t g_PresetNames[ NUM_PROCEDURAL_PRESET_TYPES ] =
  1062. {
  1063. { PROCEDURAL_PRESET_NOT, "NotProcedural!!!" },
  1064. { PROCEDURAL_PRESET_IN_CROSSFADE, "In" },
  1065. { PROCEDURAL_PRESET_OUT_CROSSFADE, "Out" },
  1066. { PROCEDURAL_PRESET_REVEAL, "Reveal" },
  1067. { PROCEDURAL_PRESET_PASTE, "Paste" },
  1068. { PROCEDURAL_PRESET_JITTER, "Jitter" },
  1069. { PROCEDURAL_PRESET_SMOOTH, "Smooth" },
  1070. { PROCEDURAL_PRESET_SHARPEN, "Sharpen" },
  1071. { PROCEDURAL_PRESET_SOFTEN, "Soften" },
  1072. { PROCEDURAL_PRESET_STAGGER, "Stagger" },
  1073. };
  1074. void CDmeAnimationSet::EnsureProceduralPresets()
  1075. {
  1076. // Note: Starts at index 1 to skip the PROCEDURAL_PRESET_NOT case
  1077. for ( int i = 1; i < NUM_PROCEDURAL_PRESET_TYPES; ++i )
  1078. {
  1079. FindOrAddPreset( "Procedural", g_PresetNames[ i ].name, g_PresetNames[ i ].type );
  1080. }
  1081. }
  1082. //-----------------------------------------------------------------------------
  1083. // A cache of preset groups to be associated with specific models
  1084. //-----------------------------------------------------------------------------
  1085. class CModelPresetGroupManager : public IModelPresetGroupManager
  1086. {
  1087. public:
  1088. CModelPresetGroupManager();
  1089. virtual void AssociatePresetsWithFile( DmFileId_t fileId );
  1090. virtual void ApplyModelPresets( const char *pModelName, CDmeAnimationSet *pAnimationSet );
  1091. private:
  1092. struct QueuedPresetRequest_t
  1093. {
  1094. CUtlString m_ModelName;
  1095. CDmeHandle< CDmeAnimationSet > m_hAnimationSet;
  1096. };
  1097. typedef CUtlVector< CDmeHandle< CDmePresetGroup, true > > PresetGroupList_t;
  1098. // Loads model presets from .pre files matching the model name
  1099. void LoadModelPresets( const char *pModelName, PresetGroupList_t &list );
  1100. CUtlStringMap< PresetGroupList_t > m_Lookup;
  1101. DmFileId_t m_FileId;
  1102. CUtlVector< QueuedPresetRequest_t > m_QueuedPresetRequest;
  1103. };
  1104. //-----------------------------------------------------------------------------
  1105. // Singleton
  1106. //-----------------------------------------------------------------------------
  1107. static CModelPresetGroupManager s_ModelPresetGroupManager;
  1108. IModelPresetGroupManager *g_pModelPresetGroupMgr = &s_ModelPresetGroupManager;
  1109. //-----------------------------------------------------------------------------
  1110. // Constructor
  1111. //-----------------------------------------------------------------------------
  1112. CModelPresetGroupManager::CModelPresetGroupManager()
  1113. {
  1114. m_FileId = DMFILEID_INVALID;
  1115. }
  1116. //-----------------------------------------------------------------------------
  1117. // Associates presets in the cache with a particular file
  1118. //-----------------------------------------------------------------------------
  1119. void CModelPresetGroupManager::AssociatePresetsWithFile( DmFileId_t fileId )
  1120. {
  1121. m_FileId = fileId;
  1122. m_Lookup.Clear();
  1123. if ( m_FileId != DMFILEID_INVALID )
  1124. {
  1125. int nCount = m_QueuedPresetRequest.Count();
  1126. for ( int i = 0; i < nCount; ++i )
  1127. {
  1128. QueuedPresetRequest_t &request = m_QueuedPresetRequest[i];
  1129. if ( request.m_hAnimationSet.Get() )
  1130. {
  1131. ApplyModelPresets( request.m_ModelName, request.m_hAnimationSet.Get() );
  1132. }
  1133. }
  1134. m_QueuedPresetRequest.Purge();
  1135. }
  1136. }
  1137. //-----------------------------------------------------------------------------
  1138. // Loads model presets from .pre files matching the model name
  1139. //-----------------------------------------------------------------------------
  1140. void CModelPresetGroupManager::LoadModelPresets( const char *pModelName, PresetGroupList_t &list )
  1141. {
  1142. list.RemoveAll();
  1143. char pPresetPath[MAX_PATH];
  1144. Q_ExtractFilePath( pModelName, pPresetPath, sizeof(pPresetPath) );
  1145. char pPresetNameBuf[MAX_PATH];
  1146. Q_StripExtension( pModelName, pPresetNameBuf, sizeof(pPresetNameBuf) );
  1147. int nLen = Q_strlen( pPresetNameBuf );
  1148. Q_snprintf( &pPresetNameBuf[nLen], MAX_PATH - nLen, "*.pre" );
  1149. CDisableUndoScopeGuard sg;
  1150. FileFindHandle_t fh;
  1151. const char *pFileName = g_pFullFileSystem->FindFirstEx( pPresetNameBuf, "GAME", &fh );
  1152. for ( ; pFileName; pFileName = g_pFullFileSystem->FindNext( fh ) )
  1153. {
  1154. char pRelativePresetPath[MAX_PATH];
  1155. Q_ComposeFileName(pPresetPath, pFileName, pRelativePresetPath, sizeof(pRelativePresetPath) );
  1156. CDmElement* pRoot = NULL;
  1157. DmFileId_t fileid = g_pDataModel->RestoreFromFile( pRelativePresetPath, "GAME", NULL, &pRoot, CR_FORCE_COPY );
  1158. if ( fileid == DMFILEID_INVALID || !pRoot )
  1159. continue;
  1160. CDmePresetGroup *pPresetGroup = CastElement<CDmePresetGroup>( pRoot );
  1161. if ( !pPresetGroup )
  1162. {
  1163. if ( pRoot )
  1164. {
  1165. g_pDataModel->RemoveFileId( pRoot->GetFileId() );
  1166. }
  1167. continue;
  1168. }
  1169. pPresetGroup->SetFileId( m_FileId, TD_DEEP );
  1170. // Presets used through the model preset manager must be read only + shared
  1171. pPresetGroup->m_bIsReadOnly = true;
  1172. pPresetGroup->SetShared( true );
  1173. int i = list.AddToTail();
  1174. list[i] = pPresetGroup;
  1175. }
  1176. g_pFullFileSystem->FindClose( fh );
  1177. }
  1178. //-----------------------------------------------------------------------------
  1179. // Applies model presets associated with a particular model to an animation set
  1180. //-----------------------------------------------------------------------------
  1181. void CModelPresetGroupManager::ApplyModelPresets( const char *pModelName, CDmeAnimationSet *pAnimationSet )
  1182. {
  1183. if ( m_FileId == DMFILEID_INVALID )
  1184. {
  1185. int i = m_QueuedPresetRequest.AddToTail();
  1186. m_QueuedPresetRequest[i].m_ModelName = pModelName;
  1187. m_QueuedPresetRequest[i].m_hAnimationSet = pAnimationSet;
  1188. return;
  1189. }
  1190. if ( !m_Lookup.Defined( pModelName ) )
  1191. {
  1192. LoadModelPresets( pModelName, m_Lookup[pModelName] );
  1193. }
  1194. PresetGroupList_t &list = m_Lookup[pModelName];
  1195. int nCount = list.Count();
  1196. for ( int i = 0; i < nCount; ++i )
  1197. {
  1198. CDmePresetGroup *pPresetGroup = list[i];
  1199. int nIndex = pAnimationSet->FindPresetGroupIndex( pPresetGroup->GetName() );
  1200. if ( nIndex >= 0 )
  1201. {
  1202. pAnimationSet->GetPresetGroups().Set( nIndex, pPresetGroup );
  1203. }
  1204. else
  1205. {
  1206. pAnimationSet->GetPresetGroups().AddToTail( pPresetGroup );
  1207. }
  1208. }
  1209. }