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 | 14 | const float DEFAULT_PARTICLE_BOUNCE = 1.0f; |
| 15 | 15 | const float DEFAULT_PARTICLE_AIR_FRICTION = 2.0f; |
| 16 | −const float DEFAULT_PARTICLE_JITTER = 0.05f; | |
| 17 | 16 | const float DEFAULT_PARTICLE_GRAVITY = 0.05f; |
| 18 | 17 | |
| 19 | 18 | ParticleSystem::ParticleSystem() { |
| 20 | 19 | |
| 21 | − _timer = 0.0f; | |
| 22 | − _numEmitters = 0; | |
| 23 | − _gravity = DEFAULT_PARTICLE_GRAVITY; | |
| 24 | − _bounce = DEFAULT_PARTICLE_BOUNCE; | |
| 25 | − _airFriction = DEFAULT_PARTICLE_AIR_FRICTION; | |
| 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 | − | |
| 20 | + _timer = 0.0f; | |
| 21 | + _numEmitters = 0; | |
| 22 | + _numParticles = 0; | |
| 23 | + _upDirection = glm::vec3(0.0f, 1.0f, 0.0f); // default | |
| 24 | + | |
| 37 | 25 | for (unsigned int e = 0; e < MAX_EMITTERS; e++) { |
| 38 | − _emitter[e].position = glm::vec3(0.0f, 0.0f, 0.0f); | |
| 39 | − _emitter[e].rotation = glm::quat(); | |
| 40 | − _emitter[e].right = IDENTITY_RIGHT; | |
| 41 | − _emitter[e].up = IDENTITY_UP; | |
| 42 | − _emitter[e].front = IDENTITY_FRONT; | |
| 26 | + _emitter[e].position = glm::vec3(0.0f, 0.0f, 0.0f); | |
| 27 | + _emitter[e].rotation = glm::quat(); | |
| 28 | + _emitter[e].right = IDENTITY_RIGHT; | |
| 29 | + _emitter[e].up = IDENTITY_UP; | |
| 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 | 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 | 71 | // update emitters |
| 71 | 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 | 78 | // update particles |
| 76 | 79 | for (unsigned int p = 0; p < _numParticles; p++) { |
| 77 | 80 | if (_particle[p].alive) { |
| @@ -91,22 +94,23 @@ void ParticleSystem::updateEmitter(int e, float deltaTime) { · 13 unmodified lines | ||
| 91 | 94 | void ParticleSystem::emitParticlesNow(int e, int num, float radius, glm::vec4 color, glm::vec3 velocity, float lifespan) { |
| 92 | 95 | |
| 93 | 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 | 103 | for (unsigned int p = 0; p < MAX_PARTICLES; p++) { |
| 101 | 104 | if (!_particle[p].alive) { |
| 102 | 105 | |
| 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; | |
| 106 | + _particle[p].emitterIndex = e; | |
| 107 | + _particle[p].lifespan = lifespan; | |
| 108 | + _particle[p].alive = true; | |
| 109 | + _particle[p].age = 0.0f; | |
| 110 | + _particle[p].position = position; | |
| 111 | + _particle[p].velocity = velocity; | |
| 112 | + _particle[p].radius = radius; | |
| 113 | + _particle[p].color = color; | |
| 110 | 114 | |
| 111 | 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 | 154 | _timer += deltaTime; |
| 151 | − | |
| 152 | − glm::vec3 tilt = glm::vec3 | |
| 153 | − ( | |
| 154 | − 30.0f * sinf( _timer * 0.55f ), | |
| 155 | − 0.0f, | |
| 156 | − 30.0f * cosf( _timer * 0.75f ) | |
| 157 | − ); | |
| 158 | − | |
| 159 | − _emitter[0].rotation = glm::quat(glm::radians(tilt)); | |
| 160 | − | |
| 161 | − _gravity = 0.0f + DEFAULT_PARTICLE_GRAVITY * sinf( _timer * 0.52f ); | |
| 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; | |
| 155 | + | |
| 156 | + _emitter[e].gravity = 0.0f + DEFAULT_PARTICLE_GRAVITY * sinf( _timer * 0.52f ); | |
| 157 | + _emitter[e].airFriction = (DEFAULT_PARTICLE_AIR_FRICTION + 0.5f) + 2.0f * sinf( _timer * 0.32f ); | |
| 158 | + _emitter[e].jitter = 0.05f + 0.05f * sinf( _timer * 0.42f ); | |
| 159 | + _emitter[e].emitterAttraction = 0.015f + 0.015f * cosf( _timer * 0.6f ); | |
| 160 | + _emitter[e].tornadoForce = 0.0f + 0.03f * sinf( _timer * 0.7f ); | |
| 161 | + _emitter[e].neighborAttraction = 0.1f + 0.1f * cosf( _timer * 0.8f ); | |
| 162 | + _emitter[e].neighborRepulsion = 0.2f + 0.2f * sinf( _timer * 0.4f ); | |
| 163 | + | |
| 164 | + if (_emitter[e].gravity < 0.0f) { | |
| 165 | + _emitter[e].gravity = 0.0f; | |
| 171 | 166 | } |
| 172 | 167 | } |
| 173 | 168 | |
| @@ -179,40 +174,45 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 5 unmodified lines | ||
| 179 | 174 | if (_particle[p].age > _particle[p].lifespan) { |
| 180 | 175 | killParticle(p); |
| 181 | 176 | } |
| 177 | + | |
| 178 | + Emitter myEmitter = _emitter[_particle[p].emitterIndex]; | |
| 182 | 179 | |
| 183 | 180 | // apply random jitter |
| 184 | 181 | _particle[p].velocity += |
| 185 | 182 | glm::vec3 |
| 186 | 183 | ( |
| 187 | − -_jitter * ONE_HALF + _jitter * randFloat(), | |
| 188 | − -_jitter * ONE_HALF + _jitter * randFloat(), | |
| 189 | − -_jitter * ONE_HALF + _jitter * randFloat() | |
| 184 | + -myEmitter.jitter * ONE_HALF + myEmitter.jitter * randFloat(), | |
| 185 | + -myEmitter.jitter * ONE_HALF + myEmitter.jitter * randFloat(), | |
| 186 | + -myEmitter.jitter * ONE_HALF + myEmitter.jitter * randFloat() | |
| 190 | 187 | ) * deltaTime; |
| 191 | 188 | |
| 192 | 189 | // apply attraction to home position |
| 193 | − glm::vec3 vectorToHome = _emitter[_particle[p].emitterIndex].position - _particle[p].position; | |
| 194 | − _particle[p].velocity += vectorToHome * _emitterAttraction * deltaTime; | |
| 190 | + glm::vec3 vectorToHome = myEmitter.position - _particle[p].position; | |
| 191 | + _particle[p].velocity += vectorToHome * myEmitter.emitterAttraction * deltaTime; | |
| 195 | 192 | |
| 196 | 193 | // apply neighbor attraction |
| 197 | 194 | int neighbor = p + 1; |
| 198 | 195 | if (neighbor == _numParticles ) { |
| 199 | 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); | |
| 206 | − if (distanceToNeighbor > 0.0f) { | |
| 207 | − _particle[neighbor].velocity += (vectorToNeighbor / ( 1.0f + distanceToNeighbor * distanceToNeighbor)) * _neighborRepulsion * deltaTime; | |
| 204 | + float distanceToNeighbor = glm::length(vectorToNeighbor); | |
| 205 | + if (distanceToNeighbor > 0.0f) { | |
| 206 | + _particle[neighbor].velocity += (vectorToNeighbor / ( 1.0f + distanceToNeighbor * distanceToNeighbor)) * myEmitter.neighborRepulsion * deltaTime; | |
| 207 | + } | |
| 208 | 208 | } |
| 209 | 209 | |
| 210 | 210 | // apply tornado force |
| 211 | − glm::vec3 tornadoDirection = glm::cross(vectorToHome, _emitter[_particle[p].emitterIndex].up); | |
| 212 | − _particle[p].velocity += tornadoDirection * _tornadoForce * deltaTime; | |
| 211 | + glm::vec3 tornadoDirection = glm::cross(vectorToHome, myEmitter.up); | |
| 212 | + _particle[p].velocity += tornadoDirection * myEmitter.tornadoForce * deltaTime; | |
| 213 | 213 | |
| 214 | 214 | // apply air friction |
| 215 | − float drag = 1.0 - _airFriction * deltaTime; | |
| 215 | + float drag = 1.0 - myEmitter.airFriction * deltaTime; | |
| 216 | 216 | if (drag < 0.0f) { |
| 217 | 217 | _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); |
| 218 | 218 | } else { |
| @@ -220,7 +220,7 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 1 unmodified line | ||
| 220 | 220 | } |
| 221 | 221 | |
| 222 | 222 | // apply gravity |
| 223 | − _particle[p].velocity -= _upDirection * _gravity * deltaTime; | |
| 223 | + _particle[p].velocity -= _upDirection * myEmitter.gravity * deltaTime; | |
| 224 | 224 | |
| 225 | 225 | // update position by velocity |
| 226 | 226 | _particle[p].position += _particle[p].velocity; |
| @@ -230,36 +230,38 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 3 unmodified lines | ||
| 230 | 230 | _particle[p].position.y = _particle[p].radius; |
| 231 | 231 | |
| 232 | 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 | 237 | // collision with sphere |
| 238 | − if (_usingCollisionSphere) { | |
| 239 | − glm::vec3 vectorToSphereCenter = _collisionSpherePosition - _particle[p].position; | |
| 238 | + if (myEmitter.usingCollisionSphere) { | |
| 239 | + glm::vec3 vectorToSphereCenter = myEmitter.collisionSpherePosition - _particle[p].position; | |
| 240 | 240 | float distanceToSphereCenter = glm::length(vectorToSphereCenter); |
| 241 | − float combinedRadius = _collisionSphereRadius + _particle[p].radius; | |
| 241 | + float combinedRadius = myEmitter.collisionSphereRadius + _particle[p].radius; | |
| 242 | 242 | if (distanceToSphereCenter < combinedRadius) { |
| 243 | 243 | |
| 244 | 244 | if (distanceToSphereCenter > 0.0f){ |
| 245 | 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) { | |
| 253 | − _usingCollisionSphere = true; | |
| 254 | − _collisionSpherePosition = position; | |
| 255 | − _collisionSphereRadius = radius; | |
| 252 | +void ParticleSystem::setCollisionSphere(int e, glm::vec3 position, float radius) { | |
| 253 | + _emitter[e].usingCollisionSphere = true; | |
| 254 | + _emitter[e].collisionSpherePosition = position; | |
| 255 | + _emitter[e].collisionSphereRadius = radius; | |
| 256 | 256 | } |
| 257 | 257 | |
| 258 | 258 | void ParticleSystem::render() { |
| 259 | 259 | |
| 260 | 260 | // render the emitters |
| 261 | 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 | 267 | // render the particles |