-
Notifications
You must be signed in to change notification settings - Fork 2
/
PEmitter.h
executable file
·214 lines (172 loc) · 5.36 KB
/
PEmitter.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#pragma once
#include "Particle.h"
#include <list>
#include <glm/glm.hpp>
#include <vector>
#include <string>
// Forward declaration necessary for friending
class ParticleManager;
////////////////////////////////////////////////////
// Functors
/////////////////////////////////////////////////////
// The generic, simple lifetime function
struct lifetimeF
{
lifetimeF(float mu) : mu_(mu) { }
virtual float operator () () { return mu_; }
protected:
float mu_;
};
struct lifetimeNormalF : lifetimeF
{
lifetimeNormalF(float mu, float variance);
virtual float operator () ();
private:
float var_;
};
// Simpleton velocity function
struct velocityF
{
velocityF() : mu_(0), sigma_(0), vel_(0) { }
velocityF(float vel, float mu, float sigma) : mu_(mu), sigma_(sigma), vel_(vel) { }
virtual glm::vec3 operator() (const glm::vec3 &epos, const glm::vec3 &ppos);
protected:
float mu_, sigma_;
float vel_;
};
struct velocityCombinerF : public velocityF
{
// combines f1 with f2 like a*f1 + (1-a)*f2
velocityCombinerF(velocityF *f1, velocityF *f2, float a) :
f1_(f1), f2_(f2), a_(a)
{ }
~velocityCombinerF();
virtual glm::vec3 operator() (const glm::vec3 &epos, const glm::vec3 &ppos);
protected:
velocityF *f1_, *f2_;
const float a_;
};
// Assumes that locations are on a circle around epos. Gives them a velocity
// pointing "up" and away from the center
struct coneVelocityF : public velocityF
{
// upfact is in [0, 1] and determines amount of "up velocity"
coneVelocityF(float mu, float sigma, const glm::vec3 &up, float upfact) :
mu_(mu), sigma_(sigma), upvec_(glm::normalize(up)), upfact_(upfact)
{ }
virtual glm::vec3 operator()(const glm::vec3 &epos, const glm::vec3 &ppos);
protected:
// hiding velocityF members because it should be just an interface
float mu_, sigma_;
glm::vec3 upvec_;
float upfact_;
};
struct circleTangentVelocityF : public velocityF
{
circleTangentVelocityF(float mu, float sigma, const glm::vec3 &upvec) :
mu_(mu), sigma_(sigma), upvec_(upvec)
{ }
virtual glm::vec3 operator()(const glm::vec3 &epos, const glm::vec3 &ppos);
protected:
const float mu_, sigma_;
const glm::vec3 upvec_;
};
struct locationF
{
locationF() : r_(0.f) { }
locationF(float radius) : r_(radius) { }
virtual glm::vec3 operator()(const glm::vec3 &epos);
protected:
float r_;
};
// Creates particles on a circle, with radius and orientation
struct circleLocationF : public locationF
{
circleLocationF(float radius, const glm::vec3 &up) :
r_(radius), upvec_(glm::normalize(up))
{ }
virtual glm::vec3 operator()(const glm::vec3 &epos);
protected:
// Repeated because eventually locationF will be just an interface
float r_;
glm::vec3 upvec_;
};
// Creates particles on the interior a circle, with radius and orientation
struct circleInteriorLocationF : public circleLocationF
{
circleInteriorLocationF(float radius, const glm::vec3 &up);
virtual glm::vec3 operator()(const glm::vec3 &epos);
protected:
// Repeated because eventually locationF will be just an interface
float r_;
glm::vec3 upvec_;
};
struct colorF
{
colorF() { }
colorF(const glm::vec4 &color, float bright, float brightvar) :
mu_(color), bright_(bright), brightvar_(brightvar)
{
}
virtual ~colorF() {}
virtual glm::vec4 operator() ();
protected:
glm::vec4 mu_;
float bright_, brightvar_;
};
struct discreteColorF : public colorF
{
discreteColorF(const std::vector<glm::vec4> &colors) : colors_(colors)
{ }
virtual glm::vec4 operator() ();
protected:
std::vector<glm::vec4> colors_;
};
class PEmitterActionF;
//
// The emitter class is the main particle engine configuration point.
// With its setter methods particle lifetime, location, and spew rate
// can be defined.
// Emitters will spew particles (and take up clock cycles) until a call to
// ParticleManager::quashEmitter()
//
class Emitter
{
public:
Emitter* setParticleLocationF(locationF *);
Emitter* setParticleLifetimeF(lifetimeF *);
Emitter* setParticleVelocityF(velocityF *);
Emitter* setParticleColorF(colorF *);
Emitter* setLocation(const glm::vec3 &l);
Emitter* setOutputRate(float r);
// How much time is left before this emitter expires?
Emitter* setTimeRemaining(float);
Emitter* setOutputGroup(const std::string &);
std::string getOutputGroup() const;
bool isDone() const;
// The update function. Spew some new particles, given that dt seconds
// have elapsed.
void emit(float dt);
void addEmitterAction(PEmitterActionF *);
private:
Emitter();
// Lifetime, and a functor that determines particle lifetime
lifetimeF *lifetime_func;
// particle velocity, and its associated functor
velocityF *velocity_func;
locationF *location_func;
colorF *color_func;
// Since this is a sperical emitter, we need two pieces of information:
glm::vec3 loc_;
// Particles will spawn with this initial velocity
// And with a frequency determined by this (particles per second)
float rate_;
// Each particle will be about this size.
glm::vec3 size_;
std::list<PEmitterActionF *> eactions_;
std::string outputGroup_;
float timeRemaining_;
float particlesToEmit_;
friend class PERandomF;
friend class ParticleManager;
};