ribbonNode.cpp
Engine/source/T3D/fx/ribbonNode.cpp
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>" )
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