source: OGRE/trunk/ogrenew/OgreMain/src/OgreParticleSystemManager.cpp @ 692

Revision 692, 21.8 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

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#include "OgreStableHeaders.h"
26
27#include "OgreParticleSystemManager.h"
28#include "OgreParticleEmitterFactory.h"
29#include "OgreParticleAffectorFactory.h"
30#include "OgreException.h"
31#include "OgreRoot.h"
32#include "OgreLogManager.h"
33#include "OgreString.h"
34#include "OgreParticleSystemRenderer.h"
35#include "OgreBillboardParticleRenderer.h"
36#include "OgreStringConverter.h"
37
38namespace Ogre {
39    //-----------------------------------------------------------------------
40    // Shortcut to set up billboard particle renderer
41    BillboardParticleRendererFactory* mBillboardRendererFactory = 0;
42    //-----------------------------------------------------------------------
43    template<> ParticleSystemManager* Singleton<ParticleSystemManager>::ms_Singleton = 0;
44    ParticleSystemManager* ParticleSystemManager::getSingletonPtr(void)
45    {
46        return ms_Singleton;
47    }
48    ParticleSystemManager& ParticleSystemManager::getSingleton(void)
49    { 
50        assert( ms_Singleton );  return ( *ms_Singleton ); 
51    }
52    //-----------------------------------------------------------------------
53    ParticleSystemManager::ParticleSystemManager()
54    {
55        mScriptPatterns.push_back("*.particle");
56        ResourceGroupManager::getSingleton()._registerScriptLoader(this);
57                mFactory = new ParticleSystemFactory();
58                Root::getSingleton().addMovableObjectFactory(mFactory);
59    }
60    //-----------------------------------------------------------------------
61    ParticleSystemManager::~ParticleSystemManager()
62    {
63        // Destroy all templates
64        ParticleTemplateMap::iterator t;
65        for (t = mSystemTemplates.begin(); t != mSystemTemplates.end(); ++t)
66        {
67            delete t->second;
68        }
69        mSystemTemplates.clear();
70        ResourceGroupManager::getSingleton()._unregisterScriptLoader(this);
71        // delete billboard factory
72        if (mBillboardRendererFactory)
73                {
74            delete mBillboardRendererFactory;
75                        mBillboardRendererFactory = 0;
76                }
77
78                if (mFactory)
79                {
80                        // delete particle system factory
81                        Root::getSingleton().removeMovableObjectFactory(mFactory);
82                        delete mFactory;
83                        mFactory = 0;
84                }
85
86    }
87    //-----------------------------------------------------------------------
88    const StringVector& ParticleSystemManager::getScriptPatterns(void) const
89    {
90        return mScriptPatterns;
91    }
92    //-----------------------------------------------------------------------
93    Real ParticleSystemManager::getLoadingOrder(void) const
94    {
95        /// Load late
96        return 1000.0f;
97    }
98    //-----------------------------------------------------------------------
99    void ParticleSystemManager::parseScript(DataStreamPtr& stream, const String& groupName)
100    {
101        String line;
102        ParticleSystem* pSys;
103        std::vector<String> vecparams;
104
105        pSys = 0;
106
107        while(!stream->eof())
108        {
109            line = stream->getLine();
110            // Ignore comments & blanks
111            if (!(line.length() == 0 || line.substr(0,2) == "//"))
112            {
113                if (pSys == 0)
114                {
115                    // No current system
116                    // So first valid data should be a system name
117                    pSys = createTemplate(line, groupName);
118                                        pSys->_notifyOrigin(stream->getName());
119                    // Skip to and over next {
120                    skipToNextOpenBrace(stream);
121                }
122                else
123                {
124                    // Already in a system
125                    if (line == "}")
126                    {
127                        // Finished system
128                        pSys = 0;
129                    }
130                    else if (line.substr(0,7) == "emitter")
131                    {
132                        // new emitter
133                        // Get typename
134                        vecparams = StringUtil::split(line, "\t ");
135                        if (vecparams.size() < 2)
136                        {
137                            // Oops, bad emitter
138                            LogManager::getSingleton().logMessage("Bad particle system emitter line: '"
139                                + line + "' in " + pSys->getName());
140                            skipToNextCloseBrace(stream);
141
142                        }
143                        skipToNextOpenBrace(stream);
144                        parseNewEmitter(vecparams[1], stream, pSys);
145
146                    }
147                    else if (line.substr(0,8) == "affector")
148                    {
149                        // new affector
150                        // Get typename
151                        vecparams = StringUtil::split(line, "\t ");
152                        if (vecparams.size() < 2)
153                        {
154                            // Oops, bad emitter
155                            LogManager::getSingleton().logMessage("Bad particle system affector line: '"
156                                + line + "' in " + pSys->getName());
157                            skipToNextCloseBrace(stream);
158
159                        }
160                        skipToNextOpenBrace(stream);
161                        parseNewAffector(vecparams[1],stream, pSys);
162                    }
163                    else
164                    {
165                        // Attribute
166                        parseAttrib(line, pSys);
167                    }
168
169                }
170
171            }
172
173
174        }
175
176
177    }
178    //-----------------------------------------------------------------------
179    void ParticleSystemManager::addEmitterFactory(ParticleEmitterFactory* factory)
180    {
181        String name = factory->getName();
182        mEmitterFactories[name] = factory;
183        LogManager::getSingleton().logMessage("Particle Emitter Type '" + name + "' registered");
184    }
185    //-----------------------------------------------------------------------
186    void ParticleSystemManager::addAffectorFactory(ParticleAffectorFactory* factory)
187    {
188        String name = factory->getName();
189        mAffectorFactories[name] = factory;
190        LogManager::getSingleton().logMessage("Particle Affector Type '" + name + "' registered");
191    }
192        //-----------------------------------------------------------------------
193        void ParticleSystemManager::addRendererFactory(ParticleSystemRendererFactory* factory)
194        {
195        String name = factory->getType();
196        mRendererFactories[name] = factory;
197        LogManager::getSingleton().logMessage("Particle Renderer Type '" + name + "' registered");
198        }
199        //-----------------------------------------------------------------------
200    void ParticleSystemManager::addTemplate(const String& name, ParticleSystem* sysTemplate)
201    {
202                // check name
203                if (mSystemTemplates.find(name) != mSystemTemplates.end())
204                {
205                        OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM,
206                                "ParticleSystem template with name '" + name + "' already exists.",
207                                "ParticleSystemManager::addTemplate");
208                }
209
210        mSystemTemplates[name] = sysTemplate;
211    }
212    //-----------------------------------------------------------------------
213    ParticleSystem* ParticleSystemManager::createTemplate(const String& name,
214        const String& resourceGroup)
215    {
216                // check name
217                if (mSystemTemplates.find(name) != mSystemTemplates.end())
218                {
219                        OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM,
220                                "ParticleSystem template with name '" + name + "' already exists.",
221                                "ParticleSystemManager::createTemplate");
222                }
223
224        ParticleSystem* tpl = new ParticleSystem(name, resourceGroup);
225        addTemplate(name, tpl);
226        return tpl;
227
228    }
229    //-----------------------------------------------------------------------
230    ParticleSystem* ParticleSystemManager::getTemplate(const String& name)
231    {
232        ParticleTemplateMap::iterator i = mSystemTemplates.find(name);
233        if (i != mSystemTemplates.end())
234        {
235            return i->second;
236        }
237        else
238        {
239            return 0;
240        }
241    }
242        //-----------------------------------------------------------------------
243    ParticleSystem* ParticleSystemManager::createSystemImpl(const String& name,
244                size_t quota, const String& resourceGroup)
245    {
246        ParticleSystem* sys = new ParticleSystem(name, resourceGroup);
247        sys->setParticleQuota(quota);
248        return sys;
249    }
250    //-----------------------------------------------------------------------
251    ParticleSystem* ParticleSystemManager::createSystemImpl(const String& name,
252                const String& templateName)
253    {
254        // Look up template
255        ParticleSystem* pTemplate = getTemplate(templateName);
256        if (!pTemplate)
257        {
258            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot find required template '" + templateName + "'", "ParticleSystemManager::createSystem");
259        }
260
261        ParticleSystem* sys = createSystemImpl(name, pTemplate->getParticleQuota(),
262            pTemplate->getResourceGroupName());
263        // Copy template settings
264        *sys = *pTemplate;
265        return sys;
266       
267    }
268    //-----------------------------------------------------------------------
269    void ParticleSystemManager::destroySystemImpl(ParticleSystem* sys)
270        {
271                delete sys;
272        }
273    //-----------------------------------------------------------------------
274    ParticleEmitter* ParticleSystemManager::_createEmitter(
275        const String& emitterType, ParticleSystem* psys)
276    {
277        // Locate emitter type
278        ParticleEmitterFactoryMap::iterator pFact = mEmitterFactories.find(emitterType);
279
280        if (pFact == mEmitterFactories.end())
281        {
282            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot find requested emitter type.",
283                "ParticleSystemManager::_createEmitter");
284        }
285
286        return pFact->second->createEmitter(psys);
287    }
288    //-----------------------------------------------------------------------
289    void ParticleSystemManager::_destroyEmitter(ParticleEmitter* emitter)
290    {
291        // Destroy using the factory which created it
292        ParticleEmitterFactoryMap::iterator pFact = mEmitterFactories.find(emitter->getType());
293
294        if (pFact == mEmitterFactories.end())
295        {
296            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot find emitter factory to destroy emitter.",
297                "ParticleSystemManager::_destroyEmitter");
298        }
299
300        pFact->second->destroyEmitter(emitter);
301    }
302    //-----------------------------------------------------------------------
303    ParticleAffector* ParticleSystemManager::_createAffector(
304        const String& affectorType, ParticleSystem* psys)
305    {
306        // Locate affector type
307        ParticleAffectorFactoryMap::iterator pFact = mAffectorFactories.find(affectorType);
308
309        if (pFact == mAffectorFactories.end())
310        {
311            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot find requested affector type.",
312                "ParticleSystemManager::_createAffector");
313        }
314
315        return pFact->second->createAffector(psys);
316
317    }
318    //-----------------------------------------------------------------------
319    void ParticleSystemManager::_destroyAffector(ParticleAffector* affector)
320    {
321        // Destroy using the factory which created it
322        ParticleAffectorFactoryMap::iterator pFact = mAffectorFactories.find(affector->getType());
323
324        if (pFact == mAffectorFactories.end())
325        {
326            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot find affector factory to destroy affector.",
327                "ParticleSystemManager::_destroyAffector");
328        }
329
330        pFact->second->destroyAffector(affector);
331    }
332    //-----------------------------------------------------------------------
333    ParticleSystemRenderer* ParticleSystemManager::_createRenderer(const String& rendererType)
334        {
335        // Locate affector type
336        ParticleSystemRendererFactoryMap::iterator pFact = mRendererFactories.find(rendererType);
337
338        if (pFact == mRendererFactories.end())
339        {
340            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot find requested renderer type.",
341                "ParticleSystemManager::_createRenderer");
342        }
343
344        return pFact->second->createInstance(rendererType);
345        }
346        //-----------------------------------------------------------------------
347    void ParticleSystemManager::_destroyRenderer(ParticleSystemRenderer* renderer)
348        {
349        // Destroy using the factory which created it
350        ParticleSystemRendererFactoryMap::iterator pFact = mRendererFactories.find(renderer->getType());
351
352        if (pFact == mRendererFactories.end())
353        {
354            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot find renderer factory to destroy renderer.",
355                "ParticleSystemManager::_destroyRenderer");
356        }
357
358        pFact->second->destroyInstance(renderer);
359        }
360    //-----------------------------------------------------------------------
361    void ParticleSystemManager::_initialise(void)
362    {
363        // Create Billboard renderer factory
364        mBillboardRendererFactory = new BillboardParticleRendererFactory();
365        addRendererFactory(mBillboardRendererFactory);
366
367    }
368    //-----------------------------------------------------------------------
369    void ParticleSystemManager::parseNewEmitter(const String& type, DataStreamPtr& stream, ParticleSystem* sys)
370    {
371        // Create new emitter
372        ParticleEmitter* pEmit = sys->addEmitter(type);
373        // Parse emitter details
374        String line;
375
376        while(!stream->eof())
377        {
378            line = stream->getLine();
379            // Ignore comments & blanks
380            if (!(line.length() == 0 || line.substr(0,2) == "//"))
381            {
382                if (line == "}")
383                {
384                    // Finished emitter
385                    break;
386                }
387                else
388                {
389                    // Attribute
390                                        StringUtil::toLowerCase(line);
391                    parseEmitterAttrib(line, pEmit);
392                }
393            }
394        }
395
396
397       
398    }
399    //-----------------------------------------------------------------------
400    void ParticleSystemManager::parseNewAffector(const String& type, DataStreamPtr& stream, ParticleSystem* sys)
401    {
402        // Create new affector
403        ParticleAffector* pAff = sys->addAffector(type);
404        // Parse affector details
405        String line;
406
407        while(!stream->eof())
408        {
409            line = stream->getLine();
410            // Ignore comments & blanks
411            if (!(line.length() == 0 || line.substr(0,2) == "//"))
412            {
413                if (line == "}")
414                {
415                    // Finished affector
416                    break;
417                }
418                else
419                {
420                    // Attribute
421                                        StringUtil::toLowerCase(line);
422                    parseAffectorAttrib(line, pAff);
423                }
424            }
425        }
426    }
427    //-----------------------------------------------------------------------
428    void ParticleSystemManager::parseAttrib(const String& line, ParticleSystem* sys)
429    {
430        std::vector<String> vecparams;
431
432        // Split params on space
433        vecparams = StringUtil::split(line, "\t ", 1);
434
435        // Look up first param (command setting)
436        if (!sys->setParameter(vecparams[0], vecparams[1]))
437        {
438            // Attribute not supported by particle system, try the renderer
439            ParticleSystemRenderer* renderer = sys->getRenderer();
440            if (renderer)
441            {
442                if (!renderer->setParameter(vecparams[0], vecparams[1]))
443                {
444                    LogManager::getSingleton().logMessage("Bad particle system attribute line: '"
445                        + line + "' in " + sys->getName() + " (tried renderer)");
446                }
447            }
448            else
449            {
450                // BAD command. BAD!
451                LogManager::getSingleton().logMessage("Bad particle system attribute line: '"
452                    + line + "' in " + sys->getName() + " (no renderer)");
453            }
454        }
455    }
456    //-----------------------------------------------------------------------
457    void ParticleSystemManager::parseEmitterAttrib(const String& line, ParticleEmitter* emit)
458    {
459        std::vector<String> vecparams;
460
461        // Split params on first space
462        vecparams = StringUtil::split(line, "\t ", 1);
463
464        // Look up first param (command setting)
465        if (!emit->setParameter(vecparams[0], vecparams[1]))
466        {
467            // BAD command. BAD!
468            LogManager::getSingleton().logMessage("Bad particle emitter attribute line: '"
469                + line + "' for emitter " + emit->getType());
470        }
471    }
472    //-----------------------------------------------------------------------
473    void ParticleSystemManager::parseAffectorAttrib(const String& line, ParticleAffector* aff)
474    {
475        std::vector<String> vecparams;
476
477        // Split params on space
478        vecparams = StringUtil::split(line, "\t ", 1);
479
480        // Look up first param (command setting)
481        if (!aff->setParameter(vecparams[0], vecparams[1]))
482        {
483            // BAD command. BAD!
484            LogManager::getSingleton().logMessage("Bad particle affector attribute line: '"
485                + line + "' for affector " + aff->getType());
486        }
487    }
488    //-----------------------------------------------------------------------
489    void ParticleSystemManager::skipToNextCloseBrace(DataStreamPtr& stream)
490    {
491        String line = "";
492        while (!stream->eof() && line != "}")
493        {
494            line = stream->getLine();
495        }
496
497    }
498    //-----------------------------------------------------------------------
499    void ParticleSystemManager::skipToNextOpenBrace(DataStreamPtr& stream)
500    {
501        String line = "";
502        while (!stream->eof() && line != "{")
503        {
504            line = stream->getLine();
505        }
506
507    }
508        //-----------------------------------------------------------------------
509        ParticleSystemManager::ParticleAffectorFactoryIterator
510        ParticleSystemManager::getAffectorFactoryIterator(void)
511        {
512                return ParticleAffectorFactoryIterator(
513                        mAffectorFactories.begin(), mAffectorFactories.end());
514        }
515        //-----------------------------------------------------------------------
516        ParticleSystemManager::ParticleEmitterFactoryIterator
517        ParticleSystemManager::getEmitterFactoryIterator(void)
518        {
519                return ParticleEmitterFactoryIterator(
520                        mEmitterFactories.begin(), mEmitterFactories.end());
521        }
522        //-----------------------------------------------------------------------
523        ParticleSystemManager::ParticleRendererFactoryIterator
524        ParticleSystemManager::getRendererFactoryIterator(void)
525        {
526                return ParticleRendererFactoryIterator(
527                        mRendererFactories.begin(), mRendererFactories.end());
528        }
529        //-----------------------------------------------------------------------
530    //-----------------------------------------------------------------------
531    //-----------------------------------------------------------------------
532        String ParticleSystemFactory::FACTORY_TYPE_NAME = "ParticleSystem";
533    //-----------------------------------------------------------------------
534        MovableObject* ParticleSystemFactory::createInstanceImpl( const String& name,
535                        const NameValuePairList* params)
536        {
537                if (params != 0)
538                {
539                        NameValuePairList::const_iterator ni = params->find("templateName");
540                        if (ni != params->end())
541                        {
542                                String templateName = ni->second;
543                                // create using manager
544                                return ParticleSystemManager::getSingleton().createSystemImpl(
545                                                name, templateName);
546                        }
547                }
548                // Not template based, look for quota & resource name
549                size_t quota = 500;
550                String resourceGroup = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME;
551                if (params != 0)
552                {
553                        NameValuePairList::const_iterator ni = params->find("quota");
554                        if (ni != params->end())
555                        {
556                                quota = StringConverter::parseUnsignedInt(ni->second);
557                        }
558                        ni = params->find("resourceGroup");
559                        if (ni != params->end())
560                        {
561                                resourceGroup = ni->second;
562                        }
563                }
564                // create using manager
565                return ParticleSystemManager::getSingleton().createSystemImpl(
566                                name, quota, resourceGroup);
567                               
568
569        }
570    //-----------------------------------------------------------------------
571        const String& ParticleSystemFactory::getType(void) const
572        {
573                return FACTORY_TYPE_NAME;
574        }
575    //-----------------------------------------------------------------------
576        void ParticleSystemFactory::destroyInstance( MovableObject* obj)
577        {
578                // use manager
579                ParticleSystemManager::getSingleton().destroySystemImpl(
580                        static_cast<ParticleSystem*>(obj));
581
582        }
583    //-----------------------------------------------------------------------
584}
Note: See TracBrowser for help on using the repository browser.