Showing the changes to interface/src/ParticleSystem.cpp (1 of 3 files). Show all
Unified · Split
| @@ -8,59 +8,91 @@ · 7 unmodified lines | |||
| 8 | #include <glm/glm.hpp> | 8 | #include <glm/glm.hpp> |
| 9 | #include "InterfaceConfig.h" | 9 | #include "InterfaceConfig.h" |
| 10 | #include <SharedUtil.h> | 10 | #include <SharedUtil.h> |
| 11 | |||
| 12 | #include "ParticleSystem.h" | 11 | #include "ParticleSystem.h" |
| 12 | #include "Application.h" | ||
| 13 | 13 | ||
| 14 | ParticleSystem::ParticleSystem() { | 14 | ParticleSystem::ParticleSystem() { |
| 15 | 15 | ||
| 16 | _numberOfParticles = 1500; | 16 | _gravity = 0.005; |
| 17 | assert(_numberOfParticles <= MAX_PARTICLES); | 17 | _numEmitters = 1; |
| 18 | 18 | _bounce = 0.9f; | |
| 19 | _bounce = 0.9f; | 19 | _timer = 0.0f; |
| 20 | _timer = 0.0f; | 20 | _airFriction = 6.0f; |
| 21 | _airFriction = 6.0f; | 21 | _jitter = 0.1f; |
| 22 | _jitter = 0.1f; | 22 | _homeAttraction = 0.0f; |
| 23 | _homeAttraction = 0.0f; | 23 | _tornadoForce = 0.0f; |
| 24 | _tornadoForce = 0.0f; | 24 | _neighborAttraction = 0.02f; |
| 25 | _neighborAttraction = 0.02f; | 25 | _neighborRepulsion = 0.9f; |
| 26 | _neighborRepulsion = 0.9f; | 26 | _TEST_bigSphereRadius = 0.5f; |
| 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; | ||
| 31 | _TEST_bigSpherePosition = glm::vec3( 5.0f, _TEST_bigSphereRadius, 5.0f); | 27 | _TEST_bigSpherePosition = glm::vec3( 5.0f, _TEST_bigSphereRadius, 5.0f); |
| 32 | 28 | _numParticles = 1500; | |
| 33 | for (unsigned int p = 0; p < _numberOfParticles; p++) { | 29 | |
| 34 | _particle[p].position = _home; | 30 | for (unsigned int e = 0; e < _numEmitters; e++) { |
| 35 | _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); | 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 | float wave = sinf(radian); | 42 | float wave = sinf(radian); |
| 39 | 43 | ||
| 40 | float red = 0.5f + 0.5f * wave; | 44 | float red = 0.5f + 0.5f * wave; |
| 41 | float green = 0.3f + 0.3f * wave; | 45 | float green = 0.3f + 0.3f * wave; |
| 42 | float blue = 0.2f - 0.2f * wave; | 46 | float blue = 0.2f - 0.2f * wave; |
| 43 | 47 | ||
| 44 | _particle[p].color = glm::vec3(red, green, blue); | 48 | _particle[p].color = glm::vec3(red, green, blue); |
| 45 | _particle[p].age = 0.0f; | 49 | _particle[p].age = 0.0f; |
| 46 | _particle[p].radius = 0.01f; | 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 | void ParticleSystem::simulate(float deltaTime) { | 61 | void ParticleSystem::simulate(float deltaTime) { |
| 51 | 62 | ||
| 52 | runSpecialEffectsTest(deltaTime); | 63 | // update emitters |
| 53 | 64 | for (unsigned int e = 0; e < _numEmitters; e++) { | |
| 54 | for (unsigned int p = 0; p < _numberOfParticles; p++) { | 65 | updateEmitter(e, deltaTime); |
| 66 | } | ||
| 67 | |||
| 68 | // update particles | ||
| 69 | for (unsigned int p = 0; p < _numParticles; p++) { | ||
| 55 | updateParticle(p, deltaTime); | 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 | void ParticleSystem::runSpecialEffectsTest(float deltaTime) { | 84 | void ParticleSystem::runSpecialEffectsTest(float deltaTime) { |
| 62 | 85 | ||
| 63 | _timer += deltaTime; | 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 | _gravity = 0.01f + 0.01f * sinf( _timer * 0.52f ); | 97 | _gravity = 0.01f + 0.01f * sinf( _timer * 0.52f ); |
| 66 | _airFriction = 3.0f + 2.0f * sinf( _timer * 0.32f ); | 98 | _airFriction = 3.0f + 2.0f * sinf( _timer * 0.32f ); |
| @@ -69,13 +101,6 @@ void ParticleSystem::runSpecialEffectsTest(float deltaTime) { · 2 unmodified lines | |||
| 69 | _tornadoForce = 0.0f + 0.03f * sinf( _timer * 0.7f ); | 101 | _tornadoForce = 0.0f + 0.03f * sinf( _timer * 0.7f ); |
| 70 | _neighborAttraction = 0.1f + 0.1f * cosf( _timer * 0.8f ); | 102 | _neighborAttraction = 0.1f + 0.1f * cosf( _timer * 0.8f ); |
| 71 | _neighborRepulsion = 0.4f + 0.3f * sinf( _timer * 0.4f ); | 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 | // apply attraction to home position | 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 | _particle[p].velocity += vectorToHome * _homeAttraction * deltaTime; | 124 | _particle[p].velocity += vectorToHome * _homeAttraction * deltaTime; |
| 100 | 125 | ||
| 101 | // apply neighbor attraction | 126 | // apply neighbor attraction |
| 102 | int neighbor = p + 1; | 127 | int neighbor = p + 1; |
| 103 | if (neighbor == _numberOfParticles ) { | 128 | if (neighbor == _numParticles ) { |
| 104 | neighbor = 0; | 129 | neighbor = 0; |
| 105 | } | 130 | } |
| 106 | glm::vec3 vectorToNeighbor = _particle[p].position - _particle[neighbor].position; | 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 | // apply tornado force | 140 | // apply tornado force |
| 116 | glm::vec3 tornadoDirection = glm::cross(vectorToHome, _tornadoAxis); | 141 | //glm::vec3 tornadoDirection = glm::cross(vectorToHome, _emitter[_particle[p].emitterIndex].up); |
| 117 | _particle[p].velocity += tornadoDirection * _tornadoForce * deltaTime; | 142 | //_particle[p].velocity += tornadoDirection * _tornadoForce * deltaTime; |
| 143 | //_particle[p].velocity += _emitter[_particle[p].emitterIndex].up * _tornadoForce * deltaTime; | ||
| 118 | 144 | ||
| 119 | // apply air friction | 145 | // apply air friction |
| 120 | float drag = 1.0 - _airFriction * deltaTime; | 146 | float drag = 1.0 - _airFriction * deltaTime; |
| @@ -155,27 +181,67 @@ void ParticleSystem::updateParticle(int p, float deltaTime) { · 34 unmodified lines | |||
| 155 | 181 | ||
| 156 | void ParticleSystem::render() { | 182 | void ParticleSystem::render() { |
| 157 | 183 | ||
| 158 | for (unsigned int p = 0; p < _numberOfParticles; p++) { | 184 | // render the emitters |
| 159 | glColor3f(_particle[p].color.x, _particle[p].color.y, _particle[p].color.z); | 185 | for (unsigned int e = 0; e < _numEmitters; e++) { |
| 160 | glPushMatrix(); | 186 | renderEmitter(e, 0.2f); |
| 161 | glTranslatef(_particle[p].position.x, _particle[p].position.y, _particle[p].position.z); | 187 | }; |
| 162 | glutSolidSphere(_particle[p].radius, 6, 6); | 188 | |
| 163 | glPopMatrix(); | 189 | // render the particles |
| 164 | 190 | for (unsigned int p = 0; p < _numParticles; p++) { | |
| 165 | // render velocity lines | 191 | renderParticle(p); |
| 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 | |||
| 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 | ||