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