ParticleAssetEmitter.cc 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "2d/assets/ParticleAssetEmitter.h"
  23. #ifndef _PARTICLE_ASSET_H_
  24. #include "2d/assets/ParticleAsset.h"
  25. #endif
  26. #ifndef _CONSOLETYPES_H_
  27. #include "console/consoleTypes.h"
  28. #endif
  29. // Script bindings.
  30. #include "ParticleAssetEmitter_ScriptBinding.h"
  31. //------------------------------------------------------------------------------
  32. static EnumTable::Enums emitterTypeLookup[] =
  33. {
  34. { ParticleAssetEmitter::POINT_EMITTER, "POINT" },
  35. { ParticleAssetEmitter::LINE_EMITTER, "LINE" },
  36. { ParticleAssetEmitter::BOX_EMITTER, "BOX" },
  37. { ParticleAssetEmitter::DISK_EMITTER, "DISK" },
  38. { ParticleAssetEmitter::ELLIPSE_EMITTER, "ELLIPSE" },
  39. { ParticleAssetEmitter::TORUS_EMITTER, "TORUS" },
  40. };
  41. //------------------------------------------------------------------------------
  42. static EnumTable EmitterTypeTable(sizeof(emitterTypeLookup) / sizeof(EnumTable::Enums), &emitterTypeLookup[0]);
  43. //------------------------------------------------------------------------------
  44. ParticleAssetEmitter::EmitterType ParticleAssetEmitter::getEmitterTypeEnum(const char* label)
  45. {
  46. // Search for Mnemonic.
  47. for(U32 i = 0; i < (sizeof(emitterTypeLookup) / sizeof(EnumTable::Enums)); i++)
  48. if( dStricmp(emitterTypeLookup[i].label, label) == 0)
  49. return((ParticleAssetEmitter::EmitterType)emitterTypeLookup[i].index);
  50. // Warn.
  51. Con::warnf( "ParticleAssetEmitter::getEmitterTypeEnum() - Invalid emitter-type '%s'.", label );
  52. return ParticleAssetEmitter::INVALID_EMITTER_TYPE;
  53. }
  54. //-----------------------------------------------------------------------------
  55. const char* ParticleAssetEmitter::getEmitterTypeDescription( const EmitterType emitterType )
  56. {
  57. // Search for Mnemonic.
  58. for (U32 i = 0; i < (sizeof(emitterTypeLookup) / sizeof(EnumTable::Enums)); i++)
  59. {
  60. if( emitterTypeLookup[i].index == (S32)emitterType )
  61. return emitterTypeLookup[i].label;
  62. }
  63. // Warn.
  64. Con::warnf( "ParticleAssetEmitter::getEmitterTypeDescription() - Invalid emitter-type." );
  65. return StringTable->EmptyString;
  66. }
  67. //------------------------------------------------------------------------------
  68. static EnumTable::Enums particleOrientationTypeLookup[] =
  69. {
  70. { ParticleAssetEmitter::FIXED_ORIENTATION, "FIXED" },
  71. { ParticleAssetEmitter::ALIGNED_ORIENTATION, "ALIGNED" },
  72. { ParticleAssetEmitter::RANDOM_ORIENTATION, "RANDOM" },
  73. };
  74. //------------------------------------------------------------------------------
  75. static EnumTable OrientationTypeTable(sizeof(particleOrientationTypeLookup) / sizeof(EnumTable::Enums), &particleOrientationTypeLookup[0]);
  76. //------------------------------------------------------------------------------
  77. ParticleAssetEmitter::ParticleOrientationType ParticleAssetEmitter::getOrientationTypeEnum(const char* label)
  78. {
  79. // Search for Mnemonic.
  80. for(U32 i = 0; i < (sizeof(particleOrientationTypeLookup) / sizeof(EnumTable::Enums)); i++)
  81. if( dStricmp(particleOrientationTypeLookup[i].label, label) == 0)
  82. return((ParticleAssetEmitter::ParticleOrientationType)particleOrientationTypeLookup[i].index);
  83. // Warn.
  84. Con::warnf( "ParticleAssetEmitter::getOrientationTypeEnum() - Invalid orientation type '%s'.", label );
  85. return ParticleAssetEmitter::INVALID_ORIENTATION;
  86. }
  87. //------------------------------------------------------------------------------
  88. const char* ParticleAssetEmitter::getOrientationTypeDescription( const ParticleOrientationType orientationType )
  89. {
  90. // Search for Mnemonic.
  91. for (U32 i = 0; i < (sizeof(particleOrientationTypeLookup) / sizeof(EnumTable::Enums)); i++)
  92. {
  93. if( particleOrientationTypeLookup[i].index == (S32)orientationType )
  94. return particleOrientationTypeLookup[i].label;
  95. }
  96. // Warn.
  97. Con::warnf( "ParticleAssetEmitter::getOrientationTypeDescription() - Invalid orientation-type" );
  98. return StringTable->EmptyString;
  99. }
  100. //------------------------------------------------------------------------------
  101. ParticleAssetEmitter::ParticleAssetEmitter() :
  102. mEmitterName( StringTable->EmptyString ),
  103. mOwner( NULL ),
  104. mEmitterType( POINT_EMITTER ),
  105. mEmitterOffset( 0.0f, 0.0f),
  106. mEmitterAngle( 0.0f ),
  107. mEmitterSize( 10.0f, 10.0f ),
  108. mFixedAspect( true ),
  109. mOrientationType( FIXED_ORIENTATION ),
  110. mKeepAligned( false ),
  111. mAlignedAngleOffset( 0.0f ),
  112. mRandomAngleOffset( 0.0f ),
  113. mRandomArc( 360.0f ),
  114. mFixedAngleOffset( 0.0f ),
  115. mLinkEmissionRotation( true ),
  116. mIntenseParticles( false ),
  117. mSingleParticle( false ),
  118. mAttachPositionToEmitter( false ),
  119. mAttachRotationToEmitter( false ),
  120. mOldestInFront( false ),
  121. mStaticMode( true ),
  122. mImageAsset( NULL ),
  123. mImageFrame( 0 ),
  124. mRandomImageFrame( false ),
  125. mAnimationAsset( NULL ),
  126. mBlendMode( true ),
  127. mSrcBlendFactor( GL_SRC_ALPHA ),
  128. mDstBlendFactor( GL_ONE_MINUS_SRC_ALPHA ),
  129. mAlphaTest( -1.0f )
  130. {
  131. // Set the pivot point.
  132. // NOTE: This is called to set the local AABB.
  133. setPivotPoint( Vector2::getZero() );
  134. // Set fixed force angle.
  135. // NOTE: This is called to set the fixed-force-direction.
  136. setFixedForceAngle( 0.0f );
  137. // Initialize particle fields.
  138. mParticleFields.addField( mParticleLife.getBase(), "Lifetime", 1000.0f, 0.0f, 10000.0f, 2.0f );
  139. mParticleFields.addField( mParticleLife.getVariation(), "LifetimeVariation", 1000.0f, 0.0f, 5000.0f, 0.0f );
  140. mParticleFields.addField( mQuantity.getBase(), "Quantity", 1000.0f, 0.0f, 100000.0f, 10.0f );
  141. mParticleFields.addField( mQuantity.getVariation(), "QuantityVariation", 1000.0f, 0.0f, 100000.0f, 0.0f );
  142. mParticleFields.addField( mSizeX.getBase(), "SizeX", 1000.0f, 0.0f, 100.0f, 2.0f );
  143. mParticleFields.addField( mSizeX.getVariation(), "SizeXVariation", 1000.0f, 0.0f, 200.0f, 0.0f );
  144. mParticleFields.addField( mSizeX.getLife(), "SizeXLife", 1.0f, -100.0f, 100.0f, 1.0f );
  145. mParticleFields.addField( mSizeY.getBase(), "SizeY", 1000.0f, 0.0f, 100.0f, 2.0f );
  146. mParticleFields.addField( mSizeY.getVariation(), "SizeYVariation", 1000.0f, 0.0f, 200.0f, 0.0f );
  147. mParticleFields.addField( mSizeY.getLife(), "SizeYLife", 1.0f, -100.0f, 100.0f, 1.0f );
  148. mParticleFields.addField( mSpeed.getBase(), "Speed", 1000.0f, 0.0f, 100.0f, 10.0f );
  149. mParticleFields.addField( mSpeed.getVariation(), "SpeedVariation", 1000.0f, 0.0f, 200.0f, 0.0f );
  150. mParticleFields.addField( mSpeed.getLife(), "SpeedLife", 1.0f, -100.0f, 100.0f, 1.0f );
  151. mParticleFields.addField( mSpin.getBase(), "Spin", 1000.0f, -1000.0f, 1000.0f, 0.0f );
  152. mParticleFields.addField( mSpin.getVariation(), "SpinVariation", 1000.0f, 0.0f, 2000.0f, 0.0f );
  153. mParticleFields.addField( mSpin.getLife(), "SpinLife", 1.0f, -1000.0f, 1000.0f, 1.0f );
  154. mParticleFields.addField( mFixedForce.getBase(), "FixedForce", 1000.0f, -1000.0f, 1000.0f, 0.0f );
  155. mParticleFields.addField( mFixedForce.getVariation(), "FixedForceVariation", 1000.0f, 0.0f, 2000.0f, 0.0f );
  156. mParticleFields.addField( mFixedForce.getLife(), "FixedForceLife", 1.0f, -1000.0f, 1000.0f, 1.0f );
  157. mParticleFields.addField( mRandomMotion.getBase(), "RandomMotion", 1000.0f, 0.0f, 1000.0f, 0.0f );
  158. mParticleFields.addField( mRandomMotion.getVariation(), "RandomMotionVariation", 1000.0f, 0.0f, 2000.0f, 0.0f );
  159. mParticleFields.addField( mRandomMotion.getLife(), "RandomMotionLife", 1.0f, -100.0f, 100.0f, 1.0f );
  160. mParticleFields.addField( mEmissionForce.getBase(), "EmissionForce", 1000.0f, -100.0f, 1000.0f, 5.0f );
  161. mParticleFields.addField( mEmissionForce.getVariation(), "EmissionForceVariation", 1000.0f, -500.0f, 500.0f, 5.0f );
  162. mParticleFields.addField( mEmissionAngle.getBase(), "EmissionAngle", 1000.0f, -180.0f, 180.0f, 0.0f );
  163. mParticleFields.addField( mEmissionAngle.getVariation(), "EmissionAngleVariation", 1000.0f, 0.0f, 360.0f, 0.0f );
  164. mParticleFields.addField( mEmissionArc.getBase(), "EmissionArc", 1000.0f, 0.0f, 360.0f, 360.0f );
  165. mParticleFields.addField( mEmissionArc.getVariation(), "EmissionArcVariation", 1000.0f, 0.0f, 720.0f, 0.0f );
  166. mParticleFields.addField( mRedChannel.getLife(), "RedChannel", 1.0f, 0.0f, 1.0f, 1.0f );
  167. mParticleFields.addField( mGreenChannel.getLife(), "GreenChannel", 1.0f, 0.0f, 1.0f, 1.0f );
  168. mParticleFields.addField( mBlueChannel.getLife(), "BlueChannel", 1.0f, 0.0f, 1.0f, 1.0f );
  169. mParticleFields.addField( mAlphaChannel.getLife(), "AlphaChannel", 1.0f, 0.0f, 1.0f, 1.0f );
  170. // Register for refresh notifications.
  171. mImageAsset.registerRefreshNotify( this );
  172. mAnimationAsset.registerRefreshNotify( this );
  173. mNamedImageFrame = "";
  174. mUsingNamedFrame = false;
  175. }
  176. //------------------------------------------------------------------------------
  177. ParticleAssetEmitter::~ParticleAssetEmitter()
  178. {
  179. }
  180. //------------------------------------------------------------------------------
  181. void ParticleAssetEmitter::initPersistFields()
  182. {
  183. // Call parent.
  184. Parent::initPersistFields();
  185. addProtectedField("EmitterName", TypeString, Offset(mEmitterName, ParticleAssetEmitter), &setEmitterName, &defaultProtectedGetFn, &defaultProtectedWriteFn, "");
  186. addProtectedField("EmitterType", TypeEnum, Offset(mEmitterType, ParticleAssetEmitter), &setEmitterType, &defaultProtectedGetFn, &writeEmitterType, 1, &EmitterTypeTable);
  187. addProtectedField("EmitterOffset", TypeVector2, Offset(mEmitterOffset, ParticleAssetEmitter), &setEmitterOffset, &defaultProtectedGetFn, &writeEmitterOffset, "");
  188. addProtectedField("EmitterAngle", TypeF32, Offset(mEmitterAngle, ParticleAssetEmitter), &setEmitterAngle, &defaultProtectedGetFn, &writeEmitterAngle, "");
  189. addProtectedField("EmitterSize", TypeVector2, Offset(mEmitterSize, ParticleAssetEmitter), &setEmitterSize, &defaultProtectedGetFn, &writeEmitterSize, "");
  190. addProtectedField("FixedAspect", TypeBool, Offset(mFixedAspect, ParticleAssetEmitter), &setFixedAspect, &defaultProtectedGetFn, &writeFixedAspect, "");
  191. addProtectedField("FixedForceAngle", TypeF32, Offset(mFixedForceAngle, ParticleAssetEmitter), &setFixedForceAngle, &defaultProtectedGetFn, &writeFixedForceAngle, "");
  192. addProtectedField("OrientationType", TypeEnum, Offset(mOrientationType, ParticleAssetEmitter), &setOrientationType, &defaultProtectedGetFn, &writeOrientationType, 1, &OrientationTypeTable);
  193. addProtectedField("KeepAligned", TypeBool, Offset(mKeepAligned, ParticleAssetEmitter), &setKeepAligned, &defaultProtectedGetFn, &writeKeepAligned, "");
  194. addProtectedField("AlignedAngleOffset", TypeF32, Offset(mAlignedAngleOffset, ParticleAssetEmitter), &setAlignedAngleOffset, &defaultProtectedGetFn, &writeAlignedAngleOffset, "");
  195. addProtectedField("RandomAngleOffset", TypeF32, Offset(mRandomAngleOffset, ParticleAssetEmitter), &setRandomAngleOffset, &defaultProtectedGetFn, &writeRandomAngleOffset, "");
  196. addProtectedField("RandomArc", TypeF32, Offset(mRandomArc, ParticleAssetEmitter), &setRandomArc, &defaultProtectedGetFn, &writeRandomArc, "");
  197. addProtectedField("FixedAngleOffset", TypeF32, Offset(mFixedAngleOffset, ParticleAssetEmitter), &setFixedAngleOffset, &defaultProtectedGetFn, &writeFixedAngleOffset, "");
  198. addProtectedField("PivotPoint", TypeVector2, Offset(mPivotPoint, ParticleAssetEmitter), &setPivotPoint, &defaultProtectedGetFn, &writePivotPoint, "");
  199. addProtectedField("LinkEmissionRotation", TypeBool, Offset(mLinkEmissionRotation, ParticleAssetEmitter), &setLinkEmissionRotation, &defaultProtectedGetFn, &writeLinkEmissionRotation, "");
  200. addProtectedField("IntenseParticles", TypeBool, Offset(mIntenseParticles, ParticleAssetEmitter), &setIntenseParticles, &defaultProtectedGetFn, &writeIntenseParticles, "");
  201. addProtectedField("SingleParticle", TypeBool, Offset(mSingleParticle, ParticleAssetEmitter), &setSingleParticle, &defaultProtectedGetFn, &writeSingleParticle, "");
  202. addProtectedField("AttachPositionToEmitter", TypeBool, Offset(mAttachPositionToEmitter, ParticleAssetEmitter), &setAttachPositionToEmitter, &defaultProtectedGetFn, &writeAttachPositionToEmitter, "");
  203. addProtectedField("AttachRotationToEmitter", TypeBool, Offset(mAttachRotationToEmitter, ParticleAssetEmitter), &setAttachRotationToEmitter, &defaultProtectedGetFn, &writeAttachRotationToEmitter, "");
  204. addProtectedField("OldestInFront", TypeBool, Offset(mOldestInFront, ParticleAssetEmitter), &setOldestInFront, &defaultProtectedGetFn, &writeOldestInFront, "");
  205. addProtectedField("BlendMode", TypeBool, Offset(mBlendMode, ParticleAssetEmitter), &setBlendMode, &defaultProtectedGetFn, &writeBlendMode, "");
  206. addProtectedField("SrcBlendFactor", TypeEnum, Offset(mSrcBlendFactor, ParticleAssetEmitter), &setSrcBlendFactor, &defaultProtectedGetFn, &writeSrcBlendFactor, 1, &srcBlendFactorTable, "");
  207. addProtectedField("DstBlendFactor", TypeEnum, Offset(mDstBlendFactor, ParticleAssetEmitter), &setDstBlendFactor, &defaultProtectedGetFn, &writeDstBlendFactor, 1, &dstBlendFactorTable, "");
  208. addProtectedField("AlphaTest", TypeF32, Offset(mAlphaTest, ParticleAssetEmitter), &setAlphaTest, &defaultProtectedGetFn, &writeAlphaTest, "");
  209. addProtectedField("Image", TypeImageAssetPtr, Offset(mImageAsset, ParticleAssetEmitter), &setImage, &getImage, &writeImage, "");
  210. addProtectedField("Frame", TypeS32, Offset(mImageFrame, ParticleAssetEmitter), &setImageFrame, &defaultProtectedGetFn, &writeImageFrame, "");
  211. addProtectedField("NamedFrame", TypeString, Offset(mNamedImageFrame, ParticleAssetEmitter), &setNamedImageFrame, &defaultProtectedGetFn, &writeNamedImageFrame, "");
  212. addProtectedField("RandomImageFrame", TypeBool, Offset(mRandomImageFrame, ParticleAssetEmitter), &setRandomImageFrame, &defaultProtectedGetFn, &writeRandomImageFrame, "");
  213. addProtectedField("Animation", TypeAnimationAssetPtr, Offset(mAnimationAsset, ParticleAssetEmitter), &setAnimation, &getAnimation, &writeAnimation, "");
  214. }
  215. //------------------------------------------------------------------------------
  216. void ParticleAssetEmitter::copyTo(SimObject* object)
  217. {
  218. // Fetch particle asset emitter object.
  219. ParticleAssetEmitter* pParticleAssetEmitter = static_cast<ParticleAssetEmitter*>( object );
  220. // Sanity!
  221. AssertFatal( pParticleAssetEmitter != NULL, "ParticleAssetEmitter::copyTo() - Object is not the correct type.");
  222. // Copy parent.
  223. Parent::copyTo( object );
  224. // Copy fields.
  225. pParticleAssetEmitter->setEmitterName( getEmitterName() );
  226. pParticleAssetEmitter->setEmitterType( getEmitterType() );
  227. pParticleAssetEmitter->setEmitterOffset( getEmitterOffset() );
  228. pParticleAssetEmitter->setEmitterSize( getEmitterSize() );
  229. pParticleAssetEmitter->setEmitterAngle( getEmitterAngle() );
  230. pParticleAssetEmitter->setFixedAspect( getFixedAspect() );
  231. pParticleAssetEmitter->setFixedForceAngle( getFixedForceAngle() );
  232. pParticleAssetEmitter->setOrientationType( getOrientationType() );
  233. pParticleAssetEmitter->setKeepAligned( getKeepAligned() );
  234. pParticleAssetEmitter->setAlignedAngleOffset( getAlignedAngleOffset() );
  235. pParticleAssetEmitter->setRandomAngleOffset( getRandomAngleOffset() );
  236. pParticleAssetEmitter->setRandomArc( getRandomArc() );
  237. pParticleAssetEmitter->setFixedAngleOffset( getFixedAngleOffset() );
  238. pParticleAssetEmitter->setPivotPoint( getPivotPoint() );
  239. pParticleAssetEmitter->setLinkEmissionRotation( getLinkEmissionRotation() );
  240. pParticleAssetEmitter->setIntenseParticles( getIntenseParticles() );
  241. pParticleAssetEmitter->setSingleParticle( getSingleParticle() );
  242. pParticleAssetEmitter->setAttachPositionToEmitter( getAttachPositionToEmitter() );
  243. pParticleAssetEmitter->setAttachRotationToEmitter( getAttachRotationToEmitter() );
  244. pParticleAssetEmitter->setOldestInFront( getOldestInFront() );
  245. pParticleAssetEmitter->setBlendMode( getBlendMode() );
  246. pParticleAssetEmitter->setSrcBlendFactor( getSrcBlendFactor() );
  247. pParticleAssetEmitter->setDstBlendFactor( getDstBlendFactor() );
  248. pParticleAssetEmitter->setAlphaTest( getAlphaTest() );
  249. pParticleAssetEmitter->setRandomImageFrame( getRandomImageFrame() );
  250. // Static provider?
  251. if ( pParticleAssetEmitter->isStaticFrameProvider() )
  252. {
  253. // Named image frame?
  254. if ( pParticleAssetEmitter->isUsingNamedImageFrame() )
  255. pParticleAssetEmitter->setImage( getImage(), getNamedImageFrame() );
  256. else
  257. pParticleAssetEmitter->setImage( getImage(), getImageFrame() );
  258. }
  259. else
  260. {
  261. pParticleAssetEmitter->setAnimation( getAnimation() );
  262. }
  263. // Copy particle fields.
  264. mParticleFields.copyTo( pParticleAssetEmitter->mParticleFields );
  265. }
  266. //-----------------------------------------------------------------------------
  267. void ParticleAssetEmitter::setEmitterName( const char* pEmitterName )
  268. {
  269. // Sanity!
  270. AssertFatal( mEmitterName != NULL, "ParticleAssetEmitter::setEmitterName() - Cannot set a NULL particle asset emitter name." );
  271. // Set the emitter name.
  272. mEmitterName = StringTable->insert( pEmitterName );
  273. // Refresh the asset.
  274. refreshAsset();
  275. }
  276. //-----------------------------------------------------------------------------
  277. void ParticleAssetEmitter::setOwner( ParticleAsset* pParticleAsset )
  278. {
  279. // Sanity!
  280. AssertFatal( mOwner == NULL, "ParticleAssetEmitter::setOwner() - Cannot set an owner when one is already assigned." );
  281. // Set owner.
  282. mOwner = pParticleAsset;
  283. }
  284. //------------------------------------------------------------------------------
  285. void ParticleAssetEmitter::setPivotPoint( const Vector2& pivotPoint )
  286. {
  287. // Set the pivot point.
  288. mPivotPoint = pivotPoint;
  289. // Calculate the local pivot AABB.
  290. mLocalPivotAABB[0].Set( -0.5f + mPivotPoint.x, -0.5f + mPivotPoint.y );
  291. mLocalPivotAABB[1].Set( 0.5f + mPivotPoint.x, -0.5f + mPivotPoint.y );
  292. mLocalPivotAABB[2].Set( 0.5f + mPivotPoint.x, 0.5f + mPivotPoint.y );
  293. mLocalPivotAABB[3].Set( -0.5f + mPivotPoint.x, 0.5f + mPivotPoint.y );
  294. // Refresh the asset.
  295. refreshAsset(); }
  296. //------------------------------------------------------------------------------
  297. void ParticleAssetEmitter::setFixedForceAngle( F32 fixedForceAngle )
  298. {
  299. // Set Fixed-Force Angle.
  300. mFixedForceAngle = fixedForceAngle;
  301. // Calculate the angle in radians.
  302. const F32 fixedForceAngleRadians = mDegToRad(mFixedForceAngle);
  303. // Set Fixed-Force Direction.
  304. mFixedForceDirection.Set( mCos(fixedForceAngleRadians), mSin(fixedForceAngleRadians) );
  305. // Refresh the asset.
  306. refreshAsset();
  307. }
  308. //------------------------------------------------------------------------------
  309. bool ParticleAssetEmitter::setImage( const char* pAssetId, U32 frame )
  310. {
  311. // Sanity!
  312. AssertFatal( pAssetId != NULL, "ParticleAssetEmitter::setImage() - Cannot use a NULL asset Id." );
  313. // Set static mode.
  314. mStaticMode = true;
  315. // Clear animation asset.
  316. mAnimationAsset.clear();
  317. // Set asset Id.
  318. mImageAsset = pAssetId;
  319. // Is there an asset?
  320. if ( mImageAsset.notNull() )
  321. {
  322. // Yes, so is the frame valid?
  323. if ( frame >= mImageAsset->getFrameCount() )
  324. {
  325. // No, so warn.
  326. Con::warnf( "ParticleAssetEmitter::setImage() - Invalid frame '%d' for ImageAsset '%s'.", frame, mImageAsset.getAssetId() );
  327. }
  328. else
  329. {
  330. // Yes, so set the frame.
  331. mImageFrame = frame;
  332. }
  333. }
  334. else
  335. {
  336. // No, so reset the image frame.
  337. mImageFrame = 0;
  338. }
  339. // Using a numerical frame index
  340. mUsingNamedFrame = false;
  341. // Refresh the asset.
  342. refreshAsset();
  343. // Return Okay.
  344. return true;
  345. }
  346. //------------------------------------------------------------------------------
  347. bool ParticleAssetEmitter::setImage( const char* pAssetId, const char* frameName )
  348. {
  349. // Sanity!
  350. AssertFatal( pAssetId != NULL, "ParticleAssetEmitter::setImage() - Cannot use a NULL asset Id." );
  351. // Set static mode.
  352. mStaticMode = true;
  353. // Clear animation asset.
  354. mAnimationAsset.clear();
  355. // Set asset Id.
  356. mImageAsset = pAssetId;
  357. // Is there an asset?
  358. if ( mImageAsset.notNull() )
  359. {
  360. // Yes, so is the frame valid?
  361. if ( !mImageAsset->containsFrame(frameName) )
  362. {
  363. // No, so warn.
  364. Con::warnf( "ParticleAssetEmitter::setImage() - Invalid frame '%s' for ImageAsset '%s'.", frameName, mImageAsset.getAssetId() );
  365. }
  366. else
  367. {
  368. // Yes, so set the frame.
  369. mNamedImageFrame = StringTable->insert(frameName);
  370. }
  371. }
  372. else
  373. {
  374. // No, so reset the image frame.
  375. mNamedImageFrame = StringTable->insert(StringTable->EmptyString);
  376. }
  377. // Using a named frame index
  378. mUsingNamedFrame = true;
  379. // Refresh the asset.
  380. refreshAsset();
  381. // Return Okay.
  382. return true;
  383. }
  384. //------------------------------------------------------------------------------
  385. bool ParticleAssetEmitter::setImageFrame( const U32 frame )
  386. {
  387. // Check Existing Image.
  388. if ( mImageAsset.isNull() )
  389. {
  390. // Warn.
  391. Con::warnf("ParticleAssetEmitter::setImageFrame() - Cannot set Frame without existing asset Id.");
  392. // Return Here.
  393. return false;
  394. }
  395. // Check Frame Validity.
  396. if ( frame >= mImageAsset->getFrameCount() )
  397. {
  398. // Warn.
  399. Con::warnf( "ParticleAssetEmitter::setImageFrame() - Invalid Frame #%d for asset Id '%s'.", frame, mImageAsset.getAssetId() );
  400. // Return Here.
  401. return false;
  402. }
  403. // Set Frame.
  404. mImageFrame = frame;
  405. // Using a numerical frame index.
  406. mUsingNamedFrame = false;
  407. // Refresh the asset.
  408. refreshAsset();
  409. // Return Okay.
  410. return true;
  411. }
  412. //------------------------------------------------------------------------------
  413. bool ParticleAssetEmitter::setNamedImageFrame( const char* frameName )
  414. {
  415. // Check Existing Image.
  416. if ( mImageAsset.isNull() )
  417. {
  418. // Warn.
  419. Con::warnf("ParticleAssetEmitter::setNamedImageFrame() - Cannot set Frame without existing asset Id.");
  420. // Return Here.
  421. return false;
  422. }
  423. // Check Frame Validity.
  424. if ( !mImageAsset->containsFrame(frameName) )
  425. {
  426. // Warn.
  427. Con::warnf( "ParticleAssetEmitter::setNamedImageFrame() - Invalid Frame %s for asset Id '%s'.", frameName, mImageAsset.getAssetId() );
  428. // Return Here.
  429. return false;
  430. }
  431. // Set frame.
  432. mNamedImageFrame = StringTable->insert(frameName);
  433. // Using a named frame index
  434. mUsingNamedFrame = true;
  435. // Refresh the asset.
  436. refreshAsset();
  437. // Return Okay.
  438. return true;
  439. }
  440. //------------------------------------------------------------------------------
  441. bool ParticleAssetEmitter::setAnimation( const char* pAnimationAssetId )
  442. {
  443. // Sanity!
  444. AssertFatal( pAnimationAssetId != NULL, "ParticleAssetEmitter::setAnimation() - Cannot use NULL asset Id." );
  445. // Set animated mode.
  446. mStaticMode = false;
  447. // Clear static asset.
  448. mImageAsset.clear();
  449. // Set animation asset.
  450. mAnimationAsset = pAnimationAssetId;
  451. // Refresh the asset.
  452. refreshAsset();
  453. return true;
  454. }
  455. //------------------------------------------------------------------------------
  456. void ParticleAssetEmitter::refreshAsset( void )
  457. {
  458. // Finish if no owner.
  459. if ( mOwner == NULL )
  460. return;
  461. // Refresh the asset.
  462. mOwner->refreshAsset();
  463. }
  464. //------------------------------------------------------------------------------
  465. void ParticleAssetEmitter::onAssetRefreshed( AssetPtrBase* pAssetPtrBase )
  466. {
  467. // Either the image or animation asset has been refreshed to just refresh the
  468. // asset that this emitter may belong to.
  469. ParticleAssetEmitter::refreshAsset();
  470. }
  471. //------------------------------------------------------------------------------
  472. void ParticleAssetEmitter::onTamlCustomWrite( TamlCustomNodes& customNodes )
  473. {
  474. // Debug Profiling.
  475. PROFILE_SCOPE(ParticleAssetEmitter_OnTamlCustomWrite);
  476. // Write the fields.
  477. mParticleFields.onTamlCustomWrite( customNodes );
  478. }
  479. //-----------------------------------------------------------------------------
  480. void ParticleAssetEmitter::onTamlCustomRead( const TamlCustomNodes& customNodes )
  481. {
  482. // Debug Profiling.
  483. PROFILE_SCOPE(ParticleAssetEmitter_OnTamlCustomRead);
  484. // Read the fields.
  485. mParticleFields.onTamlCustomRead( customNodes );
  486. }
  487. //-----------------------------------------------------------------------------
  488. static void WriteCustomTamlSchema( const AbstractClassRep* pClassRep, TiXmlElement* pParentElement )
  489. {
  490. // Sanity!
  491. AssertFatal( pClassRep != NULL, "ParticleAssetEmitter::WriteCustomTamlSchema() - ClassRep cannot be NULL." );
  492. AssertFatal( pParentElement != NULL, "ParticleAssetEmitter::WriteCustomTamlSchema() - Parent Element cannot be NULL." );
  493. // Write the particle asset emitter fields.
  494. ParticleAssetEmitter particleAssetEmitter;
  495. particleAssetEmitter.getParticleFields().WriteCustomTamlSchema( pClassRep, pParentElement );
  496. }
  497. //-----------------------------------------------------------------------------
  498. IMPLEMENT_CONOBJECT_SCHEMA(ParticleAssetEmitter, WriteCustomTamlSchema);