Coverage Report

Created: 2025-08-29 06:18

/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