/src/ogre/OgreMain/include/OgreParticleSystem.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | ----------------------------------------------------------------------------- |
3 | | This source file is part of OGRE |
4 | | (Object-oriented Graphics Rendering Engine) |
5 | | For the latest info, see http://www.ogre3d.org/ |
6 | | |
7 | | Copyright (c) 2000-2014 Torus Knot Software Ltd |
8 | | |
9 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | | of this software and associated documentation files (the "Software"), to deal |
11 | | in the Software without restriction, including without limitation the rights |
12 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | | copies of the Software, and to permit persons to whom the Software is |
14 | | furnished to do so, subject to the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be included in |
17 | | all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | | THE SOFTWARE. |
26 | | ----------------------------------------------------------------------------- |
27 | | */ |
28 | | #ifndef __ParticleSystem_H__ |
29 | | #define __ParticleSystem_H__ |
30 | | |
31 | | #include "OgrePrerequisites.h" |
32 | | |
33 | | #include "OgreVector.h" |
34 | | #include "OgreStringInterface.h" |
35 | | #include "OgreMovableObject.h" |
36 | | #include "OgreResourceGroupManager.h" |
37 | | #include "OgreHeaderPrefix.h" |
38 | | |
39 | | |
40 | | namespace Ogre { |
41 | | |
42 | | /** \addtogroup Core |
43 | | * @{ |
44 | | */ |
45 | | /** \addtogroup Effects |
46 | | * @{ |
47 | | */ |
48 | | /** Class defining particle system based special effects. |
49 | | |
50 | | Particle systems are special effects generators which are based on a |
51 | | number of moving points to create the impression of things like like |
52 | | sparkles, smoke, blood spurts, dust etc. |
53 | | @par |
54 | | This class simply manages a single collection of particles in world space |
55 | | with a shared local origin for emission. The visual aspect of the |
56 | | particles is handled by a ParticleSystemRenderer instance. |
57 | | @par |
58 | | Particle systems are created using the SceneManager, never directly. |
59 | | In addition, like all subclasses of MovableObject, the ParticleSystem |
60 | | will only be considered for rendering once it has been attached to a |
61 | | SceneNode. |
62 | | */ |
63 | | class _OgreExport ParticleSystem : public MovableObject, public StringInterface |
64 | | { |
65 | | public: |
66 | | /// Default constructor required for STL creation in manager |
67 | | ParticleSystem(); |
68 | | /** Creates a particle system with no emitters or affectors. |
69 | | |
70 | | You should use the ParticleSystemManager to create particle systems rather than creating |
71 | | them directly. |
72 | | */ |
73 | | ParticleSystem(const String& name, const String& resourceGroupName); |
74 | | |
75 | | virtual ~ParticleSystem(); |
76 | | |
77 | | /** Sets the ParticleRenderer to be used to render this particle system. |
78 | | |
79 | | The main ParticleSystem just manages the creation and movement of |
80 | | particles; they are rendered using functions in ParticleRenderer |
81 | | and the ParticleVisual instances they create. |
82 | | @param typeName String identifying the type of renderer to use; a new |
83 | | instance of this type will be created; a factory must have been registered |
84 | | with ParticleSystemManager. |
85 | | */ |
86 | | void setRenderer(const String& typeName); |
87 | | |
88 | | /** Gets the ParticleRenderer to be used to render this particle system. */ |
89 | | ParticleSystemRenderer* getRenderer(void) const; |
90 | | /** Gets the name of the ParticleRenderer to be used to render this particle system. */ |
91 | | const String& getRendererName(void) const; |
92 | | |
93 | | /** Adds an emitter to this particle system. |
94 | | |
95 | | Particles are created in a particle system by emitters - see the ParticleEmitter |
96 | | class for more details. |
97 | | @param |
98 | | emitterType String identifying the emitter type to create. Emitter types are defined |
99 | | by registering new factories with the manager - see ParticleEmitterFactory for more details. |
100 | | Emitter types can be extended by OGRE, plugin authors or application developers. |
101 | | */ |
102 | | ParticleEmitter* addEmitter(const String& emitterType); |
103 | | |
104 | | /** Retrieves an emitter by it's index (zero-based). |
105 | | |
106 | | Used to retrieve a pointer to an emitter for a particle system to procedurally change |
107 | | emission parameters etc. |
108 | | You should check how many emitters are registered against this system before calling |
109 | | this method with an arbitrary index using getNumEmitters. |
110 | | @param |
111 | | index Zero-based index of the emitter to retrieve. |
112 | | */ |
113 | | ParticleEmitter* getEmitter(unsigned short index) const; |
114 | | |
115 | | /** Returns the number of emitters for this particle system. */ |
116 | | unsigned short getNumEmitters(void) const; |
117 | | |
118 | | /** Removes an emitter from the system. |
119 | | |
120 | | Drops the emitter with the index specified from this system. |
121 | | You should check how many emitters are registered against this system before calling |
122 | | this method with an arbitrary index using getNumEmitters. |
123 | | @param |
124 | | index Zero-based index of the emitter to retrieve. |
125 | | */ |
126 | | void removeEmitter(unsigned short index); |
127 | | |
128 | | /** Removes all the emitters from this system. */ |
129 | | void removeAllEmitters(void); |
130 | | |
131 | | /** Removes an emitter from the system. |
132 | | |
133 | | Drops the emitter from this system. |
134 | | @param |
135 | | emitter Pointer to a particle emitter. |
136 | | */ |
137 | | void removeEmitter(ParticleEmitter *emitter); |
138 | | |
139 | | /** Adds an affector to this particle system. |
140 | | |
141 | | Particles are modified over time in a particle system by affectors - see the ParticleAffector |
142 | | class for more details. |
143 | | @param |
144 | | affectorType String identifying the affector type to create. Affector types are defined |
145 | | by registering new factories with the manager - see ParticleAffectorFactory for more details. |
146 | | Affector types can be extended by OGRE, plugin authors or application developers. |
147 | | */ |
148 | | ParticleAffector* addAffector(const String& affectorType); |
149 | | |
150 | | /** Retrieves an affector by it's index (zero-based). |
151 | | |
152 | | Used to retrieve a pointer to an affector for a particle system to procedurally change |
153 | | affector parameters etc. |
154 | | You should check how many affectors are registered against this system before calling |
155 | | this method with an arbitrary index using getNumAffectors. |
156 | | @param |
157 | | index Zero-based index of the affector to retrieve. |
158 | | */ |
159 | | ParticleAffector* getAffector(unsigned short index) const; |
160 | | |
161 | | /** Returns the number of affectors for this particle system. */ |
162 | | unsigned short getNumAffectors(void) const; |
163 | | |
164 | | /** Removes an affector from the system. |
165 | | |
166 | | Drops the affector with the index specified from this system. |
167 | | You should check how many affectors are registered against this system before calling |
168 | | this method with an arbitrary index using getNumAffectors. |
169 | | @param |
170 | | index Zero-based index of the affector to retrieve. |
171 | | */ |
172 | | void removeAffector(unsigned short index); |
173 | | |
174 | | /** Removes all the affectors from this system. */ |
175 | | void removeAllAffectors(void); |
176 | | |
177 | | /** Empties this set of all particles. |
178 | | */ |
179 | | void clear(); |
180 | | |
181 | | /** Gets the number of individual particles in the system right now. |
182 | | |
183 | | The number of particles active in a system at a point in time depends on |
184 | | the number of emitters, their emission rates, the time-to-live (TTL) each particle is |
185 | | given on emission (and whether any affectors modify that TTL) and the maximum |
186 | | number of particles allowed in this system at once (particle quota). |
187 | | */ |
188 | | size_t getNumParticles(void) const; |
189 | | |
190 | | /** Manually add a particle to the system. |
191 | | |
192 | | Instead of using an emitter, you can manually add a particle to the system. |
193 | | You must initialise the returned particle instance immediately with the |
194 | | 'emission' state. |
195 | | @note |
196 | | There is no corresponding 'destroyParticle' method - if you want to dispose of a |
197 | | particle manually (say, if you've used setSpeedFactor(0) to make particles live forever) |
198 | | you should use getParticle() and modify it's timeToLive to zero, meaning that it will |
199 | | get cleaned up in the next update. |
200 | | */ |
201 | | Particle* createParticle(void); |
202 | | |
203 | | /** Manually add an emitter particle to the system. |
204 | | |
205 | | The purpose of a particle emitter is to emit particles. Besides visual particles, also other other |
206 | | particle types can be emitted, other emitters for example. The emitted emitters have a double role; |
207 | | they behave as particles and can be influenced by affectors, but they are still emitters and capable |
208 | | to emit other particles (or emitters). It is possible to create a chain of emitters - emitters |
209 | | emitting other emitters, which also emit emitters. |
210 | | @param emitterName The name of a particle emitter that must be emitted. |
211 | | */ |
212 | | Particle* createEmitterParticle(const String& emitterName); |
213 | | |
214 | | /** Retrieve a particle from the system for manual tweaking. |
215 | | |
216 | | Normally you use an affector to alter particles in flight, but |
217 | | for small manually controlled particle systems you might want to use |
218 | | this method. |
219 | | */ |
220 | | Particle* getParticle(size_t index); |
221 | | |
222 | | /** Returns the maximum number of particles this system is allowed to have active at once. |
223 | | |
224 | | See ParticleSystem::setParticleQuota for more info. |
225 | | */ |
226 | | size_t getParticleQuota(void) const; |
227 | | |
228 | | /** Sets the maximum number of particles this system is allowed to have active at once. |
229 | | |
230 | | Particle systems all have a particle quota, i.e. a maximum number of particles they are |
231 | | allowed to have active at a time. This allows the application to set a keep particle systems |
232 | | under control should they be affected by complex parameters which alter their emission rates |
233 | | etc. If a particle system reaches it's particle quota, none of the emitters will be able to |
234 | | emit any more particles. As existing particles die, the spare capacity will be allocated |
235 | | equally across all emitters to be as consistent to the original particle system style as possible. |
236 | | The quota can be increased but not decreased after the system has been created. |
237 | | @param quota The maximum number of particles this system is allowed to have. |
238 | | */ |
239 | | void setParticleQuota(size_t quota); |
240 | | |
241 | | /** Returns the maximum number of emitted emitters this system is allowed to have active at once. |
242 | | |
243 | | See ParticleSystem::setEmittedEmitterQuota for more info. |
244 | | */ |
245 | | size_t getEmittedEmitterQuota(void) const; |
246 | | |
247 | | /** Sets the maximum number of emitted emitters this system is allowed to have active at once. |
248 | | |
249 | | Particle systems can have - besides a particle quota - also an emitted emitter quota. |
250 | | @param quota The maximum number of emitted emitters this system is allowed to have. |
251 | | */ |
252 | | void setEmittedEmitterQuota(size_t quota); |
253 | | |
254 | | /** Assignment operator for copying. |
255 | | |
256 | | This operator deep copies all particle emitters and effectors, but not particles. The |
257 | | system's name is also not copied. |
258 | | */ |
259 | | ParticleSystem& operator=(const ParticleSystem& rhs); |
260 | | |
261 | | /** Updates the particles in the system based on time elapsed. |
262 | | |
263 | | This is called automatically every frame by OGRE. |
264 | | @param |
265 | | timeElapsed The amount of time, in seconds, since the last frame. |
266 | | */ |
267 | | void _update(Real timeElapsed); |
268 | | |
269 | | /** Returns all active particles in this system. |
270 | | |
271 | | This method is designed to be used by people providing new ParticleAffector subclasses, |
272 | | this is the easiest way to step through all the particles in a system and apply the |
273 | | changes the affector wants to make. |
274 | | */ |
275 | 0 | const std::vector<Particle*>& _getActiveParticles() { return mActiveParticles; } |
276 | | |
277 | | /** Sets the name of the material to be used for this billboard set. |
278 | | */ |
279 | | virtual void setMaterialName( const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME ); |
280 | | |
281 | | /** Sets the name of the material to be used for this billboard set. |
282 | | @return The name of the material that is used for this set. |
283 | | */ |
284 | | virtual const String& getMaterialName(void) const; |
285 | | |
286 | | void _notifyCurrentCamera(Camera* cam) override; |
287 | | void _notifyAttached(Node* parent, bool isTagPoint = false) override; |
288 | 0 | const AxisAlignedBox& getBoundingBox(void) const override { return mAABB; } |
289 | 0 | Real getBoundingRadius(void) const override { return mBoundingRadius; } |
290 | | void _updateRenderQueue(RenderQueue* queue) override; |
291 | | |
292 | | /// @copydoc MovableObject::visitRenderables |
293 | | void visitRenderables(Renderable::Visitor* visitor, |
294 | | bool debugRenderables = false) override; |
295 | | |
296 | | /** Fast-forwards this system by the required number of seconds. |
297 | | |
298 | | This method allows you to fast-forward a system so that it effectively looks like |
299 | | it has already been running for the time you specify. This is useful to avoid the |
300 | | 'startup sequence' of a system, when you want the system to be fully populated right |
301 | | from the start. |
302 | | @param |
303 | | time The number of seconds to fast-forward by. |
304 | | @param |
305 | | interval The sampling interval used to generate particles, apply affectors etc. The lower this |
306 | | is the more realistic the fast-forward, but it takes more iterations to do it. |
307 | | */ |
308 | | void fastForward(Real time, Real interval = 0.1f); |
309 | | |
310 | | /** Sets a 'speed factor' on this particle system, which means it scales the elapsed |
311 | | real time which has passed by this factor before passing it to the emitters, affectors, |
312 | | and the particle life calculation. |
313 | | |
314 | | An interesting side effect - if you want to create a completely manual particle system |
315 | | where you control the emission and life of particles yourself, you can set the speed |
316 | | factor to 0.0f, thus disabling normal particle emission, alteration, and death. |
317 | | */ |
318 | 0 | void setSpeedFactor(Real speedFactor) { mSpeedFactor = speedFactor; } |
319 | | |
320 | | /** Gets the 'speed factor' on this particle system. |
321 | | */ |
322 | 0 | Real getSpeedFactor(void) const { return mSpeedFactor; } |
323 | | |
324 | | /** Sets a 'iteration interval' on this particle system. |
325 | | |
326 | | The default Particle system update interval, based on elapsed frame time, |
327 | | will cause different behavior between low frame-rate and high frame-rate. |
328 | | By using this option, you can make the particle system update at |
329 | | a fixed interval, keeping the behavior the same no matter what frame-rate |
330 | | is. |
331 | | @par |
332 | | When iteration interval is set to zero, it means the update occurs based |
333 | | on an elapsed frame time, otherwise each iteration will take place |
334 | | at the given interval, repeating until it has used up all the elapsed |
335 | | frame time. |
336 | | @param |
337 | | iterationInterval The iteration interval, default to zero. |
338 | | */ |
339 | | void setIterationInterval(Real iterationInterval); |
340 | | |
341 | | /** Gets a 'iteration interval' on this particle system. |
342 | | */ |
343 | 0 | Real getIterationInterval(void) const { return mIterationInterval; } |
344 | | |
345 | | /** Set the default iteration interval for all ParticleSystem instances. |
346 | | */ |
347 | 0 | static void setDefaultIterationInterval(Real iterationInterval) { msDefaultIterationInterval = iterationInterval; } |
348 | | |
349 | | /** Get the default iteration interval for all ParticleSystem instances. |
350 | | */ |
351 | 0 | static Real getDefaultIterationInterval(void) { return msDefaultIterationInterval; } |
352 | | |
353 | | /** Sets when the particle system should stop updating after it hasn't been |
354 | | visible for a while. |
355 | | |
356 | | By default, visible particle systems update all the time, even when |
357 | | not in view. This means that they are guaranteed to be consistent when |
358 | | they do enter view. However, this comes at a cost, updating particle |
359 | | systems can be expensive, especially if they are perpetual. |
360 | | @par |
361 | | This option lets you set a 'timeout' on the particle system, so that |
362 | | if it isn't visible for this amount of time, it will stop updating |
363 | | until it is next visible. |
364 | | @param timeout The time after which the particle system will be disabled |
365 | | if it is no longer visible. 0 to disable the timeout and always update. |
366 | | */ |
367 | | void setNonVisibleUpdateTimeout(Real timeout); |
368 | | /** Gets when the particle system should stop updating after it hasn't been |
369 | | visible for a while. |
370 | | */ |
371 | 0 | Real getNonVisibleUpdateTimeout(void) const { return mNonvisibleTimeout; } |
372 | | |
373 | | /** Set the default nonvisible timeout for all ParticleSystem instances. |
374 | | */ |
375 | | static void setDefaultNonVisibleUpdateTimeout(Real timeout) |
376 | 0 | { msDefaultNonvisibleTimeout = timeout; } |
377 | | |
378 | | /** Get the default nonvisible timeout for all ParticleSystem instances. |
379 | | */ |
380 | 0 | static Real getDefaultNonVisibleUpdateTimeout(void) { return msDefaultNonvisibleTimeout; } |
381 | | |
382 | | const String& getMovableType(void) const override; |
383 | | |
384 | | /** Sets the default dimensions of the particles in this set. |
385 | | |
386 | | All particles in a set are created with these default dimensions. The set will render most efficiently if |
387 | | all the particles in the set are the default size. It is possible to alter the size of individual |
388 | | particles at the expense of extra calculation. See the Particle class for more info. |
389 | | @param width |
390 | | The new default width for the particles in this set. Must be non-negative! |
391 | | @param height |
392 | | The new default height for the particles in this set. Must be non-negative! |
393 | | */ |
394 | | void setDefaultDimensions(Real width, Real height); |
395 | | |
396 | | /** See setDefaultDimensions - this sets 1 component individually. */ |
397 | | virtual void setDefaultWidth(Real width); |
398 | | /** See setDefaultDimensions - this gets 1 component individually. */ |
399 | | virtual Real getDefaultWidth(void) const; |
400 | | /** See setDefaultDimensions - this sets 1 component individually. */ |
401 | | virtual void setDefaultHeight(Real height); |
402 | | /** See setDefaultDimensions - this gets 1 component individually. */ |
403 | | virtual Real getDefaultHeight(void) const; |
404 | | /** Returns whether or not particles in this are tested individually for culling. */ |
405 | | virtual bool getCullIndividually(void) const; |
406 | | /** Sets whether culling tests particles in this individually as well as in a group. |
407 | | |
408 | | Particle sets are always culled as a whole group, based on a bounding box which |
409 | | encloses all particles in the set. For fairly localised sets, this is enough. However, you |
410 | | can optionally tell the set to also cull individual particles in the set, i.e. to test |
411 | | each individual particle before rendering. The default is not to do this. |
412 | | @par |
413 | | This is useful when you have a large, fairly distributed set of particles, like maybe |
414 | | trees on a landscape. You probably still want to group them into more than one |
415 | | set (maybe one set per section of landscape), which will be culled coarsely, but you also |
416 | | want to cull the particles individually because they are spread out. Whilst you could have |
417 | | lots of single-tree sets which are culled separately, this would be inefficient to render |
418 | | because each tree would be issued as it's own rendering operation. |
419 | | @par |
420 | | By calling this method with a parameter of true, you can have large particle sets which |
421 | | are spaced out and so get the benefit of batch rendering and coarse culling, but also have |
422 | | fine-grained culling so unnecessary rendering is avoided. |
423 | | @param cullIndividual If true, each particle is tested before being sent to the pipeline as well |
424 | | as the whole set having to pass the coarse group bounding test. |
425 | | */ |
426 | | virtual void setCullIndividually(bool cullIndividual); |
427 | | /// Return the resource group to be used to load dependent resources |
428 | 0 | virtual const String& getResourceGroupName(void) const { return mResourceGroupName; } |
429 | | /** Get the origin of this particle system, e.g. a script file name. |
430 | | |
431 | | This property will only contain something if the creator of |
432 | | this particle system chose to populate it. Script loaders are advised |
433 | | to populate it. |
434 | | */ |
435 | 0 | const String& getOrigin(void) const { return mOrigin; } |
436 | | /// Notify this particle system of it's origin |
437 | 0 | void _notifyOrigin(const String& origin) { mOrigin = origin; } |
438 | | |
439 | | /** @copydoc MovableObject::setRenderQueueGroup */ |
440 | | void setRenderQueueGroup(uint8 queueID) override; |
441 | | /** @copydoc MovableObject::setRenderQueueGroupAndPriority */ |
442 | | void setRenderQueueGroupAndPriority(uint8 queueID, ushort priority) override; |
443 | | |
444 | | /** Set whether or not particles are sorted according to the camera. |
445 | | |
446 | | Enabling sorting alters the order particles are sent to the renderer. |
447 | | When enabled, particles are sent to the renderer in order of |
448 | | furthest distance from the camera. |
449 | | */ |
450 | 0 | void setSortingEnabled(bool enabled) { mSorted = enabled; } |
451 | | /// Gets whether particles are sorted relative to the camera. |
452 | 0 | bool getSortingEnabled(void) const { return mSorted; } |
453 | | |
454 | | /** Set the (initial) bounds of the particle system manually. |
455 | | |
456 | | If you can, set the bounds of a particle system up-front and |
457 | | call setBoundsAutoUpdated(false); this is the most efficient way to |
458 | | organise it. Otherwise, set an initial bounds and let the bounds increase |
459 | | for a little while (the default is 5 seconds), after which time the |
460 | | AABB is fixed to save time. |
461 | | @param aabb Bounds in local space. |
462 | | */ |
463 | | void setBounds(const AxisAlignedBox& aabb); |
464 | | |
465 | | /** Sets whether the bounds will be automatically updated |
466 | | for the life of the particle system |
467 | | |
468 | | If you have a stationary particle system, it would be a good idea to |
469 | | call this method and set the value to 'false', since the maximum |
470 | | bounds of the particle system will eventually be static. If you do |
471 | | this, you can either set the bounds manually using the setBounds() |
472 | | method, or set the second parameter of this method to a positive |
473 | | number of seconds, so that the bounds are calculated for a few |
474 | | seconds and then frozen. |
475 | | @param autoUpdate If true (the default), the particle system will |
476 | | update it's bounds every frame. If false, the bounds update will |
477 | | cease after the 'stopIn' number of seconds have passed. |
478 | | @param stopIn Only applicable if the first parameter is true, this is the |
479 | | number of seconds after which the automatic update will cease. |
480 | | */ |
481 | | void setBoundsAutoUpdated(bool autoUpdate, Real stopIn = 0.0f); |
482 | | |
483 | | /** Sets whether particles (and any affector effects) remain relative |
484 | | to the node the particle system is attached to. |
485 | | |
486 | | By default particles are in world space once emitted, so they are not |
487 | | affected by movement in the parent node of the particle system. This |
488 | | makes the most sense when dealing with completely independent particles, |
489 | | but if you want to constrain them to follow local motion too, you |
490 | | can set this to true. |
491 | | */ |
492 | | void setKeepParticlesInLocalSpace(bool keepLocal); |
493 | | |
494 | | /** Gets whether particles (and any affector effects) remain relative |
495 | | to the node the particle system is attached to. |
496 | | */ |
497 | 0 | bool getKeepParticlesInLocalSpace(void) const { return mLocalSpace; } |
498 | | |
499 | | /** Internal method for updating the bounds of the particle system. |
500 | | |
501 | | This is called automatically for a period of time after the system's |
502 | | creation (10 seconds by default, settable by setBoundsAutoUpdated) |
503 | | to increase (and only increase) the bounds of the system according |
504 | | to the emitted and affected particles. After this period, the |
505 | | system is assumed to achieved its maximum size, and the bounds are |
506 | | no longer computed for efficiency. You can tweak the behaviour by |
507 | | either setting the bounds manually (setBounds, preferred), or |
508 | | changing the time over which the bounds are updated (performance cost). |
509 | | You can also call this method manually if you need to update the |
510 | | bounds on an ad-hoc basis. |
511 | | */ |
512 | | void _updateBounds(void); |
513 | | |
514 | | /** This is used to turn on or off particle emission for this system. |
515 | | |
516 | | By default particle system is always emitting particles (if a emitters exists) |
517 | | and this can be used to stop the emission for all emitters. To turn it on again, |
518 | | call it passing true. |
519 | | |
520 | | Note that this does not detach the particle system from the scene node, it will |
521 | | still use some CPU. |
522 | | */ |
523 | | void setEmitting(bool v); |
524 | | |
525 | | /** Returns true if the particle system emitting flag is turned on. |
526 | | |
527 | | This function will not actually return whether the particles are being emitted. |
528 | | It only returns the value of emitting flag. |
529 | | */ |
530 | | bool getEmitting() const; |
531 | | |
532 | | /// Override to return specific type flag |
533 | | uint32 getTypeFlags(void) const override; |
534 | | private: |
535 | | AxisAlignedBox mAABB; |
536 | | Real mBoundingRadius; |
537 | | bool mBoundsAutoUpdate; |
538 | | Real mBoundsUpdateTime; |
539 | | Real mUpdateRemainTime; |
540 | | |
541 | | /// Name of the resource group to use to load materials |
542 | | String mResourceGroupName; |
543 | | /// Have we set the material etc on the renderer? |
544 | | bool mIsRendererConfigured; |
545 | | /// Pointer to the material to use |
546 | | MaterialPtr mMaterial; |
547 | | /// Default width of each particle |
548 | | Real mDefaultWidth; |
549 | | /// Default height of each particle |
550 | | Real mDefaultHeight; |
551 | | /// Speed factor |
552 | | Real mSpeedFactor; |
553 | | /// Iteration interval |
554 | | Real mIterationInterval; |
555 | | /// Iteration interval set? Otherwise track default |
556 | | bool mIterationIntervalSet; |
557 | | /// Particles sorted according to camera? |
558 | | bool mSorted; |
559 | | /// Particles in local space? |
560 | | bool mLocalSpace; |
561 | | /// Update timeout when nonvisible (0 for no timeout) |
562 | | Real mNonvisibleTimeout; |
563 | | /// Update timeout when nonvisible set? Otherwise track default |
564 | | bool mNonvisibleTimeoutSet; |
565 | | /// Amount of time non-visible so far |
566 | | Real mTimeSinceLastVisible; |
567 | | /// Last frame in which known to be visible |
568 | | unsigned long mLastVisibleFrame; |
569 | | /// Controller for time update |
570 | | ControllerFloat* mTimeController; |
571 | | /// Indication whether the emitted emitter pool (= pool with particle emitters that are emitted) is initialised |
572 | | bool mEmittedEmitterPoolInitialised; |
573 | | /// Used to control if the particle system should emit particles or not. |
574 | | bool mIsEmitting; |
575 | | |
576 | | typedef std::vector<Particle*> ParticlePool; |
577 | | |
578 | | /** Sort by direction functor */ |
579 | | struct SortByDirectionFunctor |
580 | | { |
581 | | /// Direction to sort in |
582 | | Vector3 sortDir; |
583 | | |
584 | | SortByDirectionFunctor(const Vector3& dir); |
585 | | float operator()(Particle* p) const; |
586 | | }; |
587 | | |
588 | | /** Sort by distance functor */ |
589 | | struct SortByDistanceFunctor |
590 | | { |
591 | | /// Position to sort in |
592 | | Vector3 sortPos; |
593 | | |
594 | | SortByDistanceFunctor(const Vector3& pos); |
595 | | float operator()(Particle* p) const; |
596 | | }; |
597 | | |
598 | | /** Active particle list. |
599 | | |
600 | | This is a linked list of pointers to particles in the particle pool. |
601 | | @par |
602 | | This allows very fast insertions and deletions from anywhere in |
603 | | the list to activate / deactivate particles as well as reuse of |
604 | | Particle instances in the pool without construction & destruction |
605 | | which avoids memory thrashing. |
606 | | */ |
607 | | ParticlePool mActiveParticles; |
608 | | |
609 | | /** Free particle queue. |
610 | | |
611 | | This contains a list of the particles free for use as new instances |
612 | | as required by the set. Particle instances are preconstructed up |
613 | | to the estimated size in the mParticlePool vector and are |
614 | | referenced on this deque at startup. As they get used this list |
615 | | reduces, as they get released back to to the set they get added |
616 | | back to the list. |
617 | | */ |
618 | | ParticlePool mFreeParticles; |
619 | | |
620 | | /** Pool of particle instances for use and reuse in the active particle list. |
621 | | |
622 | | This vector will be preallocated with the estimated size of the set,and will extend as required. |
623 | | */ |
624 | | ParticlePool mParticlePool; |
625 | | |
626 | | typedef std::list<ParticleEmitter*> FreeEmittedEmitterList; |
627 | | typedef std::list<ParticleEmitter*> ActiveEmittedEmitterList; |
628 | | typedef std::vector<ParticleEmitter*> EmittedEmitterList; |
629 | | typedef std::map<String, FreeEmittedEmitterList> FreeEmittedEmitterMap; |
630 | | typedef std::map<String, EmittedEmitterList> EmittedEmitterPool; |
631 | | |
632 | | /** Pool of emitted emitters for use and reuse in the active emitted emitter list. |
633 | | |
634 | | The emitters in this pool act as particles and as emitters. The pool is a map containing lists |
635 | | of emitters, identified by their name. |
636 | | @par |
637 | | The emitters in this pool are cloned using emitters that are kept in the main emitter list |
638 | | of the ParticleSystem. |
639 | | */ |
640 | | EmittedEmitterPool mEmittedEmitterPool; |
641 | | |
642 | | /** Free emitted emitter list. |
643 | | |
644 | | This contains a list of the emitters free for use as new instances as required by the set. |
645 | | */ |
646 | | FreeEmittedEmitterMap mFreeEmittedEmitters; |
647 | | |
648 | | /** Active emitted emitter list. |
649 | | |
650 | | This is a linked list of pointers to emitters in the emitted emitter pool. |
651 | | Emitters that are used are stored (their pointers) in both the list with active particles and in |
652 | | the list with active emitted emitters. */ |
653 | | ActiveEmittedEmitterList mActiveEmittedEmitters; |
654 | | |
655 | | typedef std::vector<ParticleEmitter*> ParticleEmitterList; |
656 | | typedef std::vector<ParticleAffector*> ParticleAffectorList; |
657 | | |
658 | | /// List of particle emitters, ie sources of particles |
659 | | ParticleEmitterList mEmitters; |
660 | | /// List of particle affectors, ie modifiers of particles |
661 | | ParticleAffectorList mAffectors; |
662 | | |
663 | | /// The renderer used to render this particle system |
664 | | ParticleSystemRenderer* mRenderer; |
665 | | |
666 | | /// Do we cull each particle individually? |
667 | | bool mCullIndividual; |
668 | | |
669 | | /// The name of the type of renderer used to render this system |
670 | | String mRendererType; |
671 | | |
672 | | /// The number of particles in the pool. |
673 | | size_t mPoolSize; |
674 | | |
675 | | /// The number of emitted emitters in the pool. |
676 | | size_t mEmittedEmitterPoolSize; |
677 | | |
678 | | /// Optional origin of this particle system (eg script name) |
679 | | String mOrigin; |
680 | | |
681 | | /// Default iteration interval |
682 | | static Real msDefaultIterationInterval; |
683 | | /// Default nonvisible update timeout |
684 | | static Real msDefaultNonvisibleTimeout; |
685 | | |
686 | | /** Internal method used to expire dead particles. */ |
687 | | void _expire(Real timeElapsed); |
688 | | |
689 | | /** Spawn new particles based on free quota and emitter requirements. */ |
690 | | void _triggerEmitters(Real timeElapsed); |
691 | | |
692 | | /** Helper function that actually performs the emission of particles |
693 | | */ |
694 | | void _executeTriggerEmitters(ParticleEmitter* emitter, unsigned requested, Real timeElapsed); |
695 | | |
696 | | /** Updates existing particle based on their momentum. */ |
697 | | void _applyMotion(Real timeElapsed); |
698 | | |
699 | | /** Applies the effects of affectors. */ |
700 | | void _triggerAffectors(Real timeElapsed); |
701 | | |
702 | | /** Sort the particles in the system **/ |
703 | | void _sortParticles(Camera* cam); |
704 | | |
705 | | /** Resize the internal pool of particles. */ |
706 | | void increasePool(size_t size); |
707 | | |
708 | | /** Resize the internal pool of emitted emitters. |
709 | | |
710 | | The pool consists of multiple vectors containing pointers to particle emitters. Increasing the |
711 | | pool with size implies that the vectors are equally increased. The quota of emitted emitters is |
712 | | defined on a particle system level and not on a particle emitter level. This is to prevent that |
713 | | the number of created emitters becomes too high; the quota is shared amongst the emitted emitters. |
714 | | */ |
715 | | void increaseEmittedEmitterPool(size_t size); |
716 | | |
717 | | /** Internal method for initialising string interface. */ |
718 | | void initParameters(void); |
719 | | |
720 | | /** Internal method to configure the renderer. */ |
721 | | void configureRenderer(void); |
722 | | |
723 | | /** Create a pool of emitted emitters and assign them to the free emitter list. |
724 | | |
725 | | The emitters in the pool are grouped by name. This name is the name of the base emitter in the |
726 | | main list with particle emitters, which forms the template of the created emitted emitters. |
727 | | */ |
728 | | void initialiseEmittedEmitters(void); |
729 | | |
730 | | /** Determine which emitters in the Particle Systems main emitter become a template for creating an |
731 | | pool of emitters that can be emitted. |
732 | | */ |
733 | | void initialiseEmittedEmitterPool(void); |
734 | | |
735 | | /** Add emitters from the pool to the free emitted emitter queue. */ |
736 | | void addFreeEmittedEmitters(void); |
737 | | |
738 | | /** Removes all emitted emitters from this system. */ |
739 | | void removeAllEmittedEmitters(void); |
740 | | |
741 | | /** Find the list with free emitted emitters. |
742 | | @param name The name that identifies the list with free emitted emitters. |
743 | | */ |
744 | | FreeEmittedEmitterList* findFreeEmittedEmitter (const String& name); |
745 | | |
746 | | /** Removes an emitter from the active emitted emitter list. |
747 | | |
748 | | The emitter will not be destroyed! |
749 | | @param emitter Pointer to a particle emitter. |
750 | | */ |
751 | | void removeFromActiveEmittedEmitters (ParticleEmitter* emitter); |
752 | | |
753 | | /** Moves all emitted emitters from the active list to the free list |
754 | | |
755 | | The active emitted emitter list will not be cleared and still keeps references to the emitters! |
756 | | */ |
757 | | void addActiveEmittedEmittersToFreeList (void); |
758 | | |
759 | | /** This function clears all data structures that are used in combination with emitted emitters and |
760 | | sets the flag to indicate that the emitted emitter pool must be initialised again. |
761 | | |
762 | | This function should be called if new emitters are added to a ParticleSystem or deleted from a |
763 | | ParticleSystem. The emitted emitter data structures become out of sync and need to be build up |
764 | | again. The data structures are not reorganised in this function, but by setting a flag, |
765 | | they are rebuild in the regular process flow. |
766 | | */ |
767 | | void _notifyReorganiseEmittedEmitterData (void); |
768 | | }; |
769 | | /** @} */ |
770 | | /** @} */ |
771 | | |
772 | | } |
773 | | |
774 | | #include "OgreHeaderSuffix.h" |
775 | | |
776 | | #endif |