tcp: Add APICall trace entry and move TRACEs into locked parts.
[haiku.git] / src / add-ons / screen_savers / flurry / Smoke.cpp
blobf4ef4e19743e0736586561a2cdc6c5e092eba403
1 /*
3 Copyright (c) 2002, Calum Robinson
4 All rights reserved.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
9 * Redistributions of source code must retain the above copyright notice, this
10 list of conditions and the following disclaimer.
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.
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.
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.
34 #include "Smoke.h"
36 #include "Shared.h"
37 #include "Star.h"
38 #include "Spark.h"
41 #define MAXANGLES 16384
42 #define NOT_QUITE_DEAD 3
44 #define streamBias 7.0f
45 #define incohesion 0.07f
46 #define streamSpeed 450.0
47 #define gravity 1500000.0f
48 #define intensity 75000.0f;
49 #define streamSize 25000.0f
50 #define colorIncoherence 0.15f
53 static float
54 FastDistance2D(float x, float y)
56 // this function computes the distance from 0,0 to x,y with ~3.5% error
58 // first compute the absolute value of x,y
59 x = (x < 0.0f) ? -x : x;
60 y = (y < 0.0f) ? -y : y;
62 // compute the minimum of x,y
63 float mn = x < y ? x : y;
65 // return the distance
66 return x + y - (mn * 0.5f) - (mn * 0.25f) + (mn * 0.0625f);
70 void
71 InitSmoke(SmokeV* s)
73 s->nextParticle = 0;
74 s->nextSubParticle = 0;
75 s->lastParticleTime = 0.25f;
76 s->firstTime = 1;
77 s->frame = 0;
79 for (int i = 0; i < 3; i++)
80 s->old[i] = RandFlt(-100.0, 100.0);
84 void
85 UpdateSmoke_ScalarBase(flurry_info_t* info, SmokeV* s)
87 float sx = info->star->position[0];
88 float sy = info->star->position[1];
89 float sz = info->star->position[2];
90 double frameRate;
91 double frameRateModifier;
93 s->frame++;
95 if (!s->firstTime) {
96 /* release 12 puffs every frame */
97 if (info->fTime - s->lastParticleTime >= 1.0f / 121.0f) {
98 float dx;
99 float dy;
100 float dz;
101 float deltax;
102 float deltay;
103 float deltaz;
104 float f;
105 float rsquared;
106 float mag;
108 dx = s->old[0] - sx;
109 dy = s->old[1] - sy;
110 dz = s->old[2] - sz;
111 mag = 5.0f;
112 deltax = (dx * mag);
113 deltay = (dy * mag);
114 deltaz = (dz * mag);
115 for(int i=0; i < info->numStreams; i++) {
116 float streamSpeedCoherenceFactor;
118 s->p[s->nextParticle].delta[0].f[s->nextSubParticle] = deltax;
119 s->p[s->nextParticle].delta[1].f[s->nextSubParticle] = deltay;
120 s->p[s->nextParticle].delta[2].f[s->nextSubParticle] = deltaz;
121 s->p[s->nextParticle].position[0].f[s->nextSubParticle] = sx;
122 s->p[s->nextParticle].position[1].f[s->nextSubParticle] = sy;
123 s->p[s->nextParticle].position[2].f[s->nextSubParticle] = sz;
124 s->p[s->nextParticle].oldposition[0].f[s->nextSubParticle] = sx;
125 s->p[s->nextParticle].oldposition[1].f[s->nextSubParticle] = sy;
126 s->p[s->nextParticle].oldposition[2].f[s->nextSubParticle] = sz;
127 streamSpeedCoherenceFactor = MAX_(0.0f,1.0f
128 + RandBell(0.25f * incohesion));
129 dx = s->p[s->nextParticle].position[0].f[s->nextSubParticle]
130 - info->spark[i]->position[0];
131 dy = s->p[s->nextParticle].position[1].f[s->nextSubParticle]
132 - info->spark[i]->position[1];
133 dz = s->p[s->nextParticle].position[2].f[s->nextSubParticle]
134 - info->spark[i]->position[2];
135 rsquared = (dx * dx + dy * dy + dz * dz);
136 f = streamSpeed * streamSpeedCoherenceFactor;
138 mag = f / (float)sqrt(rsquared);
140 s->p[s->nextParticle].delta[0].f[s->nextSubParticle]
141 -= (dx * mag);
142 s->p[s->nextParticle].delta[1].f[s->nextSubParticle]
143 -= (dy * mag);
144 s->p[s->nextParticle].delta[2].f[s->nextSubParticle]
145 -= (dz * mag);
146 s->p[s->nextParticle].color[0].f[s->nextSubParticle]
147 = info->spark[i]->color[0] * (1.0f
148 + RandBell(colorIncoherence));
149 s->p[s->nextParticle].color[1].f[s->nextSubParticle]
150 = info->spark[i]->color[1] * (1.0f
151 + RandBell(colorIncoherence));
152 s->p[s->nextParticle].color[2].f[s->nextSubParticle]
153 = info->spark[i]->color[2] * (1.0f
154 + RandBell(colorIncoherence));
155 s->p[s->nextParticle].color[3].f[s->nextSubParticle]
156 = 0.85f * (1.0f + RandBell(0.5f*colorIncoherence));
157 s->p[s->nextParticle].time.f[s->nextSubParticle] = info->fTime;
158 s->p[s->nextParticle].dead.i[s->nextSubParticle] = 0;
159 s->p[s->nextParticle].animFrame.i[s->nextSubParticle]
160 = (random() & 63);
161 s->nextSubParticle++;
162 if (s->nextSubParticle == 4) {
163 s->nextParticle++;
164 s->nextSubParticle = 0;
166 if (s->nextParticle >= NUMSMOKEPARTICLES / 4) {
167 s->nextParticle = 0;
168 s->nextSubParticle = 0;
172 s->lastParticleTime = info->fTime;
174 } else {
175 s->lastParticleTime = info->fTime;
176 s->firstTime = 0;
179 for(int i = 0; i < 3; i++)
180 s->old[i] = info->star->position[i];
182 frameRate = ((double) info->dframe) / (info->fTime);
183 frameRateModifier = 42.5f / frameRate;
185 for(int i = 0; i < NUMSMOKEPARTICLES / 4; i++) {
186 for(int k = 0; k < 4; k++) {
187 float dx;
188 float dy;
189 float dz;
190 float f;
191 float rsquared;
192 float mag;
193 float deltax;
194 float deltay;
195 float deltaz;
197 if (s->p[i].dead.i[k])
198 continue;
200 deltax = s->p[i].delta[0].f[k];
201 deltay = s->p[i].delta[1].f[k];
202 deltaz = s->p[i].delta[2].f[k];
204 for(int j = 0; j < info->numStreams; j++) {
205 dx = s->p[i].position[0].f[k] - info->spark[j]->position[0];
206 dy = s->p[i].position[1].f[k] - info->spark[j]->position[1];
207 dz = s->p[i].position[2].f[k] - info->spark[j]->position[2];
208 rsquared = (dx * dx + dy * dy + dz * dz);
210 f = (gravity/rsquared) * frameRateModifier;
212 if ((((i * 4) + k) % info->numStreams) == j)
213 f *= 1.0f + streamBias;
215 mag = f / (float) sqrt(rsquared);
217 deltax -= (dx * mag);
218 deltay -= (dy * mag);
219 deltaz -= (dz * mag);
222 // slow this particle down by info->drag
223 deltax *= info->drag;
224 deltay *= info->drag;
225 deltaz *= info->drag;
227 if ((deltax * deltax + deltay * deltay + deltaz * deltaz)
228 >= 25000000.0f) {
229 s->p[i].dead.i[k] = 1;
230 continue;
233 // update the position
234 s->p[i].delta[0].f[k] = deltax;
235 s->p[i].delta[1].f[k] = deltay;
236 s->p[i].delta[2].f[k] = deltaz;
237 for(int j = 0; j < 3; j++) {
238 s->p[i].oldposition[j].f[k] = s->p[i].position[j].f[k];
239 s->p[i].position[j].f[k]
240 += (s->p[i].delta[j].f[k]) * info->fDeltaTime;
247 void
248 DrawSmoke_Scalar(flurry_info_t* info, SmokeV* s, float brightness)
250 int svi = 0;
251 int sci = 0;
252 int sti = 0;
253 int si = 0;
254 float width;
255 float sx;
256 float sy;
257 float u0;
258 float v0;
259 float u1;
260 float v1;
261 float w;
262 float z;
263 float screenRatio = info->sys_glWidth / 1024.0f;
264 float hslash2 = info->sys_glHeight * 0.5f;
265 float wslash2 = info->sys_glWidth * 0.5f;
267 width = (streamSize + 2.5f * info->streamExpansion) * screenRatio;
269 for (int i = 0; i < NUMSMOKEPARTICLES / 4; i++) {
270 for (int k = 0; k < 4; k++) {
271 float thisWidth;
272 float oldz;
274 if (s->p[i].dead.i[k])
275 continue;
277 thisWidth = (streamSize + (info->fTime - s->p[i].time.f[k])
278 * info->streamExpansion) * screenRatio;
279 if (thisWidth >= width) {
280 s->p[i].dead.i[k] = 1;
281 continue;
283 z = s->p[i].position[2].f[k];
284 sx = s->p[i].position[0].f[k] * info->sys_glWidth / z + wslash2;
285 sy = s->p[i].position[1].f[k] * info->sys_glWidth / z + hslash2;
286 oldz = s->p[i].oldposition[2].f[k];
287 if (sx > info->sys_glWidth + 50.0f || sx < -50.0f
288 || sy > info->sys_glHeight + 50.0f || sy < -50.0f || z < 25.0f
289 || oldz < 25.0f) {
290 continue;
293 w = MAX_(1.0f, thisWidth / z);
295 float oldx = s->p[i].oldposition[0].f[k];
296 float oldy = s->p[i].oldposition[1].f[k];
297 float oldscreenx = (oldx * info->sys_glWidth / oldz) + wslash2;
298 float oldscreeny = (oldy * info->sys_glWidth / oldz) + hslash2;
299 float dx = (sx - oldscreenx);
300 float dy = (sy - oldscreeny);
302 float d = FastDistance2D(dx, dy);
304 float sm, os, ow;
305 if (d)
306 sm = w / d;
307 else
308 sm = 0.0f;
310 ow = MAX_(1.0f, thisWidth / oldz);
311 if (d)
312 os = ow / d;
313 else
314 os = 0.0f;
317 floatToVector cmv;
318 float cm;
319 float m = 1.0f + sm;
321 float dxs = dx * sm;
322 float dys = dy * sm;
323 float dxos = dx * os;
324 float dyos = dy * os;
325 float dxm = dx * m;
326 float dym = dy * m;
328 s->p[i].animFrame.i[k]++;
329 if (s->p[i].animFrame.i[k] >= 64)
330 s->p[i].animFrame.i[k] = 0;
332 u0 = (s->p[i].animFrame.i[k] & 7) * 0.125f;
333 v0 = (s->p[i].animFrame.i[k] >> 3) * 0.125f;
334 u1 = u0 + 0.125f;
335 v1 = v0 + 0.125f;
336 u1 = u0 + 0.125f;
337 v1 = v0 + 0.125f;
338 cm = (1.375f - thisWidth / width);
339 if (s->p[i].dead.i[k] == 3) {
340 cm *= 0.125f;
341 s->p[i].dead.i[k] = 1;
343 si++;
344 cm *= brightness;
345 cmv.f[0] = s->p[i].color[0].f[k] * cm;
346 cmv.f[1] = s->p[i].color[1].f[k] * cm;
347 cmv.f[2] = s->p[i].color[2].f[k] * cm;
348 cmv.f[3] = s->p[i].color[3].f[k] * cm;
350 #if 0
351 // MDT we can't use vectors in the Scalar routine
352 s->seraphimColors[sci++].v = cmv.v;
353 s->seraphimColors[sci++].v = cmv.v;
354 s->seraphimColors[sci++].v = cmv.v;
355 s->seraphimColors[sci++].v = cmv.v;
356 #else
358 for (int jj = 0; jj < 4; jj++) {
359 for (int ii = 0; ii < 4; ii++)
360 s->seraphimColors[sci].f[ii] = cmv.f[ii];
361 sci += 1;
364 #endif
366 s->seraphimTextures[sti++] = u0;
367 s->seraphimTextures[sti++] = v0;
368 s->seraphimTextures[sti++] = u0;
369 s->seraphimTextures[sti++] = v1;
371 s->seraphimTextures[sti++] = u1;
372 s->seraphimTextures[sti++] = v1;
373 s->seraphimTextures[sti++] = u1;
374 s->seraphimTextures[sti++] = v0;
376 s->seraphimVertices[svi].f[0] = sx + dxm - dys;
377 s->seraphimVertices[svi].f[1] = sy + dym + dxs;
378 s->seraphimVertices[svi].f[2] = sx + dxm + dys;
379 s->seraphimVertices[svi].f[3] = sy + dym - dxs;
380 svi++;
382 s->seraphimVertices[svi].f[0] = oldscreenx - dxm + dyos;
383 s->seraphimVertices[svi].f[1] = oldscreeny - dym - dxos;
384 s->seraphimVertices[svi].f[2] = oldscreenx - dxm - dyos;
385 s->seraphimVertices[svi].f[3] = oldscreeny - dym + dxos;
386 svi++;
392 glColorPointer(4, GL_FLOAT, 0, s->seraphimColors);
393 glVertexPointer(2, GL_FLOAT, 0, s->seraphimVertices);
394 glTexCoordPointer(2, GL_FLOAT, 0, s->seraphimTextures);
395 glDrawArrays(GL_QUADS, 0, si * 4);