source: OGRE/trunk/ogrenew/OgreMain/include/OgreParticleSystemManager.h @ 657

Revision 657, 21.4 KB checked in by mattausch, 19 years ago (diff)

added ogre dependencies and patched ogre sources

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4        (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#ifndef __ParticleSystemManager_H__
26#define __ParticleSystemManager_H__
27
28
29#include "OgrePrerequisites.h"
30#include "OgreParticleSystem.h"
31#include "OgreFrameListener.h"
32#include "OgreSingleton.h"
33#include "OgreIteratorWrappers.h"
34#include "OgreScriptLoader.h"
35#include "OgreResourceGroupManager.h"
36
37namespace Ogre {
38
39    /** Manages particle systems, particle system scripts (templates) and the available emitter & affector factories.
40    @remarks
41        This singleton class is responsible for creating and managing particle systems. All particle
42        systems must be created and destroyed using this object. Remember that like all other MovableObject
43        subclasses, ParticleSystems do not get rendered until they are attached to a SceneNode object.
44    @par
45        This class also manages factories for ParticleEmitter and ParticleAffector classes. To enable easy
46        extensions to the types of emitters (particle sources) and affectors (particle modifiers), the
47        ParticleSystemManager lets plugins or applications register factory classes which submit new
48        subclasses to ParticleEmitter and ParticleAffector. Ogre comes with a number of them already provided,
49        such as cone, sphere and box-shaped emitters, and simple affectors such as constant directional force
50        and colour faders. However using this registration process, a plugin can create any behaviour
51        required.
52    @par
53        This class also manages the loading and parsing of particle system scripts, which are text files
54        describing named particle system templates. Instances of particle systems using these templates can
55        then be created easily through the createParticleSystem method.
56    */
57    class _OgreExport ParticleSystemManager: public Singleton<ParticleSystemManager>,
58        public FrameListener, public ScriptLoader
59    {
60        public:
61        typedef std::map<String, ParticleSystem*> ParticleTemplateMap;
62                typedef std::map<String, ParticleAffectorFactory*> ParticleAffectorFactoryMap;
63                typedef std::map<String, ParticleEmitterFactory*> ParticleEmitterFactoryMap;
64                typedef std::map<String, ParticleSystemRendererFactory*> ParticleSystemRendererFactoryMap;
65    protected:
66        /// Templates based on scripts
67        ParticleTemplateMap mSystemTemplates;
68       
69        typedef std::map<String, ParticleSystem*> ParticleSystemMap;
70        /// Actual instantiated particle systems (may be based on template, may be manual)
71        ParticleSystemMap mSystems;
72
73        /// Factories for named emitter types (can be extended using plugins)
74        ParticleEmitterFactoryMap mEmitterFactories;
75
76        /// Factories for named affector types (can be extended using plugins)
77        ParticleAffectorFactoryMap mAffectorFactories;
78
79                /// Map of renderer types to factories
80                ParticleSystemRendererFactoryMap mRendererFactories;
81
82        StringVector mScriptPatterns;
83
84                /// Controls time
85                Real mTimeFactor;
86
87        /** Internal script parsing method. */
88        void parseNewEmitter(const String& type, DataStreamPtr& chunk, ParticleSystem* sys);
89        /** Internal script parsing method. */
90        void parseNewAffector(const String& type, DataStreamPtr& chunk, ParticleSystem* sys);
91        /** Internal script parsing method. */
92        void parseAttrib(const String& line, ParticleSystem* sys);
93        /** Internal script parsing method. */
94        void parseEmitterAttrib(const String& line, ParticleEmitter* sys);
95        /** Internal script parsing method. */
96        void parseAffectorAttrib(const String& line, ParticleAffector* sys);
97        /** Internal script parsing method. */
98        void skipToNextCloseBrace(DataStreamPtr& chunk);
99        /** Internal script parsing method. */
100        void skipToNextOpenBrace(DataStreamPtr& chunk);
101    public:
102
103        ParticleSystemManager();
104        virtual ~ParticleSystemManager();
105
106        /** Adds a new 'factory' object for emitters to the list of available emitter types.
107        @remarks
108            This method allows plugins etc to add new particle emitter types to Ogre. Particle emitters
109            are sources of particles, and generate new particles with their start positions, colours and
110            momentums appropriately. Plugins would create new subclasses of ParticleEmitter which
111            emit particles a certain way, and register a subclass of ParticleEmitterFactory to create them (since multiple
112            emitters can be created for different particle systems).
113        @par
114            All particle emitter factories have an assigned name which is used to identify the emitter
115            type. This must be unique.
116        @par
117            Note that the object passed to this function will not be destroyed by the ParticleSystemManager,
118            since it may have been allocted on a different heap in the case of plugins. The caller must
119            destroy the object later on, probably on plugin shutdown.
120        @param
121            factory Pointer to a ParticleEmitterFactory subclass created by the plugin or application code.
122        */
123        void addEmitterFactory(ParticleEmitterFactory* factory);
124
125        /** Adds a new 'factory' object for affectors to the list of available affector types.
126        @remarks
127            This method allows plugins etc to add new particle affector types to Ogre. Particle
128            affectors modify the particles in a system a certain way such as affecting their direction
129            or changing their colour, lifespan etc. Plugins would
130            create new subclasses of ParticleAffector which affect particles a certain way, and register
131            a subclass of ParticleAffectorFactory to create them.
132        @par
133            All particle affector factories have an assigned name which is used to identify the affector
134            type. This must be unique.
135        @par
136            Note that the object passed to this function will not be destroyed by the ParticleSystemManager,
137            since it may have been allocted on a different heap in the case of plugins. The caller must
138            destroy the object later on, probably on plugin shutdown.
139        @param
140            factory Pointer to a ParticleAffectorFactory subclass created by the plugin or application code.
141        */
142        void addAffectorFactory(ParticleAffectorFactory* factory);
143
144                /** Registers a factory class for creating ParticleSystemRenderer instances.
145        @par
146            Note that the object passed to this function will not be destroyed by the ParticleSystemManager,
147            since it may have been allocted on a different heap in the case of plugins. The caller must
148            destroy the object later on, probably on plugin shutdown.
149        @param
150            factory Pointer to a ParticleSystemRendererFactory subclass created by the plugin or application code.
151                */
152                void addRendererFactory(ParticleSystemRendererFactory* factory);
153
154        /** Adds a new particle system template to the list of available templates.
155        @remarks
156            Instances of particle systems in a scene are not normally unique - often you want to place the
157            same effect in many places. This method allows you to register a ParticleSystem as a named template,
158            which can subsequently be used to create instances using the createSystem method.
159        @par
160            Note that particle system templates can either be created programmatically by an application
161            and registered using this method, or they can be defined in a script file (*.particle) which is
162            loaded by the engine at startup, very much like Material scripts.
163        @param
164            name The name of the template. Must be unique across all templates.
165        @param
166            sysTemplate A pointer to a particle system to be used as a template. The manager
167                will take over ownership of this pointer.
168           
169        */
170        void addTemplate(const String& name, ParticleSystem* sysTemplate);
171
172        /** Create a new particle system template.
173        @remarks
174            This method is similar to the addTemplate method, except this just creates a new template
175            and returns a pointer to it to be populated. Use this when you don't already have a system
176            to add as a template and just want to create a new template which you will build up in-place.
177        @param
178            name The name of the template. Must be unique across all templates.
179        @param
180            resourceGroup The name of the resource group which will be used to
181                load any dependent resources.
182           
183        */
184        ParticleSystem* createTemplate(const String& name, const String& resourceGroup);
185
186        /** Retrieves a particle system template for possible modification.
187        @remarks
188            Modifying a template does not affect the settings on any ParticleSystems already created
189            from this template.
190        */
191        ParticleSystem* getTemplate(const String& name);
192
193        /** Basic method for creating a blank particle system.
194        @remarks
195            This method creates a new, blank ParticleSystem instance and returns a pointer to it.
196            The caller should not delete this object, it will be freed at system shutdown, or can
197            be released earlier using the destroySystem method.
198        @par
199            The instance returned from this method won't actually do anything because on creation a
200            particle system has no emitters. The caller should manipulate the instance through it's
201            ParticleSystem methods to actually create a real particle effect.
202        @par
203            Creating a particle system does not make it a part of the scene. As with other MovableObject
204            subclasses, a ParticleSystem is not rendered until it is attached to a SceneNode.
205        @param
206            name The name to give the ParticleSystem.
207        @param
208            quota The maximum number of particles to allow in this system.
209        @param
210            resourceGroup The resource group which will be used to load dependent resources
211        */
212        ParticleSystem* createSystem(const String& name, size_t quota = 500,
213            const String& resourceGroup = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
214
215        /** Creates a particle system based on a template.
216        @remarks
217            This method creates a new ParticleSystem instance based on the named template and returns a
218            pointer to the caller. The caller should not delete this object, it will be freed at system shutdown,
219            or can be released earlier using the destroySystem method.
220        @par
221            Each system created from a template takes the template's settings at the time of creation,
222            but is completely separate from the template from there on.
223        @par
224            Creating a particle system does not make it a part of the scene. As with other MovableObject
225            subclasses, a ParticleSystem is not rendered until it is attached to a SceneNode.
226        @par
227            This is probably the more useful particle system creation method since it does not require manual
228            setup of the system. Note that the initial quota is based on the template but may be changed later.
229        @param
230            name The name to give the new particle system instance.
231        @param
232            templateName The name of the template to base the new instance on.
233        */
234        ParticleSystem* createSystem(const String& name, const String& templateName);
235
236        /** Destroys a particle system, freeing it's memory and removing references to it in this class.
237        @remarks
238            You should ensure that before calling this method, the particle system has been detached from
239            any SceneNode objects, and that no other objects are referencing it.
240        @param
241            name The name of the ParticleSystem to destroy.
242        */
243        void destroySystem(const String& name);
244
245        /** Destroys a particle system, freeing it's memory and removing references to it in this class.
246        @remarks
247            You should ensure that before calling this method, the particle system has been detached from
248            any SceneNode objects, and that no other objects are referencing it.
249        @param
250            sys Pointer to the ParticleSystem to be destroyed.
251        */
252        void destroySystem(ParticleSystem* sys);
253
254        /** Retrieves a pointer to a system already created. */
255        ParticleSystem* getSystem(const String& name);
256
257
258        /** Internal method for creating a new emitter from a factory.
259        @remarks
260            Used internally by the engine to create new ParticleEmitter instances from named
261            factories. Applications should use the ParticleSystem::addEmitter method instead,
262            which calls this method to create an instance.
263        @param
264            emitterType String name of the emitter type to be created. A factory of this type must have been registered.
265        @param
266            psys The particle system this is being created for
267        */
268        ParticleEmitter* _createEmitter(const String& emitterType, ParticleSystem* psys);
269
270        /** Internal method for destroying an emitter.
271        @remarks
272            Because emitters are created by factories which may allocate memory from separate heaps,
273            the memory allocated must be freed from the same place. This method is used to ask the factory
274            to destroy the instance passed in as a pointer.
275        @param
276            emitter Pointer to emitter to be destroyed. On return this pointer will point to invalid (freed) memory.
277        */
278        void _destroyEmitter(ParticleEmitter* emitter);
279
280        /** Internal method for creating a new affector from a factory.
281        @remarks
282            Used internally by the engine to create new ParticleAffector instances from named
283            factories. Applications should use the ParticleSystem::addAffector method instead,
284            which calls this method to create an instance.
285        @param
286            effectorType String name of the affector type to be created. A factory of this type must have been registered.
287        @param
288            psys The particle system it is being created for
289        */
290        ParticleAffector* _createAffector(const String& affectorType, ParticleSystem* psys);
291
292        /** Internal method for destroying an affector.
293        @remarks
294            Because affectors are created by factories which may allocate memory from separate heaps,
295            the memory allocated must be freed from the same place. This method is used to ask the factory
296            to destroy the instance passed in as a pointer.
297        @param
298            affector Pointer to affector to be destroyed. On return this pointer will point to invalid (freed) memory.
299        */
300        void _destroyAffector(ParticleAffector* affector);
301
302        /** Internal method for creating a new renderer from a factory.
303        @remarks
304            Used internally by the engine to create new ParticleSystemRenderer instances from named
305            factories. Applications should use the ParticleSystem::setRenderer method instead,
306            which calls this method to create an instance.
307        @param
308            rendererType String name of the renderer type to be created. A factory of this type must have been registered.
309        */
310        ParticleSystemRenderer* _createRenderer(const String& rendererType);
311
312        /** Internal method for destroying a renderer.
313        @remarks
314            Because renderer are created by factories which may allocate memory from separate heaps,
315            the memory allocated must be freed from the same place. This method is used to ask the factory
316            to destroy the instance passed in as a pointer.
317        @param
318            renderer Pointer to renderer to be destroyed. On return this pointer will point to invalid (freed) memory.
319        */
320        void _destroyRenderer(ParticleSystemRenderer* renderer);
321
322        /** Frame event */
323        bool frameStarted(const FrameEvent &evt);
324
325        /** Frame event */
326        bool frameEnded(const FrameEvent &evt);
327
328        /** Init method to be called by OGRE system.
329        @remarks
330            Due to dependencies between various objects certain initialisation tasks cannot be done
331            on construction. OGRE will call this method when the rendering subsystem is initialised.
332        */
333        void _initialise(void);
334
335        /// @copydoc ScriptLoader::getScriptPatterns
336        const StringVector& getScriptPatterns(void) const;
337        /// @copydoc ScriptLoader::parseScript
338        void parseScript(DataStreamPtr& stream, const String& groupName);
339        /// @copydoc ScriptLoader::getLoadingOrder
340        Real getLoadingOrder(void) const;
341
342                typedef MapIterator<ParticleAffectorFactoryMap> ParticleAffectorFactoryIterator;
343                typedef MapIterator<ParticleEmitterFactoryMap> ParticleEmitterFactoryIterator;
344                typedef MapIterator<ParticleSystemRendererFactoryMap> ParticleRendererFactoryIterator;
345                /** Return an iterator over the affector factories currently registered */
346                ParticleAffectorFactoryIterator getAffectorFactoryIterator(void);
347                /** Return an iterator over the emitter factories currently registered */
348                ParticleEmitterFactoryIterator getEmitterFactoryIterator(void);
349                /** Return an iterator over the renderer factories currently registered */
350                ParticleRendererFactoryIterator getRendererFactoryIterator(void);
351
352
353                /** Return relative speed of time as perceived by particle systems.
354        @remarks
355            See setTimeFactor for full information on the meaning of this value.
356                */
357                Real getTimeFactor(void) const;
358
359                /** Set the relative speed of time as perceived by particle systems.
360        @remarks
361            Normally particle systems are updated automatically in line with the real
362            passage of time. This method allows you to change that, so that
363            particle systems are told that the time is passing slower or faster than it
364            actually is. Use this to globally speed up / slow down particle systems.
365        @param tf The virtual speed of time (1.0 is real time).
366                */
367                void setTimeFactor(Real tf);
368
369        typedef MapIterator<ParticleTemplateMap> ParticleSystemTemplateIterator;
370        /** Gets an iterator over the list of particle system templates. */
371        ParticleSystemTemplateIterator getTemplateIterator(void)
372        {
373            return ParticleSystemTemplateIterator(
374                mSystemTemplates.begin(), mSystemTemplates.end());
375        }
376
377        /** Override standard Singleton retrieval.
378        @remarks
379        Why do we do this? Well, it's because the Singleton
380        implementation is in a .h file, which means it gets compiled
381        into anybody who includes it. This is needed for the
382        Singleton template to work, but we actually only want it
383        compiled into the implementation of the class based on the
384        Singleton, not all of them. If we don't change this, we get
385        link errors when trying to use the Singleton-based class from
386        an outside dll.
387        @par
388        This method just delegates to the template version anyway,
389        but the implementation stays in this single compilation unit,
390        preventing link errors.
391        */
392        static ParticleSystemManager& getSingleton(void);
393        /** Override standard Singleton retrieval.
394        @remarks
395        Why do we do this? Well, it's because the Singleton
396        implementation is in a .h file, which means it gets compiled
397        into anybody who includes it. This is needed for the
398        Singleton template to work, but we actually only want it
399        compiled into the implementation of the class based on the
400        Singleton, not all of them. If we don't change this, we get
401        link errors when trying to use the Singleton-based class from
402        an outside dll.
403        @par
404        This method just delegates to the template version anyway,
405        but the implementation stays in this single compilation unit,
406        preventing link errors.
407        */
408        static ParticleSystemManager* getSingletonPtr(void);
409
410    };
411
412}
413
414#endif
415
Note: See TracBrowser for help on using the repository browser.