xref: /haiku/src/add-ons/screen_savers/gravity/Particle.cpp (revision 7f4d1af49dd1d67ecbf1d934eddd92cae7c4c558)
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