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/
6 
7 Copyright (c) 2000-2014 Torus Knot Software Ltd
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15 
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -----------------------------------------------------------------------------
27 */
28 #include "OgreStableHeaders.h"
29 
30 #include "OgreParticleEmitter.h"
31 #include "OgreParticleEmitterFactory.h"
32 
33 namespace Ogre
34 {
35     // Define static members
36     EmitterCommands::CmdAngle ParticleEmitter::msAngleCmd;
37     EmitterCommands::CmdColour ParticleEmitter::msColourCmd;
38     EmitterCommands::CmdColourRangeStart ParticleEmitter::msColourRangeStartCmd;
39     EmitterCommands::CmdColourRangeEnd ParticleEmitter::msColourRangeEndCmd;
40     EmitterCommands::CmdDirection ParticleEmitter::msDirectionCmd;
41     EmitterCommands::CmdUp ParticleEmitter::msUpCmd;
42     EmitterCommands::CmdDirPositionRef ParticleEmitter::msDirPositionRefCmd;
43     EmitterCommands::CmdEmissionRate ParticleEmitter::msEmissionRateCmd;
44     EmitterCommands::CmdMaxTTL ParticleEmitter::msMaxTTLCmd;
45     EmitterCommands::CmdMaxVelocity ParticleEmitter::msMaxVelocityCmd;
46     EmitterCommands::CmdMinTTL ParticleEmitter::msMinTTLCmd;
47     EmitterCommands::CmdMinVelocity ParticleEmitter::msMinVelocityCmd;
48     EmitterCommands::CmdPosition ParticleEmitter::msPositionCmd;
49     EmitterCommands::CmdTTL ParticleEmitter::msTTLCmd;
50     EmitterCommands::CmdVelocity ParticleEmitter::msVelocityCmd;
51     EmitterCommands::CmdDuration ParticleEmitter::msDurationCmd;
52     EmitterCommands::CmdMinDuration ParticleEmitter::msMinDurationCmd;
53     EmitterCommands::CmdMaxDuration ParticleEmitter::msMaxDurationCmd;
54     EmitterCommands::CmdRepeatDelay ParticleEmitter::msRepeatDelayCmd;
55     EmitterCommands::CmdMinRepeatDelay ParticleEmitter::msMinRepeatDelayCmd;
56     EmitterCommands::CmdMaxRepeatDelay ParticleEmitter::msMaxRepeatDelayCmd;
57     EmitterCommands::CmdName ParticleEmitter::msNameCmd;
58     EmitterCommands::CmdEmittedEmitter ParticleEmitter::msEmittedEmitterCmd;
59 
60 
61     //-----------------------------------------------------------------------
ParticleEmitter(ParticleSystem * psys)62     ParticleEmitter::ParticleEmitter(ParticleSystem* psys)
63       : mParent(psys),
64         mUseDirPositionRef(false),
65         mDirPositionRef(Vector3::ZERO),
66         mStartTime(0),
67         mDurationMin(0),
68         mDurationMax(0),
69         mDurationRemain(0),
70         mRepeatDelayMin(0),
71         mRepeatDelayMax(0),
72         mRepeatDelayRemain(0)
73     {
74 
75         // Reasonable defaults
76         mAngle = 0;
77         setDirection(Vector3::UNIT_X);
78         mEmissionRate = 10;
79         mMaxSpeed = mMinSpeed = 1;
80         mMaxTTL = mMinTTL = 5;
81         mPosition = Vector3::ZERO;
82         mColourRangeStart = mColourRangeEnd = ColourValue::White;
83         mEnabled = true;
84         mRemainder = 0;
85         mName = BLANKSTRING;
86         mEmittedEmitter = BLANKSTRING;
87         mEmitted = false;
88     }
89     //-----------------------------------------------------------------------
~ParticleEmitter()90     ParticleEmitter::~ParticleEmitter()
91     {
92     }
93     //-----------------------------------------------------------------------
setPosition(const Vector3 & pos)94     void ParticleEmitter::setPosition(const Vector3& pos)
95     {
96         mPosition = pos;
97     }
98     //-----------------------------------------------------------------------
getPosition(void) const99     const Vector3& ParticleEmitter::getPosition(void) const
100     {
101         return mPosition;
102     }
103     //-----------------------------------------------------------------------
setDirection(const Vector3 & inDirection)104     void ParticleEmitter::setDirection(const Vector3& inDirection)
105     {
106         mDirection = inDirection;
107         mDirection.normalise();
108         // Generate a default up vector.
109         mUp = mDirection.perpendicular();
110         mUp.normalise();
111     }
112     //-----------------------------------------------------------------------
getDirection(void) const113     const Vector3& ParticleEmitter::getDirection(void) const
114     {
115         return mDirection;
116     }
117     //-----------------------------------------------------------------------
setUp(const Vector3 & inUp)118     void ParticleEmitter::setUp(const Vector3& inUp)
119     {
120         mUp = inUp;
121         mUp.normalise();
122     }
123     //-----------------------------------------------------------------------
getUp(void) const124     const Vector3& ParticleEmitter::getUp(void) const
125     {
126         return mUp;
127     }
128     //-----------------------------------------------------------------------
setDirPositionReference(const Vector3 & nposition,bool enable)129     void ParticleEmitter::setDirPositionReference( const Vector3& nposition, bool enable )
130     {
131     mUseDirPositionRef  = enable;
132         mDirPositionRef     = nposition;
133     }
134     //-----------------------------------------------------------------------
getDirPositionReference() const135     const Vector3& ParticleEmitter::getDirPositionReference() const
136     {
137         return mDirPositionRef;
138     }
139     //-----------------------------------------------------------------------
getDirPositionReferenceEnabled() const140     bool ParticleEmitter::getDirPositionReferenceEnabled() const
141     {
142         return mUseDirPositionRef;
143     }
144     //-----------------------------------------------------------------------
setAngle(const Radian & angle)145     void ParticleEmitter::setAngle(const Radian& angle)
146     {
147         // Store as radians for efficiency
148         mAngle = angle;
149     }
150     //-----------------------------------------------------------------------
getAngle(void) const151     const Radian& ParticleEmitter::getAngle(void) const
152     {
153         return mAngle;
154     }
155     //-----------------------------------------------------------------------
setParticleVelocity(Real speed)156     void ParticleEmitter::setParticleVelocity(Real speed)
157     {
158         assert(std::isfinite(speed));
159         mMinSpeed = mMaxSpeed = speed;
160     }
161     //-----------------------------------------------------------------------
setParticleVelocity(Real min,Real max)162     void ParticleEmitter::setParticleVelocity(Real min, Real max)
163     {
164         assert(std::isfinite(min) && std::isfinite(max));
165         mMinSpeed = min;
166         mMaxSpeed = max;
167     }
168     //-----------------------------------------------------------------------
setEmissionRate(Real particlesPerSecond)169     void ParticleEmitter::setEmissionRate(Real particlesPerSecond)
170     {
171         mEmissionRate = particlesPerSecond;
172     }
173     //-----------------------------------------------------------------------
getEmissionRate(void) const174     Real ParticleEmitter::getEmissionRate(void) const
175     {
176         return mEmissionRate;
177     }
178     //-----------------------------------------------------------------------
setTimeToLive(Real ttl)179     void ParticleEmitter::setTimeToLive(Real ttl)
180     {
181         assert (ttl >= 0 && "Time to live can not be negative");
182         mMinTTL = mMaxTTL = ttl;
183     }
184     //-----------------------------------------------------------------------
setTimeToLive(Real minTtl,Real maxTtl)185     void ParticleEmitter::setTimeToLive(Real minTtl, Real maxTtl)
186     {
187         assert (minTtl >= 0 && "Time to live can not be negative");
188         assert (maxTtl >= 0 && "Time to live can not be negative");
189         mMinTTL = minTtl;
190         mMaxTTL = maxTtl;
191     }
192     //-----------------------------------------------------------------------
setColour(const ColourValue & inColour)193     void ParticleEmitter::setColour(const ColourValue& inColour)
194     {
195         mColourRangeStart = mColourRangeEnd = inColour;
196     }
197     //-----------------------------------------------------------------------
setColour(const ColourValue & colourStart,const ColourValue & colourEnd)198     void ParticleEmitter::setColour(const ColourValue& colourStart, const ColourValue& colourEnd)
199     {
200         mColourRangeStart = colourStart;
201         mColourRangeEnd = colourEnd;
202     }
203     //-----------------------------------------------------------------------
getName(void) const204     const String& ParticleEmitter::getName(void) const
205     {
206         return mName;
207     }
208     //-----------------------------------------------------------------------
setName(const String & newName)209     void ParticleEmitter::setName(const String& newName)
210     {
211         mName = newName;
212     }
213     //-----------------------------------------------------------------------
getEmittedEmitter(void) const214     const String& ParticleEmitter::getEmittedEmitter(void) const
215     {
216         return mEmittedEmitter;
217     }
218     //-----------------------------------------------------------------------
setEmittedEmitter(const String & emittedEmitter)219     void ParticleEmitter::setEmittedEmitter(const String& emittedEmitter)
220     {
221         mEmittedEmitter = emittedEmitter;
222     }
223     //-----------------------------------------------------------------------
isEmitted(void) const224     bool ParticleEmitter::isEmitted(void) const
225     {
226         return mEmitted;
227     }
228     //-----------------------------------------------------------------------
setEmitted(bool emitted)229     void ParticleEmitter::setEmitted(bool emitted)
230     {
231         mEmitted = emitted;
232     }
233     //-----------------------------------------------------------------------
genEmissionDirection(const Vector3 & particlePos,Vector3 & destVector)234     void ParticleEmitter::genEmissionDirection( const Vector3 &particlePos, Vector3& destVector )
235     {
236         if( mUseDirPositionRef )
237         {
238             Vector3 particleDir = particlePos - mDirPositionRef;
239             particleDir.normalise();
240 
241             if (mAngle != Radian(0))
242             {
243                 // Randomise angle
244                 Radian angle = Math::UnitRandom() * mAngle;
245 
246                 // Randomise direction
247                 destVector = particleDir.randomDeviant( angle );
248             }
249             else
250             {
251                 // Constant angle
252                 destVector = particleDir;
253             }
254         }
255         else
256         {
257             if (mAngle != Radian(0))
258             {
259                 // Randomise angle
260                 Radian angle = Math::UnitRandom() * mAngle;
261 
262                 // Randomise direction
263                 destVector = mDirection.randomDeviant(angle, mUp);
264             }
265             else
266             {
267                 // Constant angle
268                 destVector = mDirection;
269             }
270         }
271 
272         // Don't normalise, we can assume that it will still be a unit vector since
273         // both direction and 'up' are.
274     }
275     //-----------------------------------------------------------------------
genEmissionVelocity(Vector3 & destVector)276     void ParticleEmitter::genEmissionVelocity(Vector3& destVector)
277     {
278         Real scalar;
279         if (mMinSpeed != mMaxSpeed)
280         {
281             scalar = mMinSpeed + (Math::UnitRandom() * (mMaxSpeed - mMinSpeed));
282         }
283         else
284         {
285             scalar = mMinSpeed;
286         }
287 
288         destVector *= scalar;
289     }
290     //-----------------------------------------------------------------------
genEmissionTTL(void)291     Real ParticleEmitter::genEmissionTTL(void)
292     {
293         if (mMaxTTL != mMinTTL)
294         {
295             return mMinTTL + (Math::UnitRandom() * (mMaxTTL - mMinTTL));
296         }
297         else
298         {
299             return mMinTTL;
300         }
301     }
302     //-----------------------------------------------------------------------
genConstantEmissionCount(Real timeElapsed)303     unsigned short ParticleEmitter::genConstantEmissionCount(Real timeElapsed)
304     {
305         if (mEnabled)
306         {
307             // Keep fractions, otherwise a high frame rate will result in zero emissions!
308             mRemainder += mEmissionRate * timeElapsed;
309             unsigned short intRequest = (unsigned short)mRemainder;
310             mRemainder -= intRequest;
311 
312             // Check duration
313             if (mDurationMax)
314             {
315                 mDurationRemain -= timeElapsed;
316                 if (mDurationRemain <= 0)
317                 {
318                     // Disable, duration is out (takes effect next time)
319                     setEnabled(false);
320                 }
321             }
322             return intRequest;
323         }
324         else
325         {
326             // Check repeat
327             if (mRepeatDelayMax)
328             {
329                 mRepeatDelayRemain -= timeElapsed;
330                 if (mRepeatDelayRemain <= 0)
331                 {
332                     // Enable, repeat delay is out (takes effect next time)
333                     setEnabled(true);
334                 }
335             }
336             if(mStartTime)
337             {
338                 mStartTime -= timeElapsed;
339                 if(mStartTime <= 0)
340                 {
341                     setEnabled(true);
342                     mStartTime = 0;
343                 }
344             }
345             return 0;
346         }
347 
348     }
349     //-----------------------------------------------------------------------
genEmissionColour(ColourValue & destColour)350     void ParticleEmitter::genEmissionColour(ColourValue& destColour)
351     {
352         if (mColourRangeStart != mColourRangeEnd)
353         {
354             // Randomise
355             //Real t = Math::UnitRandom();
356             destColour.r = mColourRangeStart.r + (Math::UnitRandom() * (mColourRangeEnd.r - mColourRangeStart.r));
357             destColour.g = mColourRangeStart.g + (Math::UnitRandom() * (mColourRangeEnd.g - mColourRangeStart.g));
358             destColour.b = mColourRangeStart.b + (Math::UnitRandom() * (mColourRangeEnd.b - mColourRangeStart.b));
359             destColour.a = mColourRangeStart.a + (Math::UnitRandom() * (mColourRangeEnd.a - mColourRangeStart.a));
360         }
361         else
362         {
363             destColour = mColourRangeStart;
364         }
365     }
366     //-----------------------------------------------------------------------
addBaseParameters(void)367     void ParticleEmitter::addBaseParameters(void)
368     {
369         ParamDictionary* dict = getParamDictionary();
370 
371         dict->addParameter(ParameterDef("angle",
372             "The angle up to which particles may vary in their initial direction "
373             "from the emitters direction, in degrees." , PT_REAL),
374             &msAngleCmd);
375 
376         dict->addParameter(ParameterDef("colour",
377             "The colour of emitted particles.", PT_COLOURVALUE),
378             &msColourCmd);
379 
380         dict->addParameter(ParameterDef("colour_range_start",
381             "The start of a range of colours to be assigned to emitted particles.", PT_COLOURVALUE),
382             &msColourRangeStartCmd);
383 
384         dict->addParameter(ParameterDef("colour_range_end",
385             "The end of a range of colours to be assigned to emitted particles.", PT_COLOURVALUE),
386             &msColourRangeEndCmd);
387 
388         dict->addParameter(ParameterDef("direction",
389             "The base direction of the emitter." , PT_VECTOR3),
390             &msDirectionCmd);
391 
392         dict->addParameter(ParameterDef("up",
393             "The up vector of the emitter." , PT_VECTOR3),
394             &msUpCmd);
395 
396         dict->addParameter(ParameterDef("direction_position_reference",
397             "The reference position to calculate the direction of emitted particles "
398             "based on their position. Good for explosions and implosions (use negative velocity)" , PT_COLOURVALUE),
399             &msDirPositionRefCmd);
400 
401         dict->addParameter(ParameterDef("emission_rate",
402             "The number of particles emitted per second." , PT_REAL),
403             &msEmissionRateCmd);
404 
405         dict->addParameter(ParameterDef("position",
406             "The position of the emitter relative to the particle system center." , PT_VECTOR3),
407             &msPositionCmd);
408 
409         dict->addParameter(ParameterDef("velocity",
410             "The initial velocity to be assigned to every particle, in world units per second." , PT_REAL),
411             &msVelocityCmd);
412 
413         dict->addParameter(ParameterDef("velocity_min",
414             "The minimum initial velocity to be assigned to each particle." , PT_REAL),
415             &msMinVelocityCmd);
416 
417         dict->addParameter(ParameterDef("velocity_max",
418             "The maximum initial velocity to be assigned to each particle." , PT_REAL),
419             &msMaxVelocityCmd);
420 
421         dict->addParameter(ParameterDef("time_to_live",
422             "The lifetime of each particle in seconds." , PT_REAL),
423             &msTTLCmd);
424 
425         dict->addParameter(ParameterDef("time_to_live_min",
426             "The minimum lifetime of each particle in seconds." , PT_REAL),
427             &msMinTTLCmd);
428 
429         dict->addParameter(ParameterDef("time_to_live_max",
430             "The maximum lifetime of each particle in seconds." , PT_REAL),
431             &msMaxTTLCmd);
432 
433         dict->addParameter(ParameterDef("duration",
434             "The length of time in seconds which an emitter stays enabled for." , PT_REAL),
435             &msDurationCmd);
436 
437         dict->addParameter(ParameterDef("duration_min",
438             "The minimum length of time in seconds which an emitter stays enabled for." , PT_REAL),
439             &msMinDurationCmd);
440 
441         dict->addParameter(ParameterDef("duration_max",
442             "The maximum length of time in seconds which an emitter stays enabled for." , PT_REAL),
443             &msMaxDurationCmd);
444 
445         dict->addParameter(ParameterDef("repeat_delay",
446             "If set, after disabling an emitter will repeat (reenable) after this many seconds." , PT_REAL),
447             &msRepeatDelayCmd);
448 
449         dict->addParameter(ParameterDef("repeat_delay_min",
450             "If set, after disabling an emitter will repeat (reenable) after this minimum number of seconds." , PT_REAL),
451             &msMinRepeatDelayCmd);
452 
453         dict->addParameter(ParameterDef("repeat_delay_max",
454             "If set, after disabling an emitter will repeat (reenable) after this maximum number of seconds." , PT_REAL),
455             &msMaxRepeatDelayCmd);
456 
457         dict->addParameter(ParameterDef("name",
458             "This is the name of the emitter" , PT_STRING),
459             &msNameCmd);
460 
461         dict->addParameter(ParameterDef("emit_emitter",
462             "If set, this emitter will emit other emitters instead of visual particles" , PT_STRING),
463             &msEmittedEmitterCmd);
464     }
465     //-----------------------------------------------------------------------
getParticleVelocity(void) const466     Real ParticleEmitter::getParticleVelocity(void) const
467     {
468         return mMinSpeed;
469     }
470     //-----------------------------------------------------------------------
getMinParticleVelocity(void) const471     Real ParticleEmitter::getMinParticleVelocity(void) const
472     {
473         return mMinSpeed;
474     }
475     //-----------------------------------------------------------------------
getMaxParticleVelocity(void) const476     Real ParticleEmitter::getMaxParticleVelocity(void) const
477     {
478         return mMaxSpeed;
479     }
480     //-----------------------------------------------------------------------
setMinParticleVelocity(Real min)481     void ParticleEmitter::setMinParticleVelocity(Real min)
482     {
483         assert(std::isfinite(min));
484         mMinSpeed = min;
485     }
486     //-----------------------------------------------------------------------
setMaxParticleVelocity(Real max)487     void ParticleEmitter::setMaxParticleVelocity(Real max)
488     {
489         assert(std::isfinite(max));
490         mMaxSpeed = max;
491     }
492     //-----------------------------------------------------------------------
getTimeToLive(void) const493     Real ParticleEmitter::getTimeToLive(void) const
494     {
495         return mMinTTL;
496     }
497     //-----------------------------------------------------------------------
getMinTimeToLive(void) const498     Real ParticleEmitter::getMinTimeToLive(void) const
499     {
500         return mMinTTL;
501     }
502     //-----------------------------------------------------------------------
getMaxTimeToLive(void) const503     Real ParticleEmitter::getMaxTimeToLive(void) const
504     {
505         return mMaxTTL;
506     }
507     //-----------------------------------------------------------------------
setMinTimeToLive(Real min)508     void ParticleEmitter::setMinTimeToLive(Real min)
509     {
510         mMinTTL = min;
511     }
512     //-----------------------------------------------------------------------
setMaxTimeToLive(Real max)513     void ParticleEmitter::setMaxTimeToLive(Real max)
514     {
515         mMaxTTL = max;
516     }
517     //-----------------------------------------------------------------------
getColour(void) const518     const ColourValue& ParticleEmitter::getColour(void) const
519     {
520         return mColourRangeStart;
521     }
522     //-----------------------------------------------------------------------
getColourRangeStart(void) const523     const ColourValue& ParticleEmitter::getColourRangeStart(void) const
524     {
525         return mColourRangeStart;
526     }
527     //-----------------------------------------------------------------------
getColourRangeEnd(void) const528     const ColourValue& ParticleEmitter::getColourRangeEnd(void) const
529     {
530         return mColourRangeEnd;
531     }
532     //-----------------------------------------------------------------------
setColourRangeStart(const ColourValue & val)533     void ParticleEmitter::setColourRangeStart(const ColourValue& val)
534     {
535         mColourRangeStart = val;
536     }
537     //-----------------------------------------------------------------------
setColourRangeEnd(const ColourValue & val)538     void ParticleEmitter::setColourRangeEnd(const ColourValue& val )
539     {
540         mColourRangeEnd = val;
541     }
542     //-----------------------------------------------------------------------
setEnabled(bool enabled)543     void ParticleEmitter::setEnabled(bool enabled)
544     {
545         mEnabled = enabled;
546         // Reset duration & repeat
547         initDurationRepeat();
548     }
549     //-----------------------------------------------------------------------
getEnabled(void) const550     bool ParticleEmitter::getEnabled(void) const
551     {
552         return mEnabled;
553     }
554     //-----------------------------------------------------------------------
setStartTime(Real startTime)555     void ParticleEmitter::setStartTime(Real startTime)
556     {
557         setEnabled(false);
558         mStartTime = startTime;
559     }
560     //-----------------------------------------------------------------------
getStartTime(void) const561     Real ParticleEmitter::getStartTime(void) const
562     {
563         return mStartTime;
564     }
565     //-----------------------------------------------------------------------
setDuration(Real duration)566     void ParticleEmitter::setDuration(Real duration)
567     {
568         setDuration(duration, duration);
569     }
570     //-----------------------------------------------------------------------
getDuration(void) const571     Real ParticleEmitter::getDuration(void) const
572     {
573         return mDurationMin;
574     }
575     //-----------------------------------------------------------------------
setDuration(Real min,Real max)576     void ParticleEmitter::setDuration(Real min, Real max)
577     {
578         mDurationMin = min;
579         mDurationMax = max;
580         initDurationRepeat();
581     }
582     //-----------------------------------------------------------------------
setMinDuration(Real min)583     void ParticleEmitter::setMinDuration(Real min)
584     {
585         mDurationMin = min;
586         initDurationRepeat();
587     }
588     //-----------------------------------------------------------------------
setMaxDuration(Real max)589     void ParticleEmitter::setMaxDuration(Real max)
590     {
591         mDurationMax = max;
592         initDurationRepeat();
593     }
594     //-----------------------------------------------------------------------
initDurationRepeat(void)595     void ParticleEmitter::initDurationRepeat(void)
596     {
597         if (mEnabled)
598         {
599             if (mDurationMin == mDurationMax)
600             {
601                 mDurationRemain = mDurationMin;
602             }
603             else
604             {
605                 mDurationRemain = Math::RangeRandom(mDurationMin, mDurationMax);
606             }
607         }
608         else
609         {
610             // Reset repeat
611             if (mRepeatDelayMin == mRepeatDelayMax)
612             {
613                 mRepeatDelayRemain = mRepeatDelayMin;
614             }
615             else
616             {
617                 mRepeatDelayRemain = Math::RangeRandom(mRepeatDelayMax, mRepeatDelayMin);
618             }
619 
620         }
621     }
622     //-----------------------------------------------------------------------
setRepeatDelay(Real delay)623     void ParticleEmitter::setRepeatDelay(Real delay)
624     {
625         setRepeatDelay(delay, delay);
626     }
627     //-----------------------------------------------------------------------
getRepeatDelay(void) const628     Real ParticleEmitter::getRepeatDelay(void) const
629     {
630         return mRepeatDelayMin;
631     }
632     //-----------------------------------------------------------------------
setRepeatDelay(Real min,Real max)633     void ParticleEmitter::setRepeatDelay(Real min, Real max)
634     {
635         mRepeatDelayMin = min;
636         mRepeatDelayMax = max;
637         initDurationRepeat();
638     }
639     //-----------------------------------------------------------------------
setMinRepeatDelay(Real min)640     void ParticleEmitter::setMinRepeatDelay(Real min)
641     {
642         mRepeatDelayMin = min;
643         initDurationRepeat();
644     }
645     //-----------------------------------------------------------------------
setMaxRepeatDelay(Real max)646     void ParticleEmitter::setMaxRepeatDelay(Real max)
647     {
648         mRepeatDelayMax = max;
649         initDurationRepeat();
650     }
651     //-----------------------------------------------------------------------
getMinDuration(void) const652     Real ParticleEmitter::getMinDuration(void) const
653     {
654         return mDurationMin;
655     }
656     //-----------------------------------------------------------------------
getMaxDuration(void) const657     Real ParticleEmitter::getMaxDuration(void) const
658     {
659         return mDurationMax;
660     }
661     //-----------------------------------------------------------------------
getMinRepeatDelay(void) const662     Real ParticleEmitter::getMinRepeatDelay(void) const
663     {
664         return mRepeatDelayMin;
665     }
666     //-----------------------------------------------------------------------
getMaxRepeatDelay(void) const667     Real ParticleEmitter::getMaxRepeatDelay(void) const
668     {
669         return mRepeatDelayMax;
670     }
671 
672     //-----------------------------------------------------------------------
~ParticleEmitterFactory()673     ParticleEmitterFactory::~ParticleEmitterFactory()
674     {
675         // Destroy all emitters
676         std::vector<ParticleEmitter*>::iterator i;
677         for (i = mEmitters.begin(); i != mEmitters.end(); ++i)
678         {
679             OGRE_DELETE (*i);
680         }
681 
682         mEmitters.clear();
683 
684     }
685     //-----------------------------------------------------------------------
destroyEmitter(ParticleEmitter * e)686     void ParticleEmitterFactory::destroyEmitter(ParticleEmitter* e)
687     {
688         std::vector<ParticleEmitter*>::iterator i;
689         for (i = mEmitters.begin(); i != mEmitters.end(); ++i)
690         {
691             if ((*i) == e)
692             {
693                 mEmitters.erase(i);
694                 OGRE_DELETE e;
695                 break;
696             }
697         }
698     }
699 
700     //-----------------------------------------------------------------------
701 
702 }
703 
704