diff options
Diffstat (limited to 'core/math')
45 files changed, 1096 insertions, 828 deletions
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index ce2435216b..14057b96be 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -32,7 +32,6 @@ #include "core/math/geometry_3d.h" #include "core/object/script_language.h" -#include "scene/scene_string_names.h" int AStar::get_available_point_id() const { if (points.has(last_free_id)) { diff --git a/core/math/aabb.h b/core/math/aabb.h index 3d19410ddf..e88ba33531 100644 --- a/core/math/aabb.h +++ b/core/math/aabb.h @@ -36,13 +36,13 @@ #include "core/math/vector3.h" /** - * AABB / AABB (Axis Aligned Bounding Box) - * This is implemented by a point (position) and the box size + * AABB (Axis Aligned Bounding Box) + * This is implemented by a point (position) and the box size. */ + class Variant; -class _NO_DISCARD_ AABB { -public: +struct _NO_DISCARD_ AABB { Vector3 position; Vector3 size; @@ -119,7 +119,7 @@ public: } _FORCE_INLINE_ Vector3 get_center() const { - return position + (size * 0.5); + return position + (size * 0.5f); } operator String() const; @@ -208,7 +208,7 @@ inline bool AABB::encloses(const AABB &p_aabb) const { } Vector3 AABB::get_support(const Vector3 &p_normal) const { - Vector3 half_extents = size * 0.5; + Vector3 half_extents = size * 0.5f; Vector3 ofs = position + half_extents; return Vector3( @@ -242,7 +242,7 @@ Vector3 AABB::get_endpoint(int p_point) const { } bool AABB::intersects_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count) const { - Vector3 half_extents = size * 0.5; + Vector3 half_extents = size * 0.5f; Vector3 ofs = position + half_extents; for (int i = 0; i < p_plane_count; i++) { @@ -284,7 +284,7 @@ bool AABB::intersects_convex_shape(const Plane *p_planes, int p_plane_count, con } bool AABB::inside_convex_shape(const Plane *p_planes, int p_plane_count) const { - Vector3 half_extents = size * 0.5; + Vector3 half_extents = size * 0.5f; Vector3 ofs = position + half_extents; for (int i = 0; i < p_plane_count; i++) { @@ -364,7 +364,7 @@ inline void AABB::expand_to(const Vector3 &p_vector) { } void AABB::project_range_in_plane(const Plane &p_plane, real_t &r_min, real_t &r_max) const { - Vector3 half_extents(size.x * 0.5, size.y * 0.5, size.z * 0.5); + Vector3 half_extents(size.x * 0.5f, size.y * 0.5f, size.z * 0.5f); Vector3 center(position.x + half_extents.x, position.y + half_extents.y, position.z + half_extents.z); real_t length = p_plane.normal.abs().dot(half_extents); @@ -407,9 +407,9 @@ bool AABB::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size."); } #endif - real_t divx = 1.0 / p_dir.x; - real_t divy = 1.0 / p_dir.y; - real_t divz = 1.0 / p_dir.z; + real_t divx = 1.0f / p_dir.x; + real_t divy = 1.0f / p_dir.y; + real_t divz = 1.0f / p_dir.z; Vector3 upbound = position + size; real_t tmin, tmax, tymin, tymax, tzmin, tzmax; @@ -459,9 +459,9 @@ void AABB::grow_by(real_t p_amount) { position.x -= p_amount; position.y -= p_amount; position.z -= p_amount; - size.x += 2.0 * p_amount; - size.y += 2.0 * p_amount; - size.z += 2.0 * p_amount; + size.x += 2.0f * p_amount; + size.y += 2.0f * p_amount; + size.z += 2.0f * p_amount; } void AABB::quantize(real_t p_unit) { diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h index 94fc3de2b1..8b244e9fe4 100644 --- a/core/math/audio_frame.h +++ b/core/math/audio_frame.h @@ -140,4 +140,16 @@ struct AudioFrame { _ALWAYS_INLINE_ AudioFrame() {} }; +_ALWAYS_INLINE_ AudioFrame operator*(float p_scalar, const AudioFrame &p_frame) { + return AudioFrame(p_frame.l * p_scalar, p_frame.r * p_scalar); +} + +_ALWAYS_INLINE_ AudioFrame operator*(int32_t p_scalar, const AudioFrame &p_frame) { + return AudioFrame(p_frame.l * p_scalar, p_frame.r * p_scalar); +} + +_ALWAYS_INLINE_ AudioFrame operator*(int64_t p_scalar, const AudioFrame &p_frame) { + return AudioFrame(p_frame.l * p_scalar, p_frame.r * p_scalar); +} + #endif // AUDIO_FRAME_H diff --git a/core/math/basis.cpp b/core/math/basis.cpp index a9b4651664..84f9d12bb1 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -37,16 +37,16 @@ (elements[row1][col1] * elements[row2][col2] - elements[row1][col2] * elements[row2][col1]) void Basis::from_z(const Vector3 &p_z) { - if (Math::abs(p_z.z) > Math_SQRT12) { + if (Math::abs(p_z.z) > (real_t)Math_SQRT12) { // choose p in y-z plane real_t a = p_z[1] * p_z[1] + p_z[2] * p_z[2]; - real_t k = 1.0 / Math::sqrt(a); + real_t k = 1.0f / Math::sqrt(a); elements[0] = Vector3(0, -p_z[2] * k, p_z[1] * k); elements[1] = Vector3(a * k, -p_z[0] * elements[0][2], p_z[0] * elements[0][1]); } else { // choose p in x-y plane real_t a = p_z.x * p_z.x + p_z.y * p_z.y; - real_t k = 1.0 / Math::sqrt(a); + real_t k = 1.0f / Math::sqrt(a); elements[0] = Vector3(-p_z.y * k, p_z.x * k, 0); elements[1] = Vector3(-p_z.z * elements[0].y, p_z.z * elements[0].x, a * k); } @@ -63,7 +63,7 @@ void Basis::invert() { #ifdef MATH_CHECKS ERR_FAIL_COND(det == 0); #endif - real_t s = 1.0 / det; + real_t s = 1.0f / det; set(co[0] * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s, co[1] * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s, @@ -153,7 +153,7 @@ Basis Basis::diagonalize() { int ite = 0; Basis acc_rot; - while (off_matrix_norm_2 > CMP_EPSILON2 && ite++ < ite_max) { + while (off_matrix_norm_2 > (real_t)CMP_EPSILON2 && ite++ < ite_max) { real_t el01_2 = elements[0][1] * elements[0][1]; real_t el02_2 = elements[0][2] * elements[0][2]; real_t el12_2 = elements[1][2] * elements[1][2]; @@ -182,7 +182,7 @@ Basis Basis::diagonalize() { if (Math::is_equal_approx(elements[j][j], elements[i][i])) { angle = Math_PI / 4; } else { - angle = 0.5 * Math::atan(2 * elements[i][j] / (elements[j][j] - elements[i][i])); + angle = 0.5f * Math::atan(2 * elements[i][j] / (elements[j][j] - elements[i][i])); } // Compute the rotation matrix @@ -268,11 +268,11 @@ Basis Basis::scaled_orthogonal(const Vector3 &p_scale) const { } float Basis::get_uniform_scale() const { - return (elements[0].length() + elements[1].length() + elements[2].length()) / 3.0; + return (elements[0].length() + elements[1].length() + elements[2].length()) / 3.0f; } void Basis::make_scale_uniform() { - float l = (elements[0].length() + elements[1].length() + elements[2].length()) / 3.0; + float l = (elements[0].length() + elements[1].length() + elements[2].length()) / 3.0f; for (int i = 0; i < 3; i++) { elements[i].normalize(); elements[i] *= l; @@ -415,7 +415,7 @@ void Basis::rotate_to_align(Vector3 p_start_direction, Vector3 p_end_direction) const Vector3 axis = p_start_direction.cross(p_end_direction).normalized(); if (axis.length_squared() != 0) { real_t dot = p_start_direction.dot(p_end_direction); - dot = CLAMP(dot, -1.0, 1.0); + dot = CLAMP(dot, -1.0f, 1.0f); const real_t angle_rads = Math::acos(dot); set_axis_angle(axis, angle_rads); } @@ -463,10 +463,10 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { Vector3 euler; real_t sy = elements[0][2]; - if (sy < (1.0 - CMP_EPSILON)) { - if (sy > -(1.0 - CMP_EPSILON)) { + if (sy < (1.0f - (real_t)CMP_EPSILON)) { + if (sy > -(1.0f - (real_t)CMP_EPSILON)) { // 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) { + if (elements[1][0] == 0 && elements[0][1] == 0 && elements[1][2] == 0 && elements[2][1] == 0 && elements[1][1] == 1) { // return the simplest form (human friendlier in editor and scripts) euler.x = 0; euler.y = atan2(elements[0][2], elements[0][0]); @@ -478,13 +478,13 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { } } else { euler.x = Math::atan2(elements[2][1], elements[1][1]); - euler.y = -Math_PI / 2.0; - euler.z = 0.0; + euler.y = -Math_PI / 2.0f; + euler.z = 0.0f; } } else { euler.x = Math::atan2(elements[2][1], elements[1][1]); - euler.y = Math_PI / 2.0; - euler.z = 0.0; + euler.y = Math_PI / 2.0f; + euler.z = 0.0f; } return euler; } break; @@ -498,22 +498,22 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { Vector3 euler; real_t sz = elements[0][1]; - if (sz < (1.0 - CMP_EPSILON)) { - if (sz > -(1.0 - CMP_EPSILON)) { + if (sz < (1.0f - (real_t)CMP_EPSILON)) { + if (sz > -(1.0f - (real_t)CMP_EPSILON)) { euler.x = Math::atan2(elements[2][1], elements[1][1]); euler.y = Math::atan2(elements[0][2], elements[0][0]); euler.z = Math::asin(-sz); } else { // It's -1 euler.x = -Math::atan2(elements[1][2], elements[2][2]); - euler.y = 0.0; - euler.z = Math_PI / 2.0; + euler.y = 0.0f; + euler.z = Math_PI / 2.0f; } } else { // It's 1 euler.x = -Math::atan2(elements[1][2], elements[2][2]); - euler.y = 0.0; - euler.z = -Math_PI / 2.0; + euler.y = 0.0f; + euler.z = -Math_PI / 2.0f; } return euler; } break; @@ -529,8 +529,8 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { real_t m12 = elements[1][2]; - if (m12 < (1 - CMP_EPSILON)) { - if (m12 > -(1 - CMP_EPSILON)) { + if (m12 < (1 - (real_t)CMP_EPSILON)) { + if (m12 > -(1 - (real_t)CMP_EPSILON)) { // 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 (human friendlier in editor and scripts) @@ -543,12 +543,12 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { euler.z = atan2(elements[1][0], elements[1][1]); } } else { // m12 == -1 - euler.x = Math_PI * 0.5; + euler.x = Math_PI * 0.5f; euler.y = atan2(elements[0][1], elements[0][0]); euler.z = 0; } } else { // m12 == 1 - euler.x = -Math_PI * 0.5; + euler.x = -Math_PI * 0.5f; euler.y = -atan2(elements[0][1], elements[0][0]); euler.z = 0; } @@ -565,22 +565,22 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { Vector3 euler; real_t sz = elements[1][0]; - if (sz < (1.0 - CMP_EPSILON)) { - if (sz > -(1.0 - CMP_EPSILON)) { + if (sz < (1.0f - (real_t)CMP_EPSILON)) { + if (sz > -(1.0f - (real_t)CMP_EPSILON)) { euler.x = Math::atan2(-elements[1][2], elements[1][1]); euler.y = Math::atan2(-elements[2][0], elements[0][0]); euler.z = Math::asin(sz); } else { // It's -1 euler.x = Math::atan2(elements[2][1], elements[2][2]); - euler.y = 0.0; - euler.z = -Math_PI / 2.0; + euler.y = 0.0f; + euler.z = -Math_PI / 2.0f; } } else { // It's 1 euler.x = Math::atan2(elements[2][1], elements[2][2]); - euler.y = 0.0; - euler.z = Math_PI / 2.0; + euler.y = 0.0f; + euler.z = Math_PI / 2.0f; } return euler; } break; @@ -593,20 +593,20 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { // -cx*sy sx cx*cy Vector3 euler; real_t sx = elements[2][1]; - if (sx < (1.0 - CMP_EPSILON)) { - if (sx > -(1.0 - CMP_EPSILON)) { + if (sx < (1.0f - (real_t)CMP_EPSILON)) { + if (sx > -(1.0f - (real_t)CMP_EPSILON)) { euler.x = Math::asin(sx); euler.y = Math::atan2(-elements[2][0], elements[2][2]); euler.z = Math::atan2(-elements[0][1], elements[1][1]); } else { // It's -1 - euler.x = -Math_PI / 2.0; + euler.x = -Math_PI / 2.0f; euler.y = Math::atan2(elements[0][2], elements[0][0]); euler.z = 0; } } else { // It's 1 - euler.x = Math_PI / 2.0; + euler.x = Math_PI / 2.0f; euler.y = Math::atan2(elements[0][2], elements[0][0]); euler.z = 0; } @@ -621,21 +621,21 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { // -sy cy*sx cy*cx Vector3 euler; real_t sy = elements[2][0]; - if (sy < (1.0 - CMP_EPSILON)) { - if (sy > -(1.0 - CMP_EPSILON)) { + if (sy < (1.0f - (real_t)CMP_EPSILON)) { + if (sy > -(1.0f - (real_t)CMP_EPSILON)) { euler.x = Math::atan2(elements[2][1], elements[2][2]); euler.y = Math::asin(-sy); euler.z = Math::atan2(elements[1][0], elements[0][0]); } else { // It's -1 euler.x = 0; - euler.y = Math_PI / 2.0; + euler.y = Math_PI / 2.0f; euler.z = -Math::atan2(elements[0][1], elements[1][1]); } } else { // It's 1 euler.x = 0; - euler.y = -Math_PI / 2.0; + euler.y = -Math_PI / 2.0f; euler.z = -Math::atan2(elements[0][1], elements[1][1]); } return euler; @@ -652,15 +652,15 @@ void Basis::set_euler(const Vector3 &p_euler, EulerOrder p_order) { c = Math::cos(p_euler.x); s = Math::sin(p_euler.x); - Basis xmat(1.0, 0.0, 0.0, 0.0, c, -s, 0.0, s, c); + Basis xmat(1, 0, 0, 0, c, -s, 0, s, c); c = Math::cos(p_euler.y); s = Math::sin(p_euler.y); - Basis ymat(c, 0.0, s, 0.0, 1.0, 0.0, -s, 0.0, c); + Basis ymat(c, 0, s, 0, 1, 0, -s, 0, c); c = Math::cos(p_euler.z); s = Math::sin(p_euler.z); - Basis zmat(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0); + Basis zmat(c, -s, 0, s, c, 0, 0, 0, 1); switch (p_order) { case EULER_ORDER_XYZ: { @@ -722,10 +722,10 @@ Quaternion Basis::get_quaternion() const { real_t trace = m.elements[0][0] + m.elements[1][1] + m.elements[2][2]; real_t temp[4]; - if (trace > 0.0) { - real_t s = Math::sqrt(trace + 1.0); - temp[3] = (s * 0.5); - s = 0.5 / s; + if (trace > 0.0f) { + real_t s = Math::sqrt(trace + 1.0f); + temp[3] = (s * 0.5f); + s = 0.5f / s; temp[0] = ((m.elements[2][1] - m.elements[1][2]) * s); temp[1] = ((m.elements[0][2] - m.elements[2][0]) * s); @@ -737,9 +737,9 @@ Quaternion Basis::get_quaternion() const { int j = (i + 1) % 3; int k = (i + 2) % 3; - real_t s = Math::sqrt(m.elements[i][i] - m.elements[j][j] - m.elements[k][k] + 1.0); - temp[i] = s * 0.5; - s = 0.5 / s; + real_t s = Math::sqrt(m.elements[i][i] - m.elements[j][j] - m.elements[k][k] + 1.0f); + temp[i] = s * 0.5f; + s = 0.5f / s; temp[3] = (m.elements[k][j] - m.elements[j][k]) * s; temp[j] = (m.elements[j][i] + m.elements[i][j]) * s; @@ -782,10 +782,10 @@ int Basis::get_orthogonal_index() const { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { real_t v = orth[i][j]; - if (v > 0.5) { - v = 1.0; - } else if (v < -0.5) { - v = -1.0; + if (v > 0.5f) { + v = 1.0f; + } else if (v < -0.5f) { + v = -1.0f; } else { v = 0; } @@ -890,14 +890,14 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const { void Basis::set_quaternion(const Quaternion &p_quaternion) { real_t d = p_quaternion.length_squared(); - real_t s = 2.0 / d; + real_t s = 2.0f / d; real_t xs = p_quaternion.x * s, ys = p_quaternion.y * s, zs = p_quaternion.z * s; real_t wx = p_quaternion.w * xs, wy = p_quaternion.w * ys, wz = p_quaternion.w * zs; real_t xx = p_quaternion.x * xs, xy = p_quaternion.x * ys, xz = p_quaternion.x * zs; real_t yy = p_quaternion.y * ys, yz = p_quaternion.y * zs, zz = p_quaternion.z * zs; - set(1.0 - (yy + zz), xy - wz, xz + wy, - xy + wz, 1.0 - (xx + zz), yz - wx, - xz - wy, yz + wx, 1.0 - (xx + yy)); + set(1.0f - (yy + zz), xy - wz, xz + wy, + xy + wz, 1.0f - (xx + zz), yz - wx, + xz - wy, yz + wx, 1.0f - (xx + yy)); } void Basis::set_axis_angle(const Vector3 &p_axis, real_t p_phi) { @@ -907,9 +907,9 @@ void Basis::set_axis_angle(const Vector3 &p_axis, real_t p_phi) { #endif Vector3 axis_sq(p_axis.x * p_axis.x, p_axis.y * p_axis.y, p_axis.z * p_axis.z); real_t cosine = Math::cos(p_phi); - elements[0][0] = axis_sq.x + cosine * (1.0 - axis_sq.x); - elements[1][1] = axis_sq.y + cosine * (1.0 - axis_sq.y); - elements[2][2] = axis_sq.z + cosine * (1.0 - axis_sq.z); + elements[0][0] = axis_sq.x + cosine * (1.0f - axis_sq.x); + elements[1][1] = axis_sq.y + cosine * (1.0f - axis_sq.y); + elements[2][2] = axis_sq.z + cosine * (1.0f - axis_sq.z); real_t sine = Math::sin(p_phi); real_t t = 1 - cosine; diff --git a/core/math/basis.h b/core/math/basis.h index 802da82089..683f05150c 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -34,11 +34,7 @@ #include "core/math/quaternion.h" #include "core/math/vector3.h" -class _NO_DISCARD_ Basis { -private: - void _set_diagonal(const Vector3 &p_diag); - -public: +struct _NO_DISCARD_ Basis { Vector3 elements[3] = { Vector3(1, 0, 0), Vector3(0, 1, 0), @@ -263,6 +259,10 @@ public: } _FORCE_INLINE_ Basis() {} + +private: + // Helper method. + void _set_diagonal(const Vector3 &p_diag); }; _FORCE_INLINE_ void Basis::operator*=(const Basis &p_matrix) { @@ -334,4 +334,5 @@ real_t Basis::determinant() const { elements[1][0] * (elements[0][1] * elements[2][2] - elements[2][1] * elements[0][2]) + elements[2][0] * (elements[0][1] * elements[1][2] - elements[1][1] * elements[0][2]); } + #endif // BASIS_H diff --git a/core/math/bvh_cull.inc b/core/math/bvh_cull.inc index d7edc8a884..ab468bfd29 100644 --- a/core/math/bvh_cull.inc +++ b/core/math/bvh_cull.inc @@ -508,8 +508,9 @@ bool _cull_convex_iterative(uint32_t p_node_id, CullParams &r_params, bool p_ful uint32_t child_id = leaf.get_item_ref_id(n); // full up with results? exit early, no point in further testing - if (!_cull_hit(child_id, r_params)) + if (!_cull_hit(child_id, r_params)) { return false; + } } } #endif // BVH_CONVEX_CULL_OPTIMIZED diff --git a/core/math/bvh_debug.inc b/core/math/bvh_debug.inc index 55db794ee3..896c36ecf1 100644 --- a/core/math/bvh_debug.inc +++ b/core/math/bvh_debug.inc @@ -1,8 +1,9 @@ public: #ifdef BVH_VERBOSE void _debug_recursive_print_tree(int p_tree_id) const { - if (_root_node_id[p_tree_id] != BVHCommon::INVALID) + if (_root_node_id[p_tree_id] != BVHCommon::INVALID) { _debug_recursive_print_tree_node(_root_node_id[p_tree_id]); + } } String _debug_aabb_to_string(const BVHABB_CLASS &aabb) const { @@ -42,8 +43,9 @@ void _debug_recursive_print_tree_node(uint32_t p_node_id, int depth = 0) const { sz += "["; for (int n = 0; n < leaf.num_items; n++) { - if (n) + if (n) { sz += ", "; + } sz += "r"; sz += itos(leaf.get_item_ref_id(n)); } diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index 2902ca59b9..f4392c74b7 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -30,7 +30,11 @@ #include "camera_matrix.h" +#include "core/math/aabb.h" #include "core/math/math_funcs.h" +#include "core/math/plane.h" +#include "core/math/rect2.h" +#include "core/math/transform_3d.h" #include "core/string/print_string.h" float CameraMatrix::determinant() const { @@ -432,9 +436,7 @@ void CameraMatrix::invert() { int pvt_i[4], pvt_j[4]; /* Locations of pivot matrix */ real_t pvt_val; /* Value of current pivot element */ real_t hold; /* Temporary storage */ - real_t determinat; /* Determinant */ - - determinat = 1.0; + real_t determinant = 1.0f; for (k = 0; k < 4; k++) { /** Locate k'th pivot element **/ pvt_val = matrix[k][k]; /** Initialize for search **/ @@ -442,7 +444,7 @@ void CameraMatrix::invert() { pvt_j[k] = k; for (i = k; i < 4; i++) { for (j = k; j < 4; j++) { - if (Math::absd(matrix[i][j]) > Math::absd(pvt_val)) { + if (Math::abs(matrix[i][j]) > Math::abs(pvt_val)) { pvt_i[k] = i; pvt_j[k] = j; pvt_val = matrix[i][j]; @@ -451,9 +453,9 @@ void CameraMatrix::invert() { } /** Product of pivots, gives determinant when finished **/ - determinat *= pvt_val; - if (Math::absd(determinat) < 1e-7) { - return; //(false); /** Matrix is singular (zero determinant). **/ + determinant *= pvt_val; + if (Math::is_zero_approx(determinant)) { + return; /** Matrix is singular (zero determinant). **/ } /** "Interchange" rows (with sign change stuff) **/ diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h index da1aba7562..f1aea5e4e8 100644 --- a/core/math/camera_matrix.h +++ b/core/math/camera_matrix.h @@ -31,8 +31,15 @@ #ifndef CAMERA_MATRIX_H #define CAMERA_MATRIX_H -#include "core/math/rect2.h" -#include "core/math/transform_3d.h" +#include "core/math/math_defs.h" +#include "core/math/vector3.h" +#include "core/templates/vector.h" + +struct AABB; +struct Plane; +struct Rect2; +struct Transform3D; +struct Vector2; struct CameraMatrix { enum Planes { diff --git a/core/math/color.cpp b/core/math/color.cpp index b06d20b3d3..e32f9147d9 100644 --- a/core/math/color.cpp +++ b/core/math/color.cpp @@ -161,9 +161,9 @@ float Color::get_h() const { h = 4 + (r - g) / delta; // between magenta & cyan } - h /= 6.0; + h /= 6.0f; if (h < 0) { - h += 1.0; + h += 1.0f; } return h; @@ -197,7 +197,7 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) { return; } - p_h *= 6.0; + p_h *= 6.0f; p_h = Math::fmod(p_h, 6); i = Math::floor(p_h); @@ -253,31 +253,31 @@ Color Color::clamp(const Color &p_min, const Color &p_max) const { } void Color::invert() { - r = 1.0 - r; - g = 1.0 - g; - b = 1.0 - b; + r = 1.0f - r; + g = 1.0f - g; + b = 1.0f - b; } Color Color::hex(uint32_t p_hex) { - float a = (p_hex & 0xFF) / 255.0; + float a = (p_hex & 0xFF) / 255.0f; p_hex >>= 8; - float b = (p_hex & 0xFF) / 255.0; + float b = (p_hex & 0xFF) / 255.0f; p_hex >>= 8; - float g = (p_hex & 0xFF) / 255.0; + float g = (p_hex & 0xFF) / 255.0f; p_hex >>= 8; - float r = (p_hex & 0xFF) / 255.0; + float r = (p_hex & 0xFF) / 255.0f; return Color(r, g, b, a); } Color Color::hex64(uint64_t p_hex) { - float a = (p_hex & 0xFFFF) / 65535.0; + float a = (p_hex & 0xFFFF) / 65535.0f; p_hex >>= 16; - float b = (p_hex & 0xFFFF) / 65535.0; + float b = (p_hex & 0xFFFF) / 65535.0f; p_hex >>= 16; - float g = (p_hex & 0xFFFF) / 65535.0; + float g = (p_hex & 0xFFFF) / 65535.0f; p_hex >>= 16; - float r = (p_hex & 0xFFFF) / 65535.0; + float r = (p_hex & 0xFFFF) / 65535.0f; return Color(r, g, b, a); } @@ -333,18 +333,18 @@ Color Color::html(const String &p_rgba) { float r, g, b, a = 1.0; if (is_shorthand) { - r = _parse_col4(color, 0) / 15.0; - g = _parse_col4(color, 1) / 15.0; - b = _parse_col4(color, 2) / 15.0; + r = _parse_col4(color, 0) / 15.0f; + g = _parse_col4(color, 1) / 15.0f; + b = _parse_col4(color, 2) / 15.0f; if (alpha) { - a = _parse_col4(color, 3) / 15.0; + a = _parse_col4(color, 3) / 15.0f; } } else { - r = _parse_col8(color, 0) / 255.0; - g = _parse_col8(color, 2) / 255.0; - b = _parse_col8(color, 4) / 255.0; + r = _parse_col8(color, 0) / 255.0f; + g = _parse_col8(color, 2) / 255.0f; + b = _parse_col8(color, 4) / 255.0f; if (alpha) { - a = _parse_col8(color, 6) / 255.0; + a = _parse_col8(color, 6) / 255.0f; } } ERR_FAIL_COND_V_MSG(r < 0, Color(), "Invalid color code: " + p_rgba + "."); @@ -458,7 +458,7 @@ Color Color::from_rgbe9995(uint32_t p_rgbe) { float g = (p_rgbe >> 9) & 0x1ff; float b = (p_rgbe >> 18) & 0x1ff; float e = (p_rgbe >> 27); - float m = Math::pow(2, e - 15.0 - 9.0); + float m = Math::pow(2, e - 15.0f - 9.0f); float rd = r * m; float gd = g * m; @@ -563,8 +563,8 @@ void Color::operator/=(float p_scalar) { Color Color::operator-() const { return Color( - 1.0 - r, - 1.0 - g, - 1.0 - b, - 1.0 - a); + 1.0f - r, + 1.0f - g, + 1.0f - b, + 1.0f - a); } diff --git a/core/math/color.h b/core/math/color.h index 72a4a5f8be..b90a0f33a2 100644 --- a/core/math/color.h +++ b/core/math/color.h @@ -95,7 +95,7 @@ struct _NO_DISCARD_ Color { Color inverted() const; _FORCE_INLINE_ float get_luminance() const { - return 0.2126 * r + 0.7152 * g + 0.0722 * b; + return 0.2126f * r + 0.7152f * g + 0.0722f * b; } _FORCE_INLINE_ Color lerp(const Color &p_to, float p_weight) const { @@ -138,13 +138,13 @@ struct _NO_DISCARD_ Color { float cMax = MAX(cRed, MAX(cGreen, cBlue)); - float expp = MAX(-B - 1.0f, floor(Math::log(cMax) / Math_LN2)) + 1.0f + B; + float expp = MAX(-B - 1.0f, floor(Math::log(cMax) / (real_t)Math_LN2)) + 1.0f + B; float sMax = (float)floor((cMax / Math::pow(2.0f, expp - B - N)) + 0.5f); float exps = expp + 1.0f; - if (0.0 <= sMax && sMax < pow2to9) { + if (0.0f <= sMax && sMax < pow2to9) { exps = expp; } @@ -157,7 +157,7 @@ struct _NO_DISCARD_ Color { _FORCE_INLINE_ Color blend(const Color &p_over) const { Color res; - float sa = 1.0 - p_over.a; + float sa = 1.0f - p_over.a; res.a = a * sa + p_over.a; if (res.a == 0) { return Color(0, 0, 0, 0); @@ -171,16 +171,16 @@ struct _NO_DISCARD_ Color { _FORCE_INLINE_ Color to_linear() const { return Color( - r < 0.04045 ? r * (1.0 / 12.92) : Math::pow((r + 0.055) * (1.0 / (1 + 0.055)), 2.4), - g < 0.04045 ? g * (1.0 / 12.92) : Math::pow((g + 0.055) * (1.0 / (1 + 0.055)), 2.4), - b < 0.04045 ? b * (1.0 / 12.92) : Math::pow((b + 0.055) * (1.0 / (1 + 0.055)), 2.4), + r < 0.04045f ? r * (1.0 / 12.92) : Math::pow((r + 0.055f) * (float)(1.0 / (1 + 0.055)), 2.4f), + g < 0.04045f ? g * (1.0 / 12.92) : Math::pow((g + 0.055f) * (float)(1.0 / (1 + 0.055)), 2.4f), + b < 0.04045f ? b * (1.0 / 12.92) : Math::pow((b + 0.055f) * (float)(1.0 / (1 + 0.055)), 2.4f), a); } _FORCE_INLINE_ Color to_srgb() const { return Color( - r < 0.0031308 ? 12.92 * r : (1.0 + 0.055) * Math::pow(r, 1.0f / 2.4f) - 0.055, - g < 0.0031308 ? 12.92 * g : (1.0 + 0.055) * Math::pow(g, 1.0f / 2.4f) - 0.055, - b < 0.0031308 ? 12.92 * b : (1.0 + 0.055) * Math::pow(b, 1.0f / 2.4f) - 0.055, a); + r < 0.0031308f ? 12.92f * r : (1.0f + 0.055f) * Math::pow(r, 1.0f / 2.4f) - 0.055f, + g < 0.0031308f ? 12.92f * g : (1.0f + 0.055f) * Math::pow(g, 1.0f / 2.4f) - 0.055f, + b < 0.0031308f ? 12.92f * b : (1.0f + 0.055f) * Math::pow(b, 1.0f / 2.4f) - 0.055f, a); } static Color hex(uint32_t p_hex); @@ -201,13 +201,13 @@ struct _NO_DISCARD_ Color { operator String() const; // For the binder. - _FORCE_INLINE_ void set_r8(int32_t r8) { r = (CLAMP(r8, 0, 255) / 255.0); } + _FORCE_INLINE_ void set_r8(int32_t r8) { r = (CLAMP(r8, 0, 255) / 255.0f); } _FORCE_INLINE_ int32_t get_r8() const { return int32_t(CLAMP(Math::round(r * 255.0f), 0.0f, 255.0f)); } - _FORCE_INLINE_ void set_g8(int32_t g8) { g = (CLAMP(g8, 0, 255) / 255.0); } + _FORCE_INLINE_ void set_g8(int32_t g8) { g = (CLAMP(g8, 0, 255) / 255.0f); } _FORCE_INLINE_ int32_t get_g8() const { return int32_t(CLAMP(Math::round(g * 255.0f), 0.0f, 255.0f)); } - _FORCE_INLINE_ void set_b8(int32_t b8) { b = (CLAMP(b8, 0, 255) / 255.0); } + _FORCE_INLINE_ void set_b8(int32_t b8) { b = (CLAMP(b8, 0, 255) / 255.0f); } _FORCE_INLINE_ int32_t get_b8() const { return int32_t(CLAMP(Math::round(b * 255.0f), 0.0f, 255.0f)); } - _FORCE_INLINE_ void set_a8(int32_t a8) { a = (CLAMP(a8, 0, 255) / 255.0); } + _FORCE_INLINE_ void set_a8(int32_t a8) { a = (CLAMP(a8, 0, 255) / 255.0f); } _FORCE_INLINE_ int32_t get_a8() const { return int32_t(CLAMP(Math::round(a * 255.0f), 0.0f, 255.0f)); } _FORCE_INLINE_ void set_h(float p_h) { set_hsv(p_h, get_s(), get_v()); } @@ -234,7 +234,7 @@ struct _NO_DISCARD_ Color { r = p_r; g = p_g; b = p_b; - a = 1.0; + a = 1.0f; } /** diff --git a/core/math/convex_hull.cpp b/core/math/convex_hull.cpp index 912ffb8b16..bd292f4c2a 100644 --- a/core/math/convex_hull.cpp +++ b/core/math/convex_hull.cpp @@ -2129,7 +2129,7 @@ bool ConvexHullInternal::shift_face(Face *p_face, real_t p_amount, LocalVector<V printf("Needed %d iterations to remove part\n", n); #endif - p_stack.resize(0); + p_stack.clear(); p_face->origin = shifted_origin; return true; @@ -2167,9 +2167,9 @@ real_t ConvexHullComputer::compute(const Vector3 *p_coords, int32_t p_count, rea return shift; } - vertices.resize(0); - edges.resize(0); - faces.resize(0); + vertices.clear(); + edges.clear(); + faces.clear(); LocalVector<ConvexHullInternal::Vertex *> old_vertices; get_vertex_copy(hull.vertex_list, old_vertices); diff --git a/core/math/delaunay_2d.h b/core/math/delaunay_2d.h index 08f5df8472..c39997d6a9 100644 --- a/core/math/delaunay_2d.h +++ b/core/math/delaunay_2d.h @@ -32,6 +32,7 @@ #define DELAUNAY_2D_H #include "core/math/rect2.h" +#include "core/templates/vector.h" class Delaunay2D { public: diff --git a/core/math/dynamic_bvh.h b/core/math/dynamic_bvh.h index 3041cdf268..50ec2c2b30 100644 --- a/core/math/dynamic_bvh.h +++ b/core/math/dynamic_bvh.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef DYNAMICBVH_H -#define DYNAMICBVH_H +#ifndef DYNAMIC_BVH_H +#define DYNAMIC_BVH_H #include "core/math/aabb.h" #include "core/templates/list.h" @@ -474,4 +474,4 @@ void DynamicBVH::ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResu } while (depth > 0); } -#endif // DYNAMICBVH_H +#endif // DYNAMIC_BVH_H diff --git a/core/math/expression.cpp b/core/math/expression.cpp index 4f8e79038f..0ddac9744e 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -37,10 +37,6 @@ #include "core/os/os.h" #include "core/variant/variant_parser.h" -static bool _is_number(char32_t c) { - return (c >= '0' && c <= '9'); -} - Error Expression::_get_token(Token &r_token) { while (true) { #define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++]) @@ -88,7 +84,7 @@ Error Expression::_get_token(Token &r_token) { r_token.type = TK_INPUT; int index = 0; do { - if (!_is_number(expression[str_ofs])) { + if (!is_digit(expression[str_ofs])) { _set_error("Expected number after '$'"); r_token.type = TK_ERROR; return ERR_PARSE_ERROR; @@ -97,7 +93,7 @@ Error Expression::_get_token(Token &r_token) { index += expression[str_ofs] - '0'; str_ofs++; - } while (_is_number(expression[str_ofs])); + } while (is_digit(expression[str_ofs])); r_token.value = index; return OK; @@ -197,6 +193,7 @@ Error Expression::_get_token(Token &r_token) { case '\'': case '"': { String str; + char32_t prev = 0; while (true) { char32_t ch = GET_CHAR(); @@ -234,9 +231,11 @@ Error Expression::_get_token(Token &r_token) { case 'r': res = 13; break; + case 'U': case 'u': { - // hex number - for (int j = 0; j < 4; j++) { + // Hexadecimal sequence. + int hex_len = (next == 'U') ? 6 : 4; + for (int j = 0; j < hex_len; j++) { char32_t c = GET_CHAR(); if (c == 0) { @@ -244,13 +243,13 @@ Error Expression::_get_token(Token &r_token) { r_token.type = TK_ERROR; return ERR_PARSE_ERROR; } - if (!(_is_number(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) { + if (!is_hex_digit(c)) { _set_error("Malformed hex constant in string"); r_token.type = TK_ERROR; return ERR_PARSE_ERROR; } char32_t v; - if (_is_number(c)) { + if (is_digit(c)) { v = c - '0'; } else if (c >= 'a' && c <= 'f') { v = c - 'a'; @@ -273,12 +272,46 @@ Error Expression::_get_token(Token &r_token) { } break; } + // Parse UTF-16 pair. + if ((res & 0xfffffc00) == 0xd800) { + if (prev == 0) { + prev = res; + continue; + } else { + _set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate"); + r_token.type = TK_ERROR; + return ERR_PARSE_ERROR; + } + } else if ((res & 0xfffffc00) == 0xdc00) { + if (prev == 0) { + _set_error("Invalid UTF-16 sequence in string, unpaired trail surrogate"); + r_token.type = TK_ERROR; + return ERR_PARSE_ERROR; + } else { + res = (prev << 10UL) + res - ((0xd800 << 10UL) + 0xdc00 - 0x10000); + prev = 0; + } + } + if (prev != 0) { + _set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate"); + r_token.type = TK_ERROR; + return ERR_PARSE_ERROR; + } str += res; - } else { + if (prev != 0) { + _set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate"); + r_token.type = TK_ERROR; + return ERR_PARSE_ERROR; + } str += ch; } } + if (prev != 0) { + _set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate"); + r_token.type = TK_ERROR; + return ERR_PARSE_ERROR; + } r_token.type = TK_CONSTANT; r_token.value = str; @@ -291,39 +324,67 @@ Error Expression::_get_token(Token &r_token) { } char32_t next_char = (str_ofs >= expression.length()) ? 0 : expression[str_ofs]; - if (_is_number(cchar) || (cchar == '.' && _is_number(next_char))) { + if (is_digit(cchar) || (cchar == '.' && is_digit(next_char))) { //a number String num; #define READING_SIGN 0 #define READING_INT 1 -#define READING_DEC 2 -#define READING_EXP 3 -#define READING_DONE 4 +#define READING_HEX 2 +#define READING_BIN 3 +#define READING_DEC 4 +#define READING_EXP 5 +#define READING_DONE 6 int reading = READING_INT; char32_t c = cchar; bool exp_sign = false; bool exp_beg = false; + bool bin_beg = false; + bool hex_beg = false; bool is_float = false; + bool is_first_char = true; while (true) { switch (reading) { case READING_INT: { - if (_is_number(c)) { - //pass + if (is_digit(c)) { + if (is_first_char && c == '0') { + if (next_char == 'b') { + reading = READING_BIN; + } else if (next_char == 'x') { + reading = READING_HEX; + } + } } else if (c == '.') { reading = READING_DEC; is_float = true; } else if (c == 'e') { reading = READING_EXP; + is_float = true; } else { reading = READING_DONE; } } break; + case READING_BIN: { + if (bin_beg && !is_binary_digit(c)) { + reading = READING_DONE; + } else if (c == 'b') { + bin_beg = true; + } + + } break; + case READING_HEX: { + if (hex_beg && !is_hex_digit(c)) { + reading = READING_DONE; + } else if (c == 'x') { + hex_beg = true; + } + + } break; case READING_DEC: { - if (_is_number(c)) { + if (is_digit(c)) { } else if (c == 'e') { reading = READING_EXP; @@ -333,13 +394,10 @@ Error Expression::_get_token(Token &r_token) { } break; case READING_EXP: { - if (_is_number(c)) { + if (is_digit(c)) { exp_beg = true; } else if ((c == '-' || c == '+') && !exp_sign && !exp_beg) { - if (c == '-') { - is_float = true; - } exp_sign = true; } else { @@ -353,6 +411,7 @@ Error Expression::_get_token(Token &r_token) { } num += String::chr(c); c = GET_CHAR(); + is_first_char = false; } str_ofs--; @@ -361,16 +420,20 @@ Error Expression::_get_token(Token &r_token) { if (is_float) { r_token.value = num.to_float(); + } else if (bin_beg) { + r_token.value = num.bin_to_int(); + } else if (hex_beg) { + r_token.value = num.hex_to_int(); } else { r_token.value = num.to_int(); } return OK; - } else if ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_') { + } else if (is_ascii_char(cchar) || is_underscore(cchar)) { String id; bool first = true; - while ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_' || (!first && _is_number(cchar))) { + while (is_ascii_char(cchar) || is_underscore(cchar) || (!first && is_digit(cchar))) { id += String::chr(cchar); cchar = GET_CHAR(); first = false; diff --git a/core/math/face3.cpp b/core/math/face3.cpp index d588f34e5d..5bc1bc25e6 100644 --- a/core/math/face3.cpp +++ b/core/math/face3.cpp @@ -42,7 +42,7 @@ int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_ int below_count = 0; for (int i = 0; i < 3; i++) { - if (p_plane.has_point(vertex[i], CMP_EPSILON)) { // point is in plane + if (p_plane.has_point(vertex[i], (real_t)CMP_EPSILON)) { // point is in plane ERR_FAIL_COND_V(above_count >= 4, 0); above[above_count++] = vertex[i]; @@ -117,7 +117,7 @@ bool Face3::intersects_segment(const Vector3 &p_from, const Vector3 &p_dir, Vect bool Face3::is_degenerate() const { Vector3 normal = vec3_cross(vertex[0] - vertex[1], vertex[0] - vertex[2]); - return (normal.length_squared() < CMP_EPSILON2); + return (normal.length_squared() < (real_t)CMP_EPSILON2); } Face3::Side Face3::get_side_of(const Face3 &p_face, ClockDirection p_clock_dir) const { @@ -157,7 +157,7 @@ Vector3 Face3::get_random_point_inside() const { SWAP(a, b); } - return vertex[0] * a + vertex[1] * (b - a) + vertex[2] * (1.0 - b); + return vertex[0] * a + vertex[1] * (b - a) + vertex[2] * (1.0f - b); } Plane Face3::get_plane(ClockDirection p_dir) const { @@ -165,11 +165,11 @@ Plane Face3::get_plane(ClockDirection p_dir) const { } Vector3 Face3::get_median_point() const { - return (vertex[0] + vertex[1] + vertex[2]) / 3.0; + return (vertex[0] + vertex[1] + vertex[2]) / 3.0f; } real_t Face3::get_area() const { - return vec3_cross(vertex[0] - vertex[1], vertex[0] - vertex[2]).length() * 0.5; + return vec3_cross(vertex[0] - vertex[1], vertex[0] - vertex[2]).length() * 0.5f; } ClockDirection Face3::get_clock_dir() const { @@ -223,7 +223,7 @@ bool Face3::intersects_aabb(const AABB &p_aabb) const { Vector3 axis = vec3_cross(e1, e2); - if (axis.length_squared() < 0.0001) { + if (axis.length_squared() < 0.0001f) { continue; // coplanar } axis.normalize(); diff --git a/core/math/face3.h b/core/math/face3.h index 3dbbca09e0..c61d6ad66e 100644 --- a/core/math/face3.h +++ b/core/math/face3.h @@ -36,8 +36,7 @@ #include "core/math/transform_3d.h" #include "core/math/vector3.h" -class _NO_DISCARD_ Face3 { -public: +struct _NO_DISCARD_ Face3 { enum Side { SIDE_OVER, SIDE_UNDER, @@ -48,14 +47,11 @@ public: Vector3 vertex[3]; /** - * * @param p_plane plane used to split the face * @param p_res array of at least 3 faces, amount used in function return * @param p_is_point_over array of at least 3 booleans, determining which face is over the plane, amount used in function return - * @param _epsilon constant used for numerical error rounding, to add "thickness" to the plane (so coplanar points can happen) * @return amount of faces generated by the split, either 0 (means no split possible), 2 or 3 */ - int split_by_plane(const Plane &p_plane, Face3 *p_res, bool *p_is_point_over) const; Plane get_plane(ClockDirection p_dir = CLOCKWISE) const; @@ -99,7 +95,7 @@ public: bool Face3::intersects_aabb2(const AABB &p_aabb) const { Vector3 perp = (vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]); - Vector3 half_extents = p_aabb.size * 0.5; + Vector3 half_extents = p_aabb.size * 0.5f; Vector3 ofs = p_aabb.position + half_extents; Vector3 sup = Vector3( @@ -210,7 +206,7 @@ bool Face3::intersects_aabb2(const AABB &p_aabb) const { Vector3 axis = vec3_cross(e1, e2); - if (axis.length_squared() < 0.0001) { + if (axis.length_squared() < 0.0001f) { continue; // coplanar } //axis.normalize(); diff --git a/core/math/geometry_2d.cpp b/core/math/geometry_2d.cpp index 9fa45a3363..46b7d99b43 100644 --- a/core/math/geometry_2d.cpp +++ b/core/math/geometry_2d.cpp @@ -218,10 +218,10 @@ Vector<Vector<Point2>> Geometry2D::_polypaths_do_operation(PolyBooleanOperation // Need to scale points (Clipper's requirement for robust computation). for (int i = 0; i != p_polypath_a.size(); ++i) { - path_a << IntPoint(p_polypath_a[i].x * SCALE_FACTOR, p_polypath_a[i].y * SCALE_FACTOR); + path_a << IntPoint(p_polypath_a[i].x * (real_t)SCALE_FACTOR, p_polypath_a[i].y * (real_t)SCALE_FACTOR); } for (int i = 0; i != p_polypath_b.size(); ++i) { - path_b << IntPoint(p_polypath_b[i].x * SCALE_FACTOR, p_polypath_b[i].y * SCALE_FACTOR); + path_b << IntPoint(p_polypath_b[i].x * (real_t)SCALE_FACTOR, p_polypath_b[i].y * (real_t)SCALE_FACTOR); } Clipper clp; clp.AddPath(path_a, ptSubject, !is_a_open); // Forward compatible with Clipper 10.0.0. @@ -246,8 +246,8 @@ Vector<Vector<Point2>> Geometry2D::_polypaths_do_operation(PolyBooleanOperation for (Paths::size_type j = 0; j < scaled_path.size(); ++j) { polypath.push_back(Point2( - static_cast<real_t>(scaled_path[j].X) / SCALE_FACTOR, - static_cast<real_t>(scaled_path[j].Y) / SCALE_FACTOR)); + static_cast<real_t>(scaled_path[j].X) / (real_t)SCALE_FACTOR, + static_cast<real_t>(scaled_path[j].Y) / (real_t)SCALE_FACTOR)); } polypaths.push_back(polypath); } @@ -290,17 +290,17 @@ Vector<Vector<Point2>> Geometry2D::_polypath_offset(const Vector<Point2> &p_poly et = etOpenRound; break; } - ClipperOffset co(2.0, 0.25 * SCALE_FACTOR); // Defaults from ClipperOffset. + ClipperOffset co(2.0, 0.25f * (real_t)SCALE_FACTOR); // Defaults from ClipperOffset. Path path; // Need to scale points (Clipper's requirement for robust computation). for (int i = 0; i != p_polypath.size(); ++i) { - path << IntPoint(p_polypath[i].x * SCALE_FACTOR, p_polypath[i].y * SCALE_FACTOR); + path << IntPoint(p_polypath[i].x * (real_t)SCALE_FACTOR, p_polypath[i].y * (real_t)SCALE_FACTOR); } co.AddPath(path, jt, et); Paths paths; - co.Execute(paths, p_delta * SCALE_FACTOR); // Inflate/deflate. + co.Execute(paths, p_delta * (real_t)SCALE_FACTOR); // Inflate/deflate. // Have to scale points down now. Vector<Vector<Point2>> polypaths; @@ -312,8 +312,8 @@ Vector<Vector<Point2>> Geometry2D::_polypath_offset(const Vector<Point2> &p_poly for (Paths::size_type j = 0; j < scaled_path.size(); ++j) { polypath.push_back(Point2( - static_cast<real_t>(scaled_path[j].X) / SCALE_FACTOR, - static_cast<real_t>(scaled_path[j].Y) / SCALE_FACTOR)); + static_cast<real_t>(scaled_path[j].X) / (real_t)SCALE_FACTOR, + static_cast<real_t>(scaled_path[j].Y) / (real_t)SCALE_FACTOR)); } polypaths.push_back(polypath); } diff --git a/core/math/geometry_2d.h b/core/math/geometry_2d.h index 7385dba438..62786d69be 100644 --- a/core/math/geometry_2d.h +++ b/core/math/geometry_2d.h @@ -32,7 +32,11 @@ #define GEOMETRY_2D_H #include "core/math/delaunay_2d.h" +#include "core/math/math_funcs.h" #include "core/math/triangulate.h" +#include "core/math/vector2.h" +#include "core/math/vector2i.h" +#include "core/math/vector3.h" #include "core/math/vector3i.h" #include "core/templates/vector.h" @@ -47,31 +51,31 @@ public: real_t f = d2.dot(r); real_t s, t; // Check if either or both segments degenerate into points. - if (a <= CMP_EPSILON && e <= CMP_EPSILON) { + if (a <= (real_t)CMP_EPSILON && e <= (real_t)CMP_EPSILON) { // Both segments degenerate into points. c1 = p1; c2 = p2; return Math::sqrt((c1 - c2).dot(c1 - c2)); } - if (a <= CMP_EPSILON) { + if (a <= (real_t)CMP_EPSILON) { // First segment degenerates into a point. s = 0.0; t = f / e; // s = 0 => t = (b*s + f) / e = f / e - t = CLAMP(t, 0.0, 1.0); + t = CLAMP(t, 0.0f, 1.0f); } else { real_t c = d1.dot(r); - if (e <= CMP_EPSILON) { + if (e <= (real_t)CMP_EPSILON) { // Second segment degenerates into a point. t = 0.0; - s = CLAMP(-c / a, 0.0, 1.0); // t = 0 => s = (b*t - c) / a = -c / a + s = CLAMP(-c / a, 0.0f, 1.0f); // t = 0 => s = (b*t - c) / a = -c / a } else { // The general nondegenerate case starts here. real_t b = d1.dot(d2); real_t denom = a * e - b * b; // Always nonnegative. // If segments not parallel, compute closest point on L1 to L2 and // clamp to segment S1. Else pick arbitrary s (here 0). - if (denom != 0.0) { - s = CLAMP((b * f - c * e) / denom, 0.0, 1.0); + if (denom != 0.0f) { + s = CLAMP((b * f - c * e) / denom, 0.0f, 1.0f); } else { s = 0.0; } @@ -82,12 +86,12 @@ public: //If t in [0,1] done. Else clamp t, recompute s for the new value // of t using s = Dot((P2 + D2*t) - P1,D1) / Dot(D1,D1)= (t*b - c) / a // and clamp s to [0, 1]. - if (t < 0.0) { + if (t < 0.0f) { t = 0.0; - s = CLAMP(-c / a, 0.0, 1.0); - } else if (t > 1.0) { + s = CLAMP(-c / a, 0.0f, 1.0f); + } else if (t > 1.0f) { t = 1.0; - s = CLAMP((b - c) / a, 0.0, 1.0); + s = CLAMP((b - c) / a, 0.0f, 1.0f); } } } @@ -100,15 +104,15 @@ public: Vector2 p = p_point - p_segment[0]; Vector2 n = p_segment[1] - p_segment[0]; real_t l2 = n.length_squared(); - if (l2 < 1e-20) { + if (l2 < 1e-20f) { return p_segment[0]; // Both points are the same, just give any. } real_t d = n.dot(p) / l2; - if (d <= 0.0) { + if (d <= 0.0f) { return p_segment[0]; // Before first point. - } else if (d >= 1.0) { + } else if (d >= 1.0f) { return p_segment[1]; // After first point. } else { return p_segment[0] + n * d; // Inside. @@ -133,7 +137,7 @@ public: Vector2 p = p_point - p_segment[0]; Vector2 n = p_segment[1] - p_segment[0]; real_t l2 = n.length_squared(); - if (l2 < 1e-20) { + if (l2 < 1e-20f) { return p_segment[0]; // Both points are the same, just give any. } @@ -181,7 +185,7 @@ public: D = Vector2(D.x * Bn.x + D.y * Bn.y, D.y * Bn.x - D.x * Bn.y); // Fail if C x B and D x B have the same sign (segments don't intersect). - if ((C.y < -CMP_EPSILON && D.y < -CMP_EPSILON) || (C.y > CMP_EPSILON && D.y > CMP_EPSILON)) { + if ((C.y < (real_t)-CMP_EPSILON && D.y < (real_t)-CMP_EPSILON) || (C.y > (real_t)CMP_EPSILON && D.y > (real_t)CMP_EPSILON)) { return false; } @@ -194,7 +198,7 @@ public: real_t ABpos = D.x + (C.x - D.x) * D.y / (D.y - C.y); // Fail if segment C-D crosses line A-B outside of segment A-B. - if (ABpos < 0 || ABpos > 1.0) { + if ((ABpos < 0) || (ABpos > 1)) { return false; } diff --git a/core/math/geometry_3d.cpp b/core/math/geometry_3d.cpp index a9ff46410e..bd22bffb1f 100644 --- a/core/math/geometry_3d.cpp +++ b/core/math/geometry_3d.cpp @@ -124,8 +124,8 @@ static bool _connect_faces(_FaceClassify *p_faces, int len, int p_group) { Vector3 vj2 = p_faces[j].face.vertex[l]; Vector3 vj1 = p_faces[j].face.vertex[(l + 1) % 3]; - if (vi1.distance_to(vj1) < 0.00001 && - vi2.distance_to(vj2) < 0.00001) { + if (vi1.distance_to(vj1) < 0.00001f && + vi2.distance_to(vj2) < 0.00001f) { if (p_faces[i].links[k].face != -1) { ERR_PRINT("already linked\n"); error = true; @@ -508,7 +508,7 @@ Vector<Face3> Geometry3D::wrap_geometry(Vector<Face3> p_array, real_t *p_error) } } - global_aabb.grow_by(0.01); // Avoid numerical error. + global_aabb.grow_by(0.01f); // Avoid numerical error. // Determine amount of cells in grid axis. int div_x, div_y, div_z; @@ -638,7 +638,7 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes Vector3 ref = Vector3(0.0, 1.0, 0.0); - if (ABS(p.normal.dot(ref)) > 0.95) { + if (ABS(p.normal.dot(ref)) > 0.95f) { ref = Vector3(0.0, 0.0, 1.0); // Change axis. } @@ -663,7 +663,7 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes Vector<Vector3> new_vertices; Plane clip = p_planes[j]; - if (clip.normal.dot(p.normal) > 0.95) { + if (clip.normal.dot(p.normal) > 0.95f) { continue; } @@ -716,7 +716,7 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes for (int j = 0; j < vertices.size(); j++) { int idx = -1; for (int k = 0; k < mesh.vertices.size(); k++) { - if (mesh.vertices[k].distance_to(vertices[j]) < 0.001) { + if (mesh.vertices[k].distance_to(vertices[j]) < 0.001f) { idx = k; break; } @@ -793,8 +793,8 @@ Vector<Plane> Geometry3D::build_cylinder_planes(real_t p_radius, real_t p_height Vector3 axis; axis[p_axis] = 1.0; - planes.push_back(Plane(axis, p_height * 0.5)); - planes.push_back(Plane(-axis, p_height * 0.5)); + planes.push_back(Plane(axis, p_height * 0.5f)); + planes.push_back(Plane(-axis, p_height * 0.5f)); return planes; } @@ -853,7 +853,7 @@ Vector<Plane> Geometry3D::build_capsule_planes(real_t p_radius, real_t p_height, for (int j = 1; j <= p_lats; j++) { Vector3 plane_normal = normal.lerp(axis, j / (real_t)p_lats).normalized(); - Vector3 position = axis * p_height * 0.5 + plane_normal * p_radius; + Vector3 position = axis * p_height * 0.5f + plane_normal * p_radius; planes.push_back(Plane(plane_normal, position)); planes.push_back(Plane(plane_normal * axis_neg, position * axis_neg)); } @@ -879,7 +879,7 @@ Vector<Vector3> Geometry3D::compute_convex_mesh_points(const Plane *p_planes, in for (int n = 0; n < p_plane_count; n++) { if (n != i && n != j && n != k) { real_t dp = p_planes[n].normal.dot(convex_shape_point); - if (dp - p_planes[n].d > CMP_EPSILON) { + if (dp - p_planes[n].d > (real_t)CMP_EPSILON) { excluded = true; break; } diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h index 0f6ab5c716..59c56906f4 100644 --- a/core/math/geometry_3d.h +++ b/core/math/geometry_3d.h @@ -76,16 +76,16 @@ public: real_t tc, tN, tD = D; // tc = tN / tD, default tD = D >= 0 // Compute the line parameters of the two closest points. - if (D < CMP_EPSILON) { // The lines are almost parallel. - sN = 0.0; // Force using point P0 on segment S1 - sD = 1.0; // to prevent possible division by 0.0 later. + if (D < (real_t)CMP_EPSILON) { // The lines are almost parallel. + sN = 0.0f; // Force using point P0 on segment S1 + sD = 1.0f; // to prevent possible division by 0.0 later. tN = e; tD = c; } else { // Get the closest points on the infinite lines sN = (b * e - c * d); tN = (a * e - b * d); - if (sN < 0.0) { // sc < 0 => the s=0 edge is visible. - sN = 0.0; + if (sN < 0.0f) { // sc < 0 => the s=0 edge is visible. + sN = 0.0f; tN = e; tD = c; } else if (sN > sD) { // sc > 1 => the s=1 edge is visible. @@ -95,11 +95,11 @@ public: } } - if (tN < 0.0) { // tc < 0 => the t=0 edge is visible. - tN = 0.0; + if (tN < 0.0f) { // tc < 0 => the t=0 edge is visible. + tN = 0.0f; // Recompute sc for this edge. - if (-d < 0.0) { - sN = 0.0; + if (-d < 0.0f) { + sN = 0.0f; } else if (-d > a) { sN = sD; } else { @@ -109,7 +109,7 @@ public: } else if (tN > tD) { // tc > 1 => the t=1 edge is visible. tN = tD; // Recompute sc for this edge. - if ((-d + b) < 0.0) { + if ((-d + b) < 0.0f) { sN = 0; } else if ((-d + b) > a) { sN = sD; @@ -119,8 +119,8 @@ public: } } // Finally do the division to get sc and tc. - sc = (Math::is_zero_approx(sN) ? 0.0 : sN / sD); - tc = (Math::is_zero_approx(tN) ? 0.0 : tN / tD); + sc = (Math::is_zero_approx(sN) ? 0.0f : sN / sD); + tc = (Math::is_zero_approx(tN) ? 0.0f : tN / tD); // Get the difference of the two closest points. Vector3 dP = w + (sc * u) - (tc * v); // = S1(sc) - S2(tc) @@ -137,12 +137,12 @@ public: return false; } - real_t f = 1.0 / a; + real_t f = 1.0f / a; Vector3 s = p_from - p_v0; real_t u = f * s.dot(h); - if (u < 0.0 || u > 1.0) { + if ((u < 0.0f) || (u > 1.0f)) { return false; } @@ -150,7 +150,7 @@ public: real_t v = f * p_dir.dot(q); - if (v < 0.0 || u + v > 1.0) { + if ((v < 0.0f) || (u + v > 1.0f)) { return false; } @@ -158,7 +158,7 @@ public: // the intersection point is on the line. real_t t = f * e2.dot(q); - if (t > 0.00001) { // ray intersection + if (t > 0.00001f) { // ray intersection if (r_res) { *r_res = p_from + p_dir * t; } @@ -178,12 +178,12 @@ public: return false; } - real_t f = 1.0 / a; + real_t f = 1.0f / a; Vector3 s = p_from - p_v0; real_t u = f * s.dot(h); - if (u < 0.0 || u > 1.0) { + if ((u < 0.0f) || (u > 1.0f)) { return false; } @@ -191,7 +191,7 @@ public: real_t v = f * rel.dot(q); - if (v < 0.0 || u + v > 1.0) { + if ((v < 0.0f) || (u + v > 1.0f)) { return false; } @@ -199,7 +199,7 @@ public: // the intersection point is on the line. real_t t = f * e2.dot(q); - if (t > CMP_EPSILON && t <= 1.0) { // Ray intersection. + if (t > (real_t)CMP_EPSILON && t <= 1.0f) { // Ray intersection. if (r_res) { *r_res = p_from + rel * t; } @@ -213,7 +213,7 @@ public: Vector3 sphere_pos = p_sphere_pos - p_from; Vector3 rel = (p_to - p_from); real_t rel_l = rel.length(); - if (rel_l < CMP_EPSILON) { + if (rel_l < (real_t)CMP_EPSILON) { return false; // Both points are the same. } Vector3 normal = rel / rel_l; @@ -229,7 +229,7 @@ public: real_t inters_d2 = p_sphere_radius * p_sphere_radius - ray_distance * ray_distance; real_t inters_d = sphere_d; - if (inters_d2 >= CMP_EPSILON) { + if (inters_d2 >= (real_t)CMP_EPSILON) { inters_d -= Math::sqrt(inters_d2); } @@ -253,14 +253,14 @@ public: static inline bool segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, real_t p_height, real_t p_radius, Vector3 *r_res = nullptr, Vector3 *r_norm = nullptr, int p_cylinder_axis = 2) { Vector3 rel = (p_to - p_from); real_t rel_l = rel.length(); - if (rel_l < CMP_EPSILON) { + if (rel_l < (real_t)CMP_EPSILON) { return false; // Both points are the same. } ERR_FAIL_COND_V(p_cylinder_axis < 0, false); ERR_FAIL_COND_V(p_cylinder_axis > 2, false); Vector3 cylinder_axis; - cylinder_axis[p_cylinder_axis] = 1.0; + cylinder_axis[p_cylinder_axis] = 1.0f; // First check if they are parallel. Vector3 normal = (rel / rel_l); @@ -269,9 +269,9 @@ public: Vector3 axis_dir; - if (crs_l < CMP_EPSILON) { + if (crs_l < (real_t)CMP_EPSILON) { Vector3 side_axis; - side_axis[(p_cylinder_axis + 1) % 3] = 1.0; // Any side axis OK. + side_axis[(p_cylinder_axis + 1) % 3] = 1.0f; // Any side axis OK. axis_dir = side_axis; } else { axis_dir = crs / crs_l; @@ -285,10 +285,10 @@ public: // Convert to 2D. real_t w2 = p_radius * p_radius - dist * dist; - if (w2 < CMP_EPSILON) { + if (w2 < (real_t)CMP_EPSILON) { return false; // Avoid numerical error. } - Size2 size(Math::sqrt(w2), p_height * 0.5); + Size2 size(Math::sqrt(w2), p_height * 0.5f); Vector3 side_dir = axis_dir.cross(cylinder_axis).normalized(); @@ -366,7 +366,7 @@ public: Vector3 rel = p_to - p_from; real_t rel_l = rel.length(); - if (rel_l < CMP_EPSILON) { + if (rel_l < (real_t)CMP_EPSILON) { return false; } @@ -379,7 +379,7 @@ public: real_t den = p.normal.dot(dir); - if (Math::abs(den) <= CMP_EPSILON) { + if (Math::abs(den) <= (real_t)CMP_EPSILON) { continue; // Ignore parallel plane. } @@ -417,15 +417,15 @@ public: Vector3 p = p_point - p_segment[0]; Vector3 n = p_segment[1] - p_segment[0]; real_t l2 = n.length_squared(); - if (l2 < 1e-20) { + if (l2 < 1e-20f) { return p_segment[0]; // Both points are the same, just give any. } real_t d = n.dot(p) / l2; - if (d <= 0.0) { + if (d <= 0.0f) { return p_segment[0]; // Before first point. - } else if (d >= 1.0) { + } else if (d >= 1.0f) { return p_segment[1]; // After first point. } else { return p_segment[0] + n * d; // Inside. @@ -436,7 +436,7 @@ public: Vector3 p = p_point - p_segment[0]; Vector3 n = p_segment[1] - p_segment[0]; real_t l2 = n.length_squared(); - if (l2 < 1e-20) { + if (l2 < 1e-20f) { return p_segment[0]; // Both points are the same, just give any. } @@ -564,11 +564,11 @@ public: for (int a = 0; a < polygon.size(); a++) { real_t dist = p_plane.distance_to(polygon[a]); - if (dist < -CMP_POINT_IN_PLANE_EPSILON) { + if (dist < (real_t)-CMP_POINT_IN_PLANE_EPSILON) { location_cache[a] = LOC_INSIDE; inside_count++; } else { - if (dist > CMP_POINT_IN_PLANE_EPSILON) { + if (dist > (real_t)CMP_POINT_IN_PLANE_EPSILON) { location_cache[a] = LOC_OUTSIDE; outside_count++; } else { @@ -907,9 +907,9 @@ public: _FORCE_INLINE_ static Vector3 octahedron_map_decode(const Vector2 &p_uv) { // https://twitter.com/Stubbesaurus/status/937994790553227264 - Vector2 f = p_uv * 2.0 - Vector2(1.0, 1.0); + Vector2 f = p_uv * 2.0f - Vector2(1.0f, 1.0f); Vector3 n = Vector3(f.x, f.y, 1.0f - Math::abs(f.x) - Math::abs(f.y)); - float t = CLAMP(-n.z, 0.0, 1.0); + float t = CLAMP(-n.z, 0.0f, 1.0f); n.x += n.x >= 0 ? -t : t; n.y += n.y >= 0 ? -t : t; return n.normalized(); diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index f3d10c3f0d..8c0b87cf4a 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -64,7 +64,7 @@ public: static _ALWAYS_INLINE_ float sinc(float p_x) { return p_x == 0 ? 1 : ::sin(p_x) / p_x; } static _ALWAYS_INLINE_ double sinc(double p_x) { return p_x == 0 ? 1 : ::sin(p_x) / p_x; } - static _ALWAYS_INLINE_ float sincn(float p_x) { return sinc(Math_PI * p_x); } + static _ALWAYS_INLINE_ float sincn(float p_x) { return sinc((float)Math_PI * p_x); } static _ALWAYS_INLINE_ double sincn(double p_x) { return sinc(Math_PI * p_x); } static _ALWAYS_INLINE_ double cosh(double p_x) { return ::cosh(p_x); } @@ -187,7 +187,7 @@ public: static _ALWAYS_INLINE_ double fposmod(double p_x, double p_y) { double value = Math::fmod(p_x, p_y); - if ((value < 0 && p_y > 0) || (value > 0 && p_y < 0)) { + if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { value += p_y; } value += 0.0; @@ -195,10 +195,10 @@ public: } static _ALWAYS_INLINE_ float fposmod(float p_x, float p_y) { float value = Math::fmod(p_x, p_y); - if ((value < 0 && p_y > 0) || (value > 0 && p_y < 0)) { + if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { value += p_y; } - value += 0.0; + value += 0.0f; return value; } static _ALWAYS_INLINE_ float fposmodp(float p_x, float p_y) { @@ -206,7 +206,7 @@ public: if (value < 0) { value += p_y; } - value += 0.0; + value += 0.0f; return value; } static _ALWAYS_INLINE_ double fposmodp(double p_x, double p_y) { @@ -220,21 +220,36 @@ public: static _ALWAYS_INLINE_ int64_t posmod(int64_t p_x, int64_t p_y) { int64_t value = p_x % p_y; - if ((value < 0 && p_y > 0) || (value > 0 && p_y < 0)) { + if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { value += p_y; } return value; } 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); } + static _ALWAYS_INLINE_ float deg2rad(float p_y) { return p_y * (float)(Math_PI / 180.0); } 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_ float rad2deg(float p_y) { return p_y * (float)(180.0 / Math_PI); } static _ALWAYS_INLINE_ double lerp(double p_from, double p_to, double p_weight) { return p_from + (p_to - p_from) * p_weight; } static _ALWAYS_INLINE_ float lerp(float p_from, float p_to, float p_weight) { return p_from + (p_to - p_from) * p_weight; } + static _ALWAYS_INLINE_ double cubic_interpolate(double p_from, double p_to, double p_pre, double p_post, double p_weight) { + return 0.5 * + ((p_from * 2.0) + + (-p_pre + p_to) * p_weight + + (2.0 * p_pre - 5.0 * p_from + 4.0 * p_to - p_post) * (p_weight * p_weight) + + (-p_pre + 3.0 * p_from - 3.0 * p_to + p_post) * (p_weight * p_weight * p_weight)); + } + static _ALWAYS_INLINE_ float cubic_interpolate(float p_from, float p_to, float p_pre, float p_post, float p_weight) { + return 0.5f * + ((p_from * 2.0f) + + (-p_pre + p_to) * p_weight + + (2.0f * p_pre - 5.0f * p_from + 4.0f * p_to - p_post) * (p_weight * p_weight) + + (-p_pre + 3.0f * p_from - 3.0f * p_to + p_post) * (p_weight * p_weight * p_weight)); + } + static _ALWAYS_INLINE_ double lerp_angle(double p_from, double p_to, double p_weight) { double difference = fmod(p_to - p_from, Math_TAU); double distance = fmod(2.0 * difference, Math_TAU) - difference; @@ -270,10 +285,10 @@ public: 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 + SIGN(p_to - p_from) * p_delta; } 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_ float linear2db(float p_linear) { return Math::log(p_linear) * (float)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 _ALWAYS_INLINE_ float db2linear(float p_db) { return Math::exp(p_db * (float)0.11512925464970228420089957273422); } static _ALWAYS_INLINE_ double round(double p_val) { return ::round(p_val); } static _ALWAYS_INLINE_ float round(float p_val) { return ::roundf(p_val); } @@ -330,9 +345,9 @@ public: return true; } // Then check for approximate equality. - float tolerance = CMP_EPSILON * abs(a); - if (tolerance < CMP_EPSILON) { - tolerance = CMP_EPSILON; + float tolerance = (float)CMP_EPSILON * abs(a); + if (tolerance < (float)CMP_EPSILON) { + tolerance = (float)CMP_EPSILON; } return abs(a - b) < tolerance; } @@ -347,7 +362,7 @@ public: } static _ALWAYS_INLINE_ bool is_zero_approx(float s) { - return abs(s) < CMP_EPSILON; + return abs(s) < (float)CMP_EPSILON; } static _ALWAYS_INLINE_ bool is_equal_approx(double a, double b) { diff --git a/core/math/octree.h b/core/math/octree.h index 23ba4c1aa3..e73f8213b3 100644 --- a/core/math/octree.h +++ b/core/math/octree.h @@ -211,11 +211,6 @@ private: E = pair_map.insert(key, pdata); E->get().eA = p_A->pair_list.push_back(&E->get()); E->get().eB = p_B->pair_list.push_back(&E->get()); - - /* - if (pair_callback) - pair_callback(pair_callback_userdata,p_A->userdata,p_B->userdata); - */ } else { E->get().refcount++; } @@ -854,11 +849,6 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) { Octant *o = F->get().octant; typename List<typename Element::OctantOwner, AL>::Element *N = F->next(); - /* - if (!use_pairs) - o->elements.erase( F->get().E ); - */ - if (use_pairs && e.pairable) { o->pairable_elements.erase(F->get().E); } else { diff --git a/core/math/plane.cpp b/core/math/plane.cpp index 8bd4b5ef4f..6881ad4014 100644 --- a/core/math/plane.cpp +++ b/core/math/plane.cpp @@ -58,7 +58,7 @@ Vector3 Plane::get_any_perpendicular_normal() const { static const Vector3 p2 = Vector3(0, 1, 0); Vector3 p; - if (ABS(normal.dot(p1)) > 0.99) { // if too similar to p1 + if (ABS(normal.dot(p1)) > 0.99f) { // if too similar to p1 p = p2; // use p2 } else { p = p1; // use p1 @@ -106,7 +106,7 @@ bool Plane::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 real_t dist = (normal.dot(p_from) - d) / den; //printf("dist is %i\n",dist); - if (dist > CMP_EPSILON) { //this is a ray, before the emitting pos (p_from) doesn't exist + if (dist > (real_t)CMP_EPSILON) { //this is a ray, before the emitting pos (p_from) doesn't exist return false; } @@ -129,7 +129,7 @@ bool Plane::intersects_segment(const Vector3 &p_begin, const Vector3 &p_end, Vec real_t dist = (normal.dot(p_begin) - d) / den; //printf("dist is %i\n",dist); - if (dist < -CMP_EPSILON || dist > (1.0 + CMP_EPSILON)) { + if (dist < (real_t)-CMP_EPSILON || dist > (1.0f + (real_t)CMP_EPSILON)) { return false; } diff --git a/core/math/plane.h b/core/math/plane.h index 8cb6f62b3b..66c1741662 100644 --- a/core/math/plane.h +++ b/core/math/plane.h @@ -35,13 +35,12 @@ class Variant; -class _NO_DISCARD_ Plane { -public: +struct _NO_DISCARD_ Plane { Vector3 normal; real_t d = 0; void set_normal(const Vector3 &p_normal); - _FORCE_INLINE_ Vector3 get_normal() const { return normal; }; ///Point is coplanar, CMP_EPSILON for precision + _FORCE_INLINE_ Vector3 get_normal() const { return normal; }; void normalize(); Plane normalized() const; diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp index 2ce603cb13..0a650a8578 100644 --- a/core/math/quaternion.cpp +++ b/core/math/quaternion.cpp @@ -114,7 +114,7 @@ Quaternion Quaternion::slerp(const Quaternion &p_to, const real_t &p_weight) con cosom = dot(p_to); // adjust signs (if necessary) - if (cosom < 0.0) { + if (cosom < 0.0f) { cosom = -cosom; to1.x = -p_to.x; to1.y = -p_to.y; @@ -129,7 +129,7 @@ Quaternion Quaternion::slerp(const Quaternion &p_to, const real_t &p_weight) con // calculate coefficients - if ((1.0 - cosom) > CMP_EPSILON) { + if ((1.0f - cosom) > (real_t)CMP_EPSILON) { // standard case (slerp) omega = Math::acos(cosom); sinom = Math::sin(omega); @@ -138,7 +138,7 @@ Quaternion Quaternion::slerp(const Quaternion &p_to, const real_t &p_weight) con } else { // "from" and "to" quaternions are very close // ... so we can do a linear interpolation - scale0 = 1.0 - p_weight; + scale0 = 1.0f - p_weight; scale1 = p_weight; } // calculate final values @@ -158,14 +158,14 @@ Quaternion Quaternion::slerpni(const Quaternion &p_to, const real_t &p_weight) c real_t dot = from.dot(p_to); - if (Math::absf(dot) > 0.9999) { + if (Math::absf(dot) > 0.9999f) { return from; } real_t theta = Math::acos(dot), - sinT = 1.0 / Math::sin(theta), + sinT = 1.0f / Math::sin(theta), newFactor = Math::sin(p_weight * theta) * sinT, - invFactor = Math::sin((1.0 - p_weight) * theta) * sinT; + invFactor = Math::sin((1.0f - p_weight) * theta) * sinT; return Quaternion(invFactor * from.x + newFactor * p_to.x, invFactor * from.y + newFactor * p_to.y, @@ -179,7 +179,7 @@ Quaternion Quaternion::cubic_slerp(const Quaternion &p_b, const Quaternion &p_pr ERR_FAIL_COND_V_MSG(!p_b.is_normalized(), Quaternion(), "The end quaternion must be normalized."); #endif //the only way to do slerp :| - real_t t2 = (1.0 - p_weight) * p_weight * 2; + real_t t2 = (1.0f - p_weight) * p_weight * 2; Quaternion sp = this->slerp(p_b, p_weight); Quaternion sq = p_pre_a.slerpni(p_post_b, p_weight); return sp.slerpni(sq, t2); @@ -209,8 +209,8 @@ Quaternion::Quaternion(const Vector3 &p_axis, real_t p_angle) { z = 0; w = 0; } else { - real_t sin_angle = Math::sin(p_angle * 0.5); - real_t cos_angle = Math::cos(p_angle * 0.5); + real_t sin_angle = Math::sin(p_angle * 0.5f); + real_t cos_angle = Math::cos(p_angle * 0.5f); real_t s = sin_angle / d; x = p_axis.x * s; y = p_axis.y * s; @@ -224,9 +224,9 @@ Quaternion::Quaternion(const Vector3 &p_axis, real_t p_angle) { // and similar for other axes. // This implementation uses YXZ convention (Z is the first rotation). Quaternion::Quaternion(const Vector3 &p_euler) { - real_t half_a1 = p_euler.y * 0.5; - real_t half_a2 = p_euler.x * 0.5; - real_t half_a3 = p_euler.z * 0.5; + real_t half_a1 = p_euler.y * 0.5f; + real_t half_a2 = p_euler.x * 0.5f; + real_t half_a3 = p_euler.z * 0.5f; // R = Y(a1).X(a2).Z(a3) convention for Euler angles. // Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6) diff --git a/core/math/quaternion.h b/core/math/quaternion.h index 2575d7d229..38729ac3df 100644 --- a/core/math/quaternion.h +++ b/core/math/quaternion.h @@ -36,8 +36,7 @@ #include "core/math/vector3.h" #include "core/string/ustring.h" -class _NO_DISCARD_ Quaternion { -public: +struct _NO_DISCARD_ Quaternion { union { struct { real_t x; @@ -146,19 +145,19 @@ public: Vector3 c = v0.cross(v1); real_t d = v0.dot(v1); - if (d < -1.0 + CMP_EPSILON) { + if (d < -1.0f + (real_t)CMP_EPSILON) { x = 0; y = 1; z = 0; w = 0; } else { - real_t s = Math::sqrt((1.0 + d) * 2.0); - real_t rs = 1.0 / s; + real_t s = Math::sqrt((1.0f + d) * 2.0f); + real_t rs = 1.0f / s; x = c.x * rs; y = c.y * rs; z = c.z * rs; - w = s * 0.5; + w = s * 0.5f; } } }; @@ -193,7 +192,7 @@ void Quaternion::operator*=(const real_t &s) { } void Quaternion::operator/=(const real_t &s) { - *this *= 1.0 / s; + *this *= 1.0f / s; } Quaternion Quaternion::operator+(const Quaternion &q2) const { @@ -216,7 +215,7 @@ Quaternion Quaternion::operator*(const real_t &s) const { } Quaternion Quaternion::operator/(const real_t &s) const { - return *this * (1.0 / s); + return *this * (1.0f / s); } bool Quaternion::operator==(const Quaternion &p_quaternion) const { diff --git a/core/math/random_pcg.h b/core/math/random_pcg.h index 974dbbfc2e..65fcf67664 100644 --- a/core/math/random_pcg.h +++ b/core/math/random_pcg.h @@ -129,7 +129,7 @@ public: return p_mean + p_deviation * (cos(Math_TAU * randd()) * sqrt(-2.0 * log(randd()))); // Box-Muller transform } _FORCE_INLINE_ float randfn(float p_mean, float p_deviation) { - return p_mean + p_deviation * (cos(Math_TAU * randf()) * sqrt(-2.0 * log(randf()))); // Box-Muller transform + return p_mean + p_deviation * (cos((float)Math_TAU * randf()) * sqrt(-2.0 * log(randf()))); // Box-Muller transform } double random(double p_from, double p_to); diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp index 9047c19434..d6e20bdc3c 100644 --- a/core/math/rect2.cpp +++ b/core/math/rect2.cpp @@ -28,7 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "core/math/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D +#include "rect2.h" + +#include "core/math/rect2i.h" +#include "core/math/transform_2d.h" +#include "core/string/ustring.h" bool Rect2::is_equal_approx(const Rect2 &p_rect) const { return position.is_equal_approx(p_rect.position) && size.is_equal_approx(p_rect.size); @@ -278,6 +282,6 @@ Rect2::operator String() const { return "[P: " + position.operator String() + ", S: " + size + "]"; } -Rect2i::operator String() const { - return "[P: " + position.operator String() + ", S: " + size + "]"; +Rect2::operator Rect2i() const { + return Rect2i(position, size); } diff --git a/core/math/rect2.h b/core/math/rect2.h index 4ea24e8f88..679af933c2 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -31,8 +31,11 @@ #ifndef RECT2_H #define RECT2_H -#include "core/math/vector2.h" // also includes math_funcs and ustring +#include "core/error/error_macros.h" +#include "core/math/vector2.h" +class String; +struct Rect2i; struct Transform2D; struct _NO_DISCARD_ Rect2 { @@ -46,7 +49,7 @@ struct _NO_DISCARD_ Rect2 { real_t get_area() const { return size.width * size.height; } - _FORCE_INLINE_ Vector2 get_center() const { return position + (size * 0.5); } + _FORCE_INLINE_ Vector2 get_center() const { return position + (size * 0.5f); } inline bool intersects(const Rect2 &p_rect, const bool p_include_borders = false) const { #ifdef MATH_CHECKS @@ -179,6 +182,7 @@ struct _NO_DISCARD_ Rect2 { return new_rect; } + inline bool has_point(const Point2 &p_point) const { #ifdef MATH_CHECKS if (unlikely(size.x < 0 || size.y < 0)) { @@ -201,6 +205,7 @@ struct _NO_DISCARD_ Rect2 { return true; } + bool is_equal_approx(const Rect2 &p_rect) const; bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; } @@ -280,7 +285,7 @@ struct _NO_DISCARD_ Rect2 { } Vector2 get_support(const Vector2 &p_normal) const { - Vector2 half_extents = size * 0.5; + Vector2 half_extents = size * 0.5f; Vector2 ofs = position + half_extents; return Vector2( (p_normal.x > 0) ? -half_extents.x : half_extents.x, @@ -302,14 +307,14 @@ struct _NO_DISCARD_ Rect2 { Vector2 r = (b - a); float l = r.length(); - if (l == 0.0) { + if (l == 0.0f) { continue; } //check inside Vector2 tg = r.orthogonal(); float s = tg.dot(center) - tg.dot(a); - if (s < 0.0) { + if (s < 0.0f) { side_plus++; } else { side_minus++; @@ -317,7 +322,7 @@ struct _NO_DISCARD_ Rect2 { //check ray box r /= l; - Vector2 ir(1.0 / r.x, 1.0 / r.y); + Vector2 ir(1.0f / r.x, 1.0f / r.y); // lb is the corner of AABB with minimal coordinates - left bottom, rt is maximal corner // r.org is origin of ray @@ -351,6 +356,7 @@ struct _NO_DISCARD_ Rect2 { } operator String() const; + operator Rect2i() const; Rect2() {} Rect2(real_t p_x, real_t p_y, real_t p_width, real_t p_height) : @@ -363,214 +369,4 @@ struct _NO_DISCARD_ Rect2 { } }; -struct _NO_DISCARD_ Rect2i { - Point2i position; - Size2i size; - - const Point2i &get_position() const { return position; } - void set_position(const Point2i &p_position) { position = p_position; } - const Size2i &get_size() const { return size; } - void set_size(const Size2i &p_size) { size = p_size; } - - int get_area() const { return size.width * size.height; } - - _FORCE_INLINE_ Vector2i get_center() const { return position + (size / 2); } - - inline bool intersects(const Rect2i &p_rect) const { -#ifdef MATH_CHECKS - if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) { - ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); - } -#endif - if (position.x > (p_rect.position.x + p_rect.size.width)) { - return false; - } - if ((position.x + size.width) < p_rect.position.x) { - return false; - } - if (position.y > (p_rect.position.y + p_rect.size.height)) { - return false; - } - if ((position.y + size.height) < p_rect.position.y) { - return false; - } - - return true; - } - - inline bool encloses(const Rect2i &p_rect) const { -#ifdef MATH_CHECKS - if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) { - ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); - } -#endif - return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) && - ((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) && - ((p_rect.position.y + p_rect.size.y) < (position.y + size.y)); - } - - _FORCE_INLINE_ bool has_no_area() const { - return (size.x <= 0 || size.y <= 0); - } - - // Returns the instersection between two Rect2is or an empty Rect2i if there is no intersection - inline Rect2i intersection(const Rect2i &p_rect) const { - Rect2i new_rect = p_rect; - - if (!intersects(new_rect)) { - return Rect2i(); - } - - new_rect.position.x = MAX(p_rect.position.x, position.x); - new_rect.position.y = MAX(p_rect.position.y, position.y); - - Point2i p_rect_end = p_rect.position + p_rect.size; - Point2i end = position + size; - - new_rect.size.x = MIN(p_rect_end.x, end.x) - new_rect.position.x; - new_rect.size.y = MIN(p_rect_end.y, end.y) - new_rect.position.y; - - return new_rect; - } - - inline Rect2i merge(const Rect2i &p_rect) const { ///< return a merged rect -#ifdef MATH_CHECKS - if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) { - ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); - } -#endif - Rect2i new_rect; - - new_rect.position.x = MIN(p_rect.position.x, position.x); - new_rect.position.y = MIN(p_rect.position.y, position.y); - - new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x, position.x + size.x); - new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y, position.y + size.y); - - new_rect.size = new_rect.size - new_rect.position; //make relative again - - return new_rect; - } - bool has_point(const Point2i &p_point) const { -#ifdef MATH_CHECKS - if (unlikely(size.x < 0 || size.y < 0)) { - ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); - } -#endif - if (p_point.x < position.x) { - return false; - } - if (p_point.y < position.y) { - return false; - } - - if (p_point.x >= (position.x + size.x)) { - return false; - } - if (p_point.y >= (position.y + size.y)) { - return false; - } - - return true; - } - - bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; } - bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; } - - Rect2i grow(int p_amount) const { - Rect2i g = *this; - g.position.x -= p_amount; - g.position.y -= p_amount; - g.size.width += p_amount * 2; - g.size.height += p_amount * 2; - return g; - } - - inline Rect2i grow_side(Side p_side, int p_amount) const { - Rect2i g = *this; - g = g.grow_individual((SIDE_LEFT == p_side) ? p_amount : 0, - (SIDE_TOP == p_side) ? p_amount : 0, - (SIDE_RIGHT == p_side) ? p_amount : 0, - (SIDE_BOTTOM == p_side) ? p_amount : 0); - return g; - } - - inline Rect2i grow_side_bind(uint32_t p_side, int p_amount) const { - return grow_side(Side(p_side), p_amount); - } - - inline Rect2i grow_individual(int p_left, int p_top, int p_right, int p_bottom) const { - Rect2i g = *this; - g.position.x -= p_left; - g.position.y -= p_top; - g.size.width += p_left + p_right; - g.size.height += p_top + p_bottom; - - return g; - } - - _FORCE_INLINE_ Rect2i expand(const Vector2i &p_vector) const { - Rect2i r = *this; - r.expand_to(p_vector); - return r; - } - - inline void expand_to(const Point2i &p_vector) { -#ifdef MATH_CHECKS - if (unlikely(size.x < 0 || size.y < 0)) { - ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); - } -#endif - Point2i begin = position; - Point2i end = position + size; - - if (p_vector.x < begin.x) { - begin.x = p_vector.x; - } - if (p_vector.y < begin.y) { - begin.y = p_vector.y; - } - - if (p_vector.x > end.x) { - end.x = p_vector.x; - } - if (p_vector.y > end.y) { - end.y = p_vector.y; - } - - position = begin; - size = end - begin; - } - - _FORCE_INLINE_ Rect2i abs() const { - return Rect2i(Point2i(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs()); - } - - _FORCE_INLINE_ void set_end(const Vector2i &p_end) { - size = p_end - position; - } - - _FORCE_INLINE_ Vector2i get_end() const { - return position + size; - } - - operator String() const; - - operator Rect2() const { return Rect2(position, size); } - - Rect2i() {} - Rect2i(const Rect2 &p_r2) : - position(p_r2.position), - size(p_r2.size) { - } - Rect2i(int p_x, int p_y, int p_width, int p_height) : - position(Point2i(p_x, p_y)), - size(Size2i(p_width, p_height)) { - } - Rect2i(const Point2i &p_pos, const Size2i &p_size) : - position(p_pos), - size(p_size) { - } -}; - #endif // RECT2_H diff --git a/core/math/rect2i.cpp b/core/math/rect2i.cpp new file mode 100644 index 0000000000..0782c450d0 --- /dev/null +++ b/core/math/rect2i.cpp @@ -0,0 +1,42 @@ +/*************************************************************************/ +/* rect2i.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "rect2i.h" + +#include "core/math/rect2.h" +#include "core/string/ustring.h" + +Rect2i::operator String() const { + return "[P: " + position.operator String() + ", S: " + size + "]"; +} + +Rect2i::operator Rect2() const { + return Rect2(position, size); +} diff --git a/core/math/rect2i.h b/core/math/rect2i.h new file mode 100644 index 0000000000..db1459a3e6 --- /dev/null +++ b/core/math/rect2i.h @@ -0,0 +1,245 @@ +/*************************************************************************/ +/* rect2i.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef RECT2I_H +#define RECT2I_H + +#include "core/error/error_macros.h" +#include "core/math/vector2i.h" + +class String; +struct Rect2; + +struct _NO_DISCARD_ Rect2i { + Point2i position; + Size2i size; + + const Point2i &get_position() const { return position; } + void set_position(const Point2i &p_position) { position = p_position; } + const Size2i &get_size() const { return size; } + void set_size(const Size2i &p_size) { size = p_size; } + + int get_area() const { return size.width * size.height; } + + _FORCE_INLINE_ Vector2i get_center() const { return position + (size / 2); } + + inline bool intersects(const Rect2i &p_rect) const { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) { + ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); + } +#endif + if (position.x >= (p_rect.position.x + p_rect.size.width)) { + return false; + } + if ((position.x + size.width) <= p_rect.position.x) { + return false; + } + if (position.y >= (p_rect.position.y + p_rect.size.height)) { + return false; + } + if ((position.y + size.height) <= p_rect.position.y) { + return false; + } + + return true; + } + + inline bool encloses(const Rect2i &p_rect) const { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) { + ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); + } +#endif + return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) && + ((p_rect.position.x + p_rect.size.x) <= (position.x + size.x)) && + ((p_rect.position.y + p_rect.size.y) <= (position.y + size.y)); + } + + _FORCE_INLINE_ bool has_no_area() const { + return (size.x <= 0 || size.y <= 0); + } + + // Returns the instersection between two Rect2is or an empty Rect2i if there is no intersection + inline Rect2i intersection(const Rect2i &p_rect) const { + Rect2i new_rect = p_rect; + + if (!intersects(new_rect)) { + return Rect2i(); + } + + new_rect.position.x = MAX(p_rect.position.x, position.x); + new_rect.position.y = MAX(p_rect.position.y, position.y); + + Point2i p_rect_end = p_rect.position + p_rect.size; + Point2i end = position + size; + + new_rect.size.x = MIN(p_rect_end.x, end.x) - new_rect.position.x; + new_rect.size.y = MIN(p_rect_end.y, end.y) - new_rect.position.y; + + return new_rect; + } + + inline Rect2i merge(const Rect2i &p_rect) const { ///< return a merged rect +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) { + ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); + } +#endif + Rect2i new_rect; + + new_rect.position.x = MIN(p_rect.position.x, position.x); + new_rect.position.y = MIN(p_rect.position.y, position.y); + + new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x, position.x + size.x); + new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y, position.y + size.y); + + new_rect.size = new_rect.size - new_rect.position; //make relative again + + return new_rect; + } + bool has_point(const Point2i &p_point) const { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0)) { + ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); + } +#endif + if (p_point.x < position.x) { + return false; + } + if (p_point.y < position.y) { + return false; + } + + if (p_point.x >= (position.x + size.x)) { + return false; + } + if (p_point.y >= (position.y + size.y)) { + return false; + } + + return true; + } + + bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; } + bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; } + + Rect2i grow(int p_amount) const { + Rect2i g = *this; + g.position.x -= p_amount; + g.position.y -= p_amount; + g.size.width += p_amount * 2; + g.size.height += p_amount * 2; + return g; + } + + inline Rect2i grow_side(Side p_side, int p_amount) const { + Rect2i g = *this; + g = g.grow_individual((SIDE_LEFT == p_side) ? p_amount : 0, + (SIDE_TOP == p_side) ? p_amount : 0, + (SIDE_RIGHT == p_side) ? p_amount : 0, + (SIDE_BOTTOM == p_side) ? p_amount : 0); + return g; + } + + inline Rect2i grow_side_bind(uint32_t p_side, int p_amount) const { + return grow_side(Side(p_side), p_amount); + } + + inline Rect2i grow_individual(int p_left, int p_top, int p_right, int p_bottom) const { + Rect2i g = *this; + g.position.x -= p_left; + g.position.y -= p_top; + g.size.width += p_left + p_right; + g.size.height += p_top + p_bottom; + + return g; + } + + _FORCE_INLINE_ Rect2i expand(const Vector2i &p_vector) const { + Rect2i r = *this; + r.expand_to(p_vector); + return r; + } + + inline void expand_to(const Point2i &p_vector) { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0)) { + ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size."); + } +#endif + Point2i begin = position; + Point2i end = position + size; + + if (p_vector.x < begin.x) { + begin.x = p_vector.x; + } + if (p_vector.y < begin.y) { + begin.y = p_vector.y; + } + + if (p_vector.x > end.x) { + end.x = p_vector.x; + } + if (p_vector.y > end.y) { + end.y = p_vector.y; + } + + position = begin; + size = end - begin; + } + + _FORCE_INLINE_ Rect2i abs() const { + return Rect2i(Point2i(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs()); + } + + _FORCE_INLINE_ void set_end(const Vector2i &p_end) { + size = p_end - position; + } + + _FORCE_INLINE_ Vector2i get_end() const { + return position + size; + } + + operator String() const; + operator Rect2() const; + + Rect2i() {} + Rect2i(int p_x, int p_y, int p_width, int p_height) : + position(Point2i(p_x, p_y)), + size(Size2i(p_width, p_height)) { + } + Rect2i(const Point2i &p_pos, const Size2i &p_size) : + position(p_pos), + size(p_size) { + } +}; + +#endif // RECT2I_H diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp index 0201cf575c..71953e4130 100644 --- a/core/math/transform_2d.cpp +++ b/core/math/transform_2d.cpp @@ -30,6 +30,8 @@ #include "transform_2d.h" +#include "core/string/ustring.h" + void Transform2D::invert() { // FIXME: this function assumes the basis is a rotation matrix, with no scaling. // Transform2D::affine_inverse can handle matrices with scaling, so GDScript should eventually use that. @@ -48,7 +50,7 @@ void Transform2D::affine_invert() { #ifdef MATH_CHECKS ERR_FAIL_COND(det == 0); #endif - real_t idet = 1.0 / det; + real_t idet = 1.0f / det; SWAP(elements[0][0], elements[1][1]); elements[0] *= Vector2(idet, -idet); @@ -69,12 +71,12 @@ void Transform2D::rotate(const real_t p_phi) { real_t Transform2D::get_skew() const { real_t det = basis_determinant(); - return Math::acos(elements[0].normalized().dot(SIGN(det) * elements[1].normalized())) - Math_PI * 0.5; + return Math::acos(elements[0].normalized().dot(SIGN(det) * elements[1].normalized())) - (real_t)Math_PI * 0.5f; } void Transform2D::set_skew(const real_t p_angle) { real_t det = basis_determinant(); - elements[1] = SIGN(det) * elements[0].rotated((Math_PI * 0.5 + p_angle)).normalized() * elements[1].length(); + elements[1] = SIGN(det) * elements[0].rotated(((real_t)Math_PI * 0.5f + p_angle)).normalized() * elements[1].length(); } real_t Transform2D::get_rotation() const { @@ -266,11 +268,11 @@ Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, const real_t dot = v1.dot(v2); - dot = CLAMP(dot, -1.0, 1.0); + dot = CLAMP(dot, -1.0f, 1.0f); Vector2 v; - if (dot > 0.9995) { + if (dot > 0.9995f) { v = v1.lerp(v2, p_c).normalized(); //linearly interpolate to avoid numerical precision issues } else { real_t angle = p_c * Math::acos(dot); diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h index 6c2d51bd9b..f4546c13c8 100644 --- a/core/math/transform_2d.h +++ b/core/math/transform_2d.h @@ -31,7 +31,12 @@ #ifndef TRANSFORM_2D_H #define TRANSFORM_2D_H -#include "core/math/rect2.h" // also includes vector2, math_funcs, and ustring +#include "core/math/math_funcs.h" +#include "core/math/rect2.h" +#include "core/math/vector2.h" +#include "core/templates/vector.h" + +class String; struct _NO_DISCARD_ Transform2D { // Warning #1: basis of Transform2D is stored differently from Basis. In terms of elements array, the basis matrix looks like "on paper": diff --git a/core/math/transform_3d.h b/core/math/transform_3d.h index c16c278e74..3b4762e221 100644 --- a/core/math/transform_3d.h +++ b/core/math/transform_3d.h @@ -28,15 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef TRANSFORM_H -#define TRANSFORM_H +#ifndef TRANSFORM_3D_H +#define TRANSFORM_3D_H #include "core/math/aabb.h" #include "core/math/basis.h" #include "core/math/plane.h" -class _NO_DISCARD_ Transform3D { -public: +struct _NO_DISCARD_ Transform3D { Basis basis; Vector3 origin; @@ -265,4 +264,4 @@ _FORCE_INLINE_ Plane Transform3D::xform_inv_fast(const Plane &p_plane, const Tra return Plane(normal, d); } -#endif // TRANSFORM_H +#endif // TRANSFORM_3D_H diff --git a/core/math/triangulate.cpp b/core/math/triangulate.cpp index f3e3de5fc2..0a9872ae08 100644 --- a/core/math/triangulate.cpp +++ b/core/math/triangulate.cpp @@ -39,7 +39,7 @@ real_t Triangulate::get_area(const Vector<Vector2> &contour) { for (int p = n - 1, q = 0; q < n; p = q++) { A += c[p].cross(c[q]); } - return A * 0.5; + return A * 0.5f; } /* `is_inside_triangle` decides if a point P is inside the triangle @@ -70,9 +70,9 @@ bool Triangulate::is_inside_triangle(real_t Ax, real_t Ay, bCROSScp = bx * cpy - by * cpx; if (include_edges) { - return ((aCROSSbp > 0.0) && (bCROSScp > 0.0) && (cCROSSap > 0.0)); + return ((aCROSSbp > 0.0f) && (bCROSScp > 0.0f) && (cCROSSap > 0.0f)); } else { - return ((aCROSSbp >= 0.0) && (bCROSScp >= 0.0) && (cCROSSap >= 0.0)); + return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); } } @@ -128,7 +128,7 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul /* we want a counter-clockwise polygon in V */ - if (0.0 < get_area(contour)) { + if (0.0f < get_area(contour)) { for (int v = 0; v < n; v++) { V.write[v] = v; } diff --git a/core/math/triangulate.h b/core/math/triangulate.h index d96bdb8cab..0bfcfcb978 100644 --- a/core/math/triangulate.h +++ b/core/math/triangulate.h @@ -32,6 +32,7 @@ #define TRIANGULATE_H #include "core/math/vector2.h" +#include "core/templates/vector.h" /* https://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index 676a0004ea..a27227905c 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -30,6 +30,9 @@ #include "vector2.h" +#include "core/math/vector2i.h" +#include "core/string/ustring.h" + real_t Vector2::angle() const { return Math::atan2(y, x); } @@ -150,29 +153,17 @@ Vector2 Vector2::limit_length(const real_t p_len) const { } Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, const real_t p_weight) const { - Vector2 p0 = p_pre_a; - Vector2 p1 = *this; - Vector2 p2 = p_b; - Vector2 p3 = p_post_b; - - real_t t = p_weight; - real_t t2 = t * t; - real_t t3 = t2 * t; - - Vector2 out; - out = 0.5 * - ((p1 * 2.0) + - (-p0 + p2) * t + - (2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 + - (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3); - return out; + Vector2 res = *this; + res.x = Math::cubic_interpolate(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight); + res.y = Math::cubic_interpolate(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight); + return res; } Vector2 Vector2::move_toward(const Vector2 &p_to, const real_t p_delta) const { Vector2 v = *this; Vector2 vd = p_to - v; real_t len = vd.length(); - return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta; + return len <= p_delta || len < (real_t)CMP_EPSILON ? p_to : v + vd / len * p_delta; } // slide returns the component of the vector along the given plane, specified by its normal vector. @@ -191,7 +182,7 @@ Vector2 Vector2::reflect(const Vector2 &p_normal) const { #ifdef MATH_CHECKS ERR_FAIL_COND_V_MSG(!p_normal.is_normalized(), Vector2(), "The normal Vector2 must be normalized."); #endif - return 2.0 * p_normal * this->dot(p_normal) - *this; + return 2.0f * p_normal * this->dot(p_normal) - *this; } bool Vector2::is_equal_approx(const Vector2 &p_v) const { @@ -202,91 +193,6 @@ Vector2::operator String() const { return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ")"; } -/* Vector2i */ - -Vector2i Vector2i::clamp(const Vector2i &p_min, const Vector2i &p_max) const { - return Vector2i( - CLAMP(x, p_min.x, p_max.x), - CLAMP(y, p_min.y, p_max.y)); -} - -int64_t Vector2i::length_squared() const { - return x * (int64_t)x + y * (int64_t)y; -} - -double Vector2i::length() const { - return Math::sqrt((double)length_squared()); -} - -Vector2i Vector2i::operator+(const Vector2i &p_v) const { - return Vector2i(x + p_v.x, y + p_v.y); -} - -void Vector2i::operator+=(const Vector2i &p_v) { - x += p_v.x; - y += p_v.y; -} - -Vector2i Vector2i::operator-(const Vector2i &p_v) const { - return Vector2i(x - p_v.x, y - p_v.y); -} - -void Vector2i::operator-=(const Vector2i &p_v) { - x -= p_v.x; - y -= p_v.y; -} - -Vector2i Vector2i::operator*(const Vector2i &p_v1) const { - return Vector2i(x * p_v1.x, y * p_v1.y); -} - -Vector2i Vector2i::operator*(const int32_t &rvalue) const { - return Vector2i(x * rvalue, y * rvalue); -} - -void Vector2i::operator*=(const int32_t &rvalue) { - x *= rvalue; - y *= rvalue; -} - -Vector2i Vector2i::operator/(const Vector2i &p_v1) const { - return Vector2i(x / p_v1.x, y / p_v1.y); -} - -Vector2i Vector2i::operator/(const int32_t &rvalue) const { - return Vector2i(x / rvalue, y / rvalue); -} - -void Vector2i::operator/=(const int32_t &rvalue) { - x /= rvalue; - y /= rvalue; -} - -Vector2i Vector2i::operator%(const Vector2i &p_v1) const { - return Vector2i(x % p_v1.x, y % p_v1.y); -} - -Vector2i Vector2i::operator%(const int32_t &rvalue) const { - return Vector2i(x % rvalue, y % rvalue); -} - -void Vector2i::operator%=(const int32_t &rvalue) { - x %= rvalue; - y %= rvalue; -} - -Vector2i Vector2i::operator-() const { - return Vector2i(-x, -y); -} - -bool Vector2i::operator==(const Vector2i &p_vec2) const { - return x == p_vec2.x && y == p_vec2.y; -} - -bool Vector2i::operator!=(const Vector2i &p_vec2) const { - return x != p_vec2.x || y != p_vec2.y; -} - -Vector2i::operator String() const { - return "(" + itos(x) + ", " + itos(y) + ")"; +Vector2::operator Vector2i() const { + return Vector2i(x, y); } diff --git a/core/math/vector2.h b/core/math/vector2.h index af40b9e68d..a2680b84fc 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -32,8 +32,8 @@ #define VECTOR2_H #include "core/math/math_funcs.h" -#include "core/string/ustring.h" +class String; struct Vector2i; struct _NO_DISCARD_ Vector2 { @@ -60,10 +60,10 @@ struct _NO_DISCARD_ Vector2 { }; _FORCE_INLINE_ real_t &operator[](int p_idx) { - return p_idx ? y : x; + return coord[p_idx]; } _FORCE_INLINE_ const real_t &operator[](int p_idx) const { - return p_idx ? y : x; + return coord[p_idx]; } _FORCE_INLINE_ void set_all(const real_t p_value) { @@ -167,6 +167,7 @@ struct _NO_DISCARD_ Vector2 { real_t aspect() const { return width / height; } operator String() const; + operator Vector2i() const; _FORCE_INLINE_ Vector2() {} _FORCE_INLINE_ Vector2(const real_t p_x, const real_t p_y) { @@ -179,22 +180,6 @@ _FORCE_INLINE_ Vector2 Vector2::plane_project(const real_t p_d, const Vector2 &p return p_vec - *this * (dot(p_vec) - p_d); } -_FORCE_INLINE_ Vector2 operator*(const float p_scalar, const Vector2 &p_vec) { - return p_vec * p_scalar; -} - -_FORCE_INLINE_ Vector2 operator*(const double p_scalar, const Vector2 &p_vec) { - return p_vec * p_scalar; -} - -_FORCE_INLINE_ Vector2 operator*(const int32_t p_scalar, const Vector2 &p_vec) { - return p_vec * p_scalar; -} - -_FORCE_INLINE_ Vector2 operator*(const int64_t p_scalar, const Vector2 &p_vec) { - return p_vec * p_scalar; -} - _FORCE_INLINE_ Vector2 Vector2::operator+(const Vector2 &p_v) const { return Vector2(x + p_v.x, y + p_v.y); } @@ -263,7 +248,7 @@ Vector2 Vector2::lerp(const Vector2 &p_to, const real_t p_weight) const { Vector2 Vector2::slerp(const Vector2 &p_to, const real_t p_weight) const { real_t start_length_sq = length_squared(); real_t end_length_sq = p_to.length_squared(); - if (unlikely(start_length_sq == 0.0 || end_length_sq == 0.0)) { + if (unlikely(start_length_sq == 0.0f || end_length_sq == 0.0f)) { // Zero length vectors have no angle, so the best we can do is either lerp or throw an error. return lerp(p_to, p_weight); } @@ -279,116 +264,26 @@ Vector2 Vector2::direction_to(const Vector2 &p_to) const { return ret; } -typedef Vector2 Size2; -typedef Vector2 Point2; - -/* INTEGER STUFF */ - -struct _NO_DISCARD_ Vector2i { - enum Axis { - AXIS_X, - AXIS_Y, - }; - - union { - int32_t x = 0; - int32_t width; - }; - union { - int32_t y = 0; - int32_t height; - }; - - _FORCE_INLINE_ int32_t &operator[](int p_idx) { - return p_idx ? y : x; - } - _FORCE_INLINE_ const int32_t &operator[](int p_idx) const { - return p_idx ? y : x; - } - - _FORCE_INLINE_ Vector2i::Axis min_axis_index() const { - return x < y ? Vector2i::AXIS_X : Vector2i::AXIS_Y; - } - - _FORCE_INLINE_ Vector2i::Axis max_axis_index() const { - return x < y ? Vector2i::AXIS_Y : Vector2i::AXIS_X; - } - - Vector2i min(const Vector2i &p_vector2i) const { - return Vector2(MIN(x, p_vector2i.x), MIN(y, p_vector2i.y)); - } - - Vector2i max(const Vector2i &p_vector2i) const { - return Vector2(MAX(x, p_vector2i.x), MAX(y, p_vector2i.y)); - } - - Vector2i operator+(const Vector2i &p_v) const; - void operator+=(const Vector2i &p_v); - Vector2i operator-(const Vector2i &p_v) const; - void operator-=(const Vector2i &p_v); - Vector2i operator*(const Vector2i &p_v1) const; - - Vector2i operator*(const int32_t &rvalue) const; - void operator*=(const int32_t &rvalue); - - Vector2i operator/(const Vector2i &p_v1) const; - Vector2i operator/(const int32_t &rvalue) const; - void operator/=(const int32_t &rvalue); - - Vector2i operator%(const Vector2i &p_v1) const; - Vector2i operator%(const int32_t &rvalue) const; - void operator%=(const int32_t &rvalue); - - Vector2i operator-() const; - bool operator<(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); } - bool operator>(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); } - - bool operator<=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); } - bool operator>=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); } - - bool operator==(const Vector2i &p_vec2) const; - bool operator!=(const Vector2i &p_vec2) const; - - int64_t length_squared() const; - double length() const; - - real_t aspect() const { return width / (real_t)height; } - Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); } - Vector2i abs() const { return Vector2i(ABS(x), ABS(y)); } - Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const; - - operator String() const; - - operator Vector2() const { return Vector2(x, y); } +// Multiplication operators required to workaround issues with LLVM using implicit conversion +// to Vector2i instead for integers where it should not. - inline Vector2i() {} - inline Vector2i(const Vector2 &p_vec2) { - x = (int32_t)p_vec2.x; - y = (int32_t)p_vec2.y; - } - inline Vector2i(const int32_t p_x, const int32_t p_y) { - x = p_x; - y = p_y; - } -}; - -_FORCE_INLINE_ Vector2i operator*(const int32_t &p_scalar, const Vector2i &p_vector) { - return p_vector * p_scalar; +_FORCE_INLINE_ Vector2 operator*(const float p_scalar, const Vector2 &p_vec) { + return p_vec * p_scalar; } -_FORCE_INLINE_ Vector2i operator*(const int64_t &p_scalar, const Vector2i &p_vector) { - return p_vector * p_scalar; +_FORCE_INLINE_ Vector2 operator*(const double p_scalar, const Vector2 &p_vec) { + return p_vec * p_scalar; } -_FORCE_INLINE_ Vector2i operator*(const float &p_scalar, const Vector2i &p_vector) { - return p_vector * p_scalar; +_FORCE_INLINE_ Vector2 operator*(const int32_t p_scalar, const Vector2 &p_vec) { + return p_vec * p_scalar; } -_FORCE_INLINE_ Vector2i operator*(const double &p_scalar, const Vector2i &p_vector) { - return p_vector * p_scalar; +_FORCE_INLINE_ Vector2 operator*(const int64_t p_scalar, const Vector2 &p_vec) { + return p_vec * p_scalar; } -typedef Vector2i Size2i; -typedef Vector2i Point2i; +typedef Vector2 Size2; +typedef Vector2 Point2; #endif // VECTOR2_H diff --git a/core/math/vector2i.cpp b/core/math/vector2i.cpp new file mode 100644 index 0000000000..dfed42e4d6 --- /dev/null +++ b/core/math/vector2i.cpp @@ -0,0 +1,125 @@ +/*************************************************************************/ +/* vector2i.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "vector2i.h" + +#include "core/math/vector2.h" +#include "core/string/ustring.h" + +Vector2i Vector2i::clamp(const Vector2i &p_min, const Vector2i &p_max) const { + return Vector2i( + CLAMP(x, p_min.x, p_max.x), + CLAMP(y, p_min.y, p_max.y)); +} + +int64_t Vector2i::length_squared() const { + return x * (int64_t)x + y * (int64_t)y; +} + +double Vector2i::length() const { + return Math::sqrt((double)length_squared()); +} + +Vector2i Vector2i::operator+(const Vector2i &p_v) const { + return Vector2i(x + p_v.x, y + p_v.y); +} + +void Vector2i::operator+=(const Vector2i &p_v) { + x += p_v.x; + y += p_v.y; +} + +Vector2i Vector2i::operator-(const Vector2i &p_v) const { + return Vector2i(x - p_v.x, y - p_v.y); +} + +void Vector2i::operator-=(const Vector2i &p_v) { + x -= p_v.x; + y -= p_v.y; +} + +Vector2i Vector2i::operator*(const Vector2i &p_v1) const { + return Vector2i(x * p_v1.x, y * p_v1.y); +} + +Vector2i Vector2i::operator*(const int32_t &rvalue) const { + return Vector2i(x * rvalue, y * rvalue); +} + +void Vector2i::operator*=(const int32_t &rvalue) { + x *= rvalue; + y *= rvalue; +} + +Vector2i Vector2i::operator/(const Vector2i &p_v1) const { + return Vector2i(x / p_v1.x, y / p_v1.y); +} + +Vector2i Vector2i::operator/(const int32_t &rvalue) const { + return Vector2i(x / rvalue, y / rvalue); +} + +void Vector2i::operator/=(const int32_t &rvalue) { + x /= rvalue; + y /= rvalue; +} + +Vector2i Vector2i::operator%(const Vector2i &p_v1) const { + return Vector2i(x % p_v1.x, y % p_v1.y); +} + +Vector2i Vector2i::operator%(const int32_t &rvalue) const { + return Vector2i(x % rvalue, y % rvalue); +} + +void Vector2i::operator%=(const int32_t &rvalue) { + x %= rvalue; + y %= rvalue; +} + +Vector2i Vector2i::operator-() const { + return Vector2i(-x, -y); +} + +bool Vector2i::operator==(const Vector2i &p_vec2) const { + return x == p_vec2.x && y == p_vec2.y; +} + +bool Vector2i::operator!=(const Vector2i &p_vec2) const { + return x != p_vec2.x || y != p_vec2.y; +} + +Vector2i::operator String() const { + return "(" + itos(x) + ", " + itos(y) + ")"; +} + +Vector2i::operator Vector2() const { + return Vector2((int32_t)x, (int32_t)y); +} diff --git a/core/math/vector2i.h b/core/math/vector2i.h new file mode 100644 index 0000000000..3f5f12d4dd --- /dev/null +++ b/core/math/vector2i.h @@ -0,0 +1,149 @@ +/*************************************************************************/ +/* vector2i.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef VECTOR2I_H +#define VECTOR2I_H + +#include "core/math/math_funcs.h" + +class String; +struct Vector2; + +struct _NO_DISCARD_ Vector2i { + enum Axis { + AXIS_X, + AXIS_Y, + }; + + union { + struct { + union { + int32_t x; + int32_t width; + }; + union { + int32_t y; + int32_t height; + }; + }; + + int32_t coord[2] = { 0 }; + }; + + _FORCE_INLINE_ int32_t &operator[](int p_idx) { + return coord[p_idx]; + } + _FORCE_INLINE_ const int32_t &operator[](int p_idx) const { + return coord[p_idx]; + } + + _FORCE_INLINE_ Vector2i::Axis min_axis_index() const { + return x < y ? Vector2i::AXIS_X : Vector2i::AXIS_Y; + } + + _FORCE_INLINE_ Vector2i::Axis max_axis_index() const { + return x < y ? Vector2i::AXIS_Y : Vector2i::AXIS_X; + } + + Vector2i min(const Vector2i &p_vector2i) const { + return Vector2i(MIN(x, p_vector2i.x), MIN(y, p_vector2i.y)); + } + + Vector2i max(const Vector2i &p_vector2i) const { + return Vector2i(MAX(x, p_vector2i.x), MAX(y, p_vector2i.y)); + } + + Vector2i operator+(const Vector2i &p_v) const; + void operator+=(const Vector2i &p_v); + Vector2i operator-(const Vector2i &p_v) const; + void operator-=(const Vector2i &p_v); + Vector2i operator*(const Vector2i &p_v1) const; + + Vector2i operator*(const int32_t &rvalue) const; + void operator*=(const int32_t &rvalue); + + Vector2i operator/(const Vector2i &p_v1) const; + Vector2i operator/(const int32_t &rvalue) const; + void operator/=(const int32_t &rvalue); + + Vector2i operator%(const Vector2i &p_v1) const; + Vector2i operator%(const int32_t &rvalue) const; + void operator%=(const int32_t &rvalue); + + Vector2i operator-() const; + bool operator<(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); } + bool operator>(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); } + + bool operator<=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); } + bool operator>=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); } + + bool operator==(const Vector2i &p_vec2) const; + bool operator!=(const Vector2i &p_vec2) const; + + int64_t length_squared() const; + double length() const; + + real_t aspect() const { return width / (real_t)height; } + Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); } + Vector2i abs() const { return Vector2i(ABS(x), ABS(y)); } + Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const; + + operator String() const; + operator Vector2() const; + + inline Vector2i() {} + inline Vector2i(const int32_t p_x, const int32_t p_y) { + x = p_x; + y = p_y; + } +}; + +// Multiplication operators required to workaround issues with LLVM using implicit conversion. + +_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; + +#endif // VECTOR2I_H diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index b6965b3c32..87b2ac7104 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -31,6 +31,9 @@ #include "vector3.h" #include "core/math/basis.h" +#include "core/math/vector2.h" +#include "core/math/vector3i.h" +#include "core/string/ustring.h" void Vector3::rotate(const Vector3 &p_axis, const real_t p_phi) { *this = Basis(p_axis, p_phi).xform(*this); @@ -83,29 +86,43 @@ Vector3 Vector3::limit_length(const real_t p_len) const { } Vector3 Vector3::cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight) const { - Vector3 p0 = p_pre_a; - Vector3 p1 = *this; - Vector3 p2 = p_b; - Vector3 p3 = p_post_b; - - real_t t = p_weight; - real_t t2 = t * t; - real_t t3 = t2 * t; - - Vector3 out; - out = 0.5 * - ((p1 * 2.0) + - (-p0 + p2) * t + - (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3) * t2 + - (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3); - return out; + Vector3 res = *this; + res.x = Math::cubic_interpolate(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight); + res.y = Math::cubic_interpolate(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight); + res.z = Math::cubic_interpolate(res.z, p_b.z, p_pre_a.z, p_post_b.z, p_weight); + return res; } Vector3 Vector3::move_toward(const Vector3 &p_to, const real_t p_delta) const { Vector3 v = *this; Vector3 vd = p_to - v; real_t len = vd.length(); - return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta; + return len <= p_delta || len < (real_t)CMP_EPSILON ? p_to : v + vd / len * p_delta; +} + +Vector2 Vector3::octahedron_encode() const { + Vector3 n = *this; + n /= Math::abs(n.x) + Math::abs(n.y) + Math::abs(n.z); + Vector2 o; + if (n.z >= 0.0f) { + o.x = n.x; + o.y = n.y; + } else { + o.x = (1.0f - Math::abs(n.y)) * (n.x >= 0.0f ? 1.0f : -1.0f); + o.y = (1.0f - Math::abs(n.x)) * (n.y >= 0.0f ? 1.0f : -1.0f); + } + o.x = o.x * 0.5f + 0.5f; + o.y = o.y * 0.5f + 0.5f; + return o; +} + +Vector3 Vector3::octahedron_decode(const Vector2 &p_oct) { + Vector2 f(p_oct.x * 2.0f - 1.0f, p_oct.y * 2.0f - 1.0f); + Vector3 n(f.x, f.y, 1.0f - Math::abs(f.x) - Math::abs(f.y)); + float t = CLAMP(-n.z, 0.0f, 1.0f); + n.x += n.x >= 0 ? -t : t; + n.y += n.y >= 0 ? -t : t; + return n.normalized(); } Basis Vector3::outer(const Vector3 &p_with) const { @@ -123,3 +140,7 @@ bool Vector3::is_equal_approx(const Vector3 &p_v) const { Vector3::operator String() const { return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ")"; } + +Vector3::operator Vector3i() const { + return Vector3i(x, y, z); +} diff --git a/core/math/vector3.h b/core/math/vector3.h index b62edef40f..89b0095741 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -31,11 +31,13 @@ #ifndef VECTOR3_H #define VECTOR3_H +#include "core/error/error_macros.h" #include "core/math/math_funcs.h" -#include "core/math/vector2.h" -#include "core/math/vector3i.h" -#include "core/string/ustring.h" -class Basis; + +class String; +struct Basis; +struct Vector2; +struct Vector3i; struct _NO_DISCARD_ Vector3 { static const int AXIS_COUNT = 3; @@ -103,30 +105,8 @@ struct _NO_DISCARD_ Vector3 { Vector3 cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight) const; Vector3 move_toward(const Vector3 &p_to, const real_t p_delta) const; - _FORCE_INLINE_ Vector2 octahedron_encode() const { - Vector3 n = *this; - n /= Math::abs(n.x) + Math::abs(n.y) + Math::abs(n.z); - Vector2 o; - if (n.z >= 0.0) { - o.x = n.x; - o.y = n.y; - } else { - o.x = (1.0 - Math::abs(n.y)) * (n.x >= 0.0 ? 1.0 : -1.0); - o.y = (1.0 - Math::abs(n.x)) * (n.y >= 0.0 ? 1.0 : -1.0); - } - o.x = o.x * 0.5 + 0.5; - o.y = o.y * 0.5 + 0.5; - return o; - } - - static _FORCE_INLINE_ Vector3 octahedron_decode(const Vector2 &p_oct) { - Vector2 f(p_oct.x * 2.0 - 1.0, p_oct.y * 2.0 - 1.0); - Vector3 n(f.x, f.y, 1.0f - Math::abs(f.x) - Math::abs(f.y)); - float t = CLAMP(-n.z, 0.0, 1.0); - n.x += n.x >= 0 ? -t : t; - n.y += n.y >= 0 ? -t : t; - return n.normalized(); - } + Vector2 octahedron_encode() const; + static Vector3 octahedron_decode(const Vector2 &p_oct); _FORCE_INLINE_ Vector3 cross(const Vector3 &p_with) const; _FORCE_INLINE_ real_t dot(const Vector3 &p_with) const; @@ -182,16 +162,9 @@ struct _NO_DISCARD_ Vector3 { _FORCE_INLINE_ bool operator>=(const Vector3 &p_v) const; operator String() const; - _FORCE_INLINE_ operator Vector3i() const { - return Vector3i(x, y, z); - } + operator Vector3i() const; _FORCE_INLINE_ Vector3() {} - _FORCE_INLINE_ Vector3(const Vector3i &p_ivec) { - x = p_ivec.x; - y = p_ivec.y; - z = p_ivec.z; - } _FORCE_INLINE_ Vector3(const real_t p_x, const real_t p_y, const real_t p_z) { x = p_x; y = p_y; @@ -242,7 +215,7 @@ Vector3 Vector3::lerp(const Vector3 &p_to, const real_t p_weight) const { Vector3 Vector3::slerp(const Vector3 &p_to, const real_t p_weight) const { real_t start_length_sq = length_squared(); real_t end_length_sq = p_to.length_squared(); - if (unlikely(start_length_sq == 0.0 || end_length_sq == 0.0)) { + if (unlikely(start_length_sq == 0.0f || end_length_sq == 0.0f)) { // Zero length vectors have no angle, so the best we can do is either lerp or throw an error. return lerp(p_to, p_weight); } @@ -342,6 +315,9 @@ Vector3 &Vector3::operator*=(const real_t p_scalar) { return *this; } +// Multiplication operators required to workaround issues with LLVM using implicit conversion +// to Vector3i instead for integers where it should not. + _FORCE_INLINE_ Vector3 operator*(const float p_scalar, const Vector3 &p_vec) { return p_vec * p_scalar; } @@ -473,7 +449,7 @@ bool Vector3::is_normalized() const { } Vector3 Vector3::inverse() const { - return Vector3(1.0 / x, 1.0 / y, 1.0 / z); + return Vector3(1.0f / x, 1.0f / y, 1.0f / z); } void Vector3::zero() { @@ -496,7 +472,7 @@ Vector3 Vector3::reflect(const Vector3 &p_normal) const { #ifdef MATH_CHECKS ERR_FAIL_COND_V_MSG(!p_normal.is_normalized(), Vector3(), "The normal Vector3 must be normalized."); #endif - return 2.0 * p_normal * this->dot(p_normal) - *this; + return 2.0f * p_normal * this->dot(p_normal) - *this; } #endif // VECTOR3_H diff --git a/core/math/vector3i.cpp b/core/math/vector3i.cpp index ac79b3c7ea..b8e74ea6d2 100644 --- a/core/math/vector3i.cpp +++ b/core/math/vector3i.cpp @@ -30,6 +30,9 @@ #include "vector3i.h" +#include "core/math/vector3.h" +#include "core/string/ustring.h" + void Vector3i::set_axis(const int p_axis, const int32_t p_value) { ERR_FAIL_INDEX(p_axis, 3); coord[p_axis] = p_value; @@ -58,3 +61,7 @@ Vector3i Vector3i::clamp(const Vector3i &p_min, const Vector3i &p_max) const { Vector3i::operator String() const { return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ")"; } + +Vector3i::operator Vector3() const { + return Vector3(x, y, z); +} diff --git a/core/math/vector3i.h b/core/math/vector3i.h index 1564ee9173..2a4c7e2e97 100644 --- a/core/math/vector3i.h +++ b/core/math/vector3i.h @@ -32,8 +32,9 @@ #define VECTOR3I_H #include "core/math/math_funcs.h" -#include "core/string/ustring.h" -#include "core/typedefs.h" + +class String; +struct Vector3; struct _NO_DISCARD_ Vector3i { enum Axis { @@ -105,6 +106,7 @@ struct _NO_DISCARD_ Vector3i { _FORCE_INLINE_ bool operator>=(const Vector3i &p_v) const; operator String() const; + operator Vector3() const; _FORCE_INLINE_ Vector3i() {} _FORCE_INLINE_ Vector3i(const int32_t p_x, const int32_t p_y, const int32_t p_z) { @@ -194,6 +196,12 @@ Vector3i &Vector3i::operator*=(const int32_t p_scalar) { return *this; } +Vector3i Vector3i::operator*(const int32_t p_scalar) const { + return Vector3i(x * p_scalar, y * p_scalar, z * p_scalar); +} + +// Multiplication operators required to workaround issues with LLVM using implicit conversion. + _FORCE_INLINE_ Vector3i operator*(const int32_t p_scalar, const Vector3i &p_vector) { return p_vector * p_scalar; } @@ -210,10 +218,6 @@ _FORCE_INLINE_ Vector3i operator*(const double p_scalar, const Vector3i &p_vecto return p_vector * p_scalar; } -Vector3i Vector3i::operator*(const int32_t p_scalar) const { - return Vector3i(x * p_scalar, y * p_scalar, z * p_scalar); -} - Vector3i &Vector3i::operator/=(const int32_t p_scalar) { x /= p_scalar; y /= p_scalar; |