Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages

# OgreParticleSystemManager.cpp

Go to the documentation of this file.

    00001 /*
    00002 -----------------------------------------------------------------------------
    00003 This source file is part of OGRE
    00004     (Object-oriented Graphics Rendering Engine)
    00005 For the latest info, see http://www.ogre3d.org/
    00006
    00007 Copyright © 2000-2002 The OGRE Team
    00008 Also see acknowledgements in Readme.html
    00009
    00010 This program is free software; you can redistribute it and/or modify it under
    00011 the terms of the GNU Lesser General Public License as published by the Free Software
    00012 Foundation; either version 2 of the License, or (at your option) any later
    00013 version.
    00014
    00015 This program is distributed in the hope that it will be useful, but WITHOUT
    00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
    00018
    00019 You should have received a copy of the GNU Lesser General Public License along with
    00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
    00022 http://www.gnu.org/copyleft/lesser.txt.
    00023 -----------------------------------------------------------------------------
    00024 */
    00025 #include "OgreStableHeaders.h"
    00026
    00027 #include "OgreParticleSystemManager.h"
    00028 #include "OgreParticleEmitterFactory.h"
    00029 #include "OgreParticleAffectorFactory.h"
    00030 #include "OgreException.h"
    00031 #include "OgreRoot.h"
    00032 #include "OgreLogManager.h"
    00033 #include "OgreString.h"
    00034 #include "OgreSDDataChunk.h"
    00035
    00036
    00037 namespace Ogre {
    00038     template<> ParticleSystemManager* Singleton<ParticleSystemManager>::ms_Singleton = 0;
    00039     ParticleSystemManager* ParticleSystemManager::getSingletonPtr(void)
    00040     {
    00041         return ms_Singleton;
    00042     }
    00043     ParticleSystemManager& ParticleSystemManager::getSingleton(void)
    00044     {
    00045         assert( ms_Singleton );  return ( *ms_Singleton );
    00046     }
    00047     //-----------------------------------------------------------------------
    00048     ParticleSystemManager::ParticleSystemManager()
    00049     {
    00050         mTimeFactor = 1;
    00051     }
    00052     //-----------------------------------------------------------------------
    00053     ParticleSystemManager::~ParticleSystemManager()
    00054     {
    00055         // Templates will be destroyed by by-value STL container
    00056         mSystemTemplates.clear();
    00057         // Destroy all systems
    00058         ParticleSystemMap::iterator i;
    00059         for (i = mSystems.begin(); i != mSystems.end(); ++i)
    00060         {
    00061             delete i->second;
    00062         }
    00063         mSystems.clear();
    00064     }
    00065     //-----------------------------------------------------------------------
    00066     void ParticleSystemManager::parseScript(DataChunk& chunk)
    00067     {
    00068         String line;
    00069         ParticleSystem* pSys;
    00070         std::vector<String> vecparams;
    00071
    00072         pSys = 0;
    00073
    00074         while(!chunk.isEOF())
    00075         {
    00076             line = chunk.getLine();
    00077             // Ignore comments & blanks
    00078             if (!(line.length() == 0 || line.substr(0,2) == "//"))
    00079             {
    00080                 if (pSys == 0)
    00081                 {
    00082                     // No current system
    00083                     // So first valid data should be a system name
    00084                     pSys = createTemplate(line);
    00085                     // Skip to and over next {
    00086                     skipToNextOpenBrace(chunk);
    00087                 }
    00088                 else
    00089                 {
    00090                     // Already in a system
    00091                     if (line == "}")
    00092                     {
    00093                         // Finished system
    00094                         pSys = 0;
    00095                     }
    00096                     else if (line.substr(0,7) == "emitter")
    00097                     {
    00098                         // new emitter
    00099                         // Get typename
    00100                         vecparams = StringUtil::split(line, "\t ");
    00101                         if (vecparams.size() < 2)
    00102                         {
    00103                             // Oops, bad emitter
    00104                             LogManager::getSingleton().logMessage("Bad particle system emitter line: '"
    00105                                 + line + "' in " + pSys->getName());
    00106                             skipToNextCloseBrace(chunk);
    00107
    00108                         }
    00109                         skipToNextOpenBrace(chunk);
    00110                         parseNewEmitter(vecparams[1], chunk, pSys);
    00111
    00112                     }
    00113                     else if (line.substr(0,8) == "affector")
    00114                     {
    00115                         // new affector
    00116                         // Get typename
    00117                         vecparams = StringUtil::split(line, "\t ");
    00118                         if (vecparams.size() < 2)
    00119                         {
    00120                             // Oops, bad emitter
    00121                             LogManager::getSingleton().logMessage("Bad particle system affector line: '"
    00122                                 + line + "' in " + pSys->getName());
    00123                             skipToNextCloseBrace(chunk);
    00124
    00125                         }
    00126                         skipToNextOpenBrace(chunk);
    00127                         parseNewAffector(vecparams[1],chunk, pSys);
    00128                     }
    00129                     else
    00130                     {
    00131                         // Attribute
    00132                         parseAttrib(line, pSys);
    00133                     }
    00134
    00135                 }
    00136
    00137             }
    00138
    00139
    00140         }
    00141
    00142
    00143     }
    00144     //-----------------------------------------------------------------------
    00145     void ParticleSystemManager::parseAllSources(const String& extension)
    00146     {
    00147         std::set<String> particleFiles;
    00148
    00149         particleFiles = ResourceManager::_getAllCommonNamesLike("./", extension);
    00150
    00151         // Iterate through returned files
    00152         std::set<String>::iterator i;
    00153         for (i = particleFiles.begin(); i != particleFiles.end(); ++i)
    00154         {
    00155             SDDataChunk chunk;
    00156             LogManager::getSingleton().logMessage("Parsing particle script " + *i);
    00157             ResourceManager::_findCommonResourceData(*i, chunk);
    00158             parseScript(chunk);
    00159         }
    00160     }
    00161     //-----------------------------------------------------------------------
    00162     void ParticleSystemManager::addEmitterFactory(ParticleEmitterFactory* factory)
    00163     {
    00164         String name = factory->getName();
    00165         mEmitterFactories[name] = factory;
    00166         LogManager::getSingleton().logMessage("Particle Emitter Type '" + name + "' registered");
    00167     }
    00168     //-----------------------------------------------------------------------
    00169     void ParticleSystemManager::addAffectorFactory(ParticleAffectorFactory* factory)
    00170     {
    00171         String name = factory->getName();
    00172         mAffectorFactories[name] = factory;
    00173         LogManager::getSingleton().logMessage("Particle Affector Type '" + name + "' registered");
    00174     }
    00175     //-----------------------------------------------------------------------
    00176     void ParticleSystemManager::addTemplate(const String& name, const ParticleSystem& sysTemplate)
    00177     {
    00178         mSystemTemplates[name] = sysTemplate;
    00179     }
    00180     //-----------------------------------------------------------------------
    00181     ParticleSystem* ParticleSystemManager::createTemplate(const String& name)
    00182     {
    00183         addTemplate(name, ParticleSystem(name));
    00184         return getTemplate(name);
    00185
    00186     }
    00187     //-----------------------------------------------------------------------
    00188     ParticleSystem* ParticleSystemManager::getTemplate(const String& name)
    00189     {
    00190         ParticleTemplateMap::iterator i = mSystemTemplates.find(name);
    00191         if (i != mSystemTemplates.end())
    00192         {
    00193             return &(i->second);
    00194         }
    00195         else
    00196         {
    00197             return 0;
    00198         }
    00199     }
    00200     //-----------------------------------------------------------------------
    00201     ParticleSystem* ParticleSystemManager::createSystem(const String& name, unsigned int quota)
    00202     {
    00203         ParticleSystem* sys = new ParticleSystem(name);
    00204         sys->setParticleQuota(quota);
    00205         mSystems.insert( ParticleSystemMap::value_type( name, sys ) );
    00206         return sys;
    00207     }
    00208     //-----------------------------------------------------------------------
    00209     ParticleSystem* ParticleSystemManager::createSystem(const String& name, const String& templateName)
    00210     {
    00211         // Look up template
    00212         ParticleSystem* pTemplate = getTemplate(templateName);
    00213         if (!pTemplate)
    00214         {
    00215             Except(Exception::ERR_INVALIDPARAMS, "Cannot find required template '" + templateName + "'", "ParticleSystemManager::createSystem");
    00216         }
    00217
    00218         ParticleSystem* sys = createSystem(name, pTemplate->getParticleQuota());
    00219         // Copy template settings
    00220         *sys = *pTemplate;
    00221         return sys;
    00222
    00223     }
    00224     //-----------------------------------------------------------------------
    00225     void ParticleSystemManager::destroySystem(const String& name)
    00226     {
    00227         ParticleSystemMap::iterator i = mSystems.find(name);
    00228         if (i != mSystems.end())
    00229         {
    00230             delete i->second;
    00231             mSystems.erase(i);
    00232         }
    00233     }
    00234     //-----------------------------------------------------------------------
    00235     void ParticleSystemManager::destroySystem(ParticleSystem* sys)
    00236     {
    00237         ParticleSystemMap::iterator i;
    00238         for (i = mSystems.begin(); i != mSystems.end(); ++i)
    00239         {
    00240             if (i->second == sys)
    00241             {
    00242                 delete i->second;
    00243                 mSystems.erase(i);
    00244                 break;
    00245             }
    00246         }
    00247     }
    00248
    00249     //-----------------------------------------------------------------------
    00250     ParticleSystem* ParticleSystemManager::getSystem(const String& name)
    00251     {
    00252         ParticleSystemMap::iterator i = mSystems.find(name);
    00253         if (i != mSystems.end())
    00254         {
    00255             return i->second;
    00256         }
    00257         else
    00258         {
    00259             Except(Exception::ERR_ITEM_NOT_FOUND, "Cannot find particle system '" + name + "'",
    00260                 "ParticleSystemManager::getSystem");
    00261         }
    00262     }
    00263
    00264     //-----------------------------------------------------------------------
    00265     ParticleEmitter* ParticleSystemManager::_createEmitter(const String& emitterType)
    00266     {
    00267         // Locate emitter type
    00268         ParticleEmitterFactoryMap::iterator pFact = mEmitterFactories.find(emitterType);
    00269
    00270         if (pFact == mEmitterFactories.end())
    00271         {
    00272             Except(Exception::ERR_INVALIDPARAMS, "Cannot find requested emitter type.",
    00273                 "ParticleSystemManager::_createEmitter");
    00274         }
    00275
    00276         return pFact->second->createEmitter();
    00277     }
    00278     //-----------------------------------------------------------------------
    00279     void ParticleSystemManager::_destroyEmitter(ParticleEmitter* emitter)
    00280     {
    00281         // Destroy using the factory which created it
    00282         ParticleEmitterFactoryMap::iterator pFact = mEmitterFactories.find(emitter->getType());
    00283
    00284         if (pFact == mEmitterFactories.end())
    00285         {
    00286             Except(Exception::ERR_INVALIDPARAMS, "Cannot find emitter factory to destroy emitter.",
    00287                 "ParticleSystemManager::_destroyEmitter");
    00288         }
    00289
    00290         pFact->second->destroyEmitter(emitter);
    00291     }
    00292     //-----------------------------------------------------------------------
    00293     ParticleAffector* ParticleSystemManager::_createAffector(const String& affectorType)
    00294     {
    00295         // Locate affector type
    00296         ParticleAffectorFactoryMap::iterator pFact = mAffectorFactories.find(affectorType);
    00297
    00298         if (pFact == mAffectorFactories.end())
    00299         {
    00300             Except(Exception::ERR_INVALIDPARAMS, "Cannot find requested affector type.",
    00301                 "ParticleSystemManager::_createAffector");
    00302         }
    00303
    00304         return pFact->second->createAffector();
    00305
    00306     }
    00307     //-----------------------------------------------------------------------
    00308     void ParticleSystemManager::_destroyAffector(ParticleAffector* affector)
    00309     {
    00310         // Destroy using the factory which created it
    00311         ParticleAffectorFactoryMap::iterator pFact = mAffectorFactories.find(affector->getType());
    00312
    00313         if (pFact == mAffectorFactories.end())
    00314         {
    00315             Except(Exception::ERR_INVALIDPARAMS, "Cannot find affector factory to destroy affector.",
    00316                 "ParticleSystemManager::_destroyAffector");
    00317         }
    00318
    00319         pFact->second->destroyAffector(affector);
    00320     }
    00321     //-----------------------------------------------------------------------
    00322     bool ParticleSystemManager::frameStarted(const FrameEvent &evt)
    00323     {
    00324         // Apply time factor
    00325         Real timeSinceLastFrame = mTimeFactor * evt.timeSinceLastFrame;
    00326
    00327         // update systems
    00328         // TODO: only do this for visible systems
    00329         ParticleSystemMap::iterator i;
    00330         for (i = mSystems.begin(); i != mSystems.end(); ++i)
    00331         {
    00332             i->second->_update(timeSinceLastFrame);
    00333         }
    00334
    00335         return true;
    00336     }
    00337     //-----------------------------------------------------------------------
    00338     bool ParticleSystemManager::frameEnded(const FrameEvent &evt)
    00339     {
    00340         return true;
    00341     }
    00342     //-----------------------------------------------------------------------
    00343     void ParticleSystemManager::_initialise(void)
    00344     {
    00345         // Register self as a frame listener
    00346         Root::getSingleton().addFrameListener(this);
    00347
    00348         // Parse all scripts
    00349         parseAllSources();
    00350     }
    00351     //-----------------------------------------------------------------------
    00352     void ParticleSystemManager::parseNewEmitter(const String& type, DataChunk& chunk, ParticleSystem* sys)
    00353     {
    00354         // Create new emitter
    00355         ParticleEmitter* pEmit = sys->addEmitter(type);
    00356         // Parse emitter details
    00357         String line;
    00358
    00359         while(!chunk.isEOF())
    00360         {
    00361             line = chunk.getLine();
    00362             // Ignore comments & blanks
    00363             if (!(line.length() == 0 || line.substr(0,2) == "//"))
    00364             {
    00365                 if (line == "}")
    00366                 {
    00367                     // Finished emitter
    00368                     break;
    00369                 }
    00370                 else
    00371                 {
    00372                     // Attribute
    00373                     StringUtil::toLowerCase(line);
    00374                     parseEmitterAttrib(line, pEmit);
    00375                 }
    00376             }
    00377         }
    00378
    00379
    00380
    00381     }
    00382     //-----------------------------------------------------------------------
    00383     void ParticleSystemManager::parseNewAffector(const String& type, DataChunk& chunk, ParticleSystem* sys)
    00384     {
    00385         // Create new affector
    00386         ParticleAffector* pAff = sys->addAffector(type);
    00387         // Parse affector details
    00388         String line;
    00389
    00390         while(!chunk.isEOF())
    00391         {
    00392             line = chunk.getLine();
    00393             // Ignore comments & blanks
    00394             if (!(line.length() == 0 || line.substr(0,2) == "//"))
    00395             {
    00396                 if (line == "}")
    00397                 {
    00398                     // Finished affector
    00399                     break;
    00400                 }
    00401                 else
    00402                 {
    00403                     // Attribute
    00404                     StringUtil::toLowerCase(line);
    00405                     parseAffectorAttrib(line, pAff);
    00406                 }
    00407             }
    00408         }
    00409     }
    00410     //-----------------------------------------------------------------------
    00411     void ParticleSystemManager::parseAttrib(const String& line, ParticleSystem* sys)
    00412     {
    00413         std::vector<String> vecparams;
    00414
    00415         // Split params on space
    00416         vecparams = StringUtil::split(line, "\t ", 1);
    00417
    00418         // Look up first param (command setting)
    00419         if (!sys->setParameter(vecparams[0], vecparams[1]))
    00420         {
    00421             // BAD command. BAD!
    00422             LogManager::getSingleton().logMessage("Bad particle system attribute line: '"
    00423                 + line + "' in " + sys->getName());
    00424         }
    00425     }
    00426     //-----------------------------------------------------------------------
    00427     void ParticleSystemManager::parseEmitterAttrib(const String& line, ParticleEmitter* emit)
    00428     {
    00429         std::vector<String> vecparams;
    00430
    00431         // Split params on first space
    00432         vecparams = StringUtil::split(line, "\t ", 1);
    00433
    00434         // Look up first param (command setting)
    00435         if (!emit->setParameter(vecparams[0], vecparams[1]))
    00436         {
    00437             // BAD command. BAD!
    00438             LogManager::getSingleton().logMessage("Bad particle emitter attribute line: '"
    00439                 + line + "' for emitter " + emit->getType());
    00440         }
    00441     }
    00442     //-----------------------------------------------------------------------
    00443     void ParticleSystemManager::parseAffectorAttrib(const String& line, ParticleAffector* aff)
    00444     {
    00445         std::vector<String> vecparams;
    00446
    00447         // Split params on space
    00448         vecparams = StringUtil::split(line, "\t ", 1);
    00449
    00450         // Look up first param (command setting)
    00451         if (!aff->setParameter(vecparams[0], vecparams[1]))
    00452         {
    00453             // BAD command. BAD!
    00454             LogManager::getSingleton().logMessage("Bad particle affector attribute line: '"
    00455                 + line + "' for affector " + aff->getType());
    00456         }
    00457     }
    00458     //-----------------------------------------------------------------------
    00459     void ParticleSystemManager::skipToNextCloseBrace(DataChunk& chunk)
    00460     {
    00461         String line = "";
    00462         while (!chunk.isEOF() && line != "}")
    00463         {
    00464             line = chunk.getLine();
    00465         }
    00466
    00467     }
    00468     //-----------------------------------------------------------------------
    00469     void ParticleSystemManager::skipToNextOpenBrace(DataChunk& chunk)
    00470     {
    00471         String line = "";
    00472         while (!chunk.isEOF() && line != "{")
    00473         {
    00474             line = chunk.getLine();
    00475         }
    00476
    00477     }
    00478     //-----------------------------------------------------------------------
    00479     Real ParticleSystemManager::getTimeFactor(void) const {
    00480         return mTimeFactor;
    00481     }
    00482     //-----------------------------------------------------------------------
    00483     void ParticleSystemManager::setTimeFactor(Real tf) {
    00484         if(tf >= 0) mTimeFactor = tf;
    00485     }
    00486 }

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:38 2004