mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-13 03:33:48 +00:00
RibbonNode class.
Simple RibbonNode class for an implementation similar to that of ParticleEmitterNodes. Datablock currently has no static fields.
This commit is contained in:
parent
cb9cfea1c4
commit
a8a141e73c
2 changed files with 432 additions and 0 deletions
324
Engine/source/T3D/fx/ribbonNode.cpp
Normal file
324
Engine/source/T3D/fx/ribbonNode.cpp
Normal file
|
|
@ -0,0 +1,324 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "ribbonNode.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "T3D/fx/ribbon.h"
|
||||
#include "math/mathIO.h"
|
||||
#include "sim/netConnection.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(RibbonNodeData);
|
||||
IMPLEMENT_CO_NETOBJECT_V1(RibbonNode);
|
||||
|
||||
ConsoleDocClass( RibbonNodeData,
|
||||
"@brief Contains additional data to be associated with a RibbonNode."
|
||||
"@ingroup FX\n"
|
||||
);
|
||||
|
||||
ConsoleDocClass( RibbonNode, ""
|
||||
);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RibbonNodeData
|
||||
//-----------------------------------------------------------------------------
|
||||
RibbonNodeData::RibbonNodeData()
|
||||
{
|
||||
}
|
||||
|
||||
RibbonNodeData::~RibbonNodeData()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// initPersistFields
|
||||
//-----------------------------------------------------------------------------
|
||||
void RibbonNodeData::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RibbonNode
|
||||
//-----------------------------------------------------------------------------
|
||||
RibbonNode::RibbonNode()
|
||||
{
|
||||
// Todo: ScopeAlways?
|
||||
mNetFlags.set(Ghostable);
|
||||
mTypeMask |= EnvironmentObjectType;
|
||||
|
||||
mActive = true;
|
||||
|
||||
mDataBlock = NULL;
|
||||
mRibbonDatablock = NULL;
|
||||
mRibbonDatablockId = 0;
|
||||
mRibbon = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
RibbonNode::~RibbonNode()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// initPersistFields
|
||||
//-----------------------------------------------------------------------------
|
||||
void RibbonNode::initPersistFields()
|
||||
{
|
||||
addField( "active", TYPEID< bool >(), Offset(mActive,RibbonNode),
|
||||
"Controls whether ribbon is emitted from this node." );
|
||||
addField( "ribbon", TYPEID< RibbonData >(), Offset(mRibbonDatablock, RibbonNode),
|
||||
"Datablock to use for the ribbon." );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// onAdd
|
||||
//-----------------------------------------------------------------------------
|
||||
bool RibbonNode::onAdd()
|
||||
{
|
||||
if( !Parent::onAdd() )
|
||||
return false;
|
||||
|
||||
if( !mRibbonDatablock && mRibbonDatablockId != 0 )
|
||||
{
|
||||
if( Sim::findObject(mRibbonDatablockId, mRibbonDatablock) == false )
|
||||
Con::errorf(ConsoleLogEntry::General, "RibbonNode::onAdd: Invalid packet, bad datablockId(mRibbonDatablock): %d", mRibbonDatablockId);
|
||||
}
|
||||
|
||||
if( isClientObject() )
|
||||
{
|
||||
setRibbonDatablock( mRibbonDatablock );
|
||||
}
|
||||
else
|
||||
{
|
||||
setMaskBits( StateMask | EmitterDBMask );
|
||||
}
|
||||
|
||||
mObjBox.minExtents.set(-0.5, -0.5, -0.5);
|
||||
mObjBox.maxExtents.set( 0.5, 0.5, 0.5);
|
||||
resetWorldBox();
|
||||
addToScene();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// onRemove
|
||||
//-----------------------------------------------------------------------------
|
||||
void RibbonNode::onRemove()
|
||||
{
|
||||
removeFromScene();
|
||||
if( isClientObject() )
|
||||
{
|
||||
if( mRibbon )
|
||||
{
|
||||
mRibbon->deleteOnEnd();
|
||||
mRibbon = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// onNewDataBlock
|
||||
//-----------------------------------------------------------------------------
|
||||
bool RibbonNode::onNewDataBlock( GameBaseData *dptr, bool reload )
|
||||
{
|
||||
mDataBlock = dynamic_cast<RibbonNodeData*>( dptr );
|
||||
if ( !mDataBlock || !Parent::onNewDataBlock( dptr, reload ) )
|
||||
return false;
|
||||
|
||||
// Todo: Uncomment if this is a "leaf" class
|
||||
scriptOnNewDataBlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RibbonNode::inspectPostApply()
|
||||
{
|
||||
Parent::inspectPostApply();
|
||||
setMaskBits(StateMask | EmitterDBMask);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// processTick
|
||||
//-----------------------------------------------------------------------------
|
||||
void RibbonNode::processTick(const Move* move)
|
||||
{
|
||||
Parent::processTick(move);
|
||||
|
||||
if ( isMounted() )
|
||||
{
|
||||
MatrixF mat;
|
||||
mMount.object->getMountTransform( mMount.node, mMount.xfm, &mat );
|
||||
setTransform( mat );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// advanceTime
|
||||
//-----------------------------------------------------------------------------
|
||||
void RibbonNode::advanceTime(F32 dt)
|
||||
{
|
||||
Parent::advanceTime(dt);
|
||||
|
||||
if(!mActive || mRibbon.isNull() || !mDataBlock)
|
||||
return;
|
||||
|
||||
MatrixF trans(getTransform());
|
||||
Point3F pos = getPosition();
|
||||
mRibbon->addSegmentPoint(pos, trans);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// packUpdate
|
||||
//-----------------------------------------------------------------------------
|
||||
U32 RibbonNode::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
|
||||
{
|
||||
U32 retMask = Parent::packUpdate(con, mask, stream);
|
||||
|
||||
if ( stream->writeFlag( mask & InitialUpdateMask ) )
|
||||
{
|
||||
mathWrite(*stream, getTransform());
|
||||
mathWrite(*stream, getScale());
|
||||
}
|
||||
|
||||
if ( stream->writeFlag( mask & EmitterDBMask ) )
|
||||
{
|
||||
if( stream->writeFlag(mRibbonDatablock != NULL) )
|
||||
{
|
||||
stream->writeRangedU32(mRibbonDatablock->getId(), DataBlockObjectIdFirst,
|
||||
DataBlockObjectIdLast);
|
||||
}
|
||||
}
|
||||
|
||||
if ( stream->writeFlag( mask & StateMask ) )
|
||||
{
|
||||
stream->writeFlag( mActive );
|
||||
}
|
||||
|
||||
return retMask;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// unpackUpdate
|
||||
//-----------------------------------------------------------------------------
|
||||
void RibbonNode::unpackUpdate(NetConnection* con, BitStream* stream)
|
||||
{
|
||||
Parent::unpackUpdate(con, stream);
|
||||
|
||||
if ( stream->readFlag() )
|
||||
{
|
||||
MatrixF temp;
|
||||
Point3F tempScale;
|
||||
mathRead(*stream, &temp);
|
||||
mathRead(*stream, &tempScale);
|
||||
|
||||
setScale(tempScale);
|
||||
setTransform(temp);
|
||||
}
|
||||
|
||||
if ( stream->readFlag() )
|
||||
{
|
||||
mRibbonDatablockId = stream->readFlag() ?
|
||||
stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast) : 0;
|
||||
|
||||
RibbonData *emitterDB = NULL;
|
||||
Sim::findObject( mRibbonDatablockId, emitterDB );
|
||||
if ( isProperlyAdded() )
|
||||
setRibbonDatablock( emitterDB );
|
||||
}
|
||||
|
||||
if ( stream->readFlag() )
|
||||
{
|
||||
mActive = stream->readFlag();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// setRibbonDatablock
|
||||
//-----------------------------------------------------------------------------
|
||||
void RibbonNode::setRibbonDatablock(RibbonData* data)
|
||||
{
|
||||
if ( isServerObject() )
|
||||
{
|
||||
setMaskBits( EmitterDBMask );
|
||||
}
|
||||
else
|
||||
{
|
||||
Ribbon* pRibbon = NULL;
|
||||
if ( data )
|
||||
{
|
||||
// Create emitter with new datablock
|
||||
pRibbon = new Ribbon;
|
||||
pRibbon->onNewDataBlock( data, false );
|
||||
if( pRibbon->registerObject() == false )
|
||||
{
|
||||
Con::warnf(ConsoleLogEntry::General, "Could not register base ribbon of class: %s", data->getName() ? data->getName() : data->getIdString() );
|
||||
delete pRibbon;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Replace emitter
|
||||
if ( mRibbon )
|
||||
mRibbon->deleteOnEnd();
|
||||
|
||||
mRibbon = pRibbon;
|
||||
}
|
||||
|
||||
mRibbonDatablock = data;
|
||||
}
|
||||
|
||||
DefineEngineMethod(RibbonNode, setRibbonDatablock, void, (RibbonData* ribbonDatablock), (0),
|
||||
"Assigns the datablock for this ribbon node.\n"
|
||||
"@param ribbonDatablock RibbonData datablock to assign\n"
|
||||
"@tsexample\n"
|
||||
"// Assign a new emitter datablock\n"
|
||||
"%emitter.setRibbonDatablock( %ribbonDatablock );\n"
|
||||
"@endtsexample\n" )
|
||||
{
|
||||
if ( !ribbonDatablock )
|
||||
{
|
||||
Con::errorf("RibbonData datablock could not be found when calling setRibbonDataBlock in ribbonNode.");
|
||||
return;
|
||||
}
|
||||
|
||||
object->setRibbonDatablock(ribbonDatablock);
|
||||
}
|
||||
|
||||
DefineEngineMethod(RibbonNode, setActive, void, (bool active),,
|
||||
"Turns the ribbon on or off.\n"
|
||||
"@param active New ribbon state\n" )
|
||||
{
|
||||
object->setActive( active );
|
||||
}
|
||||
108
Engine/source/T3D/fx/ribbonNode.h
Normal file
108
Engine/source/T3D/fx/ribbonNode.h
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _RIBBON_NODE_H_
|
||||
#define _RIBBON_NODE_H_
|
||||
|
||||
#ifndef _GAMEBASE_H_
|
||||
#include "T3D/gameBase/gameBase.h"
|
||||
#endif
|
||||
|
||||
class RibbonData;
|
||||
class Ribbon;
|
||||
|
||||
//*****************************************************************************
|
||||
// ParticleEmitterNodeData
|
||||
//*****************************************************************************
|
||||
class RibbonNodeData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
//-------------------------------------- Console set variables
|
||||
public:
|
||||
F32 timeMultiple;
|
||||
|
||||
//-------------------------------------- load set variables
|
||||
|
||||
public:
|
||||
RibbonNodeData();
|
||||
~RibbonNodeData();
|
||||
|
||||
DECLARE_CONOBJECT(RibbonNodeData);
|
||||
static void initPersistFields();
|
||||
};
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// ParticleEmitterNode
|
||||
//*****************************************************************************
|
||||
class RibbonNode : public GameBase
|
||||
{
|
||||
typedef GameBase Parent;
|
||||
|
||||
enum MaskBits
|
||||
{
|
||||
StateMask = Parent::NextFreeMask << 0,
|
||||
EmitterDBMask = Parent::NextFreeMask << 1,
|
||||
NextFreeMask = Parent::NextFreeMask << 2,
|
||||
};
|
||||
|
||||
RibbonNodeData* mDataBlock;
|
||||
|
||||
protected:
|
||||
bool onAdd();
|
||||
void onRemove();
|
||||
bool onNewDataBlock( GameBaseData *dptr, bool reload );
|
||||
void inspectPostApply();
|
||||
|
||||
RibbonData* mRibbonDatablock;
|
||||
S32 mRibbonDatablockId;
|
||||
|
||||
SimObjectPtr<Ribbon> mRibbon;
|
||||
|
||||
bool mActive;
|
||||
|
||||
public:
|
||||
RibbonNode();
|
||||
~RibbonNode();
|
||||
|
||||
Ribbon *getRibbonEmitter() {return mRibbon;}
|
||||
|
||||
// Time/Move Management
|
||||
|
||||
void processTick(const Move* move);
|
||||
void advanceTime(F32 dt);
|
||||
|
||||
DECLARE_CONOBJECT(RibbonNode);
|
||||
static void initPersistFields();
|
||||
|
||||
U32 packUpdate (NetConnection *conn, U32 mask, BitStream* stream);
|
||||
void unpackUpdate(NetConnection *conn, BitStream* stream);
|
||||
|
||||
inline bool getActive( void ) { return mActive; };
|
||||
inline void setActive( bool active ) { mActive = active; setMaskBits( StateMask ); };
|
||||
|
||||
void setRibbonDatablock(RibbonData* data);
|
||||
};
|
||||
|
||||
#endif // _RIBBON_NODE_H_
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue