Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

=update

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