Blender  V3.3
COM_VectorBlurOperation.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2011 Blender Foundation. */
3 
4 #include "BLI_jitter_2d.h"
5 
7 
8 namespace blender::compositor {
9 
10 /* Defined */
11 #define PASS_VECTOR_MAX 10000.0f
12 
13 /* Forward declarations */
14 struct DrawBufPixel;
15 struct ZSpan;
17  int xsize,
18  int ysize,
19  float *newrect,
20  const float *imgrect,
21  float *vecbufrect,
22  const float *zbufrect);
23 void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty, float clipcrop);
24 void zbuf_free_span(ZSpan *zspan);
25 void antialias_tagbuf(int xsize, int ysize, char *rectmove);
26 
27 /* VectorBlurOperation */
28 
30 {
32  this->add_input_socket(DataType::Value); /* ZBUF */
33  this->add_input_socket(DataType::Color); /* SPEED */
35  settings_ = nullptr;
36  cached_instance_ = nullptr;
37  input_image_program_ = nullptr;
38  input_speed_program_ = nullptr;
39  input_zprogram_ = nullptr;
40  flags_.complex = true;
42 }
44 {
45  init_mutex();
46  input_image_program_ = get_input_socket_reader(0);
47  input_zprogram_ = get_input_socket_reader(1);
48  input_speed_program_ = get_input_socket_reader(2);
49  cached_instance_ = nullptr;
51 }
52 
53 void VectorBlurOperation::execute_pixel(float output[4], int x, int y, void *data)
54 {
55  float *buffer = (float *)data;
56  int index = (y * this->get_width() + x) * COM_DATA_TYPE_COLOR_CHANNELS;
57  copy_v4_v4(output, &buffer[index]);
58 }
59 
61 {
62  deinit_mutex();
63  input_image_program_ = nullptr;
64  input_speed_program_ = nullptr;
65  input_zprogram_ = nullptr;
66  if (cached_instance_) {
67  MEM_freeN(cached_instance_);
68  cached_instance_ = nullptr;
69  }
70 }
72 {
73  if (cached_instance_) {
74  return cached_instance_;
75  }
76 
77  lock_mutex();
78  if (cached_instance_ == nullptr) {
79  MemoryBuffer *tile = (MemoryBuffer *)input_image_program_->initialize_tile_data(rect);
80  MemoryBuffer *speed = (MemoryBuffer *)input_speed_program_->initialize_tile_data(rect);
81  MemoryBuffer *z = (MemoryBuffer *)input_zprogram_->initialize_tile_data(rect);
82  float *data = (float *)MEM_dupallocN(tile->get_buffer());
83  this->generate_vector_blur(data, tile, speed, z);
84  cached_instance_ = data;
85  }
86  unlock_mutex();
87  return cached_instance_;
88 }
89 
91  ReadBufferOperation *read_operation,
92  rcti *output)
93 {
94  if (cached_instance_ == nullptr) {
95  rcti new_input;
96  new_input.xmax = this->get_width();
97  new_input.xmin = 0;
98  new_input.ymax = this->get_height();
99  new_input.ymin = 0;
100  return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
101  }
102 
103  return false;
104 }
105 
107  const rcti &UNUSED(output_area),
108  rcti &r_input_area)
109 {
110  r_input_area = this->get_canvas();
111 }
112 
114  const rcti &area,
116 {
117  /* TODO(manzanilla): once tiled implementation is removed, run multi-threaded where possible. */
118  if (!cached_instance_) {
120  const bool is_image_inflated = image->is_a_single_elem();
121  image = is_image_inflated ? image->inflate() : image;
122 
123  /* Must be a copy because it's modified in #generate_vector_blur. */
124  MemoryBuffer *speed = inputs[SPEED_INPUT_INDEX];
125  speed = speed->is_a_single_elem() ? speed->inflate() : new MemoryBuffer(*speed);
126 
127  MemoryBuffer *z = inputs[Z_INPUT_INDEX];
128  const bool is_z_inflated = z->is_a_single_elem();
129  z = is_z_inflated ? z->inflate() : z;
130 
131  cached_instance_ = (float *)MEM_dupallocN(image->get_buffer());
132  this->generate_vector_blur(cached_instance_, image, speed, z);
133 
134  if (is_image_inflated) {
135  delete image;
136  }
137  delete speed;
138  if (is_z_inflated) {
139  delete z;
140  }
141  }
142 
143  const int num_channels = COM_data_type_num_channels(get_output_socket()->get_data_type());
144  MemoryBuffer buf(cached_instance_, num_channels, this->get_width(), this->get_height());
145  output->copy_from(&buf, area);
146 }
147 
149  MemoryBuffer *input_image,
150  MemoryBuffer *input_speed,
151  MemoryBuffer *inputZ)
152 {
153  NodeBlurData blurdata;
154  blurdata.samples = settings_->samples / QualityStepHelper::get_step();
155  blurdata.maxspeed = settings_->maxspeed;
156  blurdata.minspeed = settings_->minspeed;
157  blurdata.curved = settings_->curved;
158  blurdata.fac = settings_->fac;
159  zbuf_accumulate_vecblur(&blurdata,
160  this->get_width(),
161  this->get_height(),
162  data,
163  input_image->get_buffer(),
164  input_speed->get_buffer(),
165  inputZ->get_buffer());
166 }
167 
168 /* -------------------------------------------------------------------- */
175 struct ZSpan {
176  /* range for clipping */
177  int rectx, recty;
178 
179  /* actual filled in range */
181  /* vertex pointers detect min/max range in */
182  const float *minp1, *maxp1, *minp2, *maxp2;
183  float *span1, *span2;
184 
185  /* transform from hoco to zbuf co */
186  float zmulx, zmuly, zofsx, zofsy;
187 
188  int *rectz;
190  float clipcrop;
191 };
192 
193 /* each zbuffer has coordinates transformed to local rect coordinates, so we can simply clip */
194 void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty, float clipcrop)
195 {
196  memset(zspan, 0, sizeof(ZSpan));
197 
198  zspan->rectx = rectx;
199  zspan->recty = recty;
200 
201  zspan->span1 = (float *)MEM_mallocN(recty * sizeof(float), "zspan");
202  zspan->span2 = (float *)MEM_mallocN(recty * sizeof(float), "zspan");
203 
204  zspan->clipcrop = clipcrop;
205 }
206 
207 void zbuf_free_span(ZSpan *zspan)
208 {
209  if (zspan) {
210  if (zspan->span1) {
211  MEM_freeN(zspan->span1);
212  }
213  if (zspan->span2) {
214  MEM_freeN(zspan->span2);
215  }
216  zspan->span1 = zspan->span2 = nullptr;
217  }
218 }
219 
220 /* reset range for clipping */
221 static void zbuf_init_span(ZSpan *zspan)
222 {
223  zspan->miny1 = zspan->miny2 = zspan->recty + 1;
224  zspan->maxy1 = zspan->maxy2 = -1;
225  zspan->minp1 = zspan->maxp1 = zspan->minp2 = zspan->maxp2 = nullptr;
226 }
227 
228 static void zbuf_add_to_span(ZSpan *zspan, const float v1[2], const float v2[2])
229 {
230  const float *minv, *maxv;
231  float *span;
232  float xx1, dx0, xs0;
233  int y, my0, my2;
234 
235  if (v1[1] < v2[1]) {
236  minv = v1;
237  maxv = v2;
238  }
239  else {
240  minv = v2;
241  maxv = v1;
242  }
243 
244  my0 = ceil(minv[1]);
245  my2 = floor(maxv[1]);
246 
247  if (my2 < 0 || my0 >= zspan->recty) {
248  return;
249  }
250 
251  /* clip top */
252  if (my2 >= zspan->recty) {
253  my2 = zspan->recty - 1;
254  }
255  /* clip bottom */
256  if (my0 < 0) {
257  my0 = 0;
258  }
259 
260  if (my0 > my2) {
261  return;
262  }
263  /* if (my0>my2) should still fill in, that way we get spans that skip nicely */
264 
265  xx1 = maxv[1] - minv[1];
266  if (xx1 > FLT_EPSILON) {
267  dx0 = (minv[0] - maxv[0]) / xx1;
268  xs0 = dx0 * (minv[1] - my2) + minv[0];
269  }
270  else {
271  dx0 = 0.0f;
272  xs0 = min_ff(minv[0], maxv[0]);
273  }
274 
275  /* empty span */
276  if (zspan->maxp1 == nullptr) {
277  span = zspan->span1;
278  }
279  else { /* does it complete left span? */
280  if (maxv == zspan->minp1 || minv == zspan->maxp1) {
281  span = zspan->span1;
282  }
283  else {
284  span = zspan->span2;
285  }
286  }
287 
288  if (span == zspan->span1) {
289  // printf("left span my0 %d my2 %d\n", my0, my2);
290  if (zspan->minp1 == nullptr || zspan->minp1[1] > minv[1]) {
291  zspan->minp1 = minv;
292  }
293  if (zspan->maxp1 == nullptr || zspan->maxp1[1] < maxv[1]) {
294  zspan->maxp1 = maxv;
295  }
296  if (my0 < zspan->miny1) {
297  zspan->miny1 = my0;
298  }
299  if (my2 > zspan->maxy1) {
300  zspan->maxy1 = my2;
301  }
302  }
303  else {
304  // printf("right span my0 %d my2 %d\n", my0, my2);
305  if (zspan->minp2 == nullptr || zspan->minp2[1] > minv[1]) {
306  zspan->minp2 = minv;
307  }
308  if (zspan->maxp2 == nullptr || zspan->maxp2[1] < maxv[1]) {
309  zspan->maxp2 = maxv;
310  }
311  if (my0 < zspan->miny2) {
312  zspan->miny2 = my0;
313  }
314  if (my2 > zspan->maxy2) {
315  zspan->maxy2 = my2;
316  }
317  }
318 
319  for (y = my2; y >= my0; y--, xs0 += dx0) {
320  /* xs0 is the X-coordinate! */
321  span[y] = xs0;
322  }
323 }
324 
327 /* ******************** VECBLUR ACCUM BUF ************************* */
328 
329 struct DrawBufPixel {
330  const float *colpoin;
331  float alpha;
332 };
333 
337 static void zbuf_fill_in_rgba(
338  ZSpan *zspan, DrawBufPixel *col, float *v1, float *v2, float *v3, float *v4)
339 {
340  DrawBufPixel *rectpofs, *rp;
341  double zxd, zyd, zy0, zverg;
342  float x0, y0, z0;
343  float x1, y1, z1, x2, y2, z2, xx1;
344  const float *span1, *span2;
345  float *rectzofs, *rz;
346  int x, y;
347  int sn1, sn2, rectx, my0, my2;
348 
349  /* init */
350  zbuf_init_span(zspan);
351 
352  /* set spans */
353  zbuf_add_to_span(zspan, v1, v2);
354  zbuf_add_to_span(zspan, v2, v3);
355  zbuf_add_to_span(zspan, v3, v4);
356  zbuf_add_to_span(zspan, v4, v1);
357 
358  /* clipped */
359  if (zspan->minp2 == nullptr || zspan->maxp2 == nullptr) {
360  return;
361  }
362 
363  my0 = max_ii(zspan->miny1, zspan->miny2);
364  my2 = min_ii(zspan->maxy1, zspan->maxy2);
365 
366  // printf("my %d %d\n", my0, my2);
367  if (my2 < my0) {
368  return;
369  }
370 
371  /* ZBUF DX DY, in floats still */
372  x1 = v1[0] - v2[0];
373  x2 = v2[0] - v3[0];
374  y1 = v1[1] - v2[1];
375  y2 = v2[1] - v3[1];
376  z1 = v1[2] - v2[2];
377  z2 = v2[2] - v3[2];
378  x0 = y1 * z2 - z1 * y2;
379  y0 = z1 * x2 - x1 * z2;
380  z0 = x1 * y2 - y1 * x2;
381 
382  if (z0 == 0.0f) {
383  return;
384  }
385 
386  xx1 = (x0 * v1[0] + y0 * v1[1]) / z0 + v1[2];
387 
388  zxd = -(double)x0 / (double)z0;
389  zyd = -(double)y0 / (double)z0;
390  zy0 = ((double)my2) * zyd + (double)xx1;
391 
392  /* start-offset in rect */
393  rectx = zspan->rectx;
394  rectzofs = (float *)(zspan->rectz + rectx * my2);
395  rectpofs = ((DrawBufPixel *)zspan->rectdraw) + rectx * my2;
396 
397  /* correct span */
398  sn1 = (my0 + my2) / 2;
399  if (zspan->span1[sn1] < zspan->span2[sn1]) {
400  span1 = zspan->span1 + my2;
401  span2 = zspan->span2 + my2;
402  }
403  else {
404  span1 = zspan->span2 + my2;
405  span2 = zspan->span1 + my2;
406  }
407 
408  for (y = my2; y >= my0; y--, span1--, span2--) {
409 
410  sn1 = floor(*span1);
411  sn2 = floor(*span2);
412  sn1++;
413 
414  if (sn2 >= rectx) {
415  sn2 = rectx - 1;
416  }
417  if (sn1 < 0) {
418  sn1 = 0;
419  }
420 
421  if (sn2 >= sn1) {
422  zverg = (double)sn1 * zxd + zy0;
423  rz = rectzofs + sn1;
424  rp = rectpofs + sn1;
425  x = sn2 - sn1;
426 
427  while (x >= 0) {
428  if (zverg < (double)*rz) {
429  *rz = zverg;
430  *rp = *col;
431  }
432  zverg += zxd;
433  rz++;
434  rp++;
435  x--;
436  }
437  }
438 
439  zy0 -= zyd;
440  rectzofs -= rectx;
441  rectpofs -= rectx;
442  }
443 }
444 
445 /* char value==255 is filled in, rest should be zero */
446 /* returns alpha values,
447  * but sets alpha to 1 for zero alpha pixels that have an alpha value as neighbor. */
448 void antialias_tagbuf(int xsize, int ysize, char *rectmove)
449 {
450  char *row1, *row2, *row3;
451  char prev, next;
452  int a, x, y, step;
453 
454  /* 1: tag pixels to be candidate for AA */
455  for (y = 2; y < ysize; y++) {
456  /* setup rows */
457  row1 = rectmove + (y - 2) * xsize;
458  row2 = row1 + xsize;
459  row3 = row2 + xsize;
460  for (x = 2; x < xsize; x++, row1++, row2++, row3++) {
461  if (row2[1]) {
462  if (row2[0] == 0 || row2[2] == 0 || row1[1] == 0 || row3[1] == 0) {
463  row2[1] = 128;
464  }
465  }
466  }
467  }
468 
469  /* 2: evaluate horizontal scan-lines and calculate alphas. */
470  row1 = rectmove;
471  for (y = 0; y < ysize; y++) {
472  row1++;
473  for (x = 1; x < xsize; x++, row1++) {
474  if (row1[0] == 128 && row1[1] == 128) {
475  /* find previous color and next color and amount of steps to blend */
476  prev = row1[-1];
477  step = 1;
478  while (x + step < xsize && row1[step] == 128) {
479  step++;
480  }
481 
482  if (x + step != xsize) {
483  /* now we can blend values */
484  next = row1[step];
485 
486  /* NOTE: prev value can be next value, but we do this loop to clear 128 then. */
487  for (a = 0; a < step; a++) {
488  int fac, mfac;
489 
490  fac = ((a + 1) << 8) / (step + 1);
491  mfac = 255 - fac;
492 
493  row1[a] = (prev * mfac + next * fac) >> 8;
494  }
495  }
496  }
497  }
498  }
499 
500  /* 3: evaluate vertical scan-lines and calculate alphas */
501  /* use for reading a copy of the original tagged buffer */
502  for (x = 0; x < xsize; x++) {
503  row1 = rectmove + x + xsize;
504 
505  for (y = 1; y < ysize; y++, row1 += xsize) {
506  if (row1[0] == 128 && row1[xsize] == 128) {
507  /* find previous color and next color and amount of steps to blend */
508  prev = row1[-xsize];
509  step = 1;
510  while (y + step < ysize && row1[step * xsize] == 128) {
511  step++;
512  }
513 
514  if (y + step != ysize) {
515  /* now we can blend values */
516  next = row1[step * xsize];
517  /* NOTE: prev value can be next value, but we do this loop to clear 128 then. */
518  for (a = 0; a < step; a++) {
519  int fac, mfac;
520 
521  fac = ((a + 1) << 8) / (step + 1);
522  mfac = 255 - fac;
523 
524  row1[a * xsize] = (prev * mfac + next * fac) >> 8;
525  }
526  }
527  }
528  }
529  }
530 
531  /* last: pixels with 0 we fill in zbuffer, with 1 we skip for mask */
532  for (y = 2; y < ysize; y++) {
533  /* setup rows */
534  row1 = rectmove + (y - 2) * xsize;
535  row2 = row1 + xsize;
536  row3 = row2 + xsize;
537  for (x = 2; x < xsize; x++, row1++, row2++, row3++) {
538  if (row2[1] == 0) {
539  if (row2[0] > 1 || row2[2] > 1 || row1[1] > 1 || row3[1] > 1) {
540  row2[1] = 1;
541  }
542  }
543  }
544  }
545 }
546 
547 /* in: two vectors, first vector points from origin back in time, 2nd vector points to future */
548 /* we make this into 3 points, center point is (0, 0) */
549 /* and offset the center point just enough to make curve go through midpoint */
550 
551 static void quad_bezier_2d(float *result, const float *v1, const float *v2, const float *ipodata)
552 {
553  float p1[2], p2[2], p3[2];
554 
555  p3[0] = -v2[0];
556  p3[1] = -v2[1];
557 
558  p1[0] = v1[0];
559  p1[1] = v1[1];
560 
561  /* official formula 2*p2 - 0.5*p1 - 0.5*p3 */
562  p2[0] = -0.5f * p1[0] - 0.5f * p3[0];
563  p2[1] = -0.5f * p1[1] - 0.5f * p3[1];
564 
565  result[0] = ipodata[0] * p1[0] + ipodata[1] * p2[0] + ipodata[2] * p3[0];
566  result[1] = ipodata[0] * p1[1] + ipodata[1] * p2[1] + ipodata[2] * p3[1];
567 }
568 
569 static void set_quad_bezier_ipo(float fac, float *data)
570 {
571  float mfac = (1.0f - fac);
572 
573  data[0] = mfac * mfac;
574  data[1] = 2.0f * mfac * fac;
575  data[2] = fac * fac;
576 }
577 
579  int xsize,
580  int ysize,
581  float *newrect,
582  const float *imgrect,
583  float *vecbufrect,
584  const float *zbufrect)
585 {
586  ZSpan zspan;
587  DrawBufPixel *rectdraw, *dr;
588  static float jit[256][2];
589  float v1[3], v2[3], v3[3], v4[3], fx, fy;
590  const float *dimg, *dz, *ro;
591  float *rectvz, *dvz, *dvec1, *dvec2, *dz1, *dz2, *rectz;
592  float *minvecbufrect = nullptr, *rectweight, *rw, *rectmax, *rm;
593  float maxspeedsq = (float)nbd->maxspeed * nbd->maxspeed;
594  int y, x, step, maxspeed = nbd->maxspeed, samples = nbd->samples;
595  int tsktsk = 0;
596  static int firsttime = 1;
597  char *rectmove, *dm;
598 
599  zbuf_alloc_span(&zspan, xsize, ysize, 1.0f);
600  zspan.zmulx = ((float)xsize) / 2.0f;
601  zspan.zmuly = ((float)ysize) / 2.0f;
602  zspan.zofsx = 0.0f;
603  zspan.zofsy = 0.0f;
604 
605  /* the buffers */
606  rectz = (float *)MEM_callocN(sizeof(float) * xsize * ysize, "zbuf accum");
607  zspan.rectz = (int *)rectz;
608 
609  rectmove = (char *)MEM_callocN(xsize * ysize, "rectmove");
610  rectdraw = (DrawBufPixel *)MEM_callocN(sizeof(DrawBufPixel) * xsize * ysize, "rect draw");
611  zspan.rectdraw = rectdraw;
612 
613  rectweight = (float *)MEM_callocN(sizeof(float) * xsize * ysize, "rect weight");
614  rectmax = (float *)MEM_callocN(sizeof(float) * xsize * ysize, "rect max");
615 
616  /* debug... check if PASS_VECTOR_MAX still is in buffers */
617  dvec1 = vecbufrect;
618  for (x = 4 * xsize * ysize; x > 0; x--, dvec1++) {
619  if (dvec1[0] == PASS_VECTOR_MAX) {
620  dvec1[0] = 0.0f;
621  tsktsk = 1;
622  }
623  }
624  if (tsktsk) {
625  printf("Found uninitialized speed in vector buffer... fixed.\n");
626  }
627 
628  /* Min speed? then copy speed-buffer to recalculate speed vectors. */
629  if (nbd->minspeed) {
630  float minspeed = (float)nbd->minspeed;
631  float minspeedsq = minspeed * minspeed;
632 
633  minvecbufrect = (float *)MEM_callocN(sizeof(float[4]) * xsize * ysize, "minspeed buf");
634 
635  dvec1 = vecbufrect;
636  dvec2 = minvecbufrect;
637  for (x = 2 * xsize * ysize; x > 0; x--, dvec1 += 2, dvec2 += 2) {
638  if (dvec1[0] == 0.0f && dvec1[1] == 0.0f) {
639  dvec2[0] = dvec1[0];
640  dvec2[1] = dvec1[1];
641  }
642  else {
643  float speedsq = dvec1[0] * dvec1[0] + dvec1[1] * dvec1[1];
644  if (speedsq <= minspeedsq) {
645  dvec2[0] = 0.0f;
646  dvec2[1] = 0.0f;
647  }
648  else {
649  speedsq = 1.0f - minspeed / sqrtf(speedsq);
650  dvec2[0] = speedsq * dvec1[0];
651  dvec2[1] = speedsq * dvec1[1];
652  }
653  }
654  }
655  SWAP(float *, minvecbufrect, vecbufrect);
656  }
657 
658  /* Make vertex buffer with averaged speed and Z-values. */
659  rectvz = (float *)MEM_callocN(sizeof(float[4]) * (xsize + 1) * (ysize + 1), "vertices");
660  dvz = rectvz;
661  for (y = 0; y <= ysize; y++) {
662 
663  if (y == 0) {
664  dvec1 = vecbufrect + 4 * y * xsize;
665  }
666  else {
667  dvec1 = vecbufrect + 4 * (y - 1) * xsize;
668  }
669 
670  if (y == ysize) {
671  dvec2 = vecbufrect + 4 * (y - 1) * xsize;
672  }
673  else {
674  dvec2 = vecbufrect + 4 * y * xsize;
675  }
676 
677  for (x = 0; x <= xsize; x++) {
678 
679  /* two vectors, so a step loop */
680  for (step = 0; step < 2; step++, dvec1 += 2, dvec2 += 2, dvz += 2) {
681  /* average on minimal speed */
682  int div = 0;
683 
684  if (x != 0) {
685  if (dvec1[-4] != 0.0f || dvec1[-3] != 0.0f) {
686  dvz[0] = dvec1[-4];
687  dvz[1] = dvec1[-3];
688  div++;
689  }
690  if (dvec2[-4] != 0.0f || dvec2[-3] != 0.0f) {
691  if (div == 0) {
692  dvz[0] = dvec2[-4];
693  dvz[1] = dvec2[-3];
694  div++;
695  }
696  else if ((fabsf(dvec2[-4]) + fabsf(dvec2[-3])) < (fabsf(dvz[0]) + fabsf(dvz[1]))) {
697  dvz[0] = dvec2[-4];
698  dvz[1] = dvec2[-3];
699  }
700  }
701  }
702 
703  if (x != xsize) {
704  if (dvec1[0] != 0.0f || dvec1[1] != 0.0f) {
705  if (div == 0) {
706  dvz[0] = dvec1[0];
707  dvz[1] = dvec1[1];
708  div++;
709  }
710  else if ((fabsf(dvec1[0]) + fabsf(dvec1[1])) < (fabsf(dvz[0]) + fabsf(dvz[1]))) {
711  dvz[0] = dvec1[0];
712  dvz[1] = dvec1[1];
713  }
714  }
715  if (dvec2[0] != 0.0f || dvec2[1] != 0.0f) {
716  if (div == 0) {
717  dvz[0] = dvec2[0];
718  dvz[1] = dvec2[1];
719  }
720  else if ((fabsf(dvec2[0]) + fabsf(dvec2[1])) < (fabsf(dvz[0]) + fabsf(dvz[1]))) {
721  dvz[0] = dvec2[0];
722  dvz[1] = dvec2[1];
723  }
724  }
725  }
726  if (maxspeed) {
727  float speedsq = dvz[0] * dvz[0] + dvz[1] * dvz[1];
728  if (speedsq > maxspeedsq) {
729  speedsq = (float)maxspeed / sqrtf(speedsq);
730  dvz[0] *= speedsq;
731  dvz[1] *= speedsq;
732  }
733  }
734  }
735  }
736  }
737 
738  /* set border speeds to keep border speeds on border */
739  dz1 = rectvz;
740  dz2 = rectvz + 4 * (ysize) * (xsize + 1);
741  for (x = 0; x <= xsize; x++, dz1 += 4, dz2 += 4) {
742  dz1[1] = 0.0f;
743  dz2[1] = 0.0f;
744  dz1[3] = 0.0f;
745  dz2[3] = 0.0f;
746  }
747  dz1 = rectvz;
748  dz2 = rectvz + 4 * (xsize);
749  for (y = 0; y <= ysize; y++, dz1 += 4 * (xsize + 1), dz2 += 4 * (xsize + 1)) {
750  dz1[0] = 0.0f;
751  dz2[0] = 0.0f;
752  dz1[2] = 0.0f;
753  dz2[2] = 0.0f;
754  }
755 
756  /* tag moving pixels, only these faces we draw */
757  dm = rectmove;
758  dvec1 = vecbufrect;
759  for (x = xsize * ysize; x > 0; x--, dm++, dvec1 += 4) {
760  if ((dvec1[0] != 0.0f || dvec1[1] != 0.0f || dvec1[2] != 0.0f || dvec1[3] != 0.0f)) {
761  *dm = 255;
762  }
763  }
764 
765  antialias_tagbuf(xsize, ysize, rectmove);
766 
767  /* Has to become static, the jitter initialization calls a random-seed,
768  * screwing up texture noise node. */
769  if (firsttime) {
770  firsttime = 0;
771  BLI_jitter_init(jit, 256);
772  }
773 
774  memset(newrect, 0, sizeof(float) * xsize * ysize * 4);
775 
776  /* accumulate */
777  samples /= 2;
778  for (step = 1; step <= samples; step++) {
779  float speedfac = 0.5f * nbd->fac * (float)step / (float)(samples + 1);
780  int side;
781 
782  for (side = 0; side < 2; side++) {
783  float blendfac, ipodata[4];
784 
785  /* clear zbuf, if we draw future we fill in not moving pixels */
786  if (false) {
787  for (x = xsize * ysize - 1; x >= 0; x--) {
788  rectz[x] = 10e16;
789  }
790  }
791  else {
792  for (x = xsize * ysize - 1; x >= 0; x--) {
793  if (rectmove[x] == 0) {
794  rectz[x] = zbufrect[x];
795  }
796  else {
797  rectz[x] = 10e16;
798  }
799  }
800  }
801 
802  /* clear drawing buffer */
803  for (x = xsize * ysize - 1; x >= 0; x--) {
804  rectdraw[x].colpoin = nullptr;
805  }
806 
807  dimg = imgrect;
808  dm = rectmove;
809  dz = zbufrect;
810  dz1 = rectvz;
811  dz2 = rectvz + 4 * (xsize + 1);
812 
813  if (side) {
814  if (nbd->curved == 0) {
815  dz1 += 2;
816  dz2 += 2;
817  }
818  speedfac = -speedfac;
819  }
820 
821  set_quad_bezier_ipo(0.5f + 0.5f * speedfac, ipodata);
822 
823  for (fy = -0.5f + jit[step & 255][0], y = 0; y < ysize; y++, fy += 1.0f) {
824  for (fx = -0.5f + jit[step & 255][1], x = 0; x < xsize;
825  x++, fx += 1.0f, dimg += 4, dz1 += 4, dz2 += 4, dm++, dz++) {
826  if (*dm > 1) {
827  float jfx = fx + 0.5f;
828  float jfy = fy + 0.5f;
830 
831  /* make vertices */
832  if (nbd->curved) { /* curved */
833  quad_bezier_2d(v1, dz1, dz1 + 2, ipodata);
834  v1[0] += jfx;
835  v1[1] += jfy;
836  v1[2] = *dz;
837 
838  quad_bezier_2d(v2, dz1 + 4, dz1 + 4 + 2, ipodata);
839  v2[0] += jfx + 1.0f;
840  v2[1] += jfy;
841  v2[2] = *dz;
842 
843  quad_bezier_2d(v3, dz2 + 4, dz2 + 4 + 2, ipodata);
844  v3[0] += jfx + 1.0f;
845  v3[1] += jfy + 1.0f;
846  v3[2] = *dz;
847 
848  quad_bezier_2d(v4, dz2, dz2 + 2, ipodata);
849  v4[0] += jfx;
850  v4[1] += jfy + 1.0f;
851  v4[2] = *dz;
852  }
853  else {
854  ARRAY_SET_ITEMS(v1, speedfac * dz1[0] + jfx, speedfac * dz1[1] + jfy, *dz);
855  ARRAY_SET_ITEMS(v2, speedfac * dz1[4] + jfx + 1.0f, speedfac * dz1[5] + jfy, *dz);
857  v3, speedfac * dz2[4] + jfx + 1.0f, speedfac * dz2[5] + jfy + 1.0f, *dz);
858  ARRAY_SET_ITEMS(v4, speedfac * dz2[0] + jfx, speedfac * dz2[1] + jfy + 1.0f, *dz);
859  }
860  if (*dm == 255) {
861  col.alpha = 1.0f;
862  }
863  else if (*dm < 2) {
864  col.alpha = 0.0f;
865  }
866  else {
867  col.alpha = ((float)*dm) / 255.0f;
868  }
869  col.colpoin = dimg;
870 
871  zbuf_fill_in_rgba(&zspan, &col, v1, v2, v3, v4);
872  }
873  }
874  dz1 += 4;
875  dz2 += 4;
876  }
877 
878  /* blend with a falloff. this fixes the ugly effect you get with
879  * a fast moving object. then it looks like a solid object overlaid
880  * over a very transparent moving version of itself. in reality, the
881  * whole object should become transparent if it is moving fast, be
882  * we don't know what is behind it so we don't do that. this hack
883  * overestimates the contribution of foreground pixels but looks a
884  * bit better without a sudden cutoff. */
885  blendfac = ((samples - step) / (float)samples);
886  /* Smooth-step to make it look a bit nicer as well. */
887  blendfac = 3.0f * pow(blendfac, 2.0f) - 2.0f * pow(blendfac, 3.0f);
888 
889  /* accum */
890  rw = rectweight;
891  rm = rectmax;
892  for (dr = rectdraw, dz2 = newrect, x = xsize * ysize - 1; x >= 0;
893  x--, dr++, dz2 += 4, rw++, rm++) {
894  if (dr->colpoin) {
895  float bfac = dr->alpha * blendfac;
896 
897  dz2[0] += bfac * dr->colpoin[0];
898  dz2[1] += bfac * dr->colpoin[1];
899  dz2[2] += bfac * dr->colpoin[2];
900  dz2[3] += bfac * dr->colpoin[3];
901 
902  *rw += bfac;
903  *rm = MAX2(*rm, bfac);
904  }
905  }
906  }
907  }
908 
909  /* blend between original images and accumulated image */
910  rw = rectweight;
911  rm = rectmax;
912  ro = imgrect;
913  dm = rectmove;
914  for (dz2 = newrect, x = xsize * ysize - 1; x >= 0; x--, dz2 += 4, ro += 4, rw++, rm++, dm++) {
915  float mfac = *rm;
916  float fac = (*rw == 0.0f) ? 0.0f : mfac / (*rw);
917  float nfac = 1.0f - mfac;
918 
919  dz2[0] = fac * dz2[0] + nfac * ro[0];
920  dz2[1] = fac * dz2[1] + nfac * ro[1];
921  dz2[2] = fac * dz2[2] + nfac * ro[2];
922  dz2[3] = fac * dz2[3] + nfac * ro[3];
923  }
924 
925  MEM_freeN(rectz);
926  MEM_freeN(rectmove);
927  MEM_freeN(rectdraw);
928  MEM_freeN(rectvz);
929  MEM_freeN(rectweight);
930  MEM_freeN(rectmax);
931  if (minvecbufrect) {
932  MEM_freeN(vecbufrect); /* rects were swapped! */
933  }
934  zbuf_free_span(&zspan);
935 }
936 
937 } // namespace blender::compositor
typedef float(TangentPoint)[2]
void BLI_jitter_init(float(*jitarr)[2], int num)
Definition: jitter_2d.c:126
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
MINLINE void copy_v4_v4(float r[4], const float a[4])
#define ARRAY_SET_ITEMS(...)
#define SWAP(type, a, b)
#define UNUSED(x)
#define MAX2(a, b)
typedef double(DMatrix)[4][4]
#define PASS_VECTOR_MAX
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble y1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble x2
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
ATTR_WARN_UNUSED_RESULT const BMVert * v2
a MemoryBuffer contains access to the data of a chunk
void copy_from(const MemoryBuffer *src, const rcti &area)
float * get_buffer()
get the data of this MemoryBuffer
void add_output_socket(DataType datatype)
SocketReader * get_input_socket_reader(unsigned int index)
NodeOperationOutput * get_output_socket(unsigned int index=0)
virtual bool determine_depending_area_of_interest(rcti *input, ReadBufferOperation *read_operation, rcti *output)
void add_input_socket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
virtual void * initialize_tile_data(rcti *)
void execute_pixel(float output[4], int x, int y, void *data) override
void update_memory_buffer(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override
Get input operation area being read by this operation on rendering given output area.
bool determine_depending_area_of_interest(rcti *input, ReadBufferOperation *read_operation, rcti *output) override
void generate_vector_blur(float *data, MemoryBuffer *input_image, MemoryBuffer *input_speed, MemoryBuffer *inputZ)
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img image(1, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D_ARRAY, "out_weight_img") .image(3
uint col
#define jit
ccl_global float * buffer
ccl_global KernelShaderEvalInput ccl_global float * output
ccl_global const KernelWorkTile * tile
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
ccl_device_inline float3 ceil(const float3 &a)
Definition: math_float3.h:363
ccl_device_inline float3 pow(float3 v, float e)
Definition: math_float3.h:533
static ulong * next
#define fabsf(x)
Definition: metal/compat.h:219
#define sqrtf(x)
Definition: metal/compat.h:243
static unsigned a[3]
Definition: RandGen.cpp:78
static void area(int d1, int d2, int e1, int e2, float weights[2])
static void zbuf_add_to_span(ZSpan *zspan, const float v1[2], const float v2[2])
void zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *newrect, const float *imgrect, float *vecbufrect, const float *zbufrect)
constexpr int COM_DATA_TYPE_COLOR_CHANNELS
Definition: COM_defines.h:62
static void zbuf_fill_in_rgba(ZSpan *zspan, DrawBufPixel *col, float *v1, float *v2, float *v3, float *v4)
static void quad_bezier_2d(float *result, const float *v1, const float *v2, const float *ipodata)
static void zbuf_init_span(ZSpan *zspan)
constexpr int COM_data_type_num_channels(const DataType datatype)
Definition: COM_defines.h:42
void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty, float clipcrop)
void antialias_tagbuf(int xsize, int ysize, char *rectmove)
static void set_quad_bezier_ipo(float fac, float *data)
void zbuf_free_span(ZSpan *zspan)
T floor(const T &a)
SymEdge< T > * prev(const SymEdge< T > *se)
Definition: delaunay_2d.cc:105
static bNodeSocketTemplate inputs[]
Definition: zbuf.h:14
int recty
Definition: zbuf.h:15
int rectx
Definition: zbuf.h:15
int ymin
Definition: DNA_vec_types.h:64
int ymax
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
int xmax
Definition: DNA_vec_types.h:63