diff options
Diffstat (limited to 'core/math/math_funcs.h')
-rw-r--r-- | core/math/math_funcs.h | 224 |
1 files changed, 90 insertions, 134 deletions
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 665182afcf..511af91835 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -38,6 +38,7 @@ #define Math_PI 3.14159265358979323846 #define Math_SQRT12 0.7071067811865475244008443621048490 +#define Math_LN2 0.693147180559945309417 class Math { @@ -51,149 +52,122 @@ public: }; - static _ALWAYS_INLINE_ double sin(double p_x) { + static _ALWAYS_INLINE_ double sin(double p_x) { return ::sin(p_x); } + static _ALWAYS_INLINE_ float sin(float p_x) { return ::sinf(p_x); } - return ::sin(p_x); + static _ALWAYS_INLINE_ double cos(double p_x) { return ::cos(p_x); } + static _ALWAYS_INLINE_ float cos(float p_x) { return ::cosf(p_x); } - } - - static _ALWAYS_INLINE_ double cos(double p_x) { - - return ::cos(p_x); - - } - - static _ALWAYS_INLINE_ double tan(double p_x) { - - return ::tan(p_x); - - } - static _ALWAYS_INLINE_ double sinh(double p_x) { - - return ::sinh(p_x); - } + static _ALWAYS_INLINE_ double tan(double p_x) { return ::tan(p_x); } + static _ALWAYS_INLINE_ float tan(float p_x) { return ::tanf(p_x); } - static _ALWAYS_INLINE_ double cosh(double p_x) { - - return ::cosh(p_x); - } - - static _ALWAYS_INLINE_ double tanh(double p_x) { - - return ::tanh(p_x); - } + static _ALWAYS_INLINE_ double sinh(double p_x) { return ::sinh(p_x); } + static _ALWAYS_INLINE_ float sinh(float p_x) { return ::sinhf(p_x); } + static _ALWAYS_INLINE_ double cosh(double p_x) { return ::cosh(p_x); } + static _ALWAYS_INLINE_ float cosh(float p_x) { return ::coshf(p_x); } - static _ALWAYS_INLINE_ double asin(double p_x) { + static _ALWAYS_INLINE_ double tanh(double p_x) { return ::tanh(p_x); } + static _ALWAYS_INLINE_ float tanh(float p_x) { return ::tanhf(p_x); } - return ::asin(p_x); + static _ALWAYS_INLINE_ double asin(double p_x) { return ::asin(p_x); } + static _ALWAYS_INLINE_ float asin(float p_x) { return ::asinf(p_x); } - } + static _ALWAYS_INLINE_ double acos(double p_x) { return ::acos(p_x); } + static _ALWAYS_INLINE_ float acos(float p_x) { return ::acosf(p_x); } - static _ALWAYS_INLINE_ double acos(double p_x) { - - return ::acos(p_x); - } - - static _ALWAYS_INLINE_ double atan(double p_x) { - - return ::atan(p_x); - } + static _ALWAYS_INLINE_ double atan(double p_x) { return ::atan(p_x); } + static _ALWAYS_INLINE_ float atan(float p_x) { return ::atanf(p_x); } - static _ALWAYS_INLINE_ double atan2(double p_y, double p_x) { + static _ALWAYS_INLINE_ double atan2(double p_y, double p_x) { return ::atan2(p_y,p_x); } + static _ALWAYS_INLINE_ float atan2(float p_y, float p_x) { return ::atan2f(p_y,p_x); } - return ::atan2(p_y,p_x); + static _ALWAYS_INLINE_ double sqrt(double p_x) { return ::sqrt(p_x); } + static _ALWAYS_INLINE_ float sqrt(float p_x) { return ::sqrtf(p_x); } - } + static _ALWAYS_INLINE_ double fmod(double p_x,double p_y) { return ::fmod(p_x,p_y); } + static _ALWAYS_INLINE_ float fmod(float p_x,float p_y) { return ::fmodf(p_x,p_y); } - static _ALWAYS_INLINE_ double deg2rad(double p_y) { + static _ALWAYS_INLINE_ double floor(double p_x) { return ::floor(p_x); } + static _ALWAYS_INLINE_ float floor(float p_x) { return ::floorf(p_x); } - return p_y*Math_PI/180.0; - } + static _ALWAYS_INLINE_ double ceil(double p_x) { return ::ceil(p_x); } + static _ALWAYS_INLINE_ float ceil(float p_x) { return ::ceilf(p_x); } - static _ALWAYS_INLINE_ double rad2deg(double p_y) { + static _ALWAYS_INLINE_ double pow(double p_x, double p_y) { return ::pow(p_x,p_y); } + static _ALWAYS_INLINE_ float pow(float p_x, float p_y) { return ::powf(p_x,p_y); } - return p_y*180.0/Math_PI; - } + static _ALWAYS_INLINE_ double log(double p_x) { return ::log(p_x); } + static _ALWAYS_INLINE_ float log(float p_x) { return ::logf(p_x); } + static _ALWAYS_INLINE_ double exp(double p_x) { return ::exp(p_x); } + static _ALWAYS_INLINE_ float exp(float p_x) { return ::expf(p_x); } - static _ALWAYS_INLINE_ double sqrt(double p_x) { + static _ALWAYS_INLINE_ bool is_nan(double p_val) { return (p_val!=p_val); } + static _ALWAYS_INLINE_ bool is_nan(float p_val) { return (p_val!=p_val); } - return ::sqrt(p_x); + static _ALWAYS_INLINE_ bool is_inf(double p_val) { + #ifdef _MSC_VER + return !_finite(p_val); + #else + return isinf(p_val); + #endif } - - static _ALWAYS_INLINE_ double fmod(double p_x,double p_y) { - - return ::fmod(p_x,p_y); + + static _ALWAYS_INLINE_ bool is_inf(float p_val) { + #ifdef _MSC_VER + return !_finite(p_val); + #else + return isinf(p_val); + #endif } + + static _ALWAYS_INLINE_ double abs(double g) { return absd(g); } + static _ALWAYS_INLINE_ float abs(float g) { return absf(g); } + static _ALWAYS_INLINE_ int abs(int g) { return g > 0 ? g : -g; } - static _ALWAYS_INLINE_ double fposmod(double p_x,double p_y) { - - if (p_x>=0) { - - return fmod(p_x,p_y); - - } else { - - return p_y-fmod(-p_x,p_y); - } + static _ALWAYS_INLINE_ double fposmod(double p_x,double p_y) { return (p_x>=0) ? Math::fmod(p_x,p_y) : p_y-Math::fmod(-p_x,p_y); } + static _ALWAYS_INLINE_ float fposmod(float p_x,float p_y) { return (p_x>=0) ? Math::fmod(p_x,p_y) : p_y-Math::fmod(-p_x,p_y); } - } - static _ALWAYS_INLINE_ double floor(double p_x) { + static _ALWAYS_INLINE_ double deg2rad(double p_y) { return p_y*Math_PI/180.0; } + static _ALWAYS_INLINE_ float deg2rad(float p_y) { return p_y*Math_PI/180.0; } - return ::floor(p_x); - } + static _ALWAYS_INLINE_ double rad2deg(double p_y) { return p_y*180.0/Math_PI; } + static _ALWAYS_INLINE_ float rad2deg(float p_y) { return p_y*180.0/Math_PI; } - static _ALWAYS_INLINE_ double ceil(double p_x) { + static _ALWAYS_INLINE_ double lerp(double a, double b, double c) { return a+(b-a)*c; } + static _ALWAYS_INLINE_ float lerp(float a, float b, float c) { return a+(b-a)*c; } - return ::ceil(p_x); - } + static _ALWAYS_INLINE_ double linear2db(double p_linear) { return Math::log( p_linear ) * 8.6858896380650365530225783783321; } + static _ALWAYS_INLINE_ float linear2db(float p_linear) { return Math::log( p_linear ) * 8.6858896380650365530225783783321; } + static _ALWAYS_INLINE_ double db2linear(double p_db) { return Math::exp( p_db * 0.11512925464970228420089957273422 ); } + static _ALWAYS_INLINE_ float db2linear(float p_db) { return Math::exp( p_db * 0.11512925464970228420089957273422 ); } - static uint32_t rand_from_seed(uint64_t *seed); + static _ALWAYS_INLINE_ double round(double p_val) { return (p_val>=0) ? Math::floor(p_val+0.5) : -Math::floor(-p_val+0.5); } + static _ALWAYS_INLINE_ float round(float p_val) { return (p_val>=0) ? Math::floor(p_val+0.5) : -Math::floor(-p_val+0.5); } + // double only, as these functions are mainly used by the editor and not performance-critical, static double ease(double p_x, double p_c); static int step_decimals(double p_step); static double stepify(double p_value,double p_step); - static void seed(uint64_t x=0); - static void randomize(); - static uint32_t larger_prime(uint32_t p_val); static double dectime(double p_value,double p_amount, double p_step); + static uint32_t larger_prime(uint32_t p_val); - static inline double linear2db(double p_linear) { - - return Math::log( p_linear ) * 8.6858896380650365530225783783321; - } - - static inline double db2linear(double p_db) { - - return Math::exp( p_db * 0.11512925464970228420089957273422 ); - } - - static _ALWAYS_INLINE_ bool is_nan(double p_val) { - - return (p_val!=p_val); - } - - static _ALWAYS_INLINE_ bool is_inf(double p_val) { - - #ifdef _MSC_VER - return !_finite(p_val); - #else - return isinf(p_val); - #endif - - } - + static void seed(uint64_t x=0); + static void randomize(); + static uint32_t rand_from_seed(uint64_t *seed); static uint32_t rand(); - static double randf(); - - static double round(double p_val); + static _ALWAYS_INLINE_ double randf() { return (double)rand() / (double)Math::RANDOM_MAX; } + static _ALWAYS_INLINE_ float randd() { return (float)rand() / (float)Math::RANDOM_MAX; } static double random(double from, double to); + static float random(float from, float to); + static real_t random(int from, int to) { return (real_t)random((real_t)from, (real_t)to); } + - static _FORCE_INLINE_ bool isequal_approx(real_t a, real_t b) { + static _ALWAYS_INLINE_ bool isequal_approx(real_t a, real_t b) { // TODO: Comparing floats for approximate-equality is non-trivial. // Using epsilon should cover the typical cases in Godot (where a == b is used to compare two reals), such as matrix and vector comparison operators. // A proper implementation in terms of ULPs should eventually replace the contents of this function. @@ -203,18 +177,7 @@ public: } - static _FORCE_INLINE_ real_t abs(real_t g) { - -#ifdef REAL_T_IS_DOUBLE - - return absd(g); -#else - - return absf(g); -#endif - } - - static _FORCE_INLINE_ float absf(float g) { + static _ALWAYS_INLINE_ float absf(float g) { union { float f; @@ -226,7 +189,7 @@ public: return u.f; } - static _FORCE_INLINE_ double absd(double g) { + static _ALWAYS_INLINE_ double absd(double g) { union { double d; @@ -238,12 +201,12 @@ public: } //this function should be as fast as possible and rounding mode should not matter - static _FORCE_INLINE_ int fast_ftoi(float a) { + static _ALWAYS_INLINE_ int fast_ftoi(float a) { static int b; #if (defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0603) || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP // windows 8 phone? - b = (int)((a>0.0f) ? (a + 0.5f):(a -0.5f)); + b = (int)((a>0.0) ? (a + 0.5):(a -0.5)); #elif defined(_MSC_VER) && _MSC_VER < 1800 __asm fld a @@ -266,23 +229,16 @@ public: #if defined(__GNUC__) - static _FORCE_INLINE_ int64_t dtoll(double p_double) { return (int64_t)p_double; } ///@TODO OPTIMIZE + static _ALWAYS_INLINE_ int64_t dtoll(double p_double) { return (int64_t)p_double; } ///@TODO OPTIMIZE + static _ALWAYS_INLINE_ int64_t dtoll(float p_float) { return (int64_t)p_float; } ///@TODO OPTIMIZE and rename #else - static _FORCE_INLINE_ int64_t dtoll(double p_double) { return (int64_t)p_double; } ///@TODO OPTIMIZE + static _ALWAYS_INLINE_ int64_t dtoll(double p_double) { return (int64_t)p_double; } ///@TODO OPTIMIZE + static _ALWAYS_INLINE_ int64_t dtoll(float p_float) { return (int64_t)p_float; } ///@TODO OPTIMIZE and rename #endif - static _FORCE_INLINE_ float lerp(float a, float b, float c) { - - return a+(b-a)*c; - } - - static double pow(double x, double y); - static double log(double x); - static double exp(double x); - - static _FORCE_INLINE_ uint32_t halfbits_to_floatbits(uint16_t h) + static _ALWAYS_INLINE_ uint32_t halfbits_to_floatbits(uint16_t h) { uint16_t h_exp, h_sig; uint32_t f_sgn, f_exp, f_sig; @@ -314,7 +270,7 @@ public: } } - static _FORCE_INLINE_ float halfptr_to_float(const uint16_t *h) { + static _ALWAYS_INLINE_ float halfptr_to_float(const uint16_t *h) { union { uint32_t u32; @@ -325,7 +281,7 @@ public: return u.f32; } - static _FORCE_INLINE_ uint16_t make_half_float(float f) { + static _ALWAYS_INLINE_ uint16_t make_half_float(float f) { union { float fv; |