diff options
Diffstat (limited to 'core/math')
69 files changed, 1315 insertions, 803 deletions
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index 1079da75ef..14057b96be 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -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)) { @@ -210,7 +209,7 @@ bool AStar::has_point(int p_id) const { return points.has(p_id); } -Array AStar::get_points() { +Array AStar::get_point_ids() { Array point_list; for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) { @@ -344,7 +343,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) { } sorter.pop_heap(0, open_list.size(), open_list.ptrw()); // Remove the current point from the open list - open_list.remove(open_list.size() - 1); + open_list.remove_at(open_list.size() - 1); p->closed_pass = pass; // Mark the point as closed for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) { @@ -539,7 +538,7 @@ void AStar::_bind_methods() { ClassDB::bind_method(D_METHOD("remove_point", "id"), &AStar::remove_point); ClassDB::bind_method(D_METHOD("has_point", "id"), &AStar::has_point); ClassDB::bind_method(D_METHOD("get_point_connections", "id"), &AStar::get_point_connections); - ClassDB::bind_method(D_METHOD("get_points"), &AStar::get_points); + ClassDB::bind_method(D_METHOD("get_point_ids"), &AStar::get_point_ids); ClassDB::bind_method(D_METHOD("set_point_disabled", "id", "disabled"), &AStar::set_point_disabled, DEFVAL(true)); ClassDB::bind_method(D_METHOD("is_point_disabled", "id"), &AStar::is_point_disabled); @@ -606,8 +605,8 @@ Vector<int> AStar2D::get_point_connections(int p_id) { return astar.get_point_connections(p_id); } -Array AStar2D::get_points() { - return astar.get_points(); +Array AStar2D::get_point_ids() { + return astar.get_point_ids(); } void AStar2D::set_point_disabled(int p_id, bool p_disabled) { @@ -699,8 +698,7 @@ Vector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) { ERR_FAIL_COND_V_MSG(!to_exists, Vector<Vector2>(), vformat("Can't get point path. Point with id: %d doesn't exist.", p_to_id)); if (a == b) { - Vector<Vector2> ret; - ret.push_back(Vector2(a->pos.x, a->pos.y)); + Vector<Vector2> ret = { Vector2(a->pos.x, a->pos.y) }; return ret; } @@ -812,7 +810,7 @@ bool AStar2D::_solve(AStar::Point *begin_point, AStar::Point *end_point) { } sorter.pop_heap(0, open_list.size(), open_list.ptrw()); // Remove the current point from the open list - open_list.remove(open_list.size() - 1); + open_list.remove_at(open_list.size() - 1); p->closed_pass = astar.pass; // Mark the point as closed for (OAHashMap<int, AStar::Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) { @@ -859,7 +857,7 @@ void AStar2D::_bind_methods() { ClassDB::bind_method(D_METHOD("remove_point", "id"), &AStar2D::remove_point); ClassDB::bind_method(D_METHOD("has_point", "id"), &AStar2D::has_point); ClassDB::bind_method(D_METHOD("get_point_connections", "id"), &AStar2D::get_point_connections); - ClassDB::bind_method(D_METHOD("get_points"), &AStar2D::get_points); + ClassDB::bind_method(D_METHOD("get_point_ids"), &AStar2D::get_point_ids); ClassDB::bind_method(D_METHOD("set_point_disabled", "id", "disabled"), &AStar2D::set_point_disabled, DEFVAL(true)); ClassDB::bind_method(D_METHOD("is_point_disabled", "id"), &AStar2D::is_point_disabled); diff --git a/core/math/a_star.h b/core/math/a_star.h index 64fa32a325..130c202a61 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -37,9 +37,7 @@ #include "core/templates/oa_hash_map.h" /** - A* pathfinding algorithm - - @author Juan Linietsky <reduzio@gmail.com> + A* pathfinding algorithm. */ class AStar : public RefCounted { @@ -138,7 +136,7 @@ public: void remove_point(int p_id); bool has_point(int p_id) const; Vector<int> get_point_connections(int p_id); - Array get_points(); + Array get_point_ids(); void set_point_disabled(int p_id, bool p_disabled = true); bool is_point_disabled(int p_id) const; @@ -188,7 +186,7 @@ public: void remove_point(int p_id); bool has_point(int p_id) const; Vector<int> get_point_connections(int p_id); - Array get_points(); + Array get_point_ids(); void set_point_disabled(int p_id, bool p_disabled = true); bool is_point_disabled(int p_id) const; diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp index f3e78c0080..4c89be7f4d 100644 --- a/core/math/aabb.cpp +++ b/core/math/aabb.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -46,6 +46,11 @@ bool AABB::operator!=(const AABB &p_rval) const { } void AABB::merge_with(const AABB &p_aabb) { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) { + ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size."); + } +#endif Vector3 beg_1, beg_2; Vector3 end_1, end_2; Vector3 min, max; @@ -72,6 +77,11 @@ bool AABB::is_equal_approx(const AABB &p_aabb) const { } AABB AABB::intersection(const AABB &p_aabb) const { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) { + ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size."); + } +#endif Vector3 src_min = position; Vector3 src_max = position + size; Vector3 dst_min = p_aabb.position; @@ -104,6 +114,11 @@ AABB AABB::intersection(const AABB &p_aabb) const { } bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip, Vector3 *r_normal) const { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) { + ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size."); + } +#endif Vector3 c1, c2; Vector3 end = position + size; real_t near = -1e20; @@ -147,6 +162,11 @@ bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 * } bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip, Vector3 *r_normal) const { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) { + ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size."); + } +#endif real_t min = 0, max = 1; int axis = 0; real_t sign = 0; @@ -266,14 +286,14 @@ int AABB::get_longest_axis_index() const { Vector3 AABB::get_shortest_axis() const { Vector3 axis(1, 0, 0); - real_t max_size = size.x; + real_t min_size = size.x; - if (size.y < max_size) { + if (size.y < min_size) { axis = Vector3(0, 1, 0); - max_size = size.y; + min_size = size.y; } - if (size.z < max_size) { + if (size.z < min_size) { axis = Vector3(0, 0, 1); } @@ -282,14 +302,14 @@ Vector3 AABB::get_shortest_axis() const { int AABB::get_shortest_axis_index() const { int axis = 0; - real_t max_size = size.x; + real_t min_size = size.x; - if (size.y < max_size) { + if (size.y < min_size) { axis = 1; - max_size = size.y; + min_size = size.y; } - if (size.z < max_size) { + if (size.z < min_size) { axis = 2; } diff --git a/core/math/aabb.h b/core/math/aabb.h index 02ce2501a0..cb6f05e9ea 100644 --- a/core/math/aabb.h +++ b/core/math/aabb.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -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 AABB { -public: +struct _NO_DISCARD_ AABB { Vector3 position; Vector3 size; @@ -132,6 +132,11 @@ public: }; inline bool AABB::intersects(const AABB &p_aabb) const { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) { + ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size."); + } +#endif if (position.x >= (p_aabb.position.x + p_aabb.size.x)) { return false; } @@ -155,6 +160,11 @@ inline bool AABB::intersects(const AABB &p_aabb) const { } inline bool AABB::intersects_inclusive(const AABB &p_aabb) const { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) { + ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size."); + } +#endif if (position.x > (p_aabb.position.x + p_aabb.size.x)) { return false; } @@ -178,6 +188,11 @@ inline bool AABB::intersects_inclusive(const AABB &p_aabb) const { } inline bool AABB::encloses(const AABB &p_aabb) const { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) { + ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size."); + } +#endif Vector3 src_min = position; Vector3 src_max = position + size; Vector3 dst_min = p_aabb.position; @@ -288,6 +303,11 @@ bool AABB::inside_convex_shape(const Plane *p_planes, int p_plane_count) const { } bool AABB::has_point(const Vector3 &p_point) const { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) { + ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size."); + } +#endif if (p_point.x < position.x) { return false; } @@ -311,6 +331,11 @@ bool AABB::has_point(const Vector3 &p_point) const { } inline void AABB::expand_to(const Vector3 &p_vector) { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) { + ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size."); + } +#endif Vector3 begin = position; Vector3 end = position + size; @@ -377,6 +402,11 @@ inline real_t AABB::get_shortest_axis_size() const { } bool AABB::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) { + 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; diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h index a5616b8d79..8b244e9fe4 100644 --- a/core/math/audio_frame.h +++ b/core/math/audio_frame.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -124,10 +124,9 @@ struct AudioFrame { r = p_frame.r; } - _ALWAYS_INLINE_ AudioFrame &operator=(const AudioFrame &p_frame) { + _ALWAYS_INLINE_ void operator=(const AudioFrame &p_frame) { l = p_frame.l; r = p_frame.r; - return *this; } _ALWAYS_INLINE_ operator Vector2() const { @@ -141,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 3d893afb4d..a9b4651664 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -94,6 +94,18 @@ Basis Basis::orthonormalized() const { return c; } +void Basis::orthogonalize() { + Vector3 scl = get_scale(); + orthonormalize(); + scale_local(scl); +} + +Basis Basis::orthogonalized() const { + Basis c = *this; + c.orthogonalize(); + return c; +} + bool Basis::is_orthogonal() const { Basis identity; Basis m = (*this) * transposed(); @@ -237,6 +249,24 @@ void Basis::scale_local(const Vector3 &p_scale) { *this = scaled_local(p_scale); } +void Basis::scale_orthogonal(const Vector3 &p_scale) { + *this = scaled_orthogonal(p_scale); +} + +Basis Basis::scaled_orthogonal(const Vector3 &p_scale) const { + Basis m = *this; + Vector3 s = Vector3(-1, -1, -1) + p_scale; + Vector3 dots; + Basis b; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + dots[j] += s[i] * abs(m.get_axis(i).normalized().dot(b.get_axis(j))); + } + } + m.scale_local(Vector3(1, 1, 1) + dots); + return m; +} + float Basis::get_uniform_scale() const { return (elements[0].length() + elements[1].length() + elements[2].length()) / 3.0; } @@ -261,7 +291,7 @@ Vector3 Basis::get_scale_abs() const { } Vector3 Basis::get_scale_local() const { - real_t det_sign = SGN(determinant()); + real_t det_sign = SIGN(determinant()); return det_sign * Vector3(elements[0].length(), elements[1].length(), elements[2].length()); } @@ -287,7 +317,7 @@ Vector3 Basis::get_scale() const { // matrix elements. // // The rotation part of this decomposition is returned by get_rotation* functions. - real_t det_sign = SGN(determinant()); + real_t det_sign = SIGN(determinant()); return det_sign * get_scale_abs(); } @@ -931,6 +961,15 @@ void Basis::_set_diagonal(const Vector3 &p_diag) { elements[2][2] = p_diag.z; } +Basis Basis::lerp(const Basis &p_to, const real_t &p_weight) const { + Basis b; + b.elements[0] = elements[0].lerp(p_to.elements[0], p_weight); + b.elements[1] = elements[1].lerp(p_to.elements[1], p_weight); + b.elements[2] = elements[2].lerp(p_to.elements[2], p_weight); + + return b; +} + Basis Basis::slerp(const Basis &p_to, const real_t &p_weight) const { //consider scale Quaternion from(*this); diff --git a/core/math/basis.h b/core/math/basis.h index e2fdb95685..683f05150c 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -34,11 +34,7 @@ #include "core/math/quaternion.h" #include "core/math/vector3.h" -class 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), @@ -123,6 +119,9 @@ public: void scale_local(const Vector3 &p_scale); Basis scaled_local(const Vector3 &p_scale) const; + void scale_orthogonal(const Vector3 &p_scale); + Basis scaled_orthogonal(const Vector3 &p_scale) const; + void make_scale_uniform(); float get_uniform_scale() const; @@ -168,6 +167,7 @@ public: bool is_diagonal() const; bool is_rotation() const; + Basis lerp(const Basis &p_to, const real_t &p_weight) const; Basis slerp(const Basis &p_to, const real_t &p_weight) const; void rotate_sh(real_t *p_values); @@ -233,6 +233,9 @@ public: void orthonormalize(); Basis orthonormalized() const; + void orthogonalize(); + Basis orthogonalized() const; + #ifdef MATH_CHECKS bool is_symmetric() const; #endif @@ -256,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) { @@ -327,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.h b/core/math/bvh.h index 65b8b102a3..a8e3cc7bbe 100644 --- a/core/math/bvh.h +++ b/core/math/bvh.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -654,7 +654,7 @@ private: // remove from changed items (not very efficient yet) for (int n = 0; n < (int)changed_items.size(); n++) { if (changed_items[n] == p_handle) { - changed_items.remove_unordered(n); + changed_items.remove_at_unordered(n); // because we are using an unordered remove, // the last changed item will now be at spot 'n', diff --git a/core/math/bvh_abb.h b/core/math/bvh_abb.h index bd9a01a87e..009032d34d 100644 --- a/core/math/bvh_abb.h +++ b/core/math/bvh_abb.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/bvh_pair.inc b/core/math/bvh_pair.inc index 839db59a3a..a12acec2b6 100644 --- a/core/math/bvh_pair.inc +++ b/core/math/bvh_pair.inc @@ -51,7 +51,7 @@ struct ItemPairs { for (int n = 0; n < num_pairs; n++) { if (extended_pairs[n].handle == h) { userdata = extended_pairs[n].userdata; - extended_pairs.remove_unordered(n); + extended_pairs.remove_at_unordered(n); num_pairs--; break; } diff --git a/core/math/bvh_split.inc b/core/math/bvh_split.inc index 6f54d06ce7..f19ee8a7da 100644 --- a/core/math/bvh_split.inc +++ b/core/math/bvh_split.inc @@ -30,8 +30,8 @@ void _split_leaf_sort_groups_simple(int &num_a, int &num_b, uint16_t *group_a, u int order[Point::AXIS_COUNT]; - order[0] = size.min_axis(); - order[Point::AXIS_COUNT - 1] = size.max_axis(); + order[0] = size.min_axis_index(); + order[Point::AXIS_COUNT - 1] = size.max_axis_index(); static_assert(Point::AXIS_COUNT <= 3); if (Point::AXIS_COUNT == 3) { diff --git a/core/math/bvh_tree.h b/core/math/bvh_tree.h index 3169d31ec7..c948d83456 100644 --- a/core/math/bvh_tree.h +++ b/core/math/bvh_tree.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index 48984c4d5b..f5d746ef0f 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -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 { @@ -346,6 +350,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform */ Vector<Plane> planes; + planes.resize(6); const real_t *matrix = (const real_t *)this->matrix; @@ -360,7 +365,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[0] = p_transform.xform(new_plane); ///////--- Far Plane ---/////// new_plane = Plane(matrix[3] - matrix[2], @@ -371,7 +376,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[1] = p_transform.xform(new_plane); ///////--- Left Plane ---/////// new_plane = Plane(matrix[3] + matrix[0], @@ -382,7 +387,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[2] = p_transform.xform(new_plane); ///////--- Top Plane ---/////// new_plane = Plane(matrix[3] - matrix[1], @@ -393,7 +398,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[3] = p_transform.xform(new_plane); ///////--- Right Plane ---/////// new_plane = Plane(matrix[3] - matrix[0], @@ -404,7 +409,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[4] = p_transform.xform(new_plane); ///////--- Bottom Plane ---/////// new_plane = Plane(matrix[3] + matrix[1], @@ -415,7 +420,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform new_plane.normal = -new_plane.normal; new_plane.normalize(); - planes.push_back(p_transform.xform(new_plane)); + planes.write[5] = p_transform.xform(new_plane); return planes; } diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h index 786d46055a..285d2ae384 100644 --- a/core/math/camera_matrix.h +++ b/core/math/camera_matrix.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -31,8 +31,14 @@ #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" + +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 dc86cacf8f..b06d20b3d3 100644 --- a/core/math/color.cpp +++ b/core/math/color.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -107,6 +107,39 @@ uint64_t Color::to_rgba64() const { return c; } +String _to_hex(float p_val) { + int v = Math::round(p_val * 255); + v = CLAMP(v, 0, 255); + String ret; + + for (int i = 0; i < 2; i++) { + char32_t c[2] = { 0, 0 }; + int lv = v & 0xF; + if (lv < 10) { + c[0] = '0' + lv; + } else { + c[0] = 'a' + lv - 10; + } + + v >>= 4; + String cs = (const char32_t *)c; + ret = cs + ret; + } + + return ret; +} + +String Color::to_html(bool p_alpha) const { + String txt; + txt += _to_hex(r); + txt += _to_hex(g); + txt += _to_hex(b); + if (p_alpha) { + txt += _to_hex(a); + } + return txt; +} + float Color::get_h() const { float min = MIN(r, g); min = MIN(min, b); @@ -249,20 +282,6 @@ Color Color::hex64(uint64_t p_hex) { return Color(r, g, b, a); } -Color Color::from_rgbe9995(uint32_t p_rgbe) { - float r = p_rgbe & 0x1ff; - 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 rd = r * m; - float gd = g * m; - float bd = b * m; - - return Color(rd, gd, bd, 1.0f); -} - static int _parse_col4(const String &p_str, int p_ofs) { char character = p_str[p_ofs]; @@ -428,43 +447,24 @@ Color Color::from_string(const String &p_string, const Color &p_default) { } } -String _to_hex(float p_val) { - int v = Math::round(p_val * 255); - v = CLAMP(v, 0, 255); - String ret; - - for (int i = 0; i < 2; i++) { - char32_t c[2] = { 0, 0 }; - int lv = v & 0xF; - if (lv < 10) { - c[0] = '0' + lv; - } else { - c[0] = 'a' + lv - 10; - } - - v >>= 4; - String cs = (const char32_t *)c; - ret = cs + ret; - } - - return ret; +Color Color::from_hsv(float p_h, float p_s, float p_v, float p_alpha) { + Color c; + c.set_hsv(p_h, p_s, p_v, p_alpha); + return c; } -String Color::to_html(bool p_alpha) const { - String txt; - txt += _to_hex(r); - txt += _to_hex(g); - txt += _to_hex(b); - if (p_alpha) { - txt += _to_hex(a); - } - return txt; -} +Color Color::from_rgbe9995(uint32_t p_rgbe) { + float r = p_rgbe & 0x1ff; + 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); -Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const { - Color c; - c.set_hsv(p_h, p_s, p_v, p_a); - return c; + float rd = r * m; + float gd = g * m; + float bd = b * m; + + return Color(rd, gd, bd, 1.0f); } Color::operator String() const { diff --git a/core/math/color.h b/core/math/color.h index a95dbf4f60..72a4a5f8be 100644 --- a/core/math/color.h +++ b/core/math/color.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -34,7 +34,7 @@ #include "core/math/math_funcs.h" #include "core/string/ustring.h" -struct Color { +struct _NO_DISCARD_ Color { union { struct { float r; @@ -51,6 +51,7 @@ struct Color { uint64_t to_rgba64() const; uint64_t to_argb64() const; uint64_t to_abgr64() const; + String to_html(bool p_alpha = true) const; float get_h() const; float get_s() const; float get_v() const; @@ -93,6 +94,10 @@ struct Color { void invert(); Color inverted() const; + _FORCE_INLINE_ float get_luminance() const { + return 0.2126 * r + 0.7152 * g + 0.0722 * b; + } + _FORCE_INLINE_ Color lerp(const Color &p_to, float p_weight) const { Color res = *this; @@ -189,8 +194,7 @@ struct Color { static String get_named_color_name(int p_idx); static Color get_named_color(int p_idx); static Color from_string(const String &p_string, const Color &p_default); - String to_html(bool p_alpha = true) const; - Color from_hsv(float p_h, float p_s, float p_v, float p_a) const; + static Color from_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0); static Color from_rgbe9995(uint32_t p_rgbe); _FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys diff --git a/core/math/convex_hull.cpp b/core/math/convex_hull.cpp index f6560f1bea..bd292f4c2a 100644 --- a/core/math/convex_hull.cpp +++ b/core/math/convex_hull.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -606,9 +606,9 @@ private: PagedAllocator<Face> face_pool; LocalVector<Vertex *> original_vertices; int32_t merge_stamp = 0; - int32_t min_axis = 0; - int32_t med_axis = 0; - int32_t max_axis = 0; + Vector3::Axis min_axis = Vector3::Axis::AXIS_X; + Vector3::Axis med_axis = Vector3::Axis::AXIS_X; + Vector3::Axis max_axis = Vector3::Axis::AXIS_X; int32_t used_edge_pairs = 0; int32_t max_used_edge_pairs = 0; @@ -1585,12 +1585,12 @@ void ConvexHullInternal::compute(const Vector3 *p_coords, int32_t p_count) { } Vector3 s = aabb.size; - max_axis = s.max_axis(); - min_axis = s.min_axis(); + max_axis = s.max_axis_index(); + min_axis = s.min_axis_index(); if (min_axis == max_axis) { - min_axis = (max_axis + 1) % 3; + min_axis = Vector3::Axis((max_axis + 1) % 3); } - med_axis = 3 - max_axis - min_axis; + med_axis = Vector3::Axis(3 - max_axis - min_axis); s /= real_t(10216); if (((med_axis + 1) % 3) != max_axis) { @@ -1688,7 +1688,7 @@ real_t ConvexHullInternal::shrink(real_t p_amount, real_t p_clamp_amount) { while (stack.size() > 0) { Vertex *v = stack[stack.size() - 1]; - stack.remove(stack.size() - 1); + stack.remove_at(stack.size() - 1); Edge *e = v->edges; if (e) { do { @@ -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/convex_hull.h b/core/math/convex_hull.h index 806c6cc3fb..bd86fe0eba 100644 --- a/core/math/convex_hull.h +++ b/core/math/convex_hull.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/delaunay_2d.h b/core/math/delaunay_2d.h index 2f80cb5634..c39997d6a9 100644 --- a/core/math/delaunay_2d.h +++ b/core/math/delaunay_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -32,6 +32,7 @@ #define DELAUNAY_2D_H #include "core/math/rect2.h" +#include "core/templates/vector.h" class Delaunay2D { public: @@ -123,7 +124,7 @@ public: for (int j = 0; j < triangles.size(); j++) { if (triangles[j].bad) { - triangles.remove(j); + triangles.remove_at(j); j--; } } @@ -154,7 +155,7 @@ public: } } if (invalid) { - triangles.remove(i); + triangles.remove_at(i); i--; } } diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h index 81adf4d19a..7ad5f76645 100644 --- a/core/math/delaunay_3d.h +++ b/core/math/delaunay_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/disjoint_set.h b/core/math/disjoint_set.h index b155412f64..8657dc068e 100644 --- a/core/math/disjoint_set.h +++ b/core/math/disjoint_set.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -34,10 +34,6 @@ #include "core/templates/map.h" #include "core/templates/vector.h" -/** - @author Marios Staikopoulos <marios@staik.net> -*/ - /* This DisjointSet class uses Find with path compression and Union by rank */ template <typename T, class C = Comparator<T>, class AL = DefaultAllocator> class DisjointSet { diff --git a/core/math/dynamic_bvh.cpp b/core/math/dynamic_bvh.cpp index f3fb473981..7aeb2aaaac 100644 --- a/core/math/dynamic_bvh.cpp +++ b/core/math/dynamic_bvh.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/dynamic_bvh.h b/core/math/dynamic_bvh.h index 0b6286cd9d..50ec2c2b30 100644 --- a/core/math/dynamic_bvh.h +++ b/core/math/dynamic_bvh.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -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 05f2c8dac9..0ddac9744e 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -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; @@ -410,6 +473,14 @@ Error Expression::_get_token(Token &r_token) { } else if (id == "self") { r_token.type = TK_SELF; } else { + for (int i = 0; i < Variant::VARIANT_MAX; i++) { + if (id == Variant::get_type_name(Variant::Type(i))) { + r_token.type = TK_BASIC_TYPE; + r_token.value = i; + return OK; + } + } + if (Variant::has_utility_function(id)) { r_token.type = TK_BUILTIN_FUNC; r_token.value = id; @@ -1087,7 +1158,7 @@ Expression::ENode *Expression::_parse_expression() { op->nodes[1] = nullptr; expression.write[i].is_op = false; expression.write[i].node = op; - expression.remove(i + 1); + expression.remove_at(i + 1); } } else { @@ -1119,8 +1190,8 @@ Expression::ENode *Expression::_parse_expression() { //replace all 3 nodes by this operator and make it an expression expression.write[next_op - 1].node = op; - expression.remove(next_op); - expression.remove(next_op); + expression.remove_at(next_op); + expression.remove_at(next_op); } } diff --git a/core/math/expression.h b/core/math/expression.h index aecf662d0a..9b87bdd6ec 100644 --- a/core/math/expression.h +++ b/core/math/expression.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/face3.cpp b/core/math/face3.cpp index 31a853e1a9..d588f34e5d 100644 --- a/core/math/face3.cpp +++ b/core/math/face3.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -260,8 +260,8 @@ void Face3::project_range(const Vector3 &p_normal, const Transform3D &p_transfor } void Face3::get_support(const Vector3 &p_normal, const Transform3D &p_transform, Vector3 *p_vertices, int *p_count, int p_max) const { -#define _FACE_IS_VALID_SUPPORT_THRESHOLD 0.98 -#define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.05 + constexpr double face_support_threshold = 0.98; + constexpr double edge_support_threshold = 0.05; if (p_max <= 0) { return; @@ -270,7 +270,7 @@ void Face3::get_support(const Vector3 &p_normal, const Transform3D &p_transform, Vector3 n = p_transform.basis.xform_inv(p_normal); /** TEST FACE AS SUPPORT **/ - if (get_plane().normal.dot(n) > _FACE_IS_VALID_SUPPORT_THRESHOLD) { + if (get_plane().normal.dot(n) > face_support_threshold) { *p_count = MIN(3, p_max); for (int i = 0; i < *p_count; i++) { @@ -304,7 +304,7 @@ void Face3::get_support(const Vector3 &p_normal, const Transform3D &p_transform, // check if edge is valid as a support real_t dot = (vertex[i] - vertex[(i + 1) % 3]).normalized().dot(n); dot = ABS(dot); - if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD) { + if (dot < edge_support_threshold) { *p_count = MIN(2, p_max); for (int j = 0; j < *p_count; j++) { diff --git a/core/math/face3.h b/core/math/face3.h index 0a8c1c6041..8b123f078c 100644 --- a/core/math/face3.h +++ b/core/math/face3.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -36,8 +36,7 @@ #include "core/math/transform_3d.h" #include "core/math/vector3.h" -class 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; diff --git a/core/math/geometry_2d.cpp b/core/math/geometry_2d.cpp index 7b2630b4ff..9fa45a3363 100644 --- a/core/math/geometry_2d.cpp +++ b/core/math/geometry_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/geometry_2d.h b/core/math/geometry_2d.h index 6010159597..a2881d5f60 100644 --- a/core/math/geometry_2d.h +++ b/core/math/geometry_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -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" @@ -181,8 +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). - // (equivalent to condition (C.y < 0 && D.y < CMP_EPSILON) || (C.y > 0 && D.y > CMP_EPSILON)) - if (C.y * D.y > CMP_EPSILON) { + if ((C.y < -CMP_EPSILON && D.y < -CMP_EPSILON) || (C.y > CMP_EPSILON && D.y > CMP_EPSILON)) { return false; } diff --git a/core/math/geometry_3d.cpp b/core/math/geometry_3d.cpp index 88d2656025..a9ff46410e 100644 --- a/core/math/geometry_3d.cpp +++ b/core/math/geometry_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -281,16 +281,16 @@ static inline void _plot_face(uint8_t ***p_cell_status, int x, int y, int z, int int div_y = len_y > 1 ? 2 : 1; int div_z = len_z > 1 ? 2 : 1; -#define _SPLIT(m_i, m_div, m_v, m_len_v, m_new_v, m_new_len_v) \ - if (m_div == 1) { \ - m_new_v = m_v; \ - m_new_len_v = 1; \ - } else if (m_i == 0) { \ - m_new_v = m_v; \ - m_new_len_v = m_len_v / 2; \ - } else { \ - m_new_v = m_v + m_len_v / 2; \ - m_new_len_v = m_len_v - m_len_v / 2; \ +#define SPLIT_DIV(m_i, m_div, m_v, m_len_v, m_new_v, m_new_len_v) \ + if (m_div == 1) { \ + m_new_v = m_v; \ + m_new_len_v = 1; \ + } else if (m_i == 0) { \ + m_new_v = m_v; \ + m_new_len_v = m_len_v / 2; \ + } else { \ + m_new_v = m_v + m_len_v / 2; \ + m_new_len_v = m_len_v - m_len_v / 2; \ } int new_x; @@ -301,18 +301,20 @@ static inline void _plot_face(uint8_t ***p_cell_status, int x, int y, int z, int int new_len_z; for (int i = 0; i < div_x; i++) { - _SPLIT(i, div_x, x, len_x, new_x, new_len_x); + SPLIT_DIV(i, div_x, x, len_x, new_x, new_len_x); for (int j = 0; j < div_y; j++) { - _SPLIT(j, div_y, y, len_y, new_y, new_len_y); + SPLIT_DIV(j, div_y, y, len_y, new_y, new_len_y); for (int k = 0; k < div_z; k++) { - _SPLIT(k, div_z, z, len_z, new_z, new_len_z); + SPLIT_DIV(k, div_z, z, len_z, new_z, new_len_z); _plot_face(p_cell_status, new_x, new_y, new_z, new_len_x, new_len_y, new_len_z, voxelsize, p_face); } } } + +#undef SPLIT_DIV } static inline void _mark_outside(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z) { @@ -491,11 +493,10 @@ static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, i } Vector<Face3> Geometry3D::wrap_geometry(Vector<Face3> p_array, real_t *p_error) { -#define _MIN_SIZE 1.0 -#define _MAX_LENGTH 20 - int face_count = p_array.size(); const Face3 *faces = p_array.ptr(); + constexpr double min_size = 1.0; + constexpr int max_length = 20; AABB global_aabb; @@ -512,22 +513,22 @@ Vector<Face3> Geometry3D::wrap_geometry(Vector<Face3> p_array, real_t *p_error) // Determine amount of cells in grid axis. int div_x, div_y, div_z; - if (global_aabb.size.x / _MIN_SIZE < _MAX_LENGTH) { - div_x = (int)(global_aabb.size.x / _MIN_SIZE) + 1; + if (global_aabb.size.x / min_size < max_length) { + div_x = (int)(global_aabb.size.x / min_size) + 1; } else { - div_x = _MAX_LENGTH; + div_x = max_length; } - if (global_aabb.size.y / _MIN_SIZE < _MAX_LENGTH) { - div_y = (int)(global_aabb.size.y / _MIN_SIZE) + 1; + if (global_aabb.size.y / min_size < max_length) { + div_y = (int)(global_aabb.size.y / min_size) + 1; } else { - div_y = _MAX_LENGTH; + div_y = max_length; } - if (global_aabb.size.z / _MIN_SIZE < _MAX_LENGTH) { - div_z = (int)(global_aabb.size.z / _MIN_SIZE) + 1; + if (global_aabb.size.z / min_size < max_length) { + div_z = (int)(global_aabb.size.z / min_size) + 1; } else { - div_z = _MAX_LENGTH; + div_z = max_length; } Vector3 voxelsize = global_aabb.size; @@ -644,14 +645,15 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes Vector3 right = p.normal.cross(ref).normalized(); Vector3 up = p.normal.cross(right).normalized(); - Vector<Vector3> vertices; - Vector3 center = p.center(); + // make a quad clockwise - vertices.push_back(center - up * subplane_size + right * subplane_size); - vertices.push_back(center - up * subplane_size - right * subplane_size); - vertices.push_back(center + up * subplane_size - right * subplane_size); - vertices.push_back(center + up * subplane_size + right * subplane_size); + Vector<Vector3> vertices = { + center - up * subplane_size + right * subplane_size, + center - up * subplane_size - right * subplane_size, + center + up * subplane_size - right * subplane_size, + center + up * subplane_size + right * subplane_size + }; for (int j = 0; j < p_planes.size(); j++) { if (j == i) { @@ -762,14 +764,14 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes } Vector<Plane> Geometry3D::build_box_planes(const Vector3 &p_extents) { - Vector<Plane> planes; - - planes.push_back(Plane(Vector3(1, 0, 0), p_extents.x)); - planes.push_back(Plane(Vector3(-1, 0, 0), p_extents.x)); - planes.push_back(Plane(Vector3(0, 1, 0), p_extents.y)); - planes.push_back(Plane(Vector3(0, -1, 0), p_extents.y)); - planes.push_back(Plane(Vector3(0, 0, 1), p_extents.z)); - planes.push_back(Plane(Vector3(0, 0, -1), p_extents.z)); + Vector<Plane> planes = { + Plane(Vector3(1, 0, 0), p_extents.x), + Plane(Vector3(-1, 0, 0), p_extents.x), + Plane(Vector3(0, 1, 0), p_extents.y), + Plane(Vector3(0, -1, 0), p_extents.y), + Plane(Vector3(0, 0, 1), p_extents.z), + Plane(Vector3(0, 0, -1), p_extents.z) + }; return planes; } diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h index 6a59b34585..0f6ab5c716 100644 --- a/core/math/geometry_3d.h +++ b/core/math/geometry_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/math_defs.h b/core/math/math_defs.h index 900e90a598..b8b82f2ff4 100644 --- a/core/math/math_defs.h +++ b/core/math/math_defs.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -68,37 +68,38 @@ enum Orientation { VERTICAL }; -enum HAlign { - HALIGN_LEFT, - HALIGN_CENTER, - HALIGN_RIGHT, - HALIGN_FILL, +enum HorizontalAlignment { + HORIZONTAL_ALIGNMENT_LEFT, + HORIZONTAL_ALIGNMENT_CENTER, + HORIZONTAL_ALIGNMENT_RIGHT, + HORIZONTAL_ALIGNMENT_FILL, }; -enum VAlign { - VALIGN_TOP, - VALIGN_CENTER, - VALIGN_BOTTOM +enum VerticalAlignment { + VERTICAL_ALIGNMENT_TOP, + VERTICAL_ALIGNMENT_CENTER, + VERTICAL_ALIGNMENT_BOTTOM, + VERTICAL_ALIGNMENT_FILL, }; -enum InlineAlign { +enum InlineAlignment { // Image alignment points. - INLINE_ALIGN_TOP_TO = 0b0000, - INLINE_ALIGN_CENTER_TO = 0b0001, - INLINE_ALIGN_BOTTOM_TO = 0b0010, - INLINE_ALIGN_IMAGE_MASK = 0b0011, + INLINE_ALIGNMENT_TOP_TO = 0b0000, + INLINE_ALIGNMENT_CENTER_TO = 0b0001, + INLINE_ALIGNMENT_BOTTOM_TO = 0b0010, + INLINE_ALIGNMENT_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, + INLINE_ALIGNMENT_TO_TOP = 0b0000, + INLINE_ALIGNMENT_TO_CENTER = 0b0100, + INLINE_ALIGNMENT_TO_BASELINE = 0b1000, + INLINE_ALIGNMENT_TO_BOTTOM = 0b1100, + INLINE_ALIGNMENT_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 + INLINE_ALIGNMENT_TOP = INLINE_ALIGNMENT_TOP_TO | INLINE_ALIGNMENT_TO_TOP, + INLINE_ALIGNMENT_CENTER = INLINE_ALIGNMENT_CENTER_TO | INLINE_ALIGNMENT_TO_CENTER, + INLINE_ALIGNMENT_BOTTOM = INLINE_ALIGNMENT_BOTTOM_TO | INLINE_ALIGNMENT_TO_BOTTOM }; enum Side { diff --git a/core/math/math_fieldwise.cpp b/core/math/math_fieldwise.cpp index 570c57e254..1717ecd74b 100644 --- a/core/math/math_fieldwise.cpp +++ b/core/math/math_fieldwise.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/math_fieldwise.h b/core/math/math_fieldwise.h index fe44d09900..f8a5b7cbb2 100644 --- a/core/math/math_fieldwise.h +++ b/core/math/math_fieldwise.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp index bbed257f60..614828d7cb 100644 --- a/core/math/math_funcs.cpp +++ b/core/math/math_funcs.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -53,6 +53,10 @@ uint32_t Math::rand() { return default_rand.rand(); } +double Math::randfn(double mean, double deviation) { + return default_rand.randfn(mean, deviation); +} + int Math::step_decimals(double p_step) { static const int maxn = 10; static const double sd[maxn] = { diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index baff10af98..f3d10c3f0d 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -266,8 +266,8 @@ public: float s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0f, 1.0f); return s * s * (3.0f - 2.0f * s); } - static _ALWAYS_INLINE_ double move_toward(double p_from, double p_to, double p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SGN(p_to - p_from) * p_delta; } - static _ALWAYS_INLINE_ float move_toward(float p_from, float p_to, float p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SGN(p_to - p_from) * p_delta; } + static _ALWAYS_INLINE_ double move_toward(double p_from, double p_to, double p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SIGN(p_to - p_from) * p_delta; } + static _ALWAYS_INLINE_ float move_toward(float p_from, float p_to, float p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + 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; } @@ -291,6 +291,19 @@ public: return is_zero_approx(range) ? min : value - (range * Math::floor((value - min) / range)); } + static _ALWAYS_INLINE_ float fract(float value) { + return value - floor(value); + } + static _ALWAYS_INLINE_ double fract(double value) { + return value - floor(value); + } + static _ALWAYS_INLINE_ float pingpong(float value, float length) { + return (length != 0.0f) ? abs(fract((value - length) / (length * 2.0f)) * length * 2.0f - length) : 0.0f; + } + static _ALWAYS_INLINE_ double pingpong(double value, double length) { + return (length != 0.0) ? abs(fract((value - length) / (length * 2.0)) * length * 2.0 - length) : 0.0; + } + // double only, as these functions are mainly used by the editor and not performance-critical, static double ease(double p_x, double p_c); static int step_decimals(double p_step); @@ -305,6 +318,7 @@ public: static uint32_t rand(); static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_32BIT_MAX; } static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_32BIT_MAX; } + static double randfn(double mean, double deviation); static double random(double from, double to); static float random(float from, float to); diff --git a/core/math/octree.h b/core/math/octree.h index 493a63aa2e..23ba4c1aa3 100644 --- a/core/math/octree.h +++ b/core/math/octree.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -103,7 +103,7 @@ private: Octant *parent = nullptr; Octant *children[8] = { nullptr }; - int children_count = 0; // cache for amount of childrens (fast check for removal) + int children_count = 0; // cache for amount of children (fast check for removal) int parent_index = -1; // cache for parent index (fast check for removal) List<Element *, AL> pairable_elements; diff --git a/core/math/plane.cpp b/core/math/plane.cpp index 59f7918258..8bd4b5ef4f 100644 --- a/core/math/plane.cpp +++ b/core/math/plane.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/plane.h b/core/math/plane.h index 18be5d5d12..66c1741662 100644 --- a/core/math/plane.h +++ b/core/math/plane.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -35,13 +35,12 @@ class Variant; -class 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 944474686a..2ce603cb13 100644 --- a/core/math/quaternion.cpp +++ b/core/math/quaternion.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/quaternion.h b/core/math/quaternion.h index d8d0c06672..7874e4f428 100644 --- a/core/math/quaternion.h +++ b/core/math/quaternion.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -36,8 +36,7 @@ #include "core/math/vector3.h" #include "core/string/ustring.h" -class Quaternion { -public: +struct _NO_DISCARD_ Quaternion { union { struct { real_t x; @@ -134,12 +133,11 @@ public: w(p_q.w) { } - Quaternion &operator=(const Quaternion &p_q) { + void operator=(const Quaternion &p_q) { x = p_q.x; y = p_q.y; z = p_q.z; w = p_q.w; - return *this; } Quaternion(const Vector3 &v0, const Vector3 &v1) // shortest arc diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index d438a9a377..8e87d44b7f 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/quick_hull.h b/core/math/quick_hull.h index 48ea139cc9..b8d813c979 100644 --- a/core/math/quick_hull.h +++ b/core/math/quick_hull.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/random_number_generator.cpp b/core/math/random_number_generator.cpp index b40d010219..31eeed4399 100644 --- a/core/math/random_number_generator.cpp +++ b/core/math/random_number_generator.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/random_number_generator.h b/core/math/random_number_generator.h index 06cd3999f3..9352bae0a6 100644 --- a/core/math/random_number_generator.h +++ b/core/math/random_number_generator.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/random_pcg.cpp b/core/math/random_pcg.cpp index 681c2a9717..c69986e6df 100644 --- a/core/math/random_pcg.cpp +++ b/core/math/random_pcg.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/random_pcg.h b/core/math/random_pcg.h index 5a03b758ce..974dbbfc2e 100644 --- a/core/math/random_pcg.h +++ b/core/math/random_pcg.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp index f64bf560c8..d6e20bdc3c 100644 --- a/core/math/rect2.cpp +++ b/core/math/rect2.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -28,13 +28,22 @@ /* 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); } bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos, Point2 *r_normal) const { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0)) { + ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size."); + } +#endif real_t min = 0, max = 1; int axis = 0; real_t sign = 0; @@ -95,6 +104,11 @@ bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 } bool Rect2::intersects_transformed(const Transform2D &p_xform, const Rect2 &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("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size."); + } +#endif //SAT intersection between local and transformed rect2 Vector2 xf_points[4] = { @@ -268,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 26e202589d..6ecc02336c 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -31,11 +31,14 @@ #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 Rect2 { +struct _NO_DISCARD_ Rect2 { Point2 position; Size2 size; @@ -49,6 +52,11 @@ struct Rect2 { _FORCE_INLINE_ Vector2 get_center() const { return position + (size * 0.5); } inline bool intersects(const Rect2 &p_rect, const bool p_include_borders = false) const { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) { + ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size."); + } +#endif if (p_include_borders) { if (position.x > (p_rect.position.x + p_rect.size.width)) { return false; @@ -81,6 +89,11 @@ struct Rect2 { } inline real_t distance_to(const Vector2 &p_point) const { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0)) { + ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size."); + } +#endif real_t dist = 0.0; bool inside = true; @@ -117,6 +130,11 @@ struct Rect2 { bool intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos = nullptr, Point2 *r_normal = nullptr) const; inline bool encloses(const Rect2 &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("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 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)); @@ -147,7 +165,11 @@ struct Rect2 { } inline Rect2 merge(const Rect2 &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("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size."); + } +#endif Rect2 new_rect; new_rect.position.x = MIN(p_rect.position.x, position.x); @@ -160,7 +182,13 @@ struct Rect2 { return new_rect; } + inline bool has_point(const Point2 &p_point) const { +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0)) { + ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size."); + } +#endif if (p_point.x < position.x) { return false; } @@ -177,6 +205,7 @@ struct 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; } @@ -225,7 +254,11 @@ struct Rect2 { } inline void expand_to(const Vector2 &p_vector) { //in place function for speed - +#ifdef MATH_CHECKS + if (unlikely(size.x < 0 || size.y < 0)) { + ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size."); + } +#endif Vector2 begin = position; Vector2 end = position + size; @@ -323,6 +356,7 @@ struct 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) : @@ -335,190 +369,4 @@ struct Rect2 { } }; -struct 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 { - 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 { - 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 = (int)(MIN(p_rect_end.x, end.x) - new_rect.position.x); - new_rect.size.y = (int)(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 - - 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 { - 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) { - 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/static_raycaster.cpp b/core/math/static_raycaster.cpp index da05d49428..2510138d90 100644 --- a/core/math/static_raycaster.cpp +++ b/core/math/static_raycaster.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/static_raycaster.h b/core/math/static_raycaster.h index 3759c788a7..33254399c7 100644 --- a/core/math/static_raycaster.h +++ b/core/math/static_raycaster.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp index df43c605f9..e6e24e9b32 100644 --- a/core/math/transform_2d.cpp +++ b/core/math/transform_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -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. @@ -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(SGN(det) * elements[1].normalized())) - Math_PI * 0.5; + return Math::acos(elements[0].normalized().dot(SIGN(det) * elements[1].normalized())) - Math_PI * 0.5; } void Transform2D::set_skew(const real_t p_angle) { real_t det = basis_determinant(); - elements[1] = SGN(det) * elements[0].rotated((Math_PI * 0.5 + p_angle)).normalized() * elements[1].length(); + elements[1] = SIGN(det) * elements[0].rotated((Math_PI * 0.5 + p_angle)).normalized() * elements[1].length(); } real_t Transform2D::get_rotation() const { @@ -111,7 +113,7 @@ Transform2D::Transform2D(const real_t p_rot, const Size2 &p_scale, const real_t } Size2 Transform2D::get_scale() const { - real_t det_sign = SGN(basis_determinant()); + real_t det_sign = SIGN(basis_determinant()); return Size2(elements[0].length(), det_sign * elements[1].length()); } diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h index 8a0e876d96..f4546c13c8 100644 --- a/core/math/transform_2d.h +++ b/core/math/transform_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -31,9 +31,14 @@ #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" -struct Transform2D { +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": // M = (elements[0][0] elements[1][0]) // (elements[0][1] elements[1][1]) diff --git a/core/math/transform_3d.cpp b/core/math/transform_3d.cpp index 78ef117443..e5374315e2 100644 --- a/core/math/transform_3d.cpp +++ b/core/math/transform_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -80,9 +80,11 @@ void Transform3D::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, con origin = p_eye; } -Transform3D Transform3D::interpolate_with(const Transform3D &p_transform, real_t p_c) const { +Transform3D Transform3D::sphere_interpolate_with(const Transform3D &p_transform, real_t p_c) const { /* not sure if very "efficient" but good enough? */ + Transform3D interp; + Vector3 src_scale = basis.get_scale(); Quaternion src_rot = basis.get_rotation_quaternion(); Vector3 src_loc = origin; @@ -91,13 +93,21 @@ Transform3D Transform3D::interpolate_with(const Transform3D &p_transform, real_t Quaternion dst_rot = p_transform.basis.get_rotation_quaternion(); Vector3 dst_loc = p_transform.origin; - Transform3D interp; interp.basis.set_quaternion_scale(src_rot.slerp(dst_rot, p_c).normalized(), src_scale.lerp(dst_scale, p_c)); interp.origin = src_loc.lerp(dst_loc, p_c); return interp; } +Transform3D Transform3D::interpolate_with(const Transform3D &p_transform, real_t p_c) const { + Transform3D interp; + + interp.basis = basis.lerp(p_transform.basis, p_c); + interp.origin = origin.lerp(p_transform.origin, p_c); + + return interp; +} + void Transform3D::scale(const Vector3 &p_scale) { basis.scale(p_scale); origin *= p_scale; @@ -139,6 +149,16 @@ Transform3D Transform3D::orthonormalized() const { return _copy; } +void Transform3D::orthogonalize() { + basis.orthogonalize(); +} + +Transform3D Transform3D::orthogonalized() const { + Transform3D _copy = *this; + _copy.orthogonalize(); + return _copy; +} + bool Transform3D::is_equal_approx(const Transform3D &p_transform) const { return basis.is_equal_approx(p_transform.basis) && origin.is_equal_approx(p_transform.origin); } diff --git a/core/math/transform_3d.h b/core/math/transform_3d.h index 345e0fade0..3b4762e221 100644 --- a/core/math/transform_3d.h +++ b/core/math/transform_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -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 Transform3D { -public: +struct _NO_DISCARD_ Transform3D { Basis basis; Vector3 origin; @@ -69,6 +68,8 @@ public: void orthonormalize(); Transform3D orthonormalized() const; + void orthogonalize(); + Transform3D orthogonalized() const; bool is_equal_approx(const Transform3D &p_transform) const; bool operator==(const Transform3D &p_transform) const; @@ -99,6 +100,7 @@ public: void operator*=(const real_t p_val); Transform3D operator*(const real_t p_val) const; + Transform3D sphere_interpolate_with(const Transform3D &p_transform, real_t p_c) const; Transform3D interpolate_with(const Transform3D &p_transform, real_t p_c) const; _FORCE_INLINE_ Transform3D inverse_xform(const Transform3D &t) const { @@ -262,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/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 2f3da0b6a8..debc5cd00d 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/triangle_mesh.h b/core/math/triangle_mesh.h index 2d3b4db4bb..1b99945698 100644 --- a/core/math/triangle_mesh.h +++ b/core/math/triangle_mesh.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/triangulate.cpp b/core/math/triangulate.cpp index 28f1d96b14..f3e3de5fc2 100644 --- a/core/math/triangulate.cpp +++ b/core/math/triangulate.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/core/math/triangulate.h b/core/math/triangulate.h index 249ca6238f..0bfcfcb978 100644 --- a/core/math/triangulate.h +++ b/core/math/triangulate.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -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 6259bdead0..40149e8cc1 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -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); } @@ -79,7 +82,7 @@ real_t Vector2::angle_to(const Vector2 &p_vector2) const { } real_t Vector2::angle_to_point(const Vector2 &p_vector2) const { - return (*this - p_vector2).angle(); + return (p_vector2 - *this).angle(); } real_t Vector2::dot(const Vector2 &p_other) const { @@ -91,7 +94,7 @@ real_t Vector2::cross(const Vector2 &p_other) const { } Vector2 Vector2::sign() const { - return Vector2(SGN(x), SGN(y)); + return Vector2(SIGN(x), SIGN(y)); } Vector2 Vector2::floor() const { @@ -202,83 +205,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)); -} - -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 332c0475fa..92ac5257b0 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -32,11 +32,11 @@ #define VECTOR2_H #include "core/math/math_funcs.h" -#include "core/string/ustring.h" +class String; struct Vector2i; -struct Vector2 { +struct _NO_DISCARD_ Vector2 { static const int AXIS_COUNT = 2; enum Axis { @@ -60,22 +60,22 @@ struct 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) { x = y = p_value; } - _FORCE_INLINE_ int min_axis() const { - return x < y ? 0 : 1; + _FORCE_INLINE_ Vector2::Axis min_axis_index() const { + return x < y ? Vector2::AXIS_X : Vector2::AXIS_Y; } - _FORCE_INLINE_ int max_axis() const { - return x < y ? 1 : 0; + _FORCE_INLINE_ Vector2::Axis max_axis_index() const { + return x < y ? Vector2::AXIS_Y : Vector2::AXIS_X; } void normalize(); @@ -167,6 +167,7 @@ struct 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); } @@ -261,11 +246,16 @@ 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 { -#ifdef MATH_CHECKS - ERR_FAIL_COND_V_MSG(!is_normalized(), Vector2(), "The start Vector2 must be normalized."); -#endif - real_t theta = angle_to(p_to); - return rotated(theta * p_weight); + 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)) { + // 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); + } + real_t start_length = Math::sqrt(start_length_sq); + real_t result_length = Math::lerp(start_length, Math::sqrt(end_length_sq), p_weight); + real_t angle = angle_to(p_to); + return rotated(angle * p_weight) * (result_length / start_length); } Vector2 Vector2::direction_to(const Vector2 &p_to) const { @@ -274,113 +264,26 @@ Vector2 Vector2::direction_to(const Vector2 &p_to) const { return ret; } -typedef Vector2 Size2; -typedef Vector2 Point2; - -/* INTEGER STUFF */ - -struct 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_ 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)); - } - - 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; - - real_t aspect() const { return width / (real_t)height; } - Vector2i sign() const { return Vector2i(SGN(x), SGN(y)); } - Vector2i abs() const { return Vector2i(ABS(x), ABS(y)); } - Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const; - - operator String() const; +// Multiplication operators required to workaround issues with LLVM using implicit conversion +// to Vector2i instead for integers where it should not. - operator Vector2() const { return Vector2(x, y); } - - 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 42e3da0b27..b6965b3c32 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -108,10 +108,10 @@ Vector3 Vector3::move_toward(const Vector3 &p_to, const real_t p_delta) const { return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta; } -Basis Vector3::outer(const Vector3 &p_b) const { - Vector3 row0(x * p_b.x, x * p_b.y, x * p_b.z); - Vector3 row1(y * p_b.x, y * p_b.y, y * p_b.z); - Vector3 row2(z * p_b.x, z * p_b.y, z * p_b.z); +Basis Vector3::outer(const Vector3 &p_with) const { + Vector3 row0(x * p_with.x, x * p_with.y, x * p_with.z); + Vector3 row1(y * p_with.x, y * p_with.y, y * p_with.z); + Vector3 row2(z * p_with.x, z * p_with.y, z * p_with.z); return Basis(row0, row1, row2); } diff --git a/core/math/vector3.h b/core/math/vector3.h index dc9aa60458..345329f7f3 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -35,9 +35,10 @@ #include "core/math/vector2.h" #include "core/math/vector3i.h" #include "core/string/ustring.h" -class Basis; -struct Vector3 { +struct Basis; + +struct _NO_DISCARD_ Vector3 { static const int AXIS_COUNT = 3; enum Axis { @@ -71,12 +72,12 @@ struct Vector3 { x = y = z = p_value; } - _FORCE_INLINE_ int min_axis() const { - return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2); + _FORCE_INLINE_ Vector3::Axis min_axis_index() const { + return x < y ? (x < z ? Vector3::AXIS_X : Vector3::AXIS_Z) : (y < z ? Vector3::AXIS_Y : Vector3::AXIS_Z); } - _FORCE_INLINE_ int max_axis() const { - return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0); + _FORCE_INLINE_ Vector3::Axis max_axis_index() const { + return x < y ? (y < z ? Vector3::AXIS_Z : Vector3::AXIS_Y) : (x < z ? Vector3::AXIS_Z : Vector3::AXIS_X); } _FORCE_INLINE_ real_t length() const; @@ -128,9 +129,9 @@ struct Vector3 { return n.normalized(); } - _FORCE_INLINE_ Vector3 cross(const Vector3 &p_b) const; - _FORCE_INLINE_ real_t dot(const Vector3 &p_b) const; - Basis outer(const Vector3 &p_b) const; + _FORCE_INLINE_ Vector3 cross(const Vector3 &p_with) const; + _FORCE_INLINE_ real_t dot(const Vector3 &p_with) const; + Basis outer(const Vector3 &p_with) const; _FORCE_INLINE_ Vector3 abs() const; _FORCE_INLINE_ Vector3 floor() const; @@ -199,17 +200,17 @@ struct Vector3 { } }; -Vector3 Vector3::cross(const Vector3 &p_b) const { +Vector3 Vector3::cross(const Vector3 &p_with) const { Vector3 ret( - (y * p_b.z) - (z * p_b.y), - (z * p_b.x) - (x * p_b.z), - (x * p_b.y) - (y * p_b.x)); + (y * p_with.z) - (z * p_with.y), + (z * p_with.x) - (x * p_with.z), + (x * p_with.y) - (y * p_with.x)); return ret; } -real_t Vector3::dot(const Vector3 &p_b) const { - return x * p_b.x + y * p_b.y + z * p_b.z; +real_t Vector3::dot(const Vector3 &p_with) const { + return x * p_with.x + y * p_with.y + z * p_with.z; } Vector3 Vector3::abs() const { @@ -217,7 +218,7 @@ Vector3 Vector3::abs() const { } Vector3 Vector3::sign() const { - return Vector3(SGN(x), SGN(y), SGN(z)); + return Vector3(SIGN(x), SIGN(y), SIGN(z)); } Vector3 Vector3::floor() const { @@ -240,8 +241,16 @@ 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 theta = angle_to(p_to); - return rotated(cross(p_to).normalized(), theta * p_weight); + 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)) { + // 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); + } + real_t start_length = Math::sqrt(start_length_sq); + real_t result_length = Math::lerp(start_length, Math::sqrt(end_length_sq), p_weight); + real_t angle = angle_to(p_to); + return rotated(cross(p_to).normalized(), angle * p_weight) * (result_length / start_length); } real_t Vector3::distance_to(const Vector3 &p_to) const { @@ -334,6 +343,9 @@ Vector3 &Vector3::operator*=(const real_t p_scalar) { return *this; } +// Multiplication operators required to workaround issues with LLVM using implicit conversion +// to Vector2i instead for integers where it should not. + _FORCE_INLINE_ Vector3 operator*(const float p_scalar, const Vector3 &p_vec) { return p_vec * p_scalar; } diff --git a/core/math/vector3i.cpp b/core/math/vector3i.cpp index d3a57af77c..ac79b3c7ea 100644 --- a/core/math/vector3i.cpp +++ b/core/math/vector3i.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -40,12 +40,12 @@ int32_t Vector3i::get_axis(const int p_axis) const { return operator[](p_axis); } -int Vector3i::min_axis() const { - return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2); +Vector3i::Axis Vector3i::min_axis_index() const { + return x < y ? (x < z ? Vector3i::AXIS_X : Vector3i::AXIS_Z) : (y < z ? Vector3i::AXIS_Y : Vector3i::AXIS_Z); } -int Vector3i::max_axis() const { - return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0); +Vector3i::Axis Vector3i::max_axis_index() const { + return x < y ? (y < z ? Vector3i::AXIS_Z : Vector3i::AXIS_Y) : (x < z ? Vector3i::AXIS_Z : Vector3i::AXIS_X); } Vector3i Vector3i::clamp(const Vector3i &p_min, const Vector3i &p_max) const { diff --git a/core/math/vector3i.h b/core/math/vector3i.h index 9308d09045..d166de80aa 100644 --- a/core/math/vector3i.h +++ b/core/math/vector3i.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -31,10 +31,11 @@ #ifndef VECTOR3I_H #define VECTOR3I_H +#include "core/math/math_funcs.h" #include "core/string/ustring.h" #include "core/typedefs.h" -struct Vector3i { +struct _NO_DISCARD_ Vector3i { enum Axis { AXIS_X, AXIS_Y, @@ -62,8 +63,11 @@ struct Vector3i { 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; + Vector3i::Axis min_axis_index() const; + Vector3i::Axis max_axis_index() const; + + _FORCE_INLINE_ int64_t length_squared() const; + _FORCE_INLINE_ double length() const; _FORCE_INLINE_ void zero(); @@ -110,12 +114,20 @@ struct Vector3i { } }; +int64_t Vector3i::length_squared() const { + return x * (int64_t)x + y * (int64_t)y + z * (int64_t)z; +} + +double Vector3i::length() const { + return Math::sqrt((double)length_squared()); +} + Vector3i Vector3i::abs() const { return Vector3i(ABS(x), ABS(y), ABS(z)); } Vector3i Vector3i::sign() const { - return Vector3i(SGN(x), SGN(y), SGN(z)); + return Vector3i(SIGN(x), SIGN(y), SIGN(z)); } /* Operators */ @@ -182,6 +194,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; } @@ -198,10 +216,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; |