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