123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2013 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "2d/assets/ParticleAssetField.h"
- #ifndef _CORE_MATH_H_
- #include "2d/core/CoreMath.h"
- #endif
- #ifndef _MMATH_H_
- #include "math/mMath.h"
- #endif
- #ifndef _SIMBASE_H_
- #include "sim/simBase.h"
- #endif
- #ifndef _STRINGUNIT_H_
- #include "string/stringUnit.h"
- #endif
- //-----------------------------------------------------------------------------
- static StringTableEntry particleAssetFieldRepeatTimeName = StringTable->insert( "RepeatTime" );
- static StringTableEntry particleAssetFieldMaxTimeName = StringTable->insert( "MaxTime" );
- static StringTableEntry particleAssetFieldMinValueName = StringTable->insert( "MinValue" );
- static StringTableEntry particleAssetFieldMaxValueName = StringTable->insert( "MaxValue" );
- static StringTableEntry particleAssetFieldDefaultValueName = StringTable->insert( "DefaultValue" );
- static StringTableEntry particleAssetFieldValueScaleName = StringTable->insert( "ValueScale" );
- static StringTableEntry particleAssetFieldDataKeysName = StringTable->insert( "Keys" );
- static StringTableEntry particleAssetFieldDataKeyName = StringTable->insert( "Key" );
- static StringTableEntry particleAssetFieldDataKeyTimeName = StringTable->insert( "Time" );
- static StringTableEntry particleAssetFieldDataKeyValueName = StringTable->insert( "Value" );
- ParticleAssetField::DataKey ParticleAssetField::BadDataKey( -1.0f, 0.0f );
- //-----------------------------------------------------------------------------
- ParticleAssetField::ParticleAssetField() :
- mFieldName( StringTable->EmptyString ),
- mRepeatTime( 1.0f ),
- mMaxTime( 1.0f ),
- mMinValue( 0.0f ),
- mMaxValue( 0.0f ),
- mDefaultValue( 1.0f ),
- mValueScale( 1.0f ),
- mValueBoundsDirty( true )
- {
- // Set Vector Associations.
- VECTOR_SET_ASSOCIATION( mDataKeys );
- }
- //-----------------------------------------------------------------------------
- ParticleAssetField::~ParticleAssetField()
- {
- }
- //-----------------------------------------------------------------------------
- void ParticleAssetField::copyTo( ParticleAssetField& field )
- {
- field.mFieldName = mFieldName;
- field.mRepeatTime = mRepeatTime;
- field.mMaxTime = mMaxTime;
- field.mMinValue = mMinValue;
- field.mMaxValue = mMaxValue;
- field.mDefaultValue = mDefaultValue;
- field.mValueScale = mValueScale;
- // Copy data keys.
- field.clearDataKeys();
- for ( S32 i = 0; i < mDataKeys.size(); i++ )
- {
- DataKey key = mDataKeys[i];
- field.addDataKey(key.mTime, key.mValue);
- }
- }
- //-----------------------------------------------------------------------------
- void ParticleAssetField::initialize( const F32 maxTime, const F32 minValue, const F32 maxValue, const F32 defaultValue )
- {
- // Set the value bounds.
- setValueBounds( maxTime, minValue, maxValue, defaultValue );
- // Reset the value bounds dirty flag.
- mValueBoundsDirty = false;
- }
- //-----------------------------------------------------------------------------
- void ParticleAssetField::setValueBounds( F32 maxTime, F32 minValue, F32 maxValue, F32 defaultValue )
- {
- // Check Max Time.
- if ( maxTime <= 0.0f )
- {
- // Warn.
- Con::warnf("ParticleAssetField::setValueBounds() - Max-time '%f' is invalid", maxTime );
- // Set Default Max Time.
- maxTime = 1.0f;
- }
- // Set Max Time.
- mMaxTime = maxTime;
- // Check Value Range Normalisation.
- if ( minValue > maxValue )
- {
- // Warn.
- Con::warnf("ParticleAssetField::setValueBounds() - Value Range is not normalised! (minValue:%f / maxValue:%f)", minValue, maxValue );
- // Normalise Y-Axis.
- F32 temp = minValue;
- minValue = maxValue;
- maxValue = temp;
- }
- // Check Value Range Scale.
- else if ( minValue == maxValue )
- {
- // Warn.
- Con::warnf("ParticleAssetField::setValueBounds() - Value Range has no scale! (minValue:%f / maxValue:%f)", minValue, maxValue );
- // Insert some Y-Axis Scale.
- maxValue = minValue + 0.001f;
- }
- // Set Bounds.
- mMinValue = minValue;
- mMaxValue = maxValue;
- // Check Default Value.
- if ( defaultValue < minValue || defaultValue > maxValue )
- {
- // Warn.
- Con::warnf("ParticleAssetField::setValueBounds() - Default Value is out of range! (minValue:%f / maxValue:%f / defaultValue:%f)", minValue, maxValue, defaultValue );
- // Clamp at lower value.
- defaultValue = minValue;
- }
- // Set Default Value.
- mDefaultValue = defaultValue;
- // Reset the data keys if none are present.
- if ( mDataKeys.size() == 0 )
- resetDataKeys();
- // Flag the value bounds as dirty.
- mValueBoundsDirty = true;
- }
- //-----------------------------------------------------------------------------
- void ParticleAssetField::setFieldName( const char* pFieldName )
- {
- // Sanity!
- AssertFatal( mFieldName == StringTable->EmptyString, "ParticleAssetField::setFieldName() - Cannot set particle asset field name once it has been set." );
- mFieldName = StringTable->insert( pFieldName );
- // Sanity!
- AssertFatal( mFieldName != StringTable->EmptyString, "ParticleAssetField::setFieldName() - Field name cannot be empty." );
- }
- //-----------------------------------------------------------------------------
- bool ParticleAssetField::setRepeatTime( const F32 repeatTime )
- {
- // Check repeat time.
- if ( repeatTime < 0.0f )
- {
- // Warn.
- Con::warnf("ParticleAssetField::setRepeatTime() - Repeat time''%f'' is invalid.", repeatTime );
- // Return Error.
- return false;
- }
- // Set repeat time.
- mRepeatTime = repeatTime;
- // Return Okay.
- return true;
- }
- //-----------------------------------------------------------------------------
- bool ParticleAssetField::setValueScale( const F32 valueScale )
- {
- // Check Value Scale.
- if ( valueScale < 0.0f )
- {
- // Warn.
- Con::warnf("ParticleAssetField::setValueScale() - Invalid Value Scale! (%f)", valueScale );
- // Return Error.
- return false;
- }
- // Set Value Scale/
- mValueScale = valueScale;
- // Return Okay.
- return true;
- }
- //-----------------------------------------------------------------------------
- void ParticleAssetField::resetDataKeys(void)
- {
- // Clear Data Keys.
- mDataKeys.clear();
- // Add default value Data-Key.
- addDataKey( 0.0f, mDefaultValue );
- }
- //-----------------------------------------------------------------------------
- S32 ParticleAssetField::setSingleDataKey( const F32 value )
- {
- // Clear Data Keys.
- mDataKeys.clear();
- // Add a single key with the specified value.
- return addDataKey( 0.0f, value );
- }
- //-----------------------------------------------------------------------------
- bool ParticleAssetField::doesKeyExist(const F32 time)
- {
- U32 index = 0;
- for (index = 0; index < getDataKeyCount(); index++)
- {
- // Found Time?
- if (mDataKeys[index].mTime == time)
- {
- return true;
- }
- // Past Time?
- else if (mDataKeys[index].mTime > time)
- // Finish search.
- break;
- }
- return false;
- }
- //-----------------------------------------------------------------------------
- S32 ParticleAssetField::addDataKey( const F32 time, const F32 value )
- {
- // Check Max Time.
- if ( time > mMaxTime )
- {
- // Warn.
- Con::warnf("ParticleAssetField::addDataKey() - Time is out of bounds! (time:%f)", time );
- // Return Error.
- return -1;
- }
- // If data key exists already then set it and return the key index.
- U32 index = 0;
- for ( index = 0; index < getDataKeyCount(); index++ )
- {
- // Found Time?
- if ( mDataKeys[index].mTime == time )
- {
- // Yes, so set time.
- mDataKeys[index].mValue = value;
- // Return Index.
- return index;
- }
- // Past Time?
- else if ( mDataKeys[index].mTime > time )
- // Finish search.
- break;
- }
- // Insert Data-Key.
- mDataKeys.insert( index );
- // Set Data-Key.
- mDataKeys[index].mTime = time;
- mDataKeys[index].mValue = value;
- // Return Index.
- return index;
- }
- //-----------------------------------------------------------------------------
- bool ParticleAssetField::removeDataKey( const U32 index )
- {
- // Cannot Remove First Node!
- if ( index == 0 )
- {
- // Warn.
- Con::warnf("rParticleAssetField::emoveDataKey() - Cannot remove first Data-Key!");
- return false;
- }
- // Check Index.
- if ( index >= getDataKeyCount() )
- {
- // Warn.
- Con::warnf("rParticleAssetField::emoveDataKey() - Index out of range! (%d of %d)", index, getDataKeyCount()-1);
- return false;
- }
- // Remove Index.
- mDataKeys.erase(index);
- // Return Okay.
- return true;
- }
- //-----------------------------------------------------------------------------
- void ParticleAssetField::clearDataKeys( void )
- {
- // Reset Data Keys.
- resetDataKeys();
- }
- //-----------------------------------------------------------------------------
- bool ParticleAssetField::setDataKeyValue( const U32 index, const F32 value )
- {
- // Check Index.
- if ( index >= getDataKeyCount() )
- {
- // Warn.
- Con::warnf("ParticleAssetField::setDataKeyValue() - Index out of range! (%d of %d)", index, getDataKeyCount()-1);
- return false;
- }
- // Set Data Key Value.
- mDataKeys[index].mValue = value;
- // Return Okay.
- return true;
- }
- //-----------------------------------------------------------------------------
- F32 ParticleAssetField::getDataKeyValue( const U32 index ) const
- {
- // Check Index.
- if ( index >= getDataKeyCount() )
- {
- // Warn.
- Con::warnf("ParticleAssetField::getDataKeyValue() - Index out of range! (%d of %d)", index, getDataKeyCount()-1);
- return 0.0f;
- }
- // Return Data Key Value.
- return mDataKeys[index].mValue;
- }
- //-----------------------------------------------------------------------------
- F32 ParticleAssetField::getDataKeyTime( const U32 index ) const
- {
- // Check Index.
- if ( index >= getDataKeyCount() )
- {
- // Warn.
- Con::warnf("ParticleAssetField::getDataKeyTime() - Index out of range! (%d of %d)", index, getDataKeyCount()-1);
- return 0.0f;
- }
- // Return Data Key Time.
- return mDataKeys[index].mTime;
- }
- //-----------------------------------------------------------------------------
- const ParticleAssetField::DataKey& ParticleAssetField::getDataKey( const U32 index ) const
- {
- // Check Index.
- if ( index >= getDataKeyCount() )
- {
- // Warn.
- Con::warnf("ParticleAssetField::getDataKey() - Index out of range! (%d of %d)", index, getDataKeyCount()-1);
- return BadDataKey;
- }
- // Return Data-Key.
- return mDataKeys[index];
- }
- //-----------------------------------------------------------------------------
- F32 ParticleAssetField::getFieldValue( F32 time ) const
- {
- // Return First Entry if it's the only one or we're using zero time.
- if ( mIsZero(time) || getDataKeyCount() < 2)
- return mDataKeys[0].mValue * mValueScale;
- // Clamp Key-Time.
- time = getMin(getMax( 0.0f, time ), mMaxTime);
- // Repeat Time.
- time = mFmod( time * mRepeatTime, mMaxTime + FLT_EPSILON );
- // Fetch Max Key Index.
- const U32 maxKeyIndex = getDataKeyCount()-1;
- // Return Last Value if we're on/past the last time.
- if ( time >= mDataKeys[maxKeyIndex].mTime )
- return mDataKeys[maxKeyIndex].mValue * mValueScale;
- // Find Data-Key Indexes.
- U32 index1;
- U32 index2;
- for ( index1 = 0; index1 < getDataKeyCount(); index1++ )
- if ( mDataKeys[index1].mTime >= time )
- break;
- // If we're exactly on a Data-Key then return that key.
- if ( mIsEqual( mDataKeys[index1].mTime, time) )
- return mDataKeys[index1].mValue * mValueScale;
- // Set Adjacent Indexes.
- index2 = index1--;
- // Fetch Index Times.
- const F32 time1 = mDataKeys[index1].mTime;
- const F32 time2 = mDataKeys[index2].mTime;
- // Calculate Time Differential.
- const F32 dTime = (time-time1)/(time2-time1);
- // Return lerped Value.
- return ((mDataKeys[index1].mValue * (1.0f-dTime)) + (mDataKeys[index2].mValue * dTime)) * mValueScale;
- }
- //-----------------------------------------------------------------------------
- F32 ParticleAssetField::calculateFieldBV( const ParticleAssetField& base, const ParticleAssetField& variation, const F32 effectAge, const bool modulate, const F32 modulo )
- {
- // Fetch Graph Components.
- const F32 baseValue = base.getFieldValue( effectAge );
- const F32 varValue = variation.getFieldValue( effectAge ) * 0.5f;
- // Modulate?
- if ( modulate )
- // Return Modulo Calculation.
- return mFmod( baseValue + CoreMath::mGetRandomF(-varValue, varValue), modulo );
- else
- // Return Clamped Calculation.
- return mClampF( baseValue + CoreMath::mGetRandomF(-varValue, varValue), base.getMinValue(), base.getMaxValue() );
- }
- //-----------------------------------------------------------------------------
- F32 ParticleAssetField::calculateFieldBVE( const ParticleAssetField& base, const ParticleAssetField& variation, const ParticleAssetField& effect, const F32 effectAge, const bool modulate, const F32 modulo )
- {
- // Fetch Graph Components.
- const F32 baseValue = base.getFieldValue( effectAge );
- const F32 varValue = variation.getFieldValue( effectAge ) * 0.5f;
- const F32 effectValue = effect.getFieldValue( effectAge );
- // Modulate?
- if ( modulate )
- // Return Modulo Calculation.
- return mFmod( (baseValue + CoreMath::mGetRandomF(-varValue, varValue)) * effectValue, modulo );
- else
- // Return Clamped Calculation.
- return mClampF( (baseValue + CoreMath::mGetRandomF(-varValue, varValue)) * effectValue, base.getMinValue(), base.getMaxValue() );
- }
- //-----------------------------------------------------------------------------
- F32 ParticleAssetField::calculateFieldBVLE( const ParticleAssetField& base, const ParticleAssetField& variation, const ParticleAssetField& overlife, const ParticleAssetField& effect, const F32 effectAge, const F32 particleAge, const bool modulate, const F32 modulo )
- {
- // Fetch Graph Components.
- const F32 baseValue = base.getFieldValue( effectAge );
- const F32 varValue = variation.getFieldValue( effectAge ) * 0.5f;
- const F32 effectValue = effect.getFieldValue( effectAge );
- const F32 lifeValue = overlife.getFieldValue( particleAge );
- // Modulate?
- if ( modulate )
- // Return Modulo Calculation.
- return mFmod( (baseValue + CoreMath::mGetRandomF(-varValue, varValue)) * effectValue * lifeValue, modulo );
- else
- // Return Clamped Calculation.
- return mClampF( (baseValue + CoreMath::mGetRandomF(-varValue, varValue)) * effectValue * lifeValue, base.getMinValue(), base.getMaxValue() );
- }
- //------------------------------------------------------------------------------
- void ParticleAssetField::onTamlCustomWrite( TamlCustomNode* pCustomNode )
- {
- // Debug Profiling.
- PROFILE_SCOPE(ParticleAssetField_OnTamlCustomWrite);
- // Add a child (ignore it if there ends up being no children).
- TamlCustomNode* pAssetField = pCustomNode->addNode( getFieldName(), true );
- // Sanity!
- AssertFatal( pAssetField != NULL, "ParticleAssetField::onTamlCustomWrite() - Could not create field." );
- if ( mValueBoundsDirty && (mNotEqual( getMinValue(), 0.0f ) || mNotEqual( getMaxValue(), 0.0f )) )
- {
- pAssetField->addField( particleAssetFieldMinValueName, getMinValue() );
- pAssetField->addField( particleAssetFieldMaxValueName, getMaxValue() );
- }
-
- if ( mValueBoundsDirty && mNotEqual( getMaxTime(), 1.0f ) )
- pAssetField->addField( particleAssetFieldMaxTimeName, getMaxTime() );
- if ( mValueBoundsDirty && mNotEqual( getDefaultValue(), 1.0f ) )
- pAssetField->addField( particleAssetFieldDefaultValueName, getDefaultValue() );
- if ( mNotEqual( getValueScale(), 1.0f ) )
- pAssetField->addField( particleAssetFieldValueScaleName, getValueScale() );
- if ( mNotEqual( getRepeatTime(), 1.0f ) )
- pAssetField->addField( particleAssetFieldRepeatTimeName, getRepeatTime() );
- // Fetch key count.
- const U32 keyCount = getDataKeyCount();
- // Finish if no data keys.
- if ( keyCount == 0 )
- return;
- // Finish if there's only one key and it's the default one.
- if ( keyCount == 1 && mIsEqual(mDataKeys[0].mTime, 0.0f) && mIsEqual(mDataKeys[0].mValue, mDefaultValue) )
- return;
- // Iterate the keys.
- for( U32 index = 0; index < keyCount; ++index )
- {
- // Fetch the data key.
- const DataKey& dataKey = mDataKeys[index];
- // Add a key node.
- TamlCustomNode* pKeyNode = pAssetField->addNode( particleAssetFieldDataKeyName );
- // Add key fields.
- pKeyNode->addField( particleAssetFieldDataKeyTimeName, dataKey.mTime );
- pKeyNode->addField( particleAssetFieldDataKeyValueName, dataKey.mValue );
- }
- }
- //-----------------------------------------------------------------------------
- void ParticleAssetField::onTamlCustomRead( const TamlCustomNode* pCustomNode )
- {
- // Debug Profiling.
- PROFILE_SCOPE(ParticleAssetField_OnTamlCustomRead);
- // Fetch existing values.
- F32 repeatTime = getRepeatTime();
- F32 maxTime = getMaxTime();
- F32 minValue = getMinValue();
- F32 maxValue = getMaxValue();
- F32 defaultValue = getDefaultValue();
- F32 valueScale = getValueScale();
- // Set-up a temporary set of keys.
- Vector<DataKey> keys;
- // Clear the existing keys.
- mDataKeys.clear();
- // Fetch fields.
- const TamlCustomFieldVector& fields = pCustomNode->getFields();
- // Iterate fields.
- for ( TamlCustomFieldVector::const_iterator fieldItr = fields.begin(); fieldItr != fields.end(); ++fieldItr )
- {
- // Fetch field.
- TamlCustomField* pField = *fieldItr;
- // Fetch property field name.
- StringTableEntry fieldName = pField->getFieldName();
- if ( fieldName == particleAssetFieldRepeatTimeName )
- {
- pField->getFieldValue( repeatTime );
- }
- else if ( fieldName == particleAssetFieldMaxTimeName )
- {
- pField->getFieldValue( maxTime );
- mValueBoundsDirty = true;
- }
- else if ( fieldName == particleAssetFieldMinValueName )
- {
- pField->getFieldValue( minValue );
- mValueBoundsDirty = true;
- }
- else if ( fieldName == particleAssetFieldMaxValueName )
- {
- pField->getFieldValue( maxValue );
- mValueBoundsDirty = true;
- }
- else if ( fieldName == particleAssetFieldDefaultValueName )
- {
- pField->getFieldValue( defaultValue );
- mValueBoundsDirty = true;
- }
- else if ( fieldName == particleAssetFieldValueScaleName )
- {
- pField->getFieldValue( valueScale );
- }
- else if ( fieldName == particleAssetFieldDataKeysName )
- {
- const char* pDataKeys = pField->getFieldValue();
- const S32 elementCount = StringUnit::getUnitCount( pDataKeys, " ,\t" );
- // Are there a valid number of elements?
- if ( elementCount < 2 || (elementCount % 2 ) != 0 )
- {
- // No, so warn.
- Con::warnf( "ParticleAssetField::onTamlCustomRead() - An invalid set of data keys was found." );
- }
- else
- {
- // Iterate the elements.
- for( S32 elementIndex = 0; elementIndex <= (elementCount-2); elementIndex += 2 )
- {
- DataKey key;
- key.mTime = dAtof( StringUnit::getUnit( pDataKeys, elementIndex, " ,\t" ) );
- key.mValue = dAtof( StringUnit::getUnit( pDataKeys, elementIndex+1, " ,\t" ) );
- keys.push_back( key );
- }
- }
- }
- }
- // Fetch any children.
- const TamlCustomNodeVector& children = pCustomNode->getChildren();
- // Iterate node children.
- for( TamlCustomNodeVector::const_iterator childItr = children.begin(); childItr != children.end(); ++childItr )
- {
- // Fetch node.
- TamlCustomNode* pKeyNode = *childItr;
- // Ignore anything that isn't a key.
- if ( pKeyNode->getNodeName() != particleAssetFieldDataKeyName )
- continue;
- // Fetch the fields.
- const TamlCustomField* pTimeField = pKeyNode->findField( particleAssetFieldDataKeyTimeName );
- const TamlCustomField* pValueField = pKeyNode->findField( particleAssetFieldDataKeyValueName );
- // Did we find the fields?
- if ( pTimeField == NULL || pValueField == NULL )
- {
- // No, so warn.
- Con::warnf("ParticleAssetField::onTamlCustomRead() - Found a key but it did not have a time and value field." );
- continue;
- }
- // Read key.
- DataKey key;
- pTimeField->getFieldValue( key.mTime );
- pValueField->getFieldValue( key.mValue );
- keys.push_back( key );
- }
- // If value bounds are present but no keys, assign the field its default values.
- if ( !keys.size() )
- {
- DataKey key;
- key.mTime = getMinTime();
- key.mValue = getDefaultValue();
- keys.push_back( key );
- }
- // Did we read in any value bounds?
- if ( mValueBoundsDirty )
- {
- // Set the value bounds.
- setValueBounds( maxTime, minValue, maxValue, defaultValue );
- }
- // Set the value scale.
- setValueScale( valueScale );
- // Set the repeat time.
- setRepeatTime( repeatTime );
- // Set the data keys.
- mDataKeys = keys;
- }
- //-----------------------------------------------------------------------------
- void ParticleAssetField::WriteCustomTamlSchema( const AbstractClassRep* pClassRep, TiXmlElement* pParentElement )
- {
- // Sanity!
- AssertFatal( pClassRep != NULL, "ParticleAssetField::WriteCustomTamlSchema() - ClassRep cannot be NULL." );
- AssertFatal( pParentElement != NULL, "ParticleAssetField::WriteCustomTamlSchema() - Parent Element cannot be NULL." );
- // Create Field element.
- TiXmlElement* pFieldElement = new TiXmlElement( "xs:element" );
- pFieldElement->SetAttribute( "name", getFieldName() );
- pFieldElement->SetAttribute( "minOccurs", 0 );
- pFieldElement->SetAttribute( "maxOccurs", 1 );
- pParentElement->LinkEndChild( pFieldElement );
- // Create complex type Element.
- TiXmlElement* pFieldComplexTypeElement = new TiXmlElement( "xs:complexType" );
- pFieldElement->LinkEndChild( pFieldComplexTypeElement );
- // Create choice element.
- TiXmlElement* pFieldChoiceElement = new TiXmlElement( "xs:choice" );
- pFieldChoiceElement->SetAttribute( "minOccurs", 0 );
- pFieldChoiceElement->SetAttribute( "maxOccurs", 1 );
- pFieldComplexTypeElement->LinkEndChild( pFieldChoiceElement );
- // Create key element.
- TiXmlElement* pKeyElement = new TiXmlElement( "xs:element" );
- pKeyElement->SetAttribute( "name", particleAssetFieldDataKeyName );
- pKeyElement->SetAttribute( "minOccurs", 0 );
- pKeyElement->SetAttribute( "maxOccurs", "unbounded" );
- pFieldChoiceElement->LinkEndChild( pKeyElement );
- // Create complex type Element.
- TiXmlElement* pKeyComplexTypeElement = new TiXmlElement( "xs:complexType" );
- pKeyElement->LinkEndChild( pKeyComplexTypeElement );
- // Create "Time" attribute.
- TiXmlElement* pKeyTimeAttribute = new TiXmlElement( "xs:attribute" );
- pKeyTimeAttribute->SetAttribute( "name", particleAssetFieldDataKeyTimeName );
- pKeyComplexTypeElement->LinkEndChild( pKeyTimeAttribute );
- TiXmlElement* pKeyTimeSimpleType = new TiXmlElement( "xs:simpleType" );
- pKeyTimeAttribute->LinkEndChild( pKeyTimeSimpleType );
- TiXmlElement* pKeyTimeRestriction = new TiXmlElement( "xs:restriction" );
- pKeyTimeRestriction->SetAttribute( "base", "xs:float" );
- pKeyTimeSimpleType->LinkEndChild( pKeyTimeRestriction );
- TiXmlElement* pKeyTimeMinRestriction = new TiXmlElement( "xs:minInclusive" );
- pKeyTimeMinRestriction->SetAttribute( "value", "0" );
- pKeyTimeRestriction->LinkEndChild( pKeyTimeMinRestriction );
- // Create "Value" attribute.
- TiXmlElement* pKeyValueAttribute = new TiXmlElement( "xs:attribute" );
- pKeyValueAttribute->SetAttribute( "name", particleAssetFieldDataKeyValueName );
- pKeyValueAttribute->SetAttribute( "type", "xs:float" );
- pKeyComplexTypeElement->LinkEndChild( pKeyValueAttribute );
- // Create "Min Value" attribute.
- TiXmlElement* pFieldMinValue = new TiXmlElement( "xs:attribute" );
- pFieldMinValue->SetAttribute( "name", particleAssetFieldMinValueName );
- pFieldMinValue->SetAttribute( "type", "xs:float" );
- pFieldComplexTypeElement->LinkEndChild( pFieldMinValue );
- // Create "Max Value" attribute.
- TiXmlElement* pFieldMaxValue = new TiXmlElement( "xs:attribute" );
- pFieldMaxValue->SetAttribute( "name", particleAssetFieldMaxValueName );
- pFieldMaxValue->SetAttribute( "type", "xs:float" );
- pFieldComplexTypeElement->LinkEndChild( pFieldMaxValue );
- // Create "Max Time" attribute.
- TiXmlElement* pFieldMaxTime = new TiXmlElement( "xs:attribute" );
- pFieldMaxTime->SetAttribute( "name", particleAssetFieldMaxTimeName );
- pFieldMaxTime->SetAttribute( "type", "xs:float" );
- pFieldComplexTypeElement->LinkEndChild( pFieldMaxTime );
- // Create "Default Value" attribute.
- TiXmlElement* pFieldDefaultValue = new TiXmlElement( "xs:attribute" );
- pFieldDefaultValue->SetAttribute( "name", particleAssetFieldDefaultValueName );
- pFieldDefaultValue->SetAttribute( "type", "xs:float" );
- pFieldComplexTypeElement->LinkEndChild( pFieldDefaultValue );
- // Create "Value Scale" attribute.
- TiXmlElement* pFieldValueScale = new TiXmlElement( "xs:attribute" );
- pFieldValueScale->SetAttribute( "name", particleAssetFieldValueScaleName );
- pFieldValueScale->SetAttribute( "type", "xs:float" );
- pFieldComplexTypeElement->LinkEndChild( pFieldValueScale );
- // Create "Repeat Time" attribute.
- TiXmlElement* pFieldRepeatTime = new TiXmlElement( "xs:attribute" );
- pFieldRepeatTime->SetAttribute( "name", particleAssetFieldRepeatTimeName );
- pFieldRepeatTime->SetAttribute( "type", "xs:float" );
- pFieldComplexTypeElement->LinkEndChild( pFieldRepeatTime );
- }
|