ribbonNode.cpp

Engine/source/T3D/fx/ribbonNode.cpp

More...

Public Functions

ConsoleDocClass(RibbonNodeData , "@brief Contains additional data <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be associated with <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> RibbonNode." "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">FX\n</a>" )
DefineEngineMethod(RibbonNode , setActive , void , (bool active) , "Turns the ribbon on or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">off.\n</a>" "@param active New ribbon <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">state\n</a>" )
DefineEngineMethod(RibbonNode , setRibbonDatablock , void , (RibbonData *ribbonDatablock) , (nullAsType< RibbonData * >()) , "Assigns the datablock <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> this ribbon <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">node.\n</a>" "@param ribbonDatablock <a href="/coding/class/classribbondata/">RibbonData</a> datablock <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">assign\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Assign <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> emitter <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">datablock\n</a>" "%emitter.setRibbonDatablock( %ribbonDatablock );\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n</a>" )

Detailed Description

Public Functions

ConsoleDocClass(RibbonNode , "" )

ConsoleDocClass(RibbonNodeData , "@brief Contains additional data <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be associated with <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> RibbonNode." "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">FX\n</a>" )

DefineEngineMethod(RibbonNode , setActive , void , (bool active) , "Turns the ribbon on or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">off.\n</a>" "@param active New ribbon <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">state\n</a>" )

DefineEngineMethod(RibbonNode , setRibbonDatablock , void , (RibbonData *ribbonDatablock) , (nullAsType< RibbonData * >()) , "Assigns the datablock <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> this ribbon <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">node.\n</a>" "@param ribbonDatablock <a href="/coding/class/classribbondata/">RibbonData</a> datablock <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">assign\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Assign <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> emitter <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">datablock\n</a>" "%emitter.setRibbonDatablock( %ribbonDatablock );\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n</a>" )

IMPLEMENT_CO_DATABLOCK_V1(RibbonNodeData )

IMPLEMENT_CO_NETOBJECT_V1(RibbonNode )

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2014 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "ribbonNode.h"
 25#include "console/consoleTypes.h"
 26#include "core/stream/bitStream.h"
 27#include "T3D/fx/ribbon.h"
 28#include "math/mathIO.h"
 29#include "sim/netConnection.h"
 30#include "console/engineAPI.h"
 31
 32IMPLEMENT_CO_DATABLOCK_V1(RibbonNodeData);
 33IMPLEMENT_CO_NETOBJECT_V1(RibbonNode);
 34
 35ConsoleDocClass( RibbonNodeData,
 36   "@brief Contains additional data to be associated with a RibbonNode."
 37   "@ingroup FX\n"
 38   );
 39
 40ConsoleDocClass( RibbonNode, ""
 41   );
 42
 43//-----------------------------------------------------------------------------
 44// RibbonNodeData
 45//-----------------------------------------------------------------------------
 46RibbonNodeData::RibbonNodeData()
 47{
 48}
 49
 50RibbonNodeData::~RibbonNodeData()
 51{
 52
 53}
 54
 55//-----------------------------------------------------------------------------
 56// initPersistFields
 57//-----------------------------------------------------------------------------
 58void RibbonNodeData::initPersistFields()
 59{
 60   Parent::initPersistFields();
 61}
 62
 63
 64//-----------------------------------------------------------------------------
 65// RibbonNode
 66//-----------------------------------------------------------------------------
 67RibbonNode::RibbonNode()
 68{
 69   // Todo: ScopeAlways?
 70   mNetFlags.set(Ghostable);
 71   mTypeMask |= EnvironmentObjectType;
 72
 73   mActive = true;
 74
 75   mDataBlock          = NULL;
 76   mRibbonDatablock   = NULL;
 77   mRibbonDatablockId = 0;
 78   mRibbon            = NULL;
 79}
 80
 81//-----------------------------------------------------------------------------
 82// Destructor
 83//-----------------------------------------------------------------------------
 84RibbonNode::~RibbonNode()
 85{
 86   //
 87}
 88
 89//-----------------------------------------------------------------------------
 90// initPersistFields
 91//-----------------------------------------------------------------------------
 92void RibbonNode::initPersistFields()
 93{
 94   addField( "active", TYPEID< bool >(), Offset(mActive,RibbonNode),
 95      "Controls whether ribbon is emitted from this node." );
 96   addField( "ribbon",  TYPEID< RibbonData >(), Offset(mRibbonDatablock, RibbonNode),
 97      "Datablock to use for the ribbon." );
 98
 99   Parent::initPersistFields();
100}
101
102//-----------------------------------------------------------------------------
103// onAdd
104//-----------------------------------------------------------------------------
105bool RibbonNode::onAdd()
106{
107   if( !Parent::onAdd() )
108      return false;
109
110   if( !mRibbonDatablock && mRibbonDatablockId != 0 )
111   {
112      if( Sim::findObject(mRibbonDatablockId, mRibbonDatablock) == false )
113         Con::errorf(ConsoleLogEntry::General, "RibbonNode::onAdd: Invalid packet, bad datablockId(mRibbonDatablock): %d", mRibbonDatablockId);
114   }
115
116   if( isClientObject() )
117   {
118      setRibbonDatablock( mRibbonDatablock );
119   }
120   else
121   {
122      setMaskBits( StateMask | EmitterDBMask );
123   }
124
125   mObjBox.minExtents.set(-0.5, -0.5, -0.5);
126   mObjBox.maxExtents.set( 0.5,  0.5,  0.5);
127   resetWorldBox();
128   addToScene();
129
130   return true;
131}
132
133//-----------------------------------------------------------------------------
134// onRemove
135//-----------------------------------------------------------------------------
136void RibbonNode::onRemove()
137{
138   removeFromScene();
139   if( isClientObject() )
140   {
141      if( mRibbon )
142      {
143         mRibbon->deleteOnEnd();
144         mRibbon = NULL;
145      }
146   }
147
148   Parent::onRemove();
149}
150
151//-----------------------------------------------------------------------------
152// onNewDataBlock
153//-----------------------------------------------------------------------------
154bool RibbonNode::onNewDataBlock( GameBaseData *dptr, bool reload )
155{
156   mDataBlock = dynamic_cast<RibbonNodeData*>( dptr );
157   if ( !mDataBlock || !Parent::onNewDataBlock( dptr, reload ) )
158      return false;
159
160   // Todo: Uncomment if this is a "leaf" class
161   scriptOnNewDataBlock();
162   return true;
163}
164
165//-----------------------------------------------------------------------------
166void RibbonNode::inspectPostApply()
167{
168   Parent::inspectPostApply();
169   setMaskBits(StateMask | EmitterDBMask);
170}
171
172//-----------------------------------------------------------------------------
173// processTick
174//-----------------------------------------------------------------------------
175void RibbonNode::processTick(const Move* move)
176{
177   Parent::processTick(move);
178
179   if ( isMounted() )
180   {
181      MatrixF mat;
182      mMount.object->getMountTransform( mMount.node, mMount.xfm, &mat );
183      setTransform( mat );
184   }
185}
186
187//-----------------------------------------------------------------------------
188// advanceTime
189//-----------------------------------------------------------------------------
190void RibbonNode::advanceTime(F32 dt)
191{
192   Parent::advanceTime(dt);
193
194   if(!mActive || mRibbon.isNull() || !mDataBlock)
195      return;
196
197   MatrixF trans(getTransform());
198   Point3F pos = getPosition();
199   mRibbon->addSegmentPoint(pos, trans);
200}
201
202//-----------------------------------------------------------------------------
203// packUpdate
204//-----------------------------------------------------------------------------
205U32 RibbonNode::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
206{
207   U32 retMask = Parent::packUpdate(con, mask, stream);
208
209   if ( stream->writeFlag( mask & InitialUpdateMask ) )
210   {
211      mathWrite(*stream, getTransform());
212      mathWrite(*stream, getScale());
213   }
214
215   if ( stream->writeFlag( mask & EmitterDBMask ) )
216   {
217      if( stream->writeFlag(mRibbonDatablock != NULL) )
218      {
219         stream->writeRangedU32(mRibbonDatablock->getId(), DataBlockObjectIdFirst,
220            DataBlockObjectIdLast);
221      }
222   }
223
224   if ( stream->writeFlag( mask & StateMask ) )
225   {
226      stream->writeFlag( mActive );
227   }
228
229   return retMask;
230}
231
232//-----------------------------------------------------------------------------
233// unpackUpdate
234//-----------------------------------------------------------------------------
235void RibbonNode::unpackUpdate(NetConnection* con, BitStream* stream)
236{
237   Parent::unpackUpdate(con, stream);
238
239   if ( stream->readFlag() )
240   {
241      MatrixF temp;
242      Point3F tempScale;
243      mathRead(*stream, &temp);
244      mathRead(*stream, &tempScale);
245
246      setScale(tempScale);
247      setTransform(temp);
248   }
249
250   if ( stream->readFlag() )
251   {
252      mRibbonDatablockId = stream->readFlag() ?
253         stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast) : 0;
254
255      RibbonData *emitterDB = NULL;
256      Sim::findObject( mRibbonDatablockId, emitterDB );
257      if ( isProperlyAdded() )
258         setRibbonDatablock( emitterDB );
259   }
260
261   if ( stream->readFlag() )
262   {
263      mActive = stream->readFlag();
264   }
265}
266
267//-----------------------------------------------------------------------------
268// setRibbonDatablock
269//-----------------------------------------------------------------------------
270void RibbonNode::setRibbonDatablock(RibbonData* data)
271{
272   if ( isServerObject() )
273   {
274      setMaskBits( EmitterDBMask );
275   }
276   else
277   {
278      Ribbon* pRibbon = NULL;
279      if ( data )
280      {
281         // Create emitter with new datablock
282         pRibbon = new Ribbon;
283         pRibbon->onNewDataBlock( data, false );
284         if( pRibbon->registerObject() == false )
285         {
286            Con::warnf(ConsoleLogEntry::General, "Could not register base ribbon of class: %s", data->getName() ? data->getName() : data->getIdString() );
287            delete pRibbon;
288            return;
289         }
290      }
291
292      // Replace emitter
293      if ( mRibbon )
294         mRibbon->deleteOnEnd();
295
296      mRibbon = pRibbon;
297   }
298
299   mRibbonDatablock = data;
300}
301
302DefineEngineMethod(RibbonNode, setRibbonDatablock, void, (RibbonData* ribbonDatablock), (nullAsType<RibbonData*>()),
303   "Assigns the datablock for this ribbon node.\n"
304   "@param ribbonDatablock RibbonData datablock to assign\n"
305   "@tsexample\n"
306   "// Assign a new emitter datablock\n"
307   "%emitter.setRibbonDatablock( %ribbonDatablock );\n"
308   "@endtsexample\n" )
309{
310   if ( !ribbonDatablock )
311   {
312      Con::errorf("RibbonData datablock could not be found when calling setRibbonDataBlock in ribbonNode.");
313      return;
314   }
315
316   object->setRibbonDatablock(ribbonDatablock);
317}
318
319DefineEngineMethod(RibbonNode, setActive, void, (bool active),,
320   "Turns the ribbon on or off.\n"
321   "@param active New ribbon state\n" )
322{
323   object->setActive( active );
324}
325