Blender V5.0
math_base_inline.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
8
9#ifndef __MATH_BASE_INLINE_C__
10#define __MATH_BASE_INLINE_C__
11
12#include <float.h>
13#include <limits.h>
14#include <math.h>
15#include <stdio.h>
16#include <stdlib.h>
17
18#include "BLI_assert.h"
19#include "BLI_math_inline.h"
20#include "BLI_sys_types.h"
21
22/* copied from BLI_utildefines.h */
23#ifdef __GNUC__
24# define UNLIKELY(x) __builtin_expect(!!(x), 0)
25#else
26# define UNLIKELY(x) (x)
27#endif
28
29MINLINE float pow2f(float x)
30{
31 return x * x;
32}
33MINLINE float pow3f(float x)
34{
35 return pow2f(x) * x;
36}
37MINLINE float pow4f(float x)
38{
39 return pow2f(pow2f(x));
40}
41MINLINE float pow5f(float x)
42{
43 return pow4f(x) * x;
44}
45MINLINE float pow7f(float x)
46{
47 return pow2f(pow3f(x)) * x;
48}
49
50MINLINE float sqrt3f(float f)
51{
52 if (UNLIKELY(f == 0.0f)) {
53 return 0.0f;
54 }
55 if (UNLIKELY(f < 0.0f)) {
56 return -(float)(exp(log(-f) / 3.0));
57 }
58 return (float)(exp(log(f) / 3.0));
59}
60
61MINLINE double sqrt3d(double d)
62{
63 if (UNLIKELY(d == 0.0)) {
64 return 0.0;
65 }
66 if (UNLIKELY(d < 0.0)) {
67 return -exp(log(-d) / 3.0);
68 }
69 return exp(log(d) / 3.0);
70}
71
72MINLINE float sqrtf_signed(float f)
73{
74 return (f >= 0.0f) ? sqrtf(f) : -sqrtf(-f);
75}
76
77MINLINE float interpf(float target, float origin, float fac)
78{
79 return (fac * target) + (1.0f - fac) * origin;
80}
81
82MINLINE double interpd(double target, double origin, double fac)
83{
84 return (fac * target) + (1.0f - fac) * origin;
85}
86
87MINLINE float ratiof(float min, float max, float pos)
88{
89 float range = max - min;
90 return range == 0 ? 0 : ((pos - min) / range);
91}
92
93MINLINE double ratiod(double min, double max, double pos)
94{
95 double range = max - min;
96 return range == 0 ? 0 : ((pos - min) / range);
97}
98
99MINLINE float power_of_2(float val)
100{
101 return (float)pow(2.0, ceil(log((double)val) / M_LN2));
102}
103
105{
106 return (n & (n - 1)) == 0;
107}
108
110{
111 if (is_power_of_2_i(n)) {
112 return n;
113 }
114
115 do {
116 n = n & (n - 1);
117 } while (!is_power_of_2_i(n));
118
119 return n * 2;
120}
121
123{
124 while (!is_power_of_2_i(n)) {
125 n = n & (n - 1);
126 }
127
128 return n;
129}
130
131MINLINE unsigned int power_of_2_max_u(unsigned int x)
132{
133 x -= 1;
134 x |= (x >> 1);
135 x |= (x >> 2);
136 x |= (x >> 4);
137 x |= (x >> 8);
138 x |= (x >> 16);
139 return x + 1;
140}
141
142MINLINE unsigned int log2_floor_u(unsigned int x)
143{
144 return x <= 1 ? 0 : 1 + log2_floor_u(x >> 1);
145}
146
147MINLINE unsigned int log2_ceil_u(unsigned int x)
148{
149 if (is_power_of_2_i((int)x)) {
150 return log2_floor_u(x);
151 }
152 return log2_floor_u(x) + 1;
153}
154
155/* rounding and clamping */
156
157#define _round_clamp_fl_impl(arg, ty, min, max) \
158 { \
159 float r = floorf(arg + 0.5f); \
160 if (UNLIKELY(r <= (float)min)) { \
161 return (ty)min; \
162 } \
163 if (UNLIKELY(r >= (float)max)) { \
164 return (ty)max; \
165 } \
166 return (ty)r; \
167 }
168
169#define _round_clamp_db_impl(arg, ty, min, max) \
170 { \
171 double r = floor(arg + 0.5); \
172 if (UNLIKELY(r <= (double)min)) { \
173 return (ty)min; \
174 } \
175 if (UNLIKELY(r >= (double)max)) { \
176 return (ty)max; \
177 } \
178 return (ty)r; \
179 }
180
181#define _round_fl_impl(arg, ty) \
182 { \
183 return (ty)floorf(arg + 0.5f); \
184 }
185#define _round_db_impl(arg, ty) \
186 { \
187 return (ty)floor(arg + 0.5); \
188 }
189
190MINLINE unsigned char round_fl_to_uchar(float a){_round_fl_impl(a, unsigned char)} MINLINE
191 short round_fl_to_short(float a){_round_fl_impl(a, short)} MINLINE
193 unsigned int round_fl_to_uint(float a){_round_fl_impl(a, unsigned int)}
194
196
197#undef _round_fl_impl
198#undef _round_db_impl
199
200MINLINE unsigned char round_fl_to_uchar_clamp(float a){
201 _round_clamp_fl_impl(a, unsigned char, 0, UCHAR_MAX)} MINLINE
202 int round_fl_to_int_clamp(float a){_round_clamp_fl_impl(a, int, INT_MIN, INT_MAX)}
203
204MINLINE unsigned char round_db_to_uchar_clamp(double a){
205 _round_clamp_db_impl(a, unsigned char, 0, UCHAR_MAX)} MINLINE
206 short round_db_to_short_clamp(double a){
207 _round_clamp_db_impl(a, short, SHRT_MIN, SHRT_MAX)} MINLINE
208 int round_db_to_int_clamp(double a){_round_clamp_db_impl(a, int, INT_MIN, INT_MAX)}
209
210#undef _round_clamp_fl_impl
211#undef _round_clamp_db_impl
212
213MINLINE float round_to_even(float f)
214{
215 return roundf(f * 0.5f) * 2.0f;
216}
217
218MINLINE int divide_round_i(int a, int b)
219{
220 return (2 * a + b) / (2 * b);
221}
222
227MINLINE int divide_floor_i(int a, int b)
228{
229 int d = a / b;
230 int r = a % b; /* Optimizes into a single division. */
231 return r ? d - ((a < 0) ^ (b < 0)) : d;
232}
233
235{
236 return (a + b - 1) / b;
237}
238
240{
241 return (a + b - 1) / b;
242}
243
245{
246 return divide_ceil_u(a, b) * b;
247}
248
253
254MINLINE int mod_i(int i, int n)
255{
256 return (i % n + n) % n;
257}
258
259MINLINE float floored_fmod(const float f, const float n)
260{
261 return f - n * floorf(f / n);
262}
263
264MINLINE float fractf(float a)
265{
266 return a - floorf(a);
267}
268
269/* Adapted from `godot-engine` math_funcs.h. */
270MINLINE float wrapf(float value, float max, float min)
271{
272 float range = max - min;
273 return (range != 0.0f) ? value - (range * floorf((value - min) / range)) : min;
274}
275
276MINLINE float pingpongf(float value, float scale)
277{
278 if (scale == 0.0f) {
279 return 0.0f;
280 }
281 return fabsf(fractf((value - scale) / (scale * 2.0f)) * scale * 2.0f - scale);
282}
283
284/* Square. */
285
286MINLINE int square_s(short a)
287{
288 return a * a;
289}
290
292{
293 return a * a;
294}
295
296MINLINE unsigned int square_uint(unsigned int a)
297{
298 return a * a;
299}
300
301MINLINE float square_f(float a)
302{
303 return a * a;
304}
305
306/* Cube. */
307
308MINLINE int cube_i(int a)
309{
310 return a * a * a;
311}
312
313MINLINE float cube_f(float a)
314{
315 return a * a * a;
316}
317
318/* Min/max */
319
320MINLINE float min_ff(float a, float b)
321{
322 return (a < b) ? a : b;
323}
324MINLINE float max_ff(float a, float b)
325{
326 return (a > b) ? a : b;
327}
328/* See: https://www.iquilezles.org/www/articles/smin/smin.htm. */
329MINLINE float smoothminf(float a, float b, float c)
330{
331 if (c != 0.0f) {
332 float h = max_ff(c - fabsf(a - b), 0.0f) / c;
333 return min_ff(a, b) - h * h * h * c * (1.0f / 6.0f);
334 }
335 return min_ff(a, b);
336}
337
338MINLINE float smoothstep(float edge0, float edge1, float x)
339{
340 float result;
341 if (x < edge0) {
342 result = 0.0f;
343 }
344 else if (x >= edge1) {
345 result = 1.0f;
346 }
347 else {
348 float t = (x - edge0) / (edge1 - edge0);
349 result = (3.0f - 2.0f * t) * (t * t);
350 }
351 return result;
352}
353
354MINLINE double min_dd(double a, double b)
355{
356 return (a < b) ? a : b;
357}
358MINLINE double max_dd(double a, double b)
359{
360 return (a > b) ? a : b;
361}
362
363MINLINE int min_ii(int a, int b)
364{
365 return (a < b) ? a : b;
366}
367MINLINE int max_ii(int a, int b)
368{
369 return (b < a) ? a : b;
370}
371
373{
374 return (a < b) ? a : b;
375}
377{
378 return (b < a) ? a : b;
379}
380
381MINLINE unsigned long long min_ulul(unsigned long long a, unsigned long long b)
382{
383 return (a < b) ? a : b;
384}
385MINLINE unsigned long long max_ulul(unsigned long long a, unsigned long long b)
386{
387 return (b < a) ? a : b;
388}
389
390MINLINE double max_ddd(double a, double b, double c)
391{
392 return max_dd(max_dd(a, b), c);
393}
394
395MINLINE float min_fff(float a, float b, float c)
396{
397 return min_ff(min_ff(a, b), c);
398}
399MINLINE float max_fff(float a, float b, float c)
400{
401 return max_ff(max_ff(a, b), c);
402}
403
404MINLINE int min_iii(int a, int b, int c)
405{
406 return min_ii(min_ii(a, b), c);
407}
408MINLINE int max_iii(int a, int b, int c)
409{
410 return max_ii(max_ii(a, b), c);
411}
412
413MINLINE float min_ffff(float a, float b, float c, float d)
414{
415 return min_ff(min_fff(a, b, c), d);
416}
417MINLINE float max_ffff(float a, float b, float c, float d)
418{
419 return max_ff(max_fff(a, b, c), d);
420}
421
422MINLINE int min_iiii(int a, int b, int c, int d)
423{
424 return min_ii(min_iii(a, b, c), d);
425}
426MINLINE int max_iiii(int a, int b, int c, int d)
427{
428 return max_ii(max_iii(a, b, c), d);
429}
430
431MINLINE size_t min_zz(size_t a, size_t b)
432{
433 return (a < b) ? a : b;
434}
435MINLINE size_t max_zz(size_t a, size_t b)
436{
437 return (b < a) ? a : b;
438}
439
440MINLINE int clamp_i(int value, int min, int max)
441{
442 return min_ii(max_ii(value, min), max);
443}
444
445MINLINE float clamp_f(float value, float min, float max)
446{
447 if (value > max) {
448 return max;
449 }
450 if (value < min) {
451 return min;
452 }
453 return value;
454}
455
456MINLINE int compare_ff(float a, float b, const float max_diff)
457{
458 return fabsf(a - b) <= max_diff;
459}
460
461MINLINE uint ulp_diff_ff(float a, float b)
462{
463 BLI_assert(sizeof(float) == sizeof(uint));
464
465 const uint sign_bit = 0x80000000;
466 const uint infinity = 0x7f800000;
467
468 union {
469 float f;
470 uint i;
471 } ua, ub;
472 ua.f = a;
473 ub.f = b;
474
475 const uint a_sign = ua.i & sign_bit;
476 const uint b_sign = ub.i & sign_bit;
477 const uint a_abs = ua.i & ~sign_bit;
478 const uint b_abs = ub.i & ~sign_bit;
479
480 if (a_abs > infinity || b_abs > infinity) {
481 /* NaNs always return maximum ulps apart. */
482 return 0xffffffff;
483 }
484 if (a_sign == b_sign) {
485 const uint min_abs = a_abs < b_abs ? a_abs : b_abs;
486 const uint max_abs = a_abs > b_abs ? a_abs : b_abs;
487 return max_abs - min_abs;
488 }
489 return a_abs + b_abs;
490}
491
492MINLINE int compare_ff_relative(float a, float b, const float max_diff, const int max_ulps)
493{
494 BLI_assert(max_ulps >= 0 && max_ulps < (1 << 22));
495
496 if (fabsf(a - b) <= max_diff) {
497 return 1;
498 }
499
500 return (ulp_diff_ff(a, b) <= (uint)max_ulps) ? 1 : 0;
501}
502
503MINLINE bool compare_threshold_relative(const float value1, const float value2, const float thresh)
504{
505 const float abs_diff = fabsf(value1 - value2);
506 /* Avoid letting the threshold get too small just because the values happen to be close to zero.
507 */
508 if (fabsf(value2) < 1) {
509 return abs_diff > thresh;
510 }
511 /* Using relative threshold in general. */
512 return abs_diff > thresh * fabsf(value2);
513}
514
515MINLINE float increment_ulp(const float value)
516{
517 if (!isfinite(value)) {
518 return value;
519 }
520
521 union {
522 float f;
523 uint i;
524 } v;
525 v.f = value;
526
527 if (v.f > 0.0f) {
528 v.i += 1;
529 }
530 else if (v.f < -0.0f) {
531 v.i -= 1;
532 }
533 else {
534 v.i = 0x00000001;
535 }
536
537 return v.f;
538}
539
540MINLINE float decrement_ulp(const float value)
541{
542 if (!isfinite(value)) {
543 return value;
544 }
545
546 union {
547 float f;
548 uint i;
549 } v;
550 v.f = value;
551
552 if (v.f > 0.0f) {
553 v.i -= 1;
554 }
555 else if (v.f < -0.0f) {
556 v.i += 1;
557 }
558 else {
559 v.i = 0x80000001;
560 }
561
562 return v.f;
563}
564
565MINLINE float signf(float f)
566{
567 return (f < 0.0f) ? -1.0f : 1.0f;
568}
569
571{
572 if (f > 0.0f) {
573 return 1.0f;
574 }
575 if (f < 0.0f) {
576 return -1.0f;
577 }
578 return 0.0f;
579}
580
581MINLINE int signum_i_ex(float a, float eps)
582{
583 if (a > eps) {
584 return 1;
585 }
586 if (a < -eps) {
587 return -1;
588 }
589 return 0;
590}
591
592MINLINE int signum_i(float a)
593{
594 if (a > 0.0f) {
595 return 1;
596 }
597 if (a < 0.0f) {
598 return -1;
599 }
600 return 0;
601}
602
603MINLINE int integer_digits_f(const float f)
604{
605 return (f == 0.0f) ? 0 : (int)floor(log10(fabs(f))) + 1;
606}
607
608MINLINE int integer_digits_d(const double d)
609{
610 return (d == 0.0) ? 0 : (int)floor(log10(fabs(d))) + 1;
611}
612
614{
615 return (int)log10((double)i) + 1;
616}
617
618/* Low level conversion functions */
619MINLINE unsigned char unit_float_to_uchar_clamp(float val)
620{
621 return (unsigned char)((
622 (val <= 0.0f) ? 0 : ((val > (1.0f - 0.5f / 255.0f)) ? 255 : ((255.0f * val) + 0.5f))));
623}
624
625MINLINE unsigned short unit_float_to_ushort_clamp(float val)
626{
627 return (unsigned short)((val >= 1.0f - 0.5f / 65535) ? 65535 :
628 (val <= 0.0f) ? 0 :
629 (val * 65535.0f + 0.5f));
630}
631
632MINLINE unsigned char unit_ushort_to_uchar(unsigned short val)
633{
634 return (unsigned char)(((val) >= 65535 - 128) ? 255 : ((val) + 128) >> 8);
635}
636
637#define unit_float_to_uchar_clamp_v3(v1, v2) \
638 { \
639 (v1)[0] = unit_float_to_uchar_clamp((v2[0])); \
640 (v1)[1] = unit_float_to_uchar_clamp((v2[1])); \
641 (v1)[2] = unit_float_to_uchar_clamp((v2[2])); \
642 } \
643 ((void)0)
644#define unit_float_to_uchar_clamp_v4(v1, v2) \
645 { \
646 (v1)[0] = unit_float_to_uchar_clamp((v2[0])); \
647 (v1)[1] = unit_float_to_uchar_clamp((v2[1])); \
648 (v1)[2] = unit_float_to_uchar_clamp((v2[2])); \
649 (v1)[3] = unit_float_to_uchar_clamp((v2[3])); \
650 } \
651 ((void)0)
652
653#endif /* __MATH_BASE_INLINE_C__ */
#define BLI_assert(a)
Definition BLI_assert.h:46
#define M_LN2
#define MINLINE
unsigned int uint
ATTR_WARN_UNUSED_RESULT const BMVert * v
unsigned long long int uint64_t
nullptr float
#define roundf(x)
uint pos
#define log
#define pow
#define exp
#define floor
#define ceil
MINLINE int round_fl_to_int_clamp(float a)
MINLINE unsigned char round_fl_to_uchar(float a)
MINLINE float max_fff(float a, float b, float c)
MINLINE uint ceil_to_multiple_u(uint a, uint b)
MINLINE double max_ddd(double a, double b, double c)
#define _round_clamp_fl_impl(arg, ty, min, max)
MINLINE uint min_uu(uint a, uint b)
MINLINE float max_ffff(float a, float b, float c, float d)
MINLINE float decrement_ulp(const float value)
MINLINE unsigned int log2_ceil_u(unsigned int x)
MINLINE int power_of_2_min_i(int n)
MINLINE int round_fl_to_int(float a)
MINLINE short round_db_to_short_clamp(double a)
MINLINE float max_ff(float a, float b)
MINLINE size_t min_zz(size_t a, size_t b)
MINLINE int min_ii(int a, int b)
MINLINE uint divide_ceil_u(uint a, uint b)
MINLINE unsigned char unit_ushort_to_uchar(unsigned short val)
MINLINE int power_of_2_max_i(int n)
MINLINE int compare_ff(float a, float b, const float max_diff)
MINLINE float power_of_2(float val)
MINLINE float min_ffff(float a, float b, float c, float d)
MINLINE unsigned int power_of_2_max_u(unsigned int x)
MINLINE uint max_uu(uint a, uint b)
MINLINE bool compare_threshold_relative(const float value1, const float value2, const float thresh)
#define _round_fl_impl(arg, ty)
MINLINE int cube_i(int a)
#define _round_db_impl(arg, ty)
MINLINE float pow2f(float x)
MINLINE double ratiod(double min, double max, double pos)
MINLINE float clamp_f(float value, float min, float max)
MINLINE int divide_floor_i(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE size_t max_zz(size_t a, size_t b)
MINLINE unsigned long long min_ulul(unsigned long long a, unsigned long long b)
MINLINE unsigned long long max_ulul(unsigned long long a, unsigned long long b)
MINLINE int integer_digits_d(const double d)
MINLINE int square_i(int a)
MINLINE float floored_fmod(const float f, const float n)
MINLINE float pow5f(float x)
MINLINE int max_ii(int a, int b)
MINLINE short round_fl_to_short(float a)
MINLINE uint64_t divide_ceil_ul(uint64_t a, uint64_t b)
MINLINE double min_dd(double a, double b)
MINLINE unsigned char unit_float_to_uchar_clamp(float val)
MINLINE float smoothminf(float a, float b, float c)
MINLINE float cube_f(float a)
MINLINE unsigned char round_fl_to_uchar_clamp(float a)
MINLINE int min_iii(int a, int b, int c)
MINLINE int divide_round_i(int a, int b)
MINLINE int integer_digits_f(const float f)
MINLINE int integer_digits_i(const int i)
MINLINE int mod_i(int i, int n)
MINLINE double interpd(double target, double origin, double fac)
MINLINE unsigned short unit_float_to_ushort_clamp(float val)
MINLINE float square_f(float a)
MINLINE unsigned int round_fl_to_uint(float a)
MINLINE float pingpongf(float value, float scale)
#define UNLIKELY(x)
MINLINE float interpf(float target, float origin, float fac)
MINLINE float sqrtf_signed(float f)
MINLINE double max_dd(double a, double b)
MINLINE uint ulp_diff_ff(float a, float b)
MINLINE int round_db_to_int_clamp(double a)
MINLINE int is_power_of_2_i(int n)
MINLINE float pow3f(float x)
MINLINE int compare_ff_relative(float a, float b, const float max_diff, const int max_ulps)
MINLINE double sqrt3d(double d)
MINLINE int round_db_to_int(double a)
MINLINE int max_iiii(int a, int b, int c, int d)
MINLINE float min_fff(float a, float b, float c)
MINLINE int signum_i_ex(float a, float eps)
MINLINE int min_iiii(int a, int b, int c, int d)
MINLINE unsigned int log2_floor_u(unsigned int x)
MINLINE float signf(float f)
MINLINE float increment_ulp(const float value)
MINLINE int max_iii(int a, int b, int c)
MINLINE int clamp_i(int value, int min, int max)
MINLINE int signum_i(float a)
MINLINE float ratiof(float min, float max, float pos)
MINLINE float smoothstep(float edge0, float edge1, float x)
MINLINE float round_to_even(float f)
#define _round_clamp_db_impl(arg, ty, min, max)
MINLINE unsigned int square_uint(unsigned int a)
MINLINE int square_s(short a)
MINLINE uint64_t ceil_to_multiple_ul(uint64_t a, uint64_t b)
MINLINE float compatible_signf(float f)
MINLINE unsigned char round_db_to_uchar_clamp(double a)
MINLINE float pow4f(float x)
MINLINE float sqrt3f(float f)
MINLINE float pow7f(float x)
MINLINE float wrapf(float value, float max, float min)
ccl_device_inline float2 fabs(const float2 a)
const btScalar eps
Definition poly34.cpp:11
#define floorf
#define fabsf
#define sqrtf
#define fractf
#define min(a, b)
Definition sort.cc:36
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251