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.h4
-rw-r--r--core/math/aabb.cpp4
-rw-r--r--core/math/aabb.h8
-rw-r--r--core/math/basis.cpp2
-rw-r--r--core/math/camera_matrix.cpp2
-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.cpp745
-rw-r--r--core/math/expression.h84
-rw-r--r--core/math/geometry_2d.h4
-rw-r--r--core/math/geometry_3d.cpp2
-rw-r--r--core/math/geometry_3d.h4
-rw-r--r--core/math/math_fieldwise.h2
-rw-r--r--core/math/math_funcs.cpp8
-rw-r--r--core/math/math_funcs.h2
-rw-r--r--core/math/octree.h8
-rw-r--r--core/math/plane.cpp2
-rw-r--r--core/math/quat.cpp2
-rw-r--r--core/math/quat.h24
-rw-r--r--core/math/quick_hull.cpp2
-rw-r--r--core/math/quick_hull.h4
-rw-r--r--core/math/random_number_generator.cpp5
-rw-r--r--core/math/random_number_generator.h17
-rw-r--r--core/math/random_pcg.cpp15
-rw-r--r--core/math/random_pcg.h6
-rw-r--r--core/math/rect2.h91
-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.h8
-rw-r--r--core/math/vector3.h2
-rw-r--r--core/math/vector3i.h28
40 files changed, 1275 insertions, 875 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..a6fa771b30 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
diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp
index e868ebc7c8..08673d0dd1 100644
--- a/core/math/aabb.cpp
+++ b/core/math/aabb.cpp
@@ -30,8 +30,8 @@
#include "aabb.h"
-#include "core/print_string.h"
-#include "core/variant.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;
diff --git a/core/math/aabb.h b/core/math/aabb.h
index 8c08754e1c..45dcbc7f7f 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -107,6 +107,14 @@ public:
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/basis.cpp b/core/math/basis.cpp
index a712ae7e3e..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])
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index c154d57a13..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] -
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 1040f9e0e4..d1f15caa5e 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -30,714 +30,12 @@
#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;
-}
-
-#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: {
- char32_t 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: {
- }
- }
-}
-
-////////
+#include "core/variant/variant_parser.h"
static bool _is_number(char32_t c) {
return (c >= '0' && c <= '9');
@@ -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 f2cfe6b1a6..d9cedb8c2c 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;
@@ -315,7 +235,7 @@ private:
};
struct BuiltinFuncNode : public ENode {
- BuiltinFunc func;
+ StringName func;
Vector<ENode *> arguments;
BuiltinFuncNode() {
type = TYPE_BUILTIN_FUNC;
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 2c19fe2085..56353de783 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"
diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h
index 11cac8f108..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();
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 f83ee44f4a..827637bf2b 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -289,7 +289,7 @@ public:
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 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..40201f99b1 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;
diff --git a/core/math/plane.cpp b/core/math/plane.cpp
index ae2021d2f6..e1ae3288ed 100644
--- a/core/math/plane.cpp
+++ b/core/math/plane.cpp
@@ -31,7 +31,7 @@
#include "plane.h"
#include "core/math/math_funcs.h"
-#include "core/variant.h"
+#include "core/variant/variant.h"
void Plane::set_normal(const Vector3 &p_normal) {
normal = p_normal;
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 3152b7d233..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);
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..80f32e191b 100644
--- a/core/math/quick_hull.h
+++ b/core/math/quick_hull.h
@@ -31,10 +31,10 @@
#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:
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 416e52ea87..0d0ea17205 100644
--- a/core/math/random_number_generator.h
+++ b/core/math/random_number_generator.h
@@ -32,7 +32,7 @@
#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);
@@ -43,7 +43,7 @@ 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 09b13ab74d..fe6b1b5639 100644
--- a/core/math/random_pcg.h
+++ b/core/math/random_pcg.h
@@ -81,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,
@@ -129,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 7660db71eb..b1fe865ba5 100644
--- a/core/math/rect2.h
+++ b/core/math/rect2.h
@@ -244,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() {}
@@ -305,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);
@@ -328,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;
}
@@ -413,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); }
@@ -423,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 c2a2656e72..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;
@@ -290,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); }
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 5370b297f1..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;
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);
}