1 #include "PresetFrameIO.hpp"
2 #include "wipemalloc.h"
3 #include <math.h>
4 #include <cassert>
5 #include <iostream>
6 #include <cmath>
7 #include "Renderer/BeatDetect.hpp"
8
9 #ifdef __SSE2__
10 #include <immintrin.h>
11 #endif
12
13
PresetInputs()14 PresetInputs::PresetInputs() : PipelineContext()
15 {
16 }
17
18
update(const BeatDetect & music,const PipelineContext & context)19 void PresetInputs::update(const BeatDetect & music, const PipelineContext & context) {
20
21 // Reflect new values form the beat detection unit
22 this->bass = music.bass;
23 this->mid = music.mid;
24 this->treb = music.treb;
25 this->bass_att = music.bass_att;
26 this->mid_att = music.mid_att;
27 this->treb_att = music.treb_att;
28
29 // Reflect new values from the pipeline context
30 this->fps = context.fps;
31 this->time = context.time;
32
33 this->frame = context.frame;
34 this->progress = context.progress;
35 }
36
37
alloc_mesh(size_t gx,size_t gy)38 float **alloc_mesh(size_t gx, size_t gy)
39 {
40 // round gy up to multiple 4 (for possible SSE optimization)
41 gy = (gy+3) & ~(size_t)3;
42
43 float **mesh = (float **)wipe_aligned_alloc(gx * sizeof(float *));
44 float *m = (float *)wipe_aligned_alloc(gx * gy * sizeof(float));
45 for (unsigned int x = 0; x < gx; x++ )
46 mesh[x] = m + (gy * x);
47 return mesh;
48 }
49
free_mesh(float ** mesh)50 float **free_mesh(float **mesh)
51 {
52 wipe_aligned_free(mesh[0]);
53 wipe_aligned_free(mesh);
54 return NULL;
55 }
56
copy_mesh(float ** dst,float ** src,int gx,int gy)57 void copy_mesh(float **dst, float **src, int gx, int gy)
58 {
59 memcpy(dst[0], src[0], gx*gy*sizeof(float));
60 }
61
62
Initialize(int _gx,int _gy)63 void PresetInputs::Initialize ( int _gx, int _gy )
64 {
65 int x, y;
66
67 this->gx = _gx;
68 this->gy = _gy;
69
70
71 /// @bug no clue if this block belongs here
72 // ***
73 progress = 0;
74 frame = 1;
75
76 x_per_pixel = 0;
77 y_per_pixel = 0;
78 rad_per_pixel = 0;
79 ang_per_pixel = 0;
80 // ***
81
82 this->x_mesh = alloc_mesh(gx, gy);
83 this->y_mesh = alloc_mesh(gx, gy);
84 this->rad_mesh = alloc_mesh(gx, gy);
85 this->theta_mesh= alloc_mesh(gx, gy);
86 this->origtheta = alloc_mesh(gx, gy);
87 this->origrad = alloc_mesh(gx, gy);
88 this->origx = alloc_mesh(gx, gy);
89 this->origy = alloc_mesh(gx, gy);
90
91 for ( x=0;x<gx;x++ )
92 {
93 for ( y=0;y<gy;y++ )
94 {
95 this->origx[x][y]=x/ ( float ) ( gx-1 );
96 this->origy[x][y]= - ( ( y/ ( float ) ( gy-1 ) )-1 );
97 this->origrad[x][y]=hypot ( ( this->origx[x][y]-.5 ) *2, ( this->origy[x][y]-.5 ) *2 ) * .7071067;
98 this->origtheta[x][y]=atan2 ( ( ( this->origy[x][y]-.5 ) *2 ), ( ( this->origx[x][y]-.5 ) *2 ) );
99 }
100 }
101 }
102
103
PresetOutputs()104 PresetOutputs::PresetOutputs() : Pipeline()
105 {}
106
107
~PresetOutputs()108 PresetOutputs::~PresetOutputs()
109 {
110 assert(this->gx > 0);
111
112 this->rad_mesh = free_mesh(this->rad_mesh);
113 this->sx_mesh = free_mesh(this->sx_mesh);
114 this->sy_mesh = free_mesh(this->sy_mesh);
115 this->dy_mesh = free_mesh(this->dy_mesh);
116 this->dx_mesh = free_mesh(this->dx_mesh);
117 this->cy_mesh = free_mesh(this->cy_mesh);
118 this->cx_mesh = free_mesh(this->cx_mesh);
119 this->warp_mesh = free_mesh(this->warp_mesh);
120 this->zoom_mesh = free_mesh(this->zoom_mesh);
121 this->zoomexp_mesh = free_mesh(this->zoomexp_mesh);
122 this->rot_mesh = free_mesh(this->rot_mesh);
123 this->orig_x = free_mesh(this->orig_x);
124 this->orig_y = free_mesh(this->orig_y);
125
126 customWaves.clear();
127 customShapes.clear();
128 drawables.clear();
129 }
130
131
Render(const BeatDetect & music,const PipelineContext & context)132 void PresetOutputs::Render(const BeatDetect &music, const PipelineContext &context)
133 {
134 PerPixelMath(context);
135
136 drawables.clear();
137
138 drawables.push_back(&mv);
139
140 for (PresetOutputs::cshape_container::iterator pos = customShapes.begin();
141 pos != customShapes.end(); ++pos)
142 {
143 if ((*pos)->enabled==1)
144 drawables.push_back((*pos));
145 }
146
147 for (PresetOutputs::cwave_container::iterator pos = customWaves.begin();
148 pos != customWaves.end(); ++pos)
149 {
150 if ((*pos)->enabled==1)
151 drawables.push_back((*pos));
152 }
153
154 drawables.push_back(&wave);
155
156 if (bDarkenCenter==1)
157 drawables.push_back(&darkenCenter);
158 drawables.push_back(&border);
159
160 compositeDrawables.clear();
161 compositeDrawables.push_back(&videoEcho);
162
163 if (bBrighten==1)
164 compositeDrawables.push_back(&brighten);
165
166 if (bDarken==1)
167 compositeDrawables.push_back(&darken);
168
169 if (bSolarize==1)
170 compositeDrawables.push_back(&solarize);
171
172 if (bInvert==1)
173 compositeDrawables.push_back(&invert);
174 }
175
176
177 // N.B. The more optimization that can be done on this method, the better! This is called a lot and can probably be improved.
PerPixelMath_c(const PipelineContext & context)178 void PresetOutputs::PerPixelMath_c(const PipelineContext &context)
179 {
180 for (int x = 0; x < gx; x++)
181 {
182 for (int y = 0; y < gy; y++)
183 {
184 const float fZoom2 = std::pow(this->zoom_mesh[x][y], std::pow(this->zoomexp_mesh[x][y],
185 rad_mesh[x][y] * 2.0f - 1.0f));
186 const float fZoom2Inv = 1.0f / fZoom2;
187 this->x_mesh[x][y] = this->orig_x[x][y] * 0.5f * fZoom2Inv + 0.5f;
188 this->x_mesh[x][y] = (this->x_mesh[x][y] - this->cx_mesh[x][y]) / this->sx_mesh[x][y] + this->cx_mesh[x][y];
189 this->y_mesh[x][y] = this->orig_y[x][y] * 0.5f * fZoom2Inv + 0.5f;
190 this->y_mesh[x][y] = (this->y_mesh[x][y] - this->cy_mesh[x][y]) / this->sy_mesh[x][y] + this->cy_mesh[x][y];
191 }
192 }
193
194 const float fWarpTime = context.time * this->fWarpAnimSpeed;
195 const float fWarpScaleInv = 1.0f / this->fWarpScale;
196 float f[4];
197 f[0] = 11.68f + 4.0f * cosf(fWarpTime * 1.413f + 10);
198 f[1] = 8.77f + 3.0f * cosf(fWarpTime * 1.113f + 7);
199 f[2] = 10.54f + 3.0f * cosf(fWarpTime * 1.233f + 3);
200 f[3] = 11.49f + 4.0f * cosf(fWarpTime * 0.933f + 5);
201
202 for (int x = 0; x < gx; x++)
203 {
204 for (int y = 0; y < gy; y++)
205 {
206 const float orig_x2 = this->orig_x[x][y];
207 const float orig_y2 = this->orig_y[x][y];
208 const float warp_mesh2 = this->warp_mesh[x][y] * 0.0035f;
209
210 this->x_mesh[x][y] +=
211 (warp_mesh2 * sinf(fWarpTime * 0.333f + fWarpScaleInv * (orig_x2 * f[0] - orig_y2 * f[3]))) +
212 (warp_mesh2 * cosf(fWarpTime * 0.753f - fWarpScaleInv * (orig_x2 * f[1] - orig_y2 * f[2])));
213
214 this->y_mesh[x][y] +=
215 (warp_mesh2 * cosf(fWarpTime * 0.375f - fWarpScaleInv * (orig_x2 * f[2] + orig_y2 * f[1]))) +
216 (warp_mesh2 * sinf(fWarpTime * 0.825f + fWarpScaleInv * (orig_x2 * f[0] + orig_y2 * f[3])));
217 }
218 }
219
220 for (int x = 0; x < gx; x++)
221 {
222 for (int y = 0; y < gy; y++)
223 {
224 const float u2 = this->x_mesh[x][y] - this->cx_mesh[x][y];
225 const float v2 = this->y_mesh[x][y] - this->cy_mesh[x][y];
226
227 const float rot2 = this->rot_mesh[x][y];
228 const float cos_rot = cosf(rot2);
229 const float sin_rot = sinf(rot2);
230
231 this->x_mesh[x][y] = u2 * cos_rot - v2 * sin_rot + this->cx_mesh[x][y] - this->dx_mesh[x][y];
232 this->y_mesh[x][y] = u2 * sin_rot + v2 * cos_rot + this->cy_mesh[x][y] - this->dy_mesh[x][y];
233 }
234 }
235 }
236
237
238 #ifdef __SSE2__
239
240 // is there an SSE way to do this?
_mm_pow(__m128 x,__m128 y)241 inline __m128 _mm_pow(__m128 x, __m128 y)
242 {
243 float X[4];
244 float Y[4];
245 _mm_store_ps(X,x);
246 _mm_store_ps(Y,y);
247 X[0] = __builtin_powf(X[0],Y[0]);
248 X[1] = __builtin_powf(X[1],Y[1]);
249 X[2] = __builtin_powf(X[2],Y[2]);
250 X[3] = __builtin_powf(X[3],Y[3]);
251 return _mm_load_ps(X);
252 }
_mm_sincosf(__m128 x,__m128 & sinx,__m128 & cosx)253 inline void _mm_sincosf(__m128 x, __m128 &sinx, __m128 &cosx)
254 {
255 float X[4], S[4], C[4];
256 _mm_store_ps(X,x);
257 S[0] = sinf(X[0]);
258 C[0] = cosf(X[0]);
259 S[1] = sinf(X[1]);
260 C[1] = cosf(X[1]);
261 S[2] = sinf(X[2]);
262 C[2] = cosf(X[2]);
263 S[3] = sinf(X[3]);
264 C[3] = cosf(X[3]);
265 sinx = _mm_load_ps(S);
266 cosx = _mm_load_ps(C);
267 }
_mm_sinf(__m128 x)268 inline __m128 _mm_sinf(__m128 x)
269 {
270 float X[4];
271 _mm_store_ps(X,x);
272 X[0] = sinf(X[0]);
273 X[1] = sinf(X[1]);
274 X[2] = sinf(X[2]);
275 X[3] = sinf(X[3]);
276 return _mm_load_ps(X);
277 }
_mm_cosf(__m128 x)278 inline __m128 _mm_cosf(__m128 x)
279 {
280 float X[4];
281 _mm_store_ps(X,x);
282 X[0] = cosf(X[0]);
283 X[1] = cosf(X[1]);
284 X[2] = cosf(X[2]);
285 X[3] = cosf(X[3]);
286 return _mm_load_ps(X);
287 }
288
289
PerPixelMath_sse(const PipelineContext & context)290 void PresetOutputs::PerPixelMath_sse(const PipelineContext &context)
291 {
292 for (int x = 0; x < gx; x++)
293 {
294 for (int y = 0; y < gy; y += 4)
295 {
296 // fZoom2 = std::pow(this->zoom_mesh[x][y], std::pow(this->zoomexp_mesh[x][y],
297 // rad_mesh[x][y] * 2.0f - 1.0f));
298 __m128 rad_mesh_scaled =
299 _mm_sub_ps(
300 _mm_mul_ps(
301 _mm_load_ps(&this->rad_mesh[x][y]),
302 _mm_set_ps1(2.0f)),
303 _mm_set_ps1(1.0f));
304 __m128 zoom_mesh2 = _mm_load_ps(&this->zoom_mesh[x][y]);
305 __m128 zoomexp_mesh2 = _mm_load_ps(&this->zoomexp_mesh[x][y]);
306 __m128 fZoom2 = _mm_pow(zoom_mesh2, _mm_pow(zoomexp_mesh2, rad_mesh_scaled));
307 // fZoom2Inv = 1.0f / fZoom2;
308 __m128 fZoomInv = _mm_rcp_ps(fZoom2);
309
310 // this->x_mesh[x][y] = this->orig_x[x][y] * 0.5f * fZoom2Inv + 0.5f;
311 __m128 x_mesh2 =
312 _mm_add_ps(
313 _mm_mul_ps(
314 _mm_load_ps(&this->orig_x[x][y]),
315 _mm_mul_ps(fZoomInv,_mm_set_ps1(0.5f))), // CONSIDER: common sub-expression
316 _mm_set_ps1(0.5f));
317 // this->x_mesh[x][y] = (this->x_mesh[x][y] - this->cx_mesh[x][y]) / this->sx_mesh[x][y] + this->cx_mesh[x][y];
318 __m128 cx_mesh2 = _mm_load_ps(&this->cx_mesh[x][y]);
319 __m128 sx_mesh2 = _mm_load_ps(&this->sx_mesh[x][y]);
320 _mm_store_ps(&this->x_mesh[x][y],
321 _mm_add_ps(
322 _mm_div_ps(
323 _mm_sub_ps(x_mesh2,cx_mesh2),
324 sx_mesh2),
325 cx_mesh2
326 ));
327
328 // this->y_mesh[x][y] = this->orig_y[x][y] * 0.5f * fZoom2Inv + 0.5f;
329 __m128 y_mesh2 =
330 _mm_add_ps(
331 _mm_mul_ps(
332 _mm_load_ps(&this->orig_y[x][y]),
333 _mm_mul_ps(fZoomInv,_mm_set_ps1(0.5f))),
334 _mm_set_ps1(0.5f));
335 // this->y_mesh[x][y] = (this->y_mesh[x][y] - this->cy_mesh[x][y]) / this->sy_mesh[x][y] + this->cy_mesh[x][y];
336 __m128 cy_mesh2 = _mm_load_ps(&this->cy_mesh[x][y]);
337 __m128 sy_mesh2 = _mm_load_ps(&this->sy_mesh[x][y]);
338 _mm_store_ps(&this->y_mesh[x][y],
339 _mm_add_ps(
340 _mm_div_ps(
341 _mm_sub_ps(y_mesh2,cy_mesh2),
342 sy_mesh2),
343 cy_mesh2
344 ));
345 }
346 }
347
348 const float fWarpTime = context.time * this->fWarpAnimSpeed;
349 const float fWarpScaleInv = 1.0f / this->fWarpScale;
350 const float f[4] =
351 {
352 11.68f + 4.0f * cosf(fWarpTime * 1.413f + 10),
353 8.77f + 3.0f * cosf(fWarpTime * 1.113f + 7),
354 10.54f + 3.0f * cosf(fWarpTime * 1.233f + 3),
355 11.49f + 4.0f * cosf(fWarpTime * 0.933f + 5)
356 };
357
358 for (int x = 0; x < gx; x++)
359 {
360 for (int y = 0; y < gy; y+=4)
361 {
362 //float orig_x = this->orig_x[x][y];
363 //float orig_y = this->orig_y[x][y];
364 //float warp_mesh = this->warp_mesh[x][y] * 0.0035f;
365 const __m128 orig_x2 = _mm_load_ps(&this->orig_x[x][y]);
366 const __m128 orig_y2 = _mm_load_ps(&this->orig_y[x][y]);
367 const __m128 warp_mesh2 = _mm_mul_ps(_mm_load_ps(&this->warp_mesh[x][y]), _mm_set_ps1(0.0035f));
368
369 // this->x_mesh[x][y] +=
370 // (warp_mesh * sinf(fWarpTime * 0.333f + fWarpScaleInv * (orig_x * f[0] - orig_y * f[3]))) +
371 // (warp_mesh * cosf(fWarpTime * 0.753f - fWarpScaleInv * (orig_x * f[1] - orig_y * f[2])));
372 _mm_store_ps(&this->x_mesh[x][y],
373 _mm_add_ps(_mm_load_ps(&this->x_mesh[x][y]),
374 _mm_add_ps(
375 _mm_mul_ps(warp_mesh2, _mm_sinf(
376 _mm_add_ps(
377 _mm_set_ps1(fWarpTime*0.333f),
378 _mm_mul_ps(_mm_set_ps1(fWarpScaleInv),
379 _mm_sub_ps(
380 _mm_mul_ps(orig_x2, _mm_set_ps1(f[0])),
381 _mm_mul_ps(orig_y2, _mm_set_ps1(f[3]))
382 ))))),
383 _mm_mul_ps(warp_mesh2, _mm_cosf(
384 _mm_sub_ps(
385 _mm_set_ps1(fWarpTime*0.753f),
386 _mm_mul_ps(_mm_set_ps1(fWarpScaleInv),
387 _mm_sub_ps(
388 _mm_mul_ps(orig_x2, _mm_set_ps1(f[1])),
389 _mm_mul_ps(orig_y2, _mm_set_ps1(f[2]))
390 ))))))));
391
392 // this->y_mesh[x][y] +=
393 // (warp_mesh * cosf(fWarpTime * 0.375f - fWarpScaleInv * (orig_x * f[2] + orig_y * f[1]))) +
394 // (warp_mesh * sinf(fWarpTime * 0.825f + fWarpScaleInv * (orig_x * f[0] + orig_y * f[3])));
395 _mm_store_ps(&this->y_mesh[x][y],
396 _mm_add_ps(_mm_load_ps(&this->y_mesh[x][y]),
397 _mm_add_ps(
398 _mm_mul_ps(warp_mesh2, _mm_cosf(
399 _mm_sub_ps(
400 _mm_set_ps1(fWarpTime*0.375f),
401 _mm_mul_ps(_mm_set_ps1(fWarpScaleInv),
402 _mm_add_ps(
403 _mm_mul_ps(orig_x2, _mm_set_ps1(f[2])),
404 _mm_mul_ps(orig_y2, _mm_set_ps1(f[1]))
405 ))))),
406 _mm_mul_ps(warp_mesh2, _mm_sinf(
407 _mm_add_ps(
408 _mm_set_ps1(fWarpTime*0.825f),
409 _mm_mul_ps(_mm_set_ps1(fWarpScaleInv),
410 _mm_add_ps(
411 _mm_mul_ps(orig_x2, _mm_set_ps1(f[0])),
412 _mm_mul_ps(orig_y2, _mm_set_ps1(f[3]))
413 ))))))));
414 }
415 }
416 for (int x = 0; x < gx; x++)
417 {
418 for (int y = 0; y < gy; y+=4)
419 {
420 // const float u2 = this->x_mesh[x][y] - this->cx_mesh[x][y];
421 // const float v2 = this->y_mesh[x][y] - this->cy_mesh[x][y];
422 const __m128 u2 = _mm_sub_ps(_mm_load_ps(&this->x_mesh[x][y]),_mm_load_ps(&this->cx_mesh[x][y]));
423 const __m128 v2 = _mm_sub_ps(_mm_load_ps(&this->y_mesh[x][y]),_mm_load_ps(&this->cy_mesh[x][y]));
424
425 // const float rot = this->rot_mesh[x][y];
426 // const float cos_rot = cosf(rot);
427 // const float sin_rot = sinf(rot);
428 __m128 sin_rot, cos_rot;
429 _mm_sincosf(_mm_load_ps(&this->rot_mesh[x][y]), sin_rot, cos_rot);
430
431 // this->x_mesh[x][y] = u2 * cos_rot - v2 * sin_rot + this->cx_mesh[x][y] - this->dx_mesh[x][y];
432 _mm_store_ps(&this->x_mesh[x][y],
433 _mm_add_ps(
434 _mm_sub_ps(_mm_mul_ps(u2, cos_rot), _mm_mul_ps(v2,sin_rot)),
435 _mm_sub_ps(_mm_load_ps(&this->cx_mesh[x][y]), _mm_load_ps(&this->dx_mesh[x][y]))
436 ));
437 // this->y_mesh[x][y] = u2 * sin_rot + v2 * cos_rot + this->cy_mesh[x][y] - this->dy_mesh[x][y];
438 _mm_store_ps(&this->y_mesh[x][y],
439 _mm_add_ps(
440 _mm_add_ps(_mm_mul_ps(u2, sin_rot), _mm_mul_ps(v2,cos_rot)),
441 _mm_sub_ps(_mm_load_ps(&this->cy_mesh[x][y]), _mm_load_ps(&this->dy_mesh[x][y]))
442 ));
443 }
444 }
445 }
446 #endif
447
448
PerPixelMath(const PipelineContext & context)449 void PresetOutputs::PerPixelMath(const PipelineContext &context)
450 {
451 #ifdef __SSE2__
452 PerPixelMath_sse(context);
453 #else
454 PerPixelMath_c(context);
455 #endif
456 }
457
458
Initialize(int _gx,int _gy)459 void PresetOutputs::Initialize ( int _gx, int _gy )
460 {
461 assert(_gx > 0);
462
463 this->gx = _gx;
464 this->gy = _gy;
465
466 staticPerPixel = true;
467
468 assert(this->gx > 0);
469 int x;
470 this->x_mesh = alloc_mesh( gx, gy );
471 this->y_mesh = alloc_mesh( gx, gy );
472 this->sx_mesh = alloc_mesh( gx, gy );
473 this->sy_mesh = alloc_mesh( gx, gy );
474 this->dx_mesh = alloc_mesh( gx, gy );
475 this->dy_mesh = alloc_mesh( gx, gy );
476 this->cx_mesh = alloc_mesh( gx, gy );
477 this->cy_mesh = alloc_mesh( gx, gy );
478 this->zoom_mesh = alloc_mesh( gx, gy );
479 this->zoomexp_mesh = alloc_mesh( gx, gy );
480 this->rot_mesh = alloc_mesh( gx, gy );
481
482 this->warp_mesh = alloc_mesh( gx, gy );
483 this->rad_mesh = alloc_mesh( gx, gy );
484 this->orig_x = alloc_mesh( gx, gy );
485 this->orig_y = alloc_mesh( gx, gy );
486
487 //initialize reference grid values
488 for (x = 0; x < gx; x++)
489 {
490 for (int y = 0; y < gy; y++)
491 {
492 float origx = x / (float) (gx - 1);
493 float origy = -((y / (float) (gy - 1)) - 1);
494
495 rad_mesh[x][y]=hypot ( ( origx-.5 ) *2, ( origy-.5 ) *2 ) * .7071067;
496 orig_x[x][y] = (origx - .5) * 2;
497 orig_y[x][y] = (origy - .5) * 2;
498 }
499 }
500 }
501
502
~PresetInputs()503 PresetInputs::~PresetInputs()
504 {
505 this->origx = free_mesh ( this->origx );
506 this->origy = free_mesh ( this->origy );
507 this->origrad = free_mesh ( this->origrad );
508 this->origtheta = free_mesh ( this->origtheta );
509 this->x_mesh = free_mesh ( this->x_mesh );
510 this->y_mesh = free_mesh ( this->y_mesh );
511 this->rad_mesh = free_mesh ( this->rad_mesh );
512 this->theta_mesh = free_mesh ( this->theta_mesh );
513 }
514
515
resetMesh()516 void PresetInputs::resetMesh()
517 {
518 assert ( x_mesh );
519 assert ( y_mesh );
520 assert ( rad_mesh );
521 assert ( theta_mesh );
522
523 copy_mesh(this->x_mesh, this->origx, gx, gy);
524 copy_mesh(this->y_mesh, this->origy, gx, gy);
525 copy_mesh(this->rad_mesh, this->origrad, gx, gy);
526 copy_mesh(this->theta_mesh, this->origtheta, gx, gy);
527 }
528
529
530 #ifdef USE_MERGE_PRESET_CODE
MergePresets(PresetOutputs & A,PresetOutputs & B,double ratio,int gx,int gy)531 void PresetMerger::MergePresets(PresetOutputs & A, PresetOutputs & B, double ratio, int gx, int gy)
532 {
533
534 double invratio = 1.0 - ratio;
535 //Merge Simple Waveforms
536 //
537 // All the mess is because of Waveform 7, which is two lines.
538 //
539
540
541 //Merge Custom Shapes and Custom Waves
542
543 for (PresetOutputs::cshape_container::iterator pos = A.customShapes.begin();
544 pos != A.customShapes.end(); ++pos)
545 {
546 (*pos)->a *= invratio;
547 (*pos)->a2 *= invratio;
548 (*pos)->border_a *= invratio;
549 }
550
551 for (PresetOutputs::cshape_container::iterator pos = B.customShapes.begin();
552 pos != B.customShapes.end(); ++pos)
553 {
554 (*pos)->a *= ratio;
555 (*pos)->a2 *= ratio;
556 (*pos)->border_a *= ratio;
557
558 A.customShapes.push_back(*pos);
559
560 }
561 for (PresetOutputs::cwave_container::iterator pos = A.customWaves.begin();
562 pos != A.customWaves.end(); ++pos)
563 {
564 (*pos)->a *= invratio;
565 for (int x=0; x < (*pos)->samples; x++)
566 {
567 (*pos)->a_mesh[x]= (*pos)->a_mesh[x]*invratio;
568 }
569 }
570
571 for (PresetOutputs::cwave_container::iterator pos = B.customWaves.begin();
572 pos != B.customWaves.end(); ++pos)
573 {
574 (*pos)->a *= ratio;
575 for (int x=0; x < (*pos)->samples; x++)
576 {
577 (*pos)->a_mesh[x]= (*pos)->a_mesh[x]*ratio;
578 }
579 A.customWaves.push_back(*pos);
580 }
581
582
583 //Interpolate Per-Pixel mesh
584
585 for (int x=0;x<gx;x++)
586 {
587 for(int y=0;y<gy;y++)
588 {
589 A.x_mesh[x][y] = A.x_mesh[x][y]* invratio + B.x_mesh[x][y]*ratio;
590 }
591 }
592 for (int x=0;x<gx;x++)
593 {
594 for(int y=0;y<gy;y++)
595 {
596 A.y_mesh[x][y] = A.y_mesh[x][y]* invratio + B.y_mesh[x][y]*ratio;
597 }
598 }
599
600
601
602 //Interpolate PerFrame floats
603
604 A.screenDecay = A.screenDecay * invratio + B.screenDecay * ratio;
605
606 A.wave.r = A.wave.r* invratio + B.wave.r*ratio;
607 A.wave.g = A.wave.g* invratio + B.wave.g*ratio;
608 A.wave.b = A.wave.b* invratio + B.wave.b*ratio;
609 A.wave.a = A.wave.a* invratio + B.wave.a*ratio;
610 A.wave.x = A.wave.x* invratio + B.wave.x*ratio;
611 A.wave.y = A.wave.y* invratio + B.wave.y*ratio;
612 A.wave.mystery = A.wave.mystery* invratio + B.wave.mystery*ratio;
613
614 A.border.outer_size = A.border.outer_size* invratio + B.border.outer_size*ratio;
615 A.border.outer_r = A.border.outer_r* invratio + B.border.outer_r*ratio;
616 A.border.outer_g = A.border.outer_g* invratio + B.border.outer_g*ratio;
617 A.border.outer_b = A.border.outer_b* invratio + B.border.outer_b*ratio;
618 A.border.outer_a = A.border.outer_a* invratio + B.border.outer_a*ratio;
619
620 A.border.inner_size = A.border.inner_size* invratio + B.border.inner_size*ratio;
621 A.border.inner_r = A.border.inner_r* invratio + B.border.inner_r*ratio;
622 A.border.inner_g = A.border.inner_g* invratio + B.border.inner_g*ratio;
623 A.border.inner_b = A.border.inner_b* invratio + B.border.inner_b*ratio;
624 A.border.inner_a = A.border.inner_a* invratio + B.border.inner_a*ratio;
625
626 A.mv.a = A.mv.a* invratio + B.mv.a*ratio;
627 A.mv.r = A.mv.r* invratio + B.mv.r*ratio;
628 A.mv.g = A.mv.g* invratio + B.mv.g*ratio;
629 A.mv.b = A.mv.b* invratio + B.mv.b*ratio;
630 A.mv.length = A.mv.length* invratio + B.mv.length*ratio;
631 A.mv.x_num = A.mv.x_num* invratio + B.mv.x_num*ratio;
632 A.mv.y_num = A.mv.y_num* invratio + B.mv.y_num*ratio;
633 A.mv.y_offset = A.mv.y_offset* invratio + B.mv.y_offset*ratio;
634 A.mv.x_offset = A.mv.x_offset* invratio + B.mv.x_offset*ratio;
635
636
637 A.fRating = A.fRating* invratio + B.fRating*ratio;
638 A.fGammaAdj = A.fGammaAdj* invratio + B.fGammaAdj*ratio;
639 A.videoEcho.zoom = A.videoEcho.zoom* invratio + B.videoEcho.zoom*ratio;
640 A.videoEcho.a = A.videoEcho.a* invratio + B.videoEcho.a*ratio;
641
642
643 A.fWarpAnimSpeed = A.fWarpAnimSpeed* invratio + B.fWarpAnimSpeed*ratio;
644 A.fWarpScale = A.fWarpScale* invratio + B.fWarpScale*ratio;
645 A.fShader = A.fShader* invratio + B.fShader*ratio;
646
647 //Switch bools and discrete values halfway. Maybe we should do some interesting stuff here.
648
649 if (ratio > 0.5)
650 {
651 A.videoEcho.orientation = B.videoEcho.orientation;
652 A.textureWrap = B.textureWrap;
653 A.bDarkenCenter = B.bDarkenCenter;
654 A.bRedBlueStereo = B.bRedBlueStereo;
655 A.bBrighten = B.bBrighten;
656 A.bDarken = B.bDarken;
657 A.bSolarize = B.bSolarize;
658 A.bInvert = B.bInvert;
659 A.bMotionVectorsOn = B.bMotionVectorsOn;
660 }
661
662 return;
663 }
664 #endif
665