mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-28 11:03:49 +00:00
datablock-temp-clone -- Implements creation of temporary datablock clones to allow late substitution of datablock fields.
This commit is contained in:
parent
83c533249f
commit
43815793d1
24 changed files with 865 additions and 11 deletions
|
|
@ -117,6 +117,85 @@ DebrisData::DebrisData()
|
|||
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()
|
||||
{
|
||||
if(!Parent::onAdd())
|
||||
|
|
@ -458,6 +537,8 @@ Debris::Debris()
|
|||
|
||||
// Only allocated client side.
|
||||
mNetFlags.set( IsGhost );
|
||||
ss_object = 0;
|
||||
ss_index = 0;
|
||||
}
|
||||
|
||||
Debris::~Debris()
|
||||
|
|
@ -473,6 +554,12 @@ Debris::~Debris()
|
|||
delete mPart;
|
||||
mPart = NULL;
|
||||
}
|
||||
|
||||
if (mDataBlock && mDataBlock->isTempClone())
|
||||
{
|
||||
delete mDataBlock;
|
||||
mDataBlock = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Debris::initPersistFields()
|
||||
|
|
@ -502,6 +589,8 @@ bool Debris::onNewDataBlock( GameBaseData *dptr, bool reload )
|
|||
if( !mDataBlock || !Parent::onNewDataBlock( dptr, reload ) )
|
||||
return false;
|
||||
|
||||
if (mDataBlock->isTempClone())
|
||||
return true;
|
||||
scriptOnNewDataBlock();
|
||||
return true;
|
||||
|
||||
|
|
@ -526,7 +615,7 @@ bool Debris::onAdd()
|
|||
if( mDataBlock->emitterList[i] != NULL )
|
||||
{
|
||||
ParticleEmitter * pEmitter = new ParticleEmitter;
|
||||
pEmitter->onNewDataBlock( mDataBlock->emitterList[i], false );
|
||||
pEmitter->onNewDataBlock(mDataBlock->emitterList[i]->cloneAndPerformSubstitutions(ss_object, ss_index), false);
|
||||
if( !pEmitter->registerObject() )
|
||||
{
|
||||
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();
|
||||
|
||||
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 );
|
||||
trans.setPosition( getPosition() );
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@
|
|||
// 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_
|
||||
#define _DEBRIS_H_
|
||||
|
||||
|
|
@ -97,6 +102,12 @@ struct DebrisData : public GameBaseData
|
|||
|
||||
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);
|
||||
|
||||
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
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "T3D/fx/explosion.h"
|
||||
|
||||
|
|
@ -54,6 +55,8 @@
|
|||
#include "renderInstance/renderPassManager.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
#include "sfx/sfxProfile.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(Explosion);
|
||||
|
||||
ConsoleDocClass( Explosion,
|
||||
|
|
@ -285,6 +288,105 @@ ExplosionData::ExplosionData()
|
|||
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()
|
||||
{
|
||||
addField( "explosionShape", TypeShapeFilename, Offset(dtsFileName, ExplosionData),
|
||||
|
|
@ -818,6 +920,10 @@ Explosion::Explosion()
|
|||
mLight = LIGHTMGR->createLightInfo();
|
||||
|
||||
mNetFlags.set( IsGhost );
|
||||
ss_object = 0;
|
||||
ss_index = 0;
|
||||
mDataBlock = 0;
|
||||
soundProfile_clone = 0;
|
||||
}
|
||||
|
||||
Explosion::~Explosion()
|
||||
|
|
@ -830,6 +936,18 @@ Explosion::~Explosion()
|
|||
}
|
||||
|
||||
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 ))
|
||||
return false;
|
||||
|
||||
if (mDataBlock->isTempClone())
|
||||
return true;
|
||||
scriptOnNewDataBlock();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1200,7 +1320,8 @@ void Explosion::launchDebris( Point3F &axis )
|
|||
launchDir *= debrisVel;
|
||||
|
||||
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->init( pos, launchDir );
|
||||
|
||||
|
|
@ -1228,7 +1349,8 @@ void Explosion::spawnSubExplosions()
|
|||
{
|
||||
MatrixF trans = getTransform();
|
||||
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->setInitialState( trans.getPosition(), mInitialNormal, 1);
|
||||
if (!pExplosion->registerObject())
|
||||
|
|
@ -1266,12 +1388,18 @@ bool Explosion::explode()
|
|||
resetWorldBox();
|
||||
}
|
||||
|
||||
if (mDataBlock->soundProfile)
|
||||
SFX->playOnce( mDataBlock->soundProfile, &getTransform() );
|
||||
SFXProfile* sound_prof = dynamic_cast<SFXProfile*>(mDataBlock->soundProfile);
|
||||
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) {
|
||||
mMainEmitter = new ParticleEmitter;
|
||||
mMainEmitter->setDataBlock(mDataBlock->particleEmitter);
|
||||
mMainEmitter->setDataBlock(mDataBlock->particleEmitter->cloneAndPerformSubstitutions(ss_object, ss_index));
|
||||
mMainEmitter->registerObject();
|
||||
|
||||
mMainEmitter->emitParticles(getPosition(), mInitialNormal, mDataBlock->particleRadius,
|
||||
|
|
@ -1283,7 +1411,7 @@ bool Explosion::explode()
|
|||
if( mDataBlock->emitterList[i] != NULL )
|
||||
{
|
||||
ParticleEmitter * pEmitter = new ParticleEmitter;
|
||||
pEmitter->setDataBlock( mDataBlock->emitterList[i] );
|
||||
pEmitter->setDataBlock(mDataBlock->emitterList[i]->cloneAndPerformSubstitutions(ss_object, ss_index));
|
||||
if( !pEmitter->registerObject() )
|
||||
{
|
||||
Con::warnf( ConsoleLogEntry::General, "Could not register emitter for particle of class: %s", mDataBlock->getName() );
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@
|
|||
// 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_
|
||||
#define _EXPLOSION_H_
|
||||
|
||||
|
|
@ -42,6 +47,7 @@ class TSThread;
|
|||
class SFXTrack;
|
||||
struct DebrisData;
|
||||
|
||||
class SFXProfile;
|
||||
//--------------------------------------------------------------------------
|
||||
class ExplosionData : public GameBaseData {
|
||||
public:
|
||||
|
|
@ -126,6 +132,11 @@ class ExplosionData : public GameBaseData {
|
|||
static void initPersistFields();
|
||||
virtual void packData(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);
|
||||
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
|
||||
|
|
|
|||
|
|
@ -19,6 +19,11 @@
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// 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 "console/consoleTypes.h"
|
||||
#include "console/typeValidators.h"
|
||||
|
|
@ -653,3 +658,78 @@ DefineEngineMethod(ParticleData, reload, void, (),,
|
|||
char errorBuffer[256];
|
||||
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();
|
||||
|
||||
bool reload(char errorBuffer[256]);
|
||||
public:
|
||||
/*C*/ ParticleData(const ParticleData&, bool = false);
|
||||
virtual void onPerformSubstitutions();
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
public:
|
||||
bool loadParameters();
|
||||
bool reload(String &errorStr);
|
||||
|
|
|
|||
|
|
@ -712,6 +712,134 @@ void ParticleEmitterData::allocPrimBuffer( S32 overrideSize )
|
|||
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
|
||||
|
|
@ -743,6 +871,7 @@ ParticleEmitter::ParticleEmitter()
|
|||
|
||||
// ParticleEmitter should be allocated on the client only.
|
||||
mNetFlags.set( IsGhost );
|
||||
mDataBlock = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -754,6 +883,19 @@ ParticleEmitter::~ParticleEmitter()
|
|||
{
|
||||
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;
|
||||
n_parts = 0;
|
||||
}
|
||||
if (mDataBlock->isTempClone())
|
||||
{
|
||||
db_temp_clone = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@
|
|||
// 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
|
||||
#define _H_PARTICLE_EMITTER
|
||||
|
||||
|
|
@ -113,6 +117,11 @@ class ParticleEmitterData : public GameBaseData
|
|||
bool glow; ///< Renders this emitter into the glow buffer.
|
||||
|
||||
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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
#include "platform/platform.h"
|
||||
#include "T3D/gameBase/gameBase.h"
|
||||
#include "console/consoleTypes.h"
|
||||
|
|
@ -122,6 +126,12 @@ GameBaseData::GameBaseData()
|
|||
category = "";
|
||||
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()
|
||||
{
|
||||
|
|
@ -290,6 +300,9 @@ bool GameBase::onNewDataBlock( GameBaseData *dptr, bool reload )
|
|||
|
||||
if ( !mDataBlock )
|
||||
return false;
|
||||
// Don't set mask when new datablock is a temp-clone.
|
||||
if (mDataBlock->isTempClone())
|
||||
return true;
|
||||
|
||||
setMaskBits(DataBlockMask);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@
|
|||
// 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_
|
||||
#define _GAMEBASE_H_
|
||||
|
||||
|
|
@ -113,6 +117,8 @@ public:
|
|||
DECLARE_CALLBACK( void, onMount, ( 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;
|
||||
}
|
||||
|
||||
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()
|
||||
|
|
@ -585,6 +619,8 @@ Projectile::Projectile()
|
|||
|
||||
mLightState.clear();
|
||||
mLightState.setLightInfo( mLight );
|
||||
|
||||
mDataBlock = 0;
|
||||
}
|
||||
|
||||
Projectile::~Projectile()
|
||||
|
|
@ -593,6 +629,11 @@ Projectile::~Projectile()
|
|||
|
||||
delete mProjectileShape;
|
||||
mProjectileShape = NULL;
|
||||
if (mDataBlock && mDataBlock->isTempClone())
|
||||
{
|
||||
delete mDataBlock;
|
||||
mDataBlock = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@
|
|||
// 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_
|
||||
#define _PROJECTILE_H_
|
||||
|
||||
|
|
@ -144,6 +148,9 @@ public:
|
|||
|
||||
DECLARE_CALLBACK( void, onExplode, ( Projectile* proj, Point3F pos, F32 fade ) );
|
||||
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 );
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
F32 mass;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@
|
|||
// 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_
|
||||
#define _SHAPEBASE_H_
|
||||
|
||||
|
|
@ -654,6 +658,8 @@ public:
|
|||
DECLARE_CALLBACK(void, onEndSequence, (ShapeBase* obj, S32 slot, const char* name));
|
||||
DECLARE_CALLBACK( void, onForceUncloak, ( ShapeBase* obj, const char* reason ) );
|
||||
/// @}
|
||||
public:
|
||||
ShapeBaseData(const ShapeBaseData&, bool = false);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@
|
|||
// 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 "core/dnet.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
|
|
@ -97,6 +101,14 @@ StaticShapeData::StaticShapeData()
|
|||
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()
|
||||
{
|
||||
addField("noIndividualDamage", TypeBool, Offset(noIndividualDamage, StaticShapeData), "Deprecated\n\n @internal");
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@
|
|||
// 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_
|
||||
#define _STATICSHAPE_H_
|
||||
|
||||
|
|
@ -38,12 +43,16 @@ struct StaticShapeData: public ShapeBaseData {
|
|||
bool noIndividualDamage;
|
||||
S32 dynamicTypeField;
|
||||
bool isShielded;
|
||||
F32 energyPerDamagePoint; // Re-added for AFX
|
||||
|
||||
//
|
||||
DECLARE_CONOBJECT(StaticShapeData);
|
||||
static void initPersistFields();
|
||||
virtual void packData(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;
|
||||
mPersistentId = NULL;
|
||||
is_temp_clone = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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 )
|
||||
{
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@
|
|||
// 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_
|
||||
#define _SIMOBJECT_H_
|
||||
|
||||
|
|
@ -970,6 +974,12 @@ class SimObject: public ConsoleObject, public TamlCallbacks
|
|||
|
||||
// EngineObject.
|
||||
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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
#include "platform/platform.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()
|
||||
{
|
||||
addGroup( "Playback" );
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@
|
|||
// 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_
|
||||
#define _SFXDESCRIPTION_H_
|
||||
|
||||
|
|
@ -192,6 +196,9 @@ class SFXDescription : public SimDataBlock
|
|||
/// Validates the description fixing any
|
||||
/// parameters that are out of range.
|
||||
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
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "platform/platform.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;
|
||||
}
|
||||
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#ifndef _SFXPROFILE_H_
|
||||
#define _SFXPROFILE_H_
|
||||
|
||||
|
|
@ -175,6 +180,11 @@ class SFXProfile : public SFXTrack
|
|||
|
||||
///
|
||||
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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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/sfxTypes.h"
|
||||
#include "sfx/sfxDescription.h"
|
||||
|
|
@ -65,6 +69,11 @@ SFXTrack::SFXTrack( SFXDescription* description )
|
|||
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()
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@
|
|||
// 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_
|
||||
#define _SFXTRACK_H_
|
||||
|
||||
|
|
@ -92,6 +96,8 @@ class SFXTrack : public SimDataBlock
|
|||
DECLARE_CONOBJECT( SFXTrack );
|
||||
DECLARE_CATEGORY( "SFX" );
|
||||
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_
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue