diff options
Diffstat (limited to 'core/math')
32 files changed, 339 insertions, 204 deletions
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index 88e11a630c..b380860522 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -35,18 +35,12 @@ #include "scene/scene_string_names.h" int AStar::get_available_point_id() const { - if (points.is_empty()) { - return 1; - } - - // calculate our new next available point id if bigger than before or next id already contained in set of points. if (points.has(last_free_id)) { - int cur_new_id = last_free_id; + int cur_new_id = last_free_id + 1; while (points.has(cur_new_id)) { cur_new_id++; } - int &non_const = const_cast<int &>(last_free_id); - non_const = cur_new_id; + const_cast<int &>(last_free_id) = cur_new_id; } return last_free_id; @@ -388,8 +382,9 @@ bool AStar::_solve(Point *begin_point, Point *end_point) { } real_t AStar::_estimate_cost(int p_from_id, int p_to_id) { - if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost)) { - return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id); + real_t scost; + if (GDVIRTUAL_CALL(_estimate_cost, p_from_id, p_to_id, scost)) { + return scost; } Point *from_point; @@ -404,8 +399,9 @@ real_t AStar::_estimate_cost(int p_from_id, int p_to_id) { } real_t AStar::_compute_cost(int p_from_id, int p_to_id) { - if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost)) { - return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id); + real_t scost; + if (GDVIRTUAL_CALL(_compute_cost, p_from_id, p_to_id, scost)) { + return scost; } Point *from_point; @@ -563,8 +559,8 @@ void AStar::_bind_methods() { ClassDB::bind_method(D_METHOD("get_point_path", "from_id", "to_id"), &AStar::get_point_path); ClassDB::bind_method(D_METHOD("get_id_path", "from_id", "to_id"), &AStar::get_id_path); - BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id"))); - BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id"))); + GDVIRTUAL_BIND(_estimate_cost, "from_id", "to_id") + GDVIRTUAL_BIND(_compute_cost, "from_id", "to_id") } AStar::~AStar() { @@ -660,8 +656,9 @@ Vector2 AStar2D::get_closest_position_in_segment(const Vector2 &p_point) const { } real_t AStar2D::_estimate_cost(int p_from_id, int p_to_id) { - if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost)) { - return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id); + real_t scost; + if (GDVIRTUAL_CALL(_estimate_cost, p_from_id, p_to_id, scost)) { + return scost; } AStar::Point *from_point; @@ -676,8 +673,9 @@ real_t AStar2D::_estimate_cost(int p_from_id, int p_to_id) { } real_t AStar2D::_compute_cost(int p_from_id, int p_to_id) { - if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost)) { - return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id); + real_t scost; + if (GDVIRTUAL_CALL(_compute_cost, p_from_id, p_to_id, scost)) { + return scost; } AStar::Point *from_point; @@ -881,6 +879,6 @@ void AStar2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_point_path", "from_id", "to_id"), &AStar2D::get_point_path); ClassDB::bind_method(D_METHOD("get_id_path", "from_id", "to_id"), &AStar2D::get_id_path); - BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id"))); - BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id"))); + GDVIRTUAL_BIND(_estimate_cost, "from_id", "to_id") + GDVIRTUAL_BIND(_compute_cost, "from_id", "to_id") } diff --git a/core/math/a_star.h b/core/math/a_star.h index 44758cb046..64fa32a325 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -31,7 +31,9 @@ #ifndef A_STAR_H #define A_STAR_H +#include "core/object/gdvirtual.gen.inc" #include "core/object/ref_counted.h" +#include "core/object/script_language.h" #include "core/templates/oa_hash_map.h" /** @@ -122,6 +124,9 @@ protected: virtual real_t _estimate_cost(int p_from_id, int p_to_id); virtual real_t _compute_cost(int p_from_id, int p_to_id); + GDVIRTUAL2RC(real_t, _estimate_cost, int64_t, int64_t) + GDVIRTUAL2RC(real_t, _compute_cost, int64_t, int64_t) + public: int get_available_point_id() const; @@ -169,6 +174,9 @@ protected: virtual real_t _estimate_cost(int p_from_id, int p_to_id); virtual real_t _compute_cost(int p_from_id, int p_to_id); + GDVIRTUAL2RC(real_t, _estimate_cost, int64_t, int64_t) + GDVIRTUAL2RC(real_t, _compute_cost, int64_t, int64_t) + public: int get_available_point_id() const; diff --git a/core/math/basis.cpp b/core/math/basis.cpp index aa3831d4cf..5c42213e61 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -381,6 +381,18 @@ Quaternion Basis::get_rotation_quaternion() const { return m.get_quaternion(); } +void Basis::rotate_to_align(Vector3 p_start_direction, Vector3 p_end_direction) { + // Takes two vectors and rotates the basis from the first vector to the second vector. + // Adopted from: https://gist.github.com/kevinmoran/b45980723e53edeb8a5a43c49f134724 + 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); + const real_t angle_rads = Math::acos(dot); + set_axis_angle(axis, angle_rads); + } +} + void Basis::get_rotation_axis_angle(Vector3 &p_axis, real_t &p_angle) const { // Assumes that the matrix can be decomposed into a proper rotation and scaling matrix as M = R.S, // and returns the Euler angles corresponding to the rotation part, complementing get_scale(). @@ -1129,3 +1141,21 @@ void Basis::rotate_sh(real_t *p_values) { p_values[7] = -d3; p_values[8] = d4 * s_scale_dst4; } + +Basis Basis::looking_at(const Vector3 &p_target, const Vector3 &p_up) { +#ifdef MATH_CHECKS + ERR_FAIL_COND_V_MSG(p_target.is_equal_approx(Vector3()), Basis(), "The target vector can't be zero."); + ERR_FAIL_COND_V_MSG(p_up.is_equal_approx(Vector3()), Basis(), "The up vector can't be zero."); +#endif + Vector3 v_z = -p_target.normalized(); + Vector3 v_x = p_up.cross(v_z); +#ifdef MATH_CHECKS + ERR_FAIL_COND_V_MSG(v_x.is_equal_approx(Vector3()), Basis(), "The target vector and up vector can't be parallel to each other."); +#endif + v_x.normalize(); + Vector3 v_y = v_z.cross(v_x); + + Basis basis; + basis.set(v_x, v_y, v_z); + return basis; +} diff --git a/core/math/basis.h b/core/math/basis.h index 3736047dd3..9d8ed16e29 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -88,6 +88,8 @@ public: Quaternion get_rotation_quaternion() const; Vector3 get_rotation() const { return get_rotation_euler(); }; + void rotate_to_align(Vector3 p_start_direction, Vector3 p_end_direction); + Vector3 rotref_posscale_decomposition(Basis &rotref) const; Vector3 get_euler_xyz() const; @@ -158,8 +160,8 @@ public: _FORCE_INLINE_ Basis operator+(const Basis &p_matrix) const; _FORCE_INLINE_ void operator-=(const Basis &p_matrix); _FORCE_INLINE_ Basis operator-(const Basis &p_matrix) const; - _FORCE_INLINE_ void operator*=(real_t p_val); - _FORCE_INLINE_ Basis operator*(real_t p_val) const; + _FORCE_INLINE_ void operator*=(const real_t p_val); + _FORCE_INLINE_ Basis operator*(const real_t p_val) const; int get_orthogonal_index() const; void set_orthogonal_index(int p_index); @@ -242,6 +244,8 @@ public: operator Quaternion() const { return get_quaternion(); } + static Basis looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)); + Basis(const Quaternion &p_quaternion) { set_quaternion(p_quaternion); }; Basis(const Quaternion &p_quaternion, const Vector3 &p_scale) { set_quaternion_scale(p_quaternion, p_scale); } @@ -298,13 +302,13 @@ _FORCE_INLINE_ Basis Basis::operator-(const Basis &p_matrix) const { return ret; } -_FORCE_INLINE_ void Basis::operator*=(real_t p_val) { +_FORCE_INLINE_ void Basis::operator*=(const real_t p_val) { elements[0] *= p_val; elements[1] *= p_val; elements[2] *= p_val; } -_FORCE_INLINE_ Basis Basis::operator*(real_t p_val) const { +_FORCE_INLINE_ Basis Basis::operator*(const real_t p_val) const { Basis ret(*this); ret *= p_val; return ret; diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index 66c18f7b3c..8066a59281 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -341,8 +341,8 @@ bool CameraMatrix::get_endpoints(const Transform3D &p_transform, Vector3 *p_8poi Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform) const { /** Fast Plane Extraction from combined modelview/projection matrices. * References: - * https://web.archive.org/web/20011221205252/http://www.markmorley.com/opengl/frustumculling.html - * https://web.archive.org/web/20061020020112/http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf + * https://web.archive.org/web/20011221205252/https://www.markmorley.com/opengl/frustumculling.html + * https://web.archive.org/web/20061020020112/https://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf */ Vector<Plane> planes; diff --git a/core/math/convex_hull.cpp b/core/math/convex_hull.cpp index 682a7ea39e..21cb0efe20 100644 --- a/core/math/convex_hull.cpp +++ b/core/math/convex_hull.cpp @@ -2278,9 +2278,18 @@ Error ConvexHullComputer::convex_hull(const Vector<Vector3> &p_points, Geometry3 e = e->get_next_edge_of_face(); } while (e != e_start); + // reverse indices: Godot wants clockwise, but this is counter-clockwise + if (face.indices.size() > 2) { + // reverse all but the first index. + int *indices = face.indices.ptrw(); + for (int c = 0; c < (face.indices.size() - 1) / 2; c++) { + SWAP(indices[c + 1], indices[face.indices.size() - 1 - c]); + } + } + // compute normal if (face.indices.size() >= 3) { - face.plane = Plane(r_mesh.vertices[face.indices[0]], r_mesh.vertices[face.indices[2]], r_mesh.vertices[face.indices[1]]); + face.plane = Plane(r_mesh.vertices[face.indices[0]], r_mesh.vertices[face.indices[1]], r_mesh.vertices[face.indices[2]]); } else { WARN_PRINT("Too few vertices per face."); } diff --git a/core/math/convex_hull.h b/core/math/convex_hull.h index ba7be9c5e8..a860d60b02 100644 --- a/core/math/convex_hull.h +++ b/core/math/convex_hull.h @@ -49,7 +49,7 @@ subject to the following restrictions: #include "core/templates/vector.h" /// Convex hull implementation based on Preparata and Hong -/// See http://code.google.com/p/bullet/issues/detail?id=275 +/// See https://code.google.com/p/bullet/issues/detail?id=275 /// Ole Kniemeyer, MAXON Computer GmbH class ConvexHullComputer { public: diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h index 6f7209556e..81adf4d19a 100644 --- a/core/math/delaunay_3d.h +++ b/core/math/delaunay_3d.h @@ -375,8 +375,7 @@ public: OutputSimplex *ret_simplicesw = ret_simplices.ptrw(); uint32_t simplices_written = 0; - for (List<Simplex *>::Element *E = simplex_list.front(); E; E = E->next()) { - Simplex *simplex = E->get(); + for (Simplex *simplex : simplex_list) { bool invalid = false; for (int j = 0; j < 4; j++) { if (simplex->points[j] >= point_count) { diff --git a/core/math/dynamic_bvh.cpp b/core/math/dynamic_bvh.cpp index 8e596f0f9d..f3fb473981 100644 --- a/core/math/dynamic_bvh.cpp +++ b/core/math/dynamic_bvh.cpp @@ -181,7 +181,7 @@ DynamicBVH::Volume DynamicBVH::_bounds(Node **leaves, int p_count) { void DynamicBVH::_bottom_up(Node **leaves, int p_count) { while (p_count > 1) { - real_t minsize = Math_INF; + real_t minsize = INFINITY; int minidx[2] = { -1, -1 }; for (int i = 0; i < p_count; ++i) { for (int j = i + 1; j < p_count; ++j) { diff --git a/core/math/dynamic_bvh.h b/core/math/dynamic_bvh.h index 0b6286cd9d..d63132b4da 100644 --- a/core/math/dynamic_bvh.h +++ b/core/math/dynamic_bvh.h @@ -41,7 +41,7 @@ /* Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2013 Erwin Coumans http://bulletphysics.org +Copyright (c) 2003-2013 Erwin Coumans https://bulletphysics.org This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/core/math/expression.cpp b/core/math/expression.cpp index 0146c345f0..05f2c8dac9 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -397,10 +397,10 @@ Error Expression::_get_token(Token &r_token) { r_token.value = Math_TAU; } else if (id == "INF") { r_token.type = TK_CONSTANT; - r_token.value = Math_INF; + r_token.value = INFINITY; } else if (id == "NAN") { r_token.type = TK_CONSTANT; - r_token.value = Math_NAN; + r_token.value = NAN; } else if (id == "not") { r_token.type = TK_OP_NOT; } else if (id == "or") { diff --git a/core/math/face3.h b/core/math/face3.h index 5091b338ef..9e9026e54e 100644 --- a/core/math/face3.h +++ b/core/math/face3.h @@ -50,8 +50,8 @@ public: /** * * @param p_plane plane used to split the face - * @param p_res array of at least 3 faces, amount used in functio return - * @param p_is_point_over array of at least 3 booleans, determining which face is over the plane, amount used in functio return + * @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 */ diff --git a/core/math/geometry_2d.h b/core/math/geometry_2d.h index 4958b5ac6a..e1a5bfe6f2 100644 --- a/core/math/geometry_2d.h +++ b/core/math/geometry_2d.h @@ -32,9 +32,8 @@ #define GEOMETRY_2D_H #include "core/math/delaunay_2d.h" -#include "core/math/rect2.h" #include "core/math/triangulate.h" -#include "core/object/object.h" +#include "core/math/vector3i.h" #include "core/templates/vector.h" class Geometry2D { @@ -362,6 +361,19 @@ public: return (intersections & 1); } + static bool is_segment_intersecting_polygon(const Vector2 &p_from, const Vector2 &p_to, const Vector<Vector2> &p_polygon) { + int c = p_polygon.size(); + const Vector2 *p = p_polygon.ptr(); + for (int i = 0; i < c; i++) { + const Vector2 &v1 = p[i]; + const Vector2 &v2 = p[(i + 1) % c]; + if (segment_intersects_segment(p_from, p_to, v1, v2, nullptr)) { + return true; + } + } + return false; + } + static real_t vec2_cross(const Point2 &O, const Point2 &A, const Point2 &B) { return (real_t)(A.x - O.x) * (B.y - O.y) - (real_t)(A.y - O.y) * (B.x - O.x); } diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h index 4ef9b4dbe6..766689e222 100644 --- a/core/math/geometry_3d.h +++ b/core/math/geometry_3d.h @@ -40,7 +40,7 @@ class Geometry3D { public: static void get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2, Vector3 &c1, Vector3 &c2) { -// Do the function 'd' as defined by pb. I think is is dot product of some sort. +// Do the function 'd' as defined by pb. I think it's a dot product of some sort. #define d_of(m, n, o, p) ((m.x - n.x) * (o.x - p.x) + (m.y - n.y) * (o.y - p.y) + (m.z - n.z) * (o.z - p.z)) // Calculate the parametric position on the 2 curves, mua and mub. diff --git a/core/math/math_defs.h b/core/math/math_defs.h index df2223fb78..c3a8f910c0 100644 --- a/core/math/math_defs.h +++ b/core/math/math_defs.h @@ -43,8 +43,6 @@ #define Math_TAU 6.2831853071795864769252867666 #define Math_PI 3.1415926535897932384626433833 #define Math_E 2.7182818284590452353602874714 -#define Math_INF INFINITY -#define Math_NAN NAN #ifdef DEBUG_ENABLED #define MATH_CHECKS @@ -83,6 +81,26 @@ enum VAlign { VALIGN_BOTTOM }; +enum InlineAlign { + // Image alignment points. + INLINE_ALIGN_TOP_TO = 0b0000, + INLINE_ALIGN_CENTER_TO = 0b0001, + INLINE_ALIGN_BOTTOM_TO = 0b0010, + INLINE_ALIGN_IMAGE_MASK = 0b0011, + + // Text alignment points. + INLINE_ALIGN_TO_TOP = 0b0000, + INLINE_ALIGN_TO_CENTER = 0b0100, + INLINE_ALIGN_TO_BASELINE = 0b1000, + INLINE_ALIGN_TO_BOTTOM = 0b1100, + INLINE_ALIGN_TEXT_MASK = 0b1100, + + // Presets. + INLINE_ALIGN_TOP = INLINE_ALIGN_TOP_TO | INLINE_ALIGN_TO_TOP, + INLINE_ALIGN_CENTER = INLINE_ALIGN_CENTER_TO | INLINE_ALIGN_TO_CENTER, + INLINE_ALIGN_BOTTOM = INLINE_ALIGN_BOTTOM_TO | INLINE_ALIGN_TO_BOTTOM +}; + enum Side { SIDE_LEFT, SIDE_TOP, diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp index e92bb9f4aa..bbed257f60 100644 --- a/core/math/math_funcs.cpp +++ b/core/math/math_funcs.cpp @@ -88,16 +88,6 @@ int Math::range_step_decimals(double p_step) { return step_decimals(p_step); } -double Math::dectime(double p_value, double p_amount, double p_step) { - double sgn = p_value < 0 ? -1.0 : 1.0; - double val = Math::abs(p_value); - val -= p_amount * p_step; - if (val < 0.0) { - val = 0.0; - } - return val * sgn; -} - double Math::ease(double p_x, double p_c) { if (p_x < 0) { p_x = 0; diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 3389407e72..4e4f566517 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -296,7 +296,6 @@ public: static int step_decimals(double p_step); static int range_step_decimals(double p_step); static double snapped(double p_value, double p_step); - static double dectime(double p_value, double p_amount, double p_step); static uint32_t larger_prime(uint32_t p_val); diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp index 7037db7112..3f1d2c58e5 100644 --- a/core/math/quaternion.cpp +++ b/core/math/quaternion.cpp @@ -33,6 +33,11 @@ #include "core/math/basis.h" #include "core/string/print_string.h" +real_t Quaternion::angle_to(const Quaternion &p_to) const { + real_t d = dot(p_to); + return Math::acos(CLAMP(d * d * 2 - 1, -1, 1)); +} + // get_euler_xyz returns a vector containing the Euler angles in the format // (ax,ay,az), where ax is the angle of rotation around x axis, // and similar for other axes. diff --git a/core/math/quaternion.h b/core/math/quaternion.h index 796214b79e..35324323b3 100644 --- a/core/math/quaternion.h +++ b/core/math/quaternion.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef QUAT_H -#define QUAT_H +#ifndef QUATERNION_H +#define QUATERNION_H #include "core/math/math_defs.h" #include "core/math/math_funcs.h" @@ -62,6 +62,7 @@ public: bool is_normalized() const; Quaternion inverse() const; _FORCE_INLINE_ real_t dot(const Quaternion &p_q) const; + real_t angle_to(const Quaternion &p_to) const; Vector3 get_euler_xyz() const; Vector3 get_euler_yxz() const; @@ -235,4 +236,4 @@ _FORCE_INLINE_ Quaternion operator*(const real_t &p_real, const Quaternion &p_qu return p_quaternion * p_real; } -#endif // QUAT_H +#endif // QUATERNION_H diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index 0d77bfe933..0960fe19a6 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -192,9 +192,9 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ continue; } - for (List<Face>::Element *E = faces.front(); E; E = E->next()) { - if (E->get().plane.distance_to(p_points[i]) > over_tolerance) { - E->get().points_over.push_back(i); + for (Face &E : faces) { + if (E.plane.distance_to(p_points[i]) > over_tolerance) { + E.points_over.push_back(i); break; } } @@ -292,8 +292,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ //distribute points into new faces - for (List<List<Face>::Element *>::Element *F = lit_faces.front(); F; F = F->next()) { - Face &lf = F->get()->get(); + for (List<Face>::Element *&F : lit_faces) { + Face &lf = F->get(); for (int i = 0; i < lf.points_over.size(); i++) { if (lf.points_over[i] == f.points_over[next]) { //do not add current one @@ -301,8 +301,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ } Vector3 p = p_points[lf.points_over[i]]; - for (List<List<Face>::Element *>::Element *E = new_faces.front(); E; E = E->next()) { - Face &f2 = E->get()->get(); + for (List<Face>::Element *&E : new_faces) { + Face &f2 = E->get(); if (f2.plane.distance_to(p) > over_tolerance) { f2.points_over.push_back(lf.points_over[i]); break; @@ -320,10 +320,10 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ //put faces that contain no points on the front - for (List<List<Face>::Element *>::Element *E = new_faces.front(); E; E = E->next()) { - Face &f2 = E->get()->get(); + for (List<Face>::Element *&E : new_faces) { + Face &f2 = E->get(); if (f2.points_over.size() == 0) { - faces.move_to_front(E->get()); + faces.move_to_front(E); } } @@ -336,19 +336,19 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ Map<Edge, RetFaceConnect> ret_edges; List<Geometry3D::MeshData::Face> ret_faces; - for (List<Face>::Element *E = faces.front(); E; E = E->next()) { + for (const Face &E : faces) { Geometry3D::MeshData::Face f; - f.plane = E->get().plane; + f.plane = E.plane; for (int i = 0; i < 3; i++) { - f.indices.push_back(E->get().vertices[i]); + f.indices.push_back(E.vertices[i]); } List<Geometry3D::MeshData::Face>::Element *F = ret_faces.push_back(f); for (int i = 0; i < 3; i++) { - uint32_t a = E->get().vertices[i]; - uint32_t b = E->get().vertices[(i + 1) % 3]; + uint32_t a = E.vertices[i]; + uint32_t b = E.vertices[(i + 1) % 3]; Edge e(a, b); Map<Edge, RetFaceConnect>::Element *G = ret_edges.find(e); @@ -439,8 +439,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ r_mesh.faces.resize(ret_faces.size()); int idx = 0; - for (List<Geometry3D::MeshData::Face>::Element *E = ret_faces.front(); E; E = E->next()) { - r_mesh.faces.write[idx++] = E->get(); + for (const Geometry3D::MeshData::Face &E : ret_faces) { + r_mesh.faces.write[idx++] = E; } r_mesh.edges.resize(ret_edges.size()); idx = 0; diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp index 0140f31b8a..16934d67df 100644 --- a/core/math/transform_2d.cpp +++ b/core/math/transform_2d.cpp @@ -276,6 +276,18 @@ Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, real_t return res; } +void Transform2D::operator*=(const real_t p_val) { + elements[0] *= p_val; + elements[1] *= p_val; + elements[2] *= p_val; +} + +Transform2D Transform2D::operator*(const real_t p_val) const { + Transform2D ret(*this); + ret *= p_val; + return ret; +} + Transform2D::operator String() const { return "[X: " + elements[0].operator String() + ", Y: " + elements[1].operator String() + diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h index 715f013701..34cfd0c1a9 100644 --- a/core/math/transform_2d.h +++ b/core/math/transform_2d.h @@ -107,6 +107,8 @@ struct Transform2D { void operator*=(const Transform2D &p_transform); Transform2D operator*(const Transform2D &p_transform) const; + void operator*=(const real_t p_val); + Transform2D operator*(const real_t p_val) const; Transform2D interpolate_with(const Transform2D &p_transform, real_t p_c) const; diff --git a/core/math/transform_3d.cpp b/core/math/transform_3d.cpp index a34d998dde..4f4943c8ef 100644 --- a/core/math/transform_3d.cpp +++ b/core/math/transform_3d.cpp @@ -71,40 +71,12 @@ void Transform3D::rotate_basis(const Vector3 &p_axis, real_t p_phi) { Transform3D Transform3D::looking_at(const Vector3 &p_target, const Vector3 &p_up) const { Transform3D t = *this; - t.set_look_at(origin, p_target, p_up); + t.basis = Basis::looking_at(p_target - origin, p_up); return t; } void Transform3D::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up) { -#ifdef MATH_CHECKS - ERR_FAIL_COND(p_eye == p_target); - ERR_FAIL_COND(p_up.length() == 0); -#endif - // Reference: MESA source code - Vector3 v_x, v_y, v_z; - - /* Make rotation matrix */ - - /* Z vector */ - v_z = p_eye - p_target; - - v_z.normalize(); - - v_y = p_up; - - v_x = v_y.cross(v_z); -#ifdef MATH_CHECKS - ERR_FAIL_COND(v_x.length() == 0); -#endif - - /* Recompute Y = Z cross X */ - v_y = v_z.cross(v_x); - - v_x.normalize(); - v_y.normalize(); - - basis.set(v_x, v_y, v_z); - + basis = Basis::looking_at(p_target - p_eye, p_up); origin = p_eye; } @@ -190,6 +162,17 @@ Transform3D Transform3D::operator*(const Transform3D &p_transform) const { return t; } +void Transform3D::operator*=(const real_t p_val) { + origin *= p_val; + basis *= p_val; +} + +Transform3D Transform3D::operator*(const real_t p_val) const { + Transform3D ret(*this); + ret *= p_val; + return ret; +} + Transform3D::operator String() const { return "[X: " + basis.get_axis(0).operator String() + ", Y: " + basis.get_axis(1).operator String() + diff --git a/core/math/transform_3d.h b/core/math/transform_3d.h index 078a2ca11a..345e0fade0 100644 --- a/core/math/transform_3d.h +++ b/core/math/transform_3d.h @@ -75,19 +75,29 @@ public: bool operator!=(const Transform3D &p_transform) const; _FORCE_INLINE_ Vector3 xform(const Vector3 &p_vector) const; + _FORCE_INLINE_ AABB xform(const AABB &p_aabb) const; + _FORCE_INLINE_ Vector<Vector3> xform(const Vector<Vector3> &p_array) const; + + // NOTE: These are UNSAFE with non-uniform scaling, and will produce incorrect results. + // They use the transpose. + // For safe inverse transforms, xform by the affine_inverse. _FORCE_INLINE_ Vector3 xform_inv(const Vector3 &p_vector) const; + _FORCE_INLINE_ AABB xform_inv(const AABB &p_aabb) const; + _FORCE_INLINE_ Vector<Vector3> xform_inv(const Vector<Vector3> &p_array) const; + // Safe with non-uniform scaling (uses affine_inverse). _FORCE_INLINE_ Plane xform(const Plane &p_plane) const; _FORCE_INLINE_ Plane xform_inv(const Plane &p_plane) const; - _FORCE_INLINE_ AABB xform(const AABB &p_aabb) const; - _FORCE_INLINE_ AABB xform_inv(const AABB &p_aabb) const; - - _FORCE_INLINE_ Vector<Vector3> xform(const Vector<Vector3> &p_array) const; - _FORCE_INLINE_ Vector<Vector3> xform_inv(const Vector<Vector3> &p_array) const; + // These fast versions use precomputed affine inverse, and should be used in bottleneck areas where + // multiple planes are to be transformed. + _FORCE_INLINE_ Plane xform_fast(const Plane &p_plane, const Basis &p_basis_inverse_transpose) const; + static _FORCE_INLINE_ Plane xform_inv_fast(const Plane &p_plane, const Transform3D &p_inverse, const Basis &p_basis_transpose); void operator*=(const Transform3D &p_transform); Transform3D operator*(const Transform3D &p_transform) const; + void operator*=(const real_t p_val); + Transform3D operator*(const real_t p_val) const; Transform3D interpolate_with(const Transform3D &p_transform, real_t p_c) const; @@ -128,34 +138,24 @@ _FORCE_INLINE_ Vector3 Transform3D::xform_inv(const Vector3 &p_vector) const { (basis.elements[0][2] * v.x) + (basis.elements[1][2] * v.y) + (basis.elements[2][2] * v.z)); } +// Neither the plane regular xform or xform_inv are particularly efficient, +// as they do a basis inverse. For xforming a large number +// of planes it is better to pre-calculate the inverse transpose basis once +// and reuse it for each plane, by using the 'fast' version of the functions. _FORCE_INLINE_ Plane Transform3D::xform(const Plane &p_plane) const { - Vector3 point = p_plane.normal * p_plane.d; - Vector3 point_dir = point + p_plane.normal; - point = xform(point); - point_dir = xform(point_dir); - - Vector3 normal = point_dir - point; - normal.normalize(); - real_t d = normal.dot(point); - - return Plane(normal, d); + Basis b = basis.inverse(); + b.transpose(); + return xform_fast(p_plane, b); } _FORCE_INLINE_ Plane Transform3D::xform_inv(const Plane &p_plane) const { - Vector3 point = p_plane.normal * p_plane.d; - Vector3 point_dir = point + p_plane.normal; - point = xform_inv(point); - point_dir = xform_inv(point_dir); - - Vector3 normal = point_dir - point; - normal.normalize(); - real_t d = normal.dot(point); - - return Plane(normal, d); + Transform3D inv = affine_inverse(); + Basis basis_transpose = basis.transposed(); + return xform_inv_fast(p_plane, inv, basis_transpose); } _FORCE_INLINE_ AABB Transform3D::xform(const AABB &p_aabb) const { - /* http://dev.theomader.com/transform-bounding-boxes/ */ + /* https://dev.theomader.com/transform-bounding-boxes/ */ Vector3 min = p_aabb.position; Vector3 max = p_aabb.position + p_aabb.size; Vector3 tmin, tmax; @@ -229,4 +229,37 @@ Vector<Vector3> Transform3D::xform_inv(const Vector<Vector3> &p_array) const { return array; } +_FORCE_INLINE_ Plane Transform3D::xform_fast(const Plane &p_plane, const Basis &p_basis_inverse_transpose) const { + // Transform a single point on the plane. + Vector3 point = p_plane.normal * p_plane.d; + point = xform(point); + + // Use inverse transpose for correct normals with non-uniform scaling. + Vector3 normal = p_basis_inverse_transpose.xform(p_plane.normal); + normal.normalize(); + + real_t d = normal.dot(point); + return Plane(normal, d); +} + +_FORCE_INLINE_ Plane Transform3D::xform_inv_fast(const Plane &p_plane, const Transform3D &p_inverse, const Basis &p_basis_transpose) { + // Transform a single point on the plane. + Vector3 point = p_plane.normal * p_plane.d; + point = p_inverse.xform(point); + + // Note that instead of precalculating the transpose, an alternative + // would be to use the transpose for the basis transform. + // However that would be less SIMD friendly (requiring a swizzle). + // So the cost is one extra precalced value in the calling code. + // This is probably worth it, as this could be used in bottleneck areas. And + // where it is not a bottleneck, the non-fast method is fine. + + // Use transpose for correct normals with non-uniform scaling. + Vector3 normal = p_basis_transpose.xform(p_plane.normal); + normal.normalize(); + + real_t d = normal.dot(point); + return Plane(normal, d); +} + #endif // TRANSFORM_H diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 903d5951a8..bf06c848c5 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -32,9 +32,9 @@ #include "core/templates/sort_array.h" -int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc) { - if (p_depth > max_depth) { - max_depth = p_depth; +int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &r_max_depth, int &r_max_alloc) { + if (p_depth > r_max_depth) { + r_max_depth = p_depth; } if (p_size == 1) { @@ -70,10 +70,10 @@ int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, in } break; } - int left = _create_bvh(p_bvh, p_bb, p_from, p_size / 2, p_depth + 1, max_depth, max_alloc); - int right = _create_bvh(p_bvh, p_bb, p_from + p_size / 2, p_size - p_size / 2, p_depth + 1, max_depth, max_alloc); + int left = _create_bvh(p_bvh, p_bb, p_from, p_size / 2, p_depth + 1, r_max_depth, r_max_alloc); + int right = _create_bvh(p_bvh, p_bb, p_from + p_size / 2, p_size - p_size / 2, p_depth + 1, r_max_depth, r_max_alloc); - int index = max_alloc++; + int index = r_max_alloc++; BVH *_new = &p_bvh[index]; _new->aabb = aabb; _new->center = aabb.position + aabb.size * 0.5; diff --git a/core/math/triangulate.h b/core/math/triangulate.h index 55dc4e8e7d..249ca6238f 100644 --- a/core/math/triangulate.h +++ b/core/math/triangulate.h @@ -34,7 +34,7 @@ #include "core/math/vector2.h" /* -http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml +https://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml */ class Triangulate { diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index eb3301f5d0..54abc1b7f2 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -102,7 +102,7 @@ Vector2 Vector2::round() const { return Vector2(Math::round(x), Math::round(y)); } -Vector2 Vector2::rotated(real_t p_by) const { +Vector2 Vector2::rotated(const real_t p_by) const { real_t sine = Math::sin(p_by); real_t cosi = Math::cos(p_by); return Vector2( @@ -145,7 +145,7 @@ Vector2 Vector2::limit_length(const real_t p_len) const { return v; } -Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_weight) 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; diff --git a/core/math/vector2.h b/core/math/vector2.h index 78deb473b4..330b4741b1 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -66,7 +66,7 @@ struct Vector2 { return p_idx ? y : x; } - _FORCE_INLINE_ void set_all(real_t p_value) { + _FORCE_INLINE_ void set_all(const real_t p_value) { x = y = p_value; } @@ -106,11 +106,11 @@ struct Vector2 { Vector2 posmodv(const Vector2 &p_modv) const; Vector2 project(const Vector2 &p_to) const; - Vector2 plane_project(real_t p_d, const Vector2 &p_vec) const; + Vector2 plane_project(const real_t p_d, const Vector2 &p_vec) const; - _FORCE_INLINE_ Vector2 lerp(const Vector2 &p_to, real_t p_weight) const; - _FORCE_INLINE_ Vector2 slerp(const Vector2 &p_to, real_t p_weight) const; - Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_weight) const; + _FORCE_INLINE_ Vector2 lerp(const Vector2 &p_to, const real_t p_weight) const; + _FORCE_INLINE_ Vector2 slerp(const Vector2 &p_to, const real_t p_weight) const; + Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, const real_t p_weight) const; Vector2 move_toward(const Vector2 &p_to, const real_t p_delta) const; Vector2 slide(const Vector2 &p_normal) const; @@ -152,7 +152,7 @@ struct Vector2 { return Vector2(Math::abs(x), Math::abs(y)); } - Vector2 rotated(real_t p_by) const; + Vector2 rotated(const real_t p_by) const; Vector2 orthogonal() const { return Vector2(y, -x); } @@ -168,29 +168,29 @@ struct Vector2 { operator String() const; _FORCE_INLINE_ Vector2() {} - _FORCE_INLINE_ Vector2(real_t p_x, real_t p_y) { + _FORCE_INLINE_ Vector2(const real_t p_x, const real_t p_y) { x = p_x; y = p_y; } }; -_FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2 &p_vec) const { +_FORCE_INLINE_ Vector2 Vector2::plane_project(const real_t p_d, const Vector2 &p_vec) const { return p_vec - *this * (dot(p_vec) - p_d); } -_FORCE_INLINE_ Vector2 operator*(float p_scalar, const Vector2 &p_vec) { +_FORCE_INLINE_ Vector2 operator*(const float p_scalar, const Vector2 &p_vec) { return p_vec * p_scalar; } -_FORCE_INLINE_ Vector2 operator*(double p_scalar, const Vector2 &p_vec) { +_FORCE_INLINE_ Vector2 operator*(const double p_scalar, const Vector2 &p_vec) { return p_vec * p_scalar; } -_FORCE_INLINE_ Vector2 operator*(int32_t p_scalar, const Vector2 &p_vec) { +_FORCE_INLINE_ Vector2 operator*(const int32_t p_scalar, const Vector2 &p_vec) { return p_vec * p_scalar; } -_FORCE_INLINE_ Vector2 operator*(int64_t p_scalar, const Vector2 &p_vec) { +_FORCE_INLINE_ Vector2 operator*(const int64_t p_scalar, const Vector2 &p_vec) { return p_vec * p_scalar; } @@ -250,7 +250,7 @@ _FORCE_INLINE_ bool Vector2::operator!=(const Vector2 &p_vec2) const { return x != p_vec2.x || y != p_vec2.y; } -Vector2 Vector2::lerp(const Vector2 &p_to, real_t p_weight) const { +Vector2 Vector2::lerp(const Vector2 &p_to, const real_t p_weight) const { Vector2 res = *this; res.x += (p_weight * (p_to.x - x)); @@ -259,7 +259,7 @@ Vector2 Vector2::lerp(const Vector2 &p_to, real_t p_weight) const { return res; } -Vector2 Vector2::slerp(const Vector2 &p_to, real_t p_weight) const { +Vector2 Vector2::slerp(const Vector2 &p_to, const real_t p_weight) const { #ifdef MATH_CHECKS ERR_FAIL_COND_V_MSG(!is_normalized(), Vector2(), "The start Vector2 must be normalized."); #endif @@ -300,6 +300,14 @@ struct Vector2i { return p_idx ? y : x; } + _FORCE_INLINE_ int min_axis() const { + return x < y ? 0 : 1; + } + + _FORCE_INLINE_ int max_axis() const { + return x < y ? 1 : 0; + } + Vector2i min(const Vector2i &p_vector2i) const { return Vector2(MIN(x, p_vector2i.x), MIN(y, p_vector2i.y)); } @@ -349,7 +357,7 @@ struct Vector2i { x = (int32_t)p_vec2.x; y = (int32_t)p_vec2.y; } - inline Vector2i(int32_t p_x, int32_t p_y) { + inline Vector2i(const int32_t p_x, const int32_t p_y) { x = p_x; y = p_y; } diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index 3d59064af6..401c3ccd9c 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -32,22 +32,22 @@ #include "core/math/basis.h" -void Vector3::rotate(const Vector3 &p_axis, real_t p_phi) { +void Vector3::rotate(const Vector3 &p_axis, const real_t p_phi) { *this = Basis(p_axis, p_phi).xform(*this); } -Vector3 Vector3::rotated(const Vector3 &p_axis, real_t p_phi) const { +Vector3 Vector3::rotated(const Vector3 &p_axis, const real_t p_phi) const { Vector3 r = *this; r.rotate(p_axis, p_phi); return r; } -void Vector3::set_axis(int p_axis, real_t p_value) { +void Vector3::set_axis(const int p_axis, const real_t p_value) { ERR_FAIL_INDEX(p_axis, 3); coord[p_axis] = p_value; } -real_t Vector3::get_axis(int p_axis) const { +real_t Vector3::get_axis(const int p_axis) const { ERR_FAIL_INDEX_V(p_axis, 3, 0); return operator[](p_axis); } @@ -59,13 +59,13 @@ Vector3 Vector3::clamp(const Vector3 &p_min, const Vector3 &p_max) const { CLAMP(z, p_min.z, p_max.z)); } -void Vector3::snap(Vector3 p_step) { +void Vector3::snap(const Vector3 p_step) { x = Math::snapped(x, p_step.x); y = Math::snapped(y, p_step.y); z = Math::snapped(z, p_step.z); } -Vector3 Vector3::snapped(Vector3 p_step) const { +Vector3 Vector3::snapped(const Vector3 p_step) const { Vector3 v = *this; v.snap(p_step); return v; @@ -82,7 +82,7 @@ Vector3 Vector3::limit_length(const real_t p_len) const { return v; } -Vector3 Vector3::cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, real_t p_weight) 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; diff --git a/core/math/vector3.h b/core/math/vector3.h index d8d3cd3cc0..6a4c42f41b 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -56,18 +56,18 @@ struct Vector3 { real_t coord[3] = { 0 }; }; - _FORCE_INLINE_ const real_t &operator[](int p_axis) const { + _FORCE_INLINE_ const real_t &operator[](const int p_axis) const { return coord[p_axis]; } - _FORCE_INLINE_ real_t &operator[](int p_axis) { + _FORCE_INLINE_ real_t &operator[](const int p_axis) { return coord[p_axis]; } - void set_axis(int p_axis, real_t p_value); - real_t get_axis(int p_axis) const; + void set_axis(const int p_axis, const real_t p_value); + real_t get_axis(const int p_axis) const; - _FORCE_INLINE_ void set_all(real_t p_value) { + _FORCE_INLINE_ void set_all(const real_t p_value) { x = y = z = p_value; } @@ -90,17 +90,17 @@ struct Vector3 { _FORCE_INLINE_ void zero(); - void snap(Vector3 p_val); - Vector3 snapped(Vector3 p_val) const; + void snap(const Vector3 p_val); + Vector3 snapped(const Vector3 p_val) const; - void rotate(const Vector3 &p_axis, real_t p_phi); - Vector3 rotated(const Vector3 &p_axis, real_t p_phi) const; + void rotate(const Vector3 &p_axis, const real_t p_phi); + Vector3 rotated(const Vector3 &p_axis, const real_t p_phi) const; /* Static Methods between 2 vector3s */ - _FORCE_INLINE_ Vector3 lerp(const Vector3 &p_to, real_t p_weight) const; - _FORCE_INLINE_ Vector3 slerp(const Vector3 &p_to, real_t p_weight) const; - Vector3 cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, real_t p_weight) const; + _FORCE_INLINE_ Vector3 lerp(const Vector3 &p_to, const real_t p_weight) const; + _FORCE_INLINE_ Vector3 slerp(const Vector3 &p_to, const real_t p_weight) const; + 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_ Vector3 cross(const Vector3 &p_b) const; @@ -143,10 +143,10 @@ struct Vector3 { _FORCE_INLINE_ Vector3 &operator/=(const Vector3 &p_v); _FORCE_INLINE_ Vector3 operator/(const Vector3 &p_v) const; - _FORCE_INLINE_ Vector3 &operator*=(real_t p_scalar); - _FORCE_INLINE_ Vector3 operator*(real_t p_scalar) const; - _FORCE_INLINE_ Vector3 &operator/=(real_t p_scalar); - _FORCE_INLINE_ Vector3 operator/(real_t p_scalar) const; + _FORCE_INLINE_ Vector3 &operator*=(const real_t p_scalar); + _FORCE_INLINE_ Vector3 operator*(const real_t p_scalar) const; + _FORCE_INLINE_ Vector3 &operator/=(const real_t p_scalar); + _FORCE_INLINE_ Vector3 operator/(const real_t p_scalar) const; _FORCE_INLINE_ Vector3 operator-() const; @@ -168,7 +168,7 @@ struct Vector3 { y = p_ivec.y; z = p_ivec.z; } - _FORCE_INLINE_ Vector3(real_t p_x, real_t p_y, real_t p_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; z = p_z; @@ -208,14 +208,14 @@ Vector3 Vector3::round() const { return Vector3(Math::round(x), Math::round(y), Math::round(z)); } -Vector3 Vector3::lerp(const Vector3 &p_to, real_t p_weight) const { +Vector3 Vector3::lerp(const Vector3 &p_to, const real_t p_weight) const { return Vector3( x + (p_weight * (p_to.x - x)), y + (p_weight * (p_to.y - y)), z + (p_weight * (p_to.z - z))); } -Vector3 Vector3::slerp(const Vector3 &p_to, real_t p_weight) const { +Vector3 Vector3::slerp(const Vector3 &p_to, const real_t p_weight) const { real_t theta = angle_to(p_to); return rotated(cross(p_to).normalized(), theta * p_weight); } @@ -303,29 +303,41 @@ Vector3 Vector3::operator/(const Vector3 &p_v) const { return Vector3(x / p_v.x, y / p_v.y, z / p_v.z); } -Vector3 &Vector3::operator*=(real_t p_scalar) { +Vector3 &Vector3::operator*=(const real_t p_scalar) { x *= p_scalar; y *= p_scalar; z *= p_scalar; return *this; } -_FORCE_INLINE_ Vector3 operator*(real_t p_scalar, const Vector3 &p_vec) { +_FORCE_INLINE_ Vector3 operator*(const float p_scalar, const Vector3 &p_vec) { return p_vec * p_scalar; } -Vector3 Vector3::operator*(real_t p_scalar) const { +_FORCE_INLINE_ Vector3 operator*(const double p_scalar, const Vector3 &p_vec) { + return p_vec * p_scalar; +} + +_FORCE_INLINE_ Vector3 operator*(const int32_t p_scalar, const Vector3 &p_vec) { + return p_vec * p_scalar; +} + +_FORCE_INLINE_ Vector3 operator*(const int64_t p_scalar, const Vector3 &p_vec) { + return p_vec * p_scalar; +} + +Vector3 Vector3::operator*(const real_t p_scalar) const { return Vector3(x * p_scalar, y * p_scalar, z * p_scalar); } -Vector3 &Vector3::operator/=(real_t p_scalar) { +Vector3 &Vector3::operator/=(const real_t p_scalar) { x /= p_scalar; y /= p_scalar; z /= p_scalar; return *this; } -Vector3 Vector3::operator/(real_t p_scalar) const { +Vector3 Vector3::operator/(const real_t p_scalar) const { return Vector3(x / p_scalar, y / p_scalar, z / p_scalar); } diff --git a/core/math/vector3i.cpp b/core/math/vector3i.cpp index 2de1e4e331..d3a57af77c 100644 --- a/core/math/vector3i.cpp +++ b/core/math/vector3i.cpp @@ -30,12 +30,12 @@ #include "vector3i.h" -void Vector3i::set_axis(int p_axis, int32_t p_value) { +void Vector3i::set_axis(const int p_axis, const int32_t p_value) { ERR_FAIL_INDEX(p_axis, 3); coord[p_axis] = p_value; } -int32_t Vector3i::get_axis(int p_axis) const { +int32_t Vector3i::get_axis(const int p_axis) const { ERR_FAIL_INDEX_V(p_axis, 3, 0); return operator[](p_axis); } diff --git a/core/math/vector3i.h b/core/math/vector3i.h index 37c7c1c368..9308d09045 100644 --- a/core/math/vector3i.h +++ b/core/math/vector3i.h @@ -51,16 +51,16 @@ struct Vector3i { int32_t coord[3] = { 0 }; }; - _FORCE_INLINE_ const int32_t &operator[](int p_axis) const { + _FORCE_INLINE_ const int32_t &operator[](const int p_axis) const { return coord[p_axis]; } - _FORCE_INLINE_ int32_t &operator[](int p_axis) { + _FORCE_INLINE_ int32_t &operator[](const int p_axis) { return coord[p_axis]; } - void set_axis(int p_axis, int32_t p_value); - int32_t get_axis(int p_axis) const; + void set_axis(const int p_axis, const int32_t p_value); + int32_t get_axis(const int p_axis) const; int min_axis() const; int max_axis() const; @@ -84,12 +84,12 @@ struct Vector3i { _FORCE_INLINE_ Vector3i &operator%=(const Vector3i &p_v); _FORCE_INLINE_ Vector3i operator%(const Vector3i &p_v) const; - _FORCE_INLINE_ Vector3i &operator*=(int32_t p_scalar); - _FORCE_INLINE_ Vector3i operator*(int32_t p_scalar) const; - _FORCE_INLINE_ Vector3i &operator/=(int32_t p_scalar); - _FORCE_INLINE_ Vector3i operator/(int32_t p_scalar) const; - _FORCE_INLINE_ Vector3i &operator%=(int32_t p_scalar); - _FORCE_INLINE_ Vector3i operator%(int32_t p_scalar) const; + _FORCE_INLINE_ Vector3i &operator*=(const int32_t p_scalar); + _FORCE_INLINE_ Vector3i operator*(const int32_t p_scalar) const; + _FORCE_INLINE_ Vector3i &operator/=(const int32_t p_scalar); + _FORCE_INLINE_ Vector3i operator/(const int32_t p_scalar) const; + _FORCE_INLINE_ Vector3i &operator%=(const int32_t p_scalar); + _FORCE_INLINE_ Vector3i operator%(const int32_t p_scalar) const; _FORCE_INLINE_ Vector3i operator-() const; @@ -103,7 +103,7 @@ struct Vector3i { operator String() const; _FORCE_INLINE_ Vector3i() {} - _FORCE_INLINE_ Vector3i(int32_t p_x, int32_t p_y, int32_t p_z) { + _FORCE_INLINE_ Vector3i(const int32_t p_x, const int32_t p_y, const int32_t p_z) { x = p_x; y = p_y; z = p_z; @@ -175,40 +175,52 @@ Vector3i Vector3i::operator%(const Vector3i &p_v) const { return Vector3i(x % p_v.x, y % p_v.y, z % p_v.z); } -Vector3i &Vector3i::operator*=(int32_t p_scalar) { +Vector3i &Vector3i::operator*=(const int32_t p_scalar) { x *= p_scalar; y *= p_scalar; z *= p_scalar; return *this; } -_FORCE_INLINE_ Vector3i operator*(int32_t p_scalar, const Vector3i &p_vec) { - return p_vec * p_scalar; +_FORCE_INLINE_ Vector3i operator*(const int32_t p_scalar, const Vector3i &p_vector) { + return p_vector * p_scalar; } -Vector3i Vector3i::operator*(int32_t p_scalar) const { +_FORCE_INLINE_ Vector3i operator*(const int64_t p_scalar, const Vector3i &p_vector) { + return p_vector * p_scalar; +} + +_FORCE_INLINE_ Vector3i operator*(const float p_scalar, const Vector3i &p_vector) { + return p_vector * p_scalar; +} + +_FORCE_INLINE_ Vector3i operator*(const double p_scalar, const Vector3i &p_vector) { + 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/=(int32_t p_scalar) { +Vector3i &Vector3i::operator/=(const int32_t p_scalar) { x /= p_scalar; y /= p_scalar; z /= p_scalar; return *this; } -Vector3i Vector3i::operator/(int32_t p_scalar) const { +Vector3i Vector3i::operator/(const int32_t p_scalar) const { return Vector3i(x / p_scalar, y / p_scalar, z / p_scalar); } -Vector3i &Vector3i::operator%=(int32_t p_scalar) { +Vector3i &Vector3i::operator%=(const int32_t p_scalar) { x %= p_scalar; y %= p_scalar; z %= p_scalar; return *this; } -Vector3i Vector3i::operator%(int32_t p_scalar) const { +Vector3i Vector3i::operator%(const int32_t p_scalar) const { return Vector3i(x % p_scalar, y % p_scalar, z % p_scalar); } |