1 /*
2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
3 * Copyright 2014 Haiku, Inc. All rights reserved.
4 *
5 * Distributed under the terms of the MIT license.
6 *
7 * Authors:
8 * Tri-Edge AI
9 * John Scipione, jscipione@gmail.com
10 */
11
12
13 #include "Particle.h"
14
15 #include <stdlib.h>
16
17
18 #define frand() ((float)rand() / (float)RAND_MAX)
19
20
21 BObjectList<Particle>* Particle::list;
22
23
24 /*static*/ void
Initialize(int32 size,int32 shade)25 Particle::Initialize(int32 size, int32 shade)
26 {
27 list = new BObjectList<Particle>(2048);
28
29 for (int32 i = 0; i < size; i++) {
30 Particle* p = new Particle();
31 Particle::_FillParticle(p, size, shade);
32 list->AddItem(p);
33 }
34 }
35
36
37 /*static*/ void
AddParticles(int32 size,int32 shade)38 Particle::AddParticles(int32 size, int32 shade)
39 {
40 for (int32 i = list->CountItems(); i < size; i++) {
41 Particle* p = new Particle();
42 Particle::_FillParticle(p, size, shade);
43 list->AddItem(p);
44 }
45 }
46
47
48 /*static*/ void
RemoveParticles(int32 size,int32 shade)49 Particle::RemoveParticles(int32 size, int32 shade)
50 {
51 while (list->CountItems() > size)
52 delete list->RemoveItemAt(list->CountItems() - 1);
53 }
54
55
56 /*static*/ void
ColorParticles(int32 size,int32 shade)57 Particle::ColorParticles(int32 size, int32 shade)
58 {
59 for (int32 i = 0; i < size; i++) {
60 Particle* p = list->ItemAt(i);
61 Particle::_ColorParticle(p, size, shade);
62 }
63 }
64
65
66 /*static*/ void
Terminate()67 Particle::Terminate()
68 {
69 list->MakeEmpty();
70 delete list;
71 }
72
73
74 /*static*/ void
Tick()75 Particle::Tick()
76 {
77 for (int32 i = 0; i < list->CountItems(); i++) {
78 Particle* p = list->ItemAt(i);
79 p->_Logic();
80 p->_Render();
81 }
82 }
83
84
85 void
_Logic()86 Particle::_Logic()
87 {
88 // Motion
89 x += vx;
90 y += vy;
91 z += vz;
92 r += vr;
93
94 // Friction
95 vx *= 0.98f;
96 vy *= 0.98f;
97 vz *= 0.98f;
98 vr *= 0.98f;
99 }
100
101
102 void
_Render() const103 Particle::_Render() const
104 {
105 glPushMatrix();
106 glTranslatef(x, y, z);
107 glRotatef(r, 0.0f, 0.0f, 1.0f);
108 glColor3f(red, green, blue);
109 glBegin(GL_QUADS);
110 glVertex3f(-0.25f, 0.25f, 0.0f);
111 glVertex3f(-0.25f, -0.25f, 0.0f);
112 glVertex3f( 0.25f, -0.25f, 0.0f);
113 glVertex3f( 0.25f, 0.25f, 0.0f);
114 glEnd();
115 glPopMatrix();
116 }
117
118
119 /*static*/ void
_FillParticle(Particle * p,int32 size,int32 shade)120 Particle::_FillParticle(Particle* p, int32 size, int32 shade)
121 {
122 p->x = frand() * 30.0f - 15.0f;
123 p->y = frand() * 30.0f - 15.0f;
124 p->z = frand() * 5.0f;
125 p->r = frand() * 360.0f;
126
127 p->vx = frand() - 0.5f;
128 p->vy = frand() - 0.5f;
129 p->vz = frand() - 0.5f;
130 p->vr = (frand() - 0.5f) * 180.0f;
131
132 Particle::_ColorParticle(p, size, shade);
133 }
134
135
136 /*static*/ void
_ColorParticle(Particle * p,int32 size,int32 shade)137 Particle::_ColorParticle(Particle* p, int32 size, int32 shade)
138 {
139 switch(shade) {
140 case 0:
141 // Red
142 p->red = 0.1f + frand() * 0.2f;
143 p->green = 0.0f;
144 p->blue = frand() * 0.05f;
145 break;
146
147 case 1:
148 // Green
149 p->red = 0;
150 p->green = 0.1f + frand() * 0.2f;
151 p->blue = frand() * 0.05f;
152 break;
153
154 case 2:
155 default:
156 // Blue
157 p->red = 0;
158 p->green = frand() * 0.05f;
159 p->blue = 0.1f + frand() * 0.2f;
160 break;
161
162 case 3:
163 // Orange
164 p->red = 0.1f + frand() * 0.1f;
165 p->green = 0.05f + frand() * 0.1f;
166 p->blue = 0.0f;
167 break;
168
169 case 4:
170 // Purple
171 p->red = 0.1f + frand() * 0.2f;
172 p->green = 0.0f;
173 p->blue = 0.1f + frand() * 0.2f;
174 break;
175
176 case 5:
177 // White
178 p->red = p->green = p->blue = 0.1f + frand() * 0.2f;
179 break;
180
181 case 6:
182 // Rainbow
183 p->red = 0.1f + frand() * 0.2f;
184 p->green = 0.1f + frand() * 0.2f;
185 p->blue = 0.1f + frand() * 0.2f;
186 break;
187 }
188 }
189