Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre_src_v1-9-0/OgreMain/include/OgreParticleSystem.h @ 151

Last change on this file since 151 was 148, checked in by patricwi, 6 years ago

Added new dependencies for ogre1.9 and cegui0.8

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