source: GTP/trunk/App/Demos/Geom/OgreStuff/include/OgreParticleSystem.h @ 1812

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