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

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