Showing the changes to interface/src/ParticleSystem.cpp (1 of 3 files). Show all
Unified · Split
| @@ -8,59 +8,91 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <glm/glm.hpp> |
| 9 | 9 | #include "InterfaceConfig.h" |
| 10 | 10 | #include <SharedUtil.h> |
| 11 | − | |
| 12 | 11 | #include "ParticleSystem.h" |
| 12 | +#include "Application.h" | |
| 13 | 13 | |
| 14 | 14 | ParticleSystem::ParticleSystem() { |
| 15 | 15 | |
| 16 | − _numberOfParticles = 1500; | |
| 17 | − assert(_numberOfParticles <= MAX_PARTICLES); | |
| 18 | − | |
| 19 | − _bounce = 0.9f; | |
| 20 | − _timer = 0.0f; | |
| 21 | − _airFriction = 6.0f; | |
| 22 | − _jitter = 0.1f; | |
| 23 | − _homeAttraction = 0.0f; | |
| 24 | − _tornadoForce = 0.0f; | |
| 25 | − _neighborAttraction = 0.02f; | |
| 26 | − _neighborRepulsion = 0.9f; | |
| 27 | − _tornadoAxis = glm::normalize(glm::vec3(0.1f, 1.0f, 0.1f)); | |
| 28 | − _home = glm::vec3(5.0f, 1.0f, 5.0f); | |
| 29 | − | |
| 30 | − _TEST_bigSphereRadius = 0.5f; | |
| 16 | + _gravity = 0.005; | |
| 17 | + _numEmitters = 1; | |
| 18 | + _bounce = 0.9f; | |
| 19 | + _timer = 0.0f; | |
| 20 | + _airFriction = 6.0f; | |
| 21 | + _jitter = 0.1f; | |
| 22 | + _homeAttraction = 0.0f; | |
| 23 | + _tornadoForce = 0.0f; | |
| 24 | + _neighborAttraction = 0.02f; | |
| 25 | + _neighborRepulsion = 0.9f; | |
| 26 | + _TEST_bigSphereRadius = 0.5f; | |
| 31 | 27 | _TEST_bigSpherePosition = glm::vec3( 5.0f, _TEST_bigSphereRadius, 5.0f); |
| 32 | − | |
| 33 | − for (unsigned int p = 0; p < _numberOfParticles; p++) { | |
| 34 | − _particle[p].position = _home; | |
| 35 | − _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); | |
| 28 | + _numParticles = 1500; | |
| 29 | + | |
| 30 | + for (unsigned int e = 0; e < _numEmitters; e++) { | |
| 31 | + | |
| 32 | + _emitter[e].position = glm::vec3(0.0f, 0.0f, 0.0f); | |
| 33 | + _emitter[e].rotation = glm::quat(); | |
| 34 | + _emitter[e].right = IDENTITY_RIGHT; | |
| 35 | + _emitter[e].up = IDENTITY_UP; | |
| 36 | + _emitter[e].front = IDENTITY_FRONT; | |
| 37 | + }; | |
| 38 | + | |
| 39 | + for (unsigned int p = 0; p < _numParticles; p++) { | |
| 36 | 40 | |
| 37 | − float radian = ((float)p / (float)_numberOfParticles) * PI_TIMES_TWO; | |
| 41 | + float radian = ((float)p / (float)_numParticles) * PI_TIMES_TWO; | |
| 38 | 42 | float wave = sinf(radian); |
| 39 | 43 | |
| 40 | 44 | float red = 0.5f + 0.5f * wave; |
| 41 | 45 | float green = 0.3f + 0.3f * wave; |
| 42 | 46 | float blue = 0.2f - 0.2f * wave; |
| 43 | 47 | |
| 44 | − _particle[p].color = glm::vec3(red, green, blue); | |
| 45 | − _particle[p].age = 0.0f; | |
| 46 | − _particle[p].radius = 0.01f; | |
| 48 | + _particle[p].color = glm::vec3(red, green, blue); | |
| 49 | + _particle[p].age = 0.0f; | |
| 50 | + _particle[p].radius = 0.01f; | |
| 51 | + _particle[p].emitterIndex = 0; | |
| 52 | + _particle[p].position = glm::vec3(0.0f, 0.0f, 0.0f); | |
| 53 | + _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); | |
| 47 | 54 | } |
| 55 | + | |
| 56 | + assert(_numParticles <= MAX_PARTICLES); | |
| 57 | + assert(_numEmitters <= MAX_EMITTERS ); | |
| 48 | 58 | } |
| 49 | 59 | |
| 60 | + | |
| 50 | 61 | void ParticleSystem::simulate(float deltaTime) { |
| 51 | 62 | |
| 52 | − runSpecialEffectsTest(deltaTime); | |
| 53 | − | |
| 54 | − for (unsigned int p = 0; p < _numberOfParticles; p++) { | |
| 63 | + // update emitters | |
| 64 | + for (unsigned int e = 0; e < _numEmitters; e++) { | |
| 65 | + updateEmitter(e, deltaTime); | |
| 66 | + } | |
| 67 | + | |
| 68 | + // update particles | |
| 69 | + for (unsigned int p = 0; p < _numParticles; p++) { | |
| 55 | 70 | updateParticle(p, deltaTime); |
| 56 | 71 | } |
| 72 | + | |
| 73 | + // apply special effects | |
| 74 | + runSpecialEffectsTest(deltaTime); | |
| 57 | 75 | } |
| 58 | 76 | |
| 77 | +void ParticleSystem::updateEmitter(int e, float deltaTime) { | |
| 59 | 78 | |
| 79 | + _emitter[e].front = _emitter[e].rotation * IDENTITY_FRONT; | |
| 80 | + _emitter[e].right = _emitter[e].rotation * IDENTITY_RIGHT; | |
| 81 | + _emitter[e].up = _emitter[e].rotation * IDENTITY_UP; | |
| 82 | +} | |
| 60 | 83 | |
| 61 | 84 | void ParticleSystem::runSpecialEffectsTest(float deltaTime) { |
| 62 | − | |
| 85 | + | |
| 63 | 86 | _timer += deltaTime; |
| 87 | + | |
| 88 | + glm::vec3 tilt = glm::vec3 | |
| 89 | + ( | |
| 90 | + 30.0f * sinf( _timer * 0.55f ), | |
| 91 | + 0.0f, | |
| 92 | + 30.0f * cosf( _timer * 0.75f ) | |
| 93 | + ); | |
| 94 | + | |
| 95 | + _emitter[0].rotation = glm::quat(glm::radians(tilt)); | |
| 64 | 96 | |
| 65 | 97 | _gravity = 0.01f + 0.01f * sinf( _timer * 0.52f ); |
| 66 | 98 | _airFriction = 3.0f + 2.0f * sinf( _timer * 0.32f ); |
| @@ -69,13 +101,6 @@ void ParticleSystem::runSpecialEffectsTest(float deltaTime) { · 2 unmodified lines | ||
| 69 | 101 | _tornadoForce = 0.0f + 0.03f * sinf( _timer * 0.7f ); |
| 70 | 102 | _neighborAttraction = 0.1f + 0.1f * cosf( _timer * 0.8f ); |
| 71 | 103 | _neighborRepulsion = 0.4f + 0.3f * sinf( _timer * 0.4f ); |
| 72 | − | |
| 73 | − _tornadoAxis = glm::vec3 | |
| 74 | − ( | |
| 75 | − 0.0f + 0.5f * sinf( _timer * 0.55f ), | |
| 76 | − 1.0f, | |
| 77 | − 0.0f + 0.5f * cosf( _timer * 0.75f ) | |
| 78 | − ); | |
| 79 | 104 | } |
| 80 | 105 | |
| 81 | 106 | |
| @@ -95,12 +120,12 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 13 unmodified lines | ||
| 95 | 120 | |
| 96 | 121 | |
| 97 | 122 | // apply attraction to home position |
| 98 | − glm::vec3 vectorToHome = _home - _particle[p].position; | |
| 123 | + glm::vec3 vectorToHome = _emitter[_particle[p].emitterIndex].position - _particle[p].position; | |
| 99 | 124 | _particle[p].velocity += vectorToHome * _homeAttraction * deltaTime; |
| 100 | 125 | |
| 101 | 126 | // apply neighbor attraction |
| 102 | 127 | int neighbor = p + 1; |
| 103 | − if (neighbor == _numberOfParticles ) { | |
| 128 | + if (neighbor == _numParticles ) { | |
| 104 | 129 | neighbor = 0; |
| 105 | 130 | } |
| 106 | 131 | glm::vec3 vectorToNeighbor = _particle[p].position - _particle[neighbor].position; |
| @@ -113,8 +138,9 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 6 unmodified lines | ||
| 113 | 138 | } |
| 114 | 139 | |
| 115 | 140 | // apply tornado force |
| 116 | − glm::vec3 tornadoDirection = glm::cross(vectorToHome, _tornadoAxis); | |
| 117 | − _particle[p].velocity += tornadoDirection * _tornadoForce * deltaTime; | |
| 141 | + //glm::vec3 tornadoDirection = glm::cross(vectorToHome, _emitter[_particle[p].emitterIndex].up); | |
| 142 | + //_particle[p].velocity += tornadoDirection * _tornadoForce * deltaTime; | |
| 143 | + //_particle[p].velocity += _emitter[_particle[p].emitterIndex].up * _tornadoForce * deltaTime; | |
| 118 | 144 | |
| 119 | 145 | // apply air friction |
| 120 | 146 | float drag = 1.0 - _airFriction * deltaTime; |
| @@ -155,27 +181,67 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 34 unmodified lines | ||
| 155 | 181 | |
| 156 | 182 | void ParticleSystem::render() { |
| 157 | 183 | |
| 158 | − for (unsigned int p = 0; p < _numberOfParticles; p++) { | |
| 159 | − glColor3f(_particle[p].color.x, _particle[p].color.y, _particle[p].color.z); | |
| 160 | − glPushMatrix(); | |
| 161 | − glTranslatef(_particle[p].position.x, _particle[p].position.y, _particle[p].position.z); | |
| 162 | − glutSolidSphere(_particle[p].radius, 6, 6); | |
| 163 | − glPopMatrix(); | |
| 164 | − | |
| 165 | − // render velocity lines | |
| 166 | − glColor4f( _particle[p].color.x, _particle[p].color.y, _particle[p].color.z, 0.5f); | |
| 167 | − glm::vec3 end = _particle[p].position - _particle[p].velocity * 2.0f; | |
| 168 | − glBegin(GL_LINES); | |
| 169 | − glVertex3f(_particle[p].position.x, _particle[p].position.y, _particle[p].position.z); | |
| 170 | − glVertex3f(end.x, end.y, end.z); | |
| 171 | − | |
| 172 | − glEnd(); | |
| 173 | − | |
| 184 | + // render the emitters | |
| 185 | + for (unsigned int e = 0; e < _numEmitters; e++) { | |
| 186 | + renderEmitter(e, 0.2f); | |
| 187 | + }; | |
| 188 | + | |
| 189 | + // render the particles | |
| 190 | + for (unsigned int p = 0; p < _numParticles; p++) { | |
| 191 | + renderParticle(p); | |
| 174 | 192 | } |
| 175 | 193 | } |
| 176 | 194 | |
| 177 | 195 | |
| 178 | 196 | |
| 197 | +void ParticleSystem::renderParticle(int p) { | |
| 198 | + | |
| 199 | + glColor3f(_particle[p].color.x, _particle[p].color.y, _particle[p].color.z); | |
| 200 | + glPushMatrix(); | |
| 201 | + glTranslatef(_particle[p].position.x, _particle[p].position.y, _particle[p].position.z); | |
| 202 | + glutSolidSphere(_particle[p].radius, 6, 6); | |
| 203 | + glPopMatrix(); | |
| 204 | + | |
| 205 | + // render velocity lines | |
| 206 | + glColor4f( _particle[p].color.x, _particle[p].color.y, _particle[p].color.z, 0.5f); | |
| 207 | + glm::vec3 end = _particle[p].position - _particle[p].velocity * 2.0f; | |
| 208 | + glBegin(GL_LINES); | |
| 209 | + glVertex3f(_particle[p].position.x, _particle[p].position.y, _particle[p].position.z); | |
| 210 | + glVertex3f(end.x, end.y, end.z); | |
| 211 | + | |
| 212 | + glEnd(); | |
| 213 | +} | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | +void ParticleSystem::renderEmitter(int e, float size) { | |
| 218 | + | |
| 219 | + glm::vec3 r = _emitter[e].right * size; | |
| 220 | + glm::vec3 u = _emitter[e].up * size; | |
| 221 | + glm::vec3 f = _emitter[e].front * size; | |
| 222 | + | |
| 223 | + glLineWidth(2.0f); | |
| 224 | + | |
| 225 | + glColor3f(0.8f, 0.4, 0.4); | |
| 226 | + glBegin(GL_LINES); | |
| 227 | + glVertex3f(_emitter[e].position.x, _emitter[e].position.y, _emitter[e].position.z); | |
| 228 | + glVertex3f(_emitter[e].position.x + r.x, _emitter[e].position.y + r.y, _emitter[e].position.z + r.z); | |
| 229 | + glEnd(); | |
| 230 | + | |
| 231 | + glColor3f(0.4f, 0.8, 0.4); | |
| 232 | + glBegin(GL_LINES); | |
| 233 | + glVertex3f(_emitter[e].position.x, _emitter[e].position.y, _emitter[e].position.z); | |
| 234 | + glVertex3f(_emitter[e].position.x + u.x, _emitter[e].position.y + u.y, _emitter[e].position.z + u.z); | |
| 235 | + glEnd(); | |
| 236 | + | |
| 237 | + glColor3f(0.4f, 0.4, 0.8); | |
| 238 | + glBegin(GL_LINES); | |
| 239 | + glVertex3f(_emitter[e].position.x, _emitter[e].position.y, _emitter[e].position.z); | |
| 240 | + glVertex3f(_emitter[e].position.x + f.x, _emitter[e].position.y + f.y, _emitter[e].position.z + f.z); | |
| 241 | + glEnd(); | |
| 242 | +} | |
| 243 | + | |
| 244 | + | |
| 179 | 245 | |
| 180 | 246 | |
| 181 | 247 | |