diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/math/math_funcs.cpp | 15 | ||||
-rw-r--r-- | core/math/math_funcs.h | 5 | ||||
-rw-r--r-- | core/math/matrix3.cpp | 25 |
3 files changed, 31 insertions, 14 deletions
diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp index 6fb688f16b..64e01e5841 100644 --- a/core/math/math_funcs.cpp +++ b/core/math/math_funcs.cpp @@ -176,3 +176,18 @@ float Math::random(float from, float to) { float ret = (float)r / (float)RANDOM_MAX; return (ret) * (to - from) + from; } + +int Math::wrapi(int value, int min, int max) { + --max; + int rng = max - min + 1; + value = ((value - min) % rng); + if (value < 0) + return max + 1 + value; + else + return min + value; +} + +float Math::wrapf(float value, float min, float max) { + float rng = max - min; + return min + (value - min) - (rng * floor((value - min) / rng)); +} diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 65b2ffb0df..7715e5d6e5 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -207,6 +207,9 @@ public: 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); } + static int wrapi(int value, int min, int max); + static float wrapf(float value, float min, float max); + // 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); @@ -268,7 +271,7 @@ public: #elif defined(_MSC_VER) && _MSC_VER < 1800 __asm fld a __asm fistp b -/*#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) + /*#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) // use AT&T inline assembly style, document that // we use memory as output (=m) and input (m) __asm__ __volatile__ ( diff --git a/core/math/matrix3.cpp b/core/math/matrix3.cpp index 85421c074b..ab3bca79ae 100644 --- a/core/math/matrix3.cpp +++ b/core/math/matrix3.cpp @@ -279,7 +279,7 @@ Vector3 Basis::get_signed_scale() const { // Decomposes a Basis into a rotation-reflection matrix (an element of the group O(3)) and a positive scaling matrix as B = O.S. // Returns the rotation-reflection matrix via reference argument, and scaling information is returned as a Vector3. -// This (internal) function is too specıfıc and named too ugly to expose to users, and probably there's no need to do so. +// This (internal) function is too specific and named too ugly to expose to users, and probably there's no need to do so. Vector3 Basis::rotref_posscale_decomposition(Basis &rotref) const { #ifdef MATH_CHECKS ERR_FAIL_COND_V(determinant() == 0, Vector3()); @@ -371,31 +371,30 @@ Vector3 Basis::get_euler_xyz() const { #ifdef MATH_CHECKS ERR_FAIL_COND_V(is_rotation() == false, euler); #endif - euler.y = Math::asin(elements[0][2]); - if (euler.y < Math_PI * 0.5) { - if (euler.y > -Math_PI * 0.5) { + real_t sy = elements[0][2]; + if (sy < 1.0) { + if (sy > -1.0) { // is this a pure Y rotation? if (elements[1][0] == 0.0 && elements[0][1] == 0.0 && elements[1][2] == 0 && elements[2][1] == 0 && elements[1][1] == 1) { - // return the simplest form + // return the simplest form (human friendlier in editor and scripts) euler.x = 0; euler.y = atan2(elements[0][2], elements[0][0]); euler.z = 0; } else { euler.x = Math::atan2(-elements[1][2], elements[2][2]); + euler.y = Math::asin(sy); euler.z = Math::atan2(-elements[0][1], elements[0][0]); } - } else { - real_t r = Math::atan2(elements[1][0], elements[1][1]); + euler.x = -Math::atan2(elements[0][1], elements[1][1]); + euler.y = -Math_PI / 2.0; euler.z = 0.0; - euler.x = euler.z - r; } } else { - real_t r = Math::atan2(elements[0][1], elements[1][1]); - euler.z = 0; - euler.x = r - euler.z; + euler.x = Math::atan2(elements[0][1], elements[1][1]); + euler.y = Math_PI / 2.0; + euler.z = 0.0; } - return euler; } @@ -445,7 +444,7 @@ Vector3 Basis::get_euler_yxz() const { if (m12 > -1) { // is this a pure X rotation? if (elements[1][0] == 0 && elements[0][1] == 0 && elements[0][2] == 0 && elements[2][0] == 0 && elements[0][0] == 1) { - // return the simplest form + // return the simplest form (human friendlier in editor and scripts) euler.x = atan2(-m12, elements[1][1]); euler.y = 0; euler.z = 0; |