diff options
Diffstat (limited to 'core/math')
-rw-r--r-- | core/math/audio_frame.h | 2 | ||||
-rw-r--r-- | core/math/basis.cpp | 21 | ||||
-rw-r--r-- | core/math/basis.h | 23 | ||||
-rw-r--r-- | core/math/camera_matrix.cpp | 5 | ||||
-rw-r--r-- | core/math/camera_matrix.h | 2 | ||||
-rw-r--r-- | core/math/expression.cpp | 22 | ||||
-rw-r--r-- | core/math/expression.h | 2 | ||||
-rw-r--r-- | core/math/math_funcs.h | 31 | ||||
-rw-r--r-- | core/math/quat.h | 6 | ||||
-rw-r--r-- | core/math/random_pcg.h | 5 | ||||
-rw-r--r-- | core/math/vector2.h | 38 | ||||
-rw-r--r-- | core/math/vector3.h | 16 |
12 files changed, 88 insertions, 85 deletions
diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h index 91f533eafb..43d4a63cd3 100644 --- a/core/math/audio_frame.h +++ b/core/math/audio_frame.h @@ -121,7 +121,7 @@ struct AudioFrame { r = p_frame.r; } - _ALWAYS_INLINE_ AudioFrame operator=(const AudioFrame &p_frame) { + _ALWAYS_INLINE_ AudioFrame &operator=(const AudioFrame &p_frame) { l = p_frame.l; r = p_frame.r; return *this; diff --git a/core/math/basis.cpp b/core/math/basis.cpp index dd38e25bb1..a712ae7e3e 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -113,19 +113,22 @@ bool Basis::is_rotation() const { return Math::is_equal_approx(determinant(), 1, UNIT_EPSILON) && is_orthogonal(); } +#ifdef MATH_CHECKS +// This method is only used once, in diagonalize. If it's desired elsewhere, feel free to remove the #ifdef. bool Basis::is_symmetric() const { - if (!Math::is_equal_approx_ratio(elements[0][1], elements[1][0], UNIT_EPSILON)) { + if (!Math::is_equal_approx(elements[0][1], elements[1][0])) { return false; } - if (!Math::is_equal_approx_ratio(elements[0][2], elements[2][0], UNIT_EPSILON)) { + if (!Math::is_equal_approx(elements[0][2], elements[2][0])) { return false; } - if (!Math::is_equal_approx_ratio(elements[1][2], elements[2][1], UNIT_EPSILON)) { + if (!Math::is_equal_approx(elements[1][2], elements[2][1])) { return false; } return true; } +#endif Basis Basis::diagonalize() { //NOTE: only implemented for symmetric matrices @@ -737,18 +740,6 @@ bool Basis::is_equal_approx(const Basis &p_basis) const { return elements[0].is_equal_approx(p_basis.elements[0]) && elements[1].is_equal_approx(p_basis.elements[1]) && elements[2].is_equal_approx(p_basis.elements[2]); } -bool Basis::is_equal_approx_ratio(const Basis &a, const Basis &b, real_t p_epsilon) const { - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if (!Math::is_equal_approx_ratio(a.elements[i][j], b.elements[i][j], p_epsilon)) { - return false; - } - } - } - - return true; -} - bool Basis::operator==(const Basis &p_matrix) const { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { diff --git a/core/math/basis.h b/core/math/basis.h index 985fb0e44f..2584f1ff48 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -36,7 +36,11 @@ class Basis { public: - Vector3 elements[3]; + Vector3 elements[3] = { + Vector3(1, 0, 0), + Vector3(0, 1, 0), + Vector3(0, 0, 1) + }; _FORCE_INLINE_ const Vector3 &operator[](int axis) const { return elements[axis]; @@ -142,9 +146,6 @@ public: } bool is_equal_approx(const Basis &p_basis) const; - // TODO: Break compatibility in 4.0 by getting rid of this so that it's only an instance method. See also TODO in variant_call.cpp - bool is_equal_approx(const Basis &a, const Basis &b) const { return a.is_equal_approx(b); } - bool is_equal_approx_ratio(const Basis &a, const Basis &b, real_t p_epsilon = UNIT_EPSILON) const; bool operator==(const Basis &p_matrix) const; bool operator!=(const Basis &p_matrix) const; @@ -234,7 +235,9 @@ public: void orthonormalize(); Basis orthonormalized() const; +#ifdef MATH_CHECKS bool is_symmetric() const; +#endif Basis diagonalize(); operator Quat() const { return get_quat(); } @@ -254,17 +257,7 @@ public: elements[2] = row2; } - _FORCE_INLINE_ Basis() { - elements[0][0] = 1; - elements[0][1] = 0; - elements[0][2] = 0; - elements[1][0] = 0; - elements[1][1] = 1; - elements[1][2] = 0; - elements[2][0] = 0; - elements[2][1] = 0; - elements[2][2] = 1; - } + _FORCE_INLINE_ Basis() {} }; _FORCE_INLINE_ void Basis::operator*=(const Basis &p_matrix) { diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index 22ab83f358..c154d57a13 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -278,7 +278,7 @@ Vector2 CameraMatrix::get_viewport_half_extents() const { return Vector2(res.x, res.y); } -void CameraMatrix::get_far_plane_size(real_t &r_width, real_t &r_height) const { +Vector2 CameraMatrix::get_far_plane_half_extents() const { const real_t *matrix = (const real_t *)this->matrix; ///////--- Far Plane ---/////// Plane far_plane = Plane(matrix[3] - matrix[2], @@ -303,8 +303,7 @@ void CameraMatrix::get_far_plane_size(real_t &r_width, real_t &r_height) const { Vector3 res; far_plane.intersect_3(right_plane, top_plane, &res); - r_width = res.x; - r_height = res.y; + return Vector2(res.x, res.y); } bool CameraMatrix::get_endpoints(const Transform &p_transform, Vector3 *p_8points) const { diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h index 49fdecae02..c5cdd98377 100644 --- a/core/math/camera_matrix.h +++ b/core/math/camera_matrix.h @@ -74,7 +74,7 @@ struct CameraMatrix { bool get_endpoints(const Transform &p_transform, Vector3 *p_8points) const; Vector2 get_viewport_half_extents() const; - void get_far_plane_size(real_t &r_width, real_t &r_height) const; + Vector2 get_far_plane_half_extents() const; void invert(); CameraMatrix inverse() const; diff --git a/core/math/expression.cpp b/core/math/expression.cpp index 13a49feb6b..1040f9e0e4 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -596,7 +596,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant } break; case TEXT_CHAR: { - CharType result[2] = { *p_inputs[0], 0 }; + char32_t result[2] = { *p_inputs[0], 0 }; *r_return = String(result); @@ -739,7 +739,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant //////// -static bool _is_number(CharType c) { +static bool _is_number(char32_t c) { return (c >= '0' && c <= '9'); } @@ -747,7 +747,7 @@ Error Expression::_get_token(Token &r_token) { while (true) { #define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++]) - CharType cchar = GET_CHAR(); + char32_t cchar = GET_CHAR(); switch (cchar) { case 0: { @@ -900,7 +900,7 @@ Error Expression::_get_token(Token &r_token) { case '"': { String str; while (true) { - CharType ch = GET_CHAR(); + char32_t ch = GET_CHAR(); if (ch == 0) { _set_error("Unterminated String"); @@ -912,13 +912,13 @@ Error Expression::_get_token(Token &r_token) { } else if (ch == '\\') { //escaped characters... - CharType next = GET_CHAR(); + char32_t next = GET_CHAR(); if (next == 0) { _set_error("Unterminated String"); r_token.type = TK_ERROR; return ERR_PARSE_ERROR; } - CharType res = 0; + char32_t res = 0; switch (next) { case 'b': @@ -939,7 +939,7 @@ Error Expression::_get_token(Token &r_token) { case 'u': { // hex number for (int j = 0; j < 4; j++) { - CharType c = GET_CHAR(); + char32_t c = GET_CHAR(); if (c == 0) { _set_error("Unterminated String"); @@ -951,7 +951,7 @@ Error Expression::_get_token(Token &r_token) { r_token.type = TK_ERROR; return ERR_PARSE_ERROR; } - CharType v; + char32_t v; if (_is_number(c)) { v = c - '0'; } else if (c >= 'a' && c <= 'f') { @@ -992,7 +992,7 @@ Error Expression::_get_token(Token &r_token) { break; } - CharType next_char = (str_ofs >= expression.length()) ? 0 : expression[str_ofs]; + char32_t next_char = (str_ofs >= expression.length()) ? 0 : expression[str_ofs]; if (_is_number(cchar) || (cchar == '.' && _is_number(next_char))) { //a number @@ -1004,7 +1004,7 @@ Error Expression::_get_token(Token &r_token) { #define READING_DONE 4 int reading = READING_INT; - CharType c = cchar; + char32_t c = cchar; bool exp_sign = false; bool exp_beg = false; bool is_float = false; @@ -1062,7 +1062,7 @@ Error Expression::_get_token(Token &r_token) { r_token.type = TK_CONSTANT; if (is_float) { - r_token.value = num.to_double(); + r_token.value = num.to_float(); } else { r_token.value = num.to_int(); } diff --git a/core/math/expression.h b/core/math/expression.h index 59a9a2f4ed..f2cfe6b1a6 100644 --- a/core/math/expression.h +++ b/core/math/expression.h @@ -343,7 +343,7 @@ protected: public: Error parse(const String &p_expression, const Vector<String> &p_input_names = Vector<String>()); - Variant execute(Array p_inputs, Object *p_base = nullptr, bool p_show_error = true); + Variant execute(Array p_inputs = Array(), Object *p_base = nullptr, bool p_show_error = true); bool has_execute_failed() const; String get_error_text() const; diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 7a9fd60e23..f83ee44f4a 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -46,7 +46,8 @@ class Math { public: Math() {} // useless to instance - static const uint64_t RANDOM_MAX = 0xFFFFFFFF; + // Not using 'RANDOM_MAX' to avoid conflict with system headers on some OSes (at least NetBSD). + static const uint64_t RANDOM_32BIT_MAX = 0xFFFFFFFF; static _ALWAYS_INLINE_ double sin(double p_x) { return ::sin(p_x); } static _ALWAYS_INLINE_ float sin(float p_x) { return ::sinf(p_x); } @@ -231,19 +232,19 @@ public: static _ALWAYS_INLINE_ double range_lerp(double p_value, double p_istart, double p_istop, double p_ostart, double p_ostop) { return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value)); } static _ALWAYS_INLINE_ float range_lerp(float p_value, float p_istart, float p_istop, float p_ostart, float p_ostop) { return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value)); } - static _ALWAYS_INLINE_ double smoothstep(double p_from, double p_to, double p_weight) { + static _ALWAYS_INLINE_ double smoothstep(double p_from, double p_to, double p_s) { if (is_equal_approx(p_from, p_to)) { return p_from; } - double x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0, 1.0); - return x * x * (3.0 - 2.0 * x); + double s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0, 1.0); + return s * s * (3.0 - 2.0 * s); } - static _ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_weight) { + static _ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_s) { if (is_equal_approx(p_from, p_to)) { return p_from; } - float x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0f, 1.0f); - return x * x * (3.0f - 2.0f * x); + float s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0f, 1.0f); + return s * s * (3.0f - 2.0f * s); } static _ALWAYS_INLINE_ double move_toward(double p_from, double p_to, double p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SGN(p_to - p_from) * p_delta; } static _ALWAYS_INLINE_ float move_toward(float p_from, float p_to, float p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SGN(p_to - p_from) * p_delta; } @@ -283,25 +284,13 @@ public: static void randomize(); static uint32_t rand_from_seed(uint64_t *seed); static uint32_t rand(); - static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_MAX; } - static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_MAX; } + static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_32BIT_MAX; } + static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_32BIT_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 _ALWAYS_INLINE_ bool is_equal_approx_ratio(real_t a, real_t b, real_t epsilon = CMP_EPSILON, real_t min_epsilon = CMP_EPSILON) { - // this is an approximate way to check that numbers are close, as a ratio of their average size - // helps compare approximate numbers that may be very big or very small - real_t diff = abs(a - b); - if (diff == 0.0 || diff < min_epsilon) { - return true; - } - real_t avg_size = (abs(a) + abs(b)) / 2.0; - diff /= avg_size; - return diff < epsilon; - } - static _ALWAYS_INLINE_ bool is_equal_approx(real_t a, real_t b) { // Check for exact equality first, required to handle "infinity" values. if (a == b) { diff --git a/core/math/quat.h b/core/math/quat.h index 64d0f00912..3152b7d233 100644 --- a/core/math/quat.h +++ b/core/math/quat.h @@ -130,7 +130,7 @@ public: w(q.w) { } - Quat operator=(const Quat &q) { + Quat &operator=(const Quat &q) { x = q.x; y = q.y; z = q.z; @@ -224,4 +224,8 @@ bool Quat::operator!=(const Quat &p_quat) const { return x != p_quat.x || y != p_quat.y || z != p_quat.z || w != p_quat.w; } +_FORCE_INLINE_ Quat operator*(const real_t &p_real, const Quat &p_quat) { + return p_quat * p_real; +} + #endif // QUAT_H diff --git a/core/math/random_pcg.h b/core/math/random_pcg.h index 8fd5a056fa..09b13ab74d 100644 --- a/core/math/random_pcg.h +++ b/core/math/random_pcg.h @@ -31,12 +31,12 @@ #ifndef RANDOM_PCG_H #define RANDOM_PCG_H -#include <math.h> - #include "core/math/math_defs.h" #include "thirdparty/misc/pcg.h" +#include <math.h> + #if defined(__GNUC__) #define CLZ32(x) __builtin_clz(x) #elif defined(_MSC_VER) @@ -67,7 +67,6 @@ class RandomPCG { public: static const uint64_t DEFAULT_SEED = 12047754176567800795U; static const uint64_t DEFAULT_INC = PCG_DEFAULT_INC_64; - static const uint64_t RANDOM_MAX = 0xFFFFFFFF; RandomPCG(uint64_t p_seed = DEFAULT_SEED, uint64_t p_inc = DEFAULT_INC); diff --git a/core/math/vector2.h b/core/math/vector2.h index 8a08d3bf64..f41bcc15bc 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -114,10 +114,10 @@ struct Vector2 { bool operator==(const Vector2 &p_vec2) const; bool operator!=(const Vector2 &p_vec2) const; - bool operator<(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); } - bool operator>(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); } - bool operator<=(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y <= p_vec2.y) : (x < p_vec2.x); } - bool operator>=(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y >= p_vec2.y) : (x > p_vec2.x); } + bool operator<(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y < p_vec2.y) : (x < p_vec2.x); } + bool operator>(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y > p_vec2.y) : (x > p_vec2.x); } + bool operator<=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); } + bool operator>=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); } real_t angle() const; @@ -150,7 +150,19 @@ _FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2 &p_vec) return p_vec - *this * (dot(p_vec) - p_d); } -_FORCE_INLINE_ Vector2 operator*(real_t p_scalar, const Vector2 &p_vec) { +_FORCE_INLINE_ Vector2 operator*(float p_scalar, const Vector2 &p_vec) { + return p_vec * p_scalar; +} + +_FORCE_INLINE_ Vector2 operator*(double p_scalar, const Vector2 &p_vec) { + return p_vec * p_scalar; +} + +_FORCE_INLINE_ Vector2 operator*(int32_t p_scalar, const Vector2 &p_vec) { + return p_vec * p_scalar; +} + +_FORCE_INLINE_ Vector2 operator*(int64_t p_scalar, const Vector2 &p_vec) { return p_vec * p_scalar; } @@ -304,6 +316,22 @@ struct Vector2i { } }; +_FORCE_INLINE_ Vector2i operator*(const int32_t &p_scalar, const Vector2i &p_vector) { + return p_vector * p_scalar; +} + +_FORCE_INLINE_ Vector2i operator*(const int64_t &p_scalar, const Vector2i &p_vector) { + return p_vector * p_scalar; +} + +_FORCE_INLINE_ Vector2i operator*(const float &p_scalar, const Vector2i &p_vector) { + return p_vector * p_scalar; +} + +_FORCE_INLINE_ Vector2i operator*(const double &p_scalar, const Vector2i &p_vector) { + return p_vector * p_scalar; +} + typedef Vector2i Size2i; typedef Vector2i Point2i; diff --git a/core/math/vector3.h b/core/math/vector3.h index 0bc1a467f2..5370b297f1 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -322,8 +322,8 @@ bool Vector3::operator!=(const Vector3 &p_v) const { } bool Vector3::operator<(const Vector3 &p_v) const { - if (Math::is_equal_approx(x, p_v.x)) { - if (Math::is_equal_approx(y, p_v.y)) { + if (x == p_v.x) { + if (y == p_v.y) { return z < p_v.z; } else { return y < p_v.y; @@ -334,8 +334,8 @@ bool Vector3::operator<(const Vector3 &p_v) const { } bool Vector3::operator>(const Vector3 &p_v) const { - if (Math::is_equal_approx(x, p_v.x)) { - if (Math::is_equal_approx(y, p_v.y)) { + if (x == p_v.x) { + if (y == p_v.y) { return z > p_v.z; } else { return y > p_v.y; @@ -346,8 +346,8 @@ bool Vector3::operator>(const Vector3 &p_v) const { } bool Vector3::operator<=(const Vector3 &p_v) const { - if (Math::is_equal_approx(x, p_v.x)) { - if (Math::is_equal_approx(y, p_v.y)) { + if (x == p_v.x) { + if (y == p_v.y) { return z <= p_v.z; } else { return y < p_v.y; @@ -358,8 +358,8 @@ bool Vector3::operator<=(const Vector3 &p_v) const { } bool Vector3::operator>=(const Vector3 &p_v) const { - if (Math::is_equal_approx(x, p_v.x)) { - if (Math::is_equal_approx(y, p_v.y)) { + if (x == p_v.x) { + if (y == p_v.y) { return z >= p_v.z; } else { return y > p_v.y; |