added 3dengfx into the repo, probably not the correct version for this
[summerhack] / src / 3dengfx / src / 3dengfx / psys.hpp
1 /*
2 This file is part of the 3dengfx, realtime visualization system.
3
4 Copyright (c) 2004, 2005 John Tsiombikas <nuclear@siggraph.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 /* Particle system
22  *
23  * Author: John Tsiombikas 2004
24  * Modified: John Tsiombikas 2005
25  */
26
27 #ifndef _PSYS_HPP_
28 #define _PSYS_HPP_
29
30 #include <list>
31 #include "gfx/3dgeom.hpp"
32 #include "n3dmath2/n3dmath2.hpp"
33
34 /* fuzzy scalar values
35  * random variables defined as a range of values around a central,
36  * with equiprobable distrubution function
37  */
38 class Fuzzy {
39 public:
40         scalar_t num, range;
41
42         Fuzzy(scalar_t num = 0.0, scalar_t range = 0.0);
43         scalar_t operator()() const;
44 };
45
46 /* TODO: make a fuzzy direction with polar coordinates, so the random 
47  * values lie on the surface of a sphere.
48  */
49
50 /* vector of the above */
51 class FuzzyVec3 {
52 private:
53         Fuzzy x, y, z;
54
55 public:
56         FuzzyVec3(const Fuzzy &x = Fuzzy(), const Fuzzy &y = Fuzzy(), const Fuzzy &z = Fuzzy());
57         Vector3 operator()() const;
58 };
59
60
61 /* particle abstract base class.
62  * Derived from XFormNode for controller functionality
63  */
64 class Particle : public XFormNode {
65 public:
66         Vector3 velocity;
67         scalar_t friction;
68         scalar_t size, size_start, size_end;
69         scalar_t birth_time, lifespan;
70
71         
72         Particle();
73         Particle(const Vector3 &pos, const Vector3 &vel, scalar_t friction, scalar_t lifespan);
74         virtual ~Particle();
75
76         virtual bool alive() const;
77
78         virtual void update(const Vector3 &ext_force = Vector3());
79         virtual void draw() const = 0;
80 };
81
82 /* draws the particle as a textured quad */
83 class BillboardParticle : public Particle {
84 public:
85         Texture *texture;
86         Color start_color, end_color;
87         scalar_t rot, birth_angle;
88         
89         Color color;
90         scalar_t angle;
91         
92         virtual void update(const Vector3 &ext_force = Vector3());
93         virtual void draw() const;
94 };
95
96 /* TODO: draws a 3D object in the position of the particle
97  * note that rotational and such controllers also apply for each
98  * of the particles seperately
99  */
100 class MeshParticle : public Particle {
101 };
102
103
104 struct ParticleSysParams {
105         Fuzzy psize;                    // particle size
106         scalar_t psize_end;             // end size (end of life)
107         Fuzzy lifespan;                 // lifespan in seconds
108         Fuzzy birth_rate;               // birth rate in particles per second
109         Vector3 gravity;                // gravitual force to be applied to all particles
110         FuzzyVec3 shoot_dir;    // shoot direction (initial particle velocity)
111         scalar_t friction;              // friction of the environment
112         FuzzyVec3 spawn_offset; // where to spawn in relation to position
113         Curve *spawn_offset_curve;      // a spawn curve in space, relative to position, offset still counts
114         Fuzzy spawn_offset_curve_area;
115         Texture *billboard_tex; // texture used for billboards
116         Color start_color;              // start color
117         Color end_color;                // end color
118         scalar_t rot;                   // particle rotation (radians / second counting from birth)
119         scalar_t glob_rot;              // particle emmiter rotation, particles inherit this
120
121         BlendingFactor src_blend, dest_blend;
122         
123         Texture *halo;                  // halo texture
124         Color halo_color;               // halo color
125         Fuzzy halo_size;                // halo size
126         scalar_t halo_rot;              // halo rotation (radians / second)
127
128         bool big_particles;             // need support for big particles (i.e. don't use point sprites)
129
130         ParticleSysParams();
131 };
132
133 enum ParticleType {PTYPE_PSYS, PTYPE_BILLBOARD, PTYPE_MESH};
134
135 /* Particle system
136  * The design here gets a bit confusing but for good reason
137  * the particle system is also a particle because it can be emmited by
138  * another particle system. This way we get a tree structure of particle
139  * emmiters with the leaves being just billboards or mesh-particles.
140  */
141 class ParticleSystem : public Particle {
142 protected:
143         scalar_t timeslice;
144
145         bool ready;
146         bool psprites_unsupported;
147         std::list<Particle*> particles;
148
149         ParticleSysParams psys_params;
150         ParticleType ptype;
151
152         scalar_t fraction;
153         scalar_t prev_update;
154         Vector3 prev_pos;
155
156         // current variables are calculated during each update()
157         scalar_t curr_time;
158         Vector3 curr_pos;
159         scalar_t curr_rot, curr_halo_rot;
160
161 public:
162         ParticleSystem(const char *fname = 0);
163         virtual ~ParticleSystem();
164
165         virtual void reset();
166         virtual void set_update_interval(scalar_t timeslice);
167
168         virtual void set_params(const ParticleSysParams &psys_params);
169         virtual ParticleSysParams *get_params();
170         virtual void set_particle_type(ParticleType ptype);
171
172         virtual void update(const Vector3 &ext_force = Vector3());
173         virtual void draw() const;
174 };
175
176 namespace psys {
177         void set_global_time(unsigned long msec);
178
179         bool load_particle_sys_params(const char *fname, ParticleSysParams *psp);
180 }
181
182
183 #endif  // _PSYS_HPP_