xref: /haiku/src/add-ons/screen_savers/gravity/Particle.cpp (revision 71452e98334eaac603bf542d159e24788a46bebb)
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
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
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
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
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
67 Particle::Terminate()
68 {
69 	list->MakeEmpty();
70 	delete list;
71 }
72 
73 
74 /*static*/ void
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
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
103 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
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
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