Coverage Report

Created: 2025-07-18 07:08

/src/ogre/OgreMain/include/OgreParticleEmitter.h
Line
Count
Source (jump to first uncovered line)
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
#ifndef __ParticleEmitter_H__
29
#define __ParticleEmitter_H__
30
31
#include "OgrePrerequisites.h"
32
#include "OgreVector.h"
33
#include "OgreColourValue.h"
34
#include "OgreStringInterface.h"
35
#include "OgreParticle.h"
36
#include "OgreParticleSystem.h"
37
#include "OgreHeaderPrefix.h"
38
39
40
namespace Ogre {
41
42
43
    /** \addtogroup Core
44
    *  @{
45
    */
46
    /** \addtogroup Effects
47
    *  @{
48
    */
49
    /** Abstract class defining the interface to be implemented by particle emitters.
50
51
        Particle emitters are the sources of particles in a particle system. 
52
        This class defines the ParticleEmitter interface, and provides a basic implementation 
53
        for tasks which most emitters will do (these are of course overridable).
54
        Particle emitters can be  grouped into types, e.g. 'point' emitters, 'box' emitters etc; each type will 
55
        create particles with a different starting point, direction and velocity (although
56
        within the types you can configure the ranges of these parameters). 
57
    @par
58
        Because there are so many types of emitters you could use, OGRE chooses not to dictate
59
        the available types. It comes with some in-built, but allows plugins or applications to extend the emitter types available.
60
        This is done by subclassing ParticleEmitter to have the appropriate emission behaviour you want,
61
        and also creating a subclass of ParticleEmitterFactory which is responsible for creating instances 
62
        of your new emitter type. You register this factory with the ParticleSystemManager using
63
        addEmitterFactory, and from then on emitters of this type can be created either from code or through
64
        text particle scripts by naming the type.
65
    @par
66
        This same approach is used for ParticleAffectors (which modify existing particles per frame).
67
        This means that OGRE is particularly flexible when it comes to creating particle system effects,
68
        with literally infinite combinations of emitter and affector types, and parameters within those
69
        types.
70
    */
71
    class _OgreExport ParticleEmitter : public StringInterface, public Particle
72
    {
73
    protected:
74
        /// Parent particle system
75
        ParticleSystem* mParent;
76
77
        /// Position relative to the center of the ParticleSystem
78
        // inherited: Vector3 mPosition;
79
        // Note, that position of the emitter becomes a position in worldspace if mLocalSpace is set
80
        // to false (will this become a problem?)
81
82
        /// Rate in particles per second at which this emitter wishes to emit particles
83
        Real mEmissionRate;
84
        /// Name of the type of emitter, MUST be initialised by subclasses
85
        String mType;
86
        /// Base direction of the emitter, may not be used by some emitters
87
        Vector3 mDirection;
88
        /// Notional up vector, used to speed up generation of variant directions, and also to orient some emitters.
89
        Vector3 mUp;
90
        /// When true, mDirPositionRef is used instead of mDirection to generate particles
91
        bool mUseDirPositionRef;
92
        /* Center position to tell in which direction will particles be emitted according to their position,
93
            useful for explosions & implosions, some emitters (i.e. point emitter) may not need it. */
94
        Vector3 mDirPositionRef;
95
        /// Angle around direction which particles may be emitted, internally radians but angleunits for interface
96
        Radian mAngle;
97
        /// Min speed of particles
98
        Real mMinSpeed;
99
        /// Max speed of particles
100
        Real mMaxSpeed;
101
        /// Initial time-to-live of particles (min)
102
        Real mMinTTL;
103
        /// Initial time-to-live of particles (max)
104
        Real mMaxTTL;
105
        /// Initial colour of particles (range start)
106
        ColourValue mColourRangeStart;
107
        /// Initial colour of particles (range end)
108
        ColourValue mColourRangeEnd;
109
110
        /// Whether this emitter is currently enabled (defaults to true)
111
        bool mEnabled;
112
113
        /// Start time (in seconds from start of first call to ParticleSystem to update)
114
        Real mStartTime;
115
        /// Minimum length of time emitter will run for (0 = forever)
116
        Real mDurationMin;
117
        /// Maximum length of time the emitter will run for (0 = forever)
118
        Real mDurationMax;
119
        /// Current duration remainder
120
        Real mDurationRemain;
121
122
        /// Time between each repeat
123
        Real mRepeatDelayMin;
124
        Real mRepeatDelayMax;
125
        /// Repeat delay left
126
        Real mRepeatDelayRemain;
127
128
        // Fractions of particles wanted to be emitted last time
129
        float mRemainder;
130
131
        /// The name of the emitter. The name is optional unless it is used as an emitter that is emitted itself.
132
        String mName;
133
134
        /// The name of the emitter to be emitted (optional)
135
        String mEmittedEmitter;
136
137
        // If 'true', this emitter is emitted by another emitter.
138
        // NB. That doesn't imply that the emitter itself emits other emitters (that could or could not be the case)
139
        bool mEmitted;
140
141
        // NB Method below here are to help out people implementing emitters by providing the
142
        // most commonly used approaches as piecemeal methods
143
144
        /** Internal utility method for generating particle exit direction
145
        @param destVector Reference to vector to complete with new direction (normalised)
146
        */
147
        virtual void genEmissionDirection( const Vector3 &particlePos, Vector3& destVector );
148
149
        /** Internal utility method to apply velocity to a particle direction.
150
        @param destVector The vector to scale by a randomly generated scale between min and max speed.
151
            Assumed normalised already, and likely already oriented in the right direction.
152
        */
153
        virtual void genEmissionVelocity(Vector3& destVector);
154
155
        /** Internal utility method for generating a time-to-live for a particle. */
156
        virtual Real genEmissionTTL(void);
157
158
        /** Internal utility method for generating a colour for a particle. */
159
        virtual void genEmissionColour(RGBA& destColour);
160
161
        /** Internal utility method for generating an emission count based on a constant emission rate. */
162
        unsigned short genConstantEmissionCount(Real timeElapsed);
163
164
        /** Internal method for setting up the basic parameter definitions for a subclass. 
165
166
            Because StringInterface holds a dictionary of parameters per class, subclasses need to
167
            call this to ask the base class to add it's parameters to their dictionary as well.
168
            Can't do this in the constructor because that runs in a non-virtual context.
169
        @par
170
            The subclass must have called it's own createParamDictionary before calling this method.
171
        */
172
        void addBaseParameters(void);
173
174
        /** Internal method for initialising the duration & repeat of an emitter. */
175
        void initDurationRepeat(void);
176
177
178
    public:
179
        ParticleEmitter(ParticleSystem* psys);
180
        /** Virtual destructor essential. */
181
        virtual ~ParticleEmitter();
182
183
        /** Sets the position of this emitter relative to the particle system center. */
184
        virtual void setPosition(const Vector3& pos);
185
186
        /** Returns the position of this emitter relative to the center of the particle system. */
187
        virtual const Vector3& getPosition(void) const;
188
189
        /** Sets the direction of the emitter.
190
191
            Most emitters will have a base direction in which they emit particles (those which
192
            emit in all directions will ignore this parameter). They may not emit exactly along this
193
            vector for every particle, many will introduce a random scatter around this vector using 
194
            the angle property.
195
        @note 
196
            This resets the up vector.
197
        @param direction
198
            The base direction for particles emitted.
199
        */
200
        virtual void setDirection(const Vector3& direction);
201
202
        /** Returns the base direction of the emitter. */
203
        virtual const Vector3& getDirection(void) const;
204
205
        /** Sets the notional up vector of the emitter
206
207
            Many emitters emit particles from within a region, and for some that region is not
208
            circularly symmetric about the emitter direction. The up vector allows such emitters
209
            to be orientated about the direction vector.
210
        @param up
211
            The base direction for particles emitted. It must be perpendicular to the direction vector.
212
        */
213
        virtual void setUp(const Vector3& up);
214
215
        /** Returns the up vector of the emitter. */
216
        virtual const Vector3& getUp(void) const;
217
218
        /** Sets the direction of the emitter.
219
            Some particle effects need to emit particles in many random directions, but still
220
            following some rules; like not having them collide against each other. Very useful
221
            for explosions and implosions (when velocity is negative)
222
        @note
223
            Although once enabled mDirPositionRef will supersede mDirection; calling setDirection()
224
            may still be needed to setup a custom up vector.
225
        @param position
226
            The reference position in which the direction of the particles will be calculated from,
227
            also taking into account the particle's position at the time of emission.
228
        @param enable
229
            True to use mDirPositionRef, false to use the default behaviour with mDirection
230
        */
231
        virtual void setDirPositionReference( const Vector3& position, bool enable );
232
233
        /** Returns the position reference to generate direction of emitted particles */
234
        virtual const Vector3& getDirPositionReference() const;
235
236
        /** Returns whether direction or position reference is used */
237
        virtual bool getDirPositionReferenceEnabled() const;
238
239
        /** Sets the maximum angle away from the emitter direction which particle will be emitted.
240
241
            Whilst the direction property defines the general direction of emission for particles, 
242
            this property defines how far the emission angle can deviate away from this base direction.
243
            This allows you to create a scatter effect - if set to 0, all particles will be emitted
244
            exactly along the emitters direction vector, whereas if you set it to 180 degrees or more,
245
            particles will be emitted in a sphere, i.e. in all directions.
246
        @param angle
247
            Maximum angle which initial particle direction can deviate from the emitter base direction vector.
248
        */
249
        virtual void setAngle(const Radian& angle);
250
251
        /** Returns the maximum angle which the initial particle direction can deviate from the emitters base direction. */
252
        virtual const Radian& getAngle(void) const;
253
254
        /** Sets the initial velocity of particles emitted.
255
256
            This method sets a constant speed for emitted particles. See the alternate version
257
            of this method which takes 2 parameters if you want a variable speed. 
258
        @param
259
            speed The initial speed in world units per second which every particle emitted starts with.
260
        */
261
        virtual void setParticleVelocity(Real speed);
262
263
264
        /** Sets the initial velocity range of particles emitted.
265
266
            This method sets the range of starting speeds for emitted particles. 
267
            See the alternate version of this method which takes 1 parameter if you want a 
268
            constant speed. This emitter will randomly choose a speed between the minimum and 
269
            maximum for each particle.
270
        @param max The maximum speed in world units per second for the initial particle speed on emission.
271
        @param min The minimum speed in world units per second for the initial particle speed on emission.
272
        */
273
        virtual void setParticleVelocity(Real min, Real max);
274
        /** Returns the minimum particle velocity. */
275
        virtual void setMinParticleVelocity(Real min);
276
        /** Returns the maximum particle velocity. */
277
        virtual void setMaxParticleVelocity(Real max);
278
279
        /** Returns the initial velocity of particles emitted. */
280
        virtual Real getParticleVelocity(void) const;
281
282
        /** Returns the minimum particle velocity. */
283
        virtual Real getMinParticleVelocity(void) const;
284
285
        /** Returns the maximum particle velocity. */
286
        virtual Real getMaxParticleVelocity(void) const;
287
288
        /** Sets the emission rate for this emitter.
289
290
            This method tells the emitter how many particles per second should be emitted. The emitter
291
            subclass does not have to emit these in a continuous burst - this is a relative parameter
292
            and the emitter may choose to emit all of the second's worth of particles every half-second
293
            for example. This is controlled by the emitter's getEmissionCount method.
294
        @par
295
            Also, if the ParticleSystem's particle quota is exceeded, not all the particles requested
296
            may be actually emitted.
297
        @param
298
            particlesPerSecond The number of particles to be emitted every second.
299
        */
300
        virtual void setEmissionRate(Real particlesPerSecond);
301
302
        /** Returns the emission rate set for this emitter. */
303
        virtual Real getEmissionRate(void) const;
304
305
        /** Sets the lifetime of all particles emitted.
306
307
            The emitter initialises particles with a time-to-live (TTL), the number of seconds a particle
308
            will exist before being destroyed. This method sets a constant TTL for all particles emitted.
309
            Note that affectors are able to modify the TTL of particles later.
310
        @par
311
            Also see the alternate version of this method which takes a min and max TTL in order to 
312
            have the TTL vary per particle.
313
        @param ttl The number of seconds each particle will live for.
314
        */
315
        virtual void setTimeToLive(Real ttl);
316
        /** Sets the range of lifetime for particles emitted.
317
318
            The emitter initialises particles with a time-to-live (TTL), the number of seconds a particle
319
            will exist before being destroyed. This method sets a range for the TTL for all particles emitted;
320
            the ttl may be randomised between these 2 extremes or will vary some other way depending on the
321
            emitter.
322
            Note that affectors are able to modify the TTL of particles later.
323
        @par
324
            Also see the alternate version of this method which takes a single TTL in order to 
325
            set a constant TTL for all particles.
326
        @param minTtl The minimum number of seconds each particle will live for. Must be non-negative!
327
        @param maxTtl The maximum number of seconds each particle will live for. Must be non-negative!
328
        */
329
        virtual void setTimeToLive(Real minTtl, Real maxTtl);
330
331
        /** Sets the minimum time each particle will live for. Must be non-negative! */
332
        virtual void setMinTimeToLive(Real min);
333
        /** Sets the maximum time each particle will live for. Must be non-negative! */
334
        virtual void setMaxTimeToLive(Real max);
335
        
336
        /** Gets the time each particle will live for. */
337
        virtual Real getTimeToLive(void) const;
338
339
        /** Gets the minimum time each particle will live for. */
340
        virtual Real getMinTimeToLive(void) const;
341
        /** Gets the maximum time each particle will live for. */
342
        virtual Real getMaxTimeToLive(void) const;
343
344
        /** Sets the initial colour of particles emitted.
345
346
            Particles have an initial colour on emission which the emitter sets. This method sets
347
            this colour. See the alternate version of this method which takes 2 colours in order to establish 
348
            a range of colours to be assigned to particles.
349
        @param colour The colour which all particles will be given on emission.
350
        */
351
        virtual void setColour(const ColourValue& colour);
352
        /** Sets the range of colours for emitted particles.
353
354
            Particles have an initial colour on emission which the emitter sets. This method sets
355
            the range of this colour. See the alternate version of this method which takes a single colour
356
            in order to set a constant colour for all particles. Emitters may choose to randomly assign
357
            a colour in this range, or may use some other method to vary the colour.
358
        @param colourStart The start of the colour range
359
        @param colourEnd The end of the colour range
360
        */
361
        virtual void setColour(const ColourValue& colourStart, const ColourValue& colourEnd);
362
        /** Sets the minimum colour of particles to be emitted. */
363
        virtual void setColourRangeStart(const ColourValue& colour);
364
        /** Sets the maximum colour of particles to be emitted. */
365
        virtual void setColourRangeEnd(const ColourValue& colour);
366
        /** Gets the colour of particles to be emitted. */
367
        virtual const ColourValue& getColour(void) const;
368
        /** Gets the minimum colour of particles to be emitted. */
369
        virtual const ColourValue& getColourRangeStart(void) const;
370
        /** Gets the maximum colour of particles to be emitted. */
371
        virtual const ColourValue& getColourRangeEnd(void) const;
372
373
        /** Gets the number of particles which this emitter would like to emit based on the time elapsed.
374
375
            For efficiency the emitter does not actually create new Particle instances (these are reused
376
            by the ParticleSystem as existing particles 'die'). The implementation for this method must
377
            return the number of particles the emitter would like to emit given the number of seconds which
378
            have elapsed (passed in as a parameter).
379
        @par
380
            Based on the return value from this method, the ParticleSystem class will call 
381
            _initParticle once for each particle it chooses to allow to be emitted by this emitter.
382
            The emitter should not track these _initParticle calls, it should assume all emissions
383
            requested were made (even if they could not be because of particle quotas).
384
        */
385
        virtual unsigned short _getEmissionCount(Real timeElapsed)
386
0
        {
387
0
            return genConstantEmissionCount(timeElapsed);
388
0
        }
389
390
        /** Initialises a particle based on the emitter's approach and parameters.
391
392
            See the _getEmissionCount method for details of why there is a separation between
393
            'requested' emissions and actual initialised particles.
394
        @param
395
            pParticle Pointer to a particle which must be initialised based on how this emitter
396
            starts particles. This is passed as a pointer rather than being created by the emitter so the
397
            ParticleSystem can reuse Particle instances, and can also set defaults itself.
398
        */
399
0
        virtual void _initParticle(Particle* pParticle) {
400
            // Initialise size in case it's been altered
401
0
            pParticle->setDimensions(mParent->getDefaultWidth(), mParent->getDefaultHeight());
402
0
        }
403
404
405
        /** Returns the name of the type of emitter. 
406
407
            This property is useful for determining the type of emitter procedurally so another
408
            can be created.
409
        */
410
0
        const String &getType(void) const { return mType; }
411
412
        /** Sets whether or not the emitter is enabled.
413
414
            You can turn an emitter off completely by setting this parameter to false.
415
        */
416
        virtual void setEnabled(bool enabled);
417
418
        /** Gets the flag indicating if this emitter is enabled or not. */
419
        virtual bool getEnabled(void) const;
420
421
        /** Sets the 'start time' of this emitter.
422
423
            By default an emitter starts straight away as soon as a ParticleSystem is first created,
424
            or also just after it is re-enabled. This parameter allows you to set a time delay so
425
            that the emitter does not 'kick in' until later.
426
        @param startTime The time in seconds from the creation or enabling of the emitter.
427
        */
428
        virtual void setStartTime(Real startTime);
429
        /** Gets the start time of the emitter. */
430
        virtual Real getStartTime(void) const;
431
432
        /** Sets the duration of the emitter.
433
434
            By default emitters run indefinitely (unless you manually disable them). By setting this
435
            parameter, you can make an emitter turn off on it's own after a set number of seconds. It
436
            will then remain disabled until either setEnabled(true) is called, or if the 'repeatAfter' parameter
437
            has been set it will also repeat after a number of seconds.
438
        @par
439
            Also see the alternative version of this method which allows you to set a min and max duration for
440
            a random variable duration.
441
        @param duration The duration in seconds.
442
        */
443
        virtual void setDuration(Real duration);
444
445
        /** Gets the duration of the emitter from when it is created or re-enabled. */
446
        virtual Real getDuration(void) const;
447
448
        /** Sets the range of random duration for this emitter. 
449
450
            By default emitters run indefinitely (unless you manually disable them). By setting this
451
            parameter, you can make an emitter turn off on it's own after a random number of seconds. It
452
            will then remain disabled until either setEnabled(true) is called, or if the 'repeatAfter' parameter
453
            has been set it will also repeat after a number of seconds.
454
        @par
455
            Also see the alternative version of this method which allows you to set a constant duration.
456
        @param min The minimum duration in seconds.
457
        @param max The minimum duration in seconds.
458
        */
459
        virtual void setDuration(Real min, Real max);
460
        /** Sets the minimum duration of this emitter in seconds (see setDuration for more details) */
461
        virtual void setMinDuration(Real min);
462
        /** Sets the maximum duration of this emitter in seconds (see setDuration for more details) */
463
        virtual void setMaxDuration(Real max);
464
        /** Gets the minimum duration of this emitter in seconds (see setDuration for more details) */
465
        virtual Real getMinDuration(void) const;
466
        /** Gets the maximum duration of this emitter in seconds (see setDuration for more details) */
467
        virtual Real getMaxDuration(void) const;
468
469
        /** Sets the time between repeats of the emitter.
470
471
            By default emitters run indefinitely (unless you manually disable them). However, if you manually
472
            disable the emitter (by calling setEnabled(false), or it's duration runs out, it will cease to emit
473
        @par
474
            Also see the alternative version of this method which allows you to set a min and max duration for
475
            a random variable duration.
476
        @param duration The duration in seconds.
477
        */
478
        virtual void setRepeatDelay(Real duration);
479
480
        /** Gets the duration of the emitter from when it is created or re-enabled. */
481
        virtual Real getRepeatDelay(void) const;
482
483
        /** Sets the range of random duration for this emitter. 
484
485
            By default emitters run indefinitely (unless you manually disable them). By setting this
486
            parameter, you can make an emitter turn off on it's own after a random number of seconds. It
487
            will then remain disabled until either setEnabled(true) is called, or if the 'repeatAfter' parameter
488
            has been set it will also repeat after a number of seconds.
489
        @par
490
            Also see the alternative version of this method which allows you to set a constant duration.
491
        @param min The minimum duration in seconds.
492
        @param max The minimum duration in seconds.
493
        */
494
        virtual void setRepeatDelay(Real min, Real max);
495
        /** Sets the minimum duration of this emitter in seconds (see setRepeatDelay for more details) */
496
        virtual void setMinRepeatDelay(Real min);
497
        /** Sets the maximum duration of this emitter in seconds (see setRepeatDelay for more details) */
498
        virtual void setMaxRepeatDelay(Real max);
499
        /** Gets the minimum duration of this emitter in seconds (see setRepeatDelay for more details) */
500
        virtual Real getMinRepeatDelay(void) const;
501
        /** Gets the maximum duration of this emitter in seconds (see setRepeatDelay for more details) */
502
        virtual Real getMaxRepeatDelay(void) const;
503
504
        /** Returns the name of the emitter */
505
        const String &getName(void) const;
506
507
        /** Sets the name of the emitter */
508
        virtual void setName(const String& newName);
509
510
        /** Returns the name of the emitter to be emitted */
511
        const String &getEmittedEmitter(void) const;
512
513
        /** Sets the name of the emitter to be emitted*/
514
        virtual void setEmittedEmitter(const String& emittedEmitter);
515
516
        /** Return true if the emitter is emitted by another emitter */
517
        virtual bool isEmitted(void) const;
518
519
        /** Set the indication (true/false) to indicate that the emitter is emitted by another emitter */
520
        virtual void setEmitted(bool emitted);
521
522
523
    };
524
    /** @} */
525
    /** @} */
526
527
}
528
529
#include "OgreHeaderSuffix.h"
530
531
#endif
532