Patch 2793067: fix trunk with OGRE_THREAD_SUPPORT=1 on non-Windows platforms (don...
[ogre3d.git] / OgreMain / src / OgreParticleEmitter.cpp
blobbd97ac7d80600d3bfd9f1fec4d68cb0ef00b321f
1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
7 Copyright (c) 2000-2006 Torus Knot Software Ltd
8 Also see acknowledgements in Readme.html
10 This program is free software; you can redistribute it and/or modify it under
11 the terms of the GNU Lesser General Public License as published by the Free Software
12 Foundation; either version 2 of the License, or (at your option) any later
13 version.
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License along with
20 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22 http://www.gnu.org/copyleft/lesser.txt.
24 You may alternatively use this source under the terms of a specific version of
25 the OGRE Unrestricted License provided you have obtained such a license from
26 Torus Knot Software Ltd.
27 -----------------------------------------------------------------------------
29 #include "OgreStableHeaders.h"
31 #include "OgreParticleEmitter.h"
32 #include "OgreParticleEmitterFactory.h"
34 namespace Ogre
36 // Define static members
37 EmitterCommands::CmdAngle ParticleEmitter::msAngleCmd;
38 EmitterCommands::CmdColour ParticleEmitter::msColourCmd;
39 EmitterCommands::CmdColourRangeStart ParticleEmitter::msColourRangeStartCmd;
40 EmitterCommands::CmdColourRangeEnd ParticleEmitter::msColourRangeEndCmd;
41 EmitterCommands::CmdDirection ParticleEmitter::msDirectionCmd;
42 EmitterCommands::CmdEmissionRate ParticleEmitter::msEmissionRateCmd;
43 EmitterCommands::CmdMaxTTL ParticleEmitter::msMaxTTLCmd;
44 EmitterCommands::CmdMaxVelocity ParticleEmitter::msMaxVelocityCmd;
45 EmitterCommands::CmdMinTTL ParticleEmitter::msMinTTLCmd;
46 EmitterCommands::CmdMinVelocity ParticleEmitter::msMinVelocityCmd;
47 EmitterCommands::CmdPosition ParticleEmitter::msPositionCmd;
48 EmitterCommands::CmdTTL ParticleEmitter::msTTLCmd;
49 EmitterCommands::CmdVelocity ParticleEmitter::msVelocityCmd;
50 EmitterCommands::CmdDuration ParticleEmitter::msDurationCmd;
51 EmitterCommands::CmdMinDuration ParticleEmitter::msMinDurationCmd;
52 EmitterCommands::CmdMaxDuration ParticleEmitter::msMaxDurationCmd;
53 EmitterCommands::CmdRepeatDelay ParticleEmitter::msRepeatDelayCmd;
54 EmitterCommands::CmdMinRepeatDelay ParticleEmitter::msMinRepeatDelayCmd;
55 EmitterCommands::CmdMaxRepeatDelay ParticleEmitter::msMaxRepeatDelayCmd;
56 EmitterCommands::CmdName ParticleEmitter::msNameCmd;
57 EmitterCommands::CmdEmittedEmitter ParticleEmitter::msEmittedEmitterCmd;
60 //-----------------------------------------------------------------------
61 ParticleEmitter::ParticleEmitter(ParticleSystem* psys)
62 : mParent(psys),
63 mStartTime(0),
64 mDurationMin(0),
65 mDurationMax(0),
66 mDurationRemain(0),
67 mRepeatDelayMin(0),
68 mRepeatDelayMax(0),
69 mRepeatDelayRemain(0)
72 // Reasonable defaults
73 mAngle = 0;
74 setDirection(Vector3::UNIT_X);
75 mEmissionRate = 10;
76 mMaxSpeed = mMinSpeed = 1;
77 mMaxTTL = mMinTTL = 5;
78 mPosition = Vector3::ZERO;
79 mColourRangeStart = mColourRangeEnd = ColourValue::White;
80 mEnabled = true;
81 mRemainder = 0;
82 mName = StringUtil::BLANK;
83 mEmittedEmitter = StringUtil::BLANK;
84 mEmitted = false;
86 //-----------------------------------------------------------------------
87 ParticleEmitter::~ParticleEmitter()
90 //-----------------------------------------------------------------------
91 void ParticleEmitter::setPosition(const Vector3& pos)
93 mPosition = pos;
95 //-----------------------------------------------------------------------
96 const Vector3& ParticleEmitter::getPosition(void) const
98 return mPosition;
100 //-----------------------------------------------------------------------
101 void ParticleEmitter::setDirection(const Vector3& direction)
103 mDirection = direction;
104 mDirection.normalise();
105 // Generate an up vector (any will do)
106 mUp = mDirection.perpendicular();
107 mUp.normalise();
109 //-----------------------------------------------------------------------
110 const Vector3& ParticleEmitter::getDirection(void) const
112 return mDirection;
114 //-----------------------------------------------------------------------
115 void ParticleEmitter::setAngle(const Radian& angle)
117 // Store as radians for efficiency
118 mAngle = angle;
120 //-----------------------------------------------------------------------
121 const Radian& ParticleEmitter::getAngle(void) const
123 return mAngle;
125 //-----------------------------------------------------------------------
126 void ParticleEmitter::setParticleVelocity(Real speed)
128 mMinSpeed = mMaxSpeed = speed;
130 //-----------------------------------------------------------------------
131 void ParticleEmitter::setParticleVelocity(Real min, Real max)
133 mMinSpeed = min;
134 mMaxSpeed = max;
136 //-----------------------------------------------------------------------
137 void ParticleEmitter::setEmissionRate(Real particlesPerSecond)
139 mEmissionRate = particlesPerSecond;
141 //-----------------------------------------------------------------------
142 Real ParticleEmitter::getEmissionRate(void) const
144 return mEmissionRate;
146 //-----------------------------------------------------------------------
147 void ParticleEmitter::setTimeToLive(Real ttl)
149 mMinTTL = mMaxTTL = ttl;
151 //-----------------------------------------------------------------------
152 void ParticleEmitter::setTimeToLive(Real minTtl, Real maxTtl)
154 mMinTTL = minTtl;
155 mMaxTTL = maxTtl;
157 //-----------------------------------------------------------------------
158 void ParticleEmitter::setColour(const ColourValue& colour)
160 mColourRangeStart = mColourRangeEnd = colour;
162 //-----------------------------------------------------------------------
163 void ParticleEmitter::setColour(const ColourValue& colourStart, const ColourValue& colourEnd)
165 mColourRangeStart = colourStart;
166 mColourRangeEnd = colourEnd;
168 //-----------------------------------------------------------------------
169 const String& ParticleEmitter::getName(void) const
171 return mName;
173 //-----------------------------------------------------------------------
174 void ParticleEmitter::setName(const String& newName)
176 mName = newName;
178 //-----------------------------------------------------------------------
179 const String& ParticleEmitter::getEmittedEmitter(void) const
181 return mEmittedEmitter;
183 //-----------------------------------------------------------------------
184 void ParticleEmitter::setEmittedEmitter(const String& emittedEmitter)
186 mEmittedEmitter = emittedEmitter;
188 //-----------------------------------------------------------------------
189 bool ParticleEmitter::isEmitted(void) const
191 return mEmitted;
193 //-----------------------------------------------------------------------
194 void ParticleEmitter::setEmitted(bool emitted)
196 mEmitted = emitted;
198 //-----------------------------------------------------------------------
199 void ParticleEmitter::genEmissionDirection(Vector3& destVector)
201 if (mAngle != Radian(0))
203 // Randomise angle
204 Radian angle = Math::UnitRandom() * mAngle;
206 // Randomise direction
207 destVector = mDirection.randomDeviant(angle, mUp);
209 else
211 // Constant angle
212 destVector = mDirection;
215 // Don't normalise, we can assume that it will still be a unit vector since
216 // both direction and 'up' are.
219 //-----------------------------------------------------------------------
220 void ParticleEmitter::genEmissionVelocity(Vector3& destVector)
222 Real scalar;
223 if (mMinSpeed != mMaxSpeed)
225 scalar = mMinSpeed + (Math::UnitRandom() * (mMaxSpeed - mMinSpeed));
227 else
229 scalar = mMinSpeed;
232 destVector *= scalar;
234 //-----------------------------------------------------------------------
235 Real ParticleEmitter::genEmissionTTL(void)
237 if (mMaxTTL != mMinTTL)
239 return mMinTTL + (Math::UnitRandom() * (mMaxTTL - mMinTTL));
241 else
243 return mMinTTL;
246 //-----------------------------------------------------------------------
247 unsigned short ParticleEmitter::genConstantEmissionCount(Real timeElapsed)
249 unsigned short intRequest;
251 if (mEnabled)
253 // Keep fractions, otherwise a high frame rate will result in zero emissions!
254 mRemainder += mEmissionRate * timeElapsed;
255 intRequest = (unsigned short)mRemainder;
256 mRemainder -= intRequest;
258 // Check duration
259 if (mDurationMax)
261 mDurationRemain -= timeElapsed;
262 if (mDurationRemain <= 0)
264 // Disable, duration is out (takes effect next time)
265 setEnabled(false);
268 return intRequest;
270 else
272 // Check repeat
273 if (mRepeatDelayMax)
275 mRepeatDelayRemain -= timeElapsed;
276 if (mRepeatDelayRemain <= 0)
278 // Enable, repeat delay is out (takes effect next time)
279 setEnabled(true);
282 if(mStartTime)
284 mStartTime -= timeElapsed;
285 if(mStartTime <= 0)
287 setEnabled(true);
288 mStartTime = 0;
291 return 0;
295 //-----------------------------------------------------------------------
296 void ParticleEmitter::genEmissionColour(ColourValue& destColour)
298 if (mColourRangeStart != mColourRangeEnd)
300 // Randomise
301 //Real t = Math::UnitRandom();
302 destColour.r = mColourRangeStart.r + (Math::UnitRandom() * (mColourRangeEnd.r - mColourRangeStart.r));
303 destColour.g = mColourRangeStart.g + (Math::UnitRandom() * (mColourRangeEnd.g - mColourRangeStart.g));
304 destColour.b = mColourRangeStart.b + (Math::UnitRandom() * (mColourRangeEnd.b - mColourRangeStart.b));
305 destColour.a = mColourRangeStart.a + (Math::UnitRandom() * (mColourRangeEnd.a - mColourRangeStart.a));
307 else
309 destColour = mColourRangeStart;
312 //-----------------------------------------------------------------------
313 void ParticleEmitter::addBaseParameters(void)
315 ParamDictionary* dict = getParamDictionary();
317 dict->addParameter(ParameterDef("angle",
318 "The angle up to which particles may vary in their initial direction "
319 "from the emitters direction, in degrees." , PT_REAL),
320 &msAngleCmd);
322 dict->addParameter(ParameterDef("colour",
323 "The colour of emitted particles.", PT_COLOURVALUE),
324 &msColourCmd);
326 dict->addParameter(ParameterDef("colour_range_start",
327 "The start of a range of colours to be assigned to emitted particles.", PT_COLOURVALUE),
328 &msColourRangeStartCmd);
330 dict->addParameter(ParameterDef("colour_range_end",
331 "The end of a range of colours to be assigned to emitted particles.", PT_COLOURVALUE),
332 &msColourRangeEndCmd);
334 dict->addParameter(ParameterDef("direction",
335 "The base direction of the emitter." , PT_VECTOR3),
336 &msDirectionCmd);
338 dict->addParameter(ParameterDef("emission_rate",
339 "The number of particles emitted per second." , PT_REAL),
340 &msEmissionRateCmd);
342 dict->addParameter(ParameterDef("position",
343 "The position of the emitter relative to the particle system center." , PT_VECTOR3),
344 &msPositionCmd);
346 dict->addParameter(ParameterDef("velocity",
347 "The initial velocity to be assigned to every particle, in world units per second." , PT_REAL),
348 &msVelocityCmd);
350 dict->addParameter(ParameterDef("velocity_min",
351 "The minimum initial velocity to be assigned to each particle." , PT_REAL),
352 &msMinVelocityCmd);
354 dict->addParameter(ParameterDef("velocity_max",
355 "The maximum initial velocity to be assigned to each particle." , PT_REAL),
356 &msMaxVelocityCmd);
358 dict->addParameter(ParameterDef("time_to_live",
359 "The lifetime of each particle in seconds." , PT_REAL),
360 &msTTLCmd);
362 dict->addParameter(ParameterDef("time_to_live_min",
363 "The minimum lifetime of each particle in seconds." , PT_REAL),
364 &msMinTTLCmd);
366 dict->addParameter(ParameterDef("time_to_live_max",
367 "The maximum lifetime of each particle in seconds." , PT_REAL),
368 &msMaxTTLCmd);
370 dict->addParameter(ParameterDef("duration",
371 "The length of time in seconds which an emitter stays enabled for." , PT_REAL),
372 &msDurationCmd);
374 dict->addParameter(ParameterDef("duration_min",
375 "The minimum length of time in seconds which an emitter stays enabled for." , PT_REAL),
376 &msMinDurationCmd);
378 dict->addParameter(ParameterDef("duration_max",
379 "The maximum length of time in seconds which an emitter stays enabled for." , PT_REAL),
380 &msMaxDurationCmd);
382 dict->addParameter(ParameterDef("repeat_delay",
383 "If set, after disabling an emitter will repeat (reenable) after this many seconds." , PT_REAL),
384 &msRepeatDelayCmd);
386 dict->addParameter(ParameterDef("repeat_delay_min",
387 "If set, after disabling an emitter will repeat (reenable) after this minimum number of seconds." , PT_REAL),
388 &msMinRepeatDelayCmd);
390 dict->addParameter(ParameterDef("repeat_delay_max",
391 "If set, after disabling an emitter will repeat (reenable) after this maximum number of seconds." , PT_REAL),
392 &msMaxRepeatDelayCmd);
394 dict->addParameter(ParameterDef("name",
395 "This is the name of the emitter" , PT_STRING),
396 &msNameCmd);
398 dict->addParameter(ParameterDef("emit_emitter",
399 "If set, this emitter will emit other emitters instead of visual particles" , PT_STRING),
400 &msEmittedEmitterCmd);
402 //-----------------------------------------------------------------------
403 Real ParticleEmitter::getParticleVelocity(void) const
405 return mMinSpeed;
407 //-----------------------------------------------------------------------
408 Real ParticleEmitter::getMinParticleVelocity(void) const
410 return mMinSpeed;
412 //-----------------------------------------------------------------------
413 Real ParticleEmitter::getMaxParticleVelocity(void) const
415 return mMaxSpeed;
417 //-----------------------------------------------------------------------
418 void ParticleEmitter::setMinParticleVelocity(Real min)
420 mMinSpeed = min;
422 //-----------------------------------------------------------------------
423 void ParticleEmitter::setMaxParticleVelocity(Real max)
425 mMaxSpeed = max;
427 //-----------------------------------------------------------------------
428 Real ParticleEmitter::getTimeToLive(void) const
430 return mMinTTL;
432 //-----------------------------------------------------------------------
433 Real ParticleEmitter::getMinTimeToLive(void) const
435 return mMinTTL;
437 //-----------------------------------------------------------------------
438 Real ParticleEmitter::getMaxTimeToLive(void) const
440 return mMaxTTL;
442 //-----------------------------------------------------------------------
443 void ParticleEmitter::setMinTimeToLive(Real min)
445 mMinTTL = min;
447 //-----------------------------------------------------------------------
448 void ParticleEmitter::setMaxTimeToLive(Real max)
450 mMaxTTL = max;
452 //-----------------------------------------------------------------------
453 const ColourValue& ParticleEmitter::getColour(void) const
455 return mColourRangeStart;
457 //-----------------------------------------------------------------------
458 const ColourValue& ParticleEmitter::getColourRangeStart(void) const
460 return mColourRangeStart;
462 //-----------------------------------------------------------------------
463 const ColourValue& ParticleEmitter::getColourRangeEnd(void) const
465 return mColourRangeEnd;
467 //-----------------------------------------------------------------------
468 void ParticleEmitter::setColourRangeStart(const ColourValue& val)
470 mColourRangeStart = val;
472 //-----------------------------------------------------------------------
473 void ParticleEmitter::setColourRangeEnd(const ColourValue& val )
475 mColourRangeEnd = val;
477 //-----------------------------------------------------------------------
478 void ParticleEmitter::setEnabled(bool enabled)
480 mEnabled = enabled;
481 // Reset duration & repeat
482 initDurationRepeat();
484 //-----------------------------------------------------------------------
485 bool ParticleEmitter::getEnabled(void) const
487 return mEnabled;
489 //-----------------------------------------------------------------------
490 void ParticleEmitter::setStartTime(Real startTime)
492 setEnabled(false);
493 mStartTime = startTime;
495 //-----------------------------------------------------------------------
496 Real ParticleEmitter::getStartTime(void) const
498 return mStartTime;
500 //-----------------------------------------------------------------------
501 void ParticleEmitter::setDuration(Real duration)
503 setDuration(duration, duration);
505 //-----------------------------------------------------------------------
506 Real ParticleEmitter::getDuration(void) const
508 return mDurationMin;
510 //-----------------------------------------------------------------------
511 void ParticleEmitter::setDuration(Real min, Real max)
513 mDurationMin = min;
514 mDurationMax = max;
515 initDurationRepeat();
517 //-----------------------------------------------------------------------
518 void ParticleEmitter::setMinDuration(Real min)
520 mDurationMin = min;
521 initDurationRepeat();
523 //-----------------------------------------------------------------------
524 void ParticleEmitter::setMaxDuration(Real max)
526 mDurationMax = max;
527 initDurationRepeat();
529 //-----------------------------------------------------------------------
530 void ParticleEmitter::initDurationRepeat(void)
532 if (mEnabled)
534 if (mDurationMin == mDurationMax)
536 mDurationRemain = mDurationMin;
538 else
540 mDurationRemain = Math::RangeRandom(mDurationMin, mDurationMax);
543 else
545 // Reset repeat
546 if (mRepeatDelayMin == mRepeatDelayMax)
548 mRepeatDelayRemain = mRepeatDelayMin;
550 else
552 mRepeatDelayRemain = Math::RangeRandom(mRepeatDelayMax, mRepeatDelayMin);
557 //-----------------------------------------------------------------------
558 void ParticleEmitter::setRepeatDelay(Real delay)
560 setRepeatDelay(delay, delay);
562 //-----------------------------------------------------------------------
563 Real ParticleEmitter::getRepeatDelay(void) const
565 return mRepeatDelayMin;
567 //-----------------------------------------------------------------------
568 void ParticleEmitter::setRepeatDelay(Real min, Real max)
570 mRepeatDelayMin = min;
571 mRepeatDelayMax = max;
572 initDurationRepeat();
574 //-----------------------------------------------------------------------
575 void ParticleEmitter::setMinRepeatDelay(Real min)
577 mRepeatDelayMin = min;
578 initDurationRepeat();
580 //-----------------------------------------------------------------------
581 void ParticleEmitter::setMaxRepeatDelay(Real max)
583 mRepeatDelayMax = max;
584 initDurationRepeat();
586 //-----------------------------------------------------------------------
587 Real ParticleEmitter::getMinDuration(void) const
589 return mDurationMin;
591 //-----------------------------------------------------------------------
592 Real ParticleEmitter::getMaxDuration(void) const
594 return mDurationMax;
596 //-----------------------------------------------------------------------
597 Real ParticleEmitter::getMinRepeatDelay(void) const
599 return mRepeatDelayMin;
601 //-----------------------------------------------------------------------
602 Real ParticleEmitter::getMaxRepeatDelay(void) const
604 return mRepeatDelayMax;
607 //-----------------------------------------------------------------------
608 ParticleEmitterFactory::~ParticleEmitterFactory()
610 // Destroy all emitters
611 vector<ParticleEmitter*>::type::iterator i;
612 for (i = mEmitters.begin(); i != mEmitters.end(); ++i)
614 OGRE_DELETE (*i);
617 mEmitters.clear();
620 //-----------------------------------------------------------------------
621 void ParticleEmitterFactory::destroyEmitter(ParticleEmitter* e)
623 vector<ParticleEmitter*>::type::iterator i;
624 for (i = mEmitters.begin(); i != mEmitters.end(); ++i)
626 if ((*i) == e)
628 mEmitters.erase(i);
629 OGRE_DELETE e;
630 break;
635 //-----------------------------------------------------------------------