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