gst/goom/: Add license headers in all source files. Remove filter.c from
[platform/upstream/gst-plugins-good.git] / gst / goom / tentacle3d.c
1 /* Goom Project
2  * Copyright (C) <2003> iOS-Software
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 #include <stdlib.h>
20
21 #include "v3d.h"
22 #include "surf3d.h"
23 #include "goom_tools.h"
24 #include "goom_config.h"
25 #include "goom_plugin_info.h"
26 #include "tentacle3d.h"
27
28 #define D 256.0f
29
30 #define nbgrid 6
31 #define definitionx 15
32 #define definitionz 45
33
34 typedef struct _TENTACLE_FX_DATA
35 {
36   PluginParam enabled_bp;
37   PluginParameters params;
38
39   float cycle;
40   grid3d *grille[nbgrid];
41   float *vals;
42
43 #define NB_TENTACLE_COLORS 4
44   int colors[NB_TENTACLE_COLORS];
45
46   int col;
47   int dstcol;
48   float lig;
49   float ligs;
50
51   /* statics from pretty_move */
52   float distt;
53   float distt2;
54   float rot;                    /* entre 0 et 2 * M_PI */
55   int happens;
56   int rotation;
57   int lock;
58 } TentacleFXData;
59
60 static void tentacle_new (TentacleFXData * data);
61 static void tentacle_update (PluginInfo * goomInfo, Pixel * buf, Pixel * back,
62     int W, int H, short[2][512], float, int drawit, TentacleFXData * data);
63 static void tentacle_free (TentacleFXData * data);
64
65 /* 
66  * VisualFX wrapper for the tentacles
67  */
68
69 static void
70 tentacle_fx_init (VisualFX * _this, PluginInfo * info)
71 {
72
73   TentacleFXData *data = (TentacleFXData *) malloc (sizeof (TentacleFXData));
74
75   data->enabled_bp = secure_b_param ("Enabled", 1);
76   data->params = plugin_parameters ("3D Tentacles", 1);
77   data->params.params[0] = &data->enabled_bp;
78
79   data->cycle = 0.0f;
80   data->col =
81       (0x28 << (ROUGE * 8)) | (0x2c << (VERT * 8)) | (0x5f << (BLEU * 8));
82   data->dstcol = 0;
83   data->lig = 1.15f;
84   data->ligs = 0.1f;
85
86   data->distt = 10.0f;
87   data->distt2 = 0.0f;
88   data->rot = 0.0f;             /* entre 0 et 2 * M_PI */
89   data->happens = 0;
90
91   data->rotation = 0;
92   data->lock = 0;
93   data->colors[0] =
94       (0x18 << (ROUGE * 8)) | (0x4c << (VERT * 8)) | (0x2f << (BLEU * 8));
95   data->colors[1] =
96       (0x48 << (ROUGE * 8)) | (0x2c << (VERT * 8)) | (0x6f << (BLEU * 8));
97   data->colors[2] =
98       (0x58 << (ROUGE * 8)) | (0x3c << (VERT * 8)) | (0x0f << (BLEU * 8));
99   data->colors[3] =
100       (0x87 << (ROUGE * 8)) | (0x55 << (VERT * 8)) | (0x74 << (BLEU * 8));
101   tentacle_new (data);
102
103   _this->params = &data->params;
104   _this->fx_data = (void *) data;
105 }
106
107 static void
108 tentacle_fx_apply (VisualFX * _this, Pixel * src, Pixel * dest,
109     PluginInfo * goomInfo)
110 {
111   TentacleFXData *data = (TentacleFXData *) _this->fx_data;
112
113   if (BVAL (data->enabled_bp)) {
114     tentacle_update (goomInfo, dest, src, goomInfo->screen.width,
115         goomInfo->screen.height, goomInfo->sound.samples,
116         (float) goomInfo->sound.accelvar,
117         goomInfo->curGState->drawTentacle, data);
118   }
119 }
120
121 static void
122 tentacle_fx_free (VisualFX * _this)
123 {
124   tentacle_free ((TentacleFXData *) _this->fx_data);
125   free (_this->fx_data);
126 }
127
128 VisualFX
129 tentacle_fx_create (void)
130 {
131   VisualFX fx;
132
133   fx.init = tentacle_fx_init;
134   fx.apply = tentacle_fx_apply;
135   fx.free = tentacle_fx_free;
136   fx.fx_data = NULL;
137   fx.params = NULL;
138   return fx;
139 }
140
141 /* ----- */
142
143 static void
144 tentacle_free (TentacleFXData * data)
145 {
146   int tmp;
147
148   /* FREE GRID */
149   for (tmp = 0; tmp < nbgrid; tmp++)
150     grid3d_free (data->grille[tmp]);
151   free (data->vals);
152
153   goom_plugin_parameters_free (&data->params);
154 }
155
156 static void
157 tentacle_new (TentacleFXData * data)
158 {
159   int tmp;
160
161   v3d center = { 0, -17.0, 0 };
162   data->vals = (float *) malloc ((definitionx + 20) * sizeof (float));
163
164   for (tmp = 0; tmp < nbgrid; tmp++) {
165     int x, z;
166
167     z = 45 + rand () % 30;
168     x = 85 + rand () % 5;
169     center.z = z;
170     data->grille[tmp] =
171         grid3d_new (x, definitionx, z, definitionz + rand () % 10, center);
172     center.y += 8;
173   }
174 }
175
176 static inline unsigned char
177 lighten (unsigned char value, float power)
178 {
179   int val = value;
180   float t = (float) val * log10 (power) / 2.0;
181
182   if (t > 0) {
183     val = (int) t;              /* (32.0f * log (t)); */
184     if (val > 255)
185       val = 255;
186     if (val < 0)
187       val = 0;
188     return val;
189   } else {
190     return 0;
191   }
192 }
193
194 static void
195 lightencolor (int *col, float power)
196 {
197   unsigned char *color;
198
199   color = (unsigned char *) col;
200   *color = lighten (*color, power);
201   color++;
202   *color = lighten (*color, power);
203   color++;
204   *color = lighten (*color, power);
205   color++;
206   *color = lighten (*color, power);
207 }
208
209 /* retourne x>>s , en testant le signe de x */
210 #define ShiftRight(_x,_s) ((_x<0) ? -(-_x>>_s) : (_x>>_s))
211
212 static int
213 evolutecolor (unsigned int src, unsigned int dest,
214     unsigned int mask, unsigned int incr)
215 {
216
217   int color = src & (~mask);
218
219   src &= mask;
220   dest &= mask;
221
222   if ((src != mask)
223       && (src < dest))
224     src += incr;
225
226   if (src > dest)
227     src -= incr;
228   return (src & mask) | color;
229 }
230
231 static void
232 pretty_move (PluginInfo * goomInfo, float cycle, float *dist, float *dist2,
233     float *rotangle, TentacleFXData * fx_data)
234 {
235
236   float tmp;
237
238   /* many magic numbers here... I don't really like that. */
239   if (fx_data->happens)
240     fx_data->happens -= 1;
241   else if (fx_data->lock == 0) {
242     fx_data->happens =
243         goom_irand (goomInfo->gRandom,
244         200) ? 0 : 100 + goom_irand (goomInfo->gRandom, 60);
245     fx_data->lock = fx_data->happens * 3 / 2;
246   } else
247     fx_data->lock--;
248
249   tmp = fx_data->happens ? 8.0f : 0;
250   *dist2 = fx_data->distt2 = (tmp + 15.0f * fx_data->distt2) / 16.0f;
251
252   tmp = 30 + D - 90.0f * (1.0f + sin (cycle * 19 / 20));
253   if (fx_data->happens)
254     tmp *= 0.6f;
255
256   *dist = fx_data->distt = (tmp + 3.0f * fx_data->distt) / 4.0f;
257
258   if (!fx_data->happens) {
259     tmp = M_PI * sin (cycle) / 32 + 3 * M_PI / 2;
260   } else {
261     fx_data->rotation =
262         goom_irand (goomInfo->gRandom,
263         500) ? fx_data->rotation : goom_irand (goomInfo->gRandom, 2);
264     if (fx_data->rotation)
265       cycle *= 2.0f * M_PI;
266     else
267       cycle *= -1.0f * M_PI;
268     tmp = cycle - (M_PI * 2.0) * floor (cycle / (M_PI * 2.0));
269   }
270
271   if (abs (tmp - fx_data->rot) > abs (tmp - (fx_data->rot + 2.0 * M_PI))) {
272     fx_data->rot = (tmp + 15.0f * (fx_data->rot + 2 * M_PI)) / 16.0f;
273     if (fx_data->rot > 2.0 * M_PI)
274       fx_data->rot -= 2.0 * M_PI;
275     *rotangle = fx_data->rot;
276   } else if (abs (tmp - fx_data->rot) > abs (tmp - (fx_data->rot - 2.0 * M_PI))) {
277     fx_data->rot = (tmp + 15.0f * (fx_data->rot - 2.0 * M_PI)) / 16.0f;
278     if (fx_data->rot < 0.0f)
279       fx_data->rot += 2.0 * M_PI;
280     *rotangle = fx_data->rot;
281   } else
282     *rotangle = fx_data->rot = (tmp + 15.0f * fx_data->rot) / 16.0f;
283 }
284
285 static void
286 tentacle_update (PluginInfo * goomInfo, Pixel * buf, Pixel * back, int W, int H,
287     short data[2][512], float rapport, int drawit, TentacleFXData * fx_data)
288 {
289
290   int tmp;
291   int tmp2;
292
293   int color;
294   int colorlow;
295
296   float dist, dist2, rotangle;
297
298   if ((!drawit) && (fx_data->ligs > 0.0f))
299     fx_data->ligs = -fx_data->ligs;
300
301   fx_data->lig += fx_data->ligs;
302
303   if (fx_data->lig > 1.01f) {
304     if ((fx_data->lig > 10.0f) | (fx_data->lig < 1.1f))
305       fx_data->ligs = -fx_data->ligs;
306
307     if ((fx_data->lig < 6.3f) && (goom_irand (goomInfo->gRandom, 30) == 0))
308       fx_data->dstcol = goom_irand (goomInfo->gRandom, NB_TENTACLE_COLORS);
309
310     fx_data->col =
311         evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff,
312         0x01);
313     fx_data->col =
314         evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff00,
315         0x0100);
316     fx_data->col =
317         evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff0000,
318         0x010000);
319     fx_data->col =
320         evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol],
321         0xff000000, 0x01000000);
322
323     color = fx_data->col;
324     colorlow = fx_data->col;
325
326     lightencolor (&color, fx_data->lig * 2.0f + 2.0f);
327     lightencolor (&colorlow, (fx_data->lig / 3.0f) + 0.67f);
328
329     rapport = 1.0f + 2.0f * (rapport - 1.0f);
330     rapport *= 1.2f;
331     if (rapport > 1.12f)
332       rapport = 1.12f;
333
334     pretty_move (goomInfo, fx_data->cycle, &dist, &dist2, &rotangle, fx_data);
335
336     for (tmp = 0; tmp < nbgrid; tmp++) {
337       for (tmp2 = 0; tmp2 < definitionx; tmp2++) {
338         float val =
339             (float) (ShiftRight (data[0][goom_irand (goomInfo->gRandom, 511)],
340                 10)) * rapport;
341
342         fx_data->vals[tmp2] = val;
343       }
344
345       grid3d_update (fx_data->grille[tmp], rotangle, fx_data->vals, dist2);
346     }
347     fx_data->cycle += 0.01f;
348     for (tmp = 0; tmp < nbgrid; tmp++)
349       grid3d_draw (goomInfo, fx_data->grille[tmp], color, colorlow, dist, buf,
350           back, W, H);
351   } else {
352     fx_data->lig = 1.05f;
353     if (fx_data->ligs < 0.0f)
354       fx_data->ligs = -fx_data->ligs;
355     pretty_move (goomInfo, fx_data->cycle, &dist, &dist2, &rotangle, fx_data);
356     fx_data->cycle += 0.1f;
357     if (fx_data->cycle > 1000)
358       fx_data->cycle = 0;
359   }
360 }