Showing the changes to interface/src/ParticleSystem.cpp (1 of 3 files). Show all
Unified · Split
| @@ -11,22 +11,28 @@ · 10 unmodified lines | |||
| 11 | #include "ParticleSystem.h" | 11 | #include "ParticleSystem.h" |
| 12 | #include "Application.h" | 12 | #include "Application.h" |
| 13 | 13 | ||
| 14 | const float DEFAULT_PARTICLE_BOUNCE = 1.0f; | ||
| 15 | const float DEFAULT_PARTICLE_AIR_FRICTION = 2.0f; | ||
| 16 | const float DEFAULT_PARTICLE_JITTER = 0.05f; | ||
| 17 | const float DEFAULT_PARTICLE_GRAVITY = 0.05f; | ||
| 18 | |||
| 14 | ParticleSystem::ParticleSystem() { | 19 | ParticleSystem::ParticleSystem() { |
| 15 | 20 | ||
| 16 | _gravity = 0.005; | ||
| 17 | _numEmitters = 0; | ||
| 18 | _bounce = 0.9f; | ||
| 19 | _timer = 0.0f; | 21 | _timer = 0.0f; |
| 20 | _airFriction = 6.0f; | 22 | _numEmitters = 0; |
| 21 | _jitter = 0.1f; | 23 | _gravity = DEFAULT_PARTICLE_GRAVITY; |
| 22 | _homeAttraction = 0.0f; | 24 | _bounce = DEFAULT_PARTICLE_BOUNCE; |
| 25 | _airFriction = DEFAULT_PARTICLE_AIR_FRICTION; | ||
| 26 | _jitter = DEFAULT_PARTICLE_JITTER; | ||
| 27 | _emitterAttraction = 0.0f; | ||
| 23 | _tornadoForce = 0.0f; | 28 | _tornadoForce = 0.0f; |
| 24 | _neighborAttraction = 0.02f; | 29 | _neighborAttraction = 0.0f; |
| 25 | _neighborRepulsion = 0.9f; | 30 | _neighborRepulsion = 0.0f; |
| 26 | _collisionSphereRadius = 0.0f; | 31 | _collisionSphereRadius = 0.0f; |
| 27 | _collisionSpherePosition = glm::vec3(0.0f, 0.0f, 0.0f); | 32 | _collisionSpherePosition = glm::vec3(0.0f, 0.0f, 0.0f); |
| 28 | _numParticles = 0; | 33 | _numParticles = 0; |
| 29 | _usingCollisionSphere = false; | 34 | _usingCollisionSphere = false; |
| 35 | _upDirection = glm::vec3(0.0f, 1.0f, 0.0f); // default | ||
| 30 | 36 | ||
| 31 | for (unsigned int e = 0; e < MAX_EMITTERS; e++) { | 37 | for (unsigned int e = 0; e < MAX_EMITTERS; e++) { |
| 32 | _emitter[e].position = glm::vec3(0.0f, 0.0f, 0.0f); | 38 | _emitter[e].position = glm::vec3(0.0f, 0.0f, 0.0f); |
| @@ -39,7 +45,8 @@ ParticleSystem::ParticleSystem() { · 6 unmodified lines | |||
| 39 | for (unsigned int p = 0; p < MAX_PARTICLES; p++) { | 45 | for (unsigned int p = 0; p < MAX_PARTICLES; p++) { |
| 40 | _particle[p].alive = false; | 46 | _particle[p].alive = false; |
| 41 | _particle[p].age = 0.0f; | 47 | _particle[p].age = 0.0f; |
| 42 | _particle[p].radius = 0.01f; | 48 | _particle[p].lifespan = 0.0f; |
| 49 | _particle[p].radius = 0.0f; | ||
| 43 | _particle[p].emitterIndex = 0; | 50 | _particle[p].emitterIndex = 0; |
| 44 | _particle[p].position = glm::vec3(0.0f, 0.0f, 0.0f); | 51 | _particle[p].position = glm::vec3(0.0f, 0.0f, 0.0f); |
| 45 | _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); | 52 | _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); |
| @@ -71,9 +78,6 @@ void ParticleSystem::simulate(float deltaTime) { · 25 unmodified lines | |||
| 71 | updateParticle(p, deltaTime); | 78 | updateParticle(p, deltaTime); |
| 72 | } | 79 | } |
| 73 | } | 80 | } |
| 74 | |||
| 75 | // apply special effects | ||
| 76 | runSpecialEffectsTest(deltaTime); | ||
| 77 | } | 81 | } |
| 78 | 82 | ||
| 79 | void ParticleSystem::updateEmitter(int e, float deltaTime) { | 83 | void ParticleSystem::updateEmitter(int e, float deltaTime) { |
| @@ -84,39 +88,63 @@ void ParticleSystem::updateEmitter(int e, float deltaTime) { · 4 unmodified lines | |||
| 84 | } | 88 | } |
| 85 | 89 | ||
| 86 | 90 | ||
| 91 | void ParticleSystem::emitParticlesNow(int e, int num, float radius, glm::vec4 color, glm::vec3 velocity, float lifespan) { | ||
| 87 | 92 | ||
| 88 | void ParticleSystem::emitParticlesNow(int e, int num) { | 93 | for (unsigned int p = 0; p < num; p++) { |
| 89 | 94 | createParticle(_emitter[e].position, velocity, radius, color, lifespan); | |
| 90 | _numParticles = num; | ||
| 91 | |||
| 92 | if (_numParticles > MAX_PARTICLES) { | ||
| 93 | _numParticles = MAX_PARTICLES; | ||
| 94 | } | 95 | } |
| 96 | } | ||
| 95 | 97 | ||
| 96 | for (unsigned int p = 0; p < num; p++) { | 98 | void ParticleSystem::createParticle(glm::vec3 position, glm::vec3 velocity, float radius, glm::vec4 color, float lifespan) { |
| 97 | _particle[p].alive = true; | 99 | |
| 98 | _particle[p].position = _emitter[e].position; | 100 | for (unsigned int p = 0; p < MAX_PARTICLES; p++) { |
| 101 | if (!_particle[p].alive) { | ||
| 102 | |||
| 103 | _particle[p].lifespan = lifespan; | ||
| 104 | _particle[p].alive = true; | ||
| 105 | _particle[p].age = 0.0f; | ||
| 106 | _particle[p].position = position; | ||
| 107 | _particle[p].velocity = velocity; | ||
| 108 | _particle[p].radius = radius; | ||
| 109 | _particle[p].color = color; | ||
| 110 | |||
| 111 | _numParticles ++; | ||
| 112 | |||
| 113 | assert(_numParticles <= MAX_PARTICLES); | ||
| 114 | |||
| 115 | return; | ||
| 116 | } | ||
| 99 | } | 117 | } |
| 100 | } | 118 | } |
| 101 | 119 | ||
| 102 | void ParticleSystem::useOrangeBlueColorPalette() { | 120 | void ParticleSystem::killParticle(int p) { |
| 121 | |||
| 122 | assert( p >= 0); | ||
| 123 | assert( p < MAX_PARTICLES); | ||
| 124 | assert( _numParticles > 0); | ||
| 125 | |||
| 126 | _particle[p].alive = false; | ||
| 127 | _numParticles --; | ||
| 128 | } | ||
| 129 | |||
| 130 | |||
| 131 | void ParticleSystem::setOrangeBlueColorPalette() { | ||
| 103 | 132 | ||
| 104 | for (unsigned int p = 0; p < _numParticles; p++) { | 133 | for (unsigned int p = 0; p < _numParticles; p++) { |
| 105 | 134 | ||
| 106 | float radian = ((float)p / (float)_numParticles) * PI_TIMES_TWO; | 135 | float radian = ((float)p / (float)_numParticles) * PI_TIMES_TWO; |
| 107 | float wave = sinf(radian); | 136 | float wave = sinf(radian); |
| 137 | |||
| 108 | float red = 0.5f + 0.5f * wave; | 138 | float red = 0.5f + 0.5f * wave; |
| 109 | float green = 0.3f + 0.3f * wave; | 139 | float green = 0.3f + 0.3f * wave; |
| 110 | float blue = 0.2f - 0.2f * wave; | 140 | float blue = 0.2f - 0.2f * wave; |
| 111 | _particle[p].color = glm::vec3(red, green, blue); | 141 | float alpha = 1.0f; |
| 142 | |||
| 143 | _particle[p].color = glm::vec4(red, green, blue, alpha); | ||
| 112 | } | 144 | } |
| 113 | } | 145 | } |
| 114 | 146 | ||
| 115 | 147 | ||
| 116 | |||
| 117 | |||
| 118 | |||
| 119 | |||
| 120 | void ParticleSystem::runSpecialEffectsTest(float deltaTime) { | 148 | void ParticleSystem::runSpecialEffectsTest(float deltaTime) { |
| 121 | 149 | ||
| 122 | _timer += deltaTime; | 150 | _timer += deltaTime; |
| @@ -130,13 +158,13 @@ void ParticleSystem::runSpecialEffectsTest(float deltaTime) { · 7 unmodified lines | |||
| 130 | 158 | ||
| 131 | _emitter[0].rotation = glm::quat(glm::radians(tilt)); | 159 | _emitter[0].rotation = glm::quat(glm::radians(tilt)); |
| 132 | 160 | ||
| 133 | _gravity = 0.0f + 0.02f * sinf( _timer * 0.52f ); | 161 | _gravity = 0.0f + DEFAULT_PARTICLE_GRAVITY * sinf( _timer * 0.52f ); |
| 134 | _airFriction = 3.0f + 1.0f * sinf( _timer * 0.32f ); | 162 | _airFriction = (DEFAULT_PARTICLE_AIR_FRICTION + 0.5f) + 2.0f * sinf( _timer * 0.32f ); |
| 135 | _jitter = 0.05f + 0.05f * sinf( _timer * 0.42f ); | 163 | _jitter = DEFAULT_PARTICLE_JITTER + DEFAULT_PARTICLE_JITTER * sinf( _timer * 0.42f ); |
| 136 | _homeAttraction = 0.01f + 0.01f * cosf( _timer * 0.6f ); | 164 | _emitterAttraction = 0.015f + 0.015f * cosf( _timer * 0.6f ); |
| 137 | _tornadoForce = 0.0f + 0.03f * sinf( _timer * 0.7f ); | 165 | _tornadoForce = 0.0f + 0.03f * sinf( _timer * 0.7f ); |
| 138 | _neighborAttraction = 0.1f + 0.1f * cosf( _timer * 0.8f ); | 166 | _neighborAttraction = 0.1f + 0.1f * cosf( _timer * 0.8f ); |
| 139 | _neighborRepulsion = 0.4f + 0.3f * sinf( _timer * 0.4f ); | 167 | _neighborRepulsion = 0.2f + 0.2f * sinf( _timer * 0.4f ); |
| 140 | 168 | ||
| 141 | if (_gravity < 0.0f) { | 169 | if (_gravity < 0.0f) { |
| 142 | _gravity = 0.0f; | 170 | _gravity = 0.0f; |
| @@ -144,10 +172,13 @@ void ParticleSystem::runSpecialEffectsTest(float deltaTime) { · 1 unmodified line | |||
| 144 | } | 172 | } |
| 145 | 173 | ||
| 146 | 174 | ||
| 147 | |||
| 148 | void ParticleSystem::updateParticle(int p, float deltaTime) { | 175 | void ParticleSystem::updateParticle(int p, float deltaTime) { |
| 149 | 176 | ||
| 150 | _particle[p].age += deltaTime; | 177 | _particle[p].age += deltaTime; |
| 178 | |||
| 179 | if (_particle[p].age > _particle[p].lifespan) { | ||
| 180 | killParticle(p); | ||
| 181 | } | ||
| 151 | 182 | ||
| 152 | // apply random jitter | 183 | // apply random jitter |
| 153 | _particle[p].velocity += | 184 | _particle[p].velocity += |
| @@ -160,7 +191,7 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 6 unmodified lines | |||
| 160 | 191 | ||
| 161 | // apply attraction to home position | 192 | // apply attraction to home position |
| 162 | glm::vec3 vectorToHome = _emitter[_particle[p].emitterIndex].position - _particle[p].position; | 193 | glm::vec3 vectorToHome = _emitter[_particle[p].emitterIndex].position - _particle[p].position; |
| 163 | _particle[p].velocity += vectorToHome * _homeAttraction * deltaTime; | 194 | _particle[p].velocity += vectorToHome * _emitterAttraction * deltaTime; |
| 164 | 195 | ||
| 165 | // apply neighbor attraction | 196 | // apply neighbor attraction |
| 166 | int neighbor = p + 1; | 197 | int neighbor = p + 1; |
| @@ -189,7 +220,7 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 22 unmodified lines | |||
| 189 | } | 220 | } |
| 190 | 221 | ||
| 191 | // apply gravity | 222 | // apply gravity |
| 192 | _particle[p].velocity.y -= _gravity * deltaTime; | 223 | _particle[p].velocity -= _upDirection * _gravity * deltaTime; |
| 193 | 224 | ||
| 194 | // update position by velocity | 225 | // update position by velocity |
| 195 | _particle[p].position += _particle[p].velocity; | 226 | _particle[p].position += _particle[p].velocity; |
| @@ -239,11 +270,9 @@ void ParticleSystem::render() { · 43 unmodified lines | |||
| 239 | } | 270 | } |
| 240 | } | 271 | } |
| 241 | 272 | ||
| 242 | |||
| 243 | |||
| 244 | void ParticleSystem::renderParticle(int p) { | 273 | void ParticleSystem::renderParticle(int p) { |
| 245 | 274 | ||
| 246 | glColor3f(_particle[p].color.x, _particle[p].color.y, _particle[p].color.z); | 275 | glColor4f(_particle[p].color.r, _particle[p].color.g, _particle[p].color.b, _particle[p].color.a ); |
| 247 | glPushMatrix(); | 276 | glPushMatrix(); |
| 248 | glTranslatef(_particle[p].position.x, _particle[p].position.y, _particle[p].position.z); | 277 | glTranslatef(_particle[p].position.x, _particle[p].position.y, _particle[p].position.z); |
| 249 | glutSolidSphere(_particle[p].radius, 6, 6); | 278 | glutSolidSphere(_particle[p].radius, 6, 6); |