mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-14 04:03:46 +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
|
|
@ -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() );
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue