summaryrefslogtreecommitdiffstats
path: root/core/math/math_funcs.h
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2017-01-20 19:24:49 -0300
committerGitHub <noreply@github.com>2017-01-20 19:24:49 -0300
commitee0f53df52d88ca57079579f3f3e943e7e40f53a (patch)
treefcf670f1e8aec411c6deaf97e9fc77bf5c195f31 /core/math/math_funcs.h
parent72a02555850016ab792cf498c5370983d3b72832 (diff)
parent6f4f9aa6ded6da027c84cc466c767334dc3d3362 (diff)
downloadredot-engine-ee0f53df52d88ca57079579f3f3e943e7e40f53a.tar.gz
Merge pull request #7528 from tagcup/real_t_float_fixes
Use real_t rather than float or double in generic functions (core/mat…
Diffstat (limited to 'core/math/math_funcs.h')
-rw-r--r--core/math/math_funcs.h224
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;