Blender V4.3
colorband.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "MEM_guardedalloc.h"
10
11#include "BLI_heap.h"
12#include "BLI_math_color.h"
13#include "BLI_math_vector.h"
14#include "BLI_utildefines.h"
15
16#include "DNA_key_types.h"
17#include "DNA_texture_types.h"
18
19#include "BKE_colorband.hh"
20#include "BKE_key.hh"
21
22void BKE_colorband_init(ColorBand *coba, bool rangetype)
23{
24 int a;
25
26 coba->data[0].pos = 0.0;
27 coba->data[1].pos = 1.0;
28
29 if (rangetype == 0) {
30 coba->data[0].r = 0.0;
31 coba->data[0].g = 0.0;
32 coba->data[0].b = 0.0;
33 coba->data[0].a = 0.0;
34
35 coba->data[1].r = 1.0;
36 coba->data[1].g = 1.0;
37 coba->data[1].b = 1.0;
38 coba->data[1].a = 1.0;
39 }
40 else {
41 coba->data[0].r = 0.0;
42 coba->data[0].g = 0.0;
43 coba->data[0].b = 0.0;
44 coba->data[0].a = 1.0;
45
46 coba->data[1].r = 1.0;
47 coba->data[1].g = 1.0;
48 coba->data[1].b = 1.0;
49 coba->data[1].a = 1.0;
50 }
51
52 for (a = 2; a < MAXCOLORBAND; a++) {
53 coba->data[a].r = 0.5;
54 coba->data[a].g = 0.5;
55 coba->data[a].b = 0.5;
56 coba->data[a].a = 1.0;
57 coba->data[a].pos = 0.5;
58 }
59
60 coba->tot = 2;
61 coba->cur = 0;
64}
65
67 const float (*array)[4],
68 const int array_len)
69{
70 /* No Re-sample, just de-duplicate. */
71 const float eps = (1.0f / 255.0f) + 1e-6f;
72 BLI_assert(array_len < MAXCOLORBAND);
73 int stops = min_ii(MAXCOLORBAND, array_len);
74 if (stops) {
75 const float step_size = 1.0f / float(max_ii(stops - 1, 1));
76 int i_curr = -1;
77 for (int i_step = 0; i_step < stops; i_step++) {
78 if ((i_curr != -1) && compare_v4v4(&coba->data[i_curr].r, array[i_step], eps)) {
79 continue;
80 }
81 i_curr += 1;
82 copy_v4_v4(&coba->data[i_curr].r, array[i_step]);
83 coba->data[i_curr].pos = i_step * step_size;
84 coba->data[i_curr].cur = i_curr;
85 }
86 coba->tot = i_curr + 1;
87 coba->cur = 0;
88 }
89 else {
90 /* coba is empty, set 1 black stop */
91 zero_v3(&coba->data[0].r);
92 coba->data[0].a = 1.0f;
93 coba->cur = 0;
94 coba->tot = 1;
95 }
96}
97
98/* -------------------------------------------------------------------- */
113
118{
119 if (c->next == nullptr || c->prev == nullptr) {
120 return -1.0f;
121 }
122 float area = 0.0f;
123#if 0
124 float xy_prev[2], xy_curr[2], xy_next[2];
125 xy_prev[0] = c->prev->pos;
126 xy_curr[0] = c->pos;
127 xy_next[0] = c->next->pos;
128 for (int i = 0; i < 4; i++) {
129 xy_prev[1] = c->prev->rgba[i];
130 xy_curr[1] = c->rgba[i];
131 xy_next[1] = c->next->rgba[i];
132 area += fabsf(cross_tri_v2(xy_prev, xy_curr, xy_next));
133 }
134#else
135 /* Above logic, optimized (p: previous, c: current, n: next). */
136 const float xpc = c->prev->pos - c->pos;
137 const float xnc = c->next->pos - c->pos;
138 for (int i = 0; i < 4; i++) {
139 const float ycn = c->rgba[i] - c->next->rgba[i];
140 const float ypc = c->prev->rgba[i] - c->rgba[i];
141 area += fabsf((xpc * ycn) + (ypc * xnc));
142 }
143#endif
144 return area;
145}
146
147/* TODO(@ideasman42): create `BLI_math_filter` ? */
148static float filter_gauss(float x)
149{
150 const float gaussfac = 1.6f;
151 const float two_gaussfac2 = 2.0f * gaussfac * gaussfac;
152 x *= 3.0f * gaussfac;
153 return 1.0f / sqrtf(float(M_PI) * two_gaussfac2) * expf(-x * x / two_gaussfac2);
154}
155
157 const float (*array)[4],
158 const int array_len,
159 bool filter_samples)
160{
161 BLI_assert(array_len >= 2);
162 const float eps_2x = ((1.0f / 255.0f) + 1e-6f);
164 *carr = static_cast<ColorResampleElem *>(MEM_mallocN(sizeof(*carr) * array_len, __func__));
165 int carr_len = array_len;
166 c = carr;
167 {
168 const float step_size = 1.0f / float(array_len - 1);
169 for (int i = 0; i < array_len; i++, c++) {
170 copy_v4_v4(carr[i].rgba, array[i]);
171 c->next = c + 1;
172 c->prev = c - 1;
173 c->pos = i * step_size;
174 }
175 }
176 carr[0].prev = nullptr;
177 carr[array_len - 1].next = nullptr;
178
179 /* -2 to remove endpoints. */
180 Heap *heap = BLI_heap_new_ex(array_len - 2);
181 c = carr;
182 for (int i = 0; i < array_len; i++, c++) {
183 float cost = color_sample_remove_cost(c);
184 if (cost != -1.0f) {
185 c->node = BLI_heap_insert(heap, cost, c);
186 }
187 else {
188 c->node = nullptr;
189 }
190 }
191
192 while ((carr_len > 1 && !BLI_heap_is_empty(heap)) &&
193 ((carr_len >= MAXCOLORBAND) || (BLI_heap_top_value(heap) <= eps_2x)))
194 {
195 c = static_cast<ColorResampleElem *>(BLI_heap_pop_min(heap));
196 ColorResampleElem *c_next = c->next, *c_prev = c->prev;
197 c_prev->next = c_next;
198 c_next->prev = c_prev;
199 /* Clear data (not essential, avoid confusion). */
200 c->prev = c->next = nullptr;
201 c->node = nullptr;
202
203 /* Update adjacent */
204 for (int i = 0; i < 2; i++) {
205 ColorResampleElem *c_other = i ? c_next : c_prev;
206 if (c_other->node != nullptr) {
207 const float cost = color_sample_remove_cost(c_other);
208 if (cost != -1.0) {
209 BLI_heap_node_value_update(heap, c_other->node, cost);
210 }
211 else {
212 BLI_heap_remove(heap, c_other->node);
213 c_other->node = nullptr;
214 }
215 }
216 }
217 carr_len -= 1;
218 }
219 BLI_heap_free(heap, nullptr);
220
221 /* First member is never removed. */
222 int i = 0;
223 BLI_assert(carr_len < MAXCOLORBAND);
224 if (filter_samples == false) {
225 for (c = carr; c != nullptr; c = c->next, i++) {
226 copy_v4_v4(&coba->data[i].r, c->rgba);
227 coba->data[i].pos = c->pos;
228 coba->data[i].cur = i;
229 }
230 }
231 else {
232 for (c = carr; c != nullptr; c = c->next, i++) {
233 const int steps_prev = c->prev ? (c - c->prev) - 1 : 0;
234 const int steps_next = c->next ? (c->next - c) - 1 : 0;
235 if (steps_prev == 0 && steps_next == 0) {
236 copy_v4_v4(&coba->data[i].r, c->rgba);
237 }
238 else {
239 float rgba[4];
240 float rgba_accum = 1;
241 copy_v4_v4(rgba, c->rgba);
242
243 if (steps_prev) {
244 const float step_size = 1.0 / float(steps_prev + 1);
245 int j = steps_prev;
246 for (ColorResampleElem *c_other = c - 1; c_other != c->prev; c_other--, j--) {
247 const float step_pos = float(j) * step_size;
248 BLI_assert(step_pos > 0.0f && step_pos < 1.0f);
249 const float f = filter_gauss(step_pos);
250 madd_v4_v4fl(rgba, c_other->rgba, f);
251 rgba_accum += f;
252 }
253 }
254 if (steps_next) {
255 const float step_size = 1.0 / float(steps_next + 1);
256 int j = steps_next;
257 for (ColorResampleElem *c_other = c + 1; c_other != c->next; c_other++, j--) {
258 const float step_pos = float(j) * step_size;
259 BLI_assert(step_pos > 0.0f && step_pos < 1.0f);
260 const float f = filter_gauss(step_pos);
261 madd_v4_v4fl(rgba, c_other->rgba, f);
262 rgba_accum += f;
263 }
264 }
265
266 mul_v4_v4fl(&coba->data[i].r, rgba, 1.0f / rgba_accum);
267 }
268 coba->data[i].pos = c->pos;
269 coba->data[i].cur = i;
270 }
271 }
272 BLI_assert(i == carr_len);
273 coba->tot = i;
274 coba->cur = 0;
275
276 MEM_freeN(carr);
277}
278
280 const float (*array)[4],
281 const int array_len,
282 bool filter_samples)
283{
284 /* NOTE: we could use MAXCOLORBAND here, but results of re-sampling are nicer,
285 * avoid different behavior when limit is hit. */
286 if (array_len < 2) {
287 /* No Re-sample, just de-duplicate. */
289 }
290 else {
291 /* Re-sample */
292 colorband_init_from_table_rgba_resample(coba, array, array_len, filter_samples);
293 }
294}
295
299{
300 ColorBand *coba;
301
302 coba = static_cast<ColorBand *>(MEM_callocN(sizeof(ColorBand), "colorband"));
303 BKE_colorband_init(coba, rangetype);
304
305 return coba;
306}
307
308/* ------------------------------------------------------------------------- */
309
311 const int ipotype_hue, const float mfac, const float fac, float h1, float h2)
312{
313 float h_interp;
314 int mode = 0;
315
316#define HUE_INTERP(h_a, h_b) ((mfac * (h_a)) + (fac * (h_b)))
317#define HUE_MOD(h) (((h) < 1.0f) ? (h) : (h)-1.0f)
318
319 h1 = HUE_MOD(h1);
320 h2 = HUE_MOD(h2);
321
322 BLI_assert(h1 >= 0.0f && h1 < 1.0f);
323 BLI_assert(h2 >= 0.0f && h2 < 1.0f);
324
325 switch (ipotype_hue) {
326 case COLBAND_HUE_NEAR: {
327 if ((h1 < h2) && (h2 - h1) > +0.5f) {
328 mode = 1;
329 }
330 else if ((h1 > h2) && (h2 - h1) < -0.5f) {
331 mode = 2;
332 }
333 else {
334 mode = 0;
335 }
336 break;
337 }
338 case COLBAND_HUE_FAR: {
339 /* Do full loop in Hue space in case both stops are the same... */
340 if (h1 == h2) {
341 mode = 1;
342 }
343 else if ((h1 < h2) && (h2 - h1) < +0.5f) {
344 mode = 1;
345 }
346 else if ((h1 > h2) && (h2 - h1) > -0.5f) {
347 mode = 2;
348 }
349 else {
350 mode = 0;
351 }
352 break;
353 }
354 case COLBAND_HUE_CCW: {
355 if (h1 > h2) {
356 mode = 2;
357 }
358 else {
359 mode = 0;
360 }
361 break;
362 }
363 case COLBAND_HUE_CW: {
364 if (h1 < h2) {
365 mode = 1;
366 }
367 else {
368 mode = 0;
369 }
370 break;
371 }
372 }
373
374 switch (mode) {
375 case 0:
376 h_interp = HUE_INTERP(h1, h2);
377 break;
378 case 1:
379 h_interp = HUE_INTERP(h1 + 1.0f, h2);
380 h_interp = HUE_MOD(h_interp);
381 break;
382 case 2:
383 h_interp = HUE_INTERP(h1, h2 + 1.0f);
384 h_interp = HUE_MOD(h_interp);
385 break;
386 }
387
388 BLI_assert(h_interp >= 0.0f && h_interp < 1.0f);
389
390#undef HUE_INTERP
391#undef HUE_MOD
392
393 return h_interp;
394}
395
396bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
397{
398 const CBData *cbd1, *cbd2, *cbd0, *cbd3;
399 float fac;
400 int ipotype;
401 int a;
402
403 if (coba == nullptr || coba->tot == 0) {
404 return false;
405 }
406
407 cbd1 = coba->data;
408
409 /* NOTE: when ipotype >= COLBAND_INTERP_B_SPLINE,
410 * we cannot do early-out with a constant color before first color stop and after last one,
411 * because interpolation starts before and ends after those... */
412 ipotype = (coba->color_mode == COLBAND_BLEND_RGB) ? coba->ipotype : int(COLBAND_INTERP_LINEAR);
413
414 if (coba->tot == 1) {
415 out[0] = cbd1->r;
416 out[1] = cbd1->g;
417 out[2] = cbd1->b;
418 out[3] = cbd1->a;
419 }
420 else if ((in <= cbd1->pos) &&
422 {
423 /* We are before first color stop. */
424 out[0] = cbd1->r;
425 out[1] = cbd1->g;
426 out[2] = cbd1->b;
427 out[3] = cbd1->a;
428 }
429 else {
430 CBData left, right;
431
432 /* we're looking for first pos > in */
433 for (a = 0; a < coba->tot; a++, cbd1++) {
434 if (cbd1->pos > in) {
435 break;
436 }
437 }
438
439 if (a == coba->tot) {
440 cbd2 = cbd1 - 1;
441 right = *cbd2;
442 right.pos = 1.0f;
443 cbd1 = &right;
444 }
445 else if (a == 0) {
446 left = *cbd1;
447 left.pos = 0.0f;
448 cbd2 = &left;
449 }
450 else {
451 cbd2 = cbd1 - 1;
452 }
453
454 if ((a == coba->tot) &&
456 {
457 /* We are after last color stop. */
458 out[0] = cbd2->r;
459 out[1] = cbd2->g;
460 out[2] = cbd2->b;
461 out[3] = cbd2->a;
462 }
463 else if (ipotype == COLBAND_INTERP_CONSTANT) {
464 /* constant */
465 out[0] = cbd2->r;
466 out[1] = cbd2->g;
467 out[2] = cbd2->b;
468 out[3] = cbd2->a;
469 }
470 else {
471 if (cbd2->pos != cbd1->pos) {
472 fac = (in - cbd1->pos) / (cbd2->pos - cbd1->pos);
473 }
474 else {
475 /* was setting to 0.0 in 2.56 & previous, but this
476 * is incorrect for the last element, see #26732. */
477 fac = (a != coba->tot) ? 0.0f : 1.0f;
478 }
479
481 /* Interpolate from right to left: `3 2 1 0`. */
482 float t[4];
483
484 if (a >= coba->tot - 1) {
485 cbd0 = cbd1;
486 }
487 else {
488 cbd0 = cbd1 + 1;
489 }
490 if (a < 2) {
491 cbd3 = cbd2;
492 }
493 else {
494 cbd3 = cbd2 - 1;
495 }
496
497 CLAMP(fac, 0.0f, 1.0f);
498
499 if (ipotype == COLBAND_INTERP_CARDINAL) {
501 }
502 else {
504 }
505
506 out[0] = t[3] * cbd3->r + t[2] * cbd2->r + t[1] * cbd1->r + t[0] * cbd0->r;
507 out[1] = t[3] * cbd3->g + t[2] * cbd2->g + t[1] * cbd1->g + t[0] * cbd0->g;
508 out[2] = t[3] * cbd3->b + t[2] * cbd2->b + t[1] * cbd1->b + t[0] * cbd0->b;
509 out[3] = t[3] * cbd3->a + t[2] * cbd2->a + t[1] * cbd1->a + t[0] * cbd0->a;
510 clamp_v4(out, 0.0f, 1.0f);
511 }
512 else {
513 if (ipotype == COLBAND_INTERP_EASE) {
514 const float fac2 = fac * fac;
515 fac = 3.0f * fac2 - 2.0f * fac2 * fac;
516 }
517 const float mfac = 1.0f - fac;
518
519 if (UNLIKELY(coba->color_mode == COLBAND_BLEND_HSV)) {
520 float col1[3], col2[3];
521
522 rgb_to_hsv_v(&cbd1->r, col1);
523 rgb_to_hsv_v(&cbd2->r, col2);
524
525 out[0] = colorband_hue_interp(coba->ipotype_hue, mfac, fac, col1[0], col2[0]);
526 out[1] = mfac * col1[1] + fac * col2[1];
527 out[2] = mfac * col1[2] + fac * col2[2];
528 out[3] = mfac * cbd1->a + fac * cbd2->a;
529
530 hsv_to_rgb_v(out, out);
531 }
532 else if (UNLIKELY(coba->color_mode == COLBAND_BLEND_HSL)) {
533 float col1[3], col2[3];
534
535 rgb_to_hsl_v(&cbd1->r, col1);
536 rgb_to_hsl_v(&cbd2->r, col2);
537
538 out[0] = colorband_hue_interp(coba->ipotype_hue, mfac, fac, col1[0], col2[0]);
539 out[1] = mfac * col1[1] + fac * col2[1];
540 out[2] = mfac * col1[2] + fac * col2[2];
541 out[3] = mfac * cbd1->a + fac * cbd2->a;
542
543 hsl_to_rgb_v(out, out);
544 }
545 else {
546 /* COLBAND_BLEND_RGB */
547 out[0] = mfac * cbd1->r + fac * cbd2->r;
548 out[1] = mfac * cbd1->g + fac * cbd2->g;
549 out[2] = mfac * cbd1->b + fac * cbd2->b;
550 out[3] = mfac * cbd1->a + fac * cbd2->a;
551 }
552 }
553 }
554 }
555
556 return true; /* OK */
557}
558
559void BKE_colorband_evaluate_table_rgba(const ColorBand *coba, float **array, int *size)
560{
561 int a;
562
563 *size = CM_TABLE + 1;
564 *array = static_cast<float *>(MEM_callocN(sizeof(float) * (*size) * 4, "ColorBand"));
565
566 for (a = 0; a < *size; a++) {
567 BKE_colorband_evaluate(coba, float(a) / float(CM_TABLE), &(*array)[a * 4]);
568 }
569}
570
571static int vergcband(const void *a1, const void *a2)
572{
573 const CBData *x1 = static_cast<const CBData *>(a1), *x2 = static_cast<const CBData *>(a2);
574
575 if (x1->pos > x2->pos) {
576 return 1;
577 }
578 if (x1->pos < x2->pos) {
579 return -1;
580 }
581 return 0;
582}
583
585{
586 int a;
587
588 if (coba->tot < 2) {
589 return;
590 }
591
592 for (a = 0; a < coba->tot; a++) {
593 coba->data[a].cur = a;
594 }
595
596 qsort(coba->data, coba->tot, sizeof(CBData), vergcband);
597
598 for (a = 0; a < coba->tot; a++) {
599 if (coba->data[a].cur == coba->cur) {
600 coba->cur = a;
601 break;
602 }
603 }
604}
605
607{
608 if (coba->tot == MAXCOLORBAND) {
609 return nullptr;
610 }
611
612 CBData *xnew;
613
614 xnew = &coba->data[coba->tot];
615 xnew->pos = position;
616
617 if (coba->tot != 0) {
618 BKE_colorband_evaluate(coba, position, &xnew->r);
619 }
620 else {
621 zero_v4(&xnew->r);
622 }
623
624 coba->tot++;
625 coba->cur = coba->tot - 1;
626
628
629 return coba->data + coba->cur;
630}
631
633{
634 if (coba->tot < 2) {
635 return false;
636 }
637
638 if (index < 0 || index >= coba->tot) {
639 return false;
640 }
641
642 coba->tot--;
643 for (int a = index; a < coba->tot; a++) {
644 coba->data[a] = coba->data[a + 1];
645 }
646 if (coba->cur) {
647 coba->cur--;
648 }
649 return true;
650}
#define MAXCOLORBAND
void key_curve_position_weights(float t, float data[4], int type)
Definition key.cc:339
#define BLI_assert(a)
Definition BLI_assert.h:50
A min-heap / priority queue ADT.
void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1)
Definition BLI_heap.c:192
Heap * BLI_heap_new_ex(unsigned int reserve_num) ATTR_WARN_UNUSED_RESULT
Definition BLI_heap.c:172
void void bool BLI_heap_is_empty(const Heap *heap) ATTR_NONNULL(1)
Definition BLI_heap.c:269
float BLI_heap_top_value(const Heap *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition BLI_heap.c:284
void BLI_heap_node_value_update(Heap *heap, HeapNode *node, float value) ATTR_NONNULL(1
void * BLI_heap_pop_min(Heap *heap) ATTR_NONNULL(1)
Definition BLI_heap.c:291
HeapNode * BLI_heap_insert(Heap *heap, float value, void *ptr) ATTR_NONNULL(1)
Definition BLI_heap.c:235
void void BLI_heap_remove(Heap *heap, HeapNode *node) ATTR_NONNULL(1
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
#define M_PI
void hsv_to_rgb_v(const float hsv[3], float r_rgb[3])
Definition math_color.cc:57
void rgb_to_hsv_v(const float rgb[3], float r_hsv[3])
void hsl_to_rgb_v(const float hsl[3], float r_rgb[3])
Definition math_color.cc:62
void rgb_to_hsl_v(const float rgb[3], float r_hsl[3])
MINLINE float cross_tri_v2(const float v1[2], const float v2[2], const float v3[2])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void clamp_v4(float vec[4], float min, float max)
MINLINE bool compare_v4v4(const float v1[4], const float v2[4], float limit) ATTR_WARN_UNUSED_RESULT
MINLINE void mul_v4_v4fl(float r[4], const float a[4], float f)
MINLINE void zero_v4(float r[4])
MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f)
MINLINE void zero_v3(float r[3])
#define CLAMP(a, b, c)
#define UNLIKELY(x)
#define ELEM(...)
#define CM_TABLE
@ KEY_CARDINAL
@ KEY_BSPLINE
@ COLBAND_HUE_FAR
@ COLBAND_HUE_CW
@ COLBAND_HUE_NEAR
@ COLBAND_HUE_CCW
@ COLBAND_BLEND_RGB
@ COLBAND_BLEND_HSL
@ COLBAND_BLEND_HSV
@ COLBAND_INTERP_LINEAR
@ COLBAND_INTERP_CONSTANT
@ COLBAND_INTERP_B_SPLINE
@ COLBAND_INTERP_EASE
@ COLBAND_INTERP_CARDINAL
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
void BKE_colorband_evaluate_table_rgba(const ColorBand *coba, float **array, int *size)
Definition colorband.cc:559
CBData * BKE_colorband_element_add(ColorBand *coba, float position)
Definition colorband.cc:606
void BKE_colorband_init_from_table_rgba(ColorBand *coba, const float(*array)[4], const int array_len, bool filter_samples)
Definition colorband.cc:279
static float colorband_hue_interp(const int ipotype_hue, const float mfac, const float fac, float h1, float h2)
Definition colorband.cc:310
static void colorband_init_from_table_rgba_resample(ColorBand *coba, const float(*array)[4], const int array_len, bool filter_samples)
Definition colorband.cc:156
void BKE_colorband_update_sort(ColorBand *coba)
Definition colorband.cc:584
bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
Definition colorband.cc:396
#define HUE_INTERP(h_a, h_b)
static float color_sample_remove_cost(const ColorResampleElem *c)
Definition colorband.cc:117
static float filter_gauss(float x)
Definition colorband.cc:148
ColorBand * BKE_colorband_add(bool rangetype)
Definition colorband.cc:298
bool BKE_colorband_element_remove(ColorBand *coba, int index)
Definition colorband.cc:632
#define HUE_MOD(h)
void BKE_colorband_init(ColorBand *coba, bool rangetype)
Definition colorband.cc:22
static int vergcband(const void *a1, const void *a2)
Definition colorband.cc:571
static void colorband_init_from_table_rgba_simple(ColorBand *coba, const float(*array)[4], const int array_len)
Definition colorband.cc:66
#define expf(x)
#define fabsf(x)
#define sqrtf(x)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
static int left
const btScalar eps
Definition poly34.cpp:11
CBData data[32]
ColorResampleElem * next
Definition colorband.cc:108
HeapNode * node
Definition colorband.cc:109
ColorResampleElem * prev
Definition colorband.cc:108