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.
598 lines
20 KiB
598 lines
20 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//============================================================================= |
|
|
|
#include "movieobjects/dmeparticlesystemdefinition.h" |
|
#include "datamodel/dmelementfactoryhelper.h" |
|
#include "movieobjects/dmeeditortypedictionary.h" |
|
#include "toolutils/enginetools_int.h" |
|
#include "tier1/KeyValues.h" |
|
#include "tier1/utlbuffer.h" |
|
#include "tier1/convar.h" |
|
#include "particles/particles.h" |
|
#include "dme_controls/attributeintchoicepanel.h" |
|
#include "dme_controls/attributeboolchoicepanel.h" |
|
#include "dme_controls/attributestringchoicepanel.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Human readable string for the particle functions |
|
//----------------------------------------------------------------------------- |
|
static const char *s_pParticleFuncTypeName[PARTICLE_FUNCTION_COUNT] = |
|
{ |
|
"Renderer", // FUNCTION_RENDERER = 0, |
|
"Operator", // FUNCTION_OPERATOR, |
|
"Initializer", // FUNCTION_INITIALIZER, |
|
"Emitter", // FUNCTION_EMITTER, |
|
"Children", // FUNCTION_CHILDREN, |
|
"ForceGenerator", // FUNCTION_FORCEGENERATOR |
|
"Constraint", // FUNCTION_CONSTRAINT |
|
}; |
|
|
|
const char *GetParticleFunctionTypeName( ParticleFunctionType_t type ) |
|
{ |
|
return s_pParticleFuncTypeName[type]; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Expose this class to the scene database |
|
//----------------------------------------------------------------------------- |
|
IMPLEMENT_ELEMENT_FACTORY_INSTALL_EXPLICITLY( DmeParticleFunction, CDmeParticleFunction ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CDmeParticleFunction::OnConstruction() |
|
{ |
|
m_bSkipNextResolve = false; |
|
} |
|
|
|
void CDmeParticleFunction::OnDestruction() |
|
{ |
|
DestroyElement( m_hTypeDictionary, TD_DEEP ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Construct an appropriate editor attribute info |
|
//----------------------------------------------------------------------------- |
|
static void CreateEditorAttributeInfo( CDmeEditorType *pEditorType, const char *pAttributeName, const char *pWidgetInfo ) |
|
{ |
|
if ( !pWidgetInfo ) |
|
return; |
|
|
|
CCommand parse; |
|
parse.Tokenize( pWidgetInfo ); |
|
if ( parse.ArgC() == 1 ) |
|
{ |
|
CDmeEditorAttributeInfo *pInfo = CreateElement< CDmeEditorAttributeInfo >( "field info" ); |
|
pEditorType->AddAttributeInfo( pAttributeName, pInfo ); |
|
pInfo->m_Widget = parse[0]; |
|
return; |
|
} |
|
|
|
if ( parse.ArgC() == 2 ) |
|
{ |
|
CDmeEditorChoicesInfo *pInfo = NULL; |
|
if ( !Q_stricmp( parse[0], "intchoice" ) ) |
|
{ |
|
pInfo = CreateElement< CDmeEditorIntChoicesInfo >( "field info" ); |
|
} |
|
|
|
if ( !Q_stricmp( parse[0], "boolchoice" ) ) |
|
{ |
|
pInfo = CreateElement< CDmeEditorBoolChoicesInfo >( "field info" ); |
|
} |
|
|
|
if ( !Q_stricmp( parse[0], "stringchoice" ) ) |
|
{ |
|
pInfo = CreateElement< CDmeEditorStringChoicesInfo >( "field info" ); |
|
} |
|
|
|
if ( !Q_stricmp( parse[0], "elementchoice" ) ) |
|
{ |
|
pInfo = CreateElement< CDmeEditorChoicesInfo >( "field info" ); |
|
} |
|
|
|
if ( pInfo ) |
|
{ |
|
pInfo->SetChoiceType( parse[1] ); |
|
pEditorType->AddAttributeInfo( pAttributeName, pInfo ); |
|
pInfo->m_Widget = parse[0]; |
|
return; |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Used for backward compat |
|
//----------------------------------------------------------------------------- |
|
void CDmeParticleFunction::AddMissingFields( const DmxElementUnpackStructure_t *pUnpack ) |
|
{ |
|
DestroyElement( m_hTypeDictionary, TD_DEEP ); |
|
m_hTypeDictionary = CreateElement< CDmeEditorTypeDictionary >( "particleFunctionDict" ); |
|
CDmeEditorType *pEditorType = CreateElement< CDmeEditorType >( GetTypeString() ); |
|
|
|
for ( ; pUnpack->m_pAttributeName; ++pUnpack ) |
|
{ |
|
CreateEditorAttributeInfo( pEditorType, pUnpack->m_pAttributeName, (const char *)pUnpack->m_pUserData ); |
|
|
|
// Can happen if 'name' or 'functionName' is used |
|
if ( HasAttribute( pUnpack->m_pAttributeName ) ) |
|
continue; |
|
|
|
CDmAttribute *pAttribute = AddAttribute( pUnpack->m_pAttributeName, pUnpack->m_AttributeType ); |
|
if ( pUnpack->m_pDefaultString ) |
|
{ |
|
int nLen = Q_strlen( pUnpack->m_pDefaultString ); |
|
CUtlBuffer bufParse( pUnpack->m_pDefaultString, nLen, CUtlBuffer::TEXT_BUFFER | CUtlBuffer::READ_ONLY ); |
|
pAttribute->Unserialize( bufParse ); |
|
} |
|
} |
|
|
|
m_hTypeDictionary->AddEditorType( pEditorType ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the particle operator |
|
//----------------------------------------------------------------------------- |
|
void CDmeParticleFunction::UpdateAttributes( const DmxElementUnpackStructure_t *pUnpack ) |
|
{ |
|
// Delete all old attributes |
|
CDmAttribute *pNext; |
|
for( CDmAttribute *pAttr = FirstAttribute(); pAttr; pAttr = pNext ) |
|
{ |
|
pNext = pAttr->NextAttribute(); |
|
if ( pAttr->IsFlagSet( FATTRIB_EXTERNAL | FATTRIB_STANDARD ) ) |
|
continue; |
|
|
|
RemoveAttributeByPtr( pAttr ); |
|
} |
|
|
|
AddMissingFields( pUnpack ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Marks a particle system as a new instance |
|
// This is basically a workaround to prevent newly-copied particle functions |
|
// from recompiling themselves a zillion times |
|
//----------------------------------------------------------------------------- |
|
void CDmeParticleFunction::MarkNewInstance() |
|
{ |
|
m_bSkipNextResolve = true; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Don't bother resolving during unserialization, the owning def will handle it |
|
//----------------------------------------------------------------------------- |
|
void CDmeParticleFunction::OnElementUnserialized() |
|
{ |
|
BaseClass::OnElementUnserialized(); |
|
MarkNewInstance(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Recompiles the particle system when a change occurs |
|
//----------------------------------------------------------------------------- |
|
void CDmeParticleFunction::Resolve() |
|
{ |
|
BaseClass::Resolve(); |
|
|
|
if ( m_bSkipNextResolve ) |
|
{ |
|
m_bSkipNextResolve = false; |
|
return; |
|
} |
|
|
|
for( CDmAttribute* pAttr = FirstAttribute(); pAttr; pAttr = pAttr->NextAttribute() ) |
|
{ |
|
if ( !pAttr->IsFlagSet( FATTRIB_DIRTY ) ) |
|
continue; |
|
|
|
// Find all CDmeParticleSystemDefinitions referring to this function |
|
DmAttributeReferenceIterator_t i = g_pDataModel->FirstAttributeReferencingElement( GetHandle() ); |
|
while ( i != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID ) |
|
{ |
|
CDmAttribute *pAttribute = g_pDataModel->GetAttribute( i ); |
|
|
|
// NOTE: This could cause the same particle system definition to recompile |
|
// multiple times if it refers to the same function multiple times, |
|
// but we don't expect that to happen, so we won't bother checking for it |
|
CDmeParticleSystemDefinition *pDef = CastElement<CDmeParticleSystemDefinition>( pAttribute->GetOwner() ); |
|
if ( pDef && pDef->GetFileId() == GetFileId() ) |
|
{ |
|
pDef->RecompileParticleSystem(); |
|
} |
|
i = g_pDataModel->NextAttributeReferencingElement( i ); |
|
} |
|
break; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns the editor type dictionary |
|
//----------------------------------------------------------------------------- |
|
CDmeEditorTypeDictionary* CDmeParticleFunction::GetEditorTypeDictionary() |
|
{ |
|
return m_hTypeDictionary; |
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Expose this class to the scene database |
|
//----------------------------------------------------------------------------- |
|
IMPLEMENT_ELEMENT_FACTORY_INSTALL_EXPLICITLY( DmeParticleOperator, CDmeParticleOperator ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Constructor, destructor |
|
//----------------------------------------------------------------------------- |
|
void CDmeParticleOperator::OnConstruction() |
|
{ |
|
m_FunctionName.Init( this, "functionName" ); |
|
} |
|
|
|
void CDmeParticleOperator::OnDestruction() |
|
{ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the particle operator |
|
//----------------------------------------------------------------------------- |
|
void CDmeParticleOperator::SetFunction( IParticleOperatorDefinition *pDefinition ) |
|
{ |
|
m_FunctionName = pDefinition->GetName(); |
|
const DmxElementUnpackStructure_t *pUnpack = pDefinition->GetUnpackStructure(); |
|
UpdateAttributes( pUnpack ); |
|
} |
|
|
|
const char *CDmeParticleOperator::GetFunctionType() const |
|
{ |
|
return m_FunctionName; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Expose this class to the scene database |
|
//----------------------------------------------------------------------------- |
|
IMPLEMENT_ELEMENT_FACTORY_INSTALL_EXPLICITLY( DmeParticleChild, CDmeParticleChild ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Constructor, destructor |
|
//----------------------------------------------------------------------------- |
|
void CDmeParticleChild::OnConstruction() |
|
{ |
|
m_Child.Init( this, "child", FATTRIB_NEVERCOPY ); |
|
} |
|
|
|
void CDmeParticleChild::OnDestruction() |
|
{ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the particle system child |
|
//----------------------------------------------------------------------------- |
|
void CDmeParticleChild::SetChildParticleSystem( CDmeParticleSystemDefinition *pDef, IParticleOperatorDefinition *pDefinition ) |
|
{ |
|
// FIXME: Convert system name into a |
|
m_Child = pDef; |
|
const DmxElementUnpackStructure_t *pUnpack = pDefinition->GetUnpackStructure(); |
|
UpdateAttributes( pUnpack ); |
|
} |
|
|
|
const char *CDmeParticleChild::GetFunctionType() const |
|
{ |
|
const CDmeParticleSystemDefinition *pChild = m_Child; |
|
return pChild ? pChild->GetName() : ""; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Expose this class to the scene database |
|
//----------------------------------------------------------------------------- |
|
IMPLEMENT_ELEMENT_FACTORY_INSTALL_EXPLICITLY( DmeParticleSystemDefinition, CDmeParticleSystemDefinition ); |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CDmeParticleSystemDefinition::OnConstruction() |
|
{ |
|
m_ParticleFunction[FUNCTION_RENDERER].Init( this, "renderers" ); |
|
m_ParticleFunction[FUNCTION_OPERATOR].Init( this, "operators" ); |
|
m_ParticleFunction[FUNCTION_INITIALIZER].Init( this, "initializers" ); |
|
m_ParticleFunction[FUNCTION_EMITTER].Init( this, "emitters" ); |
|
m_ParticleFunction[FUNCTION_CHILDREN].Init( this, "children" ); |
|
m_ParticleFunction[FUNCTION_FORCEGENERATOR].Init( this, "forces" ); |
|
m_ParticleFunction[FUNCTION_CONSTRAINT].Init( this, "constraints" ); |
|
m_bPreventNameBasedLookup.Init( this, "preventNameBasedLookup" ); |
|
|
|
m_hTypeDictionary = CreateElement< CDmeEditorTypeDictionary >( "particleSystemDefinitionDict" ); |
|
CDmeEditorType *pEditorType = CreateElement< CDmeEditorType >( "DmeParticleSystemDefinition" ); |
|
|
|
const DmxElementUnpackStructure_t *pUnpack = g_pParticleSystemMgr->GetParticleSystemDefinitionUnpackStructure(); |
|
for ( ; pUnpack->m_pAttributeName; ++pUnpack ) |
|
{ |
|
CreateEditorAttributeInfo( pEditorType, pUnpack->m_pAttributeName, (const char *)pUnpack->m_pUserData ); |
|
|
|
CDmAttribute *pAttribute = AddAttribute( pUnpack->m_pAttributeName, pUnpack->m_AttributeType ); |
|
if ( pUnpack->m_pDefaultString ) |
|
{ |
|
int nLen = Q_strlen( pUnpack->m_pDefaultString ); |
|
CUtlBuffer bufParse( pUnpack->m_pDefaultString, nLen, CUtlBuffer::TEXT_BUFFER | CUtlBuffer::READ_ONLY ); |
|
pAttribute->Unserialize( bufParse ); |
|
} |
|
} |
|
|
|
m_hTypeDictionary->AddEditorType( pEditorType ); |
|
} |
|
|
|
void CDmeParticleSystemDefinition::OnDestruction() |
|
{ |
|
DestroyElement( m_hTypeDictionary, TD_DEEP ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns the editor type dictionary |
|
//----------------------------------------------------------------------------- |
|
CDmeEditorTypeDictionary* CDmeParticleSystemDefinition::GetEditorTypeDictionary() |
|
{ |
|
return m_hTypeDictionary; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Remove obsolete attributes |
|
//----------------------------------------------------------------------------- |
|
static void RemoveObsoleteAttributes( CDmElement *pElement, const DmxElementUnpackStructure_t *pUnpack ) |
|
{ |
|
// Delete all obsolete attributes |
|
CDmAttribute *pNext; |
|
for( CDmAttribute *pAttr = pElement->FirstAttribute(); pAttr; pAttr = pNext ) |
|
{ |
|
pNext = pAttr->NextAttribute(); |
|
if ( pAttr->IsFlagSet( FATTRIB_EXTERNAL | FATTRIB_STANDARD ) ) |
|
continue; |
|
|
|
bool bFound = false; |
|
for ( const DmxElementUnpackStructure_t *pTrav = pUnpack; pTrav->m_pAttributeName; ++pTrav ) |
|
{ |
|
if ( !Q_stricmp( pTrav->m_pAttributeName, pAttr->GetName() ) ) |
|
{ |
|
bFound = true; |
|
break; |
|
} |
|
} |
|
|
|
if ( !bFound ) |
|
{ |
|
pElement->RemoveAttributeByPtr( pAttr ); |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Used for automatic handling of backward compatability |
|
//----------------------------------------------------------------------------- |
|
void CDmeParticleSystemDefinition::OnElementUnserialized() |
|
{ |
|
BaseClass::OnElementUnserialized(); |
|
|
|
RemoveObsoleteAttributes( this, g_pParticleSystemMgr->GetParticleSystemDefinitionUnpackStructure() ); |
|
|
|
// Add missing fields that are new |
|
for ( int i = 0; i < PARTICLE_FUNCTION_COUNT; ++i ) |
|
{ |
|
ParticleFunctionType_t type = (ParticleFunctionType_t)i; |
|
CUtlVector< IParticleOperatorDefinition *> &list = g_pParticleSystemMgr->GetAvailableParticleOperatorList( type ); |
|
int nAvailType = list.Count(); |
|
int nCount = GetParticleFunctionCount( type ); |
|
for ( int j = 0; j < nCount; ++j ) |
|
{ |
|
CDmeParticleFunction *pFunction = GetParticleFunction( type, j ); |
|
|
|
if ( i == FUNCTION_CHILDREN ) |
|
{ |
|
RemoveObsoleteAttributes( pFunction, list[0]->GetUnpackStructure() ); |
|
pFunction->AddMissingFields( list[0]->GetUnpackStructure() ); |
|
continue; |
|
} |
|
|
|
for ( int k = 0; k < nAvailType; ++k ) |
|
{ |
|
if ( Q_stricmp( pFunction->GetName(), list[k]->GetName() ) ) |
|
continue; |
|
|
|
RemoveObsoleteAttributes( pFunction, list[k]->GetUnpackStructure() ); |
|
pFunction->AddMissingFields( list[k]->GetUnpackStructure() ); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Check to see if any attributes changed |
|
//----------------------------------------------------------------------------- |
|
void CDmeParticleSystemDefinition::Resolve() |
|
{ |
|
BaseClass::Resolve(); |
|
for( CDmAttribute* pAttr = FirstAttribute(); pAttr; pAttr = pAttr->NextAttribute() ) |
|
{ |
|
if ( pAttr->IsFlagSet( FATTRIB_DIRTY ) ) |
|
{ |
|
RecompileParticleSystem(); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Add, remove |
|
//----------------------------------------------------------------------------- |
|
CDmeParticleFunction* CDmeParticleSystemDefinition::AddOperator( ParticleFunctionType_t type, const char *pFunctionName ) |
|
{ |
|
CUtlVector< IParticleOperatorDefinition *> &list = g_pParticleSystemMgr->GetAvailableParticleOperatorList( type ); |
|
|
|
int nCount = list.Count(); |
|
for ( int i = 0; i < nCount; ++i ) |
|
{ |
|
if ( Q_stricmp( pFunctionName, list[i]->GetName() ) ) |
|
continue; |
|
|
|
CDmeParticleOperator *pFunction = CreateElement< CDmeParticleOperator >( pFunctionName, GetFileId() ); |
|
m_ParticleFunction[type].AddToTail( pFunction ); |
|
pFunction->SetFunction( list[i] ); |
|
return pFunction; |
|
} |
|
return NULL; |
|
} |
|
|
|
CDmeParticleFunction* CDmeParticleSystemDefinition::AddChild( CDmeParticleSystemDefinition *pChild ) |
|
{ |
|
Assert( pChild ); |
|
|
|
CUtlVector< IParticleOperatorDefinition *> &list = g_pParticleSystemMgr->GetAvailableParticleOperatorList( FUNCTION_CHILDREN ); |
|
Assert( list.Count() == 1 ); |
|
CDmeParticleChild *pFunction = CreateElement< CDmeParticleChild >( pChild->GetName(), GetFileId() ); |
|
m_ParticleFunction[FUNCTION_CHILDREN].AddToTail( pFunction ); |
|
pFunction->SetChildParticleSystem( pChild, list[0] ); |
|
return pFunction; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Remove |
|
void CDmeParticleSystemDefinition::RemoveFunction( ParticleFunctionType_t type, CDmeParticleFunction *pFunction ) |
|
{ |
|
int nIndex = FindFunction( type, pFunction ); |
|
RemoveFunction( type, nIndex ); |
|
} |
|
|
|
void CDmeParticleSystemDefinition::RemoveFunction( ParticleFunctionType_t type, int nIndex ) |
|
{ |
|
if ( nIndex >= 0 ) |
|
{ |
|
m_ParticleFunction[type].Remove(nIndex); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Find |
|
//----------------------------------------------------------------------------- |
|
int CDmeParticleSystemDefinition::FindFunction( ParticleFunctionType_t type, CDmeParticleFunction *pParticleFunction ) |
|
{ |
|
int nCount = m_ParticleFunction[type].Count(); |
|
for ( int i = 0; i < nCount; ++i ) |
|
{ |
|
if ( pParticleFunction == m_ParticleFunction[type][i] ) |
|
return i; |
|
} |
|
return -1; |
|
} |
|
|
|
int CDmeParticleSystemDefinition::FindFunction( ParticleFunctionType_t type, const char *pFunctionName ) |
|
{ |
|
int nCount = m_ParticleFunction[type].Count(); |
|
for ( int i = 0; i < nCount; ++i ) |
|
{ |
|
if ( !Q_stricmp( pFunctionName, m_ParticleFunction[type][i]->GetFunctionType() ) ) |
|
return i; |
|
} |
|
return -1; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Iteration |
|
//----------------------------------------------------------------------------- |
|
int CDmeParticleSystemDefinition::GetParticleFunctionCount( ParticleFunctionType_t type ) const |
|
{ |
|
return m_ParticleFunction[type].Count(); |
|
} |
|
|
|
CDmeParticleFunction *CDmeParticleSystemDefinition::GetParticleFunction( ParticleFunctionType_t type, int nIndex ) |
|
{ |
|
return m_ParticleFunction[type][nIndex]; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Reordering |
|
//----------------------------------------------------------------------------- |
|
void CDmeParticleSystemDefinition::MoveFunctionUp( ParticleFunctionType_t type, CDmeParticleFunction *pElement ) |
|
{ |
|
int nIndex = FindFunction( type, pElement ); |
|
if ( nIndex > 0 ) |
|
{ |
|
m_ParticleFunction[type].Swap( nIndex, nIndex - 1 ); |
|
} |
|
} |
|
|
|
void CDmeParticleSystemDefinition::MoveFunctionDown( ParticleFunctionType_t type, CDmeParticleFunction *pElement ) |
|
{ |
|
int nIndex = FindFunction( type, pElement ); |
|
int nLastIndex = m_ParticleFunction[type].Count() - 1; |
|
if ( nIndex >= 0 && nIndex < nLastIndex ) |
|
{ |
|
m_ParticleFunction[type].Swap( nIndex, nIndex + 1 ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Marks a particle system as a new instance |
|
// This is basically a workaround to prevent newly-copied particle functions |
|
// from recompiling themselves a zillion times |
|
//----------------------------------------------------------------------------- |
|
void CDmeParticleSystemDefinition::MarkNewInstance() |
|
{ |
|
for ( int i = 0; i < PARTICLE_FUNCTION_COUNT; ++i ) |
|
{ |
|
int nCount = m_ParticleFunction[i].Count(); |
|
for ( int j = 0; j < nCount; ++j ) |
|
{ |
|
m_ParticleFunction[i][j]->MarkNewInstance(); |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Recompiles the particle system when a change occurs |
|
//----------------------------------------------------------------------------- |
|
void CDmeParticleSystemDefinition::RecompileParticleSystem() |
|
{ |
|
const char *pFileFormat = "pcf"; |
|
const char *pEncoding = g_pDataModel->GetDefaultEncoding( pFileFormat ); |
|
int nFlags = g_pDataModel->IsEncodingBinary( pEncoding ) ? 0 : CUtlBuffer::TEXT_BUFFER; |
|
CUtlBuffer buf( 0, 0, nFlags ); |
|
if ( g_pDataModel->Serialize( buf, pEncoding, pFileFormat, GetHandle() ) ) |
|
{ |
|
g_pParticleSystemMgr->ReadParticleConfigFile( buf, true, NULL ); |
|
} |
|
} |
|
|
|
|
|
|