1 ///////////////////////////////////////////////////////////////////////////////
2 //            Copyright (C) 2004-2011 by The Allacrost Project
3 //            Copyright (C) 2012-2016 by Bertram (Valyria Tear)
4 //                         All Rights Reserved
5 //
6 // This code is licensed under the GNU GPL version 2. It is free software
7 // and you may modify it and/or redistribute it under the terms of this license.
8 // See http://www.gnu.org/copyleft/gpl.html for details.
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 /** ***************************************************************************
12 *** \file    particle_emitter.h
13 *** \author  Raj Sharma, roos@allacrost.org
14 *** \author  Yohann Ferreira, yohann ferreira orange fr
15 *** \brief   Header file for particle emitter
16 ***
17 *** This file contains the ParticleEmitter class, and some enumerations for
18 *** emitter properties.
19 ***
20 *** ParticleEmitter stores info about how a system emits particles. This is made
21 *** up of two things:
22 ***
23 ***  1) Where are particles emitted?
24 ***      -For example, you could create a circle-shaped emitter, and then every
25 ***         time a particle is emitted, a random spot in that circle is chosen.
26 ***
27 ***  2) When are particles emitted?
28 ***      -For example, you could emit them all at once, or slowly through the
29 ***         life of the system.
30 *** **************************************************************************/
31 
32 #ifndef __PARTICLE_EMITTER_HEADER__
33 #define __PARTICLE_EMITTER_HEADER__
34 
35 #include "common/position_2d.h"
36 
37 namespace vt_mode_manager
38 {
39 
40 /*!***************************************************************************
41  *  \brief Specifies whether the orientation for particle rotations should be
42  *         counterclockwise, clockwise, or random.
43  *****************************************************************************/
44 
45 enum EMITTER_SPIN {
46     EMITTER_SPIN_INVALID          = -1,
47 
48     EMITTER_SPIN_CLOCKWISE        = 0,   //! clockwise spin
49     EMITTER_SPIN_COUNTERCLOCKWISE = 1,   //! counterclockwise spin
50     EMITTER_SPIN_RANDOM           = 2,   //! random spin
51 
52     EMITTER_SPIN_TOTAL = 3
53 };
54 
55 
56 /*!***************************************************************************
57  *  \brief Shape of the emitter. A point emitter is the most simple- all
58  *         particles come out from a point. Another example is a line emitter.
59  *         This may be useful for a snow effect- you place the line at the top
60  *         of the screen, and particles will be generated anywhere along that line.
61  *****************************************************************************/
62 
63 enum EMITTER_SHAPE {
64     EMITTER_SHAPE_INVALID          = -1,
65 
66     EMITTER_SHAPE_POINT            =  0,   //! point (_x, _y)
67     EMITTER_SHAPE_LINE             =  1,   //! line from (_x, _y) to (_x2, _y2)
68     EMITTER_SHAPE_CIRCLE           =  2,   //! outlined circle with radius of _radius, and transposed by (_x, _y)
69     EMITTER_SHAPE_ELLIPSE          =  3,   //! outlined ellipse with two different lengths at (_x) and small one (_y), and transposed by (_x2, _y2)
70     EMITTER_SHAPE_FILLED_CIRCLE    =  4,   //! filled circle with radius of _radius, and transposed by (_x, _y)
71     EMITTER_SHAPE_FILLED_RECTANGLE =  5,   //! filled rectangle from (_x, _y) to (_x2, _y2)
72     EMITTER_SHAPE_TOTAL            =  6
73 };
74 
75 /*!***************************************************************************
76  *  \brief An enumeration of EMITTER modes for particles
77  *****************************************************************************/
78 
79 enum EMITTER_MODE {
80     EMITTER_MODE_INVALID = -1,
81 
82     EMITTER_MODE_LOOPING  = 0,   //! particles are emitted continuously
83     EMITTER_MODE_ONE_SHOT = 1,   //! particles are emitted for some time, then emitter is disabled
84     EMITTER_MODE_BURST    = 2,   //! all particles in the system are emitted at the beginning
85     EMITTER_MODE_ALWAYS   = 3,   //! as long as there are free particles, they will be emitted
86 
87     EMITTER_MODE_TOTAL = 4
88 };
89 
90 
91 class ParticleEmitter
92 {
93 public:
ParticleEmitter()94     ParticleEmitter():
95         _pos(0.0f, 0.0f),
96         _pos2(0.0f, 0.0f),
97         _center(0.0f, 0.0f),
98         _variation(0.0f, 0.0f),
99         _radius(0.0f),
100         _shape(EMITTER_SHAPE_INVALID),
101         _omnidirectional(false),
102         _orientation(0.0f),
103         _angle_variation(0.0f),
104         _initial_speed(0.0f),
105         _initial_speed_variation(0.0f),
106         _emission_rate(0.0f),
107         _start_time(0.0f),
108         _emitter_mode(EMITTER_MODE_INVALID),
109         _spin(EMITTER_SPIN_INVALID)
110     {}
111 
112     //! position of emitter, or in the case of line or rectangle emitters,
113     //! this is one point/corner of the emitter
114     vt_common::Position2D _pos;
115 
116     //! The second point/corner of the emitter, for line or rectangle emitters ONLY
117     vt_common::Position2D _pos2;
118 
119     //! position of the emitter's center. In many cases this is just the same thing
120     //! as _x and _y, but we store it anyway because then if we have a rectangle
121     //! shaped emitter, we don't have to calculate the midpoint every time we want
122     //! to know where the center is
123     vt_common::Position2D _center;
124 
125     //! add some variation to the position of each particle
126     vt_common::Position2D _variation;
127 
128     //! The radius of the emitter, for circular emitters
129     float _radius;
130 
131     //! shape of the emitter
132     EMITTER_SHAPE _shape;
133 
134     //! true if emitter should spit out particles in all directions
135     bool _omnidirectional;
136 
137     //! if _omnidirectional is false, then this is the angle at which particles should
138     //! be emitted. This angle is the same one as what is used for sinf(), e.g. zero is
139     //! right, PI/2 is up, PI is left, 3PI/2 is down, etc.
140     float _orientation;
141 
142     //! angle variation, used to create some "spread" in the particle emissions. Set this
143     //! to zero if you want all particles to be emitted in exactly the same direction
144     float _angle_variation;
145 
146     //! initial speed for particles. The unit is pixels. So, with a coordinate system which
147     //! is 1024x768, a particle going from left to right with a speed of 512 pixels/sec could
148     //! move across the screen in 2 seconds
149     float _initial_speed;
150 
151     //! variation in the initial speed (it would be boring if all particles had exactly the
152     //! same speed)
153     float _initial_speed_variation;
154 
155     //! depending on the emission mode, this specifies how many particles to emit each second
156     float _emission_rate;
157 
158     //! how many seconds to wait until emitting particles. Note that if you want a particle system
159     //! to be active for 5 seconds, and start_time is 10 seconds, then you should make the system
160     //! lifetime 15 seconds.
161     float _start_time;
162 
163     //! emitter mode- e.g. burst, always, one shot, looping
164     EMITTER_MODE _emitter_mode;
165 
166     //! emitter spin- whether particles should rotate clockwise, counterclockwise, or mixed (random)
167     EMITTER_SPIN _spin;
168 };
169 
170 } // namespace vt_mode_manager
171 
172 #endif  // __PARTICLE_EMITTER_HEADER__
173