1 ///////////////////////////////////////////////////////////////////////////////
2 //            Copyright (C) 2004-2010 by The Allacrost Project
3 //                         All Rights Reserved
4 //
5 // This code is licensed under the GNU GPL version 2. It is free software
6 // and you may modify it and/or redistribute it under the terms of this license.
7 // See http://www.gnu.org/copyleft/gpl.html for details.
8 ///////////////////////////////////////////////////////////////////////////////
9 
10 /*!****************************************************************************
11  * \file    particle_effect.h
12  * \author  Raj Sharma, roos@allacrost.org
13  * \brief   Header file for particle effects
14  *
15  * Particle effects are basically nothing more than a collection of particle
16  * systems. Many effects are just one system. However, for example, if you think
17  * about a campfire effect, that might actually consist of fire + smoke + embers.
18  * So, that's an example of an effect that consists of 3 systems.
19  *
20  * This file contains two classes: ParticleEffectDef, and ParticleEffect.
21  *
22  * ParticleEffectDef is a "definition" class, which holds a list of
23  *    ParticleSystemDefs.
24  *
25  * ParticleEffect is an "instance" class, which holds a list of
26  *    ParticleSystems.
27  *
28  *
29  * This way, if you have 100 explosions, the properties of the
30  * effect are stored only once in a ParticleEffectDef, and the only thing that
31  * gets repeated 100 times is the ParticleEffect, which holds instance-specific stuff.
32  *****************************************************************************/
33 
34 #ifndef __PARTICLE_EFFECT_HEADER__
35 #define __PARTICLE_EFFECT_HEADER__
36 
37 #include "defs.h"
38 #include "utils.h"
39 
40 namespace hoa_video
41 {
42 
43 using private_video::ParticleSystem;
44 using private_video::ParticleSystemDef;
45 
46 /*!***************************************************************************
47  *  \brief particle effect definition, just consists of each of its subsystems'
48  *         definitions. This is basically just a struct, except it has a
49  *         function to load the structure from a particle file (.lua/.hoa)
50  *****************************************************************************/
51 
52 class ParticleEffectDef
53 {
54 public:
55 
56 	//! list of system definitions
57 	std::list<ParticleSystemDef *> _systems;
58 };
59 
60 
61 /*!***************************************************************************
62  *  \brief particle effect, basically one coherent "effect" like an explosion,
63  *         or snow falling from the sky. Consists of one or more ParticleSystems.
64  *         An example of using multiple systems to create one effect would be
65  *         a campfire where you have fire + smoke + glowing embers.
66  *****************************************************************************/
67 
68 class ParticleEffect
69 {
70 public:
71 
72 	/*!
73 	 *  \brief Constructor
74 	 */
75 	ParticleEffect();
76 
77 
78 	/*!
79 	 *  \brief moves the effect to the specified position on the screen,
80 	 *         This can be used if you want to move a particle system around
81 	 *         on some flight path, or if you want to attach the system to an
82 	 *         object. (e.g. smoke to a jet)
83 	 * \param x movement of system in x direction
84 	 * \param y movement of system in y direction
85 	 */
86 	void Move(float x, float y);
87 
88 
89 	/*!
90 	 *  \brief moves the effect dx and dy units relative to its current position
91 	 * \param dx x offset to move to from current x position
92 	 * \param dy y offset to move to from current y position
93 	 */
94 	void MoveRelative(float dx, float dy);
95 
96 
97 	/*!
98 	 *  \brief set the orientation of the effect (including all systems contained
99 	 *         within the effect). This is essentially added to the emitter orientation
100 	 *         for each system. For example, if you want to create a particle system for
101 	 *         smoke coming out of a jet, set the emitter orientation to zero degrees (right)
102 	 *         when you create the effect. Then, at runtime just call SetOrientation() every
103 	 *         frame with the angle the jet is facing.
104 	 * \param angle rotation of particle system
105 	 */
106 	void SetOrientation(float angle);
107 
108 
109 	/*!
110 	 *  \brief set the position of an "attractor point". Any particle systems which use
111 	 *         radial acceleration and have user-defined attractor points enabled will
112 	 *         have particles move towards this point
113 	 *
114 	 *  \note  a positive radial acceleration will move a particle away from the attractor,
115 	 *         and negative will move it towards it.
116 	 * \param x x coordiante of gravitation point
117 	 * \param y y coordiante of gravitation point
118 	 */
119 	void SetAttractorPoint(float x, float y);
120 
121 
122 	/*!
123 	 *  \brief returns true if the system is alive, i.e. the number of active
124 	 *         particles is more than zero. This is used by the particle manager
125 	 *         so it knows when to destroy an effect.
126 	 * \return true if system is alive, false if dead
127 	 */
128 	bool IsAlive();
129 
130 
131 	/*!
132 	 *  \brief stops this effect
133 	 *
134 	 *  \param kill_immediate If this is true, the effect is immediately killed. If
135 	 *                        it isn't true, then we stop the effect from emitting
136 	 *                        new particles, and allow it to live until all the active
137 	 *                        particles fizzle out.
138 	 */
139 	void Stop(bool kill_immediate = false);
140 
141 
142 	/*!
143 	 *  \brief return the number of active particles in this effect
144 	 * \return number of particles in the system
145 	 */
146 	int32 GetNumParticles() const;
147 
148 
149 	/*!
150 	 *  \brief return the position of the effect into x and y
151 	 * \param x parameter to store x value of system in
152 	 * \param y parameter to store y value of system in
153 	 */
154 	void  GetPosition(float &x, float &y) const;
155 
156 
157 	/*!
158 	 *  \brief return the age of the system, i.e. how many seconds it has been since
159 	 *         it was created
160 	 * \return age of the system
161 	 */
162 	float GetAge() const;
163 
164 private:
165 
166 	/*!
167 	 *  \brief draws the effect. This is private so that only the ParticleManager class
168 	 *         can draw effects.
169 	 * \return success/failure
170 	 */
171 	bool _Draw();
172 
173 
174 	/*!
175 	 *  \brief updates the effect. This is private so that only the ParticleManager class
176 	 *         can update effects.
177 	 * \param the new frame time
178 	 * \return success/failure
179 	 */
180 	bool _Update(float frame_time);
181 
182 
183 	/*!
184 	 *  \brief destroys the effect. This is private so that only the ParticleManager class
185 	 *         can destroy effects.
186 	 */
187 	void _Destroy();
188 
189 
190 	//! pointer to the effect definition
191 	const ParticleEffectDef *_effect_def;
192 
193 	//! list of subsystems that make up the effect. (for example, a fire effect might consist
194 	//! of a flame + smoke + embers)
195 	std::list <ParticleSystem *> _systems;
196 
197 	//! position of the effect
198 	float _x, _y;
199 
200 	//! position of attractor point
201 	float _attractor_x, _attractor_y;
202 
203 	//! orientation of the effect (angle in radians)
204 	float _orientation;
205 
206 	//! is the effect is alive or not
207 	bool  _alive;
208 
209 	//! age of the effect (seconds since it was created)
210 	float _age;
211 
212 	//! number of active particles (this is updated on each call to Update())
213 	int32 _num_particles;
214 
215 	friend class private_video::ParticleManager;
216 
217 }; // class ParticleEffect
218 
219 }  // namespace hoa_video
220 
221 #endif  //! __PARTICLE_EFFECT_HEADER__
222