summaryrefslogtreecommitdiff
path: root/core/math
diff options
context:
space:
mode:
Diffstat (limited to 'core/math')
-rw-r--r--core/math/aabb.h8
-rw-r--r--core/math/basis.h11
-rw-r--r--core/math/camera_matrix.cpp4
-rw-r--r--core/math/camera_matrix.h10
-rw-r--r--core/math/delaunay_2d.h1
-rw-r--r--core/math/dynamic_bvh.h6
-rw-r--r--core/math/expression.cpp36
-rw-r--r--core/math/face3.h6
-rw-r--r--core/math/geometry_2d.h4
-rw-r--r--core/math/plane.h5
-rw-r--r--core/math/quaternion.h3
-rw-r--r--core/math/rect2.cpp10
-rw-r--r--core/math/rect2.h218
-rw-r--r--core/math/rect2i.cpp42
-rw-r--r--core/math/rect2i.h245
-rw-r--r--core/math/transform_2d.cpp2
-rw-r--r--core/math/transform_2d.h7
-rw-r--r--core/math/transform_3d.h9
-rw-r--r--core/math/triangulate.h1
-rw-r--r--core/math/vector2.cpp92
-rw-r--r--core/math/vector2.h112
-rw-r--r--core/math/vector2i.cpp125
-rw-r--r--core/math/vector2i.h141
-rw-r--r--core/math/vector3.h3
24 files changed, 635 insertions, 466 deletions
diff --git a/core/math/aabb.h b/core/math/aabb.h
index 3d19410ddf..cb6f05e9ea 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -36,13 +36,13 @@
#include "core/math/vector3.h"
/**
- * AABB / AABB (Axis Aligned Bounding Box)
- * This is implemented by a point (position) and the box size
+ * AABB (Axis Aligned Bounding Box)
+ * This is implemented by a point (position) and the box size.
*/
+
class Variant;
-class _NO_DISCARD_ AABB {
-public:
+struct _NO_DISCARD_ AABB {
Vector3 position;
Vector3 size;
diff --git a/core/math/basis.h b/core/math/basis.h
index 802da82089..683f05150c 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -34,11 +34,7 @@
#include "core/math/quaternion.h"
#include "core/math/vector3.h"
-class _NO_DISCARD_ Basis {
-private:
- void _set_diagonal(const Vector3 &p_diag);
-
-public:
+struct _NO_DISCARD_ Basis {
Vector3 elements[3] = {
Vector3(1, 0, 0),
Vector3(0, 1, 0),
@@ -263,6 +259,10 @@ public:
}
_FORCE_INLINE_ Basis() {}
+
+private:
+ // Helper method.
+ void _set_diagonal(const Vector3 &p_diag);
};
_FORCE_INLINE_ void Basis::operator*=(const Basis &p_matrix) {
@@ -334,4 +334,5 @@ real_t Basis::determinant() const {
elements[1][0] * (elements[0][1] * elements[2][2] - elements[2][1] * elements[0][2]) +
elements[2][0] * (elements[0][1] * elements[1][2] - elements[1][1] * elements[0][2]);
}
+
#endif // BASIS_H
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index 2902ca59b9..f5d746ef0f 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -30,7 +30,11 @@
#include "camera_matrix.h"
+#include "core/math/aabb.h"
#include "core/math/math_funcs.h"
+#include "core/math/plane.h"
+#include "core/math/rect2.h"
+#include "core/math/transform_3d.h"
#include "core/string/print_string.h"
float CameraMatrix::determinant() const {
diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h
index da1aba7562..285d2ae384 100644
--- a/core/math/camera_matrix.h
+++ b/core/math/camera_matrix.h
@@ -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/delaunay_2d.h b/core/math/delaunay_2d.h
index 08f5df8472..c39997d6a9 100644
--- a/core/math/delaunay_2d.h
+++ b/core/math/delaunay_2d.h
@@ -32,6 +32,7 @@
#define DELAUNAY_2D_H
#include "core/math/rect2.h"
+#include "core/templates/vector.h"
class Delaunay2D {
public:
diff --git a/core/math/dynamic_bvh.h b/core/math/dynamic_bvh.h
index 3041cdf268..50ec2c2b30 100644
--- a/core/math/dynamic_bvh.h
+++ b/core/math/dynamic_bvh.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef DYNAMICBVH_H
-#define DYNAMICBVH_H
+#ifndef DYNAMIC_BVH_H
+#define DYNAMIC_BVH_H
#include "core/math/aabb.h"
#include "core/templates/list.h"
@@ -474,4 +474,4 @@ void DynamicBVH::ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResu
} while (depth > 0);
}
-#endif // DYNAMICBVH_H
+#endif // DYNAMIC_BVH_H
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index 87f8a95970..0ddac9744e 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -37,18 +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');
-}
-
-static bool _is_hex_digit(char32_t c) {
- return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
-}
-
-static bool _is_binary_digit(char32_t c) {
- return (c == '0' || c == '1');
-}
-
Error Expression::_get_token(Token &r_token) {
while (true) {
#define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++])
@@ -96,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;
@@ -105,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;
@@ -255,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';
@@ -336,7 +324,7 @@ 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;
@@ -360,7 +348,7 @@ Error Expression::_get_token(Token &r_token) {
while (true) {
switch (reading) {
case READING_INT: {
- if (_is_number(c)) {
+ if (is_digit(c)) {
if (is_first_char && c == '0') {
if (next_char == 'b') {
reading = READING_BIN;
@@ -380,7 +368,7 @@ Error Expression::_get_token(Token &r_token) {
} break;
case READING_BIN: {
- if (bin_beg && !_is_binary_digit(c)) {
+ if (bin_beg && !is_binary_digit(c)) {
reading = READING_DONE;
} else if (c == 'b') {
bin_beg = true;
@@ -388,7 +376,7 @@ Error Expression::_get_token(Token &r_token) {
} break;
case READING_HEX: {
- if (hex_beg && !_is_hex_digit(c)) {
+ if (hex_beg && !is_hex_digit(c)) {
reading = READING_DONE;
} else if (c == 'x') {
hex_beg = true;
@@ -396,7 +384,7 @@ Error Expression::_get_token(Token &r_token) {
} break;
case READING_DEC: {
- if (_is_number(c)) {
+ if (is_digit(c)) {
} else if (c == 'e') {
reading = READING_EXP;
@@ -406,7 +394,7 @@ 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) {
@@ -441,11 +429,11 @@ Error Expression::_get_token(Token &r_token) {
}
return OK;
- } else if ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_') {
+ } else if (is_ascii_char(cchar) || is_underscore(cchar)) {
String id;
bool first = true;
- while ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_' || (!first && _is_number(cchar))) {
+ while (is_ascii_char(cchar) || is_underscore(cchar) || (!first && is_digit(cchar))) {
id += String::chr(cchar);
cchar = GET_CHAR();
first = false;
diff --git a/core/math/face3.h b/core/math/face3.h
index 3dbbca09e0..8b123f078c 100644
--- a/core/math/face3.h
+++ b/core/math/face3.h
@@ -36,8 +36,7 @@
#include "core/math/transform_3d.h"
#include "core/math/vector3.h"
-class _NO_DISCARD_ Face3 {
-public:
+struct _NO_DISCARD_ Face3 {
enum Side {
SIDE_OVER,
SIDE_UNDER,
@@ -48,14 +47,11 @@ public:
Vector3 vertex[3];
/**
- *
* @param p_plane plane used to split the face
* @param p_res array of at least 3 faces, amount used in function return
* @param p_is_point_over array of at least 3 booleans, determining which face is over the plane, amount used in function return
- * @param _epsilon constant used for numerical error rounding, to add "thickness" to the plane (so coplanar points can happen)
* @return amount of faces generated by the split, either 0 (means no split possible), 2 or 3
*/
-
int split_by_plane(const Plane &p_plane, Face3 *p_res, bool *p_is_point_over) const;
Plane get_plane(ClockDirection p_dir = CLOCKWISE) const;
diff --git a/core/math/geometry_2d.h b/core/math/geometry_2d.h
index 7385dba438..a2881d5f60 100644
--- a/core/math/geometry_2d.h
+++ b/core/math/geometry_2d.h
@@ -32,7 +32,11 @@
#define GEOMETRY_2D_H
#include "core/math/delaunay_2d.h"
+#include "core/math/math_funcs.h"
#include "core/math/triangulate.h"
+#include "core/math/vector2.h"
+#include "core/math/vector2i.h"
+#include "core/math/vector3.h"
#include "core/math/vector3i.h"
#include "core/templates/vector.h"
diff --git a/core/math/plane.h b/core/math/plane.h
index 8cb6f62b3b..66c1741662 100644
--- a/core/math/plane.h
+++ b/core/math/plane.h
@@ -35,13 +35,12 @@
class Variant;
-class _NO_DISCARD_ Plane {
-public:
+struct _NO_DISCARD_ Plane {
Vector3 normal;
real_t d = 0;
void set_normal(const Vector3 &p_normal);
- _FORCE_INLINE_ Vector3 get_normal() const { return normal; }; ///Point is coplanar, CMP_EPSILON for precision
+ _FORCE_INLINE_ Vector3 get_normal() const { return normal; };
void normalize();
Plane normalized() const;
diff --git a/core/math/quaternion.h b/core/math/quaternion.h
index 2575d7d229..7874e4f428 100644
--- a/core/math/quaternion.h
+++ b/core/math/quaternion.h
@@ -36,8 +36,7 @@
#include "core/math/vector3.h"
#include "core/string/ustring.h"
-class _NO_DISCARD_ Quaternion {
-public:
+struct _NO_DISCARD_ Quaternion {
union {
struct {
real_t x;
diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp
index 9047c19434..d6e20bdc3c 100644
--- a/core/math/rect2.cpp
+++ b/core/math/rect2.cpp
@@ -28,7 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "core/math/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D
+#include "rect2.h"
+
+#include "core/math/rect2i.h"
+#include "core/math/transform_2d.h"
+#include "core/string/ustring.h"
bool Rect2::is_equal_approx(const Rect2 &p_rect) const {
return position.is_equal_approx(p_rect.position) && size.is_equal_approx(p_rect.size);
@@ -278,6 +282,6 @@ Rect2::operator String() const {
return "[P: " + position.operator String() + ", S: " + size + "]";
}
-Rect2i::operator String() const {
- return "[P: " + position.operator String() + ", S: " + size + "]";
+Rect2::operator Rect2i() const {
+ return Rect2i(position, size);
}
diff --git a/core/math/rect2.h b/core/math/rect2.h
index b14c69302c..6ecc02336c 100644
--- a/core/math/rect2.h
+++ b/core/math/rect2.h
@@ -31,8 +31,11 @@
#ifndef RECT2_H
#define RECT2_H
-#include "core/math/vector2.h" // also includes math_funcs and ustring
+#include "core/error/error_macros.h"
+#include "core/math/vector2.h"
+class String;
+struct Rect2i;
struct Transform2D;
struct _NO_DISCARD_ Rect2 {
@@ -179,6 +182,7 @@ struct _NO_DISCARD_ Rect2 {
return new_rect;
}
+
inline bool has_point(const Point2 &p_point) const {
#ifdef MATH_CHECKS
if (unlikely(size.x < 0 || size.y < 0)) {
@@ -201,6 +205,7 @@ struct _NO_DISCARD_ Rect2 {
return true;
}
+
bool is_equal_approx(const Rect2 &p_rect) const;
bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; }
@@ -351,6 +356,7 @@ struct _NO_DISCARD_ Rect2 {
}
operator String() const;
+ operator Rect2i() const;
Rect2() {}
Rect2(real_t p_x, real_t p_y, real_t p_width, real_t p_height) :
@@ -363,214 +369,4 @@ struct _NO_DISCARD_ Rect2 {
}
};
-struct _NO_DISCARD_ Rect2i {
- Point2i position;
- Size2i size;
-
- const Point2i &get_position() const { return position; }
- void set_position(const Point2i &p_position) { position = p_position; }
- const Size2i &get_size() const { return size; }
- void set_size(const Size2i &p_size) { size = p_size; }
-
- int get_area() const { return size.width * size.height; }
-
- _FORCE_INLINE_ Vector2i get_center() const { return position + (size / 2); }
-
- inline bool intersects(const Rect2i &p_rect) const {
-#ifdef MATH_CHECKS
- if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
- ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
- }
-#endif
- if (position.x >= (p_rect.position.x + p_rect.size.width)) {
- return false;
- }
- if ((position.x + size.width) <= p_rect.position.x) {
- return false;
- }
- if (position.y >= (p_rect.position.y + p_rect.size.height)) {
- return false;
- }
- if ((position.y + size.height) <= p_rect.position.y) {
- return false;
- }
-
- return true;
- }
-
- inline bool encloses(const Rect2i &p_rect) const {
-#ifdef MATH_CHECKS
- if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
- ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
- }
-#endif
- return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) &&
- ((p_rect.position.x + p_rect.size.x) <= (position.x + size.x)) &&
- ((p_rect.position.y + p_rect.size.y) <= (position.y + size.y));
- }
-
- _FORCE_INLINE_ bool has_no_area() const {
- return (size.x <= 0 || size.y <= 0);
- }
-
- // Returns the instersection between two Rect2is or an empty Rect2i if there is no intersection
- inline Rect2i intersection(const Rect2i &p_rect) const {
- Rect2i new_rect = p_rect;
-
- if (!intersects(new_rect)) {
- return Rect2i();
- }
-
- new_rect.position.x = MAX(p_rect.position.x, position.x);
- new_rect.position.y = MAX(p_rect.position.y, position.y);
-
- Point2i p_rect_end = p_rect.position + p_rect.size;
- Point2i end = position + size;
-
- new_rect.size.x = MIN(p_rect_end.x, end.x) - new_rect.position.x;
- new_rect.size.y = MIN(p_rect_end.y, end.y) - new_rect.position.y;
-
- return new_rect;
- }
-
- inline Rect2i merge(const Rect2i &p_rect) const { ///< return a merged rect
-#ifdef MATH_CHECKS
- if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
- ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
- }
-#endif
- Rect2i new_rect;
-
- new_rect.position.x = MIN(p_rect.position.x, position.x);
- new_rect.position.y = MIN(p_rect.position.y, position.y);
-
- new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x, position.x + size.x);
- new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y, position.y + size.y);
-
- new_rect.size = new_rect.size - new_rect.position; //make relative again
-
- return new_rect;
- }
- bool has_point(const Point2i &p_point) const {
-#ifdef MATH_CHECKS
- if (unlikely(size.x < 0 || size.y < 0)) {
- ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
- }
-#endif
- if (p_point.x < position.x) {
- return false;
- }
- if (p_point.y < position.y) {
- return false;
- }
-
- if (p_point.x >= (position.x + size.x)) {
- return false;
- }
- if (p_point.y >= (position.y + size.y)) {
- return false;
- }
-
- return true;
- }
-
- bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; }
- bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; }
-
- Rect2i grow(int p_amount) const {
- Rect2i g = *this;
- g.position.x -= p_amount;
- g.position.y -= p_amount;
- g.size.width += p_amount * 2;
- g.size.height += p_amount * 2;
- return g;
- }
-
- inline Rect2i grow_side(Side p_side, int p_amount) const {
- Rect2i g = *this;
- g = g.grow_individual((SIDE_LEFT == p_side) ? p_amount : 0,
- (SIDE_TOP == p_side) ? p_amount : 0,
- (SIDE_RIGHT == p_side) ? p_amount : 0,
- (SIDE_BOTTOM == p_side) ? p_amount : 0);
- return g;
- }
-
- inline Rect2i grow_side_bind(uint32_t p_side, int p_amount) const {
- return grow_side(Side(p_side), p_amount);
- }
-
- inline Rect2i grow_individual(int p_left, int p_top, int p_right, int p_bottom) const {
- Rect2i g = *this;
- g.position.x -= p_left;
- g.position.y -= p_top;
- g.size.width += p_left + p_right;
- g.size.height += p_top + p_bottom;
-
- return g;
- }
-
- _FORCE_INLINE_ Rect2i expand(const Vector2i &p_vector) const {
- Rect2i r = *this;
- r.expand_to(p_vector);
- return r;
- }
-
- inline void expand_to(const Point2i &p_vector) {
-#ifdef MATH_CHECKS
- if (unlikely(size.x < 0 || size.y < 0)) {
- ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
- }
-#endif
- Point2i begin = position;
- Point2i end = position + size;
-
- if (p_vector.x < begin.x) {
- begin.x = p_vector.x;
- }
- if (p_vector.y < begin.y) {
- begin.y = p_vector.y;
- }
-
- if (p_vector.x > end.x) {
- end.x = p_vector.x;
- }
- if (p_vector.y > end.y) {
- end.y = p_vector.y;
- }
-
- position = begin;
- size = end - begin;
- }
-
- _FORCE_INLINE_ Rect2i abs() const {
- return Rect2i(Point2i(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs());
- }
-
- _FORCE_INLINE_ void set_end(const Vector2i &p_end) {
- size = p_end - position;
- }
-
- _FORCE_INLINE_ Vector2i get_end() const {
- return position + size;
- }
-
- operator String() const;
-
- operator Rect2() const { return Rect2(position, size); }
-
- Rect2i() {}
- Rect2i(const Rect2 &p_r2) :
- position(p_r2.position),
- size(p_r2.size) {
- }
- Rect2i(int p_x, int p_y, int p_width, int p_height) :
- position(Point2i(p_x, p_y)),
- size(Size2i(p_width, p_height)) {
- }
- Rect2i(const Point2i &p_pos, const Size2i &p_size) :
- position(p_pos),
- size(p_size) {
- }
-};
-
#endif // RECT2_H
diff --git a/core/math/rect2i.cpp b/core/math/rect2i.cpp
new file mode 100644
index 0000000000..0782c450d0
--- /dev/null
+++ b/core/math/rect2i.cpp
@@ -0,0 +1,42 @@
+/*************************************************************************/
+/* rect2i.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "rect2i.h"
+
+#include "core/math/rect2.h"
+#include "core/string/ustring.h"
+
+Rect2i::operator String() const {
+ return "[P: " + position.operator String() + ", S: " + size + "]";
+}
+
+Rect2i::operator Rect2() const {
+ return Rect2(position, size);
+}
diff --git a/core/math/rect2i.h b/core/math/rect2i.h
new file mode 100644
index 0000000000..db1459a3e6
--- /dev/null
+++ b/core/math/rect2i.h
@@ -0,0 +1,245 @@
+/*************************************************************************/
+/* rect2i.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef RECT2I_H
+#define RECT2I_H
+
+#include "core/error/error_macros.h"
+#include "core/math/vector2i.h"
+
+class String;
+struct Rect2;
+
+struct _NO_DISCARD_ Rect2i {
+ Point2i position;
+ Size2i size;
+
+ const Point2i &get_position() const { return position; }
+ void set_position(const Point2i &p_position) { position = p_position; }
+ const Size2i &get_size() const { return size; }
+ void set_size(const Size2i &p_size) { size = p_size; }
+
+ int get_area() const { return size.width * size.height; }
+
+ _FORCE_INLINE_ Vector2i get_center() const { return position + (size / 2); }
+
+ inline bool intersects(const Rect2i &p_rect) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
+ if (position.x >= (p_rect.position.x + p_rect.size.width)) {
+ return false;
+ }
+ if ((position.x + size.width) <= p_rect.position.x) {
+ return false;
+ }
+ if (position.y >= (p_rect.position.y + p_rect.size.height)) {
+ return false;
+ }
+ if ((position.y + size.height) <= p_rect.position.y) {
+ return false;
+ }
+
+ return true;
+ }
+
+ inline bool encloses(const Rect2i &p_rect) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
+ return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) &&
+ ((p_rect.position.x + p_rect.size.x) <= (position.x + size.x)) &&
+ ((p_rect.position.y + p_rect.size.y) <= (position.y + size.y));
+ }
+
+ _FORCE_INLINE_ bool has_no_area() const {
+ return (size.x <= 0 || size.y <= 0);
+ }
+
+ // Returns the instersection between two Rect2is or an empty Rect2i if there is no intersection
+ inline Rect2i intersection(const Rect2i &p_rect) const {
+ Rect2i new_rect = p_rect;
+
+ if (!intersects(new_rect)) {
+ return Rect2i();
+ }
+
+ new_rect.position.x = MAX(p_rect.position.x, position.x);
+ new_rect.position.y = MAX(p_rect.position.y, position.y);
+
+ Point2i p_rect_end = p_rect.position + p_rect.size;
+ Point2i end = position + size;
+
+ new_rect.size.x = MIN(p_rect_end.x, end.x) - new_rect.position.x;
+ new_rect.size.y = MIN(p_rect_end.y, end.y) - new_rect.position.y;
+
+ return new_rect;
+ }
+
+ inline Rect2i merge(const Rect2i &p_rect) const { ///< return a merged rect
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
+ Rect2i new_rect;
+
+ new_rect.position.x = MIN(p_rect.position.x, position.x);
+ new_rect.position.y = MIN(p_rect.position.y, position.y);
+
+ new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x, position.x + size.x);
+ new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y, position.y + size.y);
+
+ new_rect.size = new_rect.size - new_rect.position; //make relative again
+
+ return new_rect;
+ }
+ bool has_point(const Point2i &p_point) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
+ if (p_point.x < position.x) {
+ return false;
+ }
+ if (p_point.y < position.y) {
+ return false;
+ }
+
+ if (p_point.x >= (position.x + size.x)) {
+ return false;
+ }
+ if (p_point.y >= (position.y + size.y)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; }
+ bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; }
+
+ Rect2i grow(int p_amount) const {
+ Rect2i g = *this;
+ g.position.x -= p_amount;
+ g.position.y -= p_amount;
+ g.size.width += p_amount * 2;
+ g.size.height += p_amount * 2;
+ return g;
+ }
+
+ inline Rect2i grow_side(Side p_side, int p_amount) const {
+ Rect2i g = *this;
+ g = g.grow_individual((SIDE_LEFT == p_side) ? p_amount : 0,
+ (SIDE_TOP == p_side) ? p_amount : 0,
+ (SIDE_RIGHT == p_side) ? p_amount : 0,
+ (SIDE_BOTTOM == p_side) ? p_amount : 0);
+ return g;
+ }
+
+ inline Rect2i grow_side_bind(uint32_t p_side, int p_amount) const {
+ return grow_side(Side(p_side), p_amount);
+ }
+
+ inline Rect2i grow_individual(int p_left, int p_top, int p_right, int p_bottom) const {
+ Rect2i g = *this;
+ g.position.x -= p_left;
+ g.position.y -= p_top;
+ g.size.width += p_left + p_right;
+ g.size.height += p_top + p_bottom;
+
+ return g;
+ }
+
+ _FORCE_INLINE_ Rect2i expand(const Vector2i &p_vector) const {
+ Rect2i r = *this;
+ r.expand_to(p_vector);
+ return r;
+ }
+
+ inline void expand_to(const Point2i &p_vector) {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
+ Point2i begin = position;
+ Point2i end = position + size;
+
+ if (p_vector.x < begin.x) {
+ begin.x = p_vector.x;
+ }
+ if (p_vector.y < begin.y) {
+ begin.y = p_vector.y;
+ }
+
+ if (p_vector.x > end.x) {
+ end.x = p_vector.x;
+ }
+ if (p_vector.y > end.y) {
+ end.y = p_vector.y;
+ }
+
+ position = begin;
+ size = end - begin;
+ }
+
+ _FORCE_INLINE_ Rect2i abs() const {
+ return Rect2i(Point2i(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs());
+ }
+
+ _FORCE_INLINE_ void set_end(const Vector2i &p_end) {
+ size = p_end - position;
+ }
+
+ _FORCE_INLINE_ Vector2i get_end() const {
+ return position + size;
+ }
+
+ operator String() const;
+ operator Rect2() const;
+
+ Rect2i() {}
+ Rect2i(int p_x, int p_y, int p_width, int p_height) :
+ position(Point2i(p_x, p_y)),
+ size(Size2i(p_width, p_height)) {
+ }
+ Rect2i(const Point2i &p_pos, const Size2i &p_size) :
+ position(p_pos),
+ size(p_size) {
+ }
+};
+
+#endif // RECT2I_H
diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp
index 0201cf575c..e6e24e9b32 100644
--- a/core/math/transform_2d.cpp
+++ b/core/math/transform_2d.cpp
@@ -30,6 +30,8 @@
#include "transform_2d.h"
+#include "core/string/ustring.h"
+
void Transform2D::invert() {
// FIXME: this function assumes the basis is a rotation matrix, with no scaling.
// Transform2D::affine_inverse can handle matrices with scaling, so GDScript should eventually use that.
diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h
index 6c2d51bd9b..f4546c13c8 100644
--- a/core/math/transform_2d.h
+++ b/core/math/transform_2d.h
@@ -31,7 +31,12 @@
#ifndef TRANSFORM_2D_H
#define TRANSFORM_2D_H
-#include "core/math/rect2.h" // also includes vector2, math_funcs, and ustring
+#include "core/math/math_funcs.h"
+#include "core/math/rect2.h"
+#include "core/math/vector2.h"
+#include "core/templates/vector.h"
+
+class String;
struct _NO_DISCARD_ Transform2D {
// Warning #1: basis of Transform2D is stored differently from Basis. In terms of elements array, the basis matrix looks like "on paper":
diff --git a/core/math/transform_3d.h b/core/math/transform_3d.h
index c16c278e74..3b4762e221 100644
--- a/core/math/transform_3d.h
+++ b/core/math/transform_3d.h
@@ -28,15 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef TRANSFORM_H
-#define TRANSFORM_H
+#ifndef TRANSFORM_3D_H
+#define TRANSFORM_3D_H
#include "core/math/aabb.h"
#include "core/math/basis.h"
#include "core/math/plane.h"
-class _NO_DISCARD_ Transform3D {
-public:
+struct _NO_DISCARD_ Transform3D {
Basis basis;
Vector3 origin;
@@ -265,4 +264,4 @@ _FORCE_INLINE_ Plane Transform3D::xform_inv_fast(const Plane &p_plane, const Tra
return Plane(normal, d);
}
-#endif // TRANSFORM_H
+#endif // TRANSFORM_3D_H
diff --git a/core/math/triangulate.h b/core/math/triangulate.h
index d96bdb8cab..0bfcfcb978 100644
--- a/core/math/triangulate.h
+++ b/core/math/triangulate.h
@@ -32,6 +32,7 @@
#define TRIANGULATE_H
#include "core/math/vector2.h"
+#include "core/templates/vector.h"
/*
https://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml
diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp
index 676a0004ea..40149e8cc1 100644
--- a/core/math/vector2.cpp
+++ b/core/math/vector2.cpp
@@ -30,6 +30,9 @@
#include "vector2.h"
+#include "core/math/vector2i.h"
+#include "core/string/ustring.h"
+
real_t Vector2::angle() const {
return Math::atan2(y, x);
}
@@ -202,91 +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));
-}
-
-int64_t Vector2i::length_squared() const {
- return x * (int64_t)x + y * (int64_t)y;
-}
-
-double Vector2i::length() const {
- return Math::sqrt((double)length_squared());
-}
-
-Vector2i Vector2i::operator+(const Vector2i &p_v) const {
- return Vector2i(x + p_v.x, y + p_v.y);
-}
-
-void Vector2i::operator+=(const Vector2i &p_v) {
- x += p_v.x;
- y += p_v.y;
-}
-
-Vector2i Vector2i::operator-(const Vector2i &p_v) const {
- return Vector2i(x - p_v.x, y - p_v.y);
-}
-
-void Vector2i::operator-=(const Vector2i &p_v) {
- x -= p_v.x;
- y -= p_v.y;
-}
-
-Vector2i Vector2i::operator*(const Vector2i &p_v1) const {
- return Vector2i(x * p_v1.x, y * p_v1.y);
-}
-
-Vector2i Vector2i::operator*(const int32_t &rvalue) const {
- return Vector2i(x * rvalue, y * rvalue);
-}
-
-void Vector2i::operator*=(const int32_t &rvalue) {
- x *= rvalue;
- y *= rvalue;
-}
-
-Vector2i Vector2i::operator/(const Vector2i &p_v1) const {
- return Vector2i(x / p_v1.x, y / p_v1.y);
-}
-
-Vector2i Vector2i::operator/(const int32_t &rvalue) const {
- return Vector2i(x / rvalue, y / rvalue);
-}
-
-void Vector2i::operator/=(const int32_t &rvalue) {
- x /= rvalue;
- y /= rvalue;
-}
-
-Vector2i Vector2i::operator%(const Vector2i &p_v1) const {
- return Vector2i(x % p_v1.x, y % p_v1.y);
-}
-
-Vector2i Vector2i::operator%(const int32_t &rvalue) const {
- return Vector2i(x % rvalue, y % rvalue);
-}
-
-void Vector2i::operator%=(const int32_t &rvalue) {
- x %= rvalue;
- y %= rvalue;
-}
-
-Vector2i Vector2i::operator-() const {
- return Vector2i(-x, -y);
-}
-
-bool Vector2i::operator==(const Vector2i &p_vec2) const {
- return x == p_vec2.x && y == p_vec2.y;
-}
-
-bool Vector2i::operator!=(const Vector2i &p_vec2) const {
- return x != p_vec2.x || y != p_vec2.y;
-}
-
-Vector2i::operator String() const {
- return "(" + itos(x) + ", " + itos(y) + ")";
+Vector2::operator Vector2i() const {
+ return Vector2i(x, y);
}
diff --git a/core/math/vector2.h b/core/math/vector2.h
index af40b9e68d..9edaaebf89 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -32,8 +32,8 @@
#define VECTOR2_H
#include "core/math/math_funcs.h"
-#include "core/string/ustring.h"
+class String;
struct Vector2i;
struct _NO_DISCARD_ Vector2 {
@@ -167,6 +167,7 @@ struct _NO_DISCARD_ Vector2 {
real_t aspect() const { return width / height; }
operator String() const;
+ operator Vector2i() const;
_FORCE_INLINE_ Vector2() {}
_FORCE_INLINE_ Vector2(const real_t p_x, const real_t p_y) {
@@ -282,113 +283,4 @@ Vector2 Vector2::direction_to(const Vector2 &p_to) const {
typedef Vector2 Size2;
typedef Vector2 Point2;
-/* INTEGER STUFF */
-
-struct _NO_DISCARD_ Vector2i {
- enum Axis {
- AXIS_X,
- AXIS_Y,
- };
-
- union {
- int32_t x = 0;
- int32_t width;
- };
- union {
- int32_t y = 0;
- int32_t height;
- };
-
- _FORCE_INLINE_ int32_t &operator[](int p_idx) {
- return p_idx ? y : x;
- }
- _FORCE_INLINE_ const int32_t &operator[](int p_idx) const {
- return p_idx ? y : x;
- }
-
- _FORCE_INLINE_ Vector2i::Axis min_axis_index() const {
- return x < y ? Vector2i::AXIS_X : Vector2i::AXIS_Y;
- }
-
- _FORCE_INLINE_ Vector2i::Axis max_axis_index() const {
- return x < y ? Vector2i::AXIS_Y : Vector2i::AXIS_X;
- }
-
- Vector2i min(const Vector2i &p_vector2i) const {
- return Vector2(MIN(x, p_vector2i.x), MIN(y, p_vector2i.y));
- }
-
- Vector2i max(const Vector2i &p_vector2i) const {
- return Vector2(MAX(x, p_vector2i.x), MAX(y, p_vector2i.y));
- }
-
- Vector2i operator+(const Vector2i &p_v) const;
- void operator+=(const Vector2i &p_v);
- Vector2i operator-(const Vector2i &p_v) const;
- void operator-=(const Vector2i &p_v);
- Vector2i operator*(const Vector2i &p_v1) const;
-
- Vector2i operator*(const int32_t &rvalue) const;
- void operator*=(const int32_t &rvalue);
-
- Vector2i operator/(const Vector2i &p_v1) const;
- Vector2i operator/(const int32_t &rvalue) const;
- void operator/=(const int32_t &rvalue);
-
- Vector2i operator%(const Vector2i &p_v1) const;
- Vector2i operator%(const int32_t &rvalue) const;
- void operator%=(const int32_t &rvalue);
-
- Vector2i operator-() const;
- bool operator<(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); }
- bool operator>(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); }
-
- bool operator<=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); }
- bool operator>=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); }
-
- bool operator==(const Vector2i &p_vec2) const;
- bool operator!=(const Vector2i &p_vec2) const;
-
- int64_t length_squared() const;
- double length() const;
-
- real_t aspect() const { return width / (real_t)height; }
- Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); }
- Vector2i abs() const { return Vector2i(ABS(x), ABS(y)); }
- Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const;
-
- operator String() const;
-
- operator Vector2() const { return Vector2(x, y); }
-
- 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_ 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 // 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..446e05f5dd
--- /dev/null
+++ b/core/math/vector2i.h
@@ -0,0 +1,141 @@
+/*************************************************************************/
+/* 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 {
+ int32_t x = 0;
+ int32_t width;
+ };
+ union {
+ int32_t y = 0;
+ int32_t height;
+ };
+
+ _FORCE_INLINE_ int32_t &operator[](int p_idx) {
+ return p_idx ? y : x;
+ }
+ _FORCE_INLINE_ const int32_t &operator[](int p_idx) const {
+ return p_idx ? y : x;
+ }
+
+ _FORCE_INLINE_ Vector2i::Axis min_axis_index() const {
+ return x < y ? Vector2i::AXIS_X : Vector2i::AXIS_Y;
+ }
+
+ _FORCE_INLINE_ Vector2i::Axis max_axis_index() const {
+ return x < y ? Vector2i::AXIS_Y : Vector2i::AXIS_X;
+ }
+
+ Vector2i min(const Vector2i &p_vector2i) const {
+ return 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;
+ }
+};
+
+_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.h b/core/math/vector3.h
index b62edef40f..79ba5c4f15 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -35,7 +35,8 @@
#include "core/math/vector2.h"
#include "core/math/vector3i.h"
#include "core/string/ustring.h"
-class Basis;
+
+struct Basis;
struct _NO_DISCARD_ Vector3 {
static const int AXIS_COUNT = 3;