summaryrefslogtreecommitdiff
path: root/movieobjects/dmeanimationset.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'movieobjects/dmeanimationset.cpp')
-rw-r--r--movieobjects/dmeanimationset.cpp1407
1 files changed, 1407 insertions, 0 deletions
diff --git a/movieobjects/dmeanimationset.cpp b/movieobjects/dmeanimationset.cpp
new file mode 100644
index 0000000..926de45
--- /dev/null
+++ b/movieobjects/dmeanimationset.cpp
@@ -0,0 +1,1407 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+#include "movieobjects/dmeanimationset.h"
+#include "movieobjects/dmebookmark.h"
+#include "movieobjects/dmegamemodel.h"
+#include "movieobjects/dmecombinationoperator.h"
+#include "datamodel/dmelementfactoryhelper.h"
+#include "datamodel/dmehandle.h"
+#include "phonemeconverter.h"
+#include "tier1/utlstringmap.h"
+#include "tier2/tier2.h"
+#include "filesystem.h"
+#include "studio.h"
+#include "tier3/tier3.h"
+#include "tier1/utlbuffer.h"
+
+//-----------------------------------------------------------------------------
+// CDmePresetGroup - container for animation set info
+//-----------------------------------------------------------------------------
+IMPLEMENT_ELEMENT_FACTORY( DmePreset, CDmePreset );
+
+void CDmePreset::OnConstruction()
+{
+ m_ControlValues.Init( this, "controlValues" );
+ m_nProceduralType.InitAndSet( this, "procedural", PROCEDURAL_PRESET_NOT );
+}
+
+void CDmePreset::OnDestruction()
+{
+}
+
+CDmaElementArray< CDmElement > &CDmePreset::GetControlValues()
+{
+ return m_ControlValues;
+}
+
+const CDmaElementArray< CDmElement > &CDmePreset::GetControlValues() const
+{
+ return m_ControlValues;
+}
+
+int CDmePreset::FindControlValueIndex( const char *pControlName )
+{
+ int c = m_ControlValues.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ CDmElement *e = m_ControlValues.Get( i );
+ if ( !Q_stricmp( e->GetName(), pControlName ) )
+ return i;
+ }
+ return -1;
+}
+
+CDmElement *CDmePreset::FindControlValue( const char *pControlName )
+{
+ int i = FindControlValueIndex( pControlName );
+ if ( i >= 0 )
+ return m_ControlValues.Get(i);
+ return NULL;
+}
+
+CDmElement *CDmePreset::FindOrAddControlValue( const char *pControlName )
+{
+ CDmElement *pControlValues = FindControlValue( pControlName );
+ if ( !pControlValues )
+ {
+ // Create the default groups in order
+ pControlValues = CreateElement< CDmElement >( pControlName, GetFileId() );
+ m_ControlValues.AddToTail( pControlValues );
+ }
+ return pControlValues;
+}
+
+void CDmePreset::RemoveControlValue( const char *pControlName )
+{
+ int i = FindControlValueIndex( pControlName );
+ if ( i >= 0 )
+ {
+ m_ControlValues.Remove( i );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Is the preset read-only?
+//-----------------------------------------------------------------------------
+bool CDmePreset::IsReadOnly()
+{
+ DmAttributeReferenceIterator_t h = g_pDataModel->FirstAttributeReferencingElement( GetHandle() );
+ while ( h != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID )
+ {
+ CDmAttribute *pAttribute = g_pDataModel->GetAttribute( h );
+ CDmePresetGroup *pOwner = CastElement<CDmePresetGroup>( pAttribute->GetOwner() );
+ if ( pOwner && pOwner->m_bIsReadOnly )
+ return true;
+ h = g_pDataModel->NextAttributeReferencingElement( h );
+ }
+ return false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Copies control values
+//-----------------------------------------------------------------------------
+void CDmePreset::CopyControlValuesFrom( CDmePreset *pSource )
+{
+ m_ControlValues.RemoveAll();
+
+ const CDmaElementArray< CDmElement > &sourceValues = pSource->GetControlValues();
+ int nCount = sourceValues.Count();
+ for ( int i = 0; i < nCount; ++i )
+ {
+ CDmElement *pCopy = sourceValues[i]->Copy( );
+ m_ControlValues.AddToTail( pCopy );
+ }
+}
+
+void CDmePreset::SetProceduralPresetType( int nType )
+{
+ Assert( nType >= 0 && nType < NUM_PROCEDURAL_PRESET_TYPES );
+ m_nProceduralType = nType;
+}
+
+bool CDmePreset::IsProcedural() const
+{
+ return m_nProceduralType != PROCEDURAL_PRESET_NOT;
+}
+
+int CDmePreset::GetProceduralPresetType() const
+{
+ return m_nProceduralType;
+}
+
+IMPLEMENT_ELEMENT_FACTORY( DmeProceduralPresetSettings, CDmeProceduralPresetSettings );
+
+void CDmeProceduralPresetSettings::OnConstruction()
+{
+ m_flJitterScale.InitAndSet( this, "jitterscale", 1.0f );
+ m_flSmoothScale.InitAndSet( this, "smoothscale", 1.0f );
+ m_flSharpenScale.InitAndSet( this, "sharpenscale", 1.0f );
+ m_flSoftenScale.InitAndSet( this, "softenscale", 1.0f );
+
+ m_nJitterIterations.InitAndSet( this, "jitteriterations", 5 );
+ m_nSmoothIterations.InitAndSet( this, "smoothiterations", 5 );
+ m_nSharpenIterations.InitAndSet( this, "sharpeniterations", 1 );
+ m_nSoftenIterations.InitAndSet( this, "softeniterations", 1 );
+
+ // 1/12 second now ( 833 ten thousandths )
+ m_nStaggerInterval.InitAndSet( this, "staggerinterval", 10000 / 12 );
+}
+
+void CDmeProceduralPresetSettings::OnDestruction()
+{
+}
+
+//-----------------------------------------------------------------------------
+// CDmePresetRemap - copies presets from one group to another
+//-----------------------------------------------------------------------------
+IMPLEMENT_ELEMENT_FACTORY( DmePresetRemap, CDmePresetRemap );
+
+void CDmePresetRemap::OnConstruction()
+{
+ m_SourcePresetGroup.Init( this, "sourcePresetGroup" );
+ m_SrcPresets.Init( this, "srcPresets" );
+ m_DestPresets.Init( this, "destPresets" );
+}
+
+void CDmePresetRemap::OnDestruction()
+{
+}
+
+
+const char *CDmePresetRemap::FindSourcePreset( const char *pDestPresetName )
+{
+ int nCount = m_DestPresets.Count();
+ for ( int i = 0; i < nCount; ++i )
+ {
+ if ( !Q_stricmp( pDestPresetName, m_DestPresets[i] ) )
+ return m_SrcPresets[i];
+ }
+ return NULL;
+}
+
+void CDmePresetRemap::AddRemap( const char *pSourcePresetName, const char *pDestPresetName )
+{
+ m_SrcPresets.AddToTail( pSourcePresetName );
+ m_DestPresets.AddToTail( pDestPresetName );
+}
+
+void CDmePresetRemap::RemoveAll()
+{
+ m_SrcPresets.RemoveAll();
+ m_DestPresets.RemoveAll();
+}
+
+
+//-----------------------------------------------------------------------------
+// Iteration
+//-----------------------------------------------------------------------------
+int CDmePresetRemap::GetRemapCount()
+{
+ return m_SrcPresets.Count();
+}
+
+const char *CDmePresetRemap::GetRemapSource( int i )
+{
+ return m_SrcPresets[i];
+}
+
+const char *CDmePresetRemap::GetRemapDest( int i )
+{
+ return m_DestPresets[i];
+}
+
+
+//-----------------------------------------------------------------------------
+// CDmePresetGroup - container for animation set info
+//-----------------------------------------------------------------------------
+IMPLEMENT_ELEMENT_FACTORY( DmePresetGroup, CDmePresetGroup );
+
+void CDmePresetGroup::OnConstruction()
+{
+ m_Presets.Init( this, "presets" );
+ m_bIsVisible.InitAndSet( this, "visible", true );
+ m_bIsReadOnly.Init( this, "readonly" );
+}
+
+void CDmePresetGroup::OnDestruction()
+{
+}
+
+CDmaElementArray< CDmePreset > &CDmePresetGroup::GetPresets()
+{
+ return m_Presets;
+}
+
+const CDmaElementArray< CDmePreset > &CDmePresetGroup::GetPresets() const
+{
+ return m_Presets;
+}
+
+//-----------------------------------------------------------------------------
+// Finds the index of a particular preset group
+//-----------------------------------------------------------------------------
+int CDmePresetGroup::FindPresetIndex( CDmePreset *pPreset )
+{
+ int c = m_Presets.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ CDmePreset *e = m_Presets.Get( i );
+ if ( pPreset == e )
+ return i;
+ }
+ return -1;
+}
+
+
+CDmePreset *CDmePresetGroup::FindPreset( const char *pPresetName )
+{
+ int i;
+ int c = m_Presets.Count();
+ for ( i = 0; i < c; ++i )
+ {
+ CDmePreset *e = m_Presets.Get( i );
+ if ( !Q_stricmp( e->GetName(), pPresetName ) )
+ return e;
+ }
+ return NULL;
+}
+
+CDmePreset *CDmePresetGroup::FindOrAddPreset( const char *pPresetName, int nType /*=PROCEDURAL_PRESET_NOT*/ )
+{
+ CDmePreset *pPreset = FindPreset( pPresetName );
+ if ( !pPreset )
+ {
+ // Create the default groups in order
+ pPreset = CreateElement< CDmePreset >( pPresetName, GetFileId() );
+ pPreset->SetProceduralPresetType( nType );
+ m_Presets.AddToTail( pPreset );
+ }
+ return pPreset;
+}
+
+bool CDmePresetGroup::RemovePreset( CDmePreset *pPreset )
+{
+ int i = FindPresetIndex( pPreset );
+ if ( i >= 0 )
+ {
+ m_Presets.Remove( i );
+ return true;
+ }
+ return false;
+}
+
+void CDmePresetGroup::MovePresetUp( CDmePreset *pPreset )
+{
+ int i = FindPresetIndex( pPreset );
+ if ( i >= 1 )
+ {
+ m_Presets.Swap( i, i-1 );
+ }
+}
+
+void CDmePresetGroup::MovePresetDown( CDmePreset *pPreset )
+{
+ int i = FindPresetIndex( pPreset );
+ if ( i >= 0 && i < m_Presets.Count() - 1 )
+ {
+ m_Presets.Swap( i, i+1 );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Reorder presets
+//-----------------------------------------------------------------------------
+void CDmePresetGroup::MovePresetInFrontOf( CDmePreset *pPreset, CDmePreset *pInFrontOf )
+{
+ if ( pPreset == pInFrontOf )
+ return;
+
+ int nEnd = pInFrontOf ? FindPresetIndex( pInFrontOf ) : m_Presets.Count();
+ Assert( nEnd >= 0 );
+
+ RemovePreset( pPreset );
+ if ( nEnd > m_Presets.Count() )
+ {
+ nEnd = m_Presets.Count();
+ }
+ m_Presets.InsertBefore( nEnd, pPreset );
+}
+
+
+//-----------------------------------------------------------------------------
+// The preset remap
+//-----------------------------------------------------------------------------
+CDmePresetRemap *CDmePresetGroup::GetPresetRemap()
+{
+ return GetValueElement< CDmePresetRemap >( "presetRemap" );
+}
+
+CDmePresetRemap *CDmePresetGroup::GetOrAddPresetRemap()
+{
+ CDmePresetRemap *pPresetRemap = GetPresetRemap();
+ if ( !pPresetRemap )
+ {
+ pPresetRemap = CreateElement< CDmePresetRemap >( "PresetRemap", GetFileId() );
+ SetValue( "presetRemap", pPresetRemap );
+ }
+ return pPresetRemap;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Finds a control index
+//-----------------------------------------------------------------------------
+struct ExportedControl_t
+{
+ CUtlString m_Name;
+ bool m_bIsStereo;
+ bool m_bIsMulti;
+ int m_nFirstIndex;
+};
+
+
+//-----------------------------------------------------------------------------
+// Builds a unique list of controls found in the presets
+//-----------------------------------------------------------------------------
+static int FindExportedControlIndex( const char *pControlName, CUtlVector< ExportedControl_t > &uniqueControls )
+{
+ int nCount = uniqueControls.Count();
+ for ( int i = 0; i < nCount; ++i )
+ {
+ if ( !Q_stricmp( pControlName, uniqueControls[i].m_Name ) )
+ return i;
+ }
+ return -1;
+}
+
+
+//-----------------------------------------------------------------------------
+// Builds a unique list of controls found in the presets
+//-----------------------------------------------------------------------------
+static int BuildExportedControlList( CDmeAnimationSet *pAnimationSet, const CDmePresetGroup *pPresetGroup, CUtlVector< ExportedControl_t > &uniqueControls )
+{
+ int nGlobalIndex = 0;
+ const CDmrElementArrayConst< CDmePreset > &presets = pPresetGroup->GetPresets();
+ int nPresetCount = presets.Count();
+ for ( int iPreset = 0; iPreset < nPresetCount; ++iPreset )
+ {
+ CDmePreset *pPreset = presets[iPreset];
+ const CDmrElementArray< CDmElement > &controls = pPreset->GetControlValues();
+
+ int nControlCount = controls.Count();
+ for ( int i = 0; i < nControlCount; ++i )
+ {
+ const char *pControlName = controls[i]->GetName();
+ int nIndex = FindExportedControlIndex( pControlName, uniqueControls );
+ if ( nIndex >= 0 )
+ continue;
+ CDmAttribute *pValueAttribute = controls[i]->GetAttribute( "value" );
+ if ( !pValueAttribute || pValueAttribute->GetType() != AT_FLOAT )
+ continue;
+
+ if ( pAnimationSet )
+ {
+
+ CDmElement *pControl = pAnimationSet->FindControl( pControlName );
+ if ( !pControl )
+ continue;
+
+ int j = uniqueControls.AddToTail();
+ ExportedControl_t &control = uniqueControls[j];
+ control.m_Name = pControlName;
+ control.m_bIsStereo = pControl->GetValue<bool>( "combo" );
+ control.m_bIsMulti = pControl->GetValue<bool>( "multi" );
+ control.m_nFirstIndex = nGlobalIndex;
+ nGlobalIndex += 1 + control.m_bIsStereo + control.m_bIsMulti;
+ }
+ else
+ {
+ int j = uniqueControls.AddToTail();
+ ExportedControl_t &control = uniqueControls[j];
+ control.m_Name = pControlName;
+ // this isn't quite as reliable as querying the animation set but if we don't have one...
+ control.m_bIsStereo = controls[ i ]->GetAttribute( "balance" ) ? true : false;
+ control.m_bIsMulti = controls[ i ]->GetAttribute( "multilevel" ) ? true : false;
+ control.m_nFirstIndex = nGlobalIndex;
+ nGlobalIndex += 1 + control.m_bIsStereo + control.m_bIsMulti;
+ }
+ }
+ }
+ return nGlobalIndex;
+}
+
+
+//-----------------------------------------------------------------------------
+// Exports this preset group to a faceposer .txt expression file
+// Either an animation set or a combination operator are required so that
+// the default value for unspecified
+//-----------------------------------------------------------------------------
+bool CDmePresetGroup::ExportToTXT( const char *pFileName, CDmeAnimationSet *pAnimationSet /* = NULL */, CDmeCombinationOperator *pComboOp /* = NULL */ ) const
+{
+ const CDmePresetGroup *pPresetGroup = this;
+
+ // find all used controls
+ CUtlVector< ExportedControl_t > exportedControls;
+ BuildExportedControlList( pAnimationSet, pPresetGroup, exportedControls );
+
+ CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
+
+ // Output the unique keys
+ buf.Printf( "$keys " );
+ int nExportedControlCount = exportedControls.Count();
+ for ( int i = 0; i < nExportedControlCount; ++i )
+ {
+ char pTempBuf[MAX_PATH];
+
+ ExportedControl_t &control = exportedControls[i];
+ if ( !control.m_bIsStereo )
+ {
+ buf.Printf("%s ", control.m_Name.Get() );
+ }
+ else
+ {
+ Q_snprintf( pTempBuf, sizeof(pTempBuf), "right_%s", control.m_Name.Get() );
+ buf.Printf("%s ", pTempBuf );
+ Q_snprintf( pTempBuf, sizeof(pTempBuf), "left_%s", control.m_Name.Get() );
+ buf.Printf("%s ", pTempBuf );
+ }
+
+ if ( control.m_bIsMulti )
+ {
+ Q_snprintf( pTempBuf, sizeof(pTempBuf), "multi_%s", control.m_Name.Get() );
+ buf.Printf("%s ", pTempBuf );
+ }
+ }
+ buf.Printf( "\n" );
+ buf.Printf( "$hasweighting\n" );
+ buf.Printf( "$normalized\n" );
+
+ // Output all presets
+ const CDmrElementArrayConst< CDmePreset > &presets = pPresetGroup->GetPresets();
+ int nPresetCount = presets.Count();
+ for ( int iPreset = 0; iPreset < nPresetCount; ++iPreset )
+ {
+ CDmePreset *pPreset = presets[iPreset];
+ const char *pPresetName = pPreset->GetName();
+
+ // Hack for 'silence' and for p_ naming scheme
+ if ( !Q_stricmp( pPresetName, "p_silence" ) )
+ {
+ pPresetName = "<sil>";
+ }
+ if ( pPresetName[0] == 'p' && pPresetName[1] == '_' )
+ {
+ pPresetName = &pPresetName[2];
+ }
+
+ buf.Printf( "\"%s\" \t", pPresetName );
+
+ int nPhonemeIndex = TextToPhonemeIndex( pPresetName );
+ int nCode = CodeForPhonemeByIndex( nPhonemeIndex );
+ if ( nCode < 128 )
+ {
+ buf.Printf( "\"%c\" \t", nCode );
+ }
+ else
+ {
+ buf.Printf( "\"0x%x\"\t", nCode );
+ }
+
+ for ( int i = 0; i < nExportedControlCount; ++i )
+ {
+ ExportedControl_t &control = exportedControls[i];
+ CDmElement *pControlValue = pPreset->FindControlValue( control.m_Name );
+ if ( !pControlValue )
+ {
+ CDmElement *pControl = pAnimationSet ? pAnimationSet->FindControl( control.m_Name ) : NULL;
+ if ( !pControl )
+ {
+ const ControlIndex_t nIndex = pComboOp ? pComboOp->FindControlIndex( control.m_Name ) : -1;
+ if ( nIndex >= 0 )
+ {
+ buf.Printf( "%.5f\t0.000\t", pComboOp->GetControlDefaultValue( nIndex ) );
+ if ( control.m_bIsStereo )
+ {
+ buf.Printf( "%.5f\t0.000\t", pComboOp->GetControlDefaultValue( nIndex ) );
+ }
+ if ( control.m_bIsMulti )
+ {
+ buf.Printf( "%.5f\t0.000\t", pComboOp->GetControlDefaultValue( nIndex ) );
+ }
+ }
+ else
+ {
+ buf.Printf( "0.000\t0.000\t" );
+ if ( control.m_bIsStereo )
+ {
+ buf.Printf( "0.000\t0.000\t" );
+ }
+ if ( control.m_bIsMulti )
+ {
+ buf.Printf( "0.000\t0.000\t" );
+ }
+ }
+
+ continue;
+ }
+
+ if ( !control.m_bIsStereo )
+ {
+ buf.Printf( "%.5f\t1.000\t", pControl->GetValue<float>( "defaultValue" ) );
+ }
+ else
+ {
+ float flValue, flBalance, flLeft, flRight;
+ flValue = pControl->GetValue<float>( "defaultValue", 0.0f );
+ flBalance = pControl->GetValue<float>( "defaultBalance", 0.5f );
+ ValueBalanceToLeftRight( &flLeft, &flRight, flValue, flBalance );
+ buf.Printf( "%.5f\t1.000\t", flRight );
+ buf.Printf( "%.5f\t1.000\t", flLeft );
+ }
+
+ if ( control.m_bIsMulti )
+ {
+ buf.Printf( "%.5f\t1.000\t", pControl->GetValue<float>( "defaultMultilevel" ) );
+ }
+ continue;
+ }
+
+ if ( !control.m_bIsStereo )
+ {
+ buf.Printf( "%.5f\t1.000\t", pControlValue->GetValue<float>( "value" ) );
+ }
+ else
+ {
+ float flValue, flBalance, flLeft, flRight;
+ flValue = pControlValue->GetValue<float>( "value" );
+ flBalance = pControlValue->GetValue<float>( "balance" );
+ ValueBalanceToLeftRight( &flLeft, &flRight, flValue, flBalance );
+ buf.Printf( "%.5f\t1.000\t", flRight );
+ buf.Printf( "%.5f\t1.000\t", flLeft );
+ }
+
+ if ( control.m_bIsMulti )
+ {
+ buf.Printf( "%.5f\t1.000\t", pControlValue->GetValue<float>( "multilevel" ) );
+ }
+ }
+ const char *pDesc = DescForPhonemeByIndex( nPhonemeIndex );
+ buf.Printf( "\"%s\"\n", pDesc ? pDesc : pPresetName );
+ }
+
+ return g_pFullFileSystem->WriteFile( pFileName, NULL, buf );
+}
+
+#ifdef ALIGN4
+#undef ALIGN4
+#endif // #ifdef ALIGN4
+#define ALIGN4( a ) a = (byte *)((int)((byte *)a + 3) & ~ 3)
+
+
+//-----------------------------------------------------------------------------
+// Exports this preset group to a faceposer .vfe expression file
+//-----------------------------------------------------------------------------
+bool CDmePresetGroup::ExportToVFE( const char *pFileName, CDmeAnimationSet *pAnimationSet /* = NULL */, CDmeCombinationOperator *pComboOp /* = NULL */ ) const
+{
+ const CDmePresetGroup *pPresetGroup = this;
+
+ int i;
+ const CDmrElementArrayConst< CDmePreset > &presets = pPresetGroup->GetPresets();
+
+ // find all used controls
+ CUtlVector< ExportedControl_t > exportedControls;
+ int nTotalControlCount = BuildExportedControlList( pAnimationSet, pPresetGroup, exportedControls );
+ const int nExportedControlCount = exportedControls.Count();
+
+ byte *pData = (byte *)calloc( 1024 * 1024, 1 );
+ byte *pDataStart = pData;
+
+ flexsettinghdr_t *fhdr = (flexsettinghdr_t *)pData;
+
+ fhdr->id = ('V' << 16) + ('F' << 8) + ('E');
+ fhdr->version = 0;
+ if ( !g_pFullFileSystem->FullPathToRelativePathEx( pFileName, "GAME", fhdr->name, sizeof(fhdr->name) ) )
+ {
+ Q_strncpy( fhdr->name, pFileName, sizeof(fhdr->name) );
+ }
+
+ // allocate room for header
+ pData += sizeof( flexsettinghdr_t );
+ ALIGN4( pData );
+
+ // store flex settings
+ flexsetting_t *pSetting = (flexsetting_t *)pData;
+ fhdr->numflexsettings = presets.Count();
+ fhdr->flexsettingindex = pData - pDataStart;
+ pData += sizeof( flexsetting_t ) * fhdr->numflexsettings;
+ ALIGN4( pData );
+ for ( i = 0; i < fhdr->numflexsettings; i++ )
+ {
+ CDmePreset *pPreset = presets[i];
+ Assert( pPreset );
+
+ pSetting[i].index = i;
+ pSetting[i].settingindex = pData - (byte *)(&pSetting[i]);
+
+ flexweight_t *pFlexWeights = (flexweight_t *)pData;
+
+ for ( int j = 0; j < nExportedControlCount; j++ )
+ {
+ ExportedControl_t &control = exportedControls[ j ];
+ CDmElement *pControlValue = pPreset->FindControlValue( control.m_Name );
+ if ( !pControlValue )
+ {
+ const ControlIndex_t nIndex = pComboOp ? pComboOp->FindControlIndex( control.m_Name ) : -1;
+ if ( nIndex >= 0 )
+ {
+ if ( !control.m_bIsStereo )
+ {
+ pSetting[i].numsettings++;
+ pFlexWeights->key = control.m_nFirstIndex;
+ pFlexWeights->weight = pComboOp->GetControlDefaultValue( nIndex );
+ pFlexWeights->influence = 1.0f;
+ pFlexWeights++;
+ }
+ else
+ {
+ float flValue, flBalance, flLeft, flRight;
+ flValue = pComboOp->GetControlDefaultValue( nIndex );
+ flBalance = 0.5;
+ ValueBalanceToLeftRight( &flLeft, &flRight, flValue, flBalance );
+
+ pSetting[i].numsettings += 2;
+ pFlexWeights->key = control.m_nFirstIndex;
+ pFlexWeights->weight = flRight;
+ pFlexWeights->influence = 1.0f;
+ pFlexWeights++;
+ pFlexWeights->key = control.m_nFirstIndex + 1;
+ pFlexWeights->weight = flLeft;
+ pFlexWeights->influence = 1.0f;
+ pFlexWeights++;
+ }
+
+ if ( control.m_bIsMulti )
+ {
+ pSetting[i].numsettings++;
+ pFlexWeights->key = control.m_nFirstIndex + 1 + control.m_bIsStereo;
+ pFlexWeights->weight = 0.5f;
+ pFlexWeights->influence = 1.0f;
+ pFlexWeights++;
+ }
+ }
+ else
+ {
+ pSetting[i].numsettings++;
+ pFlexWeights->key = control.m_nFirstIndex;
+ pFlexWeights->weight = 0.0f;
+ pFlexWeights->influence = 0.0f;
+ pFlexWeights++;
+
+ if ( control.m_bIsStereo )
+ {
+ pSetting[i].numsettings++;
+ pFlexWeights->key = control.m_nFirstIndex + 1;
+ pFlexWeights->weight = 0.0f;
+ pFlexWeights->influence = 0.0f;
+ pFlexWeights++;
+ }
+
+ if ( control.m_bIsMulti )
+ {
+ pSetting[i].numsettings++;
+ pFlexWeights->key = control.m_nFirstIndex + 1 + control.m_bIsStereo;
+ pFlexWeights->weight = 0.5f;
+ pFlexWeights->influence = 0.0f;
+ pFlexWeights++;
+ }
+ }
+
+ continue;
+ }
+
+ if ( !control.m_bIsStereo )
+ {
+ pSetting[i].numsettings++;
+ pFlexWeights->key = control.m_nFirstIndex;
+ pFlexWeights->weight = pControlValue->GetValue<float>( "value" );
+ pFlexWeights->influence = 1.0f;
+ pFlexWeights++;
+ }
+ else
+ {
+ float flValue, flBalance, flLeft, flRight;
+ flValue = pControlValue->GetValue<float>( "value" );
+ flBalance = pControlValue->GetValue<float>( "balance" );
+ ValueBalanceToLeftRight( &flLeft, &flRight, flValue, flBalance );
+
+ pSetting[i].numsettings += 2;
+ pFlexWeights->key = control.m_nFirstIndex;
+ pFlexWeights->weight = flRight;
+ pFlexWeights->influence = 1.0f;
+ pFlexWeights++;
+ pFlexWeights->key = control.m_nFirstIndex + 1;
+ pFlexWeights->weight = flLeft;
+ pFlexWeights->influence = 1.0f;
+ pFlexWeights++;
+ }
+
+ if ( control.m_bIsMulti )
+ {
+ pSetting[i].numsettings++;
+ pFlexWeights->key = control.m_nFirstIndex + 1 + control.m_bIsStereo;
+ pFlexWeights->weight = pControlValue->GetValue<float>( "multilevel" );
+ pFlexWeights->influence = 1.0f;
+ pFlexWeights++;
+ }
+ }
+
+ pData = (byte *)pFlexWeights;
+ ALIGN4( pData );
+ }
+
+ int numindexes = 1;
+ for (i = 0; i < fhdr->numflexsettings; i++)
+ {
+ if ( pSetting[i].index >= numindexes )
+ {
+ numindexes = pSetting[i].index + 1;
+ }
+ }
+
+ // store indexed table
+ int *pIndex = (int *)pData;
+ fhdr->numindexes = numindexes;
+ fhdr->indexindex = pData - pDataStart;
+ pData += sizeof( int ) * numindexes;
+ ALIGN4( pData );
+ for (i = 0; i < numindexes; i++)
+ {
+ pIndex[i] = -1;
+ }
+ for (i = 0; i < fhdr->numflexsettings; i++)
+ {
+ pIndex[pSetting[i].index] = i;
+ }
+
+ // store flex setting names
+ for (i = 0; i < fhdr->numflexsettings; i++)
+ {
+ CDmePreset *pPreset = presets[i];
+ const char *pPresetName = pPreset->GetName();
+
+ // Hack for 'silence' and for p_ naming scheme
+ if ( pPresetName[0] == 'p' && pPresetName[1] == '_' )
+ {
+ pPresetName = &pPresetName[2];
+ }
+ if ( !Q_stricmp( pPresetName, "silence" ) )
+ {
+ pPresetName = "<sil>";
+ }
+
+ pSetting[i].nameindex = pData - (byte *)(&pSetting[i]);
+ strcpy( (char *)pData, pPresetName );
+ pData += Q_strlen( pPresetName ) + 1;
+ }
+ ALIGN4( pData );
+
+ // store key names
+ char **pKeynames = (char **)pData;
+ fhdr->numkeys = nTotalControlCount;
+ fhdr->keynameindex = pData - pDataStart;
+ pData += sizeof(char *) * nTotalControlCount;
+ int j = 0;
+ for ( i = 0; i < nExportedControlCount; ++i )
+ {
+ char pTempBuf[MAX_PATH];
+
+ ExportedControl_t &control = exportedControls[i];
+ if ( !control.m_bIsStereo )
+ {
+ pKeynames[j++] = (char *)(pData - pDataStart);
+ strcpy( (char *)pData, control.m_Name );
+ pData += Q_strlen( control.m_Name ) + 1;
+ }
+ else
+ {
+ pKeynames[j++] = (char *)(pData - pDataStart);
+ Q_snprintf( pTempBuf, sizeof(pTempBuf), "right_%s", control.m_Name.Get() );
+ strcpy( (char *)pData, pTempBuf );
+ pData += Q_strlen( pTempBuf ) + 1;
+
+ pKeynames[j++] = (char *)(pData - pDataStart);
+ Q_snprintf( pTempBuf, sizeof(pTempBuf), "left_%s", control.m_Name.Get() );
+ strcpy( (char *)pData, pTempBuf );
+ pData += Q_strlen( pTempBuf ) + 1;
+ }
+
+ if ( control.m_bIsMulti )
+ {
+ pKeynames[j++] = (char *)(pData - pDataStart);
+ Q_snprintf( pTempBuf, sizeof(pTempBuf), "multi_%s", control.m_Name.Get() );
+ strcpy( (char *)pData, pTempBuf );
+ pData += Q_strlen( pTempBuf ) + 1;
+ }
+ }
+ Assert( j == nTotalControlCount );
+ ALIGN4( pData );
+
+ // allocate room for remapping
+ int *keymapping = (int *)pData;
+ fhdr->keymappingindex = pData - pDataStart;
+ pData += sizeof( int ) * nTotalControlCount;
+ for (i = 0; i < nTotalControlCount; i++)
+ {
+ keymapping[i] = -1;
+ }
+ ALIGN4( pData );
+
+ fhdr->length = pData - pDataStart;
+
+ FileHandle_t fh = g_pFullFileSystem->Open( pFileName, "wb" );
+ if ( !fh )
+ {
+ ConWarning( "Unable to write to %s (read-only?)\n", pFileName );
+ free( pDataStart );
+ return false;
+ }
+
+ g_pFullFileSystem->Write( pDataStart, fhdr->length, fh );
+ g_pFullFileSystem->Close( fh );
+ free( pDataStart );
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Constructor, destructor
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// CDmeAnimationSet - container for animation set info
+//-----------------------------------------------------------------------------
+IMPLEMENT_ELEMENT_FACTORY( DmeAnimationSet, CDmeAnimationSet );
+
+void CDmeAnimationSet::OnConstruction()
+{
+ m_Controls.Init( this, "controls" );
+ m_PresetGroups.Init( this, "presetGroups" );
+ m_SelectionGroups.Init( this, "selectionGroups" );
+ m_PhonemeMap.Init( this, "phonememap" );
+ m_Operators.Init( this, "operators" );
+ m_Bookmarks.Init( this, "bookmarks" );
+}
+
+void CDmeAnimationSet::OnDestruction()
+{
+}
+
+CDmaElementArray< CDmElement > &CDmeAnimationSet::GetControls()
+{
+ return m_Controls;
+}
+
+CDmaElementArray< CDmePresetGroup > &CDmeAnimationSet::GetPresetGroups()
+{
+ return m_PresetGroups;
+}
+
+CDmaElementArray< CDmeOperator > &CDmeAnimationSet::GetOperators()
+{
+ return m_Operators;
+}
+
+void CDmeAnimationSet::AddOperator( CDmeOperator *pOperator )
+{
+ m_Operators.AddToTail( pOperator );
+}
+
+void CDmeAnimationSet::RemoveOperator( CDmeOperator *pOperator )
+{
+ int nCount = m_Operators.Count();
+ for ( int i = 0; i < nCount; ++i )
+ {
+ if ( m_Operators[i] == pOperator )
+ {
+ m_Operators.Remove(i);
+ break;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Finds the index of a particular preset group
+//-----------------------------------------------------------------------------
+void CDmeAnimationSet::OnElementUnserialized()
+{
+ BaseClass::OnElementUnserialized();
+
+ CDmeGameModel *pGameModel = GetValueElement< CDmeGameModel >( "gameModel" );
+ if ( pGameModel )
+ {
+ // NOTE: The model preset manager can't possibly have the right
+ // file id at this point; it's up to the preset group manager to queue
+ // application requests until it gets one
+ g_pModelPresetGroupMgr->ApplyModelPresets( pGameModel->GetModelName(), this );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Finds the index of a particular preset group
+//-----------------------------------------------------------------------------
+int CDmeAnimationSet::FindPresetGroupIndex( CDmePresetGroup *pPresetGroup )
+{
+ int c = m_PresetGroups.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ CDmePresetGroup *e = m_PresetGroups.Get( i );
+ if ( pPresetGroup == e )
+ return i;
+ }
+ return -1;
+}
+
+int CDmeAnimationSet::FindPresetGroupIndex( const char *pGroupName )
+{
+ int c = m_PresetGroups.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ CDmePresetGroup *e = m_PresetGroups.Get( i );
+ if ( e && !Q_stricmp( e->GetName(), pGroupName ) )
+ return i;
+ }
+ return -1;
+}
+
+
+//-----------------------------------------------------------------------------
+// Find by name
+//-----------------------------------------------------------------------------
+CDmePresetGroup *CDmeAnimationSet::FindPresetGroup( const char *pGroupName )
+{
+ int nIndex = FindPresetGroupIndex( pGroupName );
+ if ( nIndex >= 0 )
+ return m_PresetGroups[nIndex];
+ return NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Find or add by name
+//-----------------------------------------------------------------------------
+CDmePresetGroup *CDmeAnimationSet::FindOrAddPresetGroup( const char *pGroupName )
+{
+ CDmePresetGroup *pPresetGroup = FindPresetGroup( pGroupName );
+ if ( !pPresetGroup )
+ {
+ // Create the default groups in order
+ pPresetGroup = CreateElement< CDmePresetGroup >( pGroupName, GetFileId() );
+ m_PresetGroups.AddToTail( pPresetGroup );
+ }
+ return pPresetGroup;
+}
+
+
+//-----------------------------------------------------------------------------
+// Remove preset group
+//-----------------------------------------------------------------------------
+bool CDmeAnimationSet::RemovePresetGroup( CDmePresetGroup *pPresetGroup )
+{
+ int i = FindPresetGroupIndex( pPresetGroup );
+ if ( i >= 0 )
+ {
+ m_PresetGroups.Remove( i );
+ return true;
+ }
+ return false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Move preset group up/down in the list
+//-----------------------------------------------------------------------------
+void CDmeAnimationSet::MovePresetGroupUp( CDmePresetGroup *pPresetGroup )
+{
+ int i = FindPresetGroupIndex( pPresetGroup );
+ if ( i >= 1 )
+ {
+ m_PresetGroups.Swap( i, i-1 );
+ }
+}
+
+void CDmeAnimationSet::MovePresetGroupDown( CDmePresetGroup *pPresetGroup )
+{
+ int i = FindPresetGroupIndex( pPresetGroup );
+ if ( i >= 0 && i < m_PresetGroups.Count() - 1 )
+ {
+ m_PresetGroups.Swap( i, i+1 );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Reorder preset groups
+//-----------------------------------------------------------------------------
+void CDmeAnimationSet::MovePresetGroupInFrontOf( CDmePresetGroup *pPresetGroup, CDmePresetGroup *pInFrontOf )
+{
+ if ( pPresetGroup == pInFrontOf )
+ return;
+
+#ifdef DBGFLAG_ASSERT
+ int nStart = FindPresetGroupIndex( pPresetGroup );
+#endif
+
+ int nEnd = pInFrontOf ? FindPresetGroupIndex( pInFrontOf ) : m_PresetGroups.Count();
+ Assert( nStart >= 0 && nEnd >= 0 );
+
+ RemovePresetGroup( pPresetGroup );
+ if ( nEnd > m_PresetGroups.Count() )
+ {
+ nEnd = m_PresetGroups.Count();
+ }
+ m_PresetGroups.InsertBefore( nEnd, pPresetGroup );
+}
+
+
+CDmePreset *CDmeAnimationSet::FindOrAddPreset( const char *pGroupName, const char *pPresetName, int nType /*=PROCEDURAL_PRESET_NOT*/ )
+{
+ CDmePresetGroup *pPresetGroup = FindOrAddPresetGroup( pGroupName );
+ return pPresetGroup->FindOrAddPreset( pPresetName, nType );
+}
+
+bool CDmeAnimationSet::RemovePreset( CDmePreset *pPreset )
+{
+ int c = m_PresetGroups.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ if ( m_PresetGroups[i]->RemovePreset( pPreset ) )
+ return true;
+ }
+ return false;
+}
+
+
+const CDmaElementArray< CDmeBookmark > &CDmeAnimationSet::GetBookmarks() const
+{
+ return m_Bookmarks;
+}
+
+CDmaElementArray< CDmeBookmark > &CDmeAnimationSet::GetBookmarks()
+{
+ return m_Bookmarks;
+}
+
+
+CDmaElementArray< CDmElement > &CDmeAnimationSet::GetSelectionGroups()
+{
+ return m_SelectionGroups;
+}
+
+CDmaElementArray< CDmePhonemeMapping > &CDmeAnimationSet::GetPhonemeMap()
+{
+ return m_PhonemeMap;
+}
+
+void CDmeAnimationSet::RestoreDefaultPhonemeMap()
+{
+ CUndoScopeGuard guard( "RestoreDefaultPhonemeMap" );
+
+ int i;
+ int c = m_PhonemeMap.Count();
+ for ( i = 0; i < c; ++i )
+ {
+ g_pDataModel->DestroyElement( m_PhonemeMap[ i ]->GetHandle() );
+ }
+ m_PhonemeMap.Purge();
+
+ int phonemeCount = NumPhonemes();
+ for ( i = 0; i < phonemeCount; ++i )
+ {
+ const char *pName = NameForPhonemeByIndex( i );
+ CDmePhonemeMapping *mapping = CreateElement< CDmePhonemeMapping >( pName, GetFileId() );
+ char presetName[ 256 ];
+ Q_snprintf( presetName, sizeof( presetName ), "p_%s", pName );
+ mapping->m_Preset = presetName;
+ mapping->m_Weight = 1.0f;
+
+ m_PhonemeMap.AddToTail( mapping );
+ }
+}
+
+CDmePhonemeMapping *CDmeAnimationSet::FindMapping( const char *pRawPhoneme )
+{
+ int c = m_PhonemeMap.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ CDmePhonemeMapping *e = m_PhonemeMap.Get( i );
+ Assert( e );
+ if ( !e )
+ continue;
+
+ if ( !Q_stricmp( e->GetName(), pRawPhoneme ) )
+ return e;
+ }
+ return NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Finds a control
+//-----------------------------------------------------------------------------
+CDmElement *CDmeAnimationSet::FindControl( const char *pControlName )
+{
+ int c = m_Controls.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ CDmElement *e = m_Controls.Get( i );
+ if ( !Q_stricmp( e->GetName(), pControlName ) )
+ return e;
+ }
+ return NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Finds or adds a control
+//-----------------------------------------------------------------------------
+CDmElement *CDmeAnimationSet::FindOrAddControl( const char *pControlName )
+{
+ CDmElement *pControl = FindControl( pControlName );
+ if ( !pControl )
+ {
+ // If not, then create one
+ pControl = CreateElement< CDmElement >( pControlName, GetFileId() );
+ m_Controls.AddToTail( pControl );
+ }
+ return pControl;
+}
+
+
+CDmElement *CDmeAnimationSet::FindSelectionGroup( const char *pSelectionGroupName )
+{
+ int c = m_SelectionGroups.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ CDmElement *e = m_SelectionGroups.Get( i );
+ if ( !Q_stricmp( e->GetName(), pSelectionGroupName ) )
+ return e;
+ }
+ return NULL;
+}
+
+CDmElement *CDmeAnimationSet::FindOrAddSelectionGroup( const char *pSelectionGroupName )
+{
+ CDmElement *pSelectionGroup = FindSelectionGroup( pSelectionGroupName );
+ if ( !pSelectionGroup )
+ {
+ // Create the default groups in order
+ pSelectionGroup = CreateElement< CDmElement >( pSelectionGroupName, GetFileId() );
+ pSelectionGroup->AddAttribute( "selectedControls", AT_STRING_ARRAY );
+ m_SelectionGroups.AddToTail( pSelectionGroup );
+ }
+ return pSelectionGroup;
+}
+
+void CDmeAnimationSet::CollectOperators( CUtlVector< DmElementHandle_t > &operators )
+{
+ int numOperators = m_Operators.Count();
+ for ( int i = 0; i < numOperators; ++i )
+ {
+ DmElementHandle_t h = m_Operators.GetHandle( i );
+ if ( h != DMELEMENT_HANDLE_INVALID )
+ {
+ operators.AddToTail( h );
+ }
+ }
+}
+
+struct PPType_t
+{
+ int type;
+ char const *name;
+};
+
+static PPType_t g_PresetNames[ NUM_PROCEDURAL_PRESET_TYPES ] =
+{
+ { PROCEDURAL_PRESET_NOT, "NotProcedural!!!" },
+ { PROCEDURAL_PRESET_IN_CROSSFADE, "In" },
+ { PROCEDURAL_PRESET_OUT_CROSSFADE, "Out" },
+ { PROCEDURAL_PRESET_REVEAL, "Reveal" },
+ { PROCEDURAL_PRESET_PASTE, "Paste" },
+ { PROCEDURAL_PRESET_JITTER, "Jitter" },
+ { PROCEDURAL_PRESET_SMOOTH, "Smooth" },
+ { PROCEDURAL_PRESET_SHARPEN, "Sharpen" },
+ { PROCEDURAL_PRESET_SOFTEN, "Soften" },
+ { PROCEDURAL_PRESET_STAGGER, "Stagger" },
+};
+
+void CDmeAnimationSet::EnsureProceduralPresets()
+{
+ // Note: Starts at index 1 to skip the PROCEDURAL_PRESET_NOT case
+ for ( int i = 1; i < NUM_PROCEDURAL_PRESET_TYPES; ++i )
+ {
+ FindOrAddPreset( "Procedural", g_PresetNames[ i ].name, g_PresetNames[ i ].type );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// A cache of preset groups to be associated with specific models
+//-----------------------------------------------------------------------------
+class CModelPresetGroupManager : public IModelPresetGroupManager
+{
+public:
+ CModelPresetGroupManager();
+ virtual void AssociatePresetsWithFile( DmFileId_t fileId );
+ virtual void ApplyModelPresets( const char *pModelName, CDmeAnimationSet *pAnimationSet );
+
+private:
+ struct QueuedPresetRequest_t
+ {
+ CUtlString m_ModelName;
+ CDmeHandle< CDmeAnimationSet > m_hAnimationSet;
+ };
+
+ typedef CUtlVector< CDmeHandle< CDmePresetGroup, true > > PresetGroupList_t;
+
+ // Loads model presets from .pre files matching the model name
+ void LoadModelPresets( const char *pModelName, PresetGroupList_t &list );
+
+ CUtlStringMap< PresetGroupList_t > m_Lookup;
+ DmFileId_t m_FileId;
+ CUtlVector< QueuedPresetRequest_t > m_QueuedPresetRequest;
+};
+
+
+//-----------------------------------------------------------------------------
+// Singleton
+//-----------------------------------------------------------------------------
+static CModelPresetGroupManager s_ModelPresetGroupManager;
+IModelPresetGroupManager *g_pModelPresetGroupMgr = &s_ModelPresetGroupManager;
+
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+CModelPresetGroupManager::CModelPresetGroupManager()
+{
+ m_FileId = DMFILEID_INVALID;
+}
+
+
+//-----------------------------------------------------------------------------
+// Associates presets in the cache with a particular file
+//-----------------------------------------------------------------------------
+void CModelPresetGroupManager::AssociatePresetsWithFile( DmFileId_t fileId )
+{
+ m_FileId = fileId;
+ m_Lookup.Clear();
+ if ( m_FileId != DMFILEID_INVALID )
+ {
+ int nCount = m_QueuedPresetRequest.Count();
+ for ( int i = 0; i < nCount; ++i )
+ {
+ QueuedPresetRequest_t &request = m_QueuedPresetRequest[i];
+ if ( request.m_hAnimationSet.Get() )
+ {
+ ApplyModelPresets( request.m_ModelName, request.m_hAnimationSet.Get() );
+ }
+ }
+ m_QueuedPresetRequest.Purge();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Loads model presets from .pre files matching the model name
+//-----------------------------------------------------------------------------
+void CModelPresetGroupManager::LoadModelPresets( const char *pModelName, PresetGroupList_t &list )
+{
+ list.RemoveAll();
+
+ char pPresetPath[MAX_PATH];
+ Q_ExtractFilePath( pModelName, pPresetPath, sizeof(pPresetPath) );
+
+ char pPresetNameBuf[MAX_PATH];
+ Q_StripExtension( pModelName, pPresetNameBuf, sizeof(pPresetNameBuf) );
+ int nLen = Q_strlen( pPresetNameBuf );
+ Q_snprintf( &pPresetNameBuf[nLen], MAX_PATH - nLen, "*.pre" );
+
+ CDisableUndoScopeGuard sg;
+
+ FileFindHandle_t fh;
+ const char *pFileName = g_pFullFileSystem->FindFirstEx( pPresetNameBuf, "GAME", &fh );
+ for ( ; pFileName; pFileName = g_pFullFileSystem->FindNext( fh ) )
+ {
+ char pRelativePresetPath[MAX_PATH];
+ Q_ComposeFileName(pPresetPath, pFileName, pRelativePresetPath, sizeof(pRelativePresetPath) );
+
+ CDmElement* pRoot = NULL;
+ DmFileId_t fileid = g_pDataModel->RestoreFromFile( pRelativePresetPath, "GAME", NULL, &pRoot, CR_FORCE_COPY );
+ if ( fileid == DMFILEID_INVALID || !pRoot )
+ continue;
+
+ CDmePresetGroup *pPresetGroup = CastElement<CDmePresetGroup>( pRoot );
+ if ( !pPresetGroup )
+ {
+ if ( pRoot )
+ {
+ g_pDataModel->RemoveFileId( pRoot->GetFileId() );
+ }
+ continue;
+ }
+
+ pPresetGroup->SetFileId( m_FileId, TD_DEEP );
+
+ // Presets used through the model preset manager must be read only + shared
+ pPresetGroup->m_bIsReadOnly = true;
+ pPresetGroup->SetShared( true );
+
+ int i = list.AddToTail();
+ list[i] = pPresetGroup;
+ }
+ g_pFullFileSystem->FindClose( fh );
+}
+
+
+//-----------------------------------------------------------------------------
+// Applies model presets associated with a particular model to an animation set
+//-----------------------------------------------------------------------------
+void CModelPresetGroupManager::ApplyModelPresets( const char *pModelName, CDmeAnimationSet *pAnimationSet )
+{
+ if ( m_FileId == DMFILEID_INVALID )
+ {
+ int i = m_QueuedPresetRequest.AddToTail();
+ m_QueuedPresetRequest[i].m_ModelName = pModelName;
+ m_QueuedPresetRequest[i].m_hAnimationSet = pAnimationSet;
+ return;
+ }
+
+ if ( !m_Lookup.Defined( pModelName ) )
+ {
+ LoadModelPresets( pModelName, m_Lookup[pModelName] );
+ }
+
+ PresetGroupList_t &list = m_Lookup[pModelName];
+ int nCount = list.Count();
+ for ( int i = 0; i < nCount; ++i )
+ {
+ CDmePresetGroup *pPresetGroup = list[i];
+ int nIndex = pAnimationSet->FindPresetGroupIndex( pPresetGroup->GetName() );
+ if ( nIndex >= 0 )
+ {
+ pAnimationSet->GetPresetGroups().Set( nIndex, pPresetGroup );
+ }
+ else
+ {
+ pAnimationSet->GetPresetGroups().AddToTail( pPresetGroup );
+ }
+ }
+}