Showing the changes to interface/src/ParticleSystem.cpp (1 of 2 files). Show all
Unified · Split
| @@ -15,7 +15,7 @@ ParticleSystem::ParticleSystem() { · 14 unmodified lines | |||
| 15 | 15 | ||
| 16 | _numberOfParticles = 1500; | 16 | _numberOfParticles = 1500; |
| 17 | assert(_numberOfParticles <= MAX_PARTICLES); | 17 | assert(_numberOfParticles <= MAX_PARTICLES); |
| 18 | 18 | ||
| 19 | _bounce = 0.9f; | 19 | _bounce = 0.9f; |
| 20 | _timer = 0.0f; | 20 | _timer = 0.0f; |
| 21 | _airFriction = 6.0f; | 21 | _airFriction = 6.0f; |
| @@ -34,18 +34,32 @@ ParticleSystem::ParticleSystem() { · 12 unmodified lines | |||
| 34 | _particle[p].position = _home; | 34 | _particle[p].position = _home; |
| 35 | _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); | 35 | _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); |
| 36 | 36 | ||
| 37 | float red = 0.5f + 0.5f * sinf(((float)p / (float)_numberOfParticles) * 3.141592 * 2.0f); | 37 | float radian = ((float)p / (float)_numberOfParticles) * PI_TIMES_TWO; |
| 38 | float green = 0.3f + 0.3f * sinf(((float)p / (float)_numberOfParticles) * 3.141592 * 2.0f); | 38 | float wave = sinf(radian); |
| 39 | float blue = 0.2f - 0.2f * sinf(((float)p / (float)_numberOfParticles) * 3.141592 * 2.0f); | 39 | |
| 40 | float red = 0.5f + 0.5f * wave; | ||
| 41 | float green = 0.3f + 0.3f * wave; | ||
| 42 | float blue = 0.2f - 0.2f * wave; | ||
| 40 | 43 | ||
| 41 | _particle[p].color = glm::vec3(red, green, blue); | 44 | _particle[p].color = glm::vec3(red, green, blue); |
| 42 | _particle[p].age = 0; | 45 | _particle[p].age = 0.0f; |
| 43 | _particle[p].radius = 0.01f; | 46 | _particle[p].radius = 0.01f; |
| 44 | } | 47 | } |
| 45 | } | 48 | } |
| 46 | 49 | ||
| 47 | void ParticleSystem::simulate(float deltaTime) { | 50 | void ParticleSystem::simulate(float deltaTime) { |
| 51 | |||
| 52 | runSpecialEffectsTest(deltaTime); | ||
| 53 | |||
| 54 | for (unsigned int p = 0; p < _numberOfParticles; p++) { | ||
| 55 | updateParticle(p, deltaTime); | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | |||
| 48 | 60 | ||
| 61 | void ParticleSystem::runSpecialEffectsTest(float deltaTime) { | ||
| 62 | |||
| 49 | _timer += deltaTime; | 63 | _timer += deltaTime; |
| 50 | 64 | ||
| 51 | _gravity = 0.01f + 0.01f * sinf( _timer * 0.52f ); | 65 | _gravity = 0.01f + 0.01f * sinf( _timer * 0.52f ); |
| @@ -62,81 +76,83 @@ void ParticleSystem::simulate(float deltaTime) { · 10 unmodified lines | |||
| 62 | 1.0f, | 76 | 1.0f, |
| 63 | 0.0f + 0.5f * cosf( _timer * 0.75f ) | 77 | 0.0f + 0.5f * cosf( _timer * 0.75f ) |
| 64 | ); | 78 | ); |
| 79 | } | ||
| 65 | 80 | ||
| 66 | for (unsigned int p = 0; p < _numberOfParticles; p++) { | ||
| 67 | 81 | ||
| 68 | // apply random jitter | ||
| 69 | _particle[p].velocity += | ||
| 70 | glm::vec3 | ||
| 71 | ( | ||
| 72 | -_jitter * ONE_HALF + _jitter * randFloat(), | ||
| 73 | -_jitter * ONE_HALF + _jitter * randFloat(), | ||
| 74 | -_jitter * ONE_HALF + _jitter * randFloat() | ||
| 75 | ) * deltaTime; | ||
| 76 | |||
| 77 | |||
| 78 | // apply attraction to home position | ||
| 79 | glm::vec3 vectorToHome = _home - _particle[p].position; | ||
| 80 | _particle[p].velocity += vectorToHome * _homeAttraction * deltaTime; | ||
| 81 | |||
| 82 | // apply neighbor attraction | ||
| 83 | int neighbor = p + 1; | ||
| 84 | if (neighbor == _numberOfParticles ) { | ||
| 85 | neighbor = 0; | ||
| 86 | } | ||
| 87 | glm::vec3 vectorToNeighbor = _particle[p].position - _particle[neighbor].position; | ||
| 88 | |||
| 89 | _particle[p].velocity -= vectorToNeighbor * _neighborAttraction * deltaTime; | ||
| 90 | 82 | ||
| 91 | float distanceToNeighbor = glm::length(vectorToNeighbor); | 83 | void ParticleSystem::updateParticle(int p, float deltaTime) { |
| 92 | if (distanceToNeighbor > 0.0f) { | 84 | |
| 93 | _particle[neighbor].velocity += (vectorToNeighbor / ( 1.0f + distanceToNeighbor * distanceToNeighbor)) * _neighborRepulsion * deltaTime; | 85 | _particle[p].age += deltaTime; |
| 94 | } | ||
| 95 | |||
| 96 | // apply tornado force | ||
| 97 | glm::vec3 tornadoDirection = glm::cross(vectorToHome, _tornadoAxis); | ||
| 98 | _particle[p].velocity += tornadoDirection * _tornadoForce * deltaTime; | ||
| 99 | |||
| 100 | // apply air friction | ||
| 101 | float drag = 1.0 - _airFriction * deltaTime; | ||
| 102 | if (drag < 0.0f) { | ||
| 103 | _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); | ||
| 104 | } else { | ||
| 105 | _particle[p].velocity *= drag; | ||
| 106 | } | ||
| 107 | |||
| 108 | // apply gravity | ||
| 109 | _particle[p].velocity.y -= _gravity * deltaTime; | ||
| 110 | 86 | ||
| 111 | // update position by velocity | 87 | // apply random jitter |
| 112 | _particle[p].position += _particle[p].velocity; | 88 | _particle[p].velocity += |
| 89 | glm::vec3 | ||
| 90 | ( | ||
| 91 | -_jitter * ONE_HALF + _jitter * randFloat(), | ||
| 92 | -_jitter * ONE_HALF + _jitter * randFloat(), | ||
| 93 | -_jitter * ONE_HALF + _jitter * randFloat() | ||
| 94 | ) * deltaTime; | ||
| 95 | |||
| 96 | |||
| 97 | // apply attraction to home position | ||
| 98 | glm::vec3 vectorToHome = _home - _particle[p].position; | ||
| 99 | _particle[p].velocity += vectorToHome * _homeAttraction * deltaTime; | ||
| 100 | |||
| 101 | // apply neighbor attraction | ||
| 102 | int neighbor = p + 1; | ||
| 103 | if (neighbor == _numberOfParticles ) { | ||
| 104 | neighbor = 0; | ||
| 105 | } | ||
| 106 | glm::vec3 vectorToNeighbor = _particle[p].position - _particle[neighbor].position; | ||
| 107 | |||
| 108 | _particle[p].velocity -= vectorToNeighbor * _neighborAttraction * deltaTime; | ||
| 109 | |||
| 110 | float distanceToNeighbor = glm::length(vectorToNeighbor); | ||
| 111 | if (distanceToNeighbor > 0.0f) { | ||
| 112 | _particle[neighbor].velocity += (vectorToNeighbor / ( 1.0f + distanceToNeighbor * distanceToNeighbor)) * _neighborRepulsion * deltaTime; | ||
| 113 | } | ||
| 114 | |||
| 115 | // apply tornado force | ||
| 116 | glm::vec3 tornadoDirection = glm::cross(vectorToHome, _tornadoAxis); | ||
| 117 | _particle[p].velocity += tornadoDirection * _tornadoForce * deltaTime; | ||
| 118 | |||
| 119 | // apply air friction | ||
| 120 | float drag = 1.0 - _airFriction * deltaTime; | ||
| 121 | if (drag < 0.0f) { | ||
| 122 | _particle[p].velocity = glm::vec3(0.0f, 0.0f, 0.0f); | ||
| 123 | } else { | ||
| 124 | _particle[p].velocity *= drag; | ||
| 125 | } | ||
| 126 | |||
| 127 | // apply gravity | ||
| 128 | _particle[p].velocity.y -= _gravity * deltaTime; | ||
| 129 | |||
| 130 | // update position by velocity | ||
| 131 | _particle[p].position += _particle[p].velocity; | ||
| 132 | |||
| 133 | // collision with ground | ||
| 134 | if (_particle[p].position.y < _particle[p].radius) { | ||
| 135 | _particle[p].position.y = _particle[p].radius; | ||
| 113 | 136 | ||
| 114 | // collision with ground | 137 | if (_particle[p].velocity.y < 0.0f) { |
| 115 | if (_particle[p].position.y < _particle[p].radius) { | 138 | _particle[p].velocity.y *= -_bounce; |
| 116 | _particle[p].position.y = _particle[p].radius; | ||
| 117 | |||
| 118 | if (_particle[p].velocity.y < 0.0f) { | ||
| 119 | _particle[p].velocity.y *= -_bounce; | ||
| 120 | } | ||
| 121 | } | 139 | } |
| 122 | 140 | } | |
| 123 | // collision with sphere | 141 | |
| 124 | glm::vec3 vectorToSphereCenter = _TEST_bigSpherePosition - _particle[p].position; | 142 | // collision with sphere |
| 125 | float distanceToSphereCenter = glm::length(vectorToSphereCenter); | 143 | glm::vec3 vectorToSphereCenter = _TEST_bigSpherePosition - _particle[p].position; |
| 126 | float combinedRadius = _TEST_bigSphereRadius + _particle[p].radius; | 144 | float distanceToSphereCenter = glm::length(vectorToSphereCenter); |
| 127 | if (distanceToSphereCenter < combinedRadius) { | 145 | float combinedRadius = _TEST_bigSphereRadius + _particle[p].radius; |
| 128 | 146 | if (distanceToSphereCenter < combinedRadius) { | |
| 129 | if (distanceToSphereCenter > 0.0f){ | 147 | |
| 130 | glm::vec3 directionToSphereCenter = vectorToSphereCenter / distanceToSphereCenter; | 148 | if (distanceToSphereCenter > 0.0f){ |
| 131 | _particle[p].position = _TEST_bigSpherePosition - directionToSphereCenter * combinedRadius; | 149 | glm::vec3 directionToSphereCenter = vectorToSphereCenter / distanceToSphereCenter; |
| 132 | //_particle[p].velocity.y += 0.005f; | 150 | _particle[p].position = _TEST_bigSpherePosition - directionToSphereCenter * combinedRadius; |
| 133 | } | ||
| 134 | } | 151 | } |
| 135 | } | 152 | } |
| 136 | } | 153 | } |
| 137 | 154 | ||
| 138 | 155 | ||
| 139 | |||
| 140 | void ParticleSystem::render() { | 156 | void ParticleSystem::render() { |
| 141 | 157 | ||
| 142 | for (unsigned int p = 0; p < _numberOfParticles; p++) { | 158 | for (unsigned int p = 0; p < _numberOfParticles; p++) { |