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

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