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

Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:21 2004