Initial commit
This commit is contained in:
262
Torque/SDK/engine/game/fx/particleEmitter.cc
Normal file
262
Torque/SDK/engine/game/fx/particleEmitter.cc
Normal file
@@ -0,0 +1,262 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/bitStream.h"
|
||||
#include "game/fx/particleEmitter.h"
|
||||
#include "game/fx/particleEngine.h"
|
||||
#include "math/mathIO.h"
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(ParticleEmitterNodeData);
|
||||
IMPLEMENT_CO_NETOBJECT_V1(ParticleEmitterNode);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------
|
||||
//
|
||||
ParticleEmitterNodeData::ParticleEmitterNodeData()
|
||||
{
|
||||
timeMultiple = 1.0;
|
||||
}
|
||||
|
||||
ParticleEmitterNodeData::~ParticleEmitterNodeData()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void ParticleEmitterNodeData::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
|
||||
addField("timeMultiple", TypeF32, Offset(timeMultiple, ParticleEmitterNodeData));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
bool ParticleEmitterNodeData::onAdd()
|
||||
{
|
||||
if(!Parent::onAdd())
|
||||
return false;
|
||||
|
||||
if (timeMultiple < 0.01 || timeMultiple > 100) {
|
||||
Con::warnf("ParticleEmitterNodeData::onAdd(%s): timeMultiple must be between 0.01 and 100", getName());
|
||||
timeMultiple = timeMultiple < 0.01 ? 0.01 : 100;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ParticleEmitterNodeData::preload(bool server, char errorBuffer[256])
|
||||
{
|
||||
if (Parent::preload(server, errorBuffer) == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void ParticleEmitterNodeData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->write(timeMultiple);
|
||||
}
|
||||
|
||||
void ParticleEmitterNodeData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
stream->read(&timeMultiple);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------
|
||||
//
|
||||
ParticleEmitterNode::ParticleEmitterNode()
|
||||
{
|
||||
// Todo: ScopeAlways?
|
||||
mNetFlags.set(Ghostable);
|
||||
mTypeMask |= EnvironmentObjectType;
|
||||
|
||||
mEmitterDatablock = NULL;
|
||||
mEmitterDatablockId = 0;
|
||||
mEmitter = NULL;
|
||||
mVelocity = 1.0;
|
||||
}
|
||||
|
||||
ParticleEmitterNode::~ParticleEmitterNode()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void ParticleEmitterNode::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
addField("emitter", TypeParticleEmitterDataPtr, Offset(mEmitterDatablock, ParticleEmitterNode));
|
||||
addField("velocity", TypeF32, Offset(mVelocity, ParticleEmitterNode));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
bool ParticleEmitterNode::onAdd()
|
||||
{
|
||||
if(!Parent::onAdd())
|
||||
return false;
|
||||
|
||||
if (!mEmitterDatablock && mEmitterDatablockId != 0)
|
||||
{
|
||||
if (Sim::findObject(mEmitterDatablockId, mEmitterDatablock) == false)
|
||||
Con::errorf(ConsoleLogEntry::General, "ParticleEmitterNode::onAdd: Invalid packet, bad datablockId(mEmitterDatablock): %d", mEmitterDatablockId);
|
||||
}
|
||||
|
||||
if (mEmitterDatablock == NULL)
|
||||
return false;
|
||||
|
||||
if (isClientObject())
|
||||
{
|
||||
ParticleEmitter* pEmitter = new ParticleEmitter;
|
||||
pEmitter->onNewDataBlock(mEmitterDatablock);
|
||||
if (pEmitter->registerObject() == false)
|
||||
{
|
||||
Con::warnf(ConsoleLogEntry::General, "Could not register base emitter for particle of class: %s", mDataBlock->getName());
|
||||
delete pEmitter;
|
||||
return false;
|
||||
}
|
||||
mEmitter = pEmitter;
|
||||
}
|
||||
|
||||
mObjBox.min.set(-0.5, -0.5, -0.5);
|
||||
mObjBox.max.set( 0.5, 0.5, 0.5);
|
||||
resetWorldBox();
|
||||
addToScene();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ParticleEmitterNode::onRemove()
|
||||
{
|
||||
removeFromScene();
|
||||
|
||||
if (isClientObject())
|
||||
{
|
||||
mEmitter->deleteWhenEmpty();
|
||||
mEmitter = NULL;
|
||||
}
|
||||
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
void ParticleEmitterNode::onGroupAdd()
|
||||
{
|
||||
Parent::onGroupAdd();
|
||||
|
||||
// To make sure that we don't orphan our emitter on mission end,
|
||||
// let's add it to our parent group, so it will get cleaned up.
|
||||
SimGroup* myGroup = getGroup();
|
||||
if (myGroup && mEmitter)
|
||||
myGroup->addObject(mEmitter);
|
||||
}
|
||||
|
||||
bool ParticleEmitterNode::onNewDataBlock(GameBaseData* dptr)
|
||||
{
|
||||
mDataBlock = dynamic_cast<ParticleEmitterNodeData*>(dptr);
|
||||
if (!mDataBlock || !Parent::onNewDataBlock(dptr))
|
||||
return false;
|
||||
|
||||
// Todo: Uncomment if this is a "leaf" class
|
||||
scriptOnNewDataBlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void ParticleEmitterNode::advanceTime(F32 dt)
|
||||
{
|
||||
Parent::advanceTime(dt);
|
||||
|
||||
Point3F emitPoint, emitVelocity;
|
||||
Point3F emitAxis(0, 0, 1);
|
||||
getTransform().mulV(emitAxis);
|
||||
getTransform().getColumn(3, &emitPoint);
|
||||
emitVelocity = emitAxis * mVelocity;
|
||||
|
||||
mEmitter->emitParticles(emitPoint, emitPoint,
|
||||
emitAxis,
|
||||
emitVelocity, (U32)(dt * mDataBlock->timeMultiple * 1000.0f));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
U32 ParticleEmitterNode::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
|
||||
{
|
||||
U32 retMask = Parent::packUpdate(con, mask, stream);
|
||||
|
||||
mathWrite(*stream, getTransform());
|
||||
mathWrite(*stream, getScale());
|
||||
if (stream->writeFlag(mEmitterDatablock != NULL)) {
|
||||
stream->writeRangedU32(mEmitterDatablock->getId(), DataBlockObjectIdFirst,
|
||||
DataBlockObjectIdLast);
|
||||
}
|
||||
|
||||
return retMask;
|
||||
}
|
||||
|
||||
void ParticleEmitterNode::unpackUpdate(NetConnection* con, BitStream* stream)
|
||||
{
|
||||
Parent::unpackUpdate(con, stream);
|
||||
|
||||
MatrixF temp;
|
||||
Point3F tempScale;
|
||||
mathRead(*stream, &temp);
|
||||
mathRead(*stream, &tempScale);
|
||||
|
||||
if (stream->readFlag()) {
|
||||
mEmitterDatablockId = stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
DataBlockObjectIdLast);
|
||||
} else {
|
||||
mEmitterDatablockId = 0;
|
||||
}
|
||||
|
||||
setScale(tempScale);
|
||||
setTransform(temp);
|
||||
}
|
||||
|
||||
void ParticleEmitterNode::setEmitterDataBlock(ParticleEmitterData* data)
|
||||
{
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
if (mEmitter)
|
||||
{
|
||||
mEmitterDatablock = data;
|
||||
ParticleEmitter* pEmitter = new ParticleEmitter;
|
||||
pEmitter->onNewDataBlock(mEmitterDatablock);
|
||||
if (pEmitter->registerObject() == false) {
|
||||
Con::warnf(ConsoleLogEntry::General, "Could not register base emitter for particle of class: %s", mDataBlock->getName());
|
||||
delete pEmitter;
|
||||
pEmitter = NULL;
|
||||
}
|
||||
if (pEmitter)
|
||||
{
|
||||
mEmitter->deleteWhenEmpty();
|
||||
mEmitter = pEmitter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConsoleMethod(ParticleEmitterNode, setEmitterDataBlock, void, 3, 3, "(data)")
|
||||
{
|
||||
ParticleEmitterData* data = dynamic_cast<ParticleEmitterData*>(Sim::findObject(dAtoi(argv[2])));
|
||||
if (!data)
|
||||
data = dynamic_cast<ParticleEmitterData*>(Sim::findObject(argv[2]));
|
||||
|
||||
if (data)
|
||||
object->setEmitterDataBlock(data);
|
||||
}
|
||||
Reference in New Issue
Block a user