xref: /haiku/src/add-ons/screen_savers/flurry/Spark.cpp (revision be012e21222c4d8d70082d12353acb163dc60ba8)
1 /*
2 
3 Copyright (c) 2002, Calum Robinson
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 
9 * Redistributions of source code must retain the above copyright notice, this
10   list of conditions and the following disclaimer.
11 
12 * Redistributions in binary form must reproduce the above copyright notice,
13   this list of conditions and the following disclaimer in the documentation
14   and/or other materials provided with the distribution.
15 
16 * Neither the name of the author nor the names of its contributors may be used
17   to endorse or promote products derived from this software without specific
18   prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
24 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 */
32 
33 
34 #include "Spark.h"
35 #include "Shared.h"
36 
37 
38 #define BIGMYSTERY 1800.0
39 #define MAXANGLES 16384
40 
41 #define fieldCoherence 0
42 #define fieldSpeed 12.0f
43 #define fieldRange 1000.0f
44 
45 
46 void
47 InitSpark(Spark* s)
48 {
49 	for (int i = 0; i < 3; i++)
50 		s->position[i] = RandFlt(-100.0, 100.0);
51 }
52 
53 
54 void DrawSpark(flurry_info_t* info, Spark* s)
55 {
56 	const float black[4] = {0.0f, 0.0f, 0.0f, 1.0f};
57 	float width;
58 	float sx;
59 	float sy;
60 	float a;
61 	float c = 0.0625f;
62 	float screenx;
63 	float screeny;
64 	float w;
65 	float z;
66 	float scale;
67 	width = 60000.0f * info->sys_glWidth / 1024.0f;
68 
69 	z = s->position[2];
70 	sx = s->position[0] * info->sys_glWidth / z + info->sys_glWidth * 0.5f;
71 	sy = s->position[1] * info->sys_glWidth / z + info->sys_glHeight * 0.5f;
72 	w = width*4.0f / z;
73 
74 	screenx = sx;
75 	screeny = sy;
76 
77 	glPushMatrix();
78 	glTranslatef(screenx,screeny,0.0f);
79 	scale = w/50.0f;
80 	glScalef(scale,scale,0.0f);
81 	for (int k = 0; k < 12; k++) {
82 		a = ((float)(random() % 3600)) / 10.0f;
83 		glRotatef(a,0.0f,0.0f,1.0f);
84 		glBegin(GL_QUAD_STRIP);
85 		glColor4fv(black);
86 		glVertex2f(-3.0f,0.0f);
87 		a = 2.0f + (float) (random() & 255) * c;
88 		glVertex2f(-3.0f,a);
89 		glColor4fv(s->color);
90 		glVertex2f(0.0f,0.0f);
91 		glColor4fv(black);
92 		glVertex2f(0.0f,a);
93 		glVertex2f(3.0f,0.0f);
94 		glVertex2f(3.0f,a);
95 		glEnd();
96 	}
97 
98 	glPopMatrix();
99 }
100 
101 
102 void
103 UpdateSparkColour(flurry_info_t* info, Spark* s)
104 {
105 	const float rotationsPerSecond = (float)(2.0 * M_PI * fieldSpeed
106 		/ MAXANGLES);
107 	double thisPointInRadians;
108 	double thisAngle = info->fTime*rotationsPerSecond;
109 	float cf;
110 	float cycleTime = 20.0f;
111 	float colorRot;
112 	float redPhaseShift;
113 	float greenPhaseShift;
114 	float bluePhaseShift;
115 	float baseRed;
116 	float baseGreen;
117 	float baseBlue;
118 	float colorTime;
119 
120 	if (info->currentColorMode == rainbowColorMode)
121 		cycleTime = 1.5f;
122 	else if (info->currentColorMode == tiedyeColorMode)
123 		cycleTime = 4.5f;
124 	else if (info->currentColorMode == cyclicColorMode)
125 		cycleTime = 20.0f;
126 	else if (info->currentColorMode == slowCyclicColorMode)
127 		cycleTime = 120.0f;
128 
129 	colorRot = (float)(2.0 * M_PI / cycleTime);
130 	redPhaseShift = 0.0f; /* cycleTime * 0.0f / 3.0f */
131 	greenPhaseShift = cycleTime / 3.0f;
132 	bluePhaseShift = cycleTime * 2.0f / 3.0f;
133 	colorTime = info->fTime;
134 	if (info->currentColorMode == whiteColorMode) {
135 		baseRed = 0.1875f;
136 		baseGreen = 0.1875f;
137 		baseBlue = 0.1875f;
138 	} else if (info->currentColorMode == multiColorMode) {
139 		baseRed = 0.0625f;
140 		baseGreen = 0.0625f;
141 		baseBlue = 0.0625f;
142 	} else if (info->currentColorMode == darkColorMode) {
143 		baseRed = 0.0f;
144 		baseGreen = 0.0f;
145 		baseBlue = 0.0f;
146 	} else {
147 		if (info->currentColorMode < slowCyclicColorMode)
148 			colorTime = (info->currentColorMode / 6.0f) * cycleTime;
149 		else
150 			colorTime = info->fTime + info->randomSeed;
151 
152 		baseRed = 0.109375f
153 			* ((float)cos((colorTime + redPhaseShift) * colorRot) + 1.0f);
154 		baseGreen = 0.109375f
155 			* ((float)cos((colorTime + greenPhaseShift) * colorRot) + 1.0f);
156 		baseBlue = 0.109375f
157 			* ((float)cos((colorTime + bluePhaseShift) * colorRot) + 1.0f);
158 	}
159 
160 	cf = ((float)(cos(7.0 * ((info->fTime) * rotationsPerSecond))
161 		+ cos(3.0 * ((info->fTime) * rotationsPerSecond))
162 		+ cos(13.0 * ((info->fTime) * rotationsPerSecond))));
163 	cf /= 6.0f;
164 	cf += 2.0f;
165 	thisPointInRadians = 2.0 * M_PI * (double) s->mystery / (double) BIGMYSTERY;
166 
167 	s->color[0] = baseRed + 0.0625f
168 		* (0.5f + (float)cos((15.0 * (thisPointInRadians + 3.0*thisAngle)))
169 		+ (float)sin((7.0 * (thisPointInRadians + thisAngle))));
170 	s->color[1] = baseGreen + 0.0625f
171 		* (0.5f + (float)sin(((thisPointInRadians) + thisAngle)));
172 	s->color[2] = baseBlue + 0.0625f
173 		* (0.5f + (float)cos((37.0 * (thisPointInRadians + thisAngle))));
174 }
175 
176 
177 void
178 UpdateSpark(flurry_info_t* info, Spark* s)
179 {
180 	const float rotationsPerSecond = (float) (2.0*M_PI*fieldSpeed/MAXANGLES);
181 	double thisPointInRadians;
182 	double thisAngle = info->fTime*rotationsPerSecond;
183 	float cf;
184 	double tmpX1,tmpY1,tmpZ1;
185 	double tmpX2,tmpY2,tmpZ2;
186 	double tmpX3,tmpY3,tmpZ3;
187 	double tmpX4,tmpY4,tmpZ4;
188 	double rotation;
189 	double cr;
190 	double sr;
191 	float cycleTime = 20.0f;
192 	float colorRot;
193 	float redPhaseShift;
194 	float greenPhaseShift;
195 	float bluePhaseShift;
196 	float baseRed;
197 	float baseGreen;
198 	float baseBlue;
199 	float colorTime;
200 
201 	float old[3];
202 
203 	if (info->currentColorMode == rainbowColorMode)
204 		cycleTime = 1.5f;
205 	else if (info->currentColorMode == tiedyeColorMode)
206 		cycleTime = 4.5f;
207 	else if (info->currentColorMode == cyclicColorMode)
208 		cycleTime = 20.0f;
209 	else if (info->currentColorMode == slowCyclicColorMode)
210 		cycleTime = 120.0f;
211 
212 	colorRot = (float)(2.0 * M_PI / cycleTime);
213 	redPhaseShift = 0.0f; /* cycleTime * 0.0f / 3.0f */
214 	greenPhaseShift = cycleTime / 3.0f;
215 	bluePhaseShift = cycleTime * 2.0f / 3.0f ;
216 	colorTime = info->fTime;
217 	if (info->currentColorMode == whiteColorMode) {
218 		baseRed = 0.1875f;
219 		baseGreen = 0.1875f;
220 		baseBlue = 0.1875f;
221 	} else if (info->currentColorMode == multiColorMode) {
222 		baseRed = 0.0625f;
223 		baseGreen = 0.0625f;
224 		baseBlue = 0.0625f;
225 	} else if (info->currentColorMode == darkColorMode) {
226 		baseRed = 0.0f;
227 		baseGreen = 0.0f;
228 		baseBlue = 0.0f;
229 	} else {
230 		if (info->currentColorMode < slowCyclicColorMode)
231 			colorTime = (info->currentColorMode / 6.0f) * cycleTime;
232 		else
233 			colorTime = info->fTime + info->randomSeed;
234 
235 		baseRed = 0.109375f
236 			* ((float)cos((colorTime + redPhaseShift) * colorRot) + 1.0f);
237 		baseGreen = 0.109375f
238 			* ((float)cos((colorTime + greenPhaseShift) * colorRot) + 1.0f);
239 		baseBlue = 0.109375f
240 			* ((float)cos((colorTime + bluePhaseShift) * colorRot) + 1.0f);
241 	}
242 
243 	for (int i = 0; i < 3; i++)
244 		old[i] = s->position[i];
245 
246 	cf = ((float)cos(7.0 * ((info->fTime) * rotationsPerSecond)
247 		+ (float)cos(3.0 * ((info->fTime) * rotationsPerSecond))
248 		+ (float)cos(13.0 * ((info->fTime) * rotationsPerSecond))));
249 	cf /= 6.0f;
250 	cf += 2.0f;
251 	thisPointInRadians = 2.0 * M_PI * (double)s->mystery / (double)BIGMYSTERY;
252 
253 	s->color[0] = baseRed + 0.0625f
254 		* (0.5f + (float) cos((15.0 * (thisPointInRadians + 3.0*thisAngle)))
255 		+ (float) sin((7.0 * (thisPointInRadians + thisAngle))));
256 	s->color[1] = baseGreen + 0.0625f
257 		* (0.5f + (float) sin(((thisPointInRadians) + thisAngle)));
258 	s->color[2] = baseBlue + 0.0625f
259 		* (0.5f + (float) cos((37.0 * (thisPointInRadians + thisAngle))));
260 	s->position[0] = fieldRange * cf
261 		* (float)cos(11.0 * (thisPointInRadians + (3.0*thisAngle)));
262 	s->position[1] = fieldRange * cf *
263 		(float) sin(12.0 * (thisPointInRadians + (4.0*thisAngle)));
264 	s->position[2] = fieldRange *
265 		(float) cos((23.0 * (thisPointInRadians + (12.0*thisAngle))));
266 
267 	rotation = thisAngle * 0.501 + 5.01 * (double)s->mystery
268 		/ (double)BIGMYSTERY;
269 	cr = cos(rotation);
270 	sr = sin(rotation);
271 	tmpX1 = s->position[0] * cr - s->position[1] * sr;
272 	tmpY1 = s->position[1] * cr + s->position[0] * sr;
273 	tmpZ1 = s->position[2];
274 
275 	tmpX2 = tmpX1 * cr - tmpZ1 * sr;
276 	tmpY2 = tmpY1;
277 	tmpZ2 = tmpZ1 * cr + tmpX1 * sr;
278 
279 	tmpX3 = tmpX2;
280 	tmpY3 = tmpY2 * cr - tmpZ2 * sr;
281 	tmpZ3 = tmpZ2 * cr + tmpY2 * sr + seraphDistance;
282 
283 	rotation = thisAngle * 2.501 + 85.01 * (double)s->mystery
284 		/ (double)BIGMYSTERY;
285 	cr = cos(rotation);
286 	sr = sin(rotation);
287 	tmpX4 = tmpX3 * cr - tmpY3 * sr;
288 	tmpY4 = tmpY3 * cr + tmpX3 * sr;
289 	tmpZ4 = tmpZ3;
290 
291 	s->position[0] = (float) tmpX4 + RandBell(5.0f*fieldCoherence);
292 	s->position[1] = (float) tmpY4 + RandBell(5.0f*fieldCoherence);
293 	s->position[2] = (float) tmpZ4 + RandBell(5.0f*fieldCoherence);
294 
295 	for (int i = 0;i < 3; i++)
296 		s->delta[i] = (s->position[i] - old[i]) / info->fDeltaTime;
297 }
298