Blender V5.0
math_base.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
7/* Math
8 *
9 * Basic math functions on scalar and vector types. This header is used by
10 * both the kernel code when compiled as C++, and other C++ non-kernel code. */
11
12#include "util/defines.h"
13#include "util/types_base.h"
14
15#ifdef __HIP__
16# include <hip/hip_vector_types.h>
17#endif
18
19#if !defined(__KERNEL_METAL__)
20# include <cfloat> // IWYU pragma: export
21# include <cmath> // IWYU pragma: export
22#endif
23
25
26/* Float Pi variations */
27
28/* Division */
29#ifndef M_PI_F
30# define M_PI_F (3.1415926535897932f) /* `pi` */
31#endif
32#ifndef M_PI_2_F
33# define M_PI_2_F (1.5707963267948966f) /* `pi/2` */
34#endif
35#ifndef M_PI_4_F
36# define M_PI_4_F (0.7853981633974830f) /* `pi/4` */
37#endif
38#ifndef M_1_PI_F
39# define M_1_PI_F (0.3183098861837067f) /* `1/pi` */
40#endif
41#ifndef M_2_PI_F
42# define M_2_PI_F (0.6366197723675813f) /* `2/pi` */
43#endif
44#ifndef M_1_2PI_F
45# define M_1_2PI_F (0.1591549430918953f) /* `1/(2*pi)` */
46#endif
47#ifndef M_1_4PI_F
48# define M_1_4PI_F (0.0795774715459476f) /* `1/(4*pi)` */
49#endif
50#ifndef M_SQRT_PI_8_F
51# define M_SQRT_PI_8_F (0.6266570686577501f) /* `sqrt(pi/8)` */
52#endif
53#ifndef M_LN_2PI_F
54# define M_LN_2PI_F (1.8378770664093454f) /* `ln(2*pi)` */
55#endif
56
57/* Multiplication */
58#ifndef M_2PI_F
59# define M_2PI_F (6.2831853071795864f) /* `2*pi` */
60#endif
61#ifndef M_4PI_F
62# define M_4PI_F (12.566370614359172f) /* `4*pi` */
63#endif
64#ifndef M_PI_4F
65# define M_PI_4F 0.78539816339744830962f /* `pi/4` */
66#endif
67
68/* Float sqrt variations */
69#ifndef M_SQRT2_F
70# define M_SQRT2_F (1.4142135623730950f) /* `sqrt(2)` */
71#endif
72#ifndef M_CBRT2_F
73# define M_CBRT2_F 1.2599210498948732f /* `cbrt(2)` */
74#endif
75#ifndef M_SQRT1_2F
76# define M_SQRT1_2F 0.70710678118654752440f /* `sqrt(1/2)` */
77#endif
78#ifndef M_SQRT3_F
79# define M_SQRT3_F (1.7320508075688772f) /* `sqrt(3)` */
80#endif
81#ifndef M_LN2_F
82# define M_LN2_F (0.6931471805599453f) /* `ln(2)` */
83#endif
84#ifndef M_LN10_F
85# define M_LN10_F (2.3025850929940457f) /* `ln(10)` */
86#endif
87
88/* Scalar */
89
90#if !defined(__HIP__) && !defined(__KERNEL_ONEAPI__)
91# ifdef _WIN32
92ccl_device_inline float fmaxf(const float a, const float b)
93{
94 return (a > b) ? a : b;
95}
96
97ccl_device_inline float fminf(const float a, const float b)
98{
99 return (a < b) ? a : b;
100}
101
102# endif /* _WIN32 */
103#endif /* __HIP__, __KERNEL_ONEAPI__ */
104
105#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
106# ifndef __KERNEL_ONEAPI__
107using std::isfinite;
108using std::isnan;
109using std::sqrt;
110# else
111# define isfinite(x) sycl::isfinite((x))
112# define isnan(x) sycl::isnan((x))
113# endif
114
115ccl_device_inline int abs(const int x)
116{
117 return (x > 0) ? x : -x;
118}
119
120ccl_device_inline int max(const int a, const int b)
121{
122 return (a > b) ? a : b;
123}
124
125ccl_device_inline int min(const int a, const int b)
126{
127 return (a < b) ? a : b;
128}
129
130ccl_device_inline uint32_t max(const uint32_t a, const uint32_t b)
131{
132 return (a > b) ? a : b;
133}
134
135ccl_device_inline uint32_t min(const uint32_t a, const uint32_t b)
136{
137 return (a < b) ? a : b;
138}
139
141{
142 return (a > b) ? a : b;
143}
144
146{
147 return (a < b) ? a : b;
148}
149
150/* NOTE: On 64bit Darwin the `size_t` is defined as `unsigned long int` and `uint64_t` is defined
151 * as `unsigned long long`. Both of the definitions are 64 bit unsigned integer, but the automatic
152 * substitution does not allow to automatically pick function defined for `uint64_t` as it is not
153 * exactly the same type definition.
154 * Work this around by adding a templated function enabled for `size_t` type which will be used
155 * when there is no explicit specialization of `min()`/`max()` above. */
156
157template<class T>
158ccl_device_inline typename std::enable_if_t<std::is_same_v<T, size_t>, T> max(T a, T b)
159{
160 return (a > b) ? a : b;
161}
162
163template<class T>
164ccl_device_inline typename std::enable_if_t<std::is_same_v<T, size_t>, T> min(T a, T b)
165{
166 return (a < b) ? a : b;
167}
168
169ccl_device_inline float max(const float a, const float b)
170{
171 return (a > b) ? a : b;
172}
173
174ccl_device_inline float min(const float a, const float b)
175{
176 return (a < b) ? a : b;
177}
178
179ccl_device_inline double max(const double a, const double b)
180{
181 return (a > b) ? a : b;
182}
183
184ccl_device_inline double min(const double a, const double b)
185{
186 return (a < b) ? a : b;
187}
188
189/* These 2 guys are templated for usage with registers data.
190 *
191 * NOTE: Since this is CPU-only functions it is ok to use references here.
192 * But for other devices we'll need to be careful about this.
193 */
194
195template<typename T> ccl_device_inline T min4(const T &a, const T &b, const T &c, const T &d)
196{
197 return min(min(a, b), min(c, d));
198}
199
200template<typename T> ccl_device_inline T max4(const T &a, const T &b, const T &c, const T &d)
201{
202 return max(max(a, b), max(c, d));
203}
204#endif /* __KERNEL_GPU__ */
205
206ccl_device_inline float min4(const float a, const float b, float c, const float d)
207{
208 return min(min(a, b), min(c, d));
209}
210
211ccl_device_inline float max4(const float a, const float b, float c, const float d)
212{
213 return max(max(a, b), max(c, d));
214}
215
216template<typename T> ccl_device_inline T make_zero();
217
219{
220 return 0.0f;
221}
222
223#if !defined(__KERNEL_METAL__) && !defined(__KERNEL_ONEAPI__)
224/* Int/Float conversion */
225
227{
228 union {
229 uint ui;
230 int i;
231 } u;
232 u.ui = i;
233 return u.i;
234}
235
237{
238 union {
239 uint ui;
240 int i;
241 } u;
242 u.i = i;
243 return u.ui;
244}
245
247{
248 union {
249 uint i;
250 float f;
251 } u;
252 u.f = f;
253 return u.i;
254}
255
256# ifndef __HIP__
258{
259 union {
260 int i;
261 float f;
262 } u;
263 u.f = f;
264 return u.i;
265}
266
268{
269 union {
270 int i;
271 float f;
272 } u;
273 u.i = i;
274 return u.f;
275}
276
278{
279 union {
280 uint i;
281 float f;
282 } u;
283 u.f = f;
284 return u.i;
285}
286
288{
289 union {
290 uint i;
291 float f;
292 } u;
293 u.i = i;
294 return u.f;
295}
296# endif
297
298#endif /* !defined(__KERNEL_METAL__) */
299
300#if defined(__KERNEL_METAL__)
301ccl_device_forceinline bool isnan_safe(const float f)
302{
303 return isnan(f);
304}
305
306ccl_device_forceinline bool isfinite_safe(const float f)
307{
308 return isfinite(f);
309}
310#else
312{
313 return ((uint64_t)ptr) & 0xFFFFFFFF;
314}
315
317{
318 return (((uint64_t)ptr) >> 32) & 0xFFFFFFFF;
319}
320
321template<typename T> ccl_device_inline T *pointer_unpack_from_uint(const uint a, const uint b)
322{
323 return (T *)(((uint64_t)b << 32) | a);
324}
325
327{
328 return (a << 16) | b;
329}
330
332{
333 return i >> 16;
334}
335
337{
338 return i & 0xFFFF;
339}
340
341/* Versions of functions which are safe for fast math. */
342ccl_device_inline bool isnan_safe(const float f)
343{
344 const unsigned int x = __float_as_uint(f);
345 return (x << 1) > 0xff000000u;
346}
347
349{
350 /* By IEEE 754 rule, 2*Inf equals Inf */
351 const unsigned int x = __float_as_uint(f);
352 return (f == f) && (x == 0 || x == (1u << 31) || (f != 2.0f * f)) && !((x << 1) > 0xff000000u);
353}
354#endif
355
357{
358 return isfinite_safe(v) ? v : 0.0f;
359}
360
361#if !defined(__KERNEL_METAL__)
362ccl_device_inline int clamp(const int a, const int mn, const int mx)
363{
364 return min(max(a, mn), mx);
365}
366
367ccl_device_inline float clamp(const float a, const float mn, const float mx)
368{
369 return min(max(a, mn), mx);
370}
371
372ccl_device_inline float mix(const float a, const float b, float t)
373{
374 return a + t * (b - a);
375}
376
377ccl_device_inline float smoothstep(const float edge0, const float edge1, const float x)
378{
379 float result;
380 if (x < edge0) {
381 result = 0.0f;
382 }
383 else if (x >= edge1) {
384 result = 1.0f;
385 }
386 else {
387 const float t = (x - edge0) / (edge1 - edge0);
388 result = (3.0f - 2.0f * t) * (t * t);
389 }
390 return result;
391}
392
393#endif /* !defined(__KERNEL_METAL__) */
394
395#if defined(__KERNEL_CUDA__)
396ccl_device_inline float saturatef(const float a)
397{
398 return __saturatef(a);
399}
400#elif !defined(__KERNEL_METAL__)
401ccl_device_inline float saturatef(const float a)
402{
403 return clamp(a, 0.0f, 1.0f);
404}
405#endif /* __KERNEL_CUDA__ */
406
408{
409 return (int)f;
410}
411
413{
414 return float_to_int(floorf(f));
415}
416
417ccl_device_inline float floorfrac(const float x, ccl_private int *i)
418{
419 const float f = floorf(x);
420 *i = float_to_int(f);
421 return x - f;
422}
423
425{
426 return float_to_int(ceilf(f));
427}
428
429ccl_device_inline float fractf(const float x)
430{
431 return x - floorf(x);
432}
433
434/* Adapted from `godot-engine` math_funcs.h. */
435ccl_device_inline float wrapf(const float value, const float max, const float min)
436{
437 const float range = max - min;
438 return (range != 0.0f) ? value - (range * floorf((value - min) / range)) : min;
439}
440
441ccl_device_inline float pingpongf(const float a, const float b)
442{
443 return (b != 0.0f) ? fabsf(fractf((a - b) / (b * 2.0f)) * b * 2.0f - b) : 0.0f;
444}
445
446ccl_device_inline float smoothminf(const float a, const float b, float k)
447{
448 if (k != 0.0f) {
449 const float h = fmaxf(k - fabsf(a - b), 0.0f) / k;
450 return fminf(a, b) - h * h * h * k * (1.0f / 6.0f);
451 }
452 return fminf(a, b);
453}
454
455ccl_device_inline float signf(const float f)
456{
457 return (f < 0.0f) ? -1.0f : 1.0f;
458}
459
460ccl_device_inline float nonzerof(const float f, const float eps)
461{
462 if (fabsf(f) < eps) {
463 return signf(f) * eps;
464 }
465 return f;
466}
467
468/* The behavior of `atan2(0, 0)` is undefined on many platforms, to ensure consistent behavior, we
469 * return 0 in this case. See !126951.
470 * Computes the angle between the positive x axis and the vector pointing from origin to (x, y). */
471ccl_device_inline float compatible_atan2(const float y, const float x)
472{
473 return (x == 0.0f && y == 0.0f) ? 0.0f : atan2f(y, x);
474}
475
476/* `signum` function testing for zero. Matches GLSL and OSL functions. */
478{
479 if (f == 0.0f) {
480 return 0.0f;
481 }
482 return signf(f);
483}
484
485ccl_device_inline float smoothstepf(const float f)
486{
487 if (f <= 0.0f) {
488 return 0.0f;
489 }
490 if (f >= 1.0f) {
491 return 1.0f;
492 }
493 const float ff = f * f;
494 return (3.0f * ff - 2.0f * ff * f);
495}
496
497ccl_device_inline int mod(const int x, const int m)
498{
499 return (x % m + m) % m;
500}
501
502ccl_device_inline float interp(const float a, const float b, const float t)
503{
504 return a + t * (b - a);
505}
506
507ccl_device_inline float inverse_lerp(const float a, const float b, const float x)
508{
509 return (x - a) / (b - a);
510}
511
512/* Cubic interpolation between b and c, a and d are the previous and next point. */
513ccl_device_inline float cubic_interp(const float a, const float b, float c, const float d, float x)
514{
515 return 0.5f *
516 (((d + 3.0f * (b - c) - a) * x + (2.0f * a - 5.0f * b + 4.0f * c - d)) * x +
517 (c - a)) *
518 x +
519 b;
520}
521
522/* NaN-safe math ops */
523
524ccl_device_inline float safe_sqrtf(const float f)
525{
526 return sqrtf(max(f, 0.0f));
527}
528
529ccl_device_inline float inversesqrtf(const float f)
530{
531#if defined(__KERNEL_METAL__)
532 return (f > 0.0f) ? rsqrt(f) : 0.0f;
533#else
534 return (f > 0.0f) ? 1.0f / sqrtf(f) : 0.0f;
535#endif
536}
537
538ccl_device float safe_asinf(const float a)
539{
540 return asinf(clamp(a, -1.0f, 1.0f));
541}
542
543ccl_device float safe_acosf(const float a)
544{
545 return acosf(clamp(a, -1.0f, 1.0f));
546}
547
548ccl_device float compatible_powf(const float x, const float y)
549{
550 if (y == 0.0f) {
551 /* x^0 -> 1, including 0^0. */
552 return 1.0f;
553 }
554 if (x == 0.0f) {
555 return 0.0f;
556 }
557#ifdef __KERNEL_GPU__
558 /* GPU pow doesn't accept negative x, do manual checks here */
559 if (x < 0.0f) {
560 if (fmodf(-y, 2.0f) == 0.0f) {
561 return powf(-x, y);
562 }
563 else {
564 return -powf(-x, y);
565 }
566 }
567#endif
568 return powf(x, y);
569}
570
571ccl_device float safe_powf(const float a, const float b)
572{
573 if (UNLIKELY(a < 0.0f && b != float_to_int(b))) {
574 return 0.0f;
575 }
576
577 return compatible_powf(a, b);
578}
579
580ccl_device float safe_divide(const float a, const float b)
581{
582 return (b != 0.0f) ? a / b : 0.0f;
583}
584
585ccl_device float safe_logf(const float a, const float b)
586{
587 if (UNLIKELY(a <= 0.0f || b <= 0.0f)) {
588 return 0.0f;
589 }
590
591 return safe_divide(logf(a), logf(b));
592}
593
594ccl_device float safe_modulo(const float a, const float b)
595{
596 return (b != 0.0f) ? fmodf(a, b) : 0.0f;
597}
598
599ccl_device float safe_floored_modulo(const float a, const float b)
600{
601 return (b != 0.0f) ? a - floorf(a / b) * b : 0.0f;
602}
603
604ccl_device_inline float sqr(const float a)
605{
606 return a * a;
607}
608
609ccl_device_inline float sin_from_cos(const float c)
610{
611 return safe_sqrtf(1.0f - sqr(c));
612}
613
614ccl_device_inline float cos_from_sin(const float s)
615{
616 return safe_sqrtf(1.0f - sqr(s));
617}
618
620{
621 /* Using second-order Taylor expansion at small angles for better accuracy. */
622 return s_sq > 0.0004f ? 1.0f - safe_sqrtf(1.0f - s_sq) : 0.5f * s_sq;
623}
624
626{
627 /* Using second-order Taylor expansion at small angles for better accuracy. */
628 return angle > 0.02f ? 1.0f - cosf(angle) : 0.5f * sqr(angle);
629}
630
631/* 2^a. */
633{
634 return 1 << a;
635}
636
637ccl_device_inline float pow20(const float a)
638{
639 return sqr(sqr(sqr(sqr(a)) * a));
640}
641
642ccl_device_inline float pow22(const float a)
643{
644 return sqr(a * sqr(sqr(sqr(a)) * a));
645}
646
647#ifdef __KERNEL_METAL__
648ccl_device_inline float lgammaf(const float x)
649{
650 /* Nemes, Gergő (2010), "New asymptotic expansion for the Gamma function", Archiv der Mathematik
651 */
652 const float _1_180 = 1.0f / 180.0f;
653 const float log2pi = 1.83787706641f;
654 const float logx = log(x);
655 return (log2pi - logx +
656 x * (logx * 2.0f + log(x * sinh(1.0f / x) + (_1_180 / pow(x, 6.0f))) - 2.0f)) *
657 0.5f;
658}
659#endif
660
661ccl_device_inline float beta(const float x, const float y)
662{
663 return expf(lgammaf(x) + lgammaf(y) - lgammaf(x + y));
664}
665
666ccl_device_inline float xor_mask(const float x, const uint y)
667{
669}
670
671ccl_device_inline float or_mask(const float x, const uint y)
672{
674}
675
676ccl_device float bits_to_01(const uint bits)
677{
678 return bits * (1.0f / (float)0xFFFFFFFF);
679}
680
681#if !defined(__KERNEL_GPU__)
682# if defined(__GNUC__)
684{
685 return __builtin_popcount(x);
686}
687# else
689{
690 /* TODO(Stefan): pop-count intrinsic for Windows with fallback for older CPUs. */
691 uint i = x;
692 i = i - ((i >> 1) & 0x55555555);
693 i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
694 i = (((i + (i >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
695 return i;
696}
697# endif
698#elif defined(__KERNEL_ONEAPI__)
699# define popcount(x) sycl::popcount(x)
700#elif defined(__KERNEL_HIP__)
701/* Use popcll to support 64-bit wave for pre-RDNA AMD GPUs */
702# define popcount(x) __popcll(x)
703#elif !defined(__KERNEL_METAL__)
704# define popcount(x) __popc(x)
705#endif
706
708{
709#if defined(__KERNEL_CUDA__) || defined(__KERNEL_OPTIX__) || defined(__KERNEL_HIP__)
710 return __clz(x);
711#elif defined(__KERNEL_METAL__)
712 return clz(x);
713#elif defined(__KERNEL_ONEAPI__)
714 return sycl::clz(x);
715#else
716 assert(x != 0);
717# ifdef _MSC_VER
718 unsigned long leading_zero = 0;
719 _BitScanReverse(&leading_zero, x);
720 return (31 - leading_zero);
721# else
722 return __builtin_clz(x);
723# endif
724#endif
725}
726
728{
729#if defined(__KERNEL_CUDA__) || defined(__KERNEL_OPTIX__) || defined(__KERNEL_HIP__)
730 return (__ffs(x) - 1);
731#elif defined(__KERNEL_METAL__)
732 return ctz(x);
733#elif defined(__KERNEL_ONEAPI__)
734 return sycl::ctz(x);
735#else
736 assert(x != 0);
737# ifdef _MSC_VER
738 unsigned long ctz = 0;
739 _BitScanForward(&ctz, x);
740 return ctz;
741# else
742 return __builtin_ctz(x);
743# endif
744#endif
745}
746
748{
749#if defined(__KERNEL_CUDA__) || defined(__KERNEL_OPTIX__) || defined(__KERNEL_HIP__)
750 return __ffs(x);
751#elif defined(__KERNEL_METAL__)
752 return (x != 0) ? ctz(x) + 1 : 0;
753#else
754# ifdef _MSC_VER
755 return (x != 0) ? (32 - count_leading_zeros(x & (~x + 1))) : 0;
756# else
757 return __builtin_ffs(x);
758# endif
759#endif
760}
761
762/* Compares two floats.
763 * Returns true if their absolute difference is smaller than abs_diff (for numbers near zero)
764 * or their relative difference is less than ulp_diff ULPs.
765 * Based on
766 * https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
767 */
768
770 const float b,
771 float abs_diff,
772 const int ulp_diff)
773{
774 if (fabsf(a - b) < abs_diff) {
775 return true;
776 }
777
778 if ((a < 0.0f) != (b < 0.0f)) {
779 return false;
780 }
781
782 return (abs(__float_as_int(a) - __float_as_int(b)) < ulp_diff);
783}
784
785/* Return value which is greater than the given one and is a power of two. */
787{
788 return x == 0 ? 1 : 1 << (32 - count_leading_zeros(x));
789}
790
791/* Return value which is lower than the given one and is a power of two. */
793{
794 return x < 2 ? x : 1 << (31 - count_leading_zeros(x - 1));
795}
796
797#ifndef __has_builtin
798# define __has_builtin(v) 0
799#endif
800
801/* Reverses the bits of a 32 bit integer. */
803{
804 /* Use a native instruction if it exists. */
805#if defined(__KERNEL_CUDA__)
806 return __brev(x);
807#elif defined(__KERNEL_METAL__)
808 return reverse_bits(x);
809#elif defined(__aarch64__) || (defined(_M_ARM64) && !defined(_MSC_VER))
810 /* Assume the rbit is always available on 64bit ARM architecture. */
811 __asm__("rbit %w0, %w1" : "=r"(x) : "r"(x));
812 return x;
813#elif defined(__arm__) && ((__ARM_ARCH > 7) || __ARM_ARCH == 6 && __ARM_ARCH_ISA_THUMB >= 2)
814 /* This ARM instruction is available in ARMv6T2 and above.
815 * This 32-bit Thumb instruction is available in ARMv6T2 and above. */
816 __asm__("rbit %0, %1" : "=r"(x) : "r"(x));
817 return x;
818#elif __has_builtin(__builtin_bitreverse32)
819 return __builtin_bitreverse32(x);
820#else
821 /* Flip pairwise. */
822 x = ((x & 0x55555555) << 1) | ((x & 0xAAAAAAAA) >> 1);
823 /* Flip pairs. */
824 x = ((x & 0x33333333) << 2) | ((x & 0xCCCCCCCC) >> 2);
825 /* Flip nibbles. */
826 x = ((x & 0x0F0F0F0F) << 4) | ((x & 0xF0F0F0F0) >> 4);
827 /* Flip bytes. CPUs have an instruction for that, pretty fast one. */
828# ifdef _MSC_VER
829 return _byteswap_ulong(x);
830# elif defined(__INTEL_COMPILER)
831 return (uint32_t)_bswap((int)x);
832# else
833 /* Assuming gcc or clang. */
834 return __builtin_bswap32(x);
835# endif
836#endif
837}
838
839/* Solve quadratic equation a*x^2 + b*x + c = 0, adapted from Mitsuba 3
840 * The solution is ordered so that x1 <= x2.
841 * Returns true if at least one solution is found. */
843 const float a, const float b, const float c, ccl_private float &x1, ccl_private float &x2)
844{
845 /* If the equation is linear, the solution is -c/b, but b has to be non-zero. */
846 const bool valid_linear = (a == 0.0f) && (b != 0.0f);
847 x1 = x2 = -c / b;
848
849 const float discriminant = sqr(b) - 4.0f * a * c;
850 /* Allow slightly negative discriminant in case of numerical precision issues. */
851 const bool valid_quadratic = (a != 0.0f) && (discriminant > -1e-5f);
852
853 if (valid_quadratic) {
854 /* Numerically stable version of (-b ± sqrt(discriminant)) / (2 * a), avoiding catastrophic
855 * cancellation when `b` is very close to `sqrt(discriminant)`, by finding the solution of
856 * greater magnitude which does not suffer from loss of precision, then using the identity
857 * x1 * x2 = c / a. */
858 const float temp = -0.5f * (b + copysignf(safe_sqrtf(discriminant), b));
859 const float r1 = temp / a;
860 const float r2 = c / temp;
861
862 x1 = fminf(r1, r2);
863 x2 = fmaxf(r1, r2);
864 }
865
866 return (valid_linear || valid_quadratic);
867}
868
869/* Defines a closed interval [min, max]. */
870template<typename T> struct Interval {
873
875 {
876 /* NaN-safe comparison. */
877 return !(min < max);
878 }
879
881 {
882 return value >= min && value <= max;
883 }
884
886 {
887 return max - min;
888 }
889};
890
891template<typename T1, typename T2>
893{
894 interval.min /= f;
895 interval.max /= f;
896 return interval;
897}
898
899/* Computes the intersection of two intervals. */
900template<typename T>
902 const ccl_private Interval<T> &second)
903{
904 return {max(first.min, second.min), min(first.max, second.max)};
905}
906
907/* Defines the minimal and maximal values of a quantity. */
908template<typename T> struct Extrema {
911 Extrema() = default;
912 ccl_device_inline_method Extrema(T value) : min(value), max(value) {}
913 ccl_device_inline_method Extrema(T min_, T max_) : min(min_), max(max_) {}
914
916 {
917 return max - min;
918 }
919};
920
921template<typename T> ccl_device_inline Extrema<T> operator*(const Extrema<T> a, const T b)
922{
923 return {a.min * b, a.max * b};
924}
925
926template<typename T>
928 const ccl_private Extrema<T> &b)
929{
930 return {a.min + b.min, a.max + b.max};
931}
932
933template<typename T>
938
939/* Returns the extrema of both extrema. */
940template<typename T>
942 const ccl_private Extrema<T> &b)
943{
944 return {min(a.min, b.min), max(a.max, b.max)};
945}
946
947template<typename T>
949{
950 return {min(a.min, v), max(a.max, v)};
951}
952
unsigned int uint
#define UNLIKELY(x)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
ATTR_WARN_UNUSED_RESULT const BMVert * v
unsigned long long int uint64_t
nullptr float
#define ccl_device_forceinline
#define ccl_private
#define ccl_device_inline
#define ccl_device_template_spec
#define ccl_device_inline_method
#define logf(x)
#define expf(x)
#define powf(x, y)
#define CCL_NAMESPACE_END
#define saturatef(x)
#define asinf(x)
#define fmodf(x, y)
#define acosf(x)
#define copysignf(x, y)
#define __int_as_float(x)
#define __float_as_int(x)
#define __float_as_uint(x)
#define __uint_as_float(x)
#define lgammaf(x)
#define assert(assertion)
#define isnan
#define log
#define pow
#define abs
VecBase< float, D > constexpr mod(VecOp< float, D >, VecOp< float, D >) RET
#define sinh
ccl_device_inline float floorfrac(const float x, ccl_private int *i)
Definition math_base.h:417
ccl_device_inline bool isnan_safe(const float f)
Definition math_base.h:342
ccl_device_inline float smoothstepf(const float f)
Definition math_base.h:485
ccl_device float safe_floored_modulo(const float a, const float b)
Definition math_base.h:599
ccl_device_inline int clamp(const int a, const int mn, const int mx)
Definition math_base.h:362
ccl_device_inline uint as_uint(const int i)
Definition math_base.h:236
ccl_device_inline Extrema< T > merge(const ccl_private Extrema< T > &a, const ccl_private Extrema< T > &b)
Definition math_base.h:941
ccl_device_inline Interval< T1 > operator/=(ccl_private Interval< T1 > &interval, const T2 f)
Definition math_base.h:892
ccl_device_inline uint prev_power_of_two(const uint x)
Definition math_base.h:792
ccl_device_inline int ceil_to_int(const float f)
Definition math_base.h:424
ccl_device float safe_asinf(const float a)
Definition math_base.h:538
ccl_device_inline uint uint16_unpack_from_uint_1(const uint i)
Definition math_base.h:336
ccl_device_inline float or_mask(const float x, const uint y)
Definition math_base.h:671
ccl_device_inline float signf(const float f)
Definition math_base.h:455
ccl_device float safe_powf(const float a, const float b)
Definition math_base.h:571
ccl_device_inline T min4(const T &a, const T &b, const T &c, const T &d)
Definition math_base.h:195
ccl_device_inline float pow22(const float a)
Definition math_base.h:642
ccl_device_inline uint count_leading_zeros(const uint x)
Definition math_base.h:707
ccl_device float bits_to_01(const uint bits)
Definition math_base.h:676
ccl_device float safe_modulo(const float a, const float b)
Definition math_base.h:594
ccl_device_inline float inversesqrtf(const float f)
Definition math_base.h:529
ccl_device_inline float compatible_atan2(const float y, const float x)
Definition math_base.h:471
ccl_device float compatible_powf(const float x, const float y)
Definition math_base.h:548
ccl_device_inline Extrema< T > operator*(const Extrema< T > a, const T b)
Definition math_base.h:921
ccl_device_inline float safe_sqrtf(const float f)
Definition math_base.h:524
ccl_device_inline uint pointer_pack_to_uint_1(T *ptr)
Definition math_base.h:316
ccl_device_inline float cubic_interp(const float a, const float b, float c, const float d, float x)
Definition math_base.h:513
ccl_device_inline int floor_to_int(const float f)
Definition math_base.h:412
ccl_device_inline float sin_from_cos(const float c)
Definition math_base.h:609
ccl_device_inline uint32_t reverse_integer_bits(uint32_t x)
Definition math_base.h:802
ccl_device_inline int power_of_2(const int a)
Definition math_base.h:632
ccl_device_inline Extrema< T > operator+=(ccl_private Extrema< T > &a, const ccl_private Extrema< T > &b)
Definition math_base.h:934
ccl_device_inline float sin_sqr_to_one_minus_cos(const float s_sq)
Definition math_base.h:619
ccl_device float safe_acosf(const float a)
Definition math_base.h:543
ccl_device_inline float compatible_signf(const float f)
Definition math_base.h:477
ccl_device_inline float xor_mask(const float x, const uint y)
Definition math_base.h:666
ccl_device_inline uint uint16_pack_to_uint(const uint a, const uint b)
Definition math_base.h:326
ccl_device_inline int as_int(const uint i)
Definition math_base.h:226
ccl_device_inline float nonzerof(const float f, const float eps)
Definition math_base.h:460
ccl_device_inline bool solve_quadratic(const float a, const float b, const float c, ccl_private float &x1, ccl_private float &x2)
Definition math_base.h:842
ccl_device_inline float smoothminf(const float a, const float b, float k)
Definition math_base.h:446
ccl_device_inline uint pointer_pack_to_uint_0(T *ptr)
Definition math_base.h:311
ccl_device_inline T * pointer_unpack_from_uint(const uint a, const uint b)
Definition math_base.h:321
ccl_device_inline uint next_power_of_two(const uint x)
Definition math_base.h:786
ccl_device_inline float inverse_lerp(const float a, const float b, const float x)
Definition math_base.h:507
ccl_device_inline T max4(const T &a, const T &b, const T &c, const T &d)
Definition math_base.h:200
ccl_device_inline float pow20(const float a)
Definition math_base.h:637
ccl_device_inline int float_to_int(const float f)
Definition math_base.h:407
ccl_device_inline uint find_first_set(const uint x)
Definition math_base.h:747
ccl_device_inline Extrema< T > operator+(const ccl_private Extrema< T > &a, const ccl_private Extrema< T > &b)
Definition math_base.h:927
ccl_device_inline T make_zero()
Definition math_dual.h:17
ccl_device float safe_divide(const float a, const float b)
Definition math_base.h:580
ccl_device_inline Interval< T > intervals_intersection(const ccl_private Interval< T > &first, const ccl_private Interval< T > &second)
Definition math_base.h:901
ccl_device_inline float ensure_finite(const float v)
Definition math_base.h:356
ccl_device_inline float interp(const float a, const float b, const float t)
Definition math_base.h:502
ccl_device_inline uint uint16_unpack_from_uint_0(const uint i)
Definition math_base.h:331
ccl_device_inline float smoothstep(const float edge0, const float edge1, const float x)
Definition math_base.h:377
ccl_device_inline uint popcount(const uint x)
Definition math_base.h:688
ccl_device_inline float wrapf(const float value, const float max, const float min)
Definition math_base.h:435
ccl_device_inline bool compare_floats(const float a, const float b, float abs_diff, const int ulp_diff)
Definition math_base.h:769
ccl_device float safe_logf(const float a, const float b)
Definition math_base.h:585
ccl_device_inline bool isfinite_safe(const float f)
Definition math_base.h:348
ccl_device_inline float one_minus_cos(const float angle)
Definition math_base.h:625
ccl_device_inline float beta(const float x, const float y)
Definition math_base.h:661
ccl_device_inline float cos_from_sin(const float s)
Definition math_base.h:614
ccl_device_inline float pingpongf(const float a, const float b)
Definition math_base.h:441
ccl_device_inline uint count_trailing_zeros(const uint x)
Definition math_base.h:727
#define T
#define T2
Definition md5.cpp:21
const btScalar eps
Definition poly34.cpp:11
#define mix
#define sqr
#define floorf
#define fabsf
#define sqrtf
#define ccl_device
#define fmaxf
#define fractf
#define fminf
#define cosf
#define ceilf
#define atan2f
#define min(a, b)
Definition sort.cc:36
ccl_device_inline_method Extrema(T value)
Definition math_base.h:912
ccl_device_inline_method Extrema(T min_, T max_)
Definition math_base.h:913
ccl_device_inline_method T range() const
Definition math_base.h:915
Extrema()=default
ccl_device_inline_method T length() const
Definition math_base.h:885
ccl_device_inline_method bool contains(T value) const
Definition math_base.h:880
ccl_device_inline_method bool is_empty() const
Definition math_base.h:874
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251
PointerRNA * ptr
Definition wm_files.cc:4238