// no header guards... do NOT include directly! /// @addtogroup MATH /// @{ static const Float32 MINVALUE_FLOAT32 = -3.402823466e+38f; ///< the minimum value a Float32 can represent static const Float32 MAXVALUE_FLOAT32 = 3.402823466e+38f; ///< the maximum value a Float32 can represent static const Float64 MINVALUE_FLOAT64 = -1.7976931348623158e+308; ///< the minimum value a Float64 can represent static const Float64 MAXVALUE_FLOAT64 = 1.7976931348623158e+308; ///< the maximum value a Float64 can represent static const Float32 MINVALUE_INT32_FLOAT32 = -2147483520.0f; ///< minimum Float32 value that can be represented by Int32 (-0x7FFFFF80). Lower values will results in an overflow static const Float32 MAXVALUE_INT32_FLOAT32 = 2147483520.0f; ///< maximum Float32 value that can be represented by Int32 ( 0x7FFFFF80). Higher values will results in an overflow static const Float64 MINVALUE_INT64_FLOAT64 = -9223372036854775295.0; ///< minimum Float64 value that can be represented by Int64 (-0x7ffffffffffffdff). Lower values will results in an overflow static const Float64 MAXVALUE_INT64_FLOAT64 = 9223372036854775295.0; ///< maximum Float64 value that can be represented by Int64 ( 0x7ffffffffffffdff). Higher values will results in an overflow static const Float32 MINRANGE_FLOAT32 = -1.0e10f; ///< 'safe' minimum range for Float32. Guarantees that multiplication of two numbers doesn't produce an overflow static const Float32 MAXRANGE_FLOAT32 = 1.0e10f; ///< 'safe' maximum range for Float32. Guarantees that multiplication of two numbers doesn't produce an overflow static const Float64 MINRANGE_FLOAT64 = -1.0e100; ///< 'safe' minimum range for Float. Guarantees that multiplication of two numbers doesn't produce an overflow static const Float64 MAXRANGE_FLOAT64 = 1.0e100; ///< 'safe' maximum range for Float. Guarantees that multiplication of two numbers doesn't produce an overflow #ifdef __FLOAT_32_BIT static const Float MINVALUE_FLOAT = MINVALUE_FLOAT32; ///< the minimum value a Float can represent static const Float MAXVALUE_FLOAT = MAXVALUE_FLOAT32; ///< the maximum value a Float can represent static const Float MINRANGE_FLOAT = MINRANGE_FLOAT32; ///< 'safe' minimum range for Float64. Guarantees that multiplication of two numbers doesn't produce an overflow static const Float MAXRANGE_FLOAT = MAXRANGE_FLOAT32; ///< 'safe' maximum range for Float64. Guarantees that multiplication of two numbers doesn't produce an overflow #else static const Float MINVALUE_FLOAT = MINVALUE_FLOAT64; ///< the minimum value a Float can represent static const Float MAXVALUE_FLOAT = MAXVALUE_FLOAT64; ///< the maximum value a Float can represent static const Float MINRANGE_FLOAT = MINRANGE_FLOAT64; ///< 'safe' minimum range for Float64. Guarantees that multiplication of two numbers doesn't produce an overflow static const Float MAXRANGE_FLOAT = MAXRANGE_FLOAT64; ///< 'safe' maximum range for Float64. Guarantees that multiplication of two numbers doesn't produce an overflow #endif /// Class to determine the limits of a datatype. Use LIMIT::Min() or LIMIT::Max() to return the minimum or maximum values that can be represented by the datatype. /// You can also use the LIMIT::MIN or LIMIT::MAX for integer datatypes (this doesn't work for floating point types though). template class LIMIT { }; template<> class LIMIT { public: static const Int64 MIN = -9223372036854775807LL - 1; static const Int64 MAX = 9223372036854775807LL; static Int64 Min() { return -9223372036854775807LL - 1; } static Int64 Max() { return 9223372036854775807LL; } }; template<> class LIMIT { public: static const UInt64 MIN = 0; static const UInt64 MAX = 0xffffffffffffffffULL; static UInt64 Min() { return 0; } static UInt64 Max() { return 0xffffffffffffffffULL; } }; template<> class LIMIT { public: static const Int32 MIN = -2147483647L - 1; static const Int32 MAX = 2147483647L; static Int32 Min() { return -2147483647L - 1; } static Int32 Max() { return 2147483647L; } }; template<> class LIMIT { public: static const UInt32 MIN = 0; static const UInt32 MAX = 0xffffffffULL; static UInt32 Min() { return 0; } static UInt32 Max() { return 0xffffffffULL; } }; template<> class LIMIT { public: static const Int16 MIN = -32767 - 1; static const Int16 MAX = 32767; static Int16 Min() { return -32767 - 1; } static Int16 Max() { return 32767; } }; template<> class LIMIT { public: static const UInt16 MIN = 0; static const UInt16 MAX = 0xffff; static UInt16 Min() { return 0; } static UInt16 Max() { return 0xffff; } }; template<> class LIMIT { public: static const Char MIN = -127 - 1; static const Char MAX = 127; static Char Min() { return -127 - 1; } static Char Max() { return 127; } }; template<> class LIMIT { public: static const UChar MIN = 0; static const UChar MAX = 0xff; static UChar Min() { return 0; } static UChar Max() { return 0xff; } }; template<> class LIMIT { public: static Float32 Min() { return -3.402823466e+38f; } static Float32 Max() { return 3.402823466e+38f; } }; template<> class LIMIT { public: static Float64 Min() { return -1.7976931348623158e+308; } static Float64 Max() { return 1.7976931348623158e+308; } }; #ifndef NOTOK static const Int NOTOK = -1; ///< constant used for special cases #endif /// floating point constant: PI static const Float64 PI = 3.1415926535897932384626433832795; /// floating point constant: 1.0 / PI static const Float64 PI_INV = 0.31830988618379067153776752674508; /// floating point constant: 2.0 * PI static const Float64 PI2 = 6.283185307179586476925286766559; /// floating point constant: 1.0 / (2.0 * PI) static const Float64 PI2_INV = 0.15915494309189533576888376337251; /// floating point constant: 0.5 * PI static const Float64 PI05 = 1.5707963267948966192313216916398; /// Clip a floating point number against the lower limit 0 and the upper limit 1. The result will be returned. inline Float32 Clamp01(Float32 a) { if (a < 0.0f) return 0.0f; if (a > 1.0f) return 1.0f; return a; } /// Clip a floating point number against the lower limit 0 and the upper limit 1. The result will be returned. inline Float64 Clamp01(Float64 a) { if (a < 0.0) return 0.0; if (a > 1.0) return 1.0; return a; } #if defined __MAC || defined __iOS inline Float32 Sin(Float32 val) { return sinf(val); } inline Float64 Sin(Float64 val) { return sin(val); } inline Float32 Cos(Float32 val) { return cosf(val); } inline Float64 Cos(Float64 val) { return cos(val); } inline Float32 Tan(Float32 val) { return tanf(val); } inline Float64 Tan(Float64 val) { return tan(val); } inline Float32 ATan(Float32 val) { return atanf(val); } inline Float64 ATan(Float64 val) { return atan(val); } inline Float32 ATan2(Float32 valA, Float32 valB) { return atan2f(valA, valB); } inline Float64 ATan2(Float64 valA, Float64 valB) { return atan2(valA, valB); } inline Float32 Exp(Float32 val) { return expf(val); } inline Float64 Exp(Float64 val) { return exp(val); } inline Float32 Ln(Float32 val) { return logf(val); } inline Float64 Ln(Float64 val) { return log(val); } inline Float32 Log10(Float32 val) { return log10f(val); } inline Float64 Log10(Float64 val) { return log10(val); } inline Float32 Log2(Float32 val) { return log2f(val); } inline Float64 Log2(Float64 val) { return log2(val); } inline Float32 Sqrt(Float32 val) { return sqrtf(val); } inline Float64 Sqrt(Float64 val) { return sqrt(val); } inline Float32 Floor(Float32 val) { return floorf(val); } inline Float64 Floor(Float64 val) { return floor(val); } inline Float32 Ceil(Float32 val) { return ceilf(val); } inline Float64 Ceil(Float64 val) { return ceil(val); } inline Float32 Pow(Float32 v1, Float32 v2) { return powf(v1,v2); } inline Float64 Pow(Float64 v1, Float64 v2) { return pow(v1,v2); } inline Float32 Sinh(Float32 val) { return sinhf(val); } inline Float64 Sinh(Float64 val) { return sinh(val); } inline Float32 Cosh(Float32 val) { return coshf(val); } inline Float64 Cosh(Float64 val) { return cosh(val); } inline Float32 Tanh(Float32 val) { return tanhf(val); } inline Float64 Tanh(Float64 val) { return tanh(val); } inline Float32 FMod(Float32 v1, Float32 v2) { return fmodf(v1,v2); } inline Float64 FMod(Float64 v1, Float64 v2) { return fmod(v1,v2); } inline Float32 Abs(Float32 val) { return fabsf(val); } inline Float64 Abs(Float64 val) { return fabs(val); } #else /// Calculates the sine of a value. inline Float32 Sin(Float32 val) { return sin(val); } /// Calculates the sine of a value. inline Float64 Sin(Float64 val) { return sin(val); } /// Calculates the cosine of a value. inline Float32 Cos(Float32 val) { return cos(val); } /// Calculates the cosine of a value. inline Float64 Cos(Float64 val) { return cos(val); } /// Calculates the tangent of a value. Note that the input needs to be checked for proper range, so that no exceptions will be generated. inline Float32 Tan(Float32 val) { return tan(val); } /// Calculates the tangent of a value. Note that the input needs to be checked for proper range, so that no exceptions will be generated. inline Float64 Tan(Float64 val) { return tan(val); } /// Calculates the arcustangens of a value. inline Float32 ATan(Float32 val) { return atan(val); } /// Calculates the arcustangens of a value. inline Float64 ATan(Float64 val) { return atan(val); } /// Calculates the arcustangens2 of a value. inline Float32 ATan2(Float32 valA, Float32 valB) { return atan2(valA, valB); } /// Calculates the arcustangens2 of a value. inline Float64 ATan2(Float64 valA, Float64 valB) { return atan2(valA, valB); } /// Calculates e^value. inline Float32 Exp(Float32 val) { return exp(val); } /// Calculates e^value. inline Float64 Exp(Float64 val) { return exp(val); } /// Calculates logarithm of a value. Note that the input needs to be positive, so that no exceptions will be generated. inline Float32 Ln(Float32 val) { return log(val); } /// Calculates logarithm of a value. Note that the input needs to be positive, so that no exceptions will be generated. inline Float64 Ln(Float64 val) { return log(val); } /// Calculates logarithm with base 10 of a value. Note that the input needs to be positive, so that no exceptions will be generated. inline Float32 Log10(Float32 val) { return log10(val); } /// Calculates logarithm with base 10 of a value. Note that the input needs to be positive, so that no exceptions will be generated. inline Float64 Log10(Float64 val) { return log10(val); } /// Calculates logarithm with base 2 of a value. Note that the input needs to be positive, so that no exceptions will be generated. inline Float32 Log2(Float32 val) { return log(val) * 1.4426950408889634073599246810019f; } /// Calculates logarithm with base 2 of a value. Note that the input needs to be positive, so that no exceptions will be generated. inline Float64 Log2(Float64 val) { return log(val) * 1.4426950408889634073599246810019; } /// Calculates square root of a value. Note that the input must not be be negative, so that no exceptions will be generated. inline Float32 Sqrt(Float32 val) { return sqrt(val); } /// Calculates square root of a value. Note that the input must not be be negative, so that no exceptions will be generated. inline Float64 Sqrt(Float64 val) { return sqrt(val); } /// Calculates the largest previous integer number. inline Float32 Floor(Float32 val) { return floor(val); } /// Calculates the largest previous integer number. inline Float64 Floor(Float64 val) { return floor(val); } /// Calculates the smallest following integer number. inline Float32 Ceil(Float32 val) { return ceil(val); } /// Calculates the smallest following integer number. inline Float64 Ceil(Float64 val) { return ceil(val); } /// Calculates v1^v2 inline Float32 Pow(Float32 v1, Float32 v2) { return pow(v1,v2); } /// Calculates v1^v2 inline Float64 Pow(Float64 v1, Float64 v2) { return pow(v1,v2); } /// Calculates hyperbolic sine inline Float32 Sinh(Float32 val) { return sinh(val); } /// Calculates hyperbolic sine inline Float64 Sinh(Float64 val) { return sinh(val); } /// Calculates hyperbolic cosine inline Float32 Cosh(Float32 val) { return cosh(val); } /// Calculates hyperbolic cosine inline Float64 Cosh(Float64 val) { return cosh(val); } /// Calculates hyperbolic tangent inline Float32 Tanh(Float32 val) { return tanh(val); } /// Calculates hyperbolic tangent inline Float64 Tanh(Float64 val) { return tanh(val); } /// Calculates floating point modulo inline Float32 FMod(Float32 v1, Float32 v2) { return fmod(v1,v2); } /// Calculates floating point modulo inline Float64 FMod(Float64 v1, Float64 v2) { return fmod(v1,v2); } /// Calculates the absolute value of a floating point number. inline Float32 Abs(Float32 f) { return fabs(f); } /// Calculates the absolute value of a floating point number. inline Float64 Abs(Float64 f) { return fabs(f); } #endif /// Calculates the reciprocal value (multiplicative inverse). If the input value is zero, zero will be returned for safety to avoid exceptions. inline Float32 Inverse(Float32 f) { return (f == 0.0f) ? 0.0f : 1.0f / f; } /// Calculates the reciprocal value (multiplicative inverse). If the input value is zero, zero will be returned for safety to avoid exceptions. inline Float64 Inverse(Float64 f) { return (f == 0.0) ? 0.0 : 1.0 / f; } #ifndef SIZEOF /// Calculates the size of a datatype or element. #define SIZEOF(x) ((maxon::Int)sizeof(x)) #endif /// Calculates the absolute value of any data type template inline X Abs(X f) { if (f<0) return -f; return f; } /// Calculates the minimum of two values and return it. template inline X Min(X a, X b) { if (a inline X Max(X a, X b) { if (a inline void Swap(X &a, X &b) { X c(std::move(a)); a = std::move(b); b = std::move(c); } /// Clips a value against a lower and upper limit. The new value is returned. template inline X ClampValue(X value, X lowerLimit, X upperLimit) { if (value < lowerLimit) return lowerLimit; if (value > upperLimit) return upperLimit; return value; } /// Clips a value against a lower and upper limit. The new value is returned. template inline X Blend(const X& value1, const X& value2, Y blendValue) { return value1 + (value2 - value1) * blendValue; } /// Calculates square difference of two values template inline Float Sqr(X a, X b) { X tmp = a-b; return tmp*tmp; } /// Calculates square of a value template inline Float Sqr(X a) { return a*a; } /// Calculates arcsine. The input value is clipped for safety to avoid exceptions. inline Float32 ASin(Float32 val) { if(val>=1.0f) return Float32(PI05); else if (val<=-1.0f) return Float32(-PI05); return asinf(val); } /// Calculates arcsine. The input value is clipped for safety to avoid exceptions. inline Float64 ASin(Float64 val) { if(val>=1.0f) return Float32(PI05); else if(val<=-1.0f) return Float32(-PI05); return asin(val); } /// Calculates arccosine. The input value is clipped for safety to avoid exceptions. inline Float32 ACos(Float32 val) { if(val>=1.0f) return 0.0f; else if (val<=-1.0f) return Float32(PI); return acosf(val); } /// Calculates arccosine. The input value is clipped for safety to avoid exceptions. inline Float64 ACos(Float64 val) { if(val>=1.0f) return 0.0f; else if(val<=-1.0f) return Float32(PI); return acos(val); } /// Converts float value from degrees to radians inline Float32 Rad(Float32 r) { return ((r)*Float32(PI)/180.0f); } /// Converts float value from degrees to radians inline Float64 Rad(Float64 r) { return ((r)*PI/180.0); } /// Converts float value from radians to degrees inline Float32 Deg(Float32 r) { return ((r)*180.0f/Float32(PI)); } /// Converts float value from radians to degrees inline Float64 Deg(Float64 r) { return ((r)*180.0/PI); } inline void SinCos(Float32 r, Float32& sn, Float32& cs) { sn=Sin(r); cs=Cos(r); } inline void SinCos(Float64 r, Float64& sn, Float64& cs) { sn=Sin(r); cs=Cos(r); } /// Safely converts a 32 bit float value into Int32. /// The resulting value will be clipped against the Int64 boundaries, without raising an exception. inline Int32 SAFEINT32(Float32 x) { if (x <= MINVALUE_INT32_FLOAT32) return LIMIT::MIN; else if (x >= MAXVALUE_INT32_FLOAT32) return LIMIT::MAX; return Int32(x); } /// Safely converts a 64 bit float value into Int32. /// The resulting value will be clipped against the Int64 boundaries, without raising an exception. inline Int32 SAFEINT32(Float64 x) { if (x <= (Float64)LIMIT::MIN) return LIMIT::MIN; else if (x >= (Float64)LIMIT::MAX) return LIMIT::MAX; return Int32(x); } /// Safely converts a 32 bit float value into Int64. /// The resulting value will be clipped against the Int64 boundaries, without raising an exception. inline Int64 SAFEINT64(Float32 x) { if (x <= MINVALUE_INT32_FLOAT32) return (Int64)LIMIT::MIN; else if (x >= MAXVALUE_INT32_FLOAT32) return (Int64)LIMIT::MAX; return Int64(x); } /// Safely converts a 64 bit float value into Int64. /// The resulting value will be clipped against the Int64 boundaries, without raising an exception inline Int64 SAFEINT64(Float64 x) { if (x <= MINVALUE_INT64_FLOAT64) return LIMIT::MIN; else if (x >= MAXVALUE_INT64_FLOAT64) return LIMIT::MAX; return Int64(x); } #ifdef __C4D_64BIT /// Safely converts a 64 bit float value into Int. /// The resulting value will be clipped against the Int boundaries, without raising an exception inline Int SAFEINT(Float64 x) { return SAFEINT64(x); } /// Safely converts a 32 bit float value into Int. /// The resulting value will be clipped against the Int boundaries, without raising an exception inline Int SAFEINT(Float32 x) { return SAFEINT64(x); } #else /// Safely converts a 64 bit float value into Int. /// The resulting value will be clipped against the Int boundaries, without raising an exception inline Int SAFEINT(Float64 x) { return SAFEINT32(x); } /// Safely converts a 32 bit float value into Int. /// The resulting value will be clipped against the Int boundaries, without raising an exception inline Int SAFEINT(Float32 x) { return SAFEINT32(x); } #endif //---------------------------------------------------------------------------------------- /// Assigns the maximum of two values to the first value. /// @param[in,out] a First value. /// @param[in] b Second value. //---------------------------------------------------------------------------------------- template inline void SetMax(T& a, const T& b) { if (b > a) { a = b; } } //---------------------------------------------------------------------------------------- /// Assigns the minimum of two values to the first value. /// @param[in,out] a First value. /// @param[in] b Second value. //---------------------------------------------------------------------------------------- template inline void SetMin(T& a, const T& b) { if (b < a) { a = b; } } /// @}