source: OGRE/trunk/ogre_changes/Ogre1.2/OgreMain/include/OgreParticleSystemManager.h @ 2343

Revision 2343, 18.9 KB checked in by szirmay, 17 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#ifdef GAMETOOLS_ILLUMINATION_MODULE
190                /** Removes a specified template from the ParticleSystemManager.
191        @remarks
192            This method removes a given template from the particle system manager, optionally deleting
193            the template if the deleteTemplate method is called.  Throws an exception if the template
194            could not be found.
195        @param
196            name The name of the template to remove.
197        @param
198            deleteTemplate Whether or not to delete the template before removing it.
199        */
200        void removeTemplate(const String& name, bool deleteTemplate = true);
201
202        /** Removes a specified template from the ParticleSystemManager.
203        @remarks
204            This method removes all templates from the ParticleSystemManager.
205        @param
206            deleteTemplate Whether or not to delete the templates before removing them.
207        */
208        void removeAllTemplates(bool deleteTemplate = true);
209#endif
210
211        /** Create a new particle system template.
212        @remarks
213            This method is similar to the addTemplate method, except this just creates a new template
214            and returns a pointer to it to be populated. Use this when you don't already have a system
215            to add as a template and just want to create a new template which you will build up in-place.
216        @param
217            name The name of the template. Must be unique across all templates.
218        @param
219            resourceGroup The name of the resource group which will be used to
220                load any dependent resources.
221           
222        */
223        ParticleSystem* createTemplate(const String& name, const String& resourceGroup);
224
225        /** Retrieves a particle system template for possible modification.
226        @remarks
227            Modifying a template does not affect the settings on any ParticleSystems already created
228            from this template.
229        */
230        ParticleSystem* getTemplate(const String& name);
231
232        /** Internal method for creating a new emitter from a factory.
233        @remarks
234            Used internally by the engine to create new ParticleEmitter instances from named
235            factories. Applications should use the ParticleSystem::addEmitter method instead,
236            which calls this method to create an instance.
237        @param
238            emitterType String name of the emitter type to be created. A factory of this type must have been registered.
239        @param
240            psys The particle system this is being created for
241        */
242        ParticleEmitter* _createEmitter(const String& emitterType, ParticleSystem* psys);
243
244        /** Internal method for destroying an emitter.
245        @remarks
246            Because emitters 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            emitter Pointer to emitter to be destroyed. On return this pointer will point to invalid (freed) memory.
251        */
252        void _destroyEmitter(ParticleEmitter* emitter);
253
254        /** Internal method for creating a new affector from a factory.
255        @remarks
256            Used internally by the engine to create new ParticleAffector instances from named
257            factories. Applications should use the ParticleSystem::addAffector method instead,
258            which calls this method to create an instance.
259        @param
260            effectorType String name of the affector type to be created. A factory of this type must have been registered.
261        @param
262            psys The particle system it is being created for
263        */
264        ParticleAffector* _createAffector(const String& affectorType, ParticleSystem* psys);
265
266        /** Internal method for destroying an affector.
267        @remarks
268            Because affectors are created by factories which may allocate memory from separate heaps,
269            the memory allocated must be freed from the same place. This method is used to ask the factory
270            to destroy the instance passed in as a pointer.
271        @param
272            affector Pointer to affector to be destroyed. On return this pointer will point to invalid (freed) memory.
273        */
274        void _destroyAffector(ParticleAffector* affector);
275
276        /** Internal method for creating a new renderer from a factory.
277        @remarks
278            Used internally by the engine to create new ParticleSystemRenderer instances from named
279            factories. Applications should use the ParticleSystem::setRenderer method instead,
280            which calls this method to create an instance.
281        @param
282            rendererType String name of the renderer type to be created. A factory of this type must have been registered.
283        */
284        ParticleSystemRenderer* _createRenderer(const String& rendererType);
285
286        /** Internal method for destroying a renderer.
287        @remarks
288            Because renderer are created by factories which may allocate memory from separate heaps,
289            the memory allocated must be freed from the same place. This method is used to ask the factory
290            to destroy the instance passed in as a pointer.
291        @param
292            renderer Pointer to renderer to be destroyed. On return this pointer will point to invalid (freed) memory.
293        */
294        void _destroyRenderer(ParticleSystemRenderer* renderer);
295
296        /** Frame event */
297        bool frameStarted(const FrameEvent &evt);
298
299        /** Frame event */
300        bool frameEnded(const FrameEvent &evt);
301
302        /** Init method to be called by OGRE system.
303        @remarks
304            Due to dependencies between various objects certain initialisation tasks cannot be done
305            on construction. OGRE will call this method when the rendering subsystem is initialised.
306        */
307        void _initialise(void);
308
309        /// @copydoc ScriptLoader::getScriptPatterns
310        const StringVector& getScriptPatterns(void) const;
311        /// @copydoc ScriptLoader::parseScript
312        void parseScript(DataStreamPtr& stream, const String& groupName);
313        /// @copydoc ScriptLoader::getLoadingOrder
314        Real getLoadingOrder(void) const;
315
316                typedef MapIterator<ParticleAffectorFactoryMap> ParticleAffectorFactoryIterator;
317                typedef MapIterator<ParticleEmitterFactoryMap> ParticleEmitterFactoryIterator;
318                typedef MapIterator<ParticleSystemRendererFactoryMap> ParticleRendererFactoryIterator;
319                /** Return an iterator over the affector factories currently registered */
320                ParticleAffectorFactoryIterator getAffectorFactoryIterator(void);
321                /** Return an iterator over the emitter factories currently registered */
322                ParticleEmitterFactoryIterator getEmitterFactoryIterator(void);
323                /** Return an iterator over the renderer factories currently registered */
324                ParticleRendererFactoryIterator getRendererFactoryIterator(void);
325
326
327        typedef MapIterator<ParticleTemplateMap> ParticleSystemTemplateIterator;
328        /** Gets an iterator over the list of particle system templates. */
329        ParticleSystemTemplateIterator getTemplateIterator(void)
330        {
331            return ParticleSystemTemplateIterator(
332                mSystemTemplates.begin(), mSystemTemplates.end());
333        }
334
335        /** Get an instance of ParticleSystemFactory (internal use). */
336                ParticleSystemFactory* _getFactory(void) { return mFactory; }
337               
338                /** Override standard Singleton retrieval.
339        @remarks
340        Why do we do this? Well, it's because the Singleton
341        implementation is in a .h file, which means it gets compiled
342        into anybody who includes it. This is needed for the
343        Singleton template to work, but we actually only want it
344        compiled into the implementation of the class based on the
345        Singleton, not all of them. If we don't change this, we get
346        link errors when trying to use the Singleton-based class from
347        an outside dll.
348        @par
349        This method just delegates to the template version anyway,
350        but the implementation stays in this single compilation unit,
351        preventing link errors.
352        */
353        static ParticleSystemManager& getSingleton(void);
354        /** Override standard Singleton retrieval.
355        @remarks
356        Why do we do this? Well, it's because the Singleton
357        implementation is in a .h file, which means it gets compiled
358        into anybody who includes it. This is needed for the
359        Singleton template to work, but we actually only want it
360        compiled into the implementation of the class based on the
361        Singleton, not all of them. If we don't change this, we get
362        link errors when trying to use the Singleton-based class from
363        an outside dll.
364        @par
365        This method just delegates to the template version anyway,
366        but the implementation stays in this single compilation unit,
367        preventing link errors.
368        */
369        static ParticleSystemManager* getSingletonPtr(void);
370
371    };
372
373        /** Factory object for creating ParticleSystem instances */
374        class _OgreExport ParticleSystemFactory : public MovableObjectFactory
375        {
376        protected:
377                MovableObject* createInstanceImpl(const String& name, const NameValuePairList* params);
378        public:
379                ParticleSystemFactory() {}
380                ~ParticleSystemFactory() {}
381               
382                static String FACTORY_TYPE_NAME;
383
384                const String& getType(void) const;
385                void destroyInstance( MovableObject* obj); 
386
387        };
388       
389}
390
391#endif
392
Note: See TracBrowser for help on using the repository browser.