Showing the changes to interface/src/ParticleSystem.cpp (1 of 4 files). Show all
Unified · Split
| @@ -13,33 +13,34 @@ · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | const float DEFAULT_PARTICLE_BOUNCE = 1.0f; | 14 | const float DEFAULT_PARTICLE_BOUNCE = 1.0f; |
| 15 | const float DEFAULT_PARTICLE_AIR_FRICTION = 2.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; | 16 | const float DEFAULT_PARTICLE_GRAVITY = 0.05f; |
| 18 | 17 | ||
| 19 | ParticleSystem::ParticleSystem() { | 18 | ParticleSystem::ParticleSystem() { |
| 20 | 19 | ||
| 21 | _timer = 0.0f; | 20 | _timer = 0.0f; |
| 22 | _numEmitters = 0; | 21 | _numEmitters = 0; |
| 23 | _gravity = DEFAULT_PARTICLE_GRAVITY; | 22 | _numParticles = 0; |
| 24 | _bounce = DEFAULT_PARTICLE_BOUNCE; | 23 | _upDirection = glm::vec3(0.0f, 1.0f, 0.0f); // default |
| 25 | _airFriction = DEFAULT_PARTICLE_AIR_FRICTION; | 24 | |
| 26 | _jitter = DEFAULT_PARTICLE_JITTER; | ||
| 27 | _emitterAttraction = 0.0f; | ||
| 28 | _tornadoForce = 0.0f; | ||
| 29 | _neighborAttraction = 0.0f; | ||
| 30 | _neighborRepulsion = 0.0f; | ||
| 31 | _collisionSphereRadius = 0.0f; | ||
| 32 | _collisionSpherePosition = glm::vec3(0.0f, 0.0f, 0.0f); | ||
| 33 | _numParticles = 0; | ||
| 34 | _usingCollisionSphere = false; | ||
| 35 | _upDirection = glm::vec3(0.0f, 1.0f, 0.0f); // default | ||
| 36 | |||
| 37 | for (unsigned int e = 0; e < MAX_EMITTERS; e++) { | 25 | for (unsigned int e = 0; e < MAX_EMITTERS; e++) { |
| 38 | _emitter[e].position = glm::vec3(0.0f, 0.0f, 0.0f); | 26 | _emitter[e].position = glm::vec3(0.0f, 0.0f, 0.0f); |
| 39 | _emitter[e].rotation = glm::quat(); | 27 | _emitter[e].rotation = glm::quat(); |
| 40 | _emitter[e].right = IDENTITY_RIGHT; | 28 | _emitter[e].right = IDENTITY_RIGHT; |
| 41 | _emitter[e].up = IDENTITY_UP; | 29 | _emitter[e].up = IDENTITY_UP; |
| 42 | _emitter[e].front = IDENTITY_FRONT; | 30 | _emitter[e].front = IDENTITY_FRONT; |
| 31 | _emitter[e].bounce = DEFAULT_PARTICLE_BOUNCE; | ||
| 32 | _emitter[e].airFriction = DEFAULT_PARTICLE_AIR_FRICTION; | ||
| 33 | _emitter[e].gravity = DEFAULT_PARTICLE_GRAVITY; | ||
| 34 | _emitter[e].jitter = 0.0f; | ||
| 35 | _emitter[e].emitterAttraction = 0.0f; | ||
| 36 | _emitter[e].tornadoForce = 0.0f; | ||
| 37 | _emitter[e].neighborAttraction = 0.0f; | ||
| 38 | _emitter[e].neighborRepulsion = 0.0f; | ||
| 39 | _emitter[e].collisionSphereRadius = 0.0f; | ||
| 40 | _emitter[e].collisionSpherePosition = glm::vec3(0.0f, 0.0f, 0.0f); | ||
| 41 | _emitter[e].usingCollisionSphere = false; | ||
| 42 | _emitter[e].showingEmitter = false; | ||
| 43 | |||
| 43 | }; | 44 | }; |
| 44 | 45 | ||
| 45 | for (unsigned int p = 0; p < MAX_PARTICLES; p++) { | 46 | for (unsigned int p = 0; p < MAX_PARTICLES; p++) { |
| @@ -69,9 +70,11 @@ void ParticleSystem::simulate(float deltaTime) { · 23 unmodified lines | |||
| 69 | 70 | ||
| 70 | // update emitters | 71 | // update emitters |
| 71 | for (unsigned int e = 0; e < _numEmitters; e++) { | 72 | for (unsigned int e = 0; e < _numEmitters; e++) { |
| 72 | updateEmitter(e, deltaTime); | 73 | updateEmitter(e, deltaTime); |
| 73 | } | 74 | } |
| 74 | 75 | ||
| 76 | runSpecialEffectsTest(0, deltaTime); | ||
| 77 | |||
| 75 | // update particles | 78 | // update particles |
| 76 | for (unsigned int p = 0; p < _numParticles; p++) { | 79 | for (unsigned int p = 0; p < _numParticles; p++) { |
| 77 | if (_particle[p].alive) { | 80 | if (_particle[p].alive) { |
| @@ -91,22 +94,23 @@ void ParticleSystem::updateEmitter(int e, float deltaTime) { · 13 unmodified lines | |||
| 91 | void ParticleSystem::emitParticlesNow(int e, int num, float radius, glm::vec4 color, glm::vec3 velocity, float lifespan) { | 94 | void ParticleSystem::emitParticlesNow(int e, int num, float radius, glm::vec4 color, glm::vec3 velocity, float lifespan) { |
| 92 | 95 | ||
| 93 | for (unsigned int p = 0; p < num; p++) { | 96 | for (unsigned int p = 0; p < num; p++) { |
| 94 | createParticle(_emitter[e].position, velocity, radius, color, lifespan); | 97 | createParticle(e, _emitter[e].position, velocity, radius, color, lifespan); |
| 95 | } | 98 | } |
| 96 | } | 99 | } |
| 97 | 100 | ||
| 98 | void ParticleSystem::createParticle(glm::vec3 position, glm::vec3 velocity, float radius, glm::vec4 color, float lifespan) { | 101 | void ParticleSystem::createParticle(int e, glm::vec3 position, glm::vec3 velocity, float radius, glm::vec4 color, float lifespan) { |
| 99 | 102 | ||
| 100 | for (unsigned int p = 0; p < MAX_PARTICLES; p++) { | 103 | for (unsigned int p = 0; p < MAX_PARTICLES; p++) { |
| 101 | if (!_particle[p].alive) { | 104 | if (!_particle[p].alive) { |
| 102 | 105 | ||
| 103 | _particle[p].lifespan = lifespan; | 106 | _particle[p].emitterIndex = e; |
| 104 | _particle[p].alive = true; | 107 | _particle[p].lifespan = lifespan; |
| 105 | _particle[p].age = 0.0f; | 108 | _particle[p].alive = true; |
| 106 | _particle[p].position = position; | 109 | _particle[p].age = 0.0f; |
| 107 | _particle[p].velocity = velocity; | 110 | _particle[p].position = position; |
| 108 | _particle[p].radius = radius; | 111 | _particle[p].velocity = velocity; |
| 109 | _particle[p].color = color; | 112 | _particle[p].radius = radius; |
| 113 | _particle[p].color = color; | ||
| 110 | 114 | ||
| 111 | _numParticles ++; | 115 | _numParticles ++; |
| 112 | 116 | ||
| @@ -145,29 +149,20 @@ void ParticleSystem::setOrangeBlueColorPalette() { · 32 unmodified lines | |||
| 145 | } | 149 | } |
| 146 | 150 | ||
| 147 | 151 | ||
| 148 | void ParticleSystem::runSpecialEffectsTest(float deltaTime) { | 152 | void ParticleSystem::runSpecialEffectsTest(int e, float deltaTime) { |
| 149 | 153 | ||
| 150 | _timer += deltaTime; | 154 | _timer += deltaTime; |
| 151 | 155 | ||
| 152 | glm::vec3 tilt = glm::vec3 | 156 | _emitter[e].gravity = 0.0f + DEFAULT_PARTICLE_GRAVITY * sinf( _timer * 0.52f ); |
| 153 | ( | 157 | _emitter[e].airFriction = (DEFAULT_PARTICLE_AIR_FRICTION + 0.5f) + 2.0f * sinf( _timer * 0.32f ); |
| 154 | 30.0f * sinf( _timer * 0.55f ), | 158 | _emitter[e].jitter = 0.05f + 0.05f * sinf( _timer * 0.42f ); |
| 155 | 0.0f, | 159 | _emitter[e].emitterAttraction = 0.015f + 0.015f * cosf( _timer * 0.6f ); |
| 156 | 30.0f * cosf( _timer * 0.75f ) | 160 | _emitter[e].tornadoForce = 0.0f + 0.03f * sinf( _timer * 0.7f ); |
| 157 | ); | 161 | _emitter[e].neighborAttraction = 0.1f + 0.1f * cosf( _timer * 0.8f ); |
| 158 | 162 | _emitter[e].neighborRepulsion = 0.2f + 0.2f * sinf( _timer * 0.4f ); | |
| 159 | _emitter[0].rotation = glm::quat(glm::radians(tilt)); | 163 | |
| 160 | 164 | if (_emitter[e].gravity < 0.0f) { | |
| 161 | _gravity = 0.0f + DEFAULT_PARTICLE_GRAVITY * sinf( _timer * 0.52f ); | 165 | _emitter[e].gravity = 0.0f; |
| 162 | _airFriction = (DEFAULT_PARTICLE_AIR_FRICTION + 0.5f) + 2.0f * sinf( _timer * 0.32f ); | ||
| 163 | _jitter = DEFAULT_PARTICLE_JITTER + DEFAULT_PARTICLE_JITTER * sinf( _timer * 0.42f ); | ||
| 164 | _emitterAttraction = 0.015f + 0.015f * cosf( _timer * 0.6f ); | ||
| 165 | _tornadoForce = 0.0f + 0.03f * sinf( _timer * 0.7f ); | ||
| 166 | _neighborAttraction = 0.1f + 0.1f * cosf( _timer * 0.8f ); | ||
| 167 | _neighborRepulsion = 0.2f + 0.2f * sinf( _timer * 0.4f ); | ||
| 168 | |||
| 169 | if (_gravity < 0.0f) { | ||
| 170 | _gravity = 0.0f; | ||
| 171 | } | 166 | } |
| 172 | } | 167 | } |
| 173 | 168 | ||
| @@ -179,40 +174,45 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 5 unmodified lines | |||
| 179 | if (_particle[p].age > _particle[p].lifespan) { | 174 | if (_particle[p].age > _particle[p].lifespan) { |
| 180 | killParticle(p); | 175 | killParticle(p); |
| 181 | } | 176 | } |
| 177 | |||
| 178 | Emitter myEmitter = _emitter[_particle[p].emitterIndex]; | ||
| 182 | 179 | ||
| 183 | // apply random jitter | 180 | // apply random jitter |
| 184 | _particle[p].velocity += | 181 | _particle[p].velocity += |
| 185 | glm::vec3 | 182 | glm::vec3 |
| 186 | ( | 183 | ( |
| 187 | -_jitter * ONE_HALF + _jitter * randFloat(), | 184 | -myEmitter.jitter * ONE_HALF + myEmitter.jitter * randFloat(), |
| 188 | -_jitter * ONE_HALF + _jitter * randFloat(), | 185 | -myEmitter.jitter * ONE_HALF + myEmitter.jitter * randFloat(), |
| 189 | -_jitter * ONE_HALF + _jitter * randFloat() | 186 | -myEmitter.jitter * ONE_HALF + myEmitter.jitter * randFloat() |
| 190 | ) * deltaTime; | 187 | ) * deltaTime; |
| 191 | 188 | ||
| 192 | // apply attraction to home position | 189 | // apply attraction to home position |
| 193 | glm::vec3 vectorToHome = _emitter[_particle[p].emitterIndex].position - _particle[p].position; | 190 | glm::vec3 vectorToHome = myEmitter.position - _particle[p].position; |
| 194 | _particle[p].velocity += vectorToHome * _emitterAttraction * deltaTime; | 191 | _particle[p].velocity += vectorToHome * myEmitter.emitterAttraction * deltaTime; |
| 195 | 192 | ||
| 196 | // apply neighbor attraction | 193 | // apply neighbor attraction |
| 197 | int neighbor = p + 1; | 194 | int neighbor = p + 1; |
| 198 | if (neighbor == _numParticles ) { | 195 | if (neighbor == _numParticles ) { |
| 199 | neighbor = 0; | 196 | neighbor = 0; |
| 200 | } | 197 | } |
| 201 | glm::vec3 vectorToNeighbor = _particle[p].position - _particle[neighbor].position; | ||
| 202 | 198 | ||
| 203 | _particle[p].velocity -= vectorToNeighbor * _neighborAttraction * deltaTime; | 199 | if ( _particle[neighbor].emitterIndex == _particle[p].emitterIndex) { |
| 200 | glm::vec3 vectorToNeighbor = _particle[p].position - _particle[neighbor].position; | ||
| 201 | |||
| 202 | _particle[p].velocity -= vectorToNeighbor * myEmitter.neighborAttraction * deltaTime; | ||
| 204 | 203 | ||
| 205 | float distanceToNeighbor = glm::length(vectorToNeighbor); | 204 | float distanceToNeighbor = glm::length(vectorToNeighbor); |
| 206 | if (distanceToNeighbor > 0.0f) { | 205 | if (distanceToNeighbor > 0.0f) { |
| 207 | _particle[neighbor].velocity += (vectorToNeighbor / ( 1.0f + distanceToNeighbor * distanceToNeighbor)) * _neighborRepulsion * deltaTime; | 206 | _particle[neighbor].velocity += (vectorToNeighbor / ( 1.0f + distanceToNeighbor * distanceToNeighbor)) * myEmitter.neighborRepulsion * deltaTime; |
| 207 | } | ||
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | // apply tornado force | 210 | // apply tornado force |
| 211 | glm::vec3 tornadoDirection = glm::cross(vectorToHome, _emitter[_particle[p].emitterIndex].up); | 211 | glm::vec3 tornadoDirection = glm::cross(vectorToHome, myEmitter.up); |
| 212 | _particle[p].velocity += tornadoDirection * _tornadoForce * deltaTime; | 212 | _particle[p].velocity += tornadoDirection * myEmitter.tornadoForce * deltaTime; |
| 213 | 213 | ||
| 214 | // apply air friction | 214 | // apply air friction |
| 215 | float drag = 1.0 - _airFriction * deltaTime; | 215 | float drag = 1.0 - myEmitter.airFriction * deltaTime; |
| 216 | if (drag < 0.0f) { | 216 | if (drag < 0.0f) { |
| 217 | _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); | 217 | _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); |
| 218 | } else { | 218 | } else { |
| @@ -220,7 +220,7 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 1 unmodified line | |||
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | // apply gravity | 222 | // apply gravity |
| 223 | _particle[p].velocity -= _upDirection * _gravity * deltaTime; | 223 | _particle[p].velocity -= _upDirection * myEmitter.gravity * deltaTime; |
| 224 | 224 | ||
| 225 | // update position by velocity | 225 | // update position by velocity |
| 226 | _particle[p].position += _particle[p].velocity; | 226 | _particle[p].position += _particle[p].velocity; |
| @@ -230,36 +230,38 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 3 unmodified lines | |||
| 230 | _particle[p].position.y = _particle[p].radius; | 230 | _particle[p].position.y = _particle[p].radius; |
| 231 | 231 | ||
| 232 | if (_particle[p].velocity.y < 0.0f) { | 232 | if (_particle[p].velocity.y < 0.0f) { |
| 233 | _particle[p].velocity.y *= -_bounce; | 233 | _particle[p].velocity.y *= -myEmitter.bounce; |
| 234 | } | 234 | } |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | // collision with sphere | 237 | // collision with sphere |
| 238 | if (_usingCollisionSphere) { | 238 | if (myEmitter.usingCollisionSphere) { |
| 239 | glm::vec3 vectorToSphereCenter = _collisionSpherePosition - _particle[p].position; | 239 | glm::vec3 vectorToSphereCenter = myEmitter.collisionSpherePosition - _particle[p].position; |
| 240 | float distanceToSphereCenter = glm::length(vectorToSphereCenter); | 240 | float distanceToSphereCenter = glm::length(vectorToSphereCenter); |
| 241 | float combinedRadius = _collisionSphereRadius + _particle[p].radius; | 241 | float combinedRadius = myEmitter.collisionSphereRadius + _particle[p].radius; |
| 242 | if (distanceToSphereCenter < combinedRadius) { | 242 | if (distanceToSphereCenter < combinedRadius) { |
| 243 | 243 | ||
| 244 | if (distanceToSphereCenter > 0.0f){ | 244 | if (distanceToSphereCenter > 0.0f){ |
| 245 | glm::vec3 directionToSphereCenter = vectorToSphereCenter / distanceToSphereCenter; | 245 | glm::vec3 directionToSphereCenter = vectorToSphereCenter / distanceToSphereCenter; |
| 246 | _particle[p].position = _collisionSpherePosition - directionToSphereCenter * combinedRadius; | 246 | _particle[p].position = myEmitter.collisionSpherePosition - directionToSphereCenter * combinedRadius; |
| 247 | } | 247 | } |
| 248 | } | 248 | } |
| 249 | } | 249 | } |
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | void ParticleSystem::setCollisionSphere(glm::vec3 position, float radius) { | 252 | void ParticleSystem::setCollisionSphere(int e, glm::vec3 position, float radius) { |
| 253 | _usingCollisionSphere = true; | 253 | _emitter[e].usingCollisionSphere = true; |
| 254 | _collisionSpherePosition = position; | 254 | _emitter[e].collisionSpherePosition = position; |
| 255 | _collisionSphereRadius = radius; | 255 | _emitter[e].collisionSphereRadius = radius; |
| 256 | } | 256 | } |
| 257 | 257 | ||
| 258 | void ParticleSystem::render() { | 258 | void ParticleSystem::render() { |
| 259 | 259 | ||
| 260 | // render the emitters | 260 | // render the emitters |
| 261 | for (unsigned int e = 0; e < _numEmitters; e++) { | 261 | for (unsigned int e = 0; e < _numEmitters; e++) { |
| 262 | renderEmitter(e, 0.2f); | 262 | if (_emitter[e].showingEmitter) { |
| 263 | renderEmitter(e, 0.2f); | ||
| 264 | } | ||
| 263 | }; | 265 | }; |
| 264 | 266 | ||
| 265 | // render the particles | 267 | // render the particles |