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
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"
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
)
72 // Reasonable defaults
74 setDirection(Vector3::UNIT_X
);
76 mMaxSpeed
= mMinSpeed
= 1;
77 mMaxTTL
= mMinTTL
= 5;
78 mPosition
= Vector3::ZERO
;
79 mColourRangeStart
= mColourRangeEnd
= ColourValue::White
;
82 mName
= StringUtil::BLANK
;
83 mEmittedEmitter
= StringUtil::BLANK
;
86 //-----------------------------------------------------------------------
87 ParticleEmitter::~ParticleEmitter()
90 //-----------------------------------------------------------------------
91 void ParticleEmitter::setPosition(const Vector3
& pos
)
95 //-----------------------------------------------------------------------
96 const Vector3
& ParticleEmitter::getPosition(void) const
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();
109 //-----------------------------------------------------------------------
110 const Vector3
& ParticleEmitter::getDirection(void) const
114 //-----------------------------------------------------------------------
115 void ParticleEmitter::setAngle(const Radian
& angle
)
117 // Store as radians for efficiency
120 //-----------------------------------------------------------------------
121 const Radian
& ParticleEmitter::getAngle(void) const
125 //-----------------------------------------------------------------------
126 void ParticleEmitter::setParticleVelocity(Real speed
)
128 mMinSpeed
= mMaxSpeed
= speed
;
130 //-----------------------------------------------------------------------
131 void ParticleEmitter::setParticleVelocity(Real min
, Real 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
)
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
173 //-----------------------------------------------------------------------
174 void ParticleEmitter::setName(const String
& 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
193 //-----------------------------------------------------------------------
194 void ParticleEmitter::setEmitted(bool emitted
)
198 //-----------------------------------------------------------------------
199 void ParticleEmitter::genEmissionDirection(Vector3
& destVector
)
201 if (mAngle
!= Radian(0))
204 Radian angle
= Math::UnitRandom() * mAngle
;
206 // Randomise direction
207 destVector
= mDirection
.randomDeviant(angle
, mUp
);
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
)
223 if (mMinSpeed
!= mMaxSpeed
)
225 scalar
= mMinSpeed
+ (Math::UnitRandom() * (mMaxSpeed
- mMinSpeed
));
232 destVector
*= scalar
;
234 //-----------------------------------------------------------------------
235 Real
ParticleEmitter::genEmissionTTL(void)
237 if (mMaxTTL
!= mMinTTL
)
239 return mMinTTL
+ (Math::UnitRandom() * (mMaxTTL
- mMinTTL
));
246 //-----------------------------------------------------------------------
247 unsigned short ParticleEmitter::genConstantEmissionCount(Real timeElapsed
)
249 unsigned short intRequest
;
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
;
261 mDurationRemain
-= timeElapsed
;
262 if (mDurationRemain
<= 0)
264 // Disable, duration is out (takes effect next time)
275 mRepeatDelayRemain
-= timeElapsed
;
276 if (mRepeatDelayRemain
<= 0)
278 // Enable, repeat delay is out (takes effect next time)
284 mStartTime
-= timeElapsed
;
295 //-----------------------------------------------------------------------
296 void ParticleEmitter::genEmissionColour(ColourValue
& destColour
)
298 if (mColourRangeStart
!= mColourRangeEnd
)
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
));
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
),
322 dict
->addParameter(ParameterDef("colour",
323 "The colour of emitted particles.", PT_COLOURVALUE
),
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
),
338 dict
->addParameter(ParameterDef("emission_rate",
339 "The number of particles emitted per second." , PT_REAL
),
342 dict
->addParameter(ParameterDef("position",
343 "The position of the emitter relative to the particle system center." , PT_VECTOR3
),
346 dict
->addParameter(ParameterDef("velocity",
347 "The initial velocity to be assigned to every particle, in world units per second." , PT_REAL
),
350 dict
->addParameter(ParameterDef("velocity_min",
351 "The minimum initial velocity to be assigned to each particle." , PT_REAL
),
354 dict
->addParameter(ParameterDef("velocity_max",
355 "The maximum initial velocity to be assigned to each particle." , PT_REAL
),
358 dict
->addParameter(ParameterDef("time_to_live",
359 "The lifetime of each particle in seconds." , PT_REAL
),
362 dict
->addParameter(ParameterDef("time_to_live_min",
363 "The minimum lifetime of each particle in seconds." , PT_REAL
),
366 dict
->addParameter(ParameterDef("time_to_live_max",
367 "The maximum lifetime of each particle in seconds." , PT_REAL
),
370 dict
->addParameter(ParameterDef("duration",
371 "The length of time in seconds which an emitter stays enabled for." , PT_REAL
),
374 dict
->addParameter(ParameterDef("duration_min",
375 "The minimum length of time in seconds which an emitter stays enabled for." , PT_REAL
),
378 dict
->addParameter(ParameterDef("duration_max",
379 "The maximum length of time in seconds which an emitter stays enabled for." , PT_REAL
),
382 dict
->addParameter(ParameterDef("repeat_delay",
383 "If set, after disabling an emitter will repeat (reenable) after this many seconds." , PT_REAL
),
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
),
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
407 //-----------------------------------------------------------------------
408 Real
ParticleEmitter::getMinParticleVelocity(void) const
412 //-----------------------------------------------------------------------
413 Real
ParticleEmitter::getMaxParticleVelocity(void) const
417 //-----------------------------------------------------------------------
418 void ParticleEmitter::setMinParticleVelocity(Real min
)
422 //-----------------------------------------------------------------------
423 void ParticleEmitter::setMaxParticleVelocity(Real max
)
427 //-----------------------------------------------------------------------
428 Real
ParticleEmitter::getTimeToLive(void) const
432 //-----------------------------------------------------------------------
433 Real
ParticleEmitter::getMinTimeToLive(void) const
437 //-----------------------------------------------------------------------
438 Real
ParticleEmitter::getMaxTimeToLive(void) const
442 //-----------------------------------------------------------------------
443 void ParticleEmitter::setMinTimeToLive(Real min
)
447 //-----------------------------------------------------------------------
448 void ParticleEmitter::setMaxTimeToLive(Real 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
)
481 // Reset duration & repeat
482 initDurationRepeat();
484 //-----------------------------------------------------------------------
485 bool ParticleEmitter::getEnabled(void) const
489 //-----------------------------------------------------------------------
490 void ParticleEmitter::setStartTime(Real startTime
)
493 mStartTime
= startTime
;
495 //-----------------------------------------------------------------------
496 Real
ParticleEmitter::getStartTime(void) const
500 //-----------------------------------------------------------------------
501 void ParticleEmitter::setDuration(Real duration
)
503 setDuration(duration
, duration
);
505 //-----------------------------------------------------------------------
506 Real
ParticleEmitter::getDuration(void) const
510 //-----------------------------------------------------------------------
511 void ParticleEmitter::setDuration(Real min
, Real max
)
515 initDurationRepeat();
517 //-----------------------------------------------------------------------
518 void ParticleEmitter::setMinDuration(Real min
)
521 initDurationRepeat();
523 //-----------------------------------------------------------------------
524 void ParticleEmitter::setMaxDuration(Real max
)
527 initDurationRepeat();
529 //-----------------------------------------------------------------------
530 void ParticleEmitter::initDurationRepeat(void)
534 if (mDurationMin
== mDurationMax
)
536 mDurationRemain
= mDurationMin
;
540 mDurationRemain
= Math::RangeRandom(mDurationMin
, mDurationMax
);
546 if (mRepeatDelayMin
== mRepeatDelayMax
)
548 mRepeatDelayRemain
= mRepeatDelayMin
;
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
591 //-----------------------------------------------------------------------
592 Real
ParticleEmitter::getMaxDuration(void) const
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
)
620 //-----------------------------------------------------------------------
621 void ParticleEmitterFactory::destroyEmitter(ParticleEmitter
* e
)
623 vector
<ParticleEmitter
*>::type::iterator i
;
624 for (i
= mEmitters
.begin(); i
!= mEmitters
.end(); ++i
)
635 //-----------------------------------------------------------------------