xref: /haiku/src/add-ons/screen_savers/flurry/Spark.cpp (revision 99d027cd0238c1d86da86d7c3f4200509ccc61a6)
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 #include "Spark.h"
33 #include "Shared.h"
34 
35 #define BIGMYSTERY 1800.0
36 #define MAXANGLES 16384
37 
38 #define fieldCoherence 0
39 #define fieldSpeed 12.0f
40 #define fieldRange 1000.0f
41 
42 void InitSpark(Spark *s)
43 {
44 	int i;
45 	for (i=0;i<3;i++)
46 	{
47 		s->position[i] = RandFlt(-100.0, 100.0);
48 	}
49 }
50 
51 void DrawSpark(flurry_info_t *info, Spark *s)
52 {
53 	const float black[4] = {0.0f,0.0f,0.0f,1.0f};
54 	float width,sx,sy;
55 	float a;
56 	float c = 0.0625f;
57 	float screenx;
58 	float screeny;
59 	float w,z, scale;
60 	int k;
61 	width = 60000.0f * info->sys_glWidth / 1024.0f;
62 
63 	z = s->position[2];
64 	sx = s->position[0] * info->sys_glWidth / z + info->sys_glWidth * 0.5f;
65 	sy = s->position[1] * info->sys_glWidth / z + info->sys_glHeight * 0.5f;
66 	w = width*4.0f / z;
67 
68 	screenx = sx;
69 	screeny = sy;
70 
71 	glPushMatrix();
72 	glTranslatef(screenx,screeny,0.0f);
73 	scale = w/50.0f;
74 	glScalef(scale,scale,0.0f);
75 	for (k=0;k<12;k++)
76 	{
77 		a = ((float) (random() % 3600)) / 10.0f;
78 		glRotatef(a,0.0f,0.0f,1.0f);
79 		glBegin(GL_QUAD_STRIP);
80 		glColor4fv(black);
81 		glVertex2f(-3.0f,0.0f);
82 		a = 2.0f + (float) (random() & 255) * c;
83 		glVertex2f(-3.0f,a);
84 		glColor4fv(s->color);
85 		glVertex2f(0.0f,0.0f);
86 		glColor4fv(black);
87 		glVertex2f(0.0f,a);
88 		glVertex2f(3.0f,0.0f);
89 		glVertex2f(3.0f,a);
90 		glEnd();
91 	}
92 	glPopMatrix();
93 }
94 
95 void UpdateSparkColour(flurry_info_t *info, Spark *s)
96 {
97 	const float rotationsPerSecond = (float) (2.0*M_PI*fieldSpeed/MAXANGLES);
98 	double thisPointInRadians;
99 	double thisAngle = info->fTime*rotationsPerSecond;
100 	float cf;
101 	float cycleTime = 20.0f;
102 	float colorRot;
103 	float redPhaseShift;
104 	float greenPhaseShift;
105 	float bluePhaseShift;
106 	float baseRed;
107 	float baseGreen;
108 	float baseBlue;
109 	float colorTime;
110 
111 	if (info->currentColorMode == rainbowColorMode)
112 	{
113 		cycleTime = 1.5f;
114 	}
115 	else if (info->currentColorMode == tiedyeColorMode)
116 	{
117 		cycleTime = 4.5f;
118 	}
119 	else if (info->currentColorMode == cyclicColorMode)
120 	{
121 		cycleTime = 20.0f;
122 	}
123 	else if (info->currentColorMode == slowCyclicColorMode)
124 	{
125 		cycleTime = 120.0f;
126 	}
127 	colorRot = (float) (2.0*M_PI/cycleTime);
128 	redPhaseShift = 0.0f; /* cycleTime * 0.0f / 3.0f */
129 	greenPhaseShift = cycleTime / 3.0f;
130 	bluePhaseShift = cycleTime * 2.0f / 3.0f ;
131 	colorTime = info->fTime;
132 	if (info->currentColorMode == whiteColorMode)
133 	{
134 		baseRed = 0.1875f;
135 		baseGreen = 0.1875f;
136 		baseBlue = 0.1875f;
137 	}
138 	else if (info->currentColorMode == multiColorMode)
139 	{
140 		baseRed = 0.0625f;
141 		baseGreen = 0.0625f;
142 		baseBlue = 0.0625f;
143 	}
144 	else if (info->currentColorMode == darkColorMode)
145 	{
146 		baseRed = 0.0f;
147 		baseGreen = 0.0f;
148 		baseBlue = 0.0f;
149 	}
150 	else
151 	{
152 		if (info->currentColorMode < slowCyclicColorMode)
153 		{
154 			colorTime = (info->currentColorMode / 6.0f) * cycleTime;
155 		}
156 		else
157 		{
158 			colorTime = info->fTime + info->randomSeed;
159 		}
160 		baseRed = 0.109375f * ((float) cos((colorTime+redPhaseShift)*colorRot)+1.0f);
161 		baseGreen = 0.109375f * ((float) cos((colorTime+greenPhaseShift)*colorRot)+1.0f);
162 		baseBlue = 0.109375f * ((float) cos((colorTime+bluePhaseShift)*colorRot)+1.0f);
163 	}
164 
165 	cf = ((float) (cos(7.0*((info->fTime)*rotationsPerSecond)) +
166 		cos(3.0*((info->fTime)*rotationsPerSecond)) +
167 		cos(13.0*((info->fTime)*rotationsPerSecond))));
168 	cf /= 6.0f;
169 	cf += 2.0f;
170 	thisPointInRadians = 2.0 * M_PI * (double) s->mystery / (double) BIGMYSTERY;
171 
172 	s->color[0] = baseRed + 0.0625f *
173 		(0.5f + (float) cos((15.0 * (thisPointInRadians + 3.0*thisAngle))) +
174 		(float) sin((7.0 * (thisPointInRadians + thisAngle))));
175 	s->color[1] = baseGreen + 0.0625f *
176 		(0.5f + (float) sin(((thisPointInRadians) + thisAngle)));
177 	s->color[2] = baseBlue + 0.0625f *
178 		(0.5f + (float) cos((37.0 * (thisPointInRadians + thisAngle))));
179 }
180 
181 void UpdateSpark(flurry_info_t *info, Spark *s)
182 {
183 	const float rotationsPerSecond = (float) (2.0*M_PI*fieldSpeed/MAXANGLES);
184 	double thisPointInRadians;
185 	double thisAngle = info->fTime*rotationsPerSecond;
186 	float cf;
187 	int i;
188 	double tmpX1,tmpY1,tmpZ1;
189 	double tmpX2,tmpY2,tmpZ2;
190 	double tmpX3,tmpY3,tmpZ3;
191 	double tmpX4,tmpY4,tmpZ4;
192 	double rotation;
193 	double cr;
194 	double sr;
195 	float cycleTime = 20.0f;
196 	float colorRot;
197 	float redPhaseShift;
198 	float greenPhaseShift;
199 	float bluePhaseShift;
200 	float baseRed;
201 	float baseGreen;
202 	float baseBlue;
203 	float colorTime;
204 
205 	float old[3];
206 
207 	if (info->currentColorMode == rainbowColorMode) {
208 		cycleTime = 1.5f;
209 	} else if (info->currentColorMode == tiedyeColorMode) {
210 		cycleTime = 4.5f;
211 	} else if (info->currentColorMode == cyclicColorMode) {
212 		cycleTime = 20.0f;
213 	} else if (info->currentColorMode == slowCyclicColorMode) {
214 		cycleTime = 120.0f;
215 	}
216 	colorRot = (float) (2.0*M_PI/cycleTime);
217 	redPhaseShift = 0.0f; /* cycleTime * 0.0f / 3.0f */
218 	greenPhaseShift = cycleTime / 3.0f;
219 	bluePhaseShift = cycleTime * 2.0f / 3.0f ;
220 	colorTime = info->fTime;
221 	if (info->currentColorMode == whiteColorMode) {
222 		baseRed = 0.1875f;
223 		baseGreen = 0.1875f;
224 		baseBlue = 0.1875f;
225 	} else if (info->currentColorMode == multiColorMode) {
226 		baseRed = 0.0625f;
227 		baseGreen = 0.0625f;
228 		baseBlue = 0.0625f;
229 	} else if (info->currentColorMode == darkColorMode) {
230 		baseRed = 0.0f;
231 		baseGreen = 0.0f;
232 		baseBlue = 0.0f;
233 	} else {
234 		if(info->currentColorMode < slowCyclicColorMode) {
235 			colorTime = (info->currentColorMode / 6.0f) * cycleTime;
236 		} else {
237 			colorTime = info->fTime + info->randomSeed;
238 		}
239 		baseRed = 0.109375f * ((float) cos((colorTime+redPhaseShift)*colorRot)+1.0f);
240 		baseGreen = 0.109375f * ((float) cos((colorTime+greenPhaseShift)*colorRot)+1.0f);
241 		baseBlue = 0.109375f * ((float) cos((colorTime+bluePhaseShift)*colorRot)+1.0f);
242 	}
243 
244 	for (i=0;i<3;i++) {
245 		old[i] = s->position[i];
246 	}
247 
248 	cf = ((float) (cos(7.0*((info->fTime)*rotationsPerSecond)) +
249 		cos(3.0*((info->fTime)*rotationsPerSecond)) +
250 		cos(13.0*((info->fTime)*rotationsPerSecond))));
251 	cf /= 6.0f;
252 	cf += 2.0f;
253 	thisPointInRadians = 2.0 * M_PI * (double) s->mystery / (double) BIGMYSTERY;
254 
255 	s->color[0] = baseRed + 0.0625f *
256 		(0.5f + (float) cos((15.0 * (thisPointInRadians + 3.0*thisAngle))) +
257 		 (float) sin((7.0 * (thisPointInRadians + thisAngle))));
258 	s->color[1] = baseGreen + 0.0625f *
259 		(0.5f + (float) sin(((thisPointInRadians) + thisAngle)));
260 	s->color[2] = baseBlue + 0.0625f *
261 		(0.5f + (float) cos((37.0 * (thisPointInRadians + thisAngle))));
262 	s->position[0] = fieldRange * cf *
263 		(float) cos(11.0 * (thisPointInRadians + (3.0*thisAngle)));
264 	s->position[1] = fieldRange * cf *
265 		(float) sin(12.0 * (thisPointInRadians + (4.0*thisAngle)));
266 	s->position[2] = fieldRange *
267 		(float) cos((23.0 * (thisPointInRadians + (12.0*thisAngle))));
268 
269 	rotation = thisAngle*0.501 + 5.01 * (double) s->mystery / (double) BIGMYSTERY;
270 	cr = cos(rotation);
271 	sr = sin(rotation);
272 	tmpX1 = s->position[0] * cr - s->position[1] * sr;
273 	tmpY1 = s->position[1] * cr + s->position[0] * sr;
274 	tmpZ1 = s->position[2];
275 
276 	tmpX2 = tmpX1 * cr - tmpZ1 * sr;
277 	tmpY2 = tmpY1;
278 	tmpZ2 = tmpZ1 * cr + tmpX1 * sr;
279 
280 	tmpX3 = tmpX2;
281 	tmpY3 = tmpY2 * cr - tmpZ2 * sr;
282 	tmpZ3 = tmpZ2 * cr + tmpY2 * sr + seraphDistance;
283 
284 	rotation = thisAngle*2.501 + 85.01 * (double) s->mystery / (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 (i=0;i<3;i++) {
296 		s->delta[i] = (s->position[i] - old[i])/info->fDeltaTime;
297 	}
298 }
299