Coverage Report

Created: 2026-09-01 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ogre/OgreMain/src/OgreParticleEmitter.cpp
Line
Count
Source
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
#include "OgreParticleEmitterCommands.h"
33
34
namespace Ogre
35
{
36
    // Command object for setting / getting parameters
37
    static EmitterCommands::CmdAngle msAngleCmd;
38
    static EmitterCommands::CmdColour msColourCmd;
39
    static EmitterCommands::CmdColourRangeStart msColourRangeStartCmd;
40
    static EmitterCommands::CmdColourRangeEnd msColourRangeEndCmd;
41
    static EmitterCommands::CmdDirection msDirectionCmd;
42
    static EmitterCommands::CmdUp msUpCmd;
43
    static EmitterCommands::CmdDirPositionRef msDirPositionRefCmd;
44
    static EmitterCommands::CmdEmissionRate msEmissionRateCmd;
45
    static EmitterCommands::CmdMaxTTL msMaxTTLCmd;
46
    static EmitterCommands::CmdMaxVelocity msMaxVelocityCmd;
47
    static EmitterCommands::CmdMinTTL msMinTTLCmd;
48
    static EmitterCommands::CmdMinVelocity msMinVelocityCmd;
49
    static EmitterCommands::CmdPosition msPositionCmd;
50
    static EmitterCommands::CmdTTL msTTLCmd;
51
    static EmitterCommands::CmdVelocity msVelocityCmd;
52
    static EmitterCommands::CmdDuration msDurationCmd;
53
    static EmitterCommands::CmdMinDuration msMinDurationCmd;
54
    static EmitterCommands::CmdMaxDuration msMaxDurationCmd;
55
    static EmitterCommands::CmdRepeatDelay msRepeatDelayCmd;
56
    static EmitterCommands::CmdMinRepeatDelay msMinRepeatDelayCmd;
57
    static EmitterCommands::CmdMaxRepeatDelay msMaxRepeatDelayCmd;
58
    static EmitterCommands::CmdName msNameCmd;
59
    static EmitterCommands::CmdEmittedEmitter msEmittedEmitterCmd;
60
61
62
    //-----------------------------------------------------------------------
63
    ParticleEmitter::ParticleEmitter(ParticleSystem* psys)
64
0
      : mParent(psys),
65
0
        mUseDirPositionRef(false),
66
0
        mDirPositionRef(Vector3::ZERO),
67
0
        mStartTime(0),
68
0
        mDurationMin(0),
69
0
        mDurationMax(0),
70
0
        mDurationRemain(0),
71
0
        mRepeatDelayMin(0),
72
0
        mRepeatDelayMax(0),
73
0
        mRepeatDelayRemain(0)
74
0
    {
75
76
        // Reasonable defaults
77
0
        mAngle = 0;
78
0
        setDirection(Vector3::UNIT_X);
79
0
        mEmissionRate = 10;
80
0
        mMaxSpeed = mMinSpeed = 1;
81
0
        mMaxTTL = mMinTTL = 5;
82
0
        mPosition = Vector3::ZERO;
83
0
        mColourRangeStart = mColourRangeEnd = ColourValue::White;
84
0
        mEnabled = true;
85
0
        mRemainder = 0;
86
0
        mName = BLANKSTRING;
87
0
        mEmittedEmitter = BLANKSTRING;
88
0
        mEmitted = false;
89
0
    }
90
    //-----------------------------------------------------------------------
91
    ParticleEmitter::~ParticleEmitter() 
92
0
    {
93
0
    }
94
    //-----------------------------------------------------------------------
95
    void ParticleEmitter::setPosition(const Vector3& pos) 
96
0
    { 
97
0
        mPosition = pos; 
98
0
    }
99
    //-----------------------------------------------------------------------
100
    const Vector3& ParticleEmitter::getPosition(void) const 
101
0
    { 
102
0
        return mPosition; 
103
0
    }
104
    //-----------------------------------------------------------------------
105
    void ParticleEmitter::setDirection(const Vector3& inDirection) 
106
0
    { 
107
0
        mDirection = inDirection; 
108
0
        mDirection.normalise();
109
        // Generate a default up vector.
110
0
        mUp = mDirection.perpendicular();
111
0
        mUp.normalise();
112
0
    }
113
    //-----------------------------------------------------------------------
114
    const Vector3& ParticleEmitter::getDirection(void) const
115
0
    { 
116
0
        return mDirection; 
117
0
    }
118
    //-----------------------------------------------------------------------
119
    void ParticleEmitter::setUp(const Vector3& inUp) 
120
0
    {
121
0
        mUp = inUp; 
122
0
        mUp.normalise();
123
0
    }
124
    //-----------------------------------------------------------------------
125
    const Vector3& ParticleEmitter::getUp(void) const
126
0
    { 
127
0
        return mUp; 
128
0
    }
129
    //-----------------------------------------------------------------------
130
    void ParticleEmitter::setDirPositionReference( const Vector3& nposition, bool enable )
131
0
    { 
132
0
    mUseDirPositionRef  = enable;
133
0
        mDirPositionRef     = nposition;
134
0
    }
135
    //-----------------------------------------------------------------------
136
    const Vector3& ParticleEmitter::getDirPositionReference() const
137
0
    {
138
0
        return mDirPositionRef;
139
0
    }
140
    //-----------------------------------------------------------------------
141
    bool ParticleEmitter::getDirPositionReferenceEnabled() const
142
0
    {
143
0
        return mUseDirPositionRef;
144
0
    }
145
    //-----------------------------------------------------------------------
146
    void ParticleEmitter::setAngle(const Radian& angle)
147
0
    {
148
        // Store as radians for efficiency
149
0
        mAngle = angle;
150
0
    }
151
    //-----------------------------------------------------------------------
152
    const Radian& ParticleEmitter::getAngle(void) const
153
0
    {
154
0
        return mAngle;
155
0
    }
156
    //-----------------------------------------------------------------------
157
    void ParticleEmitter::setParticleVelocity(Real speed)
158
0
    {
159
0
        assert(std::isfinite(speed));
160
0
        mMinSpeed = mMaxSpeed = speed;
161
0
    }
162
    //-----------------------------------------------------------------------
163
    void ParticleEmitter::setParticleVelocity(Real min, Real max)
164
0
    {
165
0
        assert(std::isfinite(min) && std::isfinite(max));
166
0
        mMinSpeed = min;
167
0
        mMaxSpeed = max;
168
0
    }
169
    //-----------------------------------------------------------------------
170
    void ParticleEmitter::setEmissionRate(Real particlesPerSecond) 
171
0
    { 
172
0
        mEmissionRate = particlesPerSecond; 
173
0
    }
174
    //-----------------------------------------------------------------------
175
    Real ParticleEmitter::getEmissionRate(void) const 
176
0
    { 
177
0
        return mEmissionRate; 
178
0
    }
179
    //-----------------------------------------------------------------------
180
    void ParticleEmitter::setTimeToLive(Real ttl)
181
0
    {
182
0
        assert (ttl >= 0 && "Time to live can not be negative");
183
0
        mMinTTL = mMaxTTL = ttl;
184
0
    }
185
    //-----------------------------------------------------------------------
186
    void ParticleEmitter::setTimeToLive(Real minTtl, Real maxTtl)
187
0
    {
188
0
        assert (minTtl >= 0 && "Time to live can not be negative");
189
0
        assert (maxTtl >= 0 && "Time to live can not be negative");
190
0
        mMinTTL = minTtl;
191
0
        mMaxTTL = maxTtl;
192
0
    }
193
    //-----------------------------------------------------------------------
194
    void ParticleEmitter::setColour(const ColourValue& inColour)
195
0
    {
196
0
        mColourRangeStart = mColourRangeEnd = inColour;
197
0
    }
198
    //-----------------------------------------------------------------------
199
    void ParticleEmitter::setColour(const ColourValue& colourStart, const ColourValue& colourEnd)
200
0
    {
201
0
        mColourRangeStart = colourStart;
202
0
        mColourRangeEnd = colourEnd;
203
0
    }
204
    //-----------------------------------------------------------------------
205
    const String& ParticleEmitter::getName(void) const
206
0
    {
207
0
        return mName;
208
0
    }
209
    //-----------------------------------------------------------------------
210
    void ParticleEmitter::setName(const String& newName)
211
0
    {
212
0
        mName = newName;
213
0
    }
214
    //-----------------------------------------------------------------------
215
    const String& ParticleEmitter::getEmittedEmitter(void) const
216
0
    {
217
0
        return mEmittedEmitter;
218
0
    }
219
    //-----------------------------------------------------------------------
220
    void ParticleEmitter::setEmittedEmitter(const String& emittedEmitter)
221
0
    {
222
0
        mEmittedEmitter = emittedEmitter;
223
0
    }
224
    //-----------------------------------------------------------------------
225
    bool ParticleEmitter::isEmitted(void) const
226
0
    {
227
0
        return mEmitted;
228
0
    }
229
    //-----------------------------------------------------------------------
230
    void ParticleEmitter::setEmitted(bool emitted)
231
0
    {
232
0
        mEmitted = emitted;
233
0
    }
234
    //-----------------------------------------------------------------------
235
    static float sampleSphereUniform(const float& maxAngle)
236
0
    {
237
0
        float cosMax = -std::cos(maxAngle) + 1; // for maxAngle = pi, cosMax = 2
238
        // see https://corysimon.github.io/articles/uniformdistn-on-sphere/
239
0
        return std::acos(1 - cosMax * Math::UnitRandom());
240
0
    }
241
242
    void ParticleEmitter::genEmissionDirection( const Vector3 &particlePos, Vector3& destVector )
243
0
    {
244
0
        if( mUseDirPositionRef )
245
0
        {
246
0
            Vector3 particleDir = particlePos - mDirPositionRef;
247
0
            particleDir.normalise();
248
249
0
            if (mAngle != Radian(0))
250
0
            {
251
                // Randomise angle
252
0
                Radian angle(sampleSphereUniform(mAngle.valueRadians()));
253
254
                // Randomise direction
255
0
                destVector = particleDir.randomDeviant( angle );
256
0
            }
257
0
            else
258
0
            {
259
                // Constant angle
260
0
                destVector = particleDir;
261
0
            }
262
0
        }
263
0
        else
264
0
        {
265
0
            if (mAngle != Radian(0))
266
0
            {
267
                // Randomise angle
268
0
                Radian angle(sampleSphereUniform(mAngle.valueRadians()));
269
270
                // Randomise direction
271
0
                destVector = mDirection.randomDeviant(angle, mUp);
272
0
            }
273
0
            else
274
0
            {
275
                // Constant angle
276
0
                destVector = mDirection;
277
0
            }
278
0
        }
279
280
        // Don't normalise, we can assume that it will still be a unit vector since
281
        // both direction and 'up' are.
282
0
    }
283
    //-----------------------------------------------------------------------
284
    void ParticleEmitter::genEmissionVelocity(Vector3& destVector)
285
0
    {
286
0
        Real scalar;
287
0
        if (mMinSpeed != mMaxSpeed)
288
0
        {
289
0
            scalar = Math::RangeRandom(mMinSpeed, mMaxSpeed);
290
0
        }
291
0
        else
292
0
        {
293
0
            scalar = mMinSpeed;
294
0
        }
295
296
0
        destVector *= scalar;
297
0
    }
298
    //-----------------------------------------------------------------------
299
    Real ParticleEmitter::genEmissionTTL(void)
300
0
    {
301
0
        if (mMaxTTL != mMinTTL)
302
0
        {
303
0
            return Math::RangeRandom(mMinTTL, mMaxTTL);
304
0
        }
305
0
        else
306
0
        {
307
0
            return mMinTTL;
308
0
        }
309
0
    }
310
    //-----------------------------------------------------------------------
311
    unsigned short ParticleEmitter::genConstantEmissionCount(Real timeElapsed)
312
0
    {
313
0
        if (mEnabled)
314
0
        {
315
0
            if(mDurationMax < 0)
316
0
            {
317
                // single-shot burst
318
0
                setEnabled(false);
319
0
                return mEmissionRate;
320
0
            }
321
322
0
            unsigned short intRequest = (unsigned short)mRemainder;
323
0
            mRemainder -= intRequest;
324
325
            // Keep fractions, otherwise a high frame rate will result in zero emissions!
326
0
            mRemainder += mEmissionRate * timeElapsed;
327
328
            // Check duration
329
0
            if (mDurationMax)
330
0
            {
331
0
                mDurationRemain -= timeElapsed;
332
0
                if (mDurationRemain <= 0) 
333
0
                {
334
                    // Disable, duration is out (takes effect next time)
335
0
                    setEnabled(false);
336
0
                }
337
0
            }
338
0
            return intRequest;
339
0
        }
340
0
        else
341
0
        {
342
            // Check repeat
343
0
            if (mRepeatDelayMax)
344
0
            {
345
0
                mRepeatDelayRemain -= timeElapsed;
346
0
                if (mRepeatDelayRemain <= 0)
347
0
                {
348
                    // Enable, repeat delay is out (takes effect next time)
349
0
                    setEnabled(true);
350
0
                }
351
0
            }
352
0
            if(mStartTime)
353
0
            {
354
0
                mStartTime -= timeElapsed;
355
0
                if(mStartTime <= 0)
356
0
                {
357
0
                    setEnabled(true);
358
0
                    mStartTime = 0;
359
0
                }
360
0
            }
361
0
            return 0;
362
0
        }
363
364
0
    }
365
    //-----------------------------------------------------------------------
366
    void ParticleEmitter::genEmissionColour(RGBA& destColour)
367
0
    {
368
0
        if (mColourRangeStart != mColourRangeEnd)
369
0
        {
370
            // Randomise
371
0
            ColourValue t(Math::UnitRandom(), Math::UnitRandom(), Math::UnitRandom(), Math::UnitRandom());
372
0
            destColour = Math::lerp(mColourRangeStart, mColourRangeEnd, t).getAsBYTE();
373
0
        }
374
0
        else
375
0
        {
376
0
            destColour = mColourRangeStart.getAsBYTE();
377
0
        }
378
0
    }
379
    //-----------------------------------------------------------------------
380
    void ParticleEmitter::addBaseParameters(void)    
381
0
    {
382
0
        ParamDictionary* dict = getParamDictionary();
383
384
0
        dict->addParameter(ParameterDef("angle", 
385
0
            "The angle up to which particles may vary in their initial direction "
386
0
            "from the emitters direction, in degrees." , PT_REAL),
387
0
            &msAngleCmd);
388
389
0
        dict->addParameter(ParameterDef("colour", 
390
0
            "The colour of emitted particles.", PT_COLOURVALUE),
391
0
            &msColourCmd);
392
393
0
        dict->addParameter(ParameterDef("colour_range_start", 
394
0
            "The start of a range of colours to be assigned to emitted particles.", PT_COLOURVALUE),
395
0
            &msColourRangeStartCmd);
396
397
0
        dict->addParameter(ParameterDef("colour_range_end", 
398
0
            "The end of a range of colours to be assigned to emitted particles.", PT_COLOURVALUE),
399
0
            &msColourRangeEndCmd);
400
401
0
        dict->addParameter(ParameterDef("direction", 
402
0
            "The base direction of the emitter." , PT_VECTOR3),
403
0
            &msDirectionCmd);
404
405
0
        dict->addParameter(ParameterDef("up", 
406
0
            "The up vector of the emitter." , PT_VECTOR3),
407
0
            &msUpCmd);
408
409
0
        dict->addParameter(ParameterDef("direction_position_reference", 
410
0
            "The reference position to calculate the direction of emitted particles "
411
0
            "based on their position. Good for explosions and implosions (use negative velocity)" , PT_COLOURVALUE),
412
0
            &msDirPositionRefCmd);
413
414
0
        dict->addParameter(ParameterDef("emission_rate", 
415
0
            "The number of particles emitted per second." , PT_REAL),
416
0
            &msEmissionRateCmd);
417
418
0
        dict->addParameter(ParameterDef("position", 
419
0
            "The position of the emitter relative to the particle system center." , PT_VECTOR3),
420
0
            &msPositionCmd);
421
422
0
        dict->addParameter(ParameterDef("velocity", 
423
0
            "The initial velocity to be assigned to every particle, in world units per second." , PT_REAL),
424
0
            &msVelocityCmd);
425
426
0
        dict->addParameter(ParameterDef("velocity_min", 
427
0
            "The minimum initial velocity to be assigned to each particle." , PT_REAL),
428
0
            &msMinVelocityCmd);
429
430
0
        dict->addParameter(ParameterDef("velocity_max", 
431
0
            "The maximum initial velocity to be assigned to each particle." , PT_REAL),
432
0
            &msMaxVelocityCmd);
433
434
0
        dict->addParameter(ParameterDef("time_to_live", 
435
0
            "The lifetime of each particle in seconds." , PT_REAL),
436
0
            &msTTLCmd);
437
438
0
        dict->addParameter(ParameterDef("time_to_live_min", 
439
0
            "The minimum lifetime of each particle in seconds." , PT_REAL),
440
0
            &msMinTTLCmd);
441
442
0
        dict->addParameter(ParameterDef("time_to_live_max", 
443
0
            "The maximum lifetime of each particle in seconds." , PT_REAL),
444
0
            &msMaxTTLCmd);
445
446
0
        dict->addParameter(ParameterDef("duration", 
447
0
            "The length of time in seconds which an emitter stays enabled for." , PT_REAL),
448
0
            &msDurationCmd);
449
450
0
        dict->addParameter(ParameterDef("duration_min", 
451
0
            "The minimum length of time in seconds which an emitter stays enabled for." , PT_REAL),
452
0
            &msMinDurationCmd);
453
454
0
        dict->addParameter(ParameterDef("duration_max", 
455
0
            "The maximum length of time in seconds which an emitter stays enabled for." , PT_REAL),
456
0
            &msMaxDurationCmd);
457
458
0
        dict->addParameter(ParameterDef("repeat_delay", 
459
0
            "If set, after disabling an emitter will repeat (reenable) after this many seconds." , PT_REAL),
460
0
            &msRepeatDelayCmd);
461
462
0
        dict->addParameter(ParameterDef("repeat_delay_min", 
463
0
            "If set, after disabling an emitter will repeat (reenable) after this minimum number of seconds." , PT_REAL),
464
0
            &msMinRepeatDelayCmd);
465
466
0
        dict->addParameter(ParameterDef("repeat_delay_max", 
467
0
            "If set, after disabling an emitter will repeat (reenable) after this maximum number of seconds." , PT_REAL),
468
0
            &msMaxRepeatDelayCmd);
469
470
0
        dict->addParameter(ParameterDef("name", 
471
0
            "This is the name of the emitter" , PT_STRING),
472
0
            &msNameCmd);
473
        
474
0
        dict->addParameter(ParameterDef("emit_emitter", 
475
0
            "If set, this emitter will emit other emitters instead of visual particles" , PT_STRING),
476
0
            &msEmittedEmitterCmd);
477
0
    }
478
    //-----------------------------------------------------------------------
479
    Real ParticleEmitter::getParticleVelocity(void) const
480
0
    {
481
0
        return mMinSpeed;
482
0
    }
483
    //-----------------------------------------------------------------------
484
    Real ParticleEmitter::getMinParticleVelocity(void) const
485
0
    {
486
0
        return mMinSpeed;
487
0
    }
488
    //-----------------------------------------------------------------------
489
    Real ParticleEmitter::getMaxParticleVelocity(void) const
490
0
    {
491
0
        return mMaxSpeed;
492
0
    }
493
    //-----------------------------------------------------------------------
494
    void ParticleEmitter::setMinParticleVelocity(Real min)
495
0
    {
496
0
        assert(std::isfinite(min));
497
0
        mMinSpeed = min;
498
0
    }
499
    //-----------------------------------------------------------------------
500
    void ParticleEmitter::setMaxParticleVelocity(Real max)
501
0
    {
502
0
        assert(std::isfinite(max));
503
0
        mMaxSpeed = max;
504
0
    }
505
    //-----------------------------------------------------------------------
506
    Real ParticleEmitter::getTimeToLive(void) const
507
0
    {
508
0
        return mMinTTL;
509
0
    }
510
    //-----------------------------------------------------------------------
511
    Real ParticleEmitter::getMinTimeToLive(void) const
512
0
    {
513
0
        return mMinTTL;
514
0
    }
515
    //-----------------------------------------------------------------------
516
    Real ParticleEmitter::getMaxTimeToLive(void) const
517
0
    {
518
0
        return mMaxTTL;
519
0
    }
520
    //-----------------------------------------------------------------------
521
    void ParticleEmitter::setMinTimeToLive(Real min)
522
0
    {
523
0
        mMinTTL = min;
524
0
    }
525
    //-----------------------------------------------------------------------
526
    void ParticleEmitter::setMaxTimeToLive(Real max)
527
0
    {
528
0
        mMaxTTL = max;
529
0
    }
530
    //-----------------------------------------------------------------------
531
    const ColourValue& ParticleEmitter::getColour(void) const
532
0
    {
533
0
        return mColourRangeStart;
534
0
    }
535
    //-----------------------------------------------------------------------
536
    const ColourValue& ParticleEmitter::getColourRangeStart(void) const
537
0
    {
538
0
        return mColourRangeStart;
539
0
    }
540
    //-----------------------------------------------------------------------
541
    const ColourValue& ParticleEmitter::getColourRangeEnd(void) const
542
0
    {
543
0
        return mColourRangeEnd;
544
0
    }
545
    //-----------------------------------------------------------------------
546
    void ParticleEmitter::setColourRangeStart(const ColourValue& val)
547
0
    {
548
0
        mColourRangeStart = val;
549
0
    }
550
    //-----------------------------------------------------------------------
551
    void ParticleEmitter::setColourRangeEnd(const ColourValue& val )
552
0
    {
553
0
        mColourRangeEnd = val;
554
0
    }
555
    //-----------------------------------------------------------------------
556
    void ParticleEmitter::setEnabled(bool enabled)
557
0
    {
558
0
        mEnabled = enabled;
559
0
        mRemainder = 1.0f; // make sure we emit a particle on next update. Turns emission rate to (t0;r] interval
560
        // Reset duration & repeat
561
0
        initDurationRepeat();
562
0
    }
563
    //-----------------------------------------------------------------------
564
    bool ParticleEmitter::getEnabled(void) const
565
0
    {
566
0
        return mEnabled;
567
0
    }
568
    //-----------------------------------------------------------------------
569
    void ParticleEmitter::setStartTime(Real startTime)
570
0
    {
571
0
        setEnabled(false);
572
0
        mStartTime = startTime;
573
0
    }
574
    //-----------------------------------------------------------------------
575
    Real ParticleEmitter::getStartTime(void) const
576
0
    {
577
0
        return mStartTime;
578
0
    }
579
    //-----------------------------------------------------------------------
580
    void ParticleEmitter::setDuration(Real duration)
581
0
    {
582
0
        setDuration(duration, duration);
583
0
    }
584
    //-----------------------------------------------------------------------
585
    Real ParticleEmitter::getDuration(void) const
586
0
    {
587
0
        return mDurationMin;
588
0
    }
589
    //-----------------------------------------------------------------------
590
    void ParticleEmitter::setDuration(Real min, Real max)
591
0
    {
592
0
        mDurationMin = min;
593
0
        mDurationMax = max;
594
0
        initDurationRepeat();
595
0
    }
596
    //-----------------------------------------------------------------------
597
    void ParticleEmitter::setMinDuration(Real min)
598
0
    {
599
0
        mDurationMin = min;
600
0
        initDurationRepeat();
601
0
    }
602
    //-----------------------------------------------------------------------
603
    void ParticleEmitter::setMaxDuration(Real max)
604
0
    {
605
0
        mDurationMax = max;
606
0
        initDurationRepeat();
607
0
    }
608
    //-----------------------------------------------------------------------
609
    void ParticleEmitter::initDurationRepeat(void)
610
0
    {
611
0
        if (mEnabled)
612
0
        {
613
0
            if (mDurationMin == mDurationMax)
614
0
            {
615
0
                mDurationRemain = mDurationMin;
616
0
            }
617
0
            else
618
0
            {
619
0
                mDurationRemain = Math::RangeRandom(mDurationMin, mDurationMax);
620
0
            }
621
0
        }
622
0
        else
623
0
        {
624
            // Reset repeat
625
0
            if (mRepeatDelayMin == mRepeatDelayMax)
626
0
            {
627
0
                mRepeatDelayRemain = mRepeatDelayMin;
628
0
            }
629
0
            else
630
0
            {
631
0
                mRepeatDelayRemain = Math::RangeRandom(mRepeatDelayMax, mRepeatDelayMin);
632
0
            }
633
634
0
        }
635
0
    }
636
    //-----------------------------------------------------------------------
637
    void ParticleEmitter::setRepeatDelay(Real delay)
638
0
    {
639
0
        setRepeatDelay(delay, delay);
640
0
    }
641
    //-----------------------------------------------------------------------
642
    Real ParticleEmitter::getRepeatDelay(void) const
643
0
    {
644
0
        return mRepeatDelayMin;
645
0
    }
646
    //-----------------------------------------------------------------------
647
    void ParticleEmitter::setRepeatDelay(Real min, Real max)
648
0
    {
649
0
        mRepeatDelayMin = min;
650
0
        mRepeatDelayMax = max;
651
0
        initDurationRepeat();
652
0
    }
653
    //-----------------------------------------------------------------------
654
    void ParticleEmitter::setMinRepeatDelay(Real min)
655
0
    {
656
0
        mRepeatDelayMin = min;
657
0
        initDurationRepeat();
658
0
    }
659
    //-----------------------------------------------------------------------
660
    void ParticleEmitter::setMaxRepeatDelay(Real max)
661
0
    {
662
0
        mRepeatDelayMax = max;
663
0
        initDurationRepeat();
664
0
    }
665
    //-----------------------------------------------------------------------
666
    Real ParticleEmitter::getMinDuration(void) const
667
0
    {
668
0
        return mDurationMin;
669
0
    }
670
    //-----------------------------------------------------------------------
671
    Real ParticleEmitter::getMaxDuration(void) const
672
0
    {
673
0
        return mDurationMax;
674
0
    }
675
    //-----------------------------------------------------------------------
676
    Real ParticleEmitter::getMinRepeatDelay(void) const
677
0
    {
678
0
        return mRepeatDelayMin;    
679
0
    }
680
    //-----------------------------------------------------------------------
681
    Real ParticleEmitter::getMaxRepeatDelay(void) const
682
0
    {
683
0
        return mRepeatDelayMax;    
684
0
    }
685
686
    //-----------------------------------------------------------------------
687
    ParticleEmitterFactory::~ParticleEmitterFactory()
688
0
    {
689
0
        OGRE_IGNORE_DEPRECATED_BEGIN
690
        // Destroy all emitters
691
0
        for (auto& e : mEmitters)
692
0
        {
693
0
            OGRE_DELETE e;
694
0
        }
695
            
696
0
        mEmitters.clear();
697
0
        OGRE_IGNORE_DEPRECATED_END
698
0
    }
699
    //-----------------------------------------------------------------------
700
    void ParticleEmitterFactory::destroyEmitter(ParticleEmitter* e)        
701
0
    {
702
0
        delete e;
703
0
        OGRE_IGNORE_DEPRECATED_BEGIN
704
0
        auto i = std::find(std::begin(mEmitters), std::end(mEmitters), e);
705
0
        if (i != std::end(mEmitters)) {
706
0
            mEmitters.erase(i);
707
0
        }
708
0
        OGRE_IGNORE_DEPRECATED_END
709
0
    }
710
711
    //-----------------------------------------------------------------------
712
}
713