Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/include/OgreParticleSystem.h @ 3

Last change on this file since 3 was 3, checked in by anonymous, 17 years ago

=update

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