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
21BObjectList<Particle>* Particle::list;
22
23
24/*static*/ void
25Particle::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
38Particle::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
49Particle::RemoveParticles(int32 size, int32 shade)
50{
51	while (list->CountItems() > size)
52		delete list->RemoveItemAt(list->CountItems() - 1);
53}
54
55
56/*static*/ void
57Particle::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
67Particle::Terminate()
68{
69	list->MakeEmpty();
70	delete list;
71}
72
73
74/*static*/ void
75Particle::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
85void
86Particle::_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
102void
103Particle::_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
120Particle::_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
137Particle::_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