particleEmitter.h
Engine/source/T3D/fx/particleEmitter.h
Classes:
class
class
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 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//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 25// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames 26// Copyright (C) 2015 Faust Logic, Inc. 27//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 28 29#ifndef _H_PARTICLE_EMITTER 30#define _H_PARTICLE_EMITTER 31 32#ifndef _GAMEBASE_H_ 33#include "T3D/gameBase/gameBase.h" 34#endif 35#ifndef _COLOR_H_ 36#include "core/color.h" 37#endif 38#ifndef _GFXPRIMITIVEBUFFER_H_ 39#include "gfx/gfxPrimitiveBuffer.h" 40#endif 41#ifndef _GFXVERTEXBUFFER_H_ 42#include "gfx/gfxVertexBuffer.h" 43#endif 44#ifndef _PARTICLE_H_ 45#include "T3D/fx/particle.h" 46#endif 47 48class RenderPassManager; 49class ParticleData; 50 51#ifdef TORQUE_AFX_ENABLED 52 #define AFX_CAP_PARTICLE_POOLS 53 #if defined(AFX_CAP_PARTICLE_POOLS) 54 class afxParticlePoolData; 55 class afxParticlePool; 56 #endif 57#endif 58 59//***************************************************************************** 60// Particle Emitter Data 61//***************************************************************************** 62class ParticleEmitterData : public GameBaseData 63{ 64 typedef GameBaseData Parent; 65 66 static bool _setAlignDirection( void *object, const char *index, const char *data ); 67 68 public: 69 70 ParticleEmitterData(); 71 DECLARE_CONOBJECT(ParticleEmitterData); 72 static void initPersistFields(); 73 void packData(BitStream* stream); 74 void unpackData(BitStream* stream); 75 bool preload(bool server, String &errorStr); 76 bool onAdd(); 77 void allocPrimBuffer( S32 overrideSize = -1 ); 78 79 public: 80 S32 ejectionPeriodMS; ///< Time, in Milliseconds, between particle ejection 81 S32 periodVarianceMS; ///< Varience in ejection peroid between 0 and n 82 83 F32 ejectionVelocity; ///< Ejection velocity 84 F32 velocityVariance; ///< Variance for velocity between 0 and n 85 F32 ejectionOffset; ///< Z offset from emitter point to eject from 86 F32 ejectionOffsetVariance; ///< Z offset Variance from emitter point to eject 87 F32 thetaMin; ///< Minimum angle, from the horizontal plane, to eject from 88 F32 thetaMax; ///< Maximum angle, from the horizontal plane, to eject from 89 F32 thetaVariance; ///< Angle, from the previous particle, to eject from 90 91 F32 phiReferenceVel; ///< Reference angle, from the verticle plane, to eject from 92 F32 phiVariance; ///< Varience from the reference angle, from 0 to n 93 94 F32 softnessDistance; ///< For soft particles, the distance (in meters) where particles will be faded 95 ///< based on the difference in depth between the particle and the scene geometry. 96 97 /// A scalar value used to influence the effect 98 /// of the ambient color on the particle. 99 F32 ambientFactor; 100 101 S32 lifetimeMS; ///< Lifetime of particles 102 U32 lifetimeVarianceMS; ///< Varience in lifetime from 0 to n 103 104 bool overrideAdvance; ///< 105 bool orientParticles; ///< Particles always face the screen 106 bool orientOnVelocity; ///< Particles face the screen at the start 107 bool ribbonParticles; ///< Particles are rendered as a continous ribbon 108 bool useEmitterSizes; ///< Use emitter specified sizes instead of datablock sizes 109 bool useEmitterColors; ///< Use emitter specified colors instead of datablock colors 110 bool alignParticles; ///< Particles always face along a particular axis 111 Point3F alignDirection; ///< The direction aligned particles should face 112 113 StringTableEntry particleString; ///< Used to load particle data directly from a string 114 115 Vector<ParticleData*> particleDataBlocks; ///< Particle Datablocks 116 Vector<U32> dataBlockIds; ///< Datablock IDs (parellel array to particleDataBlocks) 117 118 U32 partListInitSize; /// initial size of particle list calc'd from datablock info 119 120 GFXPrimitiveBufferHandle primBuff; 121 122 S32 blendStyle; ///< Pre-define blend factor setting 123 bool sortParticles; ///< Particles are sorted back-to-front 124 bool reverseOrder; ///< reverses draw order 125 StringTableEntry textureName; ///< Emitter texture file to override particle textures 126 GFXTexHandle textureHandle; ///< Emitter texture handle from txrName 127 bool highResOnly; ///< This particle system should not use the mixed-resolution particle rendering 128 bool renderReflection; ///< Enables this emitter to render into reflection passes. 129 bool glow; ///< Renders this emitter into the glow buffer. 130 131 bool reload(); 132public: 133 bool fade_color; 134 bool fade_size; 135 bool fade_alpha; 136 bool ejectionInvert; 137 U8 parts_per_eject; 138 bool use_emitter_xfm; 139#if defined(AFX_CAP_PARTICLE_POOLS) 140public: 141 afxParticlePoolData* pool_datablock; 142 U32 pool_index; 143 bool pool_depth_fade; 144 bool pool_radial_fade; 145 bool do_pool_id_convert; 146#endif 147public: 148 /*C*/ ParticleEmitterData(const ParticleEmitterData&, bool = false); 149 /*D*/ ~ParticleEmitterData(); 150 virtual ParticleEmitterData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0); 151 virtual bool allowSubstitutions() const { return true; } 152}; 153 154//***************************************************************************** 155// Particle Emitter 156//***************************************************************************** 157class ParticleEmitter : public GameBase 158{ 159 typedef GameBase Parent; 160#if defined(AFX_CAP_PARTICLE_POOLS) 161 friend class afxParticlePool; 162#endif 163 164 public: 165 166 typedef GFXVertexPCT ParticleVertexType; 167 168 ParticleEmitter(); 169 ~ParticleEmitter(); 170 171 DECLARE_CONOBJECT(ParticleEmitter); 172 173 static Point3F mWindVelocity; 174 static void setWindVelocity( const Point3F &vel ){ mWindVelocity = vel; } 175 176 LinearColorF getCollectiveColor(); 177 178 /// Sets sizes of particles based on sizelist provided 179 /// @param sizeList List of sizes 180 void setSizes( F32 *sizeList ); 181 182 /// Sets colors for particles based on color list provided 183 /// @param colorList List of colors 184 void setColors( LinearColorF *colorList ); 185 186 ParticleEmitterData *getDataBlock(){ return mDataBlock; } 187 bool onNewDataBlock( GameBaseData *dptr, bool reload ); 188 189 /// By default, a particle renderer will wait for it's owner to delete it. When this 190 /// is turned on, it will delete itself as soon as it's particle count drops to zero. 191 void deleteWhenEmpty(); 192 193 /// @name Particle Emission 194 /// Main interface for creating particles. The emitter does _not_ track changes 195 /// in axis or velocity over the course of a single update, so this should be called 196 /// at a fairly fine grain. The emitter will potentially track the last particle 197 /// to be created into the next call to this function in order to create a uniformly 198 /// random time distribution of the particles. If the object to which the emitter is 199 /// attached is in motion, it should try to ensure that for call (n+1) to this 200 /// function, start is equal to the end from call (n). This will ensure a uniform 201 /// spatial distribution. 202 /// @{ 203 204 void emitParticles(const Point3F& start, 205 const Point3F& end, 206 const Point3F& axis, 207 const Point3F& velocity, 208 const U32 numMilliseconds); 209 void emitParticles(const Point3F& point, 210 const bool useLastPosition, 211 const Point3F& axis, 212 const Point3F& velocity, 213 const U32 numMilliseconds); 214 void emitParticles(const Point3F& rCenter, 215 const Point3F& rNormal, 216 const F32 radius, 217 const Point3F& velocity, 218 S32 count); 219 /// @} 220 221 bool mDead; 222 223 protected: 224 /// @name Internal interface 225 /// @{ 226 227 /// Adds a particle 228 /// @param pos Initial position of particle 229 /// @param axis 230 /// @param vel Initial velocity 231 /// @param axisx 232 void addParticle(const Point3F &pos, const Point3F &axis, const Point3F &vel, const Point3F &axisx, const U32 age_offset); 233 234 235 inline void setupBillboard( Particle *part, 236 Point3F *basePts, 237 const MatrixF &camView, 238 const LinearColorF &ambientColor, 239 ParticleVertexType *lVerts ); 240 241 inline void setupOriented( Particle *part, 242 const Point3F &camPos, 243 const LinearColorF &ambientColor, 244 ParticleVertexType *lVerts ); 245 246 inline void setupAligned( const Particle *part, 247 const LinearColorF &ambientColor, 248 ParticleVertexType *lVerts ); 249 250 inline void setupRibbon( Particle *part, 251 Particle *next, 252 Particle *prev, 253 const Point3F &camPos, 254 const LinearColorF &ambientColor, 255 ParticleVertexType *lVerts); 256 257 /// Updates the bounding box for the particle system 258 void updateBBox(); 259 260 /// @} 261 protected: 262 bool onAdd(); 263 void onRemove(); 264 265 void processTick(const Move *move); 266 void advanceTime(F32 dt); 267 268 // Rendering 269 protected: 270 void prepRenderImage( SceneRenderState *state ); 271 void copyToVB( const Point3F &camPos, const LinearColorF &ambientColor ); 272 273 // PEngine interface 274 private: 275 276 // AFX subclasses to ParticleEmitter require access to some members and methods of 277 // ParticleEmitter which are normally declared with private scope. In this section, 278 // protected and private scope statements have been inserted inline with the original 279 // code to expose the necessary members and methods. 280 void update( U32 ms ); 281protected: 282 inline void updateKeyData( Particle *part ); 283 284 285 private: 286 287 /// Constant used to calculate particle 288 /// rotation from spin and age. 289 static const F32 AgedSpinToRadians; 290 291 ParticleEmitterData* mDataBlock; 292 293protected: 294 U32 mInternalClock; 295 296 U32 mNextParticleTime; 297 298 F32 mThetaOld; 299 F32 mPhiOld; 300 301 Point3F mLastPosition; 302 bool mHasLastPosition; 303private: 304 MatrixF mBBObjToWorld; 305 306 bool mDeleteWhenEmpty; 307 bool mDeleteOnTick; 308 309protected: 310 S32 mLifetimeMS; 311 S32 mElapsedTimeMS; 312 313private: 314 F32 sizes[ ParticleData::PDC_NUM_KEYS ]; 315 LinearColorF colors[ ParticleData::PDC_NUM_KEYS ]; 316 317 GFXVertexBufferHandle<ParticleVertexType> mVertBuff; 318 319protected: 320 // These members are for implementing a link-list of the active emitter 321 // particles. Member part_store contains blocks of particles that can be 322 // chained in a link-list. Usually the first part_store block is large 323 // enough to contain all the particles but it can be expanded in emergency 324 // circumstances. 325 Vector <Particle*> part_store; 326 Particle* part_freelist; 327 Particle part_list_head; 328 S32 n_part_capacity; 329 S32 n_parts; 330private: 331 S32 mCurBuffSize; 332 333 protected: 334 F32 fade_amt; 335 bool forced_bbox; 336 bool db_temp_clone; 337 Point3F pos_pe; 338 S8 sort_priority; 339 virtual void sub_particleUpdate(Particle*) { } 340 public: 341 virtual void emitParticlesExt(const MatrixF& xfm, const Point3F& point, const Point3F& velocity, const U32 numMilliseconds); 342 void setFadeAmount(F32 amt) { fade_amt = amt; } 343 void setForcedObjBox(Box3F& box); 344 void setSortPriority(S8 priority); 345#if defined(AFX_CAP_PARTICLE_POOLS) 346 protected: 347 afxParticlePool* pool; 348 public: 349 void clearPool() { pool = 0; } 350 void setPool(afxParticlePool* p) { pool = p; } 351#endif 352}; 353 354#endif // _H_PARTICLE_EMITTER 355 356