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