History

made a test particle system

Jeffrey Ventrella committed 13 years ago

Commit 84a7a781 parent 04b88e54 files · +232 −0Browse files

Showing the changes to interface/src/ParticleSystem.cpp (1 of 4 files). Show all

Unified · Split

interface/src/ParticleSystem.cpp+167−0
@@ -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
14ParticleSystem::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
47void 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
140void 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