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 "OgreParticleEmitter.h" 00028 00029 namespace Ogre { 00030 00031 // Define static members 00032 EmitterCommands::CmdAngle ParticleEmitter::msAngleCmd; 00033 EmitterCommands::CmdColour ParticleEmitter::msColourCmd; 00034 EmitterCommands::CmdColourRangeStart ParticleEmitter::msColourRangeStartCmd; 00035 EmitterCommands::CmdColourRangeEnd ParticleEmitter::msColourRangeEndCmd; 00036 EmitterCommands::CmdDirection ParticleEmitter::msDirectionCmd; 00037 EmitterCommands::CmdEmissionRate ParticleEmitter::msEmissionRateCmd; 00038 EmitterCommands::CmdMaxTTL ParticleEmitter::msMaxTTLCmd; 00039 EmitterCommands::CmdMaxVelocity ParticleEmitter::msMaxVelocityCmd; 00040 EmitterCommands::CmdMinTTL ParticleEmitter::msMinTTLCmd; 00041 EmitterCommands::CmdMinVelocity ParticleEmitter::msMinVelocityCmd; 00042 EmitterCommands::CmdPosition ParticleEmitter::msPositionCmd; 00043 EmitterCommands::CmdTTL ParticleEmitter::msTTLCmd; 00044 EmitterCommands::CmdVelocity ParticleEmitter::msVelocityCmd; 00045 EmitterCommands::CmdDuration ParticleEmitter::msDurationCmd; 00046 EmitterCommands::CmdMinDuration ParticleEmitter::msMinDurationCmd; 00047 EmitterCommands::CmdMaxDuration ParticleEmitter::msMaxDurationCmd; 00048 EmitterCommands::CmdRepeatDelay ParticleEmitter::msRepeatDelayCmd; 00049 EmitterCommands::CmdMinRepeatDelay ParticleEmitter::msMinRepeatDelayCmd; 00050 EmitterCommands::CmdMaxRepeatDelay ParticleEmitter::msMaxRepeatDelayCmd; 00051 00052 00053 //----------------------------------------------------------------------- 00054 ParticleEmitter::ParticleEmitter() 00055 : mStartTime(0), 00056 mDurationMin(0), 00057 mDurationMax(0), 00058 mDurationRemain(0), 00059 mRepeatDelayMin(0), 00060 mRepeatDelayMax(0), 00061 mRepeatDelayRemain(0) 00062 { 00063 00064 // Reasonable defaults 00065 mAngle = 0; 00066 setDirection(Vector3::UNIT_X); 00067 mEmissionRate = 10; 00068 mMaxSpeed = mMinSpeed = 1; 00069 mMaxTTL = mMinTTL = 5; 00070 mPosition = Vector3::ZERO; 00071 mColourRangeStart = mColourRangeEnd = ColourValue::White; 00072 mEnabled = true; 00073 mRemainder = 0; 00074 00075 } 00076 //----------------------------------------------------------------------- 00077 ParticleEmitter::~ParticleEmitter() 00078 { 00079 } 00080 //----------------------------------------------------------------------- 00081 void ParticleEmitter::setPosition(const Vector3& pos) 00082 { 00083 mPosition = pos; 00084 } 00085 //----------------------------------------------------------------------- 00086 const Vector3& ParticleEmitter::getPosition(void) const 00087 { 00088 return mPosition; 00089 } 00090 //----------------------------------------------------------------------- 00091 void ParticleEmitter::setDirection(const Vector3& direction) 00092 { 00093 mDirection = direction; 00094 mDirection.normalise(); 00095 // Generate an up vector (any will do) 00096 mUp = mDirection.perpendicular(); 00097 mUp.normalise(); 00098 } 00099 //----------------------------------------------------------------------- 00100 const Vector3& ParticleEmitter::getDirection(void) const 00101 { 00102 return mDirection; 00103 } 00104 //----------------------------------------------------------------------- 00105 void ParticleEmitter::setAngle(const Radian& angle) 00106 { 00107 // Store as radians for efficiency 00108 mAngle = angle; 00109 } 00110 //----------------------------------------------------------------------- 00111 const Radian& ParticleEmitter::getAngle(void) const 00112 { 00113 return mAngle; 00114 } 00115 //----------------------------------------------------------------------- 00116 void ParticleEmitter::setParticleVelocity(Real speed) 00117 { 00118 mMinSpeed = mMaxSpeed = speed; 00119 } 00120 //----------------------------------------------------------------------- 00121 void ParticleEmitter::setParticleVelocity(Real min, Real max) 00122 { 00123 mMinSpeed = min; 00124 mMaxSpeed = max; 00125 } 00126 //----------------------------------------------------------------------- 00127 void ParticleEmitter::setEmissionRate(Real particlesPerSecond) 00128 { 00129 mEmissionRate = particlesPerSecond; 00130 } 00131 //----------------------------------------------------------------------- 00132 Real ParticleEmitter::getEmissionRate(void) const 00133 { 00134 return mEmissionRate; 00135 } 00136 //----------------------------------------------------------------------- 00137 void ParticleEmitter::setTimeToLive(Real ttl) 00138 { 00139 mMinTTL = mMaxTTL = ttl; 00140 } 00141 //----------------------------------------------------------------------- 00142 void ParticleEmitter::setTimeToLive(Real minTtl, Real maxTtl) 00143 { 00144 mMinTTL = minTtl; 00145 mMaxTTL = maxTtl; 00146 } 00147 //----------------------------------------------------------------------- 00148 void ParticleEmitter::setColour(const ColourValue& colour) 00149 { 00150 mColourRangeStart = mColourRangeEnd = colour; 00151 } 00152 //----------------------------------------------------------------------- 00153 void ParticleEmitter::setColour(const ColourValue& colourStart, const ColourValue& colourEnd) 00154 { 00155 mColourRangeStart = colourStart; 00156 mColourRangeEnd = colourEnd; 00157 } 00158 //----------------------------------------------------------------------- 00159 void ParticleEmitter::genEmissionDirection(Vector3& destVector) 00160 { 00161 if (mAngle != Radian(0)) 00162 { 00163 // Randomise angle 00164 Radian angle = Math::UnitRandom() * mAngle; 00165 00166 // Randomise direction 00167 destVector = mDirection.randomDeviant(angle, mUp); 00168 } 00169 else 00170 { 00171 // Constant angle 00172 destVector = mDirection; 00173 } 00174 00175 // Don't normalise, we can assume that it will still be a unit vector since 00176 // both direction and 'up' are. 00177 00178 } 00179 //----------------------------------------------------------------------- 00180 void ParticleEmitter::genEmissionVelocity(Vector3& destVector) 00181 { 00182 Real scalar; 00183 if (mMinSpeed != mMaxSpeed) 00184 { 00185 scalar = mMinSpeed + (Math::UnitRandom() * (mMaxSpeed - mMinSpeed)); 00186 } 00187 else 00188 { 00189 scalar = mMinSpeed; 00190 } 00191 00192 destVector *= scalar; 00193 } 00194 //----------------------------------------------------------------------- 00195 Real ParticleEmitter::genEmissionTTL(void) 00196 { 00197 if (mMaxTTL != mMinTTL) 00198 { 00199 return mMinTTL + (Math::UnitRandom() * (mMaxTTL - mMinTTL)); 00200 } 00201 else 00202 { 00203 return mMinTTL; 00204 } 00205 } 00206 //----------------------------------------------------------------------- 00207 unsigned short ParticleEmitter::genConstantEmissionCount(Real timeElapsed) 00208 { 00209 unsigned short intRequest; 00210 00211 if (mEnabled) 00212 { 00213 // Keep fractions, otherwise a high frame rate will result in zero emissions! 00214 mRemainder += mEmissionRate * timeElapsed; 00215 intRequest = (unsigned short)mRemainder; 00216 mRemainder -= intRequest; 00217 00218 // Check duration 00219 if (mDurationMax) 00220 { 00221 mDurationRemain -= timeElapsed; 00222 if (mDurationRemain <= 0) 00223 { 00224 // Disable, duration is out (takes effect next time) 00225 setEnabled(false); 00226 } 00227 } 00228 return intRequest; 00229 } 00230 else 00231 { 00232 // Check repeat 00233 if (mRepeatDelayMax) 00234 { 00235 mRepeatDelayRemain -= timeElapsed; 00236 if (mRepeatDelayRemain <= 0) 00237 { 00238 // Enable, repeat delay is out (takes effect next time) 00239 setEnabled(true); 00240 } 00241 } 00242 if(mStartTime) 00243 { 00244 mStartTime -= timeElapsed; 00245 if(mStartTime <= 0) 00246 { 00247 setEnabled(true); 00248 mStartTime = 0; 00249 } 00250 } 00251 return 0; 00252 } 00253 00254 } 00255 //----------------------------------------------------------------------- 00256 void ParticleEmitter::genEmissionColour(ColourValue& destColour) 00257 { 00258 if (mColourRangeStart != mColourRangeEnd) 00259 { 00260 // Randomise 00261 //Real t = Math::UnitRandom(); 00262 destColour.r = mColourRangeStart.r + (Math::UnitRandom() * (mColourRangeEnd.r - mColourRangeStart.r)); 00263 destColour.g = mColourRangeStart.g + (Math::UnitRandom() * (mColourRangeEnd.g - mColourRangeStart.g)); 00264 destColour.b = mColourRangeStart.b + (Math::UnitRandom() * (mColourRangeEnd.b - mColourRangeStart.b)); 00265 destColour.a = mColourRangeStart.a + (Math::UnitRandom() * (mColourRangeEnd.a - mColourRangeStart.a)); 00266 } 00267 else 00268 { 00269 destColour = mColourRangeStart; 00270 } 00271 } 00272 //----------------------------------------------------------------------- 00273 void ParticleEmitter::addBaseParameters(void) 00274 { 00275 ParamDictionary* dict = getParamDictionary(); 00276 00277 dict->addParameter(ParameterDef("angle", 00278 "The angle up to which particles may vary in their initial direction " 00279 "from the emitters direction, in degrees." , PT_REAL), 00280 &msAngleCmd); 00281 00282 dict->addParameter(ParameterDef("colour", 00283 "The colour of emitted particles.", PT_COLOURVALUE), 00284 &msColourCmd); 00285 00286 dict->addParameter(ParameterDef("colour_range_start", 00287 "The start of a range of colours to be assigned to emitted particles.", PT_COLOURVALUE), 00288 &msColourRangeStartCmd); 00289 00290 dict->addParameter(ParameterDef("colour_range_end", 00291 "The end of a range of colours to be assigned to emitted particles.", PT_COLOURVALUE), 00292 &msColourRangeEndCmd); 00293 00294 dict->addParameter(ParameterDef("direction", 00295 "The base direction of the emitter." , PT_VECTOR3), 00296 &msDirectionCmd); 00297 00298 dict->addParameter(ParameterDef("emission_rate", 00299 "The number of particles emitted per second." , PT_REAL), 00300 &msEmissionRateCmd); 00301 00302 dict->addParameter(ParameterDef("position", 00303 "The position of the emitter relative to the particle system center." , PT_VECTOR3), 00304 &msPositionCmd); 00305 00306 dict->addParameter(ParameterDef("velocity", 00307 "The initial velocity to be assigned to every particle, in world units per second." , PT_REAL), 00308 &msVelocityCmd); 00309 00310 dict->addParameter(ParameterDef("velocity_min", 00311 "The minimum initial velocity to be assigned to each particle." , PT_REAL), 00312 &msMinVelocityCmd); 00313 00314 dict->addParameter(ParameterDef("velocity_max", 00315 "The maximum initial velocity to be assigned to each particle." , PT_REAL), 00316 &msMaxVelocityCmd); 00317 00318 dict->addParameter(ParameterDef("time_to_live", 00319 "The lifetime of each particle in seconds." , PT_REAL), 00320 &msTTLCmd); 00321 00322 dict->addParameter(ParameterDef("time_to_live_min", 00323 "The minimum lifetime of each particle in seconds." , PT_REAL), 00324 &msMinTTLCmd); 00325 00326 dict->addParameter(ParameterDef("time_to_live_max", 00327 "The maximum lifetime of each particle in seconds." , PT_REAL), 00328 &msMaxTTLCmd); 00329 00330 dict->addParameter(ParameterDef("duration", 00331 "The length of time in seconds which an emitter stays enabled for." , PT_REAL), 00332 &msDurationCmd); 00333 00334 dict->addParameter(ParameterDef("duration_min", 00335 "The minimum length of time in seconds which an emitter stays enabled for." , PT_REAL), 00336 &msMinDurationCmd); 00337 00338 dict->addParameter(ParameterDef("duration_max", 00339 "The maximum length of time in seconds which an emitter stays enabled for." , PT_REAL), 00340 &msMaxDurationCmd); 00341 00342 dict->addParameter(ParameterDef("repeat_delay", 00343 "If set, after disabling an emitter will repeat (reenable) after this many seconds." , PT_REAL), 00344 &msRepeatDelayCmd); 00345 00346 dict->addParameter(ParameterDef("repeat_delay_min", 00347 "If set, after disabling an emitter will repeat (reenable) after this minimum number of seconds." , PT_REAL), 00348 &msMinRepeatDelayCmd); 00349 00350 dict->addParameter(ParameterDef("repeat_delay_max", 00351 "If set, after disabling an emitter will repeat (reenable) after this maximum number of seconds." , PT_REAL), 00352 &msMaxRepeatDelayCmd); 00353 } 00354 //----------------------------------------------------------------------- 00355 Real ParticleEmitter::getParticleVelocity(void) const 00356 { 00357 return mMinSpeed; 00358 } 00359 //----------------------------------------------------------------------- 00360 Real ParticleEmitter::getMinParticleVelocity(void) const 00361 { 00362 return mMinSpeed; 00363 } 00364 //----------------------------------------------------------------------- 00365 Real ParticleEmitter::getMaxParticleVelocity(void) const 00366 { 00367 return mMaxSpeed; 00368 } 00369 //----------------------------------------------------------------------- 00370 void ParticleEmitter::setMinParticleVelocity(Real min) 00371 { 00372 mMinSpeed = min; 00373 } 00374 //----------------------------------------------------------------------- 00375 void ParticleEmitter::setMaxParticleVelocity(Real max) 00376 { 00377 mMaxSpeed = max; 00378 } 00379 //----------------------------------------------------------------------- 00380 Real ParticleEmitter::getTimeToLive(void) const 00381 { 00382 return mMinTTL; 00383 } 00384 //----------------------------------------------------------------------- 00385 Real ParticleEmitter::getMinTimeToLive(void) const 00386 { 00387 return mMinTTL; 00388 } 00389 //----------------------------------------------------------------------- 00390 Real ParticleEmitter::getMaxTimeToLive(void) const 00391 { 00392 return mMaxTTL; 00393 } 00394 //----------------------------------------------------------------------- 00395 void ParticleEmitter::setMinTimeToLive(Real min) 00396 { 00397 mMinTTL = min; 00398 } 00399 //----------------------------------------------------------------------- 00400 void ParticleEmitter::setMaxTimeToLive(Real max) 00401 { 00402 mMaxTTL = max; 00403 } 00404 //----------------------------------------------------------------------- 00405 const ColourValue& ParticleEmitter::getColour(void) const 00406 { 00407 return mColourRangeStart; 00408 } 00409 //----------------------------------------------------------------------- 00410 const ColourValue& ParticleEmitter::getColourRangeStart(void) const 00411 { 00412 return mColourRangeStart; 00413 } 00414 //----------------------------------------------------------------------- 00415 const ColourValue& ParticleEmitter::getColourRangeEnd(void) const 00416 { 00417 return mColourRangeEnd; 00418 } 00419 //----------------------------------------------------------------------- 00420 void ParticleEmitter::setColourRangeStart(const ColourValue& val) 00421 { 00422 mColourRangeStart = val; 00423 } 00424 //----------------------------------------------------------------------- 00425 void ParticleEmitter::setColourRangeEnd(const ColourValue& val ) 00426 { 00427 mColourRangeEnd = val; 00428 } 00429 //----------------------------------------------------------------------- 00430 void ParticleEmitter::setEnabled(bool enabled) 00431 { 00432 mEnabled = enabled; 00433 // Reset duration & repeat 00434 initDurationRepeat(); 00435 } 00436 //----------------------------------------------------------------------- 00437 bool ParticleEmitter::getEnabled(void) const 00438 { 00439 return mEnabled; 00440 } 00441 //----------------------------------------------------------------------- 00442 void ParticleEmitter::setStartTime(Real startTime) 00443 { 00444 setEnabled(false); 00445 mStartTime = startTime; 00446 } 00447 //----------------------------------------------------------------------- 00448 Real ParticleEmitter::getStartTime(void) const 00449 { 00450 return mStartTime; 00451 } 00452 //----------------------------------------------------------------------- 00453 void ParticleEmitter::setDuration(Real duration) 00454 { 00455 setDuration(duration, duration); 00456 } 00457 //----------------------------------------------------------------------- 00458 Real ParticleEmitter::getDuration(void) const 00459 { 00460 return mDurationMin; 00461 } 00462 //----------------------------------------------------------------------- 00463 void ParticleEmitter::setDuration(Real min, Real max) 00464 { 00465 mDurationMin = min; 00466 mDurationMax = max; 00467 initDurationRepeat(); 00468 } 00469 //----------------------------------------------------------------------- 00470 void ParticleEmitter::setMinDuration(Real min) 00471 { 00472 mDurationMin = min; 00473 initDurationRepeat(); 00474 } 00475 //----------------------------------------------------------------------- 00476 void ParticleEmitter::setMaxDuration(Real max) 00477 { 00478 mDurationMax = max; 00479 initDurationRepeat(); 00480 } 00481 //----------------------------------------------------------------------- 00482 void ParticleEmitter::initDurationRepeat(void) 00483 { 00484 if (mEnabled) 00485 { 00486 if (mDurationMin == mDurationMax) 00487 { 00488 mDurationRemain = mDurationMin; 00489 } 00490 else 00491 { 00492 mDurationRemain = Math::RangeRandom(mDurationMin, mDurationMax); 00493 } 00494 } 00495 else 00496 { 00497 // Reset repeat 00498 if (mRepeatDelayMin == mRepeatDelayMax) 00499 { 00500 mRepeatDelayRemain = mRepeatDelayMin; 00501 } 00502 else 00503 { 00504 mRepeatDelayRemain = Math::RangeRandom(mRepeatDelayMax, mRepeatDelayMin); 00505 } 00506 00507 } 00508 } 00509 //----------------------------------------------------------------------- 00510 void ParticleEmitter::setRepeatDelay(Real delay) 00511 { 00512 setRepeatDelay(delay, delay); 00513 } 00514 //----------------------------------------------------------------------- 00515 Real ParticleEmitter::getRepeatDelay(void) const 00516 { 00517 return mRepeatDelayMin; 00518 } 00519 //----------------------------------------------------------------------- 00520 void ParticleEmitter::setRepeatDelay(Real min, Real max) 00521 { 00522 mRepeatDelayMin = min; 00523 mRepeatDelayMax = max; 00524 initDurationRepeat(); 00525 } 00526 //----------------------------------------------------------------------- 00527 void ParticleEmitter::setMinRepeatDelay(Real min) 00528 { 00529 mRepeatDelayMin = min; 00530 initDurationRepeat(); 00531 } 00532 //----------------------------------------------------------------------- 00533 void ParticleEmitter::setMaxRepeatDelay(Real max) 00534 { 00535 mRepeatDelayMax = max; 00536 initDurationRepeat(); 00537 } 00538 //----------------------------------------------------------------------- 00539 Real ParticleEmitter::getMinDuration(void) const 00540 { 00541 return mDurationMin; 00542 } 00543 //----------------------------------------------------------------------- 00544 Real ParticleEmitter::getMaxDuration(void) const 00545 { 00546 return mDurationMax; 00547 } 00548 //----------------------------------------------------------------------- 00549 Real ParticleEmitter::getMinRepeatDelay(void) const 00550 { 00551 return mRepeatDelayMin; 00552 } 00553 //----------------------------------------------------------------------- 00554 Real ParticleEmitter::getMaxRepeatDelay(void) const 00555 { 00556 return mRepeatDelayMax; 00557 } 00558 00559 //----------------------------------------------------------------------- 00560 //----------------------------------------------------------------------- 00561 //----------------------------------------------------------------------- 00562 00563 } 00564
Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:37 2004