xref: /haiku/src/add-ons/screen_savers/gravity/Particle.cpp (revision dcd112f767b89f0cb5a1e93e0515361c1742c635)
1 /*
2  * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
3  * All rights reserved. Distributed under the terms of the MIT license.
4  */
5 
6 
7 #include "Particle.h"
8 
9 #include <List.h>
10 
11 #include <stdlib.h>
12 
13 
14 #define frand() ((float)rand() / (float)RAND_MAX)
15 
16 
17 BList* Particle::list;
18 
19 
20 void
21 Particle::Initialize(int32 size, int32 shade)
22 {
23 	list = new BList();
24 
25 	for (int32 i = 0; i < size; i++) {
26 		Particle* p = new Particle();
27 
28 		p->x = frand() * 30.0f - 15.0f;
29 		p->y = frand() * 30.0f - 15.0f;
30 		p->z = frand() * 5.0f;
31 		p->r = frand() * 360.0f;
32 
33 		p->vx = frand() - 0.5f;
34 		p->vy = frand() - 0.5f;
35 		p->vz = frand() - 0.5f;
36 		p->vr = (frand() - 0.5f) * 180.0f;
37 
38 		if (shade == 0) {
39 			// Red
40 			p->red = 0.1f + frand() * 0.2f;
41 			p->green = 0.0f;
42 			p->blue = frand() * 0.05f;
43 		} else if (shade == 1) {
44 			// Green
45 			p->red = 0;
46 			p->green =  0.1f + frand() * 0.2f;
47 			p->blue = frand() * 0.05f;
48 		} else if (shade == 2) {
49 			// Blue
50 			p->red = 0;
51 			p->green = frand() * 0.05f;
52 			p->blue = 0.1f + frand() * 0.2f;
53 		} else if (shade == 3) {
54 			// Orange
55 			p->red = 0.1f + frand() * 0.1f;
56 			p->green =  0.05f + frand() * 0.1f;
57 			p->blue = 0.0f;
58 		} else if (shade == 4) {
59 			// Purple
60 			p->red = 0.1f + frand() * 0.2f;
61 			p->green = 0.0f;
62 			p->blue = 0.1f + frand() * 0.2f;
63 		} else if (shade == 5) {
64 			// White
65 			p->red = p->green = p->blue = 0.1f + frand() * 0.2f;
66 		} else if (shade == 6) {
67 			// Rainbow
68 			p->red = 0.1f + frand() * 0.2f;
69 			p->green = 0.1f + frand() * 0.2f;
70 			p->blue = 0.1f + frand() * 0.2f;
71 		} else {
72 			// Man, this shouldn't even happen.. Blue.
73 			p->red = 0;
74 			p->green = frand() * 0.05f;
75 			p->blue = 0.1f + frand() * 0.2f;
76 		}
77 
78 		list->AddItem(p);
79 	}
80 }
81 
82 
83 void
84 Particle::Terminate()
85 {
86 	for (int32 i = 0; i < list->CountItems(); i++)
87 		delete (Particle*)list->ItemAt(i);
88 
89 	list->MakeEmpty();
90 	delete list;
91 }
92 
93 
94 void
95 Particle::Tick()
96 {
97 	for (int32 i = 0; i < list->CountItems(); i++) {
98 		Particle* p = (Particle*)list->ItemAt(i);
99 		p->_Logic();
100 		p->_Render();
101 	}
102 }
103 
104 
105 void
106 Particle::_Logic()
107 {
108 	// Motion
109 	x += vx;
110 	y += vy;
111 	z += vz;
112 	r += vr;
113 
114 	// Friction
115 	vx *= 0.98f;
116 	vy *= 0.98f;
117 	vz *= 0.98f;
118 	vr *= 0.98f;
119 }
120 
121 
122 void
123 Particle::_Render() const
124 {
125 	glPushMatrix();
126 	glTranslatef(x, y, z);
127 	glRotatef(r, 0.0f, 0.0f, 1.0f);
128 	glColor3f(red, green, blue);
129 	glBegin(GL_QUADS);
130 	glVertex3f(-0.25f,  0.25f,  0.0f);
131 	glVertex3f(-0.25f, -0.25f,  0.0f);
132 	glVertex3f( 0.25f, -0.25f,  0.0f);
133 	glVertex3f( 0.25f,  0.25f,  0.0f);
134 	glEnd();
135 	glPopMatrix();
136 }
137