21 #if !defined(__MITSUBA_CORE_MATH_H_)
22 #define __MITSUBA_CORE_MATH_H_
51 template <
typename Scalar>
inline Scalar
clamp(Scalar value, Scalar min, Scalar max) {
52 return std::min(max, std::max(min, value));
56 template <
typename Scalar>
inline Scalar
lerp(Scalar t, Scalar v1, Scalar v2) {
57 return ((Scalar) 1 - t) * v1 + t * v2;
61 template <
typename Scalar>
inline Scalar
smoothStep(Scalar min, Scalar max, Scalar value) {
62 Scalar v =
clamp((value - min) / (max - min), (Scalar) 0, (Scalar) 1);
63 return v * v * (-2 * v + 3);
67 inline int32_t
modulo(int32_t a, int32_t b) {
69 return (r < 0) ? r+b : r;
73 inline int64_t
modulo(int64_t a, int64_t b) {
75 return (r < 0) ? r+b : r;
78 #if defined(MTS_AMBIGUOUS_SIZE_T)
79 inline ssize_t
modulo(ssize_t a, ssize_t b) {
80 if (
sizeof(ssize_t) == 8)
81 return modulo((int64_t) a, (int64_t) b);
83 return modulo((int32_t) a, (int32_t) b);
88 inline float modulo(
float a,
float b) {
89 float r = std::fmod(a, b);
90 return (r < 0.0f) ? r+b : r;
94 inline double modulo(
double a,
double b) {
95 double r = std::fmod(a, b);
96 return (r < 0.0) ? r+b : r;
100 template <
typename Scalar>
inline int floorToInt(Scalar value) {
return (
int) std::floor(value); }
103 template <
typename Scalar>
inline int ceilToInt(Scalar value) {
return (
int) std::ceil(value); }
107 #if defined(__MSVC__)
108 return (
int) (value < 0.0f ? std::ceil(value - 0.5f) : std::floor(value + 0.5f));
110 return (
int) ::roundf(value);
116 #if defined(__MSVC__)
117 return (
int) (value < 0.0 ? std::ceil(value - 0.5) : std::floor(value + 0.5));
119 return (
int) ::round(value);
129 #if defined(MTS_AMBIGUOUS_SIZE_T)
130 inline int log2i(
size_t value) {
131 if (
sizeof(
size_t) == 8)
132 return log2i((uint64_t) value);
142 inline bool isPowerOfTwo(int32_t i) {
return i > 0 && (i & (i-1)) == 0; }
148 inline bool isPowerOfTwo(int64_t i) {
return i > 0 && (i & (i-1)) == 0; }
150 #if defined(MTS_AMBIGUOUS_SIZE_T)
152 if (
sizeof(
size_t) == 8)
165 #if defined(MTS_AMBIGUOUS_SIZE_T)
168 if (
sizeof(
size_t) == 8)
175 #if defined(__LINUX__) && defined(__x86_64__)
185 inline float fastexp(
float value) {
186 return (
float) ::exp((
double) value);
189 inline double fastexp(
double value) {
193 inline float fastlog(
float value) {
194 return (
float) ::log((
double) value);
197 inline double fastlog(
double value) {
202 return ::expf(value);
210 return ::logf(value);
218 #if defined(_GNU_SOURCE)
219 inline void sincos(
float theta,
float *sin,
float *cos) {
220 ::sincosf(theta, sin, cos);
223 inline void sincos(
double theta,
double *sin,
double *cos) {
228 inline void sincos(
float theta,
float *_sin,
float *_cos) {
233 inline void sincos(
double theta,
double *_sin,
double *_cos) {
241 return std::asin(std::min(1.0f, std::max(-1.0f, value)));
246 return std::asin(std::min(1.0, std::max(-1.0, value)));
251 return std::acos(std::min(1.0f, std::max(-1.0f, value)));
256 return std::acos(std::min(1.0, std::max(-1.0, value)));
261 return std::sqrt(std::max(0.0f, value));
266 return std::sqrt(std::max(0.0, value));
271 #if defined(__WINDOWS__)
272 return (
Float) _copysign(1.0, value);
273 #elif defined(SINGLE_PRECISION)
274 return copysignf((
float) 1.0, value);
275 #elif defined(DOUBLE_PRECISION)
276 return copysign((
double) 1.0, value);
291 if ((
double) a < val)
307 if ((
double) a > val)
MTS_EXPORT_CORE float hypot2(float a, float b)
sqrt(a^2 + b^2) without range issues (like 'hypot' on compilers that support C99, single precision) ...
float fastlog(float value)
Definition: math.h:209
float castflt_up(float val)
Cast to single precision and round up if not exactly representable (passthrough)
Definition: math.h:281
int floorToInt(Scalar value)
Integer floor function (single precision)
Definition: math.h:100
bool isPowerOfTwo(uint32_t i)
Check if an integer is a power of two (unsigned 32 bit version)
Definition: math.h:139
float safe_asin(float value)
Arcsine variant that gracefully handles arguments > 1 that are due to roundoff errors.
Definition: math.h:240
#define MTS_EXPORT_CORE
Definition: getopt.h:29
int32_t modulo(int32_t a, int32_t b)
Always-positive modulo function (assumes b > 0)
Definition: math.h:67
MTS_EXPORT_CORE uint32_t roundToPowerOfTwo(uint32_t i)
Round an integer to the next power of two.
MTS_EXPORT_CORE float log2(float value)
Base-2 logarithm (single precision)
Scalar lerp(Scalar t, Scalar v1, Scalar v2)
Linearly interpolate between two values.
Definition: math.h:56
int ceilToInt(Scalar value)
Integer ceil function (single precision)
Definition: math.h:103
float safe_sqrt(float value)
Square root variant that gracefully handles arguments < 0 that are due to roundoff errors...
Definition: math.h:260
MTS_EXPORT_CORE Float erfinv(Float x)
Cross-platform implementation of the inverse error function.
float safe_acos(float value)
Arccosine variant that gracefully handles arguments > 1 that are due to roundoff errors.
Definition: math.h:250
void sincos(float theta, float *_sin, float *_cos)
Definition: math.h:228
float castflt_down(float val)
Cast to single precision and round down if not exactly representable (passthrough) ...
Definition: math.h:297
MTS_EXPORT_CORE int log2i(uint32_t value)
Base-2 logarithm (32-bit integer version)
float fastexp(float value)
Definition: math.h:201
int roundToInt(float value)
Integer round function (single precision)
Definition: math.h:106
Scalar smoothStep(Scalar min, Scalar max, Scalar value)
S-shaped smoothly varying interpolation between two values.
Definition: math.h:61
Float signum(Float value)
Simple signum function – note that it returns the FP sign of the input (and never zero) ...
Definition: math.h:270
MTS_EXPORT_CORE Float erf(Float x)
Cross-platform implementation of the error function.
Scalar clamp(Scalar value, Scalar min, Scalar max)
Generic clamping function.
Definition: math.h:51