Showing the changes to interface/src/ParticleSystem.cpp (1 of 4 files). Show all
Unified · Split
| @@ -0,0 +1,167 @@ | |||
| 1 | // | ||
| 2 | // ParticleSystem.cpp | ||
| 3 | // hifi | ||
| 4 | // | ||
| 5 | // Created by Jeffrey on July 10, 2013 | ||
| 6 | // | ||
| 7 | |||
| 8 | #include <glm/glm.hpp> | ||
| 9 | #include "InterfaceConfig.h" | ||
| 10 | #include <SharedUtil.h> | ||
| 11 | |||
| 12 | #include "ParticleSystem.h" | ||
| 13 | |||
| 14 | ParticleSystem::ParticleSystem() { | ||
| 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, 0.5f, 5.0f); | ||
| 29 | |||
| 30 | _TEST_bigSphereRadius = 0.5f; | ||
| 31 | _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); | ||
| 36 | |||
| 37 | float red = 0.5f + 0.5f * sinf(((float)p / (float)_numberOfParticles) * 3.141592 * 2.0f); | ||
| 38 | float green = 0.3f + 0.3f * sinf(((float)p / (float)_numberOfParticles) * 3.141592 * 2.0f); | ||
| 39 | float blue = 0.2f - 0.2f * sinf(((float)p / (float)_numberOfParticles) * 3.141592 * 2.0f); | ||
| 40 | |||
| 41 | _particle[p].color = glm::vec3(red, green, blue); | ||
| 42 | _particle[p].age = 0; | ||
| 43 | _particle[p].radius = 0.01f; | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | void ParticleSystem::simulate(float deltaTime) { | ||
| 48 | |||
| 49 | _timer += deltaTime; | ||
| 50 | |||
| 51 | _gravity = 0.01f + 0.01f * sinf( _timer * 0.52f ); | ||
| 52 | _airFriction = 3.0f + 2.0f * sinf( _timer * 0.32f ); | ||
| 53 | _jitter = 0.05f + 0.05f * sinf( _timer * 0.42f ); | ||
| 54 | _homeAttraction = 0.01f + 0.01f * cosf( _timer * 0.6f ); | ||
| 55 | _tornadoForce = 0.0f + 0.03f * sinf( _timer * 0.7f ); | ||
| 56 | _neighborAttraction = 0.1f + 0.1f * cosf( _timer * 0.8f ); | ||
| 57 | _neighborRepulsion = 0.4f + 0.3f * sinf( _timer * 0.4f ); | ||
| 58 | |||
| 59 | _tornadoAxis = glm::vec3 | ||
| 60 | ( | ||
| 61 | 0.0f + 0.5f * sinf( _timer * 0.55f ), | ||
| 62 | 1.0f, | ||
| 63 | 0.0f + 0.5f * cosf( _timer * 0.75f ) | ||
| 64 | ); | ||
| 65 | |||
| 66 | for (unsigned int p = 0; p < _numberOfParticles; p++) { | ||
| 67 | |||
| 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 | |||
| 91 | float distanceToNeighbor = glm::length(vectorToNeighbor); | ||
| 92 | if (distanceToNeighbor > 0.0f) { | ||
| 93 | _particle[neighbor].velocity += (vectorToNeighbor / ( 1.0f + distanceToNeighbor * distanceToNeighbor)) * _neighborRepulsion * 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 | |||
| 111 | // update position by velocity | ||
| 112 | _particle[p].position += _particle[p].velocity; | ||
| 113 | |||
| 114 | // collision with ground | ||
| 115 | if (_particle[p].position.y < _particle[p].radius) { | ||
| 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 | } | ||
| 122 | |||
| 123 | // collision with sphere | ||
| 124 | glm::vec3 vectorToSphereCenter = _TEST_bigSpherePosition - _particle[p].position; | ||
| 125 | float distanceToSphereCenter = glm::length(vectorToSphereCenter); | ||
| 126 | float combinedRadius = _TEST_bigSphereRadius + _particle[p].radius; | ||
| 127 | if (distanceToSphereCenter < combinedRadius) { | ||
| 128 | |||
| 129 | if (distanceToSphereCenter > 0.0f){ | ||
| 130 | glm::vec3 directionToSphereCenter = vectorToSphereCenter / distanceToSphereCenter; | ||
| 131 | _particle[p].position = _TEST_bigSpherePosition - directionToSphereCenter * combinedRadius; | ||
| 132 | _particle[p].velocity.y += 0.005f; | ||
| 133 | } | ||
| 134 | } | ||
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | |||
| 139 | |||
| 140 | void ParticleSystem::render() { | ||
| 141 | |||
| 142 | for (unsigned int p = 0; p < _numberOfParticles; p++) { | ||
| 143 | glColor3f(_particle[p].color.x, _particle[p].color.y, _particle[p].color.z); | ||
| 144 | glPushMatrix(); | ||
| 145 | glTranslatef(_particle[p].position.x, _particle[p].position.y, _particle[p].position.z); | ||
| 146 | glutSolidSphere(_particle[p].radius, 6, 6); | ||
| 147 | glPopMatrix(); | ||
| 148 | |||
| 149 | // render velocity lines | ||
| 150 | glColor4f( _particle[p].color.x, _particle[p].color.y, _particle[p].color.z, 0.5f); | ||
| 151 | glm::vec3 end = _particle[p].position - _particle[p].velocity * 2.0f; | ||
| 152 | glBegin(GL_LINES); | ||
| 153 | glVertex3f(_particle[p].position.x, _particle[p].position.y, _particle[p].position.z); | ||
| 154 | glVertex3f(end.x, end.y, end.z); | ||
| 155 | |||
| 156 | glEnd(); | ||
| 157 | |||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | |||
| 162 | |||
| 163 | |||
| 164 | |||
| 165 | |||
| 166 | |||
| 167 | |||