summaryrefslogtreecommitdiff
path: root/core/math
diff options
context:
space:
mode:
Diffstat (limited to 'core/math')
-rw-r--r--core/math/a_star.cpp2
-rw-r--r--core/math/a_star.h20
-rw-r--r--core/math/aabb.cpp18
-rw-r--r--core/math/aabb.h16
-rw-r--r--core/math/audio_frame.h2
-rw-r--r--core/math/basis.cpp23
-rw-r--r--core/math/basis.h23
-rw-r--r--core/math/camera_matrix.cpp7
-rw-r--r--core/math/camera_matrix.h2
-rw-r--r--core/math/color.cpp587
-rw-r--r--core/math/color.h263
-rw-r--r--core/math/color_names.inc160
-rw-r--r--core/math/delaunay_3d.h10
-rw-r--r--core/math/disjoint_set.h4
-rw-r--r--core/math/expression.cpp765
-rw-r--r--core/math/expression.h108
-rw-r--r--core/math/geometry_2d.h4
-rw-r--r--core/math/geometry_3d.cpp6
-rw-r--r--core/math/geometry_3d.h52
-rw-r--r--core/math/math_defs.h5
-rw-r--r--core/math/math_fieldwise.cpp10
-rw-r--r--core/math/math_fieldwise.h2
-rw-r--r--core/math/math_funcs.cpp8
-rw-r--r--core/math/math_funcs.h33
-rw-r--r--core/math/octree.h9
-rw-r--r--core/math/plane.cpp30
-rw-r--r--core/math/plane.h8
-rw-r--r--core/math/quat.cpp2
-rw-r--r--core/math/quat.h30
-rw-r--r--core/math/quick_hull.cpp2
-rw-r--r--core/math/quick_hull.h14
-rw-r--r--core/math/random_number_generator.cpp5
-rw-r--r--core/math/random_number_generator.h19
-rw-r--r--core/math/random_pcg.cpp15
-rw-r--r--core/math/random_pcg.h11
-rw-r--r--core/math/rect2.h99
-rw-r--r--core/math/transform.cpp9
-rw-r--r--core/math/transform.h5
-rw-r--r--core/math/transform_2d.cpp2
-rw-r--r--core/math/transform_2d.h6
-rw-r--r--core/math/triangle_mesh.cpp2
-rw-r--r--core/math/triangle_mesh.h2
-rw-r--r--core/math/vector2.cpp13
-rw-r--r--core/math/vector2.h54
-rw-r--r--core/math/vector3.h18
-rw-r--r--core/math/vector3i.h28
46 files changed, 1460 insertions, 1053 deletions
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index 30f712b2c3..b4410acf7d 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -31,7 +31,7 @@
#include "a_star.h"
#include "core/math/geometry_3d.h"
-#include "core/script_language.h"
+#include "core/object/script_language.h"
#include "scene/scene_string_names.h"
int AStar::get_available_point_id() const {
diff --git a/core/math/a_star.h b/core/math/a_star.h
index ba1c3033b8..7cfa73f2c2 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -31,8 +31,8 @@
#ifndef A_STAR_H
#define A_STAR_H
-#include "core/oa_hash_map.h"
-#include "core/reference.h"
+#include "core/object/reference.h"
+#include "core/templates/oa_hash_map.h"
/**
A* pathfinding algorithm
@@ -47,20 +47,20 @@ class AStar : public Reference {
struct Point {
Point() {}
- int id;
+ int id = 0;
Vector3 pos;
- real_t weight_scale;
- bool enabled;
+ real_t weight_scale = 0;
+ bool enabled = false;
OAHashMap<int, Point *> neighbours = 4u;
OAHashMap<int, Point *> unlinked_neighbours = 4u;
// Used for pathfinding.
- Point *prev_point;
- real_t g_score;
- real_t f_score;
- uint64_t open_pass;
- uint64_t closed_pass;
+ Point *prev_point = nullptr;
+ real_t g_score = 0;
+ real_t f_score = 0;
+ uint64_t open_pass = 0;
+ uint64_t closed_pass = 0;
};
struct SortPoints {
diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp
index f5c667dab0..08673d0dd1 100644
--- a/core/math/aabb.cpp
+++ b/core/math/aabb.cpp
@@ -30,7 +30,8 @@
#include "aabb.h"
-#include "core/print_string.h"
+#include "core/string/print_string.h"
+#include "core/variant/variant.h"
real_t AABB::get_area() const {
return size.x * size.y * size.z;
@@ -375,6 +376,21 @@ void AABB::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const {
}
}
+Variant AABB::intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const {
+ Vector3 inters;
+ if (intersects_segment(p_from, p_to, &inters)) {
+ return inters;
+ }
+ return Variant();
+}
+Variant AABB::intersects_ray_bind(const Vector3 &p_from, const Vector3 &p_dir) const {
+ Vector3 inters;
+ if (intersects_ray(p_from, p_dir, &inters)) {
+ return inters;
+ }
+ return Variant();
+}
+
AABB::operator String() const {
return String() + position + " - " + size;
}
diff --git a/core/math/aabb.h b/core/math/aabb.h
index 4106fbb93c..45dcbc7f7f 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -39,6 +39,7 @@
* AABB / AABB (Axis Aligned Bounding Box)
* This is implemented by a point (position) and the box size
*/
+class Variant;
class AABB {
public:
@@ -99,6 +100,21 @@ public:
_FORCE_INLINE_ void project_range_in_plane(const Plane &p_plane, real_t &r_min, real_t &r_max) const;
_FORCE_INLINE_ void expand_to(const Vector3 &p_vector); /** expand to contain a point if necessary */
+ _FORCE_INLINE_ AABB abs() const {
+ return AABB(Vector3(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0), position.z + MIN(size.z, 0)), size.abs());
+ }
+
+ Variant intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const;
+ Variant intersects_ray_bind(const Vector3 &p_from, const Vector3 &p_dir) const;
+
+ _FORCE_INLINE_ void set_end(const Vector3 &p_end) {
+ size = p_end - position;
+ }
+
+ _FORCE_INLINE_ Vector3 get_end() const {
+ return position + size;
+ }
+
operator String() const;
_FORCE_INLINE_ AABB() {}
diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h
index 91f533eafb..43d4a63cd3 100644
--- a/core/math/audio_frame.h
+++ b/core/math/audio_frame.h
@@ -121,7 +121,7 @@ struct AudioFrame {
r = p_frame.r;
}
- _ALWAYS_INLINE_ AudioFrame operator=(const AudioFrame &p_frame) {
+ _ALWAYS_INLINE_ AudioFrame &operator=(const AudioFrame &p_frame) {
l = p_frame.l;
r = p_frame.r;
return *this;
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index dd38e25bb1..c6030d9757 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -32,7 +32,7 @@
#include "core/math/math_funcs.h"
#include "core/os/copymem.h"
-#include "core/print_string.h"
+#include "core/string/print_string.h"
#define cofac(row1, col1, row2, col2) \
(elements[row1][col1] * elements[row2][col2] - elements[row1][col2] * elements[row2][col1])
@@ -113,19 +113,22 @@ bool Basis::is_rotation() const {
return Math::is_equal_approx(determinant(), 1, UNIT_EPSILON) && is_orthogonal();
}
+#ifdef MATH_CHECKS
+// This method is only used once, in diagonalize. If it's desired elsewhere, feel free to remove the #ifdef.
bool Basis::is_symmetric() const {
- if (!Math::is_equal_approx_ratio(elements[0][1], elements[1][0], UNIT_EPSILON)) {
+ if (!Math::is_equal_approx(elements[0][1], elements[1][0])) {
return false;
}
- if (!Math::is_equal_approx_ratio(elements[0][2], elements[2][0], UNIT_EPSILON)) {
+ if (!Math::is_equal_approx(elements[0][2], elements[2][0])) {
return false;
}
- if (!Math::is_equal_approx_ratio(elements[1][2], elements[2][1], UNIT_EPSILON)) {
+ if (!Math::is_equal_approx(elements[1][2], elements[2][1])) {
return false;
}
return true;
}
+#endif
Basis Basis::diagonalize() {
//NOTE: only implemented for symmetric matrices
@@ -737,18 +740,6 @@ bool Basis::is_equal_approx(const Basis &p_basis) const {
return elements[0].is_equal_approx(p_basis.elements[0]) && elements[1].is_equal_approx(p_basis.elements[1]) && elements[2].is_equal_approx(p_basis.elements[2]);
}
-bool Basis::is_equal_approx_ratio(const Basis &a, const Basis &b, real_t p_epsilon) const {
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++) {
- if (!Math::is_equal_approx_ratio(a.elements[i][j], b.elements[i][j], p_epsilon)) {
- return false;
- }
- }
- }
-
- return true;
-}
-
bool Basis::operator==(const Basis &p_matrix) const {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
diff --git a/core/math/basis.h b/core/math/basis.h
index 985fb0e44f..2584f1ff48 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -36,7 +36,11 @@
class Basis {
public:
- Vector3 elements[3];
+ Vector3 elements[3] = {
+ Vector3(1, 0, 0),
+ Vector3(0, 1, 0),
+ Vector3(0, 0, 1)
+ };
_FORCE_INLINE_ const Vector3 &operator[](int axis) const {
return elements[axis];
@@ -142,9 +146,6 @@ public:
}
bool is_equal_approx(const Basis &p_basis) const;
- // TODO: Break compatibility in 4.0 by getting rid of this so that it's only an instance method. See also TODO in variant_call.cpp
- bool is_equal_approx(const Basis &a, const Basis &b) const { return a.is_equal_approx(b); }
- bool is_equal_approx_ratio(const Basis &a, const Basis &b, real_t p_epsilon = UNIT_EPSILON) const;
bool operator==(const Basis &p_matrix) const;
bool operator!=(const Basis &p_matrix) const;
@@ -234,7 +235,9 @@ public:
void orthonormalize();
Basis orthonormalized() const;
+#ifdef MATH_CHECKS
bool is_symmetric() const;
+#endif
Basis diagonalize();
operator Quat() const { return get_quat(); }
@@ -254,17 +257,7 @@ public:
elements[2] = row2;
}
- _FORCE_INLINE_ Basis() {
- elements[0][0] = 1;
- elements[0][1] = 0;
- elements[0][2] = 0;
- elements[1][0] = 0;
- elements[1][1] = 1;
- elements[1][2] = 0;
- elements[2][0] = 0;
- elements[2][1] = 0;
- elements[2][2] = 1;
- }
+ _FORCE_INLINE_ Basis() {}
};
_FORCE_INLINE_ void Basis::operator*=(const Basis &p_matrix) {
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index 22ab83f358..5e5efb6356 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -31,7 +31,7 @@
#include "camera_matrix.h"
#include "core/math/math_funcs.h"
-#include "core/print_string.h"
+#include "core/string/print_string.h"
float CameraMatrix::determinant() const {
return matrix[0][3] * matrix[1][2] * matrix[2][1] * matrix[3][0] - matrix[0][2] * matrix[1][3] * matrix[2][1] * matrix[3][0] -
@@ -278,7 +278,7 @@ Vector2 CameraMatrix::get_viewport_half_extents() const {
return Vector2(res.x, res.y);
}
-void CameraMatrix::get_far_plane_size(real_t &r_width, real_t &r_height) const {
+Vector2 CameraMatrix::get_far_plane_half_extents() const {
const real_t *matrix = (const real_t *)this->matrix;
///////--- Far Plane ---///////
Plane far_plane = Plane(matrix[3] - matrix[2],
@@ -303,8 +303,7 @@ void CameraMatrix::get_far_plane_size(real_t &r_width, real_t &r_height) const {
Vector3 res;
far_plane.intersect_3(right_plane, top_plane, &res);
- r_width = res.x;
- r_height = res.y;
+ return Vector2(res.x, res.y);
}
bool CameraMatrix::get_endpoints(const Transform &p_transform, Vector3 *p_8points) const {
diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h
index 49fdecae02..c5cdd98377 100644
--- a/core/math/camera_matrix.h
+++ b/core/math/camera_matrix.h
@@ -74,7 +74,7 @@ struct CameraMatrix {
bool get_endpoints(const Transform &p_transform, Vector3 *p_8points) const;
Vector2 get_viewport_half_extents() const;
- void get_far_plane_size(real_t &r_width, real_t &r_height) const;
+ Vector2 get_far_plane_half_extents() const;
void invert();
CameraMatrix inverse() const;
diff --git a/core/math/color.cpp b/core/math/color.cpp
new file mode 100644
index 0000000000..2afe14bd63
--- /dev/null
+++ b/core/math/color.cpp
@@ -0,0 +1,587 @@
+/*************************************************************************/
+/* color.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 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 "color.h"
+
+#include "color_names.inc"
+#include "core/math/math_funcs.h"
+#include "core/string/print_string.h"
+#include "core/templates/map.h"
+
+uint32_t Color::to_argb32() const {
+ uint32_t c = (uint8_t)Math::round(a * 255);
+ c <<= 8;
+ c |= (uint8_t)Math::round(r * 255);
+ c <<= 8;
+ c |= (uint8_t)Math::round(g * 255);
+ c <<= 8;
+ c |= (uint8_t)Math::round(b * 255);
+
+ return c;
+}
+
+uint32_t Color::to_abgr32() const {
+ uint32_t c = (uint8_t)Math::round(a * 255);
+ c <<= 8;
+ c |= (uint8_t)Math::round(b * 255);
+ c <<= 8;
+ c |= (uint8_t)Math::round(g * 255);
+ c <<= 8;
+ c |= (uint8_t)Math::round(r * 255);
+
+ return c;
+}
+
+uint32_t Color::to_rgba32() const {
+ uint32_t c = (uint8_t)Math::round(r * 255);
+ c <<= 8;
+ c |= (uint8_t)Math::round(g * 255);
+ c <<= 8;
+ c |= (uint8_t)Math::round(b * 255);
+ c <<= 8;
+ c |= (uint8_t)Math::round(a * 255);
+
+ return c;
+}
+
+uint64_t Color::to_abgr64() const {
+ uint64_t c = (uint16_t)Math::round(a * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(b * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(g * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(r * 65535);
+
+ return c;
+}
+
+uint64_t Color::to_argb64() const {
+ uint64_t c = (uint16_t)Math::round(a * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(r * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(g * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(b * 65535);
+
+ return c;
+}
+
+uint64_t Color::to_rgba64() const {
+ uint64_t c = (uint16_t)Math::round(r * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(g * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(b * 65535);
+ c <<= 16;
+ c |= (uint16_t)Math::round(a * 65535);
+
+ return c;
+}
+
+float Color::get_h() const {
+ float min = MIN(r, g);
+ min = MIN(min, b);
+ float max = MAX(r, g);
+ max = MAX(max, b);
+
+ float delta = max - min;
+
+ if (delta == 0) {
+ return 0;
+ }
+
+ float h;
+ if (r == max) {
+ h = (g - b) / delta; // between yellow & magenta
+ } else if (g == max) {
+ h = 2 + (b - r) / delta; // between cyan & yellow
+ } else {
+ h = 4 + (r - g) / delta; // between magenta & cyan
+ }
+
+ h /= 6.0;
+ if (h < 0) {
+ h += 1.0;
+ }
+
+ return h;
+}
+
+float Color::get_s() const {
+ float min = MIN(r, g);
+ min = MIN(min, b);
+ float max = MAX(r, g);
+ max = MAX(max, b);
+
+ float delta = max - min;
+
+ return (max != 0) ? (delta / max) : 0;
+}
+
+float Color::get_v() const {
+ float max = MAX(r, g);
+ max = MAX(max, b);
+ return max;
+}
+
+void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
+ int i;
+ float f, p, q, t;
+ a = p_alpha;
+
+ if (p_s == 0) {
+ // Achromatic (grey)
+ r = g = b = p_v;
+ return;
+ }
+
+ p_h *= 6.0;
+ p_h = Math::fmod(p_h, 6);
+ i = Math::floor(p_h);
+
+ f = p_h - i;
+ p = p_v * (1 - p_s);
+ q = p_v * (1 - p_s * f);
+ t = p_v * (1 - p_s * (1 - f));
+
+ switch (i) {
+ case 0: // Red is the dominant color
+ r = p_v;
+ g = t;
+ b = p;
+ break;
+ case 1: // Green is the dominant color
+ r = q;
+ g = p_v;
+ b = p;
+ break;
+ case 2:
+ r = p;
+ g = p_v;
+ b = t;
+ break;
+ case 3: // Blue is the dominant color
+ r = p;
+ g = q;
+ b = p_v;
+ break;
+ case 4:
+ r = t;
+ g = p;
+ b = p_v;
+ break;
+ default: // (5) Red is the dominant color
+ r = p_v;
+ g = p;
+ b = q;
+ break;
+ }
+}
+
+bool Color::is_equal_approx(const Color &p_color) const {
+ return Math::is_equal_approx(r, p_color.r) && Math::is_equal_approx(g, p_color.g) && Math::is_equal_approx(b, p_color.b) && Math::is_equal_approx(a, p_color.a);
+}
+
+void Color::invert() {
+ r = 1.0 - r;
+ g = 1.0 - g;
+ b = 1.0 - b;
+}
+
+Color Color::hex(uint32_t p_hex) {
+ float a = (p_hex & 0xFF) / 255.0;
+ p_hex >>= 8;
+ float b = (p_hex & 0xFF) / 255.0;
+ p_hex >>= 8;
+ float g = (p_hex & 0xFF) / 255.0;
+ p_hex >>= 8;
+ float r = (p_hex & 0xFF) / 255.0;
+
+ return Color(r, g, b, a);
+}
+
+Color Color::hex64(uint64_t p_hex) {
+ float a = (p_hex & 0xFFFF) / 65535.0;
+ p_hex >>= 16;
+ float b = (p_hex & 0xFFFF) / 65535.0;
+ p_hex >>= 16;
+ float g = (p_hex & 0xFFFF) / 65535.0;
+ p_hex >>= 16;
+ float r = (p_hex & 0xFFFF) / 65535.0;
+
+ 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];
+
+ if (character >= '0' && character <= '9') {
+ return character - '0';
+ } else if (character >= 'a' && character <= 'f') {
+ return character + (10 - 'a');
+ } else if (character >= 'A' && character <= 'F') {
+ return character + (10 - 'A');
+ }
+ return -1;
+}
+
+static int _parse_col8(const String &p_str, int p_ofs) {
+ return _parse_col4(p_str, p_ofs) * 16 + _parse_col4(p_str, p_ofs + 1);
+}
+
+Color Color::inverted() const {
+ Color c = *this;
+ c.invert();
+ return c;
+}
+
+Color Color::html(const String &p_rgba) {
+ String color = p_rgba;
+ if (color.length() == 0) {
+ return Color();
+ }
+ if (color[0] == '#') {
+ color = color.substr(1);
+ }
+
+ // If enabled, use 1 hex digit per channel instead of 2.
+ // Other sizes aren't in the HTML/CSS spec but we could add them if desired.
+ bool is_shorthand = color.length() < 5;
+ bool alpha = false;
+
+ if (color.length() == 8) {
+ alpha = true;
+ } else if (color.length() == 6) {
+ alpha = false;
+ } else if (color.length() == 4) {
+ alpha = true;
+ } else if (color.length() == 3) {
+ alpha = false;
+ } else {
+ ERR_FAIL_V_MSG(Color(), "Invalid color code: " + p_rgba + ".");
+ }
+
+ float r, g, b, a = 1.0;
+ if (is_shorthand) {
+ r = _parse_col4(color, 0) / 15.0;
+ g = _parse_col4(color, 1) / 15.0;
+ b = _parse_col4(color, 2) / 15.0;
+ if (alpha) {
+ a = _parse_col4(color, 3) / 15.0;
+ }
+ } else {
+ r = _parse_col8(color, 0) / 255.0;
+ g = _parse_col8(color, 2) / 255.0;
+ b = _parse_col8(color, 4) / 255.0;
+ if (alpha) {
+ a = _parse_col8(color, 6) / 255.0;
+ }
+ }
+ ERR_FAIL_COND_V_MSG(r < 0, Color(), "Invalid color code: " + p_rgba + ".");
+ ERR_FAIL_COND_V_MSG(g < 0, Color(), "Invalid color code: " + p_rgba + ".");
+ ERR_FAIL_COND_V_MSG(b < 0, Color(), "Invalid color code: " + p_rgba + ".");
+ ERR_FAIL_COND_V_MSG(a < 0, Color(), "Invalid color code: " + p_rgba + ".");
+
+ return Color(r, g, b, a);
+}
+
+bool Color::html_is_valid(const String &p_color) {
+ String color = p_color;
+
+ if (color.length() == 0) {
+ return false;
+ }
+ if (color[0] == '#') {
+ color = color.substr(1);
+ }
+
+ // Check if the amount of hex digits is valid.
+ int len = color.length();
+ if (!(len == 3 || len == 4 || len == 6 || len == 8)) {
+ return false;
+ }
+
+ // Check if each hex digit is valid.
+ for (int i = 0; i < len; i++) {
+ if (_parse_col4(color, i) == -1) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+Color Color::named(const String &p_name) {
+ String name = p_name;
+ // Normalize name
+ name = name.replace(" ", "");
+ name = name.replace("-", "");
+ name = name.replace("_", "");
+ name = name.replace("'", "");
+ name = name.replace(".", "");
+ name = name.to_lower();
+
+ int idx = 0;
+ while (named_colors[idx].name != nullptr) {
+ if (name == named_colors[idx].name) {
+ return named_colors[idx].color;
+ }
+ idx++;
+ }
+
+ ERR_FAIL_V_MSG(Color(), "Invalid color name: " + p_name + ".");
+
+ return Color();
+}
+
+int Color::get_named_color_count() {
+ int idx = 0;
+ while (named_colors[idx].name != nullptr) {
+ idx++;
+ }
+ return idx;
+}
+String Color::get_named_color_name(int p_idx) {
+ return named_colors[p_idx].name;
+}
+Color Color::get_named_color(int p_idx) {
+ return named_colors[p_idx].color;
+}
+
+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;
+}
+
+Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const {
+ p_h = Math::fmod(p_h * 360.0f, 360.0f);
+ if (p_h < 0.0) {
+ p_h += 360.0f;
+ }
+
+ const float h_ = p_h / 60.0f;
+ const float c = p_v * p_s;
+ const float x = c * (1.0f - Math::abs(Math::fmod(h_, 2.0f) - 1.0f));
+ float r, g, b;
+
+ switch ((int)h_) {
+ case 0: {
+ r = c;
+ g = x;
+ b = 0;
+ } break;
+ case 1: {
+ r = x;
+ g = c;
+ b = 0;
+ } break;
+ case 2: {
+ r = 0;
+ g = c;
+ b = x;
+ } break;
+ case 3: {
+ r = 0;
+ g = x;
+ b = c;
+ } break;
+ case 4: {
+ r = x;
+ g = 0;
+ b = c;
+ } break;
+ case 5: {
+ r = c;
+ g = 0;
+ b = x;
+ } break;
+ default: {
+ r = 0;
+ g = 0;
+ b = 0;
+ } break;
+ }
+
+ const float m = p_v - c;
+ return Color(m + r, m + g, m + b, p_a);
+}
+
+Color::operator String() const {
+ return rtos(r) + ", " + rtos(g) + ", " + rtos(b) + ", " + rtos(a);
+}
+
+Color Color::operator+(const Color &p_color) const {
+ return Color(
+ r + p_color.r,
+ g + p_color.g,
+ b + p_color.b,
+ a + p_color.a);
+}
+
+void Color::operator+=(const Color &p_color) {
+ r = r + p_color.r;
+ g = g + p_color.g;
+ b = b + p_color.b;
+ a = a + p_color.a;
+}
+
+Color Color::operator-(const Color &p_color) const {
+ return Color(
+ r - p_color.r,
+ g - p_color.g,
+ b - p_color.b,
+ a - p_color.a);
+}
+
+void Color::operator-=(const Color &p_color) {
+ r = r - p_color.r;
+ g = g - p_color.g;
+ b = b - p_color.b;
+ a = a - p_color.a;
+}
+
+Color Color::operator*(const Color &p_color) const {
+ return Color(
+ r * p_color.r,
+ g * p_color.g,
+ b * p_color.b,
+ a * p_color.a);
+}
+
+Color Color::operator*(real_t p_rvalue) const {
+ return Color(
+ r * p_rvalue,
+ g * p_rvalue,
+ b * p_rvalue,
+ a * p_rvalue);
+}
+
+void Color::operator*=(const Color &p_color) {
+ r = r * p_color.r;
+ g = g * p_color.g;
+ b = b * p_color.b;
+ a = a * p_color.a;
+}
+
+void Color::operator*=(real_t p_rvalue) {
+ r = r * p_rvalue;
+ g = g * p_rvalue;
+ b = b * p_rvalue;
+ a = a * p_rvalue;
+}
+
+Color Color::operator/(const Color &p_color) const {
+ return Color(
+ r / p_color.r,
+ g / p_color.g,
+ b / p_color.b,
+ a / p_color.a);
+}
+
+Color Color::operator/(real_t p_rvalue) const {
+ return Color(
+ r / p_rvalue,
+ g / p_rvalue,
+ b / p_rvalue,
+ a / p_rvalue);
+}
+
+void Color::operator/=(const Color &p_color) {
+ r = r / p_color.r;
+ g = g / p_color.g;
+ b = b / p_color.b;
+ a = a / p_color.a;
+}
+
+void Color::operator/=(real_t p_rvalue) {
+ if (p_rvalue == 0) {
+ r = 1.0;
+ g = 1.0;
+ b = 1.0;
+ a = 1.0;
+ } else {
+ r = r / p_rvalue;
+ g = g / p_rvalue;
+ b = b / p_rvalue;
+ a = a / p_rvalue;
+ }
+}
+
+Color Color::operator-() const {
+ return Color(
+ 1.0 - r,
+ 1.0 - g,
+ 1.0 - b,
+ 1.0 - a);
+}
diff --git a/core/math/color.h b/core/math/color.h
new file mode 100644
index 0000000000..a9be9e9035
--- /dev/null
+++ b/core/math/color.h
@@ -0,0 +1,263 @@
+/*************************************************************************/
+/* color.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 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 COLOR_H
+#define COLOR_H
+
+#include "core/math/math_funcs.h"
+#include "core/string/ustring.h"
+
+struct Color {
+ union {
+ struct {
+ float r;
+ float g;
+ float b;
+ float a;
+ };
+ float components[4] = { 0, 0, 0, 1.0 };
+ };
+
+ uint32_t to_rgba32() const;
+ uint32_t to_argb32() const;
+ uint32_t to_abgr32() const;
+ uint64_t to_rgba64() const;
+ uint64_t to_argb64() const;
+ uint64_t to_abgr64() const;
+ float get_h() const;
+ float get_s() const;
+ float get_v() const;
+ void set_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0);
+
+ _FORCE_INLINE_ float &operator[](int p_idx) {
+ return components[p_idx];
+ }
+ _FORCE_INLINE_ const float &operator[](int p_idx) const {
+ return components[p_idx];
+ }
+
+ bool operator==(const Color &p_color) const {
+ return (r == p_color.r && g == p_color.g && b == p_color.b && a == p_color.a);
+ }
+ bool operator!=(const Color &p_color) const {
+ return (r != p_color.r || g != p_color.g || b != p_color.b || a != p_color.a);
+ }
+
+ Color operator+(const Color &p_color) const;
+ void operator+=(const Color &p_color);
+
+ Color operator-() const;
+ Color operator-(const Color &p_color) const;
+ void operator-=(const Color &p_color);
+
+ Color operator*(const Color &p_color) const;
+ Color operator*(real_t p_rvalue) const;
+ void operator*=(const Color &p_color);
+ void operator*=(real_t p_rvalue);
+
+ Color operator/(const Color &p_color) const;
+ Color operator/(real_t p_rvalue) const;
+ void operator/=(const Color &p_color);
+ void operator/=(real_t p_rvalue);
+
+ bool is_equal_approx(const Color &p_color) const;
+
+ void invert();
+ Color inverted() const;
+
+ _FORCE_INLINE_ Color lerp(const Color &p_b, float p_t) const {
+ Color res = *this;
+
+ res.r += (p_t * (p_b.r - r));
+ res.g += (p_t * (p_b.g - g));
+ res.b += (p_t * (p_b.b - b));
+ res.a += (p_t * (p_b.a - a));
+
+ return res;
+ }
+
+ _FORCE_INLINE_ Color darkened(float p_amount) const {
+ Color res = *this;
+ res.r = res.r * (1.0f - p_amount);
+ res.g = res.g * (1.0f - p_amount);
+ res.b = res.b * (1.0f - p_amount);
+ return res;
+ }
+
+ _FORCE_INLINE_ Color lightened(float p_amount) const {
+ Color res = *this;
+ res.r = res.r + (1.0f - res.r) * p_amount;
+ res.g = res.g + (1.0f - res.g) * p_amount;
+ res.b = res.b + (1.0f - res.b) * p_amount;
+ return res;
+ }
+
+ _FORCE_INLINE_ uint32_t to_rgbe9995() const {
+ const float pow2to9 = 512.0f;
+ const float B = 15.0f;
+ const float N = 9.0f;
+
+ float sharedexp = 65408.000f; // Result of: ((pow2to9 - 1.0f) / pow2to9) * powf(2.0f, 31.0f - 15.0f)
+
+ float cRed = MAX(0.0f, MIN(sharedexp, r));
+ float cGreen = MAX(0.0f, MIN(sharedexp, g));
+ float cBlue = MAX(0.0f, MIN(sharedexp, b));
+
+ float cMax = MAX(cRed, MAX(cGreen, cBlue));
+
+ float expp = MAX(-B - 1.0f, floor(Math::log(cMax) / Math_LN2)) + 1.0f + B;
+
+ float sMax = (float)floor((cMax / Math::pow(2.0f, expp - B - N)) + 0.5f);
+
+ float exps = expp + 1.0f;
+
+ if (0.0 <= sMax && sMax < pow2to9) {
+ exps = expp;
+ }
+
+ float sRed = Math::floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
+ float sGreen = Math::floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
+ float sBlue = Math::floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
+
+ return (uint32_t(Math::fast_ftoi(sRed)) & 0x1FF) | ((uint32_t(Math::fast_ftoi(sGreen)) & 0x1FF) << 9) | ((uint32_t(Math::fast_ftoi(sBlue)) & 0x1FF) << 18) | ((uint32_t(Math::fast_ftoi(exps)) & 0x1F) << 27);
+ }
+
+ _FORCE_INLINE_ Color blend(const Color &p_over) const {
+ Color res;
+ float sa = 1.0 - p_over.a;
+ res.a = a * sa + p_over.a;
+ if (res.a == 0) {
+ return Color(0, 0, 0, 0);
+ } else {
+ res.r = (r * a * sa + p_over.r * p_over.a) / res.a;
+ res.g = (g * a * sa + p_over.g * p_over.a) / res.a;
+ res.b = (b * a * sa + p_over.b * p_over.a) / res.a;
+ }
+ return res;
+ }
+
+ _FORCE_INLINE_ Color to_linear() const {
+ return Color(
+ r < 0.04045 ? r * (1.0 / 12.92) : Math::pow((r + 0.055) * (1.0 / (1 + 0.055)), 2.4),
+ g < 0.04045 ? g * (1.0 / 12.92) : Math::pow((g + 0.055) * (1.0 / (1 + 0.055)), 2.4),
+ b < 0.04045 ? b * (1.0 / 12.92) : Math::pow((b + 0.055) * (1.0 / (1 + 0.055)), 2.4),
+ a);
+ }
+ _FORCE_INLINE_ Color to_srgb() const {
+ return Color(
+ r < 0.0031308 ? 12.92 * r : (1.0 + 0.055) * Math::pow(r, 1.0f / 2.4f) - 0.055,
+ g < 0.0031308 ? 12.92 * g : (1.0 + 0.055) * Math::pow(g, 1.0f / 2.4f) - 0.055,
+ b < 0.0031308 ? 12.92 * b : (1.0 + 0.055) * Math::pow(b, 1.0f / 2.4f) - 0.055, a);
+ }
+
+ static Color hex(uint32_t p_hex);
+ static Color hex64(uint64_t p_hex);
+ static Color html(const String &p_rgba);
+ static bool html_is_valid(const String &p_color);
+ static Color named(const String &p_name);
+ static int get_named_color_count();
+ static String get_named_color_name(int p_idx);
+ static Color get_named_color(int p_idx);
+ 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_rgbe9995(uint32_t p_rgbe);
+
+ _FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys
+ operator String() const;
+
+ // For the binder.
+ _FORCE_INLINE_ void set_r8(int32_t r8) { r = (CLAMP(r8, 0, 255) / 255.0); }
+ _FORCE_INLINE_ int32_t get_r8() const { return int32_t(CLAMP(r * 255.0, 0.0, 255.0)); }
+ _FORCE_INLINE_ void set_g8(int32_t g8) { g = (CLAMP(g8, 0, 255) / 255.0); }
+ _FORCE_INLINE_ int32_t get_g8() const { return int32_t(CLAMP(g * 255.0, 0.0, 255.0)); }
+ _FORCE_INLINE_ void set_b8(int32_t b8) { b = (CLAMP(b8, 0, 255) / 255.0); }
+ _FORCE_INLINE_ int32_t get_b8() const { return int32_t(CLAMP(b * 255.0, 0.0, 255.0)); }
+ _FORCE_INLINE_ void set_a8(int32_t a8) { a = (CLAMP(a8, 0, 255) / 255.0); }
+ _FORCE_INLINE_ int32_t get_a8() const { return int32_t(CLAMP(a * 255.0, 0.0, 255.0)); }
+
+ _FORCE_INLINE_ void set_h(float p_h) { set_hsv(p_h, get_s(), get_v()); }
+ _FORCE_INLINE_ void set_s(float p_s) { set_hsv(get_h(), p_s, get_v()); }
+ _FORCE_INLINE_ void set_v(float p_v) { set_hsv(get_h(), get_s(), p_v); }
+
+ _FORCE_INLINE_ Color() {}
+
+ /**
+ * RGBA construct parameters.
+ * Alpha is not optional as otherwise we can't bind the RGB version for scripting.
+ */
+ _FORCE_INLINE_ Color(float p_r, float p_g, float p_b, float p_a) {
+ r = p_r;
+ g = p_g;
+ b = p_b;
+ a = p_a;
+ }
+
+ /**
+ * RGB construct parameters.
+ */
+ _FORCE_INLINE_ Color(float p_r, float p_g, float p_b) {
+ r = p_r;
+ g = p_g;
+ b = p_b;
+ a = 1.0;
+ }
+
+ /**
+ * Construct a Color from another Color, but with the specified alpha value.
+ */
+ _FORCE_INLINE_ Color(const Color &p_c, float p_a) {
+ r = p_c.r;
+ g = p_c.g;
+ b = p_c.b;
+ a = p_a;
+ }
+};
+
+bool Color::operator<(const Color &p_color) const {
+ if (r == p_color.r) {
+ if (g == p_color.g) {
+ if (b == p_color.b) {
+ return (a < p_color.a);
+ } else {
+ return (b < p_color.b);
+ }
+ } else {
+ return g < p_color.g;
+ }
+ } else {
+ return r < p_color.r;
+ }
+}
+
+_FORCE_INLINE_ Color operator*(real_t p_real, const Color &p_color) {
+ return p_color * p_real;
+}
+
+#endif // COLOR_H
diff --git a/core/math/color_names.inc b/core/math/color_names.inc
new file mode 100644
index 0000000000..523c7e3c59
--- /dev/null
+++ b/core/math/color_names.inc
@@ -0,0 +1,160 @@
+// Names from https://en.wikipedia.org/wiki/X11_color_names
+
+// So this in a way that does not require memory allocation
+// the old way leaked memory
+// this is not used as often as for more performance to make sense
+
+struct NamedColor {
+ const char *name;
+ Color color;
+};
+
+static NamedColor named_colors[] = {
+ { "aliceblue", Color(0.94, 0.97, 1.00) },
+ { "antiquewhite", Color(0.98, 0.92, 0.84) },
+ { "aqua", Color(0.00, 1.00, 1.00) },
+ { "aquamarine", Color(0.50, 1.00, 0.83) },
+ { "azure", Color(0.94, 1.00, 1.00) },
+ { "beige", Color(0.96, 0.96, 0.86) },
+ { "bisque", Color(1.00, 0.89, 0.77) },
+ { "black", Color(0.00, 0.00, 0.00) },
+ { "blanchedalmond", Color(1.00, 0.92, 0.80) },
+ { "blue", Color(0.00, 0.00, 1.00) },
+ { "blueviolet", Color(0.54, 0.17, 0.89) },
+ { "brown", Color(0.65, 0.16, 0.16) },
+ { "burlywood", Color(0.87, 0.72, 0.53) },
+ { "cadetblue", Color(0.37, 0.62, 0.63) },
+ { "chartreuse", Color(0.50, 1.00, 0.00) },
+ { "chocolate", Color(0.82, 0.41, 0.12) },
+ { "coral", Color(1.00, 0.50, 0.31) },
+ { "cornflower", Color(0.39, 0.58, 0.93) },
+ { "cornsilk", Color(1.00, 0.97, 0.86) },
+ { "crimson", Color(0.86, 0.08, 0.24) },
+ { "cyan", Color(0.00, 1.00, 1.00) },
+ { "darkblue", Color(0.00, 0.00, 0.55) },
+ { "darkcyan", Color(0.00, 0.55, 0.55) },
+ { "darkgoldenrod", Color(0.72, 0.53, 0.04) },
+ { "darkgray", Color(0.66, 0.66, 0.66) },
+ { "darkgreen", Color(0.00, 0.39, 0.00) },
+ { "darkkhaki", Color(0.74, 0.72, 0.42) },
+ { "darkmagenta", Color(0.55, 0.00, 0.55) },
+ { "darkolivegreen", Color(0.33, 0.42, 0.18) },
+ { "darkorange", Color(1.00, 0.55, 0.00) },
+ { "darkorchid", Color(0.60, 0.20, 0.80) },
+ { "darkred", Color(0.55, 0.00, 0.00) },
+ { "darksalmon", Color(0.91, 0.59, 0.48) },
+ { "darkseagreen", Color(0.56, 0.74, 0.56) },
+ { "darkslateblue", Color(0.28, 0.24, 0.55) },
+ { "darkslategray", Color(0.18, 0.31, 0.31) },
+ { "darkturquoise", Color(0.00, 0.81, 0.82) },
+ { "darkviolet", Color(0.58, 0.00, 0.83) },
+ { "deeppink", Color(1.00, 0.08, 0.58) },
+ { "deepskyblue", Color(0.00, 0.75, 1.00) },
+ { "dimgray", Color(0.41, 0.41, 0.41) },
+ { "dodgerblue", Color(0.12, 0.56, 1.00) },
+ { "firebrick", Color(0.70, 0.13, 0.13) },
+ { "floralwhite", Color(1.00, 0.98, 0.94) },
+ { "forestgreen", Color(0.13, 0.55, 0.13) },
+ { "fuchsia", Color(1.00, 0.00, 1.00) },
+ { "gainsboro", Color(0.86, 0.86, 0.86) },
+ { "ghostwhite", Color(0.97, 0.97, 1.00) },
+ { "gold", Color(1.00, 0.84, 0.00) },
+ { "goldenrod", Color(0.85, 0.65, 0.13) },
+ { "gray", Color(0.75, 0.75, 0.75) },
+ { "green", Color(0.00, 1.00, 0.00) },
+ { "greenyellow", Color(0.68, 1.00, 0.18) },
+ { "honeydew", Color(0.94, 1.00, 0.94) },
+ { "hotpink", Color(1.00, 0.41, 0.71) },
+ { "indianred", Color(0.80, 0.36, 0.36) },
+ { "indigo", Color(0.29, 0.00, 0.51) },
+ { "ivory", Color(1.00, 1.00, 0.94) },
+ { "khaki", Color(0.94, 0.90, 0.55) },
+ { "lavender", Color(0.90, 0.90, 0.98) },
+ { "lavenderblush", Color(1.00, 0.94, 0.96) },
+ { "lawngreen", Color(0.49, 0.99, 0.00) },
+ { "lemonchiffon", Color(1.00, 0.98, 0.80) },
+ { "lightblue", Color(0.68, 0.85, 0.90) },
+ { "lightcoral", Color(0.94, 0.50, 0.50) },
+ { "lightcyan", Color(0.88, 1.00, 1.00) },
+ { "lightgoldenrod", Color(0.98, 0.98, 0.82) },
+ { "lightgray", Color(0.83, 0.83, 0.83) },
+ { "lightgreen", Color(0.56, 0.93, 0.56) },
+ { "lightpink", Color(1.00, 0.71, 0.76) },
+ { "lightsalmon", Color(1.00, 0.63, 0.48) },
+ { "lightseagreen", Color(0.13, 0.70, 0.67) },
+ { "lightskyblue", Color(0.53, 0.81, 0.98) },
+ { "lightslategray", Color(0.47, 0.53, 0.60) },
+ { "lightsteelblue", Color(0.69, 0.77, 0.87) },
+ { "lightyellow", Color(1.00, 1.00, 0.88) },
+ { "lime", Color(0.00, 1.00, 0.00) },
+ { "limegreen", Color(0.20, 0.80, 0.20) },
+ { "linen", Color(0.98, 0.94, 0.90) },
+ { "magenta", Color(1.00, 0.00, 1.00) },
+ { "maroon", Color(0.69, 0.19, 0.38) },
+ { "mediumaquamarine", Color(0.40, 0.80, 0.67) },
+ { "mediumblue", Color(0.00, 0.00, 0.80) },
+ { "mediumorchid", Color(0.73, 0.33, 0.83) },
+ { "mediumpurple", Color(0.58, 0.44, 0.86) },
+ { "mediumseagreen", Color(0.24, 0.70, 0.44) },
+ { "mediumslateblue", Color(0.48, 0.41, 0.93) },
+ { "mediumspringgreen", Color(0.00, 0.98, 0.60) },
+ { "mediumturquoise", Color(0.28, 0.82, 0.80) },
+ { "mediumvioletred", Color(0.78, 0.08, 0.52) },
+ { "midnightblue", Color(0.10, 0.10, 0.44) },
+ { "mintcream", Color(0.96, 1.00, 0.98) },
+ { "mistyrose", Color(1.00, 0.89, 0.88) },
+ { "moccasin", Color(1.00, 0.89, 0.71) },
+ { "navajowhite", Color(1.00, 0.87, 0.68) },
+ { "navyblue", Color(0.00, 0.00, 0.50) },
+ { "oldlace", Color(0.99, 0.96, 0.90) },
+ { "olive", Color(0.50, 0.50, 0.00) },
+ { "olivedrab", Color(0.42, 0.56, 0.14) },
+ { "orange", Color(1.00, 0.65, 0.00) },
+ { "orangered", Color(1.00, 0.27, 0.00) },
+ { "orchid", Color(0.85, 0.44, 0.84) },
+ { "palegoldenrod", Color(0.93, 0.91, 0.67) },
+ { "palegreen", Color(0.60, 0.98, 0.60) },
+ { "paleturquoise", Color(0.69, 0.93, 0.93) },
+ { "palevioletred", Color(0.86, 0.44, 0.58) },
+ { "papayawhip", Color(1.00, 0.94, 0.84) },
+ { "peachpuff", Color(1.00, 0.85, 0.73) },
+ { "peru", Color(0.80, 0.52, 0.25) },
+ { "pink", Color(1.00, 0.75, 0.80) },
+ { "plum", Color(0.87, 0.63, 0.87) },
+ { "powderblue", Color(0.69, 0.88, 0.90) },
+ { "purple", Color(0.63, 0.13, 0.94) },
+ { "rebeccapurple", Color(0.40, 0.20, 0.60) },
+ { "red", Color(1.00, 0.00, 0.00) },
+ { "rosybrown", Color(0.74, 0.56, 0.56) },
+ { "royalblue", Color(0.25, 0.41, 0.88) },
+ { "saddlebrown", Color(0.55, 0.27, 0.07) },
+ { "salmon", Color(0.98, 0.50, 0.45) },
+ { "sandybrown", Color(0.96, 0.64, 0.38) },
+ { "seagreen", Color(0.18, 0.55, 0.34) },
+ { "seashell", Color(1.00, 0.96, 0.93) },
+ { "sienna", Color(0.63, 0.32, 0.18) },
+ { "silver", Color(0.75, 0.75, 0.75) },
+ { "skyblue", Color(0.53, 0.81, 0.92) },
+ { "slateblue", Color(0.42, 0.35, 0.80) },
+ { "slategray", Color(0.44, 0.50, 0.56) },
+ { "snow", Color(1.00, 0.98, 0.98) },
+ { "springgreen", Color(0.00, 1.00, 0.50) },
+ { "steelblue", Color(0.27, 0.51, 0.71) },
+ { "tan", Color(0.82, 0.71, 0.55) },
+ { "teal", Color(0.00, 0.50, 0.50) },
+ { "thistle", Color(0.85, 0.75, 0.85) },
+ { "tomato", Color(1.00, 0.39, 0.28) },
+ { "transparent", Color(1.00, 1.00, 1.00, 0.00) },
+ { "turquoise", Color(0.25, 0.88, 0.82) },
+ { "violet", Color(0.93, 0.51, 0.93) },
+ { "webgray", Color(0.50, 0.50, 0.50) },
+ { "webgreen", Color(0.00, 0.50, 0.00) },
+ { "webmaroon", Color(0.50, 0.00, 0.00) },
+ { "webpurple", Color(0.50, 0.00, 0.50) },
+ { "wheat", Color(0.96, 0.87, 0.70) },
+ { "white", Color(1.00, 1.00, 1.00) },
+ { "whitesmoke", Color(0.96, 0.96, 0.96) },
+ { "yellow", Color(1.00, 1.00, 0.00) },
+ { "yellowgreen", Color(0.60, 0.80, 0.20) },
+ { nullptr, Color(0.60, 0.80, 0.20) },
+};
diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h
index 014b4c4621..ea8655cfff 100644
--- a/core/math/delaunay_3d.h
+++ b/core/math/delaunay_3d.h
@@ -31,15 +31,15 @@
#ifndef DELAUNAY_3D_H
#define DELAUNAY_3D_H
-#include "core/local_vector.h"
#include "core/math/aabb.h"
#include "core/math/camera_matrix.h"
#include "core/math/vector3.h"
-#include "core/oa_hash_map.h"
#include "core/os/file_access.h"
-#include "core/print_string.h"
-#include "core/variant.h"
-#include "core/vector.h"
+#include "core/string/print_string.h"
+#include "core/templates/local_vector.h"
+#include "core/templates/oa_hash_map.h"
+#include "core/templates/vector.h"
+#include "core/variant/variant.h"
#include "thirdparty/misc/r128.h"
diff --git a/core/math/disjoint_set.h b/core/math/disjoint_set.h
index 198f46e111..51b9ce81af 100644
--- a/core/math/disjoint_set.h
+++ b/core/math/disjoint_set.h
@@ -31,8 +31,8 @@
#ifndef DISJOINT_SET_H
#define DISJOINT_SET_H
-#include "core/map.h"
-#include "core/vector.h"
+#include "core/templates/map.h"
+#include "core/templates/vector.h"
/**
@author Marios Staikopoulos <marios@staik.net>
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index 13a49feb6b..d1f15caa5e 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -30,716 +30,14 @@
#include "expression.h"
-#include "core/class_db.h"
-#include "core/func_ref.h"
#include "core/io/marshalls.h"
#include "core/math/math_funcs.h"
+#include "core/object/class_db.h"
+#include "core/object/reference.h"
#include "core/os/os.h"
-#include "core/reference.h"
-#include "core/variant_parser.h"
-
-const char *Expression::func_name[Expression::FUNC_MAX] = {
- "sin",
- "cos",
- "tan",
- "sinh",
- "cosh",
- "tanh",
- "asin",
- "acos",
- "atan",
- "atan2",
- "sqrt",
- "fmod",
- "fposmod",
- "posmod",
- "floor",
- "ceil",
- "round",
- "abs",
- "sign",
- "pow",
- "log",
- "exp",
- "is_nan",
- "is_inf",
- "ease",
- "step_decimals",
- "stepify",
- "lerp",
- "lerp_angle",
- "inverse_lerp",
- "range_lerp",
- "smoothstep",
- "move_toward",
- "dectime",
- "randomize",
- "randi",
- "randf",
- "rand_range",
- "seed",
- "rand_seed",
- "deg2rad",
- "rad2deg",
- "linear2db",
- "db2linear",
- "polar2cartesian",
- "cartesian2polar",
- "wrapi",
- "wrapf",
- "max",
- "min",
- "clamp",
- "nearest_po2",
- "weakref",
- "funcref",
- "convert",
- "typeof",
- "type_exists",
- "char",
- "ord",
- "str",
- "print",
- "printerr",
- "printraw",
- "var2str",
- "str2var",
- "var2bytes",
- "bytes2var",
- "color_named",
-};
-
-Expression::BuiltinFunc Expression::find_function(const String &p_string) {
- for (int i = 0; i < FUNC_MAX; i++) {
- if (p_string == func_name[i]) {
- return BuiltinFunc(i);
- }
- }
-
- return FUNC_MAX;
-}
-
-String Expression::get_func_name(BuiltinFunc p_func) {
- ERR_FAIL_INDEX_V(p_func, FUNC_MAX, String());
- return func_name[p_func];
-}
-
-int Expression::get_func_argument_count(BuiltinFunc p_func) {
- switch (p_func) {
- case MATH_RANDOMIZE:
- case MATH_RAND:
- case MATH_RANDF:
- return 0;
- case MATH_SIN:
- case MATH_COS:
- case MATH_TAN:
- case MATH_SINH:
- case MATH_COSH:
- case MATH_TANH:
- case MATH_ASIN:
- case MATH_ACOS:
- case MATH_ATAN:
- case MATH_SQRT:
- case MATH_FLOOR:
- case MATH_CEIL:
- case MATH_ROUND:
- case MATH_ABS:
- case MATH_SIGN:
- case MATH_LOG:
- case MATH_EXP:
- case MATH_ISNAN:
- case MATH_ISINF:
- case MATH_STEP_DECIMALS:
- case MATH_SEED:
- case MATH_RANDSEED:
- case MATH_DEG2RAD:
- case MATH_RAD2DEG:
- case MATH_LINEAR2DB:
- case MATH_DB2LINEAR:
- case LOGIC_NEAREST_PO2:
- case OBJ_WEAKREF:
- case TYPE_OF:
- case TEXT_CHAR:
- case TEXT_ORD:
- case TEXT_STR:
- case TEXT_PRINT:
- case TEXT_PRINTERR:
- case TEXT_PRINTRAW:
- case VAR_TO_STR:
- case STR_TO_VAR:
- case TYPE_EXISTS:
- return 1;
- case VAR_TO_BYTES:
- case BYTES_TO_VAR:
- case MATH_ATAN2:
- case MATH_FMOD:
- case MATH_FPOSMOD:
- case MATH_POSMOD:
- case MATH_POW:
- case MATH_EASE:
- case MATH_STEPIFY:
- case MATH_RANDOM:
- case MATH_POLAR2CARTESIAN:
- case MATH_CARTESIAN2POLAR:
- case LOGIC_MAX:
- case LOGIC_MIN:
- case FUNC_FUNCREF:
- case TYPE_CONVERT:
- case COLORN:
- return 2;
- case MATH_LERP:
- case MATH_LERP_ANGLE:
- case MATH_INVERSE_LERP:
- case MATH_SMOOTHSTEP:
- case MATH_MOVE_TOWARD:
- case MATH_DECTIME:
- case MATH_WRAP:
- case MATH_WRAPF:
- case LOGIC_CLAMP:
- return 3;
- case MATH_RANGE_LERP:
- return 5;
- case FUNC_MAX: {
- }
- }
- return 0;
-}
+#include "core/variant/variant_parser.h"
-#define VALIDATE_ARG_NUM(m_arg) \
- if (!p_inputs[m_arg]->is_num()) { \
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; \
- r_error.argument = m_arg; \
- r_error.expected = Variant::FLOAT; \
- return; \
- }
-
-void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Callable::CallError &r_error, String &r_error_str) {
- r_error.error = Callable::CallError::CALL_OK;
- switch (p_func) {
- case MATH_SIN: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::sin((double)*p_inputs[0]);
- } break;
- case MATH_COS: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::cos((double)*p_inputs[0]);
- } break;
- case MATH_TAN: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::tan((double)*p_inputs[0]);
- } break;
- case MATH_SINH: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::sinh((double)*p_inputs[0]);
- } break;
- case MATH_COSH: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::cosh((double)*p_inputs[0]);
- } break;
- case MATH_TANH: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::tanh((double)*p_inputs[0]);
- } break;
- case MATH_ASIN: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::asin((double)*p_inputs[0]);
- } break;
- case MATH_ACOS: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::acos((double)*p_inputs[0]);
- } break;
- case MATH_ATAN: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::atan((double)*p_inputs[0]);
- } break;
- case MATH_ATAN2: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- *r_return = Math::atan2((double)*p_inputs[0], (double)*p_inputs[1]);
- } break;
- case MATH_SQRT: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::sqrt((double)*p_inputs[0]);
- } break;
- case MATH_FMOD: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- *r_return = Math::fmod((double)*p_inputs[0], (double)*p_inputs[1]);
- } break;
- case MATH_FPOSMOD: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- *r_return = Math::fposmod((double)*p_inputs[0], (double)*p_inputs[1]);
- } break;
- case MATH_POSMOD: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- *r_return = Math::posmod((int)*p_inputs[0], (int)*p_inputs[1]);
- } break;
- case MATH_FLOOR: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::floor((double)*p_inputs[0]);
- } break;
- case MATH_CEIL: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::ceil((double)*p_inputs[0]);
- } break;
- case MATH_ROUND: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::round((double)*p_inputs[0]);
- } break;
- case MATH_ABS: {
- if (p_inputs[0]->get_type() == Variant::INT) {
- int64_t i = *p_inputs[0];
- *r_return = ABS(i);
- } else if (p_inputs[0]->get_type() == Variant::FLOAT) {
- real_t r = *p_inputs[0];
- *r_return = Math::abs(r);
- } else {
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = 0;
- r_error.expected = Variant::FLOAT;
- }
- } break;
- case MATH_SIGN: {
- if (p_inputs[0]->get_type() == Variant::INT) {
- int64_t i = *p_inputs[0];
- *r_return = i < 0 ? -1 : (i > 0 ? +1 : 0);
- } else if (p_inputs[0]->get_type() == Variant::FLOAT) {
- real_t r = *p_inputs[0];
- *r_return = r < 0.0 ? -1.0 : (r > 0.0 ? +1.0 : 0.0);
- } else {
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = 0;
- r_error.expected = Variant::FLOAT;
- }
- } break;
- case MATH_POW: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- *r_return = Math::pow((double)*p_inputs[0], (double)*p_inputs[1]);
- } break;
- case MATH_LOG: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::log((double)*p_inputs[0]);
- } break;
- case MATH_EXP: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::exp((double)*p_inputs[0]);
- } break;
- case MATH_ISNAN: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::is_nan((double)*p_inputs[0]);
- } break;
- case MATH_ISINF: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::is_inf((double)*p_inputs[0]);
- } break;
- case MATH_EASE: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- *r_return = Math::ease((double)*p_inputs[0], (double)*p_inputs[1]);
- } break;
- case MATH_STEP_DECIMALS: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::step_decimals((double)*p_inputs[0]);
- } break;
- case MATH_STEPIFY: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- *r_return = Math::stepify((double)*p_inputs[0], (double)*p_inputs[1]);
- } break;
- case MATH_LERP: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- VALIDATE_ARG_NUM(2);
- *r_return = Math::lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
- } break;
- case MATH_LERP_ANGLE: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- VALIDATE_ARG_NUM(2);
- *r_return = Math::lerp_angle((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
- } break;
- case MATH_INVERSE_LERP: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- VALIDATE_ARG_NUM(2);
- *r_return = Math::inverse_lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
- } break;
- case MATH_RANGE_LERP: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- VALIDATE_ARG_NUM(2);
- VALIDATE_ARG_NUM(3);
- VALIDATE_ARG_NUM(4);
- *r_return = Math::range_lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2], (double)*p_inputs[3], (double)*p_inputs[4]);
- } break;
- case MATH_SMOOTHSTEP: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- VALIDATE_ARG_NUM(2);
- *r_return = Math::smoothstep((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
- } break;
- case MATH_MOVE_TOWARD: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- VALIDATE_ARG_NUM(2);
- *r_return = Math::move_toward((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
- } break;
- case MATH_DECTIME: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- VALIDATE_ARG_NUM(2);
- *r_return = Math::dectime((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
- } break;
- case MATH_RANDOMIZE: {
- Math::randomize();
-
- } break;
- case MATH_RAND: {
- *r_return = Math::rand();
- } break;
- case MATH_RANDF: {
- *r_return = Math::randf();
- } break;
- case MATH_RANDOM: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- *r_return = Math::random((double)*p_inputs[0], (double)*p_inputs[1]);
- } break;
- case MATH_SEED: {
- VALIDATE_ARG_NUM(0);
- uint64_t seed = *p_inputs[0];
- Math::seed(seed);
-
- } break;
- case MATH_RANDSEED: {
- VALIDATE_ARG_NUM(0);
- uint64_t seed = *p_inputs[0];
- int ret = Math::rand_from_seed(&seed);
- Array reta;
- reta.push_back(ret);
- reta.push_back(seed);
- *r_return = reta;
-
- } break;
- case MATH_DEG2RAD: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::deg2rad((double)*p_inputs[0]);
- } break;
- case MATH_RAD2DEG: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::rad2deg((double)*p_inputs[0]);
- } break;
- case MATH_LINEAR2DB: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::linear2db((double)*p_inputs[0]);
- } break;
- case MATH_DB2LINEAR: {
- VALIDATE_ARG_NUM(0);
- *r_return = Math::db2linear((double)*p_inputs[0]);
- } break;
- case MATH_POLAR2CARTESIAN: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- double r = *p_inputs[0];
- double th = *p_inputs[1];
- *r_return = Vector2(r * Math::cos(th), r * Math::sin(th));
- } break;
- case MATH_CARTESIAN2POLAR: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- double x = *p_inputs[0];
- double y = *p_inputs[1];
- *r_return = Vector2(Math::sqrt(x * x + y * y), Math::atan2(y, x));
- } break;
- case MATH_WRAP: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- VALIDATE_ARG_NUM(2);
- *r_return = Math::wrapi((int64_t)*p_inputs[0], (int64_t)*p_inputs[1], (int64_t)*p_inputs[2]);
- } break;
- case MATH_WRAPF: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- VALIDATE_ARG_NUM(2);
- *r_return = Math::wrapf((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
- } break;
- case LOGIC_MAX: {
- if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT) {
- int64_t a = *p_inputs[0];
- int64_t b = *p_inputs[1];
- *r_return = MAX(a, b);
- } else {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
-
- real_t a = *p_inputs[0];
- real_t b = *p_inputs[1];
-
- *r_return = MAX(a, b);
- }
-
- } break;
- case LOGIC_MIN: {
- if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT) {
- int64_t a = *p_inputs[0];
- int64_t b = *p_inputs[1];
- *r_return = MIN(a, b);
- } else {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
-
- real_t a = *p_inputs[0];
- real_t b = *p_inputs[1];
-
- *r_return = MIN(a, b);
- }
- } break;
- case LOGIC_CLAMP: {
- if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT && p_inputs[2]->get_type() == Variant::INT) {
- int64_t a = *p_inputs[0];
- int64_t b = *p_inputs[1];
- int64_t c = *p_inputs[2];
- *r_return = CLAMP(a, b, c);
- } else {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- VALIDATE_ARG_NUM(2);
-
- real_t a = *p_inputs[0];
- real_t b = *p_inputs[1];
- real_t c = *p_inputs[2];
-
- *r_return = CLAMP(a, b, c);
- }
- } break;
- case LOGIC_NEAREST_PO2: {
- VALIDATE_ARG_NUM(0);
- int64_t num = *p_inputs[0];
- *r_return = next_power_of_2(num);
- } break;
- case OBJ_WEAKREF: {
- if (p_inputs[0]->get_type() != Variant::OBJECT) {
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = 0;
- r_error.expected = Variant::OBJECT;
-
- return;
- }
-
- if (p_inputs[0]->is_ref()) {
- REF r = *p_inputs[0];
- if (!r.is_valid()) {
- return;
- }
-
- Ref<WeakRef> wref = memnew(WeakRef);
- wref->set_ref(r);
- *r_return = wref;
- } else {
- Object *obj = *p_inputs[0];
- if (!obj) {
- return;
- }
- Ref<WeakRef> wref = memnew(WeakRef);
- wref->set_obj(obj);
- *r_return = wref;
- }
-
- } break;
- case FUNC_FUNCREF: {
- if (p_inputs[0]->get_type() != Variant::OBJECT) {
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = 0;
- r_error.expected = Variant::OBJECT;
-
- return;
- }
- if (p_inputs[1]->get_type() != Variant::STRING && p_inputs[1]->get_type() != Variant::NODE_PATH) {
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = 1;
- r_error.expected = Variant::STRING;
-
- return;
- }
-
- Ref<FuncRef> fr = memnew(FuncRef);
-
- fr->set_instance(*p_inputs[0]);
- fr->set_function(*p_inputs[1]);
-
- *r_return = fr;
-
- } break;
- case TYPE_CONVERT: {
- VALIDATE_ARG_NUM(1);
- int type = *p_inputs[1];
- if (type < 0 || type >= Variant::VARIANT_MAX) {
- r_error_str = RTR("Invalid type argument to convert(), use TYPE_* constants.");
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = 0;
- r_error.expected = Variant::INT;
- return;
-
- } else {
- *r_return = Variant::construct(Variant::Type(type), p_inputs, 1, r_error);
- }
- } break;
- case TYPE_OF: {
- *r_return = p_inputs[0]->get_type();
-
- } break;
- case TYPE_EXISTS: {
- *r_return = ClassDB::class_exists(*p_inputs[0]);
-
- } break;
- case TEXT_CHAR: {
- CharType result[2] = { *p_inputs[0], 0 };
-
- *r_return = String(result);
-
- } break;
- case TEXT_ORD: {
- if (p_inputs[0]->get_type() != Variant::STRING) {
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = 0;
- r_error.expected = Variant::STRING;
-
- return;
- }
-
- String str = *p_inputs[0];
-
- if (str.length() != 1) {
- r_error_str = RTR("Expected a string of length 1 (a character).");
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = 0;
- r_error.expected = Variant::STRING;
-
- return;
- }
-
- *r_return = str.get(0);
-
- } break;
- case TEXT_STR: {
- String str = *p_inputs[0];
-
- *r_return = str;
-
- } break;
- case TEXT_PRINT: {
- String str = *p_inputs[0];
- print_line(str);
-
- } break;
-
- case TEXT_PRINTERR: {
- String str = *p_inputs[0];
- print_error(str);
-
- } break;
- case TEXT_PRINTRAW: {
- String str = *p_inputs[0];
- OS::get_singleton()->print("%s", str.utf8().get_data());
-
- } break;
- case VAR_TO_STR: {
- String vars;
- VariantWriter::write_to_string(*p_inputs[0], vars);
- *r_return = vars;
- } break;
- case STR_TO_VAR: {
- if (p_inputs[0]->get_type() != Variant::STRING) {
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = 0;
- r_error.expected = Variant::STRING;
-
- return;
- }
-
- VariantParser::StreamString ss;
- ss.s = *p_inputs[0];
-
- String errs;
- int line;
- Error err = VariantParser::parse(&ss, *r_return, errs, line);
-
- if (err != OK) {
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = 0;
- r_error.expected = Variant::STRING;
- *r_return = "Parse error at line " + itos(line) + ": " + errs;
- return;
- }
-
- } break;
- case VAR_TO_BYTES: {
- PackedByteArray barr;
- bool full_objects = *p_inputs[1];
- int len;
- Error err = encode_variant(*p_inputs[0], nullptr, len, full_objects);
- if (err) {
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = 0;
- r_error.expected = Variant::NIL;
- r_error_str = "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).";
- return;
- }
-
- barr.resize(len);
- {
- uint8_t *w = barr.ptrw();
- encode_variant(*p_inputs[0], w, len, full_objects);
- }
- *r_return = barr;
- } break;
- case BYTES_TO_VAR: {
- if (p_inputs[0]->get_type() != Variant::PACKED_BYTE_ARRAY) {
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = 0;
- r_error.expected = Variant::PACKED_BYTE_ARRAY;
-
- return;
- }
-
- PackedByteArray varr = *p_inputs[0];
- bool allow_objects = *p_inputs[1];
- Variant ret;
- {
- const uint8_t *r = varr.ptr();
- Error err = decode_variant(ret, r, varr.size(), nullptr, allow_objects);
- if (err != OK) {
- r_error_str = RTR("Not enough bytes for decoding bytes, or invalid format.");
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = 0;
- r_error.expected = Variant::PACKED_BYTE_ARRAY;
- return;
- }
- }
-
- *r_return = ret;
-
- } break;
- case COLORN: {
- VALIDATE_ARG_NUM(1);
-
- Color color = Color::named(*p_inputs[0]);
- color.a = *p_inputs[1];
-
- *r_return = String(color);
-
- } break;
- default: {
- }
- }
-}
-
-////////
-
-static bool _is_number(CharType c) {
+static bool _is_number(char32_t c) {
return (c >= '0' && c <= '9');
}
@@ -747,7 +45,7 @@ Error Expression::_get_token(Token &r_token) {
while (true) {
#define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++])
- CharType cchar = GET_CHAR();
+ char32_t cchar = GET_CHAR();
switch (cchar) {
case 0: {
@@ -900,7 +198,7 @@ Error Expression::_get_token(Token &r_token) {
case '"': {
String str;
while (true) {
- CharType ch = GET_CHAR();
+ char32_t ch = GET_CHAR();
if (ch == 0) {
_set_error("Unterminated String");
@@ -912,13 +210,13 @@ Error Expression::_get_token(Token &r_token) {
} else if (ch == '\\') {
//escaped characters...
- CharType next = GET_CHAR();
+ char32_t next = GET_CHAR();
if (next == 0) {
_set_error("Unterminated String");
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
}
- CharType res = 0;
+ char32_t res = 0;
switch (next) {
case 'b':
@@ -939,7 +237,7 @@ Error Expression::_get_token(Token &r_token) {
case 'u': {
// hex number
for (int j = 0; j < 4; j++) {
- CharType c = GET_CHAR();
+ char32_t c = GET_CHAR();
if (c == 0) {
_set_error("Unterminated String");
@@ -951,7 +249,7 @@ Error Expression::_get_token(Token &r_token) {
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
}
- CharType v;
+ char32_t v;
if (_is_number(c)) {
v = c - '0';
} else if (c >= 'a' && c <= 'f') {
@@ -992,7 +290,7 @@ Error Expression::_get_token(Token &r_token) {
break;
}
- CharType next_char = (str_ofs >= expression.length()) ? 0 : expression[str_ofs];
+ char32_t next_char = (str_ofs >= expression.length()) ? 0 : expression[str_ofs];
if (_is_number(cchar) || (cchar == '.' && _is_number(next_char))) {
//a number
@@ -1004,7 +302,7 @@ Error Expression::_get_token(Token &r_token) {
#define READING_DONE 4
int reading = READING_INT;
- CharType c = cchar;
+ char32_t c = cchar;
bool exp_sign = false;
bool exp_beg = false;
bool is_float = false;
@@ -1062,7 +360,7 @@ Error Expression::_get_token(Token &r_token) {
r_token.type = TK_CONSTANT;
if (is_float) {
- r_token.value = num.to_double();
+ r_token.value = num.to_float();
} else {
r_token.value = num.to_int();
}
@@ -1112,18 +410,9 @@ 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;
- }
- }
-
- BuiltinFunc bifunc = find_function(id);
- if (bifunc != FUNC_MAX) {
+ if (Variant::has_utility_function(id)) {
r_token.type = TK_BUILTIN_FUNC;
- r_token.value = bifunc;
+ r_token.value = id;
return OK;
}
@@ -1421,6 +710,8 @@ Expression::ENode *Expression::_parse_expression() {
case TK_BUILTIN_FUNC: {
//builtin function
+ StringName func = tk.value;
+
_get_token(tk);
if (tk.type != TK_PARENTHESIS_OPEN) {
_set_error("Expected '('");
@@ -1428,7 +719,7 @@ Expression::ENode *Expression::_parse_expression() {
}
BuiltinFuncNode *bifunc = alloc_node<BuiltinFuncNode>();
- bifunc->func = BuiltinFunc(int(tk.value));
+ bifunc->func = func;
while (true) {
int cofs = str_ofs;
@@ -1456,9 +747,11 @@ Expression::ENode *Expression::_parse_expression() {
}
}
- int expected_args = get_func_argument_count(bifunc->func);
- if (bifunc->arguments.size() != expected_args) {
- _set_error("Builtin func '" + get_func_name(bifunc->func) + "' expects " + itos(expected_args) + " arguments.");
+ if (!Variant::is_utility_function_vararg(bifunc->func)) {
+ int expected_args = Variant::get_utility_function_argument_count(bifunc->func);
+ if (expected_args != bifunc->arguments.size()) {
+ _set_error("Builtin func '" + String(bifunc->func) + "' expects " + itos(expected_args) + " arguments.");
+ }
}
expr = bifunc;
@@ -1973,7 +1266,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
}
bool valid;
- r_ret = base.get_named(index->name, &valid);
+ r_ret = base.get_named(index->name, valid);
if (!valid) {
r_error_str = vformat(RTR("Invalid named index '%s' for base type %s"), String(index->name), Variant::get_type_name(base.get_type()));
return true;
@@ -2041,7 +1334,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
}
Callable::CallError ce;
- r_ret = Variant::construct(constructor->data_type, (const Variant **)argp.ptr(), argp.size(), ce);
+ Variant::construct(constructor->data_type, r_ret, (const Variant **)argp.ptr(), argp.size(), ce);
if (ce.error != Callable::CallError::CALL_OK) {
r_error_str = vformat(RTR("Invalid arguments to construct '%s'"), Variant::get_type_name(constructor->data_type));
@@ -2067,11 +1360,11 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
argp.write[i] = &arr[i];
}
+ r_ret = Variant(); //may not return anything
Callable::CallError ce;
- exec_func(bifunc->func, (const Variant **)argp.ptr(), &r_ret, ce, r_error_str);
-
+ Variant::call_utility_function(bifunc->func, &r_ret, (const Variant **)argp.ptr(), argp.size(), ce);
if (ce.error != Callable::CallError::CALL_OK) {
- r_error_str = "Builtin Call Failed. " + r_error_str;
+ r_error_str = "Builtin Call Failed. " + Variant::get_call_error_text(bifunc->func, (const Variant **)argp.ptr(), argp.size(), ce);
return true;
}
@@ -2103,7 +1396,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
}
Callable::CallError ce;
- r_ret = base.call(call->method, (const Variant **)argp.ptr(), argp.size(), ce);
+ base.call(call->method, (const Variant **)argp.ptr(), argp.size(), r_ret, ce);
if (ce.error != Callable::CallError::CALL_OK) {
r_error_str = vformat(RTR("On call to '%s':"), String(call->method));
diff --git a/core/math/expression.h b/core/math/expression.h
index 59a9a2f4ed..6b34bc6ae8 100644
--- a/core/math/expression.h
+++ b/core/math/expression.h
@@ -31,92 +31,12 @@
#ifndef EXPRESSION_H
#define EXPRESSION_H
-#include "core/reference.h"
+#include "core/object/reference.h"
class Expression : public Reference {
GDCLASS(Expression, Reference);
-public:
- enum BuiltinFunc {
- MATH_SIN,
- MATH_COS,
- MATH_TAN,
- MATH_SINH,
- MATH_COSH,
- MATH_TANH,
- MATH_ASIN,
- MATH_ACOS,
- MATH_ATAN,
- MATH_ATAN2,
- MATH_SQRT,
- MATH_FMOD,
- MATH_FPOSMOD,
- MATH_POSMOD,
- MATH_FLOOR,
- MATH_CEIL,
- MATH_ROUND,
- MATH_ABS,
- MATH_SIGN,
- MATH_POW,
- MATH_LOG,
- MATH_EXP,
- MATH_ISNAN,
- MATH_ISINF,
- MATH_EASE,
- MATH_STEP_DECIMALS,
- MATH_STEPIFY,
- MATH_LERP,
- MATH_LERP_ANGLE,
- MATH_INVERSE_LERP,
- MATH_RANGE_LERP,
- MATH_SMOOTHSTEP,
- MATH_MOVE_TOWARD,
- MATH_DECTIME,
- MATH_RANDOMIZE,
- MATH_RAND,
- MATH_RANDF,
- MATH_RANDOM,
- MATH_SEED,
- MATH_RANDSEED,
- MATH_DEG2RAD,
- MATH_RAD2DEG,
- MATH_LINEAR2DB,
- MATH_DB2LINEAR,
- MATH_POLAR2CARTESIAN,
- MATH_CARTESIAN2POLAR,
- MATH_WRAP,
- MATH_WRAPF,
- LOGIC_MAX,
- LOGIC_MIN,
- LOGIC_CLAMP,
- LOGIC_NEAREST_PO2,
- OBJ_WEAKREF,
- FUNC_FUNCREF,
- TYPE_CONVERT,
- TYPE_OF,
- TYPE_EXISTS,
- TEXT_CHAR,
- TEXT_ORD,
- TEXT_STR,
- TEXT_PRINT,
- TEXT_PRINTERR,
- TEXT_PRINTRAW,
- VAR_TO_STR,
- STR_TO_VAR,
- VAR_TO_BYTES,
- BYTES_TO_VAR,
- COLORN,
- FUNC_MAX
- };
-
- static int get_func_argument_count(BuiltinFunc p_func);
- static String get_func_name(BuiltinFunc p_func);
- static void exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Callable::CallError &r_error, String &r_error_str);
- static BuiltinFunc find_function(const String &p_string);
-
private:
- static const char *func_name[FUNC_MAX];
-
struct Input {
Variant::Type type = Variant::NIL;
String name;
@@ -213,7 +133,7 @@ private:
ENode *next = nullptr;
- Type type;
+ Type type = TYPE_INPUT;
ENode() {}
virtual ~ENode() {
@@ -224,7 +144,7 @@ private:
};
struct ExpressionNode {
- bool is_op;
+ bool is_op = false;
union {
Variant::Operator op;
ENode *node;
@@ -234,23 +154,23 @@ private:
ENode *_parse_expression();
struct InputNode : public ENode {
- int index;
+ int index = 0;
InputNode() {
type = TYPE_INPUT;
}
};
struct ConstantNode : public ENode {
- Variant value;
+ Variant value = Variant::NIL;
ConstantNode() {
type = TYPE_CONSTANT;
}
};
struct OperatorNode : public ENode {
- Variant::Operator op;
+ Variant::Operator op = Variant::Operator::OP_ADD;
- ENode *nodes[2];
+ ENode *nodes[2] = { nullptr, nullptr };
OperatorNode() {
type = TYPE_OPERATOR;
@@ -264,8 +184,8 @@ private:
};
struct IndexNode : public ENode {
- ENode *base;
- ENode *index;
+ ENode *base = nullptr;
+ ENode *index = nullptr;
IndexNode() {
type = TYPE_INDEX;
@@ -273,7 +193,7 @@ private:
};
struct NamedIndexNode : public ENode {
- ENode *base;
+ ENode *base = nullptr;
StringName name;
NamedIndexNode() {
@@ -282,7 +202,7 @@ private:
};
struct ConstructorNode : public ENode {
- Variant::Type data_type;
+ Variant::Type data_type = Variant::Type::NIL;
Vector<ENode *> arguments;
ConstructorNode() {
@@ -291,7 +211,7 @@ private:
};
struct CallNode : public ENode {
- ENode *base;
+ ENode *base = nullptr;
StringName method;
Vector<ENode *> arguments;
@@ -315,7 +235,7 @@ private:
};
struct BuiltinFuncNode : public ENode {
- BuiltinFunc func;
+ StringName func;
Vector<ENode *> arguments;
BuiltinFuncNode() {
type = TYPE_BUILTIN_FUNC;
@@ -343,7 +263,7 @@ protected:
public:
Error parse(const String &p_expression, const Vector<String> &p_input_names = Vector<String>());
- Variant execute(Array p_inputs, Object *p_base = nullptr, bool p_show_error = true);
+ Variant execute(Array p_inputs = Array(), Object *p_base = nullptr, bool p_show_error = true);
bool has_execute_failed() const;
String get_error_text() const;
diff --git a/core/math/geometry_2d.h b/core/math/geometry_2d.h
index cfd7abfacb..12bad5768e 100644
--- a/core/math/geometry_2d.h
+++ b/core/math/geometry_2d.h
@@ -34,8 +34,8 @@
#include "core/math/delaunay_2d.h"
#include "core/math/rect2.h"
#include "core/math/triangulate.h"
-#include "core/object.h"
-#include "core/vector.h"
+#include "core/object/object.h"
+#include "core/templates/vector.h"
class Geometry2D {
Geometry2D();
diff --git a/core/math/geometry_3d.cpp b/core/math/geometry_3d.cpp
index 7807ab19a7..ccb6648561 100644
--- a/core/math/geometry_3d.cpp
+++ b/core/math/geometry_3d.cpp
@@ -30,7 +30,7 @@
#include "geometry_3d.h"
-#include "core/print_string.h"
+#include "core/string/print_string.h"
#include "thirdparty/misc/clipper.hpp"
#include "thirdparty/misc/triangulator.h"
@@ -241,7 +241,6 @@ Vector<Vector<Face3>> Geometry3D::separate_objects(Vector<Face3> p_array) {
/*** GEOMETRY WRAPPER ***/
enum _CellFlags {
-
_CELL_SOLID = 1,
_CELL_EXTERIOR = 2,
_CELL_STEP_MASK = 0x1C,
@@ -262,7 +261,6 @@ enum _CellFlags {
_CELL_PREV_Z_POS = 5 << 5,
_CELL_PREV_Z_NEG = 6 << 5,
_CELL_PREV_FIRST = 7 << 5,
-
};
static inline void _plot_face(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z, const Vector3 &voxelsize, const Face3 &p_face) {
@@ -648,7 +646,7 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes
Vector<Vector3> vertices;
- Vector3 center = p.get_any_point();
+ 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);
diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h
index 6bbf518141..f10fbeaaaf 100644
--- a/core/math/geometry_3d.h
+++ b/core/math/geometry_3d.h
@@ -32,8 +32,8 @@
#define GEOMETRY_3D_H
#include "core/math/face3.h"
-#include "core/object.h"
-#include "core/vector.h"
+#include "core/object/object.h"
+#include "core/templates/vector.h"
class Geometry3D {
Geometry3D();
@@ -636,54 +636,6 @@ public:
void optimize_vertices();
};
- _FORCE_INLINE_ static int get_uv84_normal_bit(const Vector3 &p_vector) {
- int lat = Math::fast_ftoi(Math::floor(Math::acos(p_vector.dot(Vector3(0, 1, 0))) * 4.0 / Math_PI + 0.5));
-
- if (lat == 0) {
- return 24;
- } else if (lat == 4) {
- return 25;
- }
-
- int lon = Math::fast_ftoi(Math::floor((Math_PI + Math::atan2(p_vector.x, p_vector.z)) * 8.0 / (Math_PI * 2.0) + 0.5)) % 8;
-
- return lon + (lat - 1) * 8;
- }
-
- _FORCE_INLINE_ static int get_uv84_normal_bit_neighbors(int p_idx) {
- if (p_idx == 24) {
- return 1 | 2 | 4 | 8;
- } else if (p_idx == 25) {
- return (1 << 23) | (1 << 22) | (1 << 21) | (1 << 20);
- } else {
- int ret = 0;
- if ((p_idx % 8) == 0) {
- ret |= (1 << (p_idx + 7));
- } else {
- ret |= (1 << (p_idx - 1));
- }
- if ((p_idx % 8) == 7) {
- ret |= (1 << (p_idx - 7));
- } else {
- ret |= (1 << (p_idx + 1));
- }
-
- int mask = ret | (1 << p_idx);
- if (p_idx < 8) {
- ret |= 24;
- } else {
- ret |= mask >> 8;
- }
-
- if (p_idx >= 16) {
- ret |= 25;
- } else {
- ret |= mask << 8;
- }
-
- return ret;
- }
- }
static MeshData build_convex_mesh(const Vector<Plane> &p_planes);
static Vector<Plane> build_sphere_planes(real_t p_radius, int p_lats, int p_lons, Vector3::Axis p_axis = Vector3::AXIS_Z);
static Vector<Plane> build_box_planes(const Vector3 &p_extents);
diff --git a/core/math/math_defs.h b/core/math/math_defs.h
index 4928c96abd..5192722839 100644
--- a/core/math/math_defs.h
+++ b/core/math/math_defs.h
@@ -66,27 +66,23 @@ enum ClockDirection {
};
enum Orientation {
-
HORIZONTAL,
VERTICAL
};
enum HAlign {
-
HALIGN_LEFT,
HALIGN_CENTER,
HALIGN_RIGHT
};
enum VAlign {
-
VALIGN_TOP,
VALIGN_CENTER,
VALIGN_BOTTOM
};
enum Margin {
-
MARGIN_LEFT,
MARGIN_TOP,
MARGIN_RIGHT,
@@ -94,7 +90,6 @@ enum Margin {
};
enum Corner {
-
CORNER_TOP_LEFT,
CORNER_TOP_RIGHT,
CORNER_BOTTOM_RIGHT,
diff --git a/core/math/math_fieldwise.cpp b/core/math/math_fieldwise.cpp
index ef2a0c5339..221c6812c1 100644
--- a/core/math/math_fieldwise.cpp
+++ b/core/math/math_fieldwise.cpp
@@ -47,9 +47,7 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const
/* clang-format off */
switch (p_source.get_type()) {
-
case Variant::VECTOR2: {
-
SETUP_TYPE(Vector2)
/**/ TRY_TRANSFER_FIELD("x", x)
@@ -59,7 +57,6 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const
}
case Variant::RECT2: {
-
SETUP_TYPE(Rect2)
/**/ TRY_TRANSFER_FIELD("x", position.x)
@@ -71,7 +68,6 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const
}
case Variant::VECTOR3: {
-
SETUP_TYPE(Vector3)
/**/ TRY_TRANSFER_FIELD("x", x)
@@ -82,7 +78,6 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const
}
case Variant::PLANE: {
-
SETUP_TYPE(Plane)
/**/ TRY_TRANSFER_FIELD("x", normal.x)
@@ -94,7 +89,6 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const
}
case Variant::QUAT: {
-
SETUP_TYPE(Quat)
/**/ TRY_TRANSFER_FIELD("x", x)
@@ -106,7 +100,6 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const
}
case Variant::AABB: {
-
SETUP_TYPE(AABB)
/**/ TRY_TRANSFER_FIELD("px", position.x)
@@ -120,7 +113,6 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const
}
case Variant::TRANSFORM2D: {
-
SETUP_TYPE(Transform2D)
/**/ TRY_TRANSFER_FIELD("xx", elements[0][0])
@@ -134,7 +126,6 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const
}
case Variant::BASIS: {
-
SETUP_TYPE(Basis)
/**/ TRY_TRANSFER_FIELD("xx", elements[0][0])
@@ -151,7 +142,6 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const
}
case Variant::TRANSFORM: {
-
SETUP_TYPE(Transform)
/**/ TRY_TRANSFER_FIELD("xx", basis.elements[0][0])
diff --git a/core/math/math_fieldwise.h b/core/math/math_fieldwise.h
index c1ee9ec8f0..e8aac0dced 100644
--- a/core/math/math_fieldwise.h
+++ b/core/math/math_fieldwise.h
@@ -33,7 +33,7 @@
#ifdef TOOLS_ENABLED
-#include "core/variant.h"
+#include "core/variant/variant.h"
Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const String &p_field);
diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp
index 1585c96b38..e57257b442 100644
--- a/core/math/math_funcs.cpp
+++ b/core/math/math_funcs.cpp
@@ -30,12 +30,10 @@
#include "math_funcs.h"
-#include "core/error_macros.h"
+#include "core/error/error_macros.h"
RandomPCG Math::default_rand(RandomPCG::DEFAULT_SEED, RandomPCG::DEFAULT_INC);
-#define PHI 0x9e3779b9
-
uint32_t Math::rand_from_seed(uint64_t *seed) {
RandomPCG rng = RandomPCG(*seed, RandomPCG::DEFAULT_INC);
uint32_t r = rng.rand();
@@ -183,3 +181,7 @@ double Math::random(double from, double to) {
float Math::random(float from, float to) {
return default_rand.random(from, to);
}
+
+int Math::random(int from, int to) {
+ return default_rand.random(from, to);
+}
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 7a9fd60e23..827637bf2b 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -46,7 +46,8 @@ class Math {
public:
Math() {} // useless to instance
- static const uint64_t RANDOM_MAX = 0xFFFFFFFF;
+ // Not using 'RANDOM_MAX' to avoid conflict with system headers on some OSes (at least NetBSD).
+ static const uint64_t RANDOM_32BIT_MAX = 0xFFFFFFFF;
static _ALWAYS_INLINE_ double sin(double p_x) { return ::sin(p_x); }
static _ALWAYS_INLINE_ float sin(float p_x) { return ::sinf(p_x); }
@@ -231,19 +232,19 @@ public:
static _ALWAYS_INLINE_ double range_lerp(double p_value, double p_istart, double p_istop, double p_ostart, double p_ostop) { return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value)); }
static _ALWAYS_INLINE_ float range_lerp(float p_value, float p_istart, float p_istop, float p_ostart, float p_ostop) { return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value)); }
- static _ALWAYS_INLINE_ double smoothstep(double p_from, double p_to, double p_weight) {
+ static _ALWAYS_INLINE_ double smoothstep(double p_from, double p_to, double p_s) {
if (is_equal_approx(p_from, p_to)) {
return p_from;
}
- double x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0, 1.0);
- return x * x * (3.0 - 2.0 * x);
+ double s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0, 1.0);
+ return s * s * (3.0 - 2.0 * s);
}
- static _ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_weight) {
+ static _ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_s) {
if (is_equal_approx(p_from, p_to)) {
return p_from;
}
- float x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0f, 1.0f);
- return x * x * (3.0f - 2.0f * x);
+ float s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0f, 1.0f);
+ return s * s * (3.0f - 2.0f * s);
}
static _ALWAYS_INLINE_ double move_toward(double p_from, double p_to, double p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SGN(p_to - p_from) * p_delta; }
static _ALWAYS_INLINE_ float move_toward(float p_from, float p_to, float p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SGN(p_to - p_from) * p_delta; }
@@ -283,24 +284,12 @@ public:
static void randomize();
static uint32_t rand_from_seed(uint64_t *seed);
static uint32_t rand();
- static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_MAX; }
- static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_MAX; }
+ static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_32BIT_MAX; }
+ static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_32BIT_MAX; }
static double random(double from, double to);
static float random(float from, float to);
- static real_t random(int from, int to) { return (real_t)random((real_t)from, (real_t)to); }
-
- static _ALWAYS_INLINE_ bool is_equal_approx_ratio(real_t a, real_t b, real_t epsilon = CMP_EPSILON, real_t min_epsilon = CMP_EPSILON) {
- // this is an approximate way to check that numbers are close, as a ratio of their average size
- // helps compare approximate numbers that may be very big or very small
- real_t diff = abs(a - b);
- if (diff == 0.0 || diff < min_epsilon) {
- return true;
- }
- real_t avg_size = (abs(a) + abs(b)) / 2.0;
- diff /= avg_size;
- return diff < epsilon;
- }
+ static int random(int from, int to);
static _ALWAYS_INLINE_ bool is_equal_approx(real_t a, real_t b) {
// Check for exact equality first, required to handle "infinity" values.
diff --git a/core/math/octree.h b/core/math/octree.h
index 5d9688d442..be1e7d6a61 100644
--- a/core/math/octree.h
+++ b/core/math/octree.h
@@ -31,13 +31,13 @@
#ifndef OCTREE_H
#define OCTREE_H
-#include "core/list.h"
-#include "core/map.h"
#include "core/math/aabb.h"
#include "core/math/geometry_3d.h"
#include "core/math/vector3.h"
-#include "core/print_string.h"
-#include "core/variant.h"
+#include "core/string/print_string.h"
+#include "core/templates/list.h"
+#include "core/templates/map.h"
+#include "core/variant/variant.h"
typedef uint32_t OctreeElementID;
@@ -379,7 +379,6 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct
if (p_octant->aabb.size.x / OCTREE_DIVISOR < element_size) {
//if (p_octant->aabb.size.x*0.5 < element_size) {
-
/* at smallest possible size for the element */
typename Element::OctantOwner owner;
owner.octant = p_octant;
diff --git a/core/math/plane.cpp b/core/math/plane.cpp
index df37ceb0e5..e1ae3288ed 100644
--- a/core/math/plane.cpp
+++ b/core/math/plane.cpp
@@ -31,6 +31,7 @@
#include "plane.h"
#include "core/math/math_funcs.h"
+#include "core/variant/variant.h"
void Plane::set_normal(const Vector3 &p_normal) {
normal = p_normal;
@@ -52,10 +53,6 @@ Plane Plane::normalized() const {
return p;
}
-Vector3 Plane::get_any_point() const {
- return get_normal() * d;
-}
-
Vector3 Plane::get_any_perpendicular_normal() const {
static const Vector3 p1 = Vector3(1, 0, 0);
static const Vector3 p2 = Vector3(0, 1, 0);
@@ -142,6 +139,31 @@ bool Plane::intersects_segment(const Vector3 &p_begin, const Vector3 &p_end, Vec
return true;
}
+Variant Plane::intersect_3_bind(const Plane &p_plane1, const Plane &p_plane2) const {
+ Vector3 inters;
+ if (intersect_3(p_plane1, p_plane2, &inters)) {
+ return inters;
+ } else {
+ return Variant();
+ }
+}
+Variant Plane::intersects_ray_bind(const Vector3 &p_from, const Vector3 &p_dir) const {
+ Vector3 inters;
+ if (intersects_ray(p_from, p_dir, &inters)) {
+ return inters;
+ } else {
+ return Variant();
+ }
+}
+Variant Plane::intersects_segment_bind(const Vector3 &p_begin, const Vector3 &p_end) const {
+ Vector3 inters;
+ if (intersects_segment(p_begin, p_end, &inters)) {
+ return inters;
+ } else {
+ return Variant();
+ }
+}
+
/* misc */
bool Plane::is_equal_approx_any_side(const Plane &p_plane) const {
diff --git a/core/math/plane.h b/core/math/plane.h
index 9a3e5a485f..1386b0a2cb 100644
--- a/core/math/plane.h
+++ b/core/math/plane.h
@@ -33,6 +33,8 @@
#include "core/math/vector3.h"
+class Variant;
+
class Plane {
public:
Vector3 normal;
@@ -47,7 +49,6 @@ public:
/* Plane-Point operations */
_FORCE_INLINE_ Vector3 center() const { return normal * d; }
- Vector3 get_any_point() const;
Vector3 get_any_perpendicular_normal() const;
_FORCE_INLINE_ bool is_point_over(const Vector3 &p_point) const; ///< Point is over plane
@@ -60,6 +61,11 @@ public:
bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *p_intersection) const;
bool intersects_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 *p_intersection) const;
+ // For Variant bindings.
+ Variant intersect_3_bind(const Plane &p_plane1, const Plane &p_plane2) const;
+ Variant intersects_ray_bind(const Vector3 &p_from, const Vector3 &p_dir) const;
+ Variant intersects_segment_bind(const Vector3 &p_begin, const Vector3 &p_end) const;
+
_FORCE_INLINE_ Vector3 project(const Vector3 &p_point) const {
return p_point - normal * distance_to(p_point);
}
diff --git a/core/math/quat.cpp b/core/math/quat.cpp
index c10f5da494..b6a017dd41 100644
--- a/core/math/quat.cpp
+++ b/core/math/quat.cpp
@@ -31,7 +31,7 @@
#include "quat.h"
#include "core/math/basis.h"
-#include "core/print_string.h"
+#include "core/string/print_string.h"
// set_euler_xyz expects a vector containing the Euler angles in the format
// (ax,ay,az), where ax is the angle of rotation around x axis,
diff --git a/core/math/quat.h b/core/math/quat.h
index 64d0f00912..f8ab537d7b 100644
--- a/core/math/quat.h
+++ b/core/math/quat.h
@@ -36,12 +36,26 @@
#include "core/math/math_defs.h"
#include "core/math/math_funcs.h"
-#include "core/ustring.h"
+#include "core/string/ustring.h"
class Quat {
public:
- real_t x = 0, y = 0, z = 0, w = 1;
-
+ union {
+ struct {
+ real_t x;
+ real_t y;
+ real_t z;
+ real_t w;
+ };
+ real_t components[4] = { 0, 0, 0, 1.0 };
+ };
+
+ _FORCE_INLINE_ real_t &operator[](int idx) {
+ return components[idx];
+ }
+ _FORCE_INLINE_ const real_t &operator[](int idx) const {
+ return components[idx];
+ }
_FORCE_INLINE_ real_t length_squared() const;
bool is_equal_approx(const Quat &p_quat) const;
real_t length() const;
@@ -91,6 +105,10 @@ public:
return v + ((uv * w) + u.cross(uv)) * ((real_t)2);
}
+ _FORCE_INLINE_ Vector3 xform_inv(const Vector3 &v) const {
+ return inverse().xform(v);
+ }
+
_FORCE_INLINE_ void operator+=(const Quat &q);
_FORCE_INLINE_ void operator-=(const Quat &q);
_FORCE_INLINE_ void operator*=(const real_t &s);
@@ -130,7 +148,7 @@ public:
w(q.w) {
}
- Quat operator=(const Quat &q) {
+ Quat &operator=(const Quat &q) {
x = q.x;
y = q.y;
z = q.z;
@@ -224,4 +242,8 @@ bool Quat::operator!=(const Quat &p_quat) const {
return x != p_quat.x || y != p_quat.y || z != p_quat.z || w != p_quat.w;
}
+_FORCE_INLINE_ Quat operator*(const real_t &p_real, const Quat &p_quat) {
+ return p_quat * p_real;
+}
+
#endif // QUAT_H
diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp
index 8ba1ba9286..8dff13c050 100644
--- a/core/math/quick_hull.cpp
+++ b/core/math/quick_hull.cpp
@@ -30,7 +30,7 @@
#include "quick_hull.h"
-#include "core/map.h"
+#include "core/templates/map.h"
uint32_t QuickHull::debug_stop_after = 0xFFFFFFFF;
diff --git a/core/math/quick_hull.h b/core/math/quick_hull.h
index cac8e58d23..024325c4fc 100644
--- a/core/math/quick_hull.h
+++ b/core/math/quick_hull.h
@@ -31,17 +31,17 @@
#ifndef QUICK_HULL_H
#define QUICK_HULL_H
-#include "core/list.h"
#include "core/math/aabb.h"
#include "core/math/geometry_3d.h"
-#include "core/set.h"
+#include "core/templates/list.h"
+#include "core/templates/set.h"
class QuickHull {
public:
struct Edge {
union {
uint32_t vertices[2];
- uint64_t id;
+ uint64_t id = 0;
};
bool operator<(const Edge &p_edge) const {
@@ -60,7 +60,7 @@ public:
struct Face {
Plane plane;
- uint32_t vertices[3];
+ uint32_t vertices[3] = { 0 };
Vector<int> points_over;
bool operator<(const Face &p_face) const {
@@ -70,11 +70,13 @@ public:
private:
struct FaceConnect {
- List<Face>::Element *left, *right = nullptr;
+ List<Face>::Element *left = nullptr;
+ List<Face>::Element *right = nullptr;
FaceConnect() {}
};
struct RetFaceConnect {
- List<Geometry3D::MeshData::Face>::Element *left, *right = nullptr;
+ List<Geometry3D::MeshData::Face>::Element *left = nullptr;
+ List<Geometry3D::MeshData::Face>::Element *right = nullptr;
RetFaceConnect() {}
};
diff --git a/core/math/random_number_generator.cpp b/core/math/random_number_generator.cpp
index 67f4c0b14a..a124f63030 100644
--- a/core/math/random_number_generator.cpp
+++ b/core/math/random_number_generator.cpp
@@ -33,7 +33,6 @@
void RandomNumberGenerator::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_seed", "seed"), &RandomNumberGenerator::set_seed);
ClassDB::bind_method(D_METHOD("get_seed"), &RandomNumberGenerator::get_seed);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
ClassDB::bind_method(D_METHOD("randi"), &RandomNumberGenerator::randi);
ClassDB::bind_method(D_METHOD("randf"), &RandomNumberGenerator::randf);
@@ -41,4 +40,8 @@ void RandomNumberGenerator::_bind_methods() {
ClassDB::bind_method(D_METHOD("randf_range", "from", "to"), &RandomNumberGenerator::randf_range);
ClassDB::bind_method(D_METHOD("randi_range", "from", "to"), &RandomNumberGenerator::randi_range);
ClassDB::bind_method(D_METHOD("randomize"), &RandomNumberGenerator::randomize);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
+ // Default value is non-deterministic, override it for doc generation purposes.
+ ADD_PROPERTY_DEFAULT("seed", 0);
}
diff --git a/core/math/random_number_generator.h b/core/math/random_number_generator.h
index 920308e597..0d0ea17205 100644
--- a/core/math/random_number_generator.h
+++ b/core/math/random_number_generator.h
@@ -32,18 +32,18 @@
#define RANDOM_NUMBER_GENERATOR_H
#include "core/math/random_pcg.h"
-#include "core/reference.h"
+#include "core/object/reference.h"
class RandomNumberGenerator : public Reference {
GDCLASS(RandomNumberGenerator, Reference);
+protected:
RandomPCG randbase;
-protected:
static void _bind_methods();
public:
- _FORCE_INLINE_ void set_seed(uint64_t seed) { randbase.seed(seed); }
+ _FORCE_INLINE_ void set_seed(uint64_t p_seed) { randbase.seed(p_seed); }
_FORCE_INLINE_ uint64_t get_seed() { return randbase.get_seed(); }
@@ -53,18 +53,11 @@ public:
_FORCE_INLINE_ real_t randf() { return randbase.randf(); }
- _FORCE_INLINE_ real_t randf_range(real_t from, real_t to) { return randbase.random(from, to); }
+ _FORCE_INLINE_ real_t randf_range(real_t p_from, real_t p_to) { return randbase.random(p_from, p_to); }
- _FORCE_INLINE_ real_t randfn(real_t mean = 0.0, real_t deviation = 1.0) { return randbase.randfn(mean, deviation); }
+ _FORCE_INLINE_ real_t randfn(real_t p_mean = 0.0, real_t p_deviation = 1.0) { return randbase.randfn(p_mean, p_deviation); }
- _FORCE_INLINE_ int randi_range(int from, int to) {
- unsigned int ret = randbase.rand();
- if (to < from) {
- return ret % (from - to + 1) + to;
- } else {
- return ret % (to - from + 1) + from;
- }
- }
+ _FORCE_INLINE_ int randi_range(int p_from, int p_to) { return randbase.random(p_from, p_to); }
RandomNumberGenerator() {}
};
diff --git a/core/math/random_pcg.cpp b/core/math/random_pcg.cpp
index 02257c38d9..e0768b9403 100644
--- a/core/math/random_pcg.cpp
+++ b/core/math/random_pcg.cpp
@@ -49,3 +49,18 @@ double RandomPCG::random(double p_from, double p_to) {
float RandomPCG::random(float p_from, float p_to) {
return randf() * (p_to - p_from) + p_from;
}
+
+int RandomPCG::random(int p_from, int p_to) {
+ int range;
+ int min;
+ if (p_to > p_from) {
+ range = p_to - p_from + 1;
+ min = p_from;
+ } else if (p_to < p_from) {
+ range = p_from - p_to + 1;
+ min = p_to;
+ } else { // from == to
+ return p_from;
+ }
+ return rand(range) + min;
+}
diff --git a/core/math/random_pcg.h b/core/math/random_pcg.h
index 8fd5a056fa..fe6b1b5639 100644
--- a/core/math/random_pcg.h
+++ b/core/math/random_pcg.h
@@ -31,12 +31,12 @@
#ifndef RANDOM_PCG_H
#define RANDOM_PCG_H
-#include <math.h>
-
#include "core/math/math_defs.h"
#include "thirdparty/misc/pcg.h"
+#include <math.h>
+
#if defined(__GNUC__)
#define CLZ32(x) __builtin_clz(x)
#elif defined(_MSC_VER)
@@ -67,7 +67,6 @@ class RandomPCG {
public:
static const uint64_t DEFAULT_SEED = 12047754176567800795U;
static const uint64_t DEFAULT_INC = PCG_DEFAULT_INC_64;
- static const uint64_t RANDOM_MAX = 0xFFFFFFFF;
RandomPCG(uint64_t p_seed = DEFAULT_SEED, uint64_t p_inc = DEFAULT_INC);
@@ -82,6 +81,10 @@ public:
current_seed = pcg.state;
return pcg32_random_r(&pcg);
}
+ _FORCE_INLINE_ uint32_t rand(uint32_t bounds) {
+ current_seed = pcg.state;
+ return pcg32_boundedrand_r(&pcg, bounds);
+ }
// Obtaining floating point numbers in [0, 1] range with "good enough" uniformity.
// These functions sample the output of rand() as the fraction part of an infinite binary number,
@@ -130,7 +133,7 @@ public:
double random(double p_from, double p_to);
float random(float p_from, float p_to);
- real_t random(int p_from, int p_to) { return (real_t)random((real_t)p_from, (real_t)p_to); }
+ int random(int p_from, int p_to);
};
#endif // RANDOM_PCG_H
diff --git a/core/math/rect2.h b/core/math/rect2.h
index 14393325ec..b1fe865ba5 100644
--- a/core/math/rect2.h
+++ b/core/math/rect2.h
@@ -197,6 +197,10 @@ struct Rect2 {
return g;
}
+ inline Rect2 grow_margin_bind(uint32_t p_margin, real_t p_amount) const {
+ return grow_margin(Margin(p_margin), p_amount);
+ }
+
inline Rect2 grow_individual(real_t p_left, real_t p_top, real_t p_right, real_t p_bottom) const {
Rect2 g = *this;
g.position.x -= p_left;
@@ -240,6 +244,77 @@ struct Rect2 {
return Rect2(Point2(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs());
}
+ Vector2 get_support(const Vector2 &p_normal) const {
+ Vector2 half_extents = size * 0.5;
+ Vector2 ofs = position + half_extents;
+ return Vector2(
+ (p_normal.x > 0) ? -half_extents.x : half_extents.x,
+ (p_normal.y > 0) ? -half_extents.y : half_extents.y) +
+ ofs;
+ }
+
+ _FORCE_INLINE_ bool intersects_filled_polygon(const Vector2 *p_points, int p_point_count) const {
+ Vector2 center = position + size * 0.5;
+ int side_plus = 0;
+ int side_minus = 0;
+ Vector2 end = position + size;
+
+ int i_f = p_point_count - 1;
+ for (int i = 0; i < p_point_count; i++) {
+ const Vector2 &a = p_points[i_f];
+ const Vector2 &b = p_points[i];
+ i_f = i;
+
+ Vector2 r = (b - a);
+ float l = r.length();
+ if (l == 0.0) {
+ continue;
+ }
+
+ //check inside
+ Vector2 tg = r.tangent();
+ float s = tg.dot(center) - tg.dot(a);
+ if (s < 0.0) {
+ side_plus++;
+ } else {
+ side_minus++;
+ }
+
+ //check ray box
+ r /= l;
+ Vector2 ir(1.0 / r.x, 1.0 / r.y);
+
+ // lb is the corner of AABB with minimal coordinates - left bottom, rt is maximal corner
+ // r.org is origin of ray
+ Vector2 t13 = (position - a) * ir;
+ Vector2 t24 = (end - a) * ir;
+
+ float tmin = MAX(MIN(t13.x, t24.x), MIN(t13.y, t24.y));
+ float tmax = MIN(MAX(t13.x, t24.x), MAX(t13.y, t24.y));
+
+ // if tmax < 0, ray (line) is intersecting AABB, but the whole AABB is behind us
+ if (tmax < 0 || tmin > tmax || tmin >= l) {
+ continue;
+ }
+
+ return true;
+ }
+
+ if (side_plus * side_minus == 0) {
+ return true; //all inside
+ } else {
+ return false;
+ }
+ }
+
+ _FORCE_INLINE_ void set_end(const Vector2 &p_end) {
+ size = p_end - position;
+ }
+
+ _FORCE_INLINE_ Vector2 get_end() const {
+ return position + size;
+ }
+
operator String() const { return String(position) + ", " + String(size); }
Rect2() {}
@@ -301,8 +376,8 @@ struct Rect2i {
new_rect.position.x = MAX(p_rect.position.x, position.x);
new_rect.position.y = MAX(p_rect.position.y, position.y);
- Point2 p_rect_end = p_rect.position + p_rect.size;
- Point2 end = position + size;
+ 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);
@@ -324,7 +399,7 @@ struct Rect2i {
return new_rect;
}
- bool has_point(const Point2 &p_point) const {
+ bool has_point(const Point2i &p_point) const {
if (p_point.x < position.x) {
return false;
}
@@ -363,6 +438,10 @@ struct Rect2i {
return g;
}
+ inline Rect2i grow_margin_bind(uint32_t p_margin, int p_amount) const {
+ return grow_margin(Margin(p_margin), 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;
@@ -405,6 +484,14 @@ struct Rect2i {
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 { return String(position) + ", " + String(size); }
operator Rect2() const { return Rect2(position, size); }
@@ -415,10 +502,10 @@ struct Rect2i {
size(p_r2.size) {
}
Rect2i(int p_x, int p_y, int p_width, int p_height) :
- position(Point2(p_x, p_y)),
- size(Size2(p_width, p_height)) {
+ position(Point2i(p_x, p_y)),
+ size(Size2i(p_width, p_height)) {
}
- Rect2i(const Point2 &p_pos, const Size2 &p_size) :
+ Rect2i(const Point2i &p_pos, const Size2i &p_size) :
position(p_pos),
size(p_size) {
}
diff --git a/core/math/transform.cpp b/core/math/transform.cpp
index 0274dd18af..733bb4d55e 100644
--- a/core/math/transform.cpp
+++ b/core/math/transform.cpp
@@ -32,7 +32,7 @@
#include "core/math/math_funcs.h"
#include "core/os/copymem.h"
-#include "core/print_string.h"
+#include "core/string/print_string.h"
void Transform::affine_invert() {
basis.invert();
@@ -200,6 +200,13 @@ Transform::Transform(const Basis &p_basis, const Vector3 &p_origin) :
origin(p_origin) {
}
+Transform::Transform(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin) :
+ origin(p_origin) {
+ basis.set_axis(0, p_x);
+ basis.set_axis(1, p_y);
+ basis.set_axis(2, p_z);
+}
+
Transform::Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz) {
basis = Basis(xx, xy, xz, yx, yy, yz, zx, zy, zz);
origin = Vector3(ox, oy, oz);
diff --git a/core/math/transform.h b/core/math/transform.h
index 71847d36ac..c63dbcb989 100644
--- a/core/math/transform.h
+++ b/core/math/transform.h
@@ -106,9 +106,10 @@ public:
operator String() const;
- Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz);
- Transform(const Basis &p_basis, const Vector3 &p_origin = Vector3());
Transform() {}
+ Transform(const Basis &p_basis, const Vector3 &p_origin = Vector3());
+ Transform(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin);
+ Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz);
};
_FORCE_INLINE_ Vector3 Transform::xform(const Vector3 &p_vector) const {
diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp
index 180aeaa0af..00e561f973 100644
--- a/core/math/transform_2d.cpp
+++ b/core/math/transform_2d.cpp
@@ -251,7 +251,7 @@ Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, real_t
real_t dot = v1.dot(v2);
- dot = (dot < -1.0) ? -1.0 : ((dot > 1.0) ? 1.0 : dot); //clamp dot to [-1,1]
+ dot = CLAMP(dot, -1.0, 1.0);
Vector2 v;
diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h
index 46e97abaa7..342623939e 100644
--- a/core/math/transform_2d.h
+++ b/core/math/transform_2d.h
@@ -128,6 +128,12 @@ struct Transform2D {
elements[2][1] = oy;
}
+ Transform2D(const Vector2 &p_x, const Vector2 &p_y, const Vector2 &p_origin) {
+ elements[0] = p_x;
+ elements[1] = p_y;
+ elements[2] = p_origin;
+ }
+
Transform2D(real_t p_rot, const Vector2 &p_pos);
Transform2D() {
elements[0][0] = 1.0;
diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp
index c9a546e385..cfe8422d80 100644
--- a/core/math/triangle_mesh.cpp
+++ b/core/math/triangle_mesh.cpp
@@ -30,7 +30,7 @@
#include "triangle_mesh.h"
-#include "core/sort_array.h"
+#include "core/templates/sort_array.h"
int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc) {
if (p_depth > max_depth) {
diff --git a/core/math/triangle_mesh.h b/core/math/triangle_mesh.h
index 86412cf725..d719822ec3 100644
--- a/core/math/triangle_mesh.h
+++ b/core/math/triangle_mesh.h
@@ -32,7 +32,7 @@
#define TRIANGLE_MESH_H
#include "core/math/face3.h"
-#include "core/reference.h"
+#include "core/object/reference.h"
class TriangleMesh : public Reference {
GDCLASS(TriangleMesh, Reference);
diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp
index 233421e070..75e742a5f1 100644
--- a/core/math/vector2.cpp
+++ b/core/math/vector2.cpp
@@ -233,6 +233,19 @@ void Vector2i::operator/=(const int &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 int &rvalue) const {
+ return Vector2i(x % rvalue, y % rvalue);
+}
+
+void Vector2i::operator%=(const int &rvalue) {
+ x %= rvalue;
+ y %= rvalue;
+}
+
Vector2i Vector2i::operator-() const {
return Vector2i(-x, -y);
}
diff --git a/core/math/vector2.h b/core/math/vector2.h
index 8a08d3bf64..8cb63b2fb5 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -32,7 +32,7 @@
#define VECTOR2_H
#include "core/math/math_funcs.h"
-#include "core/ustring.h"
+#include "core/string/ustring.h"
struct Vector2i;
@@ -65,6 +65,14 @@ struct Vector2 {
real_t length() const;
real_t length_squared() const;
+ Vector2 min(const Vector2 &p_vector2) const {
+ return Vector2(MIN(x, p_vector2.x), MIN(y, p_vector2.y));
+ }
+
+ Vector2 max(const Vector2 &p_vector2) const {
+ return Vector2(MAX(x, p_vector2.x), MAX(y, p_vector2.y));
+ }
+
real_t distance_to(const Vector2 &p_vector2) const;
real_t distance_squared_to(const Vector2 &p_vector2) const;
real_t angle_to(const Vector2 &p_vector2) const;
@@ -114,10 +122,10 @@ struct Vector2 {
bool operator==(const Vector2 &p_vec2) const;
bool operator!=(const Vector2 &p_vec2) const;
- bool operator<(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); }
- bool operator>(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); }
- bool operator<=(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y <= p_vec2.y) : (x < p_vec2.x); }
- bool operator>=(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y >= p_vec2.y) : (x > p_vec2.x); }
+ bool operator<(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y < p_vec2.y) : (x < p_vec2.x); }
+ bool operator>(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y > p_vec2.y) : (x > p_vec2.x); }
+ bool operator<=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); }
+ bool operator>=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); }
real_t angle() const;
@@ -150,7 +158,19 @@ _FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2 &p_vec)
return p_vec - *this * (dot(p_vec) - p_d);
}
-_FORCE_INLINE_ Vector2 operator*(real_t p_scalar, const Vector2 &p_vec) {
+_FORCE_INLINE_ Vector2 operator*(float p_scalar, const Vector2 &p_vec) {
+ return p_vec * p_scalar;
+}
+
+_FORCE_INLINE_ Vector2 operator*(double p_scalar, const Vector2 &p_vec) {
+ return p_vec * p_scalar;
+}
+
+_FORCE_INLINE_ Vector2 operator*(int32_t p_scalar, const Vector2 &p_vec) {
+ return p_vec * p_scalar;
+}
+
+_FORCE_INLINE_ Vector2 operator*(int64_t p_scalar, const Vector2 &p_vec) {
return p_vec * p_scalar;
}
@@ -270,11 +290,13 @@ struct Vector2i {
void operator*=(const int &rvalue);
Vector2i operator/(const Vector2i &p_v1) const;
-
Vector2i operator/(const int &rvalue) const;
-
void operator/=(const int &rvalue);
+ Vector2i operator%(const Vector2i &p_v1) const;
+ Vector2i operator%(const int &rvalue) const;
+ void operator%=(const int &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); }
@@ -304,6 +326,22 @@ struct Vector2i {
}
};
+_FORCE_INLINE_ Vector2i operator*(const int32_t &p_scalar, const Vector2i &p_vector) {
+ return p_vector * p_scalar;
+}
+
+_FORCE_INLINE_ Vector2i operator*(const int64_t &p_scalar, const Vector2i &p_vector) {
+ return p_vector * p_scalar;
+}
+
+_FORCE_INLINE_ Vector2i operator*(const float &p_scalar, const Vector2i &p_vector) {
+ return p_vector * p_scalar;
+}
+
+_FORCE_INLINE_ Vector2i operator*(const double &p_scalar, const Vector2i &p_vector) {
+ return p_vector * p_scalar;
+}
+
typedef Vector2i Size2i;
typedef Vector2i Point2i;
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 0bc1a467f2..ae8b9376cf 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -33,7 +33,7 @@
#include "core/math/math_funcs.h"
#include "core/math/vector3i.h"
-#include "core/ustring.h"
+#include "core/string/ustring.h"
class Basis;
@@ -322,8 +322,8 @@ bool Vector3::operator!=(const Vector3 &p_v) const {
}
bool Vector3::operator<(const Vector3 &p_v) const {
- if (Math::is_equal_approx(x, p_v.x)) {
- if (Math::is_equal_approx(y, p_v.y)) {
+ if (x == p_v.x) {
+ if (y == p_v.y) {
return z < p_v.z;
} else {
return y < p_v.y;
@@ -334,8 +334,8 @@ bool Vector3::operator<(const Vector3 &p_v) const {
}
bool Vector3::operator>(const Vector3 &p_v) const {
- if (Math::is_equal_approx(x, p_v.x)) {
- if (Math::is_equal_approx(y, p_v.y)) {
+ if (x == p_v.x) {
+ if (y == p_v.y) {
return z > p_v.z;
} else {
return y > p_v.y;
@@ -346,8 +346,8 @@ bool Vector3::operator>(const Vector3 &p_v) const {
}
bool Vector3::operator<=(const Vector3 &p_v) const {
- if (Math::is_equal_approx(x, p_v.x)) {
- if (Math::is_equal_approx(y, p_v.y)) {
+ if (x == p_v.x) {
+ if (y == p_v.y) {
return z <= p_v.z;
} else {
return y < p_v.y;
@@ -358,8 +358,8 @@ bool Vector3::operator<=(const Vector3 &p_v) const {
}
bool Vector3::operator>=(const Vector3 &p_v) const {
- if (Math::is_equal_approx(x, p_v.x)) {
- if (Math::is_equal_approx(y, p_v.y)) {
+ if (x == p_v.x) {
+ if (y == p_v.y) {
return z >= p_v.z;
} else {
return y > p_v.y;
diff --git a/core/math/vector3i.h b/core/math/vector3i.h
index 08729ad056..1bfd6d5ab2 100644
--- a/core/math/vector3i.h
+++ b/core/math/vector3i.h
@@ -31,8 +31,8 @@
#ifndef VECTOR3I_H
#define VECTOR3I_H
+#include "core/string/ustring.h"
#include "core/typedefs.h"
-#include "core/ustring.h"
struct Vector3i {
enum Axis {
@@ -80,11 +80,15 @@ struct Vector3i {
_FORCE_INLINE_ Vector3i operator*(const Vector3i &p_v) const;
_FORCE_INLINE_ Vector3i &operator/=(const Vector3i &p_v);
_FORCE_INLINE_ Vector3i operator/(const Vector3i &p_v) const;
+ _FORCE_INLINE_ Vector3i &operator%=(const Vector3i &p_v);
+ _FORCE_INLINE_ Vector3i operator%(const Vector3i &p_v) const;
_FORCE_INLINE_ Vector3i &operator*=(int32_t p_scalar);
_FORCE_INLINE_ Vector3i operator*(int32_t p_scalar) const;
_FORCE_INLINE_ Vector3i &operator/=(int32_t p_scalar);
_FORCE_INLINE_ Vector3i operator/(int32_t p_scalar) const;
+ _FORCE_INLINE_ Vector3i &operator%=(int32_t p_scalar);
+ _FORCE_INLINE_ Vector3i operator%(int32_t p_scalar) const;
_FORCE_INLINE_ Vector3i operator-() const;
@@ -159,6 +163,17 @@ Vector3i Vector3i::operator/(const Vector3i &p_v) const {
return Vector3i(x / p_v.x, y / p_v.y, z / p_v.z);
}
+Vector3i &Vector3i::operator%=(const Vector3i &p_v) {
+ x %= p_v.x;
+ y %= p_v.y;
+ z %= p_v.z;
+ return *this;
+}
+
+Vector3i Vector3i::operator%(const Vector3i &p_v) const {
+ return Vector3i(x % p_v.x, y % p_v.y, z % p_v.z);
+}
+
Vector3i &Vector3i::operator*=(int32_t p_scalar) {
x *= p_scalar;
y *= p_scalar;
@@ -185,6 +200,17 @@ Vector3i Vector3i::operator/(int32_t p_scalar) const {
return Vector3i(x / p_scalar, y / p_scalar, z / p_scalar);
}
+Vector3i &Vector3i::operator%=(int32_t p_scalar) {
+ x %= p_scalar;
+ y %= p_scalar;
+ z %= p_scalar;
+ return *this;
+}
+
+Vector3i Vector3i::operator%(int32_t p_scalar) const {
+ return Vector3i(x % p_scalar, y % p_scalar, z % p_scalar);
+}
+
Vector3i Vector3i::operator-() const {
return Vector3i(-x, -y, -z);
}