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