mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-29 16:25:42 +00:00
datablock-temp-clone -- Implements creation of temporary datablock clones to allow late substitution of datablock fields.
This commit is contained in:
parent
0b84fccdd2
commit
f9f05f154f
24 changed files with 865 additions and 11 deletions
|
|
@ -117,6 +117,85 @@ DebrisData::DebrisData()
|
||||||
ignoreWater = true;
|
ignoreWater = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#define TRACK_DEBRIS_DATA_CLONES
|
||||||
|
|
||||||
|
#ifdef TRACK_DEBRIS_DATA_CLONES
|
||||||
|
static int debris_data_clones = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DebrisData::DebrisData(const DebrisData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||||
|
{
|
||||||
|
#ifdef TRACK_DEBRIS_DATA_CLONES
|
||||||
|
debris_data_clones++;
|
||||||
|
if (debris_data_clones == 1)
|
||||||
|
Con::errorf("DebrisData -- Clones are on the loose!");
|
||||||
|
#endif
|
||||||
|
velocity = other.velocity;
|
||||||
|
velocityVariance = other.velocityVariance;
|
||||||
|
friction = other.friction;
|
||||||
|
elasticity = other.elasticity;
|
||||||
|
lifetime = other.lifetime;
|
||||||
|
lifetimeVariance = other.lifetimeVariance;
|
||||||
|
numBounces = other.numBounces;
|
||||||
|
bounceVariance = other.bounceVariance;
|
||||||
|
minSpinSpeed = other.minSpinSpeed;
|
||||||
|
maxSpinSpeed = other.maxSpinSpeed;
|
||||||
|
explodeOnMaxBounce = other.explodeOnMaxBounce;
|
||||||
|
staticOnMaxBounce = other.staticOnMaxBounce;
|
||||||
|
snapOnMaxBounce = other.snapOnMaxBounce;
|
||||||
|
fade = other.fade;
|
||||||
|
useRadiusMass = other.useRadiusMass;
|
||||||
|
baseRadius = other.baseRadius;
|
||||||
|
gravModifier = other.gravModifier;
|
||||||
|
terminalVelocity = other.terminalVelocity;
|
||||||
|
ignoreWater = other.ignoreWater;
|
||||||
|
shapeName = other.shapeName;
|
||||||
|
shape = other.shape; // -- TSShape loaded using shapeName
|
||||||
|
textureName = other.textureName;
|
||||||
|
explosionId = other.explosionId; // -- for pack/unpack of explosion ptr
|
||||||
|
explosion = other.explosion;
|
||||||
|
dMemcpy( emitterList, other.emitterList, sizeof( emitterList ) );
|
||||||
|
dMemcpy( emitterIDList, other.emitterIDList, sizeof( emitterIDList ) ); // -- for pack/unpack of emitterList ptrs
|
||||||
|
}
|
||||||
|
|
||||||
|
DebrisData::~DebrisData()
|
||||||
|
{
|
||||||
|
if (!isTempClone())
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef TRACK_DEBRIS_DATA_CLONES
|
||||||
|
if (debris_data_clones > 0)
|
||||||
|
{
|
||||||
|
debris_data_clones--;
|
||||||
|
if (debris_data_clones == 0)
|
||||||
|
Con::errorf("DebrisData -- Clones eliminated!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Con::errorf("DebrisData -- Too many clones deleted!");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
DebrisData* DebrisData::cloneAndPerformSubstitutions(const SimObject* owner, S32 index)
|
||||||
|
{
|
||||||
|
if (!owner || getSubstitutionCount() == 0)
|
||||||
|
return this;
|
||||||
|
|
||||||
|
DebrisData* sub_debris_db = new DebrisData(*this, true);
|
||||||
|
performSubstitutions(sub_debris_db, owner, index);
|
||||||
|
|
||||||
|
return sub_debris_db;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebrisData::onPerformSubstitutions()
|
||||||
|
{
|
||||||
|
if( shapeName && shapeName[0] != '\0')
|
||||||
|
{
|
||||||
|
shape = ResourceManager::get().load(shapeName);
|
||||||
|
if( bool(shape) == false )
|
||||||
|
Con::errorf("DebrisData::onPerformSubstitutions(): failed to load shape \"%s\"", shapeName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool DebrisData::onAdd()
|
bool DebrisData::onAdd()
|
||||||
{
|
{
|
||||||
if(!Parent::onAdd())
|
if(!Parent::onAdd())
|
||||||
|
|
@ -458,6 +537,8 @@ Debris::Debris()
|
||||||
|
|
||||||
// Only allocated client side.
|
// Only allocated client side.
|
||||||
mNetFlags.set( IsGhost );
|
mNetFlags.set( IsGhost );
|
||||||
|
ss_object = 0;
|
||||||
|
ss_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debris::~Debris()
|
Debris::~Debris()
|
||||||
|
|
@ -473,6 +554,12 @@ Debris::~Debris()
|
||||||
delete mPart;
|
delete mPart;
|
||||||
mPart = NULL;
|
mPart = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mDataBlock && mDataBlock->isTempClone())
|
||||||
|
{
|
||||||
|
delete mDataBlock;
|
||||||
|
mDataBlock = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debris::initPersistFields()
|
void Debris::initPersistFields()
|
||||||
|
|
@ -502,6 +589,8 @@ bool Debris::onNewDataBlock( GameBaseData *dptr, bool reload )
|
||||||
if( !mDataBlock || !Parent::onNewDataBlock( dptr, reload ) )
|
if( !mDataBlock || !Parent::onNewDataBlock( dptr, reload ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (mDataBlock->isTempClone())
|
||||||
|
return true;
|
||||||
scriptOnNewDataBlock();
|
scriptOnNewDataBlock();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
@ -526,7 +615,7 @@ bool Debris::onAdd()
|
||||||
if( mDataBlock->emitterList[i] != NULL )
|
if( mDataBlock->emitterList[i] != NULL )
|
||||||
{
|
{
|
||||||
ParticleEmitter * pEmitter = new ParticleEmitter;
|
ParticleEmitter * pEmitter = new ParticleEmitter;
|
||||||
pEmitter->onNewDataBlock( mDataBlock->emitterList[i], false );
|
pEmitter->onNewDataBlock(mDataBlock->emitterList[i]->cloneAndPerformSubstitutions(ss_object, ss_index), false);
|
||||||
if( !pEmitter->registerObject() )
|
if( !pEmitter->registerObject() )
|
||||||
{
|
{
|
||||||
Con::warnf( ConsoleLogEntry::General, "Could not register emitter for particle of class: %s", mDataBlock->getName() );
|
Con::warnf( ConsoleLogEntry::General, "Could not register emitter for particle of class: %s", mDataBlock->getName() );
|
||||||
|
|
@ -805,7 +894,8 @@ void Debris::explode()
|
||||||
Point3F explosionPos = getPosition();
|
Point3F explosionPos = getPosition();
|
||||||
|
|
||||||
Explosion* pExplosion = new Explosion;
|
Explosion* pExplosion = new Explosion;
|
||||||
pExplosion->onNewDataBlock(mDataBlock->explosion, false);
|
pExplosion->setSubstitutionData(ss_object, ss_index);
|
||||||
|
pExplosion->onNewDataBlock(mDataBlock->explosion->cloneAndPerformSubstitutions(ss_object, ss_index), false);
|
||||||
|
|
||||||
MatrixF trans( true );
|
MatrixF trans( true );
|
||||||
trans.setPosition( getPosition() );
|
trans.setPosition( getPosition() );
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,11 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
|
||||||
#ifndef _DEBRIS_H_
|
#ifndef _DEBRIS_H_
|
||||||
#define _DEBRIS_H_
|
#define _DEBRIS_H_
|
||||||
|
|
||||||
|
|
@ -97,6 +102,12 @@ struct DebrisData : public GameBaseData
|
||||||
|
|
||||||
DECLARE_CONOBJECT(DebrisData);
|
DECLARE_CONOBJECT(DebrisData);
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*C*/ DebrisData(const DebrisData&, bool = false);
|
||||||
|
/*D*/ ~DebrisData();
|
||||||
|
DebrisData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
|
||||||
|
virtual void onPerformSubstitutions();
|
||||||
|
virtual bool allowSubstitutions() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
@ -165,6 +176,11 @@ public:
|
||||||
|
|
||||||
DECLARE_CONOBJECT(Debris);
|
DECLARE_CONOBJECT(Debris);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SimObject* ss_object;
|
||||||
|
S32 ss_index;
|
||||||
|
public:
|
||||||
|
void setSubstitutionData(SimObject* obj, S32 idx=0) { ss_object = obj; ss_index = idx; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
// Copyright (C) 2015 Faust Logic, Inc.
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
#include "T3D/fx/explosion.h"
|
#include "T3D/fx/explosion.h"
|
||||||
|
|
||||||
|
|
@ -54,6 +55,8 @@
|
||||||
#include "renderInstance/renderPassManager.h"
|
#include "renderInstance/renderPassManager.h"
|
||||||
#include "console/engineAPI.h"
|
#include "console/engineAPI.h"
|
||||||
|
|
||||||
|
#include "sfx/sfxProfile.h"
|
||||||
|
|
||||||
IMPLEMENT_CONOBJECT(Explosion);
|
IMPLEMENT_CONOBJECT(Explosion);
|
||||||
|
|
||||||
ConsoleDocClass( Explosion,
|
ConsoleDocClass( Explosion,
|
||||||
|
|
@ -285,6 +288,105 @@ ExplosionData::ExplosionData()
|
||||||
lightNormalOffset = 0.1f;
|
lightNormalOffset = 0.1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#define TRACK_EXPLOSION_DATA_CLONES
|
||||||
|
|
||||||
|
#ifdef TRACK_EXPLOSION_DATA_CLONES
|
||||||
|
static int explosion_data_clones = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ExplosionData::ExplosionData(const ExplosionData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||||
|
{
|
||||||
|
#ifdef TRACK_EXPLOSION_DATA_CLONES
|
||||||
|
explosion_data_clones++;
|
||||||
|
if (explosion_data_clones == 1)
|
||||||
|
Con::errorf("ExplosionData -- Clones are on the loose!");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dtsFileName = other.dtsFileName;
|
||||||
|
faceViewer = other.faceViewer;
|
||||||
|
particleDensity = other.particleDensity;
|
||||||
|
particleRadius = other.particleRadius;
|
||||||
|
soundProfile = other.soundProfile;
|
||||||
|
particleEmitter = other.particleEmitter;
|
||||||
|
particleEmitterId = other.particleEmitterId; // -- for pack/unpack of particleEmitter ptr
|
||||||
|
explosionScale = other.explosionScale;
|
||||||
|
playSpeed = other.playSpeed;
|
||||||
|
explosionShape = other.explosionShape; // -- TSShape loaded using dtsFileName
|
||||||
|
explosionAnimation = other.explosionAnimation; // -- from explosionShape sequence "ambient"
|
||||||
|
dMemcpy( emitterList, other.emitterList, sizeof( emitterList ) );
|
||||||
|
dMemcpy( emitterIDList, other.emitterIDList, sizeof( emitterIDList ) ); // -- for pack/unpack of emitterList ptrs
|
||||||
|
dMemcpy( debrisList, other.debrisList, sizeof( debrisList ) );
|
||||||
|
dMemcpy( debrisIDList, other.debrisIDList, sizeof( debrisIDList ) ); // -- for pack/unpack of debrisList ptrs
|
||||||
|
debrisThetaMin = other.debrisThetaMin;
|
||||||
|
debrisThetaMax = other.debrisThetaMax;
|
||||||
|
debrisPhiMin = other.debrisPhiMin;
|
||||||
|
debrisPhiMax = other.debrisPhiMax;
|
||||||
|
debrisNum = other.debrisNum;
|
||||||
|
debrisNumVariance = other.debrisNumVariance;
|
||||||
|
debrisVelocity = other.debrisVelocity;
|
||||||
|
debrisVelocityVariance = other.debrisVelocityVariance;
|
||||||
|
dMemcpy( explosionList, other.explosionList, sizeof( explosionList ) );
|
||||||
|
dMemcpy( explosionIDList, other.explosionIDList, sizeof( explosionIDList ) ); // -- for pack/unpack of explosionList ptrs
|
||||||
|
delayMS = other.delayMS;
|
||||||
|
delayVariance = other.delayVariance;
|
||||||
|
lifetimeMS = other.lifetimeMS;
|
||||||
|
lifetimeVariance = other.lifetimeVariance;
|
||||||
|
offset = other.offset;
|
||||||
|
dMemcpy( sizes, other.times, sizeof( sizes ) );
|
||||||
|
dMemcpy( times, other.times, sizeof( times ) );
|
||||||
|
shakeCamera = other.shakeCamera;
|
||||||
|
camShakeFreq = other.camShakeFreq;
|
||||||
|
camShakeAmp = other.camShakeAmp;
|
||||||
|
camShakeDuration = other.camShakeDuration;
|
||||||
|
camShakeRadius = other.camShakeRadius;
|
||||||
|
camShakeFalloff = other.camShakeFalloff;
|
||||||
|
lightStartRadius = other.lightStartRadius;
|
||||||
|
lightEndRadius = other.lightEndRadius;
|
||||||
|
lightStartColor = other.lightStartColor;
|
||||||
|
lightEndColor = other.lightEndColor;
|
||||||
|
lightStartBrightness = other.lightStartBrightness;
|
||||||
|
lightEndBrightness = other.lightEndBrightness;
|
||||||
|
lightNormalOffset = other.lightNormalOffset;
|
||||||
|
// Note - Explosion calls mDataBlock->getName() in warning messages but
|
||||||
|
// that should be safe.
|
||||||
|
}
|
||||||
|
|
||||||
|
ExplosionData::~ExplosionData()
|
||||||
|
{
|
||||||
|
if (!isTempClone())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (soundProfile && soundProfile->isTempClone())
|
||||||
|
{
|
||||||
|
delete soundProfile;
|
||||||
|
soundProfile = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// particleEmitter, emitterList[*], debrisList[*], explosionList[*] will delete themselves
|
||||||
|
|
||||||
|
#ifdef TRACK_EXPLOSION_DATA_CLONES
|
||||||
|
if (explosion_data_clones > 0)
|
||||||
|
{
|
||||||
|
explosion_data_clones--;
|
||||||
|
if (explosion_data_clones == 0)
|
||||||
|
Con::errorf("ExplosionData -- Clones eliminated!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Con::errorf("ExplosionData -- Too many clones deleted!");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ExplosionData* ExplosionData::cloneAndPerformSubstitutions(const SimObject* owner, S32 index)
|
||||||
|
{
|
||||||
|
if (!owner || getSubstitutionCount() == 0)
|
||||||
|
return this;
|
||||||
|
|
||||||
|
ExplosionData* sub_explosion_db = new ExplosionData(*this, true);
|
||||||
|
performSubstitutions(sub_explosion_db, owner, index);
|
||||||
|
|
||||||
|
return sub_explosion_db;
|
||||||
|
}
|
||||||
|
|
||||||
void ExplosionData::initPersistFields()
|
void ExplosionData::initPersistFields()
|
||||||
{
|
{
|
||||||
addField( "explosionShape", TypeShapeFilename, Offset(dtsFileName, ExplosionData),
|
addField( "explosionShape", TypeShapeFilename, Offset(dtsFileName, ExplosionData),
|
||||||
|
|
@ -818,6 +920,10 @@ Explosion::Explosion()
|
||||||
mLight = LIGHTMGR->createLightInfo();
|
mLight = LIGHTMGR->createLightInfo();
|
||||||
|
|
||||||
mNetFlags.set( IsGhost );
|
mNetFlags.set( IsGhost );
|
||||||
|
ss_object = 0;
|
||||||
|
ss_index = 0;
|
||||||
|
mDataBlock = 0;
|
||||||
|
soundProfile_clone = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Explosion::~Explosion()
|
Explosion::~Explosion()
|
||||||
|
|
@ -830,6 +936,18 @@ Explosion::~Explosion()
|
||||||
}
|
}
|
||||||
|
|
||||||
SAFE_DELETE(mLight);
|
SAFE_DELETE(mLight);
|
||||||
|
|
||||||
|
if (soundProfile_clone)
|
||||||
|
{
|
||||||
|
delete soundProfile_clone;
|
||||||
|
soundProfile_clone = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mDataBlock && mDataBlock->isTempClone())
|
||||||
|
{
|
||||||
|
delete mDataBlock;
|
||||||
|
mDataBlock = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -988,6 +1106,8 @@ bool Explosion::onNewDataBlock( GameBaseData *dptr, bool reload )
|
||||||
if (!mDataBlock || !Parent::onNewDataBlock( dptr, reload ))
|
if (!mDataBlock || !Parent::onNewDataBlock( dptr, reload ))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (mDataBlock->isTempClone())
|
||||||
|
return true;
|
||||||
scriptOnNewDataBlock();
|
scriptOnNewDataBlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1200,7 +1320,8 @@ void Explosion::launchDebris( Point3F &axis )
|
||||||
launchDir *= debrisVel;
|
launchDir *= debrisVel;
|
||||||
|
|
||||||
Debris *debris = new Debris;
|
Debris *debris = new Debris;
|
||||||
debris->setDataBlock( mDataBlock->debrisList[0] );
|
debris->setSubstitutionData(ss_object, ss_index);
|
||||||
|
debris->setDataBlock(mDataBlock->debrisList[0]->cloneAndPerformSubstitutions(ss_object, ss_index));
|
||||||
debris->setTransform( getTransform() );
|
debris->setTransform( getTransform() );
|
||||||
debris->init( pos, launchDir );
|
debris->init( pos, launchDir );
|
||||||
|
|
||||||
|
|
@ -1228,7 +1349,8 @@ void Explosion::spawnSubExplosions()
|
||||||
{
|
{
|
||||||
MatrixF trans = getTransform();
|
MatrixF trans = getTransform();
|
||||||
Explosion* pExplosion = new Explosion;
|
Explosion* pExplosion = new Explosion;
|
||||||
pExplosion->setDataBlock( mDataBlock->explosionList[i] );
|
pExplosion->setSubstitutionData(ss_object, ss_index);
|
||||||
|
pExplosion->setDataBlock(mDataBlock->explosionList[i]->cloneAndPerformSubstitutions(ss_object, ss_index));
|
||||||
pExplosion->setTransform( trans );
|
pExplosion->setTransform( trans );
|
||||||
pExplosion->setInitialState( trans.getPosition(), mInitialNormal, 1);
|
pExplosion->setInitialState( trans.getPosition(), mInitialNormal, 1);
|
||||||
if (!pExplosion->registerObject())
|
if (!pExplosion->registerObject())
|
||||||
|
|
@ -1266,12 +1388,18 @@ bool Explosion::explode()
|
||||||
resetWorldBox();
|
resetWorldBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDataBlock->soundProfile)
|
SFXProfile* sound_prof = dynamic_cast<SFXProfile*>(mDataBlock->soundProfile);
|
||||||
SFX->playOnce( mDataBlock->soundProfile, &getTransform() );
|
if (sound_prof)
|
||||||
|
{
|
||||||
|
soundProfile_clone = sound_prof->cloneAndPerformSubstitutions(ss_object, ss_index);
|
||||||
|
SFX->playOnce( soundProfile_clone, &getTransform() );
|
||||||
|
if (!soundProfile_clone->isTempClone())
|
||||||
|
soundProfile_clone = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (mDataBlock->particleEmitter) {
|
if (mDataBlock->particleEmitter) {
|
||||||
mMainEmitter = new ParticleEmitter;
|
mMainEmitter = new ParticleEmitter;
|
||||||
mMainEmitter->setDataBlock(mDataBlock->particleEmitter);
|
mMainEmitter->setDataBlock(mDataBlock->particleEmitter->cloneAndPerformSubstitutions(ss_object, ss_index));
|
||||||
mMainEmitter->registerObject();
|
mMainEmitter->registerObject();
|
||||||
|
|
||||||
mMainEmitter->emitParticles(getPosition(), mInitialNormal, mDataBlock->particleRadius,
|
mMainEmitter->emitParticles(getPosition(), mInitialNormal, mDataBlock->particleRadius,
|
||||||
|
|
@ -1283,7 +1411,7 @@ bool Explosion::explode()
|
||||||
if( mDataBlock->emitterList[i] != NULL )
|
if( mDataBlock->emitterList[i] != NULL )
|
||||||
{
|
{
|
||||||
ParticleEmitter * pEmitter = new ParticleEmitter;
|
ParticleEmitter * pEmitter = new ParticleEmitter;
|
||||||
pEmitter->setDataBlock( mDataBlock->emitterList[i] );
|
pEmitter->setDataBlock(mDataBlock->emitterList[i]->cloneAndPerformSubstitutions(ss_object, ss_index));
|
||||||
if( !pEmitter->registerObject() )
|
if( !pEmitter->registerObject() )
|
||||||
{
|
{
|
||||||
Con::warnf( ConsoleLogEntry::General, "Could not register emitter for particle of class: %s", mDataBlock->getName() );
|
Con::warnf( ConsoleLogEntry::General, "Could not register emitter for particle of class: %s", mDataBlock->getName() );
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,11 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
|
||||||
#ifndef _EXPLOSION_H_
|
#ifndef _EXPLOSION_H_
|
||||||
#define _EXPLOSION_H_
|
#define _EXPLOSION_H_
|
||||||
|
|
||||||
|
|
@ -42,6 +47,7 @@ class TSThread;
|
||||||
class SFXTrack;
|
class SFXTrack;
|
||||||
struct DebrisData;
|
struct DebrisData;
|
||||||
|
|
||||||
|
class SFXProfile;
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
class ExplosionData : public GameBaseData {
|
class ExplosionData : public GameBaseData {
|
||||||
public:
|
public:
|
||||||
|
|
@ -126,6 +132,11 @@ class ExplosionData : public GameBaseData {
|
||||||
static void initPersistFields();
|
static void initPersistFields();
|
||||||
virtual void packData(BitStream* stream);
|
virtual void packData(BitStream* stream);
|
||||||
virtual void unpackData(BitStream* stream);
|
virtual void unpackData(BitStream* stream);
|
||||||
|
public:
|
||||||
|
/*C*/ ExplosionData(const ExplosionData&, bool = false);
|
||||||
|
/*D*/ ~ExplosionData();
|
||||||
|
ExplosionData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
|
||||||
|
virtual bool allowSubstitutions() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -188,6 +199,12 @@ class Explosion : public GameBase, public ISceneLight
|
||||||
|
|
||||||
DECLARE_CONOBJECT(Explosion);
|
DECLARE_CONOBJECT(Explosion);
|
||||||
static void initPersistFields();
|
static void initPersistFields();
|
||||||
|
private:
|
||||||
|
SimObject* ss_object;
|
||||||
|
S32 ss_index;
|
||||||
|
SFXProfile* soundProfile_clone;
|
||||||
|
public:
|
||||||
|
void setSubstitutionData(SimObject* obj, S32 idx=0) { ss_object = obj; ss_index = idx; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _H_EXPLOSION
|
#endif // _H_EXPLOSION
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,11 @@
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
#include "particle.h"
|
#include "particle.h"
|
||||||
#include "console/consoleTypes.h"
|
#include "console/consoleTypes.h"
|
||||||
#include "console/typeValidators.h"
|
#include "console/typeValidators.h"
|
||||||
|
|
@ -653,3 +658,78 @@ DefineEngineMethod(ParticleData, reload, void, (),,
|
||||||
char errorBuffer[256];
|
char errorBuffer[256];
|
||||||
object->reload(errorBuffer);
|
object->reload(errorBuffer);
|
||||||
}
|
}
|
||||||
|
//#define TRACK_PARTICLE_DATA_CLONES
|
||||||
|
|
||||||
|
#ifdef TRACK_PARTICLE_DATA_CLONES
|
||||||
|
static int particle_data_clones = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ParticleData::ParticleData(const ParticleData& other, bool temp_clone) : SimDataBlock(other, temp_clone)
|
||||||
|
{
|
||||||
|
#ifdef TRACK_PARTICLE_DATA_CLONES
|
||||||
|
particle_data_clones++;
|
||||||
|
if (particle_data_clones == 1)
|
||||||
|
Con::errorf("ParticleData -- Clones are on the loose!");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dragCoefficient = other.dragCoefficient;
|
||||||
|
windCoefficient = other.windCoefficient;
|
||||||
|
gravityCoefficient = other.gravityCoefficient;
|
||||||
|
inheritedVelFactor = other.inheritedVelFactor;
|
||||||
|
constantAcceleration = other.constantAcceleration;
|
||||||
|
lifetimeMS = other.lifetimeMS;
|
||||||
|
lifetimeVarianceMS = other.lifetimeVarianceMS;
|
||||||
|
spinSpeed = other.spinSpeed;
|
||||||
|
spinRandomMin = other.spinRandomMin;
|
||||||
|
spinRandomMax = other.spinRandomMax;
|
||||||
|
useInvAlpha = other.useInvAlpha;
|
||||||
|
animateTexture = other.animateTexture;
|
||||||
|
numFrames = other.numFrames; // -- calc from other fields
|
||||||
|
framesPerSec = other.framesPerSec;
|
||||||
|
dMemcpy( colors, other.colors, sizeof( colors ) );
|
||||||
|
dMemcpy( sizes, other.sizes, sizeof( sizes ) );
|
||||||
|
dMemcpy( times, other.times, sizeof( times ) );
|
||||||
|
animTexUVs = other.animTexUVs; // -- calc from other fields
|
||||||
|
dMemcpy( texCoords, other.texCoords, sizeof( texCoords ) );
|
||||||
|
animTexTiling = other.animTexTiling;
|
||||||
|
animTexFramesString = other.animTexFramesString;
|
||||||
|
animTexFrames = other.animTexFrames; // -- parsed from animTexFramesString
|
||||||
|
textureName = other.textureName;
|
||||||
|
textureHandle = other.textureHandle;
|
||||||
|
spinBias = other.spinBias;
|
||||||
|
randomizeSpinDir = other.randomizeSpinDir;
|
||||||
|
textureExtName = other.textureExtName;
|
||||||
|
textureExtHandle = other.textureExtHandle;
|
||||||
|
constrain_pos = other.constrain_pos;
|
||||||
|
start_angle = other.start_angle;
|
||||||
|
angle_variance = other.angle_variance;
|
||||||
|
sizeBias = other.sizeBias;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParticleData::~ParticleData()
|
||||||
|
{
|
||||||
|
if (animTexUVs)
|
||||||
|
{
|
||||||
|
delete [] animTexUVs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isTempClone())
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef TRACK_PARTICLE_DATA_CLONES
|
||||||
|
if (particle_data_clones > 0)
|
||||||
|
{
|
||||||
|
particle_data_clones--;
|
||||||
|
if (particle_data_clones == 0)
|
||||||
|
Con::errorf("ParticleData -- Clones eliminated!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Con::errorf("ParticleData -- Too many clones deleted!");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleData::onPerformSubstitutions()
|
||||||
|
{
|
||||||
|
char errorBuffer[256];
|
||||||
|
reload(errorBuffer);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,10 @@ class ParticleData : public SimDataBlock
|
||||||
static void initPersistFields();
|
static void initPersistFields();
|
||||||
|
|
||||||
bool reload(char errorBuffer[256]);
|
bool reload(char errorBuffer[256]);
|
||||||
|
public:
|
||||||
|
/*C*/ ParticleData(const ParticleData&, bool = false);
|
||||||
|
virtual void onPerformSubstitutions();
|
||||||
|
virtual bool allowSubstitutions() const { return true; }
|
||||||
public:
|
public:
|
||||||
bool loadParameters();
|
bool loadParameters();
|
||||||
bool reload(String &errorStr);
|
bool reload(String &errorStr);
|
||||||
|
|
|
||||||
|
|
@ -712,6 +712,134 @@ void ParticleEmitterData::allocPrimBuffer( S32 overrideSize )
|
||||||
delete [] indices;
|
delete [] indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#define TRACK_PARTICLE_EMITTER_DATA_CLONES
|
||||||
|
|
||||||
|
#ifdef TRACK_PARTICLE_EMITTER_DATA_CLONES
|
||||||
|
static int emitter_data_clones = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ParticleEmitterData::ParticleEmitterData(const ParticleEmitterData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||||
|
{
|
||||||
|
#ifdef TRACK_PARTICLE_EMITTER_DATA_CLONES
|
||||||
|
emitter_data_clones++;
|
||||||
|
if (emitter_data_clones == 1)
|
||||||
|
Con::errorf("ParticleEmitterData -- Clones are on the loose!");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ejectionPeriodMS = other.ejectionPeriodMS;
|
||||||
|
periodVarianceMS = other.periodVarianceMS;
|
||||||
|
ejectionVelocity = other.ejectionVelocity;
|
||||||
|
velocityVariance = other.velocityVariance;
|
||||||
|
ejectionOffset = other.ejectionOffset;
|
||||||
|
ejectionOffsetVariance = other.ejectionOffsetVariance;
|
||||||
|
thetaMin = other.thetaMin;
|
||||||
|
thetaMax = other.thetaMax;
|
||||||
|
phiReferenceVel = other.phiReferenceVel;
|
||||||
|
phiVariance = other.phiVariance;
|
||||||
|
softnessDistance = other.softnessDistance;
|
||||||
|
ambientFactor = other.ambientFactor;
|
||||||
|
lifetimeMS = other.lifetimeMS;
|
||||||
|
lifetimeVarianceMS = other.lifetimeVarianceMS;
|
||||||
|
overrideAdvance = other.overrideAdvance;
|
||||||
|
orientParticles = other.orientParticles;
|
||||||
|
orientOnVelocity = other.orientOnVelocity;
|
||||||
|
useEmitterSizes = other.useEmitterSizes;
|
||||||
|
useEmitterColors = other.useEmitterColors;
|
||||||
|
alignParticles = other.alignParticles;
|
||||||
|
alignDirection = other.alignDirection;
|
||||||
|
particleString = other.particleString;
|
||||||
|
particleDataBlocks = other.particleDataBlocks; // -- derived from particleString
|
||||||
|
dataBlockIds = other.dataBlockIds; // -- derived from particleString
|
||||||
|
partListInitSize = other.partListInitSize; // -- approx calc from other fields
|
||||||
|
primBuff = other.primBuff;
|
||||||
|
blendStyle = other.blendStyle;
|
||||||
|
sortParticles = other.sortParticles;
|
||||||
|
reverseOrder = other.reverseOrder;
|
||||||
|
textureName = other.textureName;
|
||||||
|
textureHandle = other.textureHandle; // -- TextureHandle loads using textureName
|
||||||
|
highResOnly = other.highResOnly;
|
||||||
|
renderReflection = other.renderReflection;
|
||||||
|
fade_color = other.fade_color;
|
||||||
|
fade_size = other.fade_size;
|
||||||
|
fade_alpha = other.fade_alpha;
|
||||||
|
ejectionInvert = other.ejectionInvert;
|
||||||
|
parts_per_eject = other.parts_per_eject; // -- set to 1 (used by subclasses)
|
||||||
|
use_emitter_xfm = other.use_emitter_xfm;
|
||||||
|
#if defined(AFX_CAP_PARTICLE_POOLS)
|
||||||
|
pool_datablock = other.pool_datablock;
|
||||||
|
pool_index = other.pool_index;
|
||||||
|
pool_depth_fade = other.pool_depth_fade;
|
||||||
|
pool_radial_fade = other.pool_radial_fade;
|
||||||
|
do_pool_id_convert = other.do_pool_id_convert; // -- flags pool id conversion need
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ParticleEmitterData::~ParticleEmitterData()
|
||||||
|
{
|
||||||
|
if (!isTempClone())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (S32 i = 0; i < particleDataBlocks.size(); i++)
|
||||||
|
{
|
||||||
|
if (particleDataBlocks[i] && particleDataBlocks[i]->isTempClone())
|
||||||
|
{
|
||||||
|
delete particleDataBlocks[i];
|
||||||
|
particleDataBlocks[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TRACK_PARTICLE_EMITTER_DATA_CLONES
|
||||||
|
if (emitter_data_clones > 0)
|
||||||
|
{
|
||||||
|
emitter_data_clones--;
|
||||||
|
if (emitter_data_clones == 0)
|
||||||
|
Con::errorf("ParticleEmitterData -- Clones eliminated!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Con::errorf("ParticleEmitterData -- Too many clones deleted!");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ParticleEmitterData* ParticleEmitterData::cloneAndPerformSubstitutions(const SimObject* owner, S32 index)
|
||||||
|
{
|
||||||
|
if (!owner)
|
||||||
|
return this;
|
||||||
|
|
||||||
|
bool clone_parts_db = false;
|
||||||
|
|
||||||
|
// note -- this could be checked when the particle blocks are evaluated
|
||||||
|
for (S32 i = 0; i < this->particleDataBlocks.size(); i++)
|
||||||
|
{
|
||||||
|
if (this->particleDataBlocks[i] && (this->particleDataBlocks[i]->getSubstitutionCount() > 0))
|
||||||
|
{
|
||||||
|
clone_parts_db = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ParticleEmitterData* sub_emitter_db = this;
|
||||||
|
|
||||||
|
if (this->getSubstitutionCount() > 0 || clone_parts_db)
|
||||||
|
{
|
||||||
|
sub_emitter_db = new ParticleEmitterData(*this, true);
|
||||||
|
performSubstitutions(sub_emitter_db, owner, index);
|
||||||
|
|
||||||
|
if (clone_parts_db)
|
||||||
|
{
|
||||||
|
for (S32 i = 0; i < sub_emitter_db->particleDataBlocks.size(); i++)
|
||||||
|
{
|
||||||
|
if (sub_emitter_db->particleDataBlocks[i] && (sub_emitter_db->particleDataBlocks[i]->getSubstitutionCount() > 0))
|
||||||
|
{
|
||||||
|
ParticleData* orig_db = sub_emitter_db->particleDataBlocks[i];
|
||||||
|
sub_emitter_db->particleDataBlocks[i] = new ParticleData(*orig_db, true);
|
||||||
|
orig_db->performSubstitutions(sub_emitter_db->particleDataBlocks[i], owner, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sub_emitter_db;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// ParticleEmitter
|
// ParticleEmitter
|
||||||
|
|
@ -743,6 +871,7 @@ ParticleEmitter::ParticleEmitter()
|
||||||
|
|
||||||
// ParticleEmitter should be allocated on the client only.
|
// ParticleEmitter should be allocated on the client only.
|
||||||
mNetFlags.set( IsGhost );
|
mNetFlags.set( IsGhost );
|
||||||
|
mDataBlock = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -754,6 +883,19 @@ ParticleEmitter::~ParticleEmitter()
|
||||||
{
|
{
|
||||||
delete [] part_store[i];
|
delete [] part_store[i];
|
||||||
}
|
}
|
||||||
|
if (db_temp_clone && mDataBlock && mDataBlock->isTempClone())
|
||||||
|
{
|
||||||
|
for (S32 i = 0; i < mDataBlock->particleDataBlocks.size(); i++)
|
||||||
|
{
|
||||||
|
if (mDataBlock->particleDataBlocks[i] && mDataBlock->particleDataBlocks[i]->isTempClone())
|
||||||
|
{
|
||||||
|
delete mDataBlock->particleDataBlocks[i];
|
||||||
|
mDataBlock->particleDataBlocks[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete mDataBlock;
|
||||||
|
mDataBlock = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -832,6 +974,11 @@ bool ParticleEmitter::onNewDataBlock( GameBaseData *dptr, bool reload )
|
||||||
part_list_head.next = NULL;
|
part_list_head.next = NULL;
|
||||||
n_parts = 0;
|
n_parts = 0;
|
||||||
}
|
}
|
||||||
|
if (mDataBlock->isTempClone())
|
||||||
|
{
|
||||||
|
db_temp_clone = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
scriptOnNewDataBlock();
|
scriptOnNewDataBlock();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
#ifndef _H_PARTICLE_EMITTER
|
#ifndef _H_PARTICLE_EMITTER
|
||||||
#define _H_PARTICLE_EMITTER
|
#define _H_PARTICLE_EMITTER
|
||||||
|
|
||||||
|
|
@ -113,6 +117,11 @@ class ParticleEmitterData : public GameBaseData
|
||||||
bool glow; ///< Renders this emitter into the glow buffer.
|
bool glow; ///< Renders this emitter into the glow buffer.
|
||||||
|
|
||||||
bool reload();
|
bool reload();
|
||||||
|
public:
|
||||||
|
/*C*/ ParticleEmitterData(const ParticleEmitterData&, bool = false);
|
||||||
|
/*D*/ ~ParticleEmitterData();
|
||||||
|
virtual ParticleEmitterData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
|
||||||
|
virtual bool allowSubstitutions() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
#include "T3D/gameBase/gameBase.h"
|
#include "T3D/gameBase/gameBase.h"
|
||||||
#include "console/consoleTypes.h"
|
#include "console/consoleTypes.h"
|
||||||
|
|
@ -122,6 +126,12 @@ GameBaseData::GameBaseData()
|
||||||
category = "";
|
category = "";
|
||||||
packed = false;
|
packed = false;
|
||||||
}
|
}
|
||||||
|
GameBaseData::GameBaseData(const GameBaseData& other, bool temp_clone) : SimDataBlock(other, temp_clone)
|
||||||
|
{
|
||||||
|
packed = other.packed;
|
||||||
|
category = other.category;
|
||||||
|
//mReloadSignal = other.mReloadSignal; // DO NOT copy the mReloadSignal member.
|
||||||
|
}
|
||||||
|
|
||||||
void GameBaseData::inspectPostApply()
|
void GameBaseData::inspectPostApply()
|
||||||
{
|
{
|
||||||
|
|
@ -290,6 +300,9 @@ bool GameBase::onNewDataBlock( GameBaseData *dptr, bool reload )
|
||||||
|
|
||||||
if ( !mDataBlock )
|
if ( !mDataBlock )
|
||||||
return false;
|
return false;
|
||||||
|
// Don't set mask when new datablock is a temp-clone.
|
||||||
|
if (mDataBlock->isTempClone())
|
||||||
|
return true;
|
||||||
|
|
||||||
setMaskBits(DataBlockMask);
|
setMaskBits(DataBlockMask);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
#ifndef _GAMEBASE_H_
|
#ifndef _GAMEBASE_H_
|
||||||
#define _GAMEBASE_H_
|
#define _GAMEBASE_H_
|
||||||
|
|
||||||
|
|
@ -113,6 +117,8 @@ public:
|
||||||
DECLARE_CALLBACK( void, onMount, ( SceneObject* obj, SceneObject* mountObj, S32 node ) );
|
DECLARE_CALLBACK( void, onMount, ( SceneObject* obj, SceneObject* mountObj, S32 node ) );
|
||||||
DECLARE_CALLBACK( void, onUnmount, ( SceneObject* obj, SceneObject* mountObj, S32 node ) );
|
DECLARE_CALLBACK( void, onUnmount, ( SceneObject* obj, SceneObject* mountObj, S32 node ) );
|
||||||
/// @}
|
/// @}
|
||||||
|
public:
|
||||||
|
GameBaseData(const GameBaseData&, bool = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,40 @@ ProjectileData::ProjectileData()
|
||||||
lightDescId = 0;
|
lightDescId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProjectileData::ProjectileData(const ProjectileData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||||
|
{
|
||||||
|
projectileShapeName = other.projectileShapeName;
|
||||||
|
faceViewer = other.faceViewer; // -- always set to false
|
||||||
|
scale = other.scale;
|
||||||
|
velInheritFactor = other.velInheritFactor;
|
||||||
|
muzzleVelocity = other.muzzleVelocity;
|
||||||
|
impactForce = other.impactForce;
|
||||||
|
isBallistic = other.isBallistic;
|
||||||
|
bounceElasticity = other.bounceElasticity;
|
||||||
|
bounceFriction = other.bounceFriction;
|
||||||
|
gravityMod = other.gravityMod;
|
||||||
|
lifetime = other.lifetime;
|
||||||
|
armingDelay = other.armingDelay;
|
||||||
|
fadeDelay = other.fadeDelay;
|
||||||
|
explosion = other.explosion;
|
||||||
|
explosionId = other.explosionId; // -- for pack/unpack of explosion ptr
|
||||||
|
waterExplosion = other.waterExplosion;
|
||||||
|
waterExplosionId = other.waterExplosionId; // -- for pack/unpack of waterExplosion ptr
|
||||||
|
splash = other.splash;
|
||||||
|
splashId = other.splashId; // -- for pack/unpack of splash ptr
|
||||||
|
decal = other.decal;
|
||||||
|
decalId = other.decalId; // -- for pack/unpack of decal ptr
|
||||||
|
sound = other.sound;
|
||||||
|
lightDesc = other.lightDesc;
|
||||||
|
lightDescId = other.lightDescId; // -- for pack/unpack of lightDesc ptr
|
||||||
|
projectileShape = other.projectileShape; // -- TSShape loads using projectileShapeName
|
||||||
|
activateSeq = other.activateSeq; // -- from projectileShape sequence "activate"
|
||||||
|
maintainSeq = other.maintainSeq; // -- from projectileShape sequence "maintain"
|
||||||
|
particleEmitter = other.particleEmitter;
|
||||||
|
particleEmitterId = other.particleEmitterId; // -- for pack/unpack of particleEmitter ptr
|
||||||
|
particleWaterEmitter = other.particleWaterEmitter;
|
||||||
|
particleWaterEmitterId = other.particleWaterEmitterId; // -- for pack/unpack of particleWaterEmitter ptr
|
||||||
|
}
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
void ProjectileData::initPersistFields()
|
void ProjectileData::initPersistFields()
|
||||||
|
|
@ -585,6 +619,8 @@ Projectile::Projectile()
|
||||||
|
|
||||||
mLightState.clear();
|
mLightState.clear();
|
||||||
mLightState.setLightInfo( mLight );
|
mLightState.setLightInfo( mLight );
|
||||||
|
|
||||||
|
mDataBlock = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Projectile::~Projectile()
|
Projectile::~Projectile()
|
||||||
|
|
@ -593,6 +629,11 @@ Projectile::~Projectile()
|
||||||
|
|
||||||
delete mProjectileShape;
|
delete mProjectileShape;
|
||||||
mProjectileShape = NULL;
|
mProjectileShape = NULL;
|
||||||
|
if (mDataBlock && mDataBlock->isTempClone())
|
||||||
|
{
|
||||||
|
delete mDataBlock;
|
||||||
|
mDataBlock = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
#ifndef _PROJECTILE_H_
|
#ifndef _PROJECTILE_H_
|
||||||
#define _PROJECTILE_H_
|
#define _PROJECTILE_H_
|
||||||
|
|
||||||
|
|
@ -144,6 +148,9 @@ public:
|
||||||
|
|
||||||
DECLARE_CALLBACK( void, onExplode, ( Projectile* proj, Point3F pos, F32 fade ) );
|
DECLARE_CALLBACK( void, onExplode, ( Projectile* proj, Point3F pos, F32 fade ) );
|
||||||
DECLARE_CALLBACK( void, onCollision, ( Projectile* proj, SceneObject* col, F32 fade, Point3F pos, Point3F normal ) );
|
DECLARE_CALLBACK( void, onCollision, ( Projectile* proj, SceneObject* col, F32 fade, Point3F pos, Point3F normal ) );
|
||||||
|
public:
|
||||||
|
ProjectileData(const ProjectileData&, bool = false);
|
||||||
|
virtual bool allowSubstitutions() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -200,6 +200,66 @@ ShapeBaseData::ShapeBaseData()
|
||||||
dMemset( mountPointNode, -1, sizeof( S32 ) * SceneObject::NumMountPoints );
|
dMemset( mountPointNode, -1, sizeof( S32 ) * SceneObject::NumMountPoints );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShapeBaseData::ShapeBaseData(const ShapeBaseData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||||
|
{
|
||||||
|
shadowEnable = other.shadowEnable;
|
||||||
|
shadowSize = other.shadowSize;
|
||||||
|
shadowMaxVisibleDistance = other.shadowMaxVisibleDistance;
|
||||||
|
shadowProjectionDistance = other.shadowProjectionDistance;
|
||||||
|
shadowSphereAdjust = other.shadowSphereAdjust;
|
||||||
|
shapeName = other.shapeName;
|
||||||
|
cloakTexName = other.cloakTexName;
|
||||||
|
cubeDescName = other.cubeDescName;
|
||||||
|
cubeDescId = other.cubeDescId;
|
||||||
|
reflectorDesc = other.reflectorDesc;
|
||||||
|
debris = other.debris;
|
||||||
|
debrisID = other.debrisID; // -- for pack/unpack of debris ptr
|
||||||
|
debrisShapeName = other.debrisShapeName;
|
||||||
|
debrisShape = other.debrisShape; // -- TSShape loaded using debrisShapeName
|
||||||
|
explosion = other.explosion;
|
||||||
|
explosionID = other.explosionID; // -- for pack/unpack of explosion ptr
|
||||||
|
underwaterExplosion = other.underwaterExplosion;
|
||||||
|
underwaterExplosionID = other.underwaterExplosionID; // -- for pack/unpack of underwaterExplosion ptr
|
||||||
|
mass = other.mass;
|
||||||
|
drag = other.drag;
|
||||||
|
density = other.density;
|
||||||
|
maxEnergy = other.maxEnergy;
|
||||||
|
maxDamage = other.maxDamage;
|
||||||
|
repairRate = other.repairRate;
|
||||||
|
disabledLevel = other.disabledLevel;
|
||||||
|
destroyedLevel = other.destroyedLevel;
|
||||||
|
cameraMaxDist = other.cameraMaxDist;
|
||||||
|
cameraMinDist = other.cameraMinDist;
|
||||||
|
cameraDefaultFov = other.cameraDefaultFov;
|
||||||
|
cameraMinFov = other.cameraMinFov;
|
||||||
|
cameraMaxFov = other.cameraMaxFov;
|
||||||
|
cameraCanBank = other.cameraCanBank;
|
||||||
|
mountedImagesBank = other.mountedImagesBank;
|
||||||
|
mShape = other.mShape; // -- TSShape loaded using shapeName
|
||||||
|
mCRC = other.mCRC; // -- from shape, used to verify client shape
|
||||||
|
computeCRC = other.computeCRC;
|
||||||
|
eyeNode = other.eyeNode; // -- from shape node "eye"
|
||||||
|
earNode = other.earNode; // -- from shape node "ear"
|
||||||
|
cameraNode = other.cameraNode; // -- from shape node "cam"
|
||||||
|
dMemcpy(mountPointNode, other.mountPointNode, sizeof(mountPointNode)); // -- from shape nodes "mount#" 0-31
|
||||||
|
debrisDetail = other.debrisDetail; // -- from shape detail "Debris-17"
|
||||||
|
damageSequence = other.damageSequence; // -- from shape sequence "Damage"
|
||||||
|
hulkSequence = other.hulkSequence; // -- from shape sequence "Visibility"
|
||||||
|
observeThroughObject = other.observeThroughObject;
|
||||||
|
collisionDetails = other.collisionDetails; // -- calc from shape (this is a Vector copy)
|
||||||
|
collisionBounds = other.collisionBounds; // -- calc from shape (this is a Vector copy)
|
||||||
|
LOSDetails = other.LOSDetails; // -- calc from shape (this is a Vector copy)
|
||||||
|
firstPersonOnly = other.firstPersonOnly;
|
||||||
|
useEyePoint = other.useEyePoint;
|
||||||
|
isInvincible = other.isInvincible;
|
||||||
|
renderWhenDestroyed = other.renderWhenDestroyed;
|
||||||
|
inheritEnergyFromMount = other.inheritEnergyFromMount;
|
||||||
|
remap_txr_tags = other.remap_txr_tags;
|
||||||
|
remap_buffer = other.remap_buffer;
|
||||||
|
txr_tag_remappings = other.txr_tag_remappings;
|
||||||
|
silent_bbox_check = other.silent_bbox_check;
|
||||||
|
}
|
||||||
|
|
||||||
struct ShapeBaseDataProto
|
struct ShapeBaseDataProto
|
||||||
{
|
{
|
||||||
F32 mass;
|
F32 mass;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
#ifndef _SHAPEBASE_H_
|
#ifndef _SHAPEBASE_H_
|
||||||
#define _SHAPEBASE_H_
|
#define _SHAPEBASE_H_
|
||||||
|
|
||||||
|
|
@ -654,6 +658,8 @@ public:
|
||||||
DECLARE_CALLBACK(void, onEndSequence, (ShapeBase* obj, S32 slot, const char* name));
|
DECLARE_CALLBACK(void, onEndSequence, (ShapeBase* obj, S32 slot, const char* name));
|
||||||
DECLARE_CALLBACK( void, onForceUncloak, ( ShapeBase* obj, const char* reason ) );
|
DECLARE_CALLBACK( void, onForceUncloak, ( ShapeBase* obj, const char* reason ) );
|
||||||
/// @}
|
/// @}
|
||||||
|
public:
|
||||||
|
ShapeBaseData(const ShapeBaseData&, bool = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
#include "core/dnet.h"
|
#include "core/dnet.h"
|
||||||
#include "core/stream/bitStream.h"
|
#include "core/stream/bitStream.h"
|
||||||
|
|
@ -97,6 +101,14 @@ StaticShapeData::StaticShapeData()
|
||||||
noIndividualDamage = false;
|
noIndividualDamage = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StaticShapeData::StaticShapeData(const StaticShapeData& other, bool temp_clone) : ShapeBaseData(other, temp_clone)
|
||||||
|
{
|
||||||
|
noIndividualDamage = other.noIndividualDamage;
|
||||||
|
dynamicTypeField = other.dynamicTypeField;
|
||||||
|
isShielded = other.isShielded; // -- uninitialized, unused
|
||||||
|
energyPerDamagePoint = other.energyPerDamagePoint; // -- uninitialized, unused
|
||||||
|
}
|
||||||
|
|
||||||
void StaticShapeData::initPersistFields()
|
void StaticShapeData::initPersistFields()
|
||||||
{
|
{
|
||||||
addField("noIndividualDamage", TypeBool, Offset(noIndividualDamage, StaticShapeData), "Deprecated\n\n @internal");
|
addField("noIndividualDamage", TypeBool, Offset(noIndividualDamage, StaticShapeData), "Deprecated\n\n @internal");
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,11 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
|
||||||
#ifndef _STATICSHAPE_H_
|
#ifndef _STATICSHAPE_H_
|
||||||
#define _STATICSHAPE_H_
|
#define _STATICSHAPE_H_
|
||||||
|
|
||||||
|
|
@ -38,12 +43,16 @@ struct StaticShapeData: public ShapeBaseData {
|
||||||
bool noIndividualDamage;
|
bool noIndividualDamage;
|
||||||
S32 dynamicTypeField;
|
S32 dynamicTypeField;
|
||||||
bool isShielded;
|
bool isShielded;
|
||||||
|
F32 energyPerDamagePoint; // Re-added for AFX
|
||||||
|
|
||||||
//
|
//
|
||||||
DECLARE_CONOBJECT(StaticShapeData);
|
DECLARE_CONOBJECT(StaticShapeData);
|
||||||
static void initPersistFields();
|
static void initPersistFields();
|
||||||
virtual void packData(BitStream* stream);
|
virtual void packData(BitStream* stream);
|
||||||
virtual void unpackData(BitStream* stream);
|
virtual void unpackData(BitStream* stream);
|
||||||
|
public:
|
||||||
|
StaticShapeData(const StaticShapeData&, bool = false);
|
||||||
|
virtual bool allowSubstitutions() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,12 +92,17 @@ SimObject::SimObject()
|
||||||
|
|
||||||
mCopySource = NULL;
|
mCopySource = NULL;
|
||||||
mPersistentId = NULL;
|
mPersistentId = NULL;
|
||||||
|
is_temp_clone = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
SimObject::~SimObject()
|
SimObject::~SimObject()
|
||||||
{
|
{
|
||||||
|
// if this is a temp-clone, we don't delete any members that were shallow-copied
|
||||||
|
// over from the source datablock.
|
||||||
|
if (is_temp_clone)
|
||||||
|
return;
|
||||||
if( mFieldDictionary )
|
if( mFieldDictionary )
|
||||||
{
|
{
|
||||||
delete mFieldDictionary;
|
delete mFieldDictionary;
|
||||||
|
|
@ -1327,6 +1332,43 @@ void SimObject::setDataFieldType(const char *typeName, StringTableEntry slotName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is the copy-constructor used to create temporary datablock clones.
|
||||||
|
// The <temp_clone> argument is added to distinguish this copy-constructor
|
||||||
|
// from any general-purpose copy-constructor that might be needed in the
|
||||||
|
// future. <temp_clone> should always be true when creating temporary
|
||||||
|
// datablock clones.
|
||||||
|
//
|
||||||
|
SimObject::SimObject(const SimObject& other, bool temp_clone)
|
||||||
|
{
|
||||||
|
is_temp_clone = temp_clone;
|
||||||
|
|
||||||
|
objectName = other.objectName;
|
||||||
|
mOriginalName = other.mOriginalName;
|
||||||
|
nextNameObject = other.nextNameObject;
|
||||||
|
nextManagerNameObject = other.nextManagerNameObject;
|
||||||
|
nextIdObject = other.nextIdObject;
|
||||||
|
mGroup = other.mGroup;
|
||||||
|
mFlags = other.mFlags;
|
||||||
|
mCopySource = other.mCopySource;
|
||||||
|
mFieldDictionary = other.mFieldDictionary;
|
||||||
|
//mIdString = other.mIdString; // special treatment (see below)
|
||||||
|
mFilename = other.mFilename;
|
||||||
|
mDeclarationLine = other.mDeclarationLine;
|
||||||
|
mNotifyList = other.mNotifyList;
|
||||||
|
mId = other.mId;
|
||||||
|
mInternalName = other.mInternalName;
|
||||||
|
mCanSaveFieldDictionary = other.mCanSaveFieldDictionary;
|
||||||
|
mPersistentId = other.mPersistentId;
|
||||||
|
mNameSpace = other.mNameSpace;
|
||||||
|
mClassName = other.mClassName;
|
||||||
|
mSuperClassName = other.mSuperClassName;
|
||||||
|
preventNameChanging = other.preventNameChanging;
|
||||||
|
|
||||||
|
if (mId)
|
||||||
|
dSprintf( mIdString, sizeof( mIdString ), "%u", mId );
|
||||||
|
else
|
||||||
|
mIdString[ 0 ] = '\0';
|
||||||
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void SimObject::dumpClassHierarchy()
|
void SimObject::dumpClassHierarchy()
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
#ifndef _SIMOBJECT_H_
|
#ifndef _SIMOBJECT_H_
|
||||||
#define _SIMOBJECT_H_
|
#define _SIMOBJECT_H_
|
||||||
|
|
||||||
|
|
@ -970,6 +974,12 @@ class SimObject: public ConsoleObject, public TamlCallbacks
|
||||||
|
|
||||||
// EngineObject.
|
// EngineObject.
|
||||||
virtual void destroySelf();
|
virtual void destroySelf();
|
||||||
|
protected:
|
||||||
|
bool is_temp_clone;
|
||||||
|
public:
|
||||||
|
/*C*/ SimObject(const SimObject&, bool = false);
|
||||||
|
bool isTempClone() const { return is_temp_clone; }
|
||||||
|
virtual bool allowSubstitutions() const { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
|
|
||||||
#include "sfx/sfxDescription.h"
|
#include "sfx/sfxDescription.h"
|
||||||
|
|
@ -176,6 +180,37 @@ SFXDescription::SFXDescription( const SFXDescription& desc )
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
SFXDescription::SFXDescription(const SFXDescription& other, bool temp_clone)
|
||||||
|
: SimDataBlock(other, temp_clone),
|
||||||
|
mVolume( other.mVolume ),
|
||||||
|
mPitch( other.mPitch ),
|
||||||
|
mIsLooping( other.mIsLooping ),
|
||||||
|
mIsStreaming( other.mIsStreaming ),
|
||||||
|
mIs3D( other.mIs3D ),
|
||||||
|
mUseHardware( other.mUseHardware ),
|
||||||
|
mMinDistance( other.mMinDistance ),
|
||||||
|
mMaxDistance( other.mMaxDistance ),
|
||||||
|
mConeInsideAngle( other.mConeInsideAngle ),
|
||||||
|
mConeOutsideAngle( other.mConeOutsideAngle ),
|
||||||
|
mConeOutsideVolume( other.mConeOutsideVolume ),
|
||||||
|
mRolloffFactor( other.mRolloffFactor ),
|
||||||
|
mSourceGroup( other.mSourceGroup ),
|
||||||
|
mFadeInTime( other.mFadeInTime ),
|
||||||
|
mFadeOutTime( other.mFadeOutTime ),
|
||||||
|
mFadeInEase( other.mFadeInEase ),
|
||||||
|
mFadeOutEase( other.mFadeOutEase ),
|
||||||
|
mFadeLoops( other.mFadeLoops ),
|
||||||
|
mStreamPacketSize( other.mStreamPacketSize ),
|
||||||
|
mStreamReadAhead( other.mStreamReadAhead ),
|
||||||
|
mUseReverb( other.mUseReverb ),
|
||||||
|
mReverb( other.mReverb ),
|
||||||
|
mPriority( other.mPriority ),
|
||||||
|
mScatterDistance( other.mScatterDistance )
|
||||||
|
{
|
||||||
|
for( U32 i = 0; i < MaxNumParameters; ++ i )
|
||||||
|
mParameters[ i ] = other.mParameters[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
void SFXDescription::initPersistFields()
|
void SFXDescription::initPersistFields()
|
||||||
{
|
{
|
||||||
addGroup( "Playback" );
|
addGroup( "Playback" );
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
#ifndef _SFXDESCRIPTION_H_
|
#ifndef _SFXDESCRIPTION_H_
|
||||||
#define _SFXDESCRIPTION_H_
|
#define _SFXDESCRIPTION_H_
|
||||||
|
|
||||||
|
|
@ -192,6 +196,9 @@ class SFXDescription : public SimDataBlock
|
||||||
/// Validates the description fixing any
|
/// Validates the description fixing any
|
||||||
/// parameters that are out of range.
|
/// parameters that are out of range.
|
||||||
void validate();
|
void validate();
|
||||||
|
public:
|
||||||
|
SFXDescription(const SFXDescription&, bool);
|
||||||
|
virtual bool allowSubstitutions() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
// Copyright (C) 2015 Faust Logic, Inc.
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
|
|
||||||
#include "sfx/sfxProfile.h"
|
#include "sfx/sfxProfile.h"
|
||||||
|
|
@ -96,9 +97,6 @@ SFXProfile::SFXProfile( SFXDescription* desc, const String& filename, bool prelo
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
SFXProfile::~SFXProfile()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -380,3 +378,95 @@ DefineEngineMethod( SFXProfile, getSoundDuration, F32, (),,
|
||||||
{
|
{
|
||||||
return ( F32 ) object->getSoundDuration() * 0.001f;
|
return ( F32 ) object->getSoundDuration() * 0.001f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// enable this to help verify that temp-clones of AudioProfile are being deleted
|
||||||
|
//#define TRACK_AUDIO_PROFILE_CLONES
|
||||||
|
|
||||||
|
#ifdef TRACK_AUDIO_PROFILE_CLONES
|
||||||
|
static int audio_prof_clones = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SFXProfile::SFXProfile(const SFXProfile& other, bool temp_clone) : SFXTrack(other, temp_clone)
|
||||||
|
{
|
||||||
|
#ifdef TRACK_AUDIO_PROFILE_CLONES
|
||||||
|
audio_prof_clones++;
|
||||||
|
if (audio_prof_clones == 1)
|
||||||
|
Con::errorf("SFXProfile -- Clones are on the loose!");
|
||||||
|
#endif
|
||||||
|
mResource = other.mResource;
|
||||||
|
mFilename = other.mFilename;
|
||||||
|
mPreload = other.mPreload;
|
||||||
|
mBuffer = other.mBuffer; // -- AudioBuffer loaded using mFilename
|
||||||
|
mChangedSignal = other.mChangedSignal;
|
||||||
|
}
|
||||||
|
|
||||||
|
SFXProfile::~SFXProfile()
|
||||||
|
{
|
||||||
|
if (!isTempClone())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// cleanup after a temp-clone
|
||||||
|
|
||||||
|
if (mDescription && mDescription->isTempClone())
|
||||||
|
{
|
||||||
|
delete mDescription;
|
||||||
|
mDescription = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TRACK_AUDIO_PROFILE_CLONES
|
||||||
|
if (audio_prof_clones > 0)
|
||||||
|
{
|
||||||
|
audio_prof_clones--;
|
||||||
|
if (audio_prof_clones == 0)
|
||||||
|
Con::errorf("SFXProfile -- Clones eliminated!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Con::errorf("SFXProfile -- Too many clones deleted!");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone and perform substitutions on the SFXProfile and on any SFXDescription
|
||||||
|
// it references.
|
||||||
|
SFXProfile* SFXProfile::cloneAndPerformSubstitutions(const SimObject* owner, S32 index)
|
||||||
|
{
|
||||||
|
if (!owner)
|
||||||
|
return this;
|
||||||
|
|
||||||
|
SFXProfile* sub_profile_db = this;
|
||||||
|
|
||||||
|
// look for mDescriptionObject subs
|
||||||
|
SFXDescription* desc_db;
|
||||||
|
if (mDescription && mDescription->getSubstitutionCount() > 0)
|
||||||
|
{
|
||||||
|
SFXDescription* orig_db = mDescription;
|
||||||
|
desc_db = new SFXDescription(*orig_db, true);
|
||||||
|
orig_db->performSubstitutions(desc_db, owner, index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
desc_db = 0;
|
||||||
|
|
||||||
|
if (this->getSubstitutionCount() > 0 || desc_db)
|
||||||
|
{
|
||||||
|
sub_profile_db = new SFXProfile(*this, true);
|
||||||
|
performSubstitutions(sub_profile_db, owner, index);
|
||||||
|
if (desc_db)
|
||||||
|
sub_profile_db->mDescription = desc_db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sub_profile_db;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SFXProfile::onPerformSubstitutions()
|
||||||
|
{
|
||||||
|
if ( SFX )
|
||||||
|
{
|
||||||
|
// If preload is enabled we load the resource
|
||||||
|
// and device buffer now to avoid a delay on
|
||||||
|
// first playback.
|
||||||
|
if ( mPreload && !_preloadBuffer() )
|
||||||
|
Con::errorf( "SFXProfile(%s)::onPerformSubstitutions: The preload failed!", getName() );
|
||||||
|
|
||||||
|
// We need to get device change notifications.
|
||||||
|
SFX->getEventSignal().notify( this, &SFXProfile::_onDeviceEvent );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,11 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
|
||||||
#ifndef _SFXPROFILE_H_
|
#ifndef _SFXPROFILE_H_
|
||||||
#define _SFXPROFILE_H_
|
#define _SFXPROFILE_H_
|
||||||
|
|
||||||
|
|
@ -175,6 +180,11 @@ class SFXProfile : public SFXTrack
|
||||||
|
|
||||||
///
|
///
|
||||||
ChangedSignal& getChangedSignal() { return mChangedSignal; }
|
ChangedSignal& getChangedSignal() { return mChangedSignal; }
|
||||||
|
public:
|
||||||
|
/*C*/ SFXProfile(const SFXProfile&, bool = false);
|
||||||
|
SFXProfile* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
|
||||||
|
virtual void onPerformSubstitutions();
|
||||||
|
virtual bool allowSubstitutions() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
#include "sfx/sfxTrack.h"
|
#include "sfx/sfxTrack.h"
|
||||||
#include "sfx/sfxTypes.h"
|
#include "sfx/sfxTypes.h"
|
||||||
#include "sfx/sfxDescription.h"
|
#include "sfx/sfxDescription.h"
|
||||||
|
|
@ -65,6 +69,11 @@ SFXTrack::SFXTrack( SFXDescription* description )
|
||||||
dMemset( mParameters, 0, sizeof( mParameters ) );
|
dMemset( mParameters, 0, sizeof( mParameters ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SFXTrack::SFXTrack(const SFXTrack& other, bool temp_clone) : SimDataBlock(other, temp_clone)
|
||||||
|
{
|
||||||
|
mDescription = other.mDescription;
|
||||||
|
dMemcpy(mParameters, other.mParameters, sizeof(mParameters));
|
||||||
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void SFXTrack::initPersistFields()
|
void SFXTrack::initPersistFields()
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||||
|
// Copyright (C) 2015 Faust Logic, Inc.
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||||
#ifndef _SFXTRACK_H_
|
#ifndef _SFXTRACK_H_
|
||||||
#define _SFXTRACK_H_
|
#define _SFXTRACK_H_
|
||||||
|
|
||||||
|
|
@ -92,6 +96,8 @@ class SFXTrack : public SimDataBlock
|
||||||
DECLARE_CONOBJECT( SFXTrack );
|
DECLARE_CONOBJECT( SFXTrack );
|
||||||
DECLARE_CATEGORY( "SFX" );
|
DECLARE_CATEGORY( "SFX" );
|
||||||
DECLARE_DESCRIPTION( "Abstract base class for any kind of data that can be turned into SFXSources." );
|
DECLARE_DESCRIPTION( "Abstract base class for any kind of data that can be turned into SFXSources." );
|
||||||
|
public:
|
||||||
|
/*C*/ SFXTrack(const SFXTrack&, bool = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !_SFXTRACK_H_
|
#endif // !_SFXTRACK_H_
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue