summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/SCsub1
-rw-r--r--core/class_db.cpp9
-rw-r--r--core/color.cpp3
-rw-r--r--core/color_names.inc3
-rw-r--r--core/command_queue_mt.h24
-rw-r--r--core/container_type_validate.h30
-rw-r--r--core/error_macros.h36
-rw-r--r--core/image.cpp509
-rw-r--r--core/image.h2
-rw-r--r--core/input/godotcontrollerdb.txt3
-rw-r--r--core/io/file_access_pack.cpp3
-rw-r--r--core/io/ip_address.h12
-rw-r--r--core/io/json.cpp35
-rw-r--r--core/io/logger.cpp20
-rw-r--r--core/io/marshalls.h3
-rw-r--r--core/io/multiplayer_api.cpp8
-rw-r--r--core/io/resource_format_binary.cpp24
-rw-r--r--core/io/resource_format_binary.h2
-rw-r--r--core/io/resource_importer.cpp2
-rw-r--r--core/io/resource_loader.h6
-rw-r--r--core/list.h3
-rw-r--r--core/local_vector.h246
-rw-r--r--core/math/a_star.cpp24
-rw-r--r--core/math/aabb.h24
-rw-r--r--core/math/basis.cpp114
-rw-r--r--core/math/basis.h1
-rw-r--r--core/math/camera_matrix.cpp25
-rw-r--r--core/math/camera_matrix.h1
-rw-r--r--core/math/delaunay_2d.h (renamed from core/math/delaunay.h)10
-rw-r--r--core/math/delaunay_3d.h387
-rw-r--r--core/math/expression.cpp180
-rw-r--r--core/math/geometry.cpp246
-rw-r--r--core/math/geometry.h270
-rw-r--r--core/math/math_funcs.h6
-rw-r--r--core/math/plane.cpp4
-rw-r--r--core/math/plane.h1
-rw-r--r--core/math/quat.cpp3
-rw-r--r--core/math/triangle_mesh.cpp15
-rw-r--r--core/math/triangulate.cpp21
-rw-r--r--core/method_bind.h3
-rw-r--r--core/node_path.cpp3
-rw-r--r--core/object.cpp3
-rw-r--r--core/object.h3
-rw-r--r--core/os/dir_access.cpp21
-rw-r--r--core/os/dir_access.h3
-rw-r--r--core/os/file_access.cpp3
-rw-r--r--core/os/file_access.h3
-rw-r--r--core/os/memory.h7
-rw-r--r--core/os/rw_lock.h12
-rw-r--r--core/pool_allocator.cpp3
-rw-r--r--core/register_core_types.cpp4
-rw-r--r--core/self_list.h4
-rw-r--r--core/translation.cpp3
-rw-r--r--core/typed_array.cpp30
-rw-r--r--core/typed_array.h30
-rw-r--r--core/ustring.cpp30
-rw-r--r--core/ustring.h2
-rw-r--r--core/variant.cpp295
-rw-r--r--core/variant.h3
-rw-r--r--core/variant_call.cpp204
-rw-r--r--core/variant_op.cpp333
-rw-r--r--core/variant_parser.cpp20
-rw-r--r--core/vector.h11
63 files changed, 2721 insertions, 628 deletions
diff --git a/core/SCsub b/core/SCsub
index 0ab4f11d87..d53988fae7 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -49,6 +49,7 @@ thirdparty_misc_dir = "#thirdparty/misc/"
thirdparty_misc_sources = [
# C sources
"fastlz.c",
+ "r128.c",
"smaz.c",
# C++ sources
"hq2x.cpp",
diff --git a/core/class_db.cpp b/core/class_db.cpp
index 5e49688e9b..ee93ac73ae 100644
--- a/core/class_db.cpp
+++ b/core/class_db.cpp
@@ -1456,16 +1456,19 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con
}
if (!default_values.has(p_class)) {
- if (r_valid != nullptr) *r_valid = false;
+ if (r_valid != nullptr)
+ *r_valid = false;
return Variant();
}
if (!default_values[p_class].has(p_property)) {
- if (r_valid != nullptr) *r_valid = false;
+ if (r_valid != nullptr)
+ *r_valid = false;
return Variant();
}
- if (r_valid != nullptr) *r_valid = true;
+ if (r_valid != nullptr)
+ *r_valid = true;
return default_values[p_class][p_property];
}
diff --git a/core/color.cpp b/core/color.cpp
index 03aeb2085b..79b9f70a99 100644
--- a/core/color.cpp
+++ b/core/color.cpp
@@ -406,7 +406,8 @@ bool Color::html_is_valid(const String &p_color) {
}
Color Color::named(const String &p_name) {
- if (_named_colors.empty()) _populate_named_colors(); // from color_names.inc
+ if (_named_colors.empty())
+ _populate_named_colors(); // from color_names.inc
String name = p_name;
// Normalize name
name = name.replace(" ", "");
diff --git a/core/color_names.inc b/core/color_names.inc
index 428a8473fe..f249ee9868 100644
--- a/core/color_names.inc
+++ b/core/color_names.inc
@@ -3,7 +3,8 @@
static Map<String, Color> _named_colors;
static void _populate_named_colors() {
- if (!_named_colors.empty()) return;
+ if (!_named_colors.empty())
+ return;
_named_colors.insert("aliceblue", Color(0.94, 0.97, 1.00));
_named_colors.insert("antiquewhite", Color(0.98, 0.92, 0.84));
_named_colors.insert("aqua", Color(0.00, 1.00, 1.00));
diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h
index 558453bdf5..2f2b3b783c 100644
--- a/core/command_queue_mt.h
+++ b/core/command_queue_mt.h
@@ -253,7 +253,8 @@
cmd->method = p_method; \
SEMIC_SEP_LIST(CMD_ASSIGN_PARAM, N); \
unlock(); \
- if (sync) sync->post(); \
+ if (sync) \
+ sync->post(); \
}
#define CMD_RET_TYPE(N) CommandRet##N<T, M, COMMA_SEP_LIST(TYPE_ARG, N) COMMA(N) R>
@@ -269,7 +270,8 @@
cmd->ret = r_ret; \
cmd->sync_sem = ss; \
unlock(); \
- if (sync) sync->post(); \
+ if (sync) \
+ sync->post(); \
ss->sem.wait(); \
ss->in_use = false; \
}
@@ -286,7 +288,8 @@
SEMIC_SEP_LIST(CMD_ASSIGN_PARAM, N); \
cmd->sync_sem = ss; \
unlock(); \
- if (sync) sync->post(); \
+ if (sync) \
+ sync->post(); \
ss->sem.wait(); \
ss->in_use = false; \
}
@@ -418,12 +421,14 @@ class CommandQueueMT {
}
bool flush_one(bool p_lock = true) {
- if (p_lock) lock();
+ if (p_lock)
+ lock();
tryagain:
// tried to read an empty queue
if (read_ptr == write_ptr) {
- if (p_lock) unlock();
+ if (p_lock)
+ unlock();
return false;
}
@@ -442,15 +447,18 @@ class CommandQueueMT {
read_ptr += size;
- if (p_lock) unlock();
+ if (p_lock)
+ unlock();
cmd->call();
- if (p_lock) lock();
+ if (p_lock)
+ lock();
cmd->post();
cmd->~CommandBase();
*(uint32_t *)&command_mem[size_ptr] &= ~1;
- if (p_lock) unlock();
+ if (p_lock)
+ unlock();
return true;
}
diff --git a/core/container_type_validate.h b/core/container_type_validate.h
index 3721668033..7809e5f385 100644
--- a/core/container_type_validate.h
+++ b/core/container_type_validate.h
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* container_type_validate.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 CONTAINER_TYPE_VALIDATE_H
#define CONTAINER_TYPE_VALIDATE_H
diff --git a/core/error_macros.h b/core/error_macros.h
index 18c46c9e7d..83f92129a5 100644
--- a/core/error_macros.h
+++ b/core/error_macros.h
@@ -530,19 +530,19 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* Prints `m_msg`.
*/
#define ERR_PRINT(m_msg) \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, DEBUG_STR(m_msg))
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg)
/**
* Prints `m_msg` once during the application lifetime.
*/
-#define ERR_PRINT_ONCE(m_msg) \
- if (1) { \
- static bool first_print = true; \
- if (first_print) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, DEBUG_STR(m_msg)); \
- first_print = false; \
- } \
- } else \
+#define ERR_PRINT_ONCE(m_msg) \
+ if (1) { \
+ static bool first_print = true; \
+ if (first_print) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg); \
+ first_print = false; \
+ } \
+ } else \
((void)0)
// Print warning message macros.
@@ -553,21 +553,21 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* If warning about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead.
*/
#define WARN_PRINT(m_msg) \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, DEBUG_STR(m_msg), ERR_HANDLER_WARNING)
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, ERR_HANDLER_WARNING)
/**
* Prints `m_msg` once during the application lifetime.
*
* If warning about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead.
*/
-#define WARN_PRINT_ONCE(m_msg) \
- if (1) { \
- static bool first_print = true; \
- if (first_print) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, DEBUG_STR(m_msg), ERR_HANDLER_WARNING); \
- first_print = false; \
- } \
- } else \
+#define WARN_PRINT_ONCE(m_msg) \
+ if (1) { \
+ static bool first_print = true; \
+ if (first_print) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, ERR_HANDLER_WARNING); \
+ first_print = false; \
+ } \
+ } else \
((void)0)
// Print deprecated warning message macros.
diff --git a/core/image.cpp b/core/image.cpp
index 58351ae2e5..ff8acc54af 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -114,23 +114,36 @@ int Image::get_format_pixel_size(Format p_format) {
return 1; //luminance
case FORMAT_LA8:
return 2; //luminance-alpha
- case FORMAT_R8: return 1;
- case FORMAT_RG8: return 2;
- case FORMAT_RGB8: return 3;
- case FORMAT_RGBA8: return 4;
- case FORMAT_RGBA4444: return 2;
- case FORMAT_RGB565: return 2;
+ case FORMAT_R8:
+ return 1;
+ case FORMAT_RG8:
+ return 2;
+ case FORMAT_RGB8:
+ return 3;
+ case FORMAT_RGBA8:
+ return 4;
+ case FORMAT_RGBA4444:
+ return 2;
+ case FORMAT_RGB565:
+ return 2;
case FORMAT_RF:
return 4; //float
- case FORMAT_RGF: return 8;
- case FORMAT_RGBF: return 12;
- case FORMAT_RGBAF: return 16;
+ case FORMAT_RGF:
+ return 8;
+ case FORMAT_RGBF:
+ return 12;
+ case FORMAT_RGBAF:
+ return 16;
case FORMAT_RH:
return 2; //half float
- case FORMAT_RGH: return 4;
- case FORMAT_RGBH: return 6;
- case FORMAT_RGBAH: return 8;
- case FORMAT_RGBE9995: return 4;
+ case FORMAT_RGH:
+ return 4;
+ case FORMAT_RGBH:
+ return 6;
+ case FORMAT_RGBAH:
+ return 8;
+ case FORMAT_RGBE9995:
+ return 4;
case FORMAT_DXT1:
return 1; //s3tc bc1
case FORMAT_DXT3:
@@ -149,22 +162,32 @@ int Image::get_format_pixel_size(Format p_format) {
return 1; //unsigned float
case FORMAT_PVRTC2:
return 1; //pvrtc
- case FORMAT_PVRTC2A: return 1;
- case FORMAT_PVRTC4: return 1;
- case FORMAT_PVRTC4A: return 1;
+ case FORMAT_PVRTC2A:
+ return 1;
+ case FORMAT_PVRTC4:
+ return 1;
+ case FORMAT_PVRTC4A:
+ return 1;
case FORMAT_ETC:
return 1; //etc1
case FORMAT_ETC2_R11:
return 1; //etc2
case FORMAT_ETC2_R11S:
return 1; //signed: return 1; NOT srgb.
- case FORMAT_ETC2_RG11: return 1;
- case FORMAT_ETC2_RG11S: return 1;
- case FORMAT_ETC2_RGB8: return 1;
- case FORMAT_ETC2_RGBA8: return 1;
- case FORMAT_ETC2_RGB8A1: return 1;
- case FORMAT_ETC2_RA_AS_RG: return 1;
- case FORMAT_DXT5_RA_AS_RG: return 1;
+ case FORMAT_ETC2_RG11:
+ return 1;
+ case FORMAT_ETC2_RG11S:
+ return 1;
+ case FORMAT_ETC2_RGB8:
+ return 1;
+ case FORMAT_ETC2_RGBA8:
+ return 1;
+ case FORMAT_ETC2_RGB8A1:
+ return 1;
+ case FORMAT_ETC2_RA_AS_RG:
+ return 1;
+ case FORMAT_DXT5_RA_AS_RG:
+ return 1;
case FORMAT_MAX: {
}
}
@@ -478,36 +501,96 @@ void Image::convert(Format p_new_format) {
switch (conversion_type) {
- case FORMAT_L8 | (FORMAT_LA8 << 8): _convert<1, false, 1, true, true, true>(width, height, rptr, wptr); break;
- case FORMAT_L8 | (FORMAT_R8 << 8): _convert<1, false, 1, false, true, false>(width, height, rptr, wptr); break;
- case FORMAT_L8 | (FORMAT_RG8 << 8): _convert<1, false, 2, false, true, false>(width, height, rptr, wptr); break;
- case FORMAT_L8 | (FORMAT_RGB8 << 8): _convert<1, false, 3, false, true, false>(width, height, rptr, wptr); break;
- case FORMAT_L8 | (FORMAT_RGBA8 << 8): _convert<1, false, 3, true, true, false>(width, height, rptr, wptr); break;
- case FORMAT_LA8 | (FORMAT_L8 << 8): _convert<1, true, 1, false, true, true>(width, height, rptr, wptr); break;
- case FORMAT_LA8 | (FORMAT_R8 << 8): _convert<1, true, 1, false, true, false>(width, height, rptr, wptr); break;
- case FORMAT_LA8 | (FORMAT_RG8 << 8): _convert<1, true, 2, false, true, false>(width, height, rptr, wptr); break;
- case FORMAT_LA8 | (FORMAT_RGB8 << 8): _convert<1, true, 3, false, true, false>(width, height, rptr, wptr); break;
- case FORMAT_LA8 | (FORMAT_RGBA8 << 8): _convert<1, true, 3, true, true, false>(width, height, rptr, wptr); break;
- case FORMAT_R8 | (FORMAT_L8 << 8): _convert<1, false, 1, false, false, true>(width, height, rptr, wptr); break;
- case FORMAT_R8 | (FORMAT_LA8 << 8): _convert<1, false, 1, true, false, true>(width, height, rptr, wptr); break;
- case FORMAT_R8 | (FORMAT_RG8 << 8): _convert<1, false, 2, false, false, false>(width, height, rptr, wptr); break;
- case FORMAT_R8 | (FORMAT_RGB8 << 8): _convert<1, false, 3, false, false, false>(width, height, rptr, wptr); break;
- case FORMAT_R8 | (FORMAT_RGBA8 << 8): _convert<1, false, 3, true, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RG8 | (FORMAT_L8 << 8): _convert<2, false, 1, false, false, true>(width, height, rptr, wptr); break;
- case FORMAT_RG8 | (FORMAT_LA8 << 8): _convert<2, false, 1, true, false, true>(width, height, rptr, wptr); break;
- case FORMAT_RG8 | (FORMAT_R8 << 8): _convert<2, false, 1, false, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RG8 | (FORMAT_RGB8 << 8): _convert<2, false, 3, false, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RG8 | (FORMAT_RGBA8 << 8): _convert<2, false, 3, true, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RGB8 | (FORMAT_L8 << 8): _convert<3, false, 1, false, false, true>(width, height, rptr, wptr); break;
- case FORMAT_RGB8 | (FORMAT_LA8 << 8): _convert<3, false, 1, true, false, true>(width, height, rptr, wptr); break;
- case FORMAT_RGB8 | (FORMAT_R8 << 8): _convert<3, false, 1, false, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RGB8 | (FORMAT_RG8 << 8): _convert<3, false, 2, false, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RGB8 | (FORMAT_RGBA8 << 8): _convert<3, false, 3, true, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RGBA8 | (FORMAT_L8 << 8): _convert<3, true, 1, false, false, true>(width, height, rptr, wptr); break;
- case FORMAT_RGBA8 | (FORMAT_LA8 << 8): _convert<3, true, 1, true, false, true>(width, height, rptr, wptr); break;
- case FORMAT_RGBA8 | (FORMAT_R8 << 8): _convert<3, true, 1, false, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RGBA8 | (FORMAT_RG8 << 8): _convert<3, true, 2, false, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RGBA8 | (FORMAT_RGB8 << 8): _convert<3, true, 3, false, false, false>(width, height, rptr, wptr); break;
+ case FORMAT_L8 | (FORMAT_LA8 << 8):
+ _convert<1, false, 1, true, true, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_L8 | (FORMAT_R8 << 8):
+ _convert<1, false, 1, false, true, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_L8 | (FORMAT_RG8 << 8):
+ _convert<1, false, 2, false, true, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_L8 | (FORMAT_RGB8 << 8):
+ _convert<1, false, 3, false, true, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_L8 | (FORMAT_RGBA8 << 8):
+ _convert<1, false, 3, true, true, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_LA8 | (FORMAT_L8 << 8):
+ _convert<1, true, 1, false, true, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_LA8 | (FORMAT_R8 << 8):
+ _convert<1, true, 1, false, true, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_LA8 | (FORMAT_RG8 << 8):
+ _convert<1, true, 2, false, true, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_LA8 | (FORMAT_RGB8 << 8):
+ _convert<1, true, 3, false, true, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_LA8 | (FORMAT_RGBA8 << 8):
+ _convert<1, true, 3, true, true, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_R8 | (FORMAT_L8 << 8):
+ _convert<1, false, 1, false, false, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_R8 | (FORMAT_LA8 << 8):
+ _convert<1, false, 1, true, false, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_R8 | (FORMAT_RG8 << 8):
+ _convert<1, false, 2, false, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_R8 | (FORMAT_RGB8 << 8):
+ _convert<1, false, 3, false, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_R8 | (FORMAT_RGBA8 << 8):
+ _convert<1, false, 3, true, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RG8 | (FORMAT_L8 << 8):
+ _convert<2, false, 1, false, false, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RG8 | (FORMAT_LA8 << 8):
+ _convert<2, false, 1, true, false, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RG8 | (FORMAT_R8 << 8):
+ _convert<2, false, 1, false, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RG8 | (FORMAT_RGB8 << 8):
+ _convert<2, false, 3, false, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RG8 | (FORMAT_RGBA8 << 8):
+ _convert<2, false, 3, true, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGB8 | (FORMAT_L8 << 8):
+ _convert<3, false, 1, false, false, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGB8 | (FORMAT_LA8 << 8):
+ _convert<3, false, 1, true, false, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGB8 | (FORMAT_R8 << 8):
+ _convert<3, false, 1, false, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGB8 | (FORMAT_RG8 << 8):
+ _convert<3, false, 2, false, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGB8 | (FORMAT_RGBA8 << 8):
+ _convert<3, false, 3, true, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGBA8 | (FORMAT_L8 << 8):
+ _convert<3, true, 1, false, false, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGBA8 | (FORMAT_LA8 << 8):
+ _convert<3, true, 1, true, false, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGBA8 | (FORMAT_R8 << 8):
+ _convert<3, true, 1, false, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGBA8 | (FORMAT_RG8 << 8):
+ _convert<3, true, 2, false, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGBA8 | (FORMAT_RGB8 << 8):
+ _convert<3, true, 3, false, false, false>(width, height, rptr, wptr);
+ break;
}
bool gen_mipmaps = mipmaps;
@@ -949,25 +1032,49 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) {
switch (get_format_pixel_size(format)) {
- case 1: _scale_nearest<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 2: _scale_nearest<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 3: _scale_nearest<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 4: _scale_nearest<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 1:
+ _scale_nearest<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 2:
+ _scale_nearest<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 3:
+ _scale_nearest<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 4:
+ _scale_nearest<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
} else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) {
switch (get_format_pixel_size(format)) {
- case 4: _scale_nearest<1, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 8: _scale_nearest<2, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 12: _scale_nearest<3, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 16: _scale_nearest<4, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 4:
+ _scale_nearest<1, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 8:
+ _scale_nearest<2, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 12:
+ _scale_nearest<3, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 16:
+ _scale_nearest<4, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
} else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) {
switch (get_format_pixel_size(format)) {
- case 2: _scale_nearest<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 4: _scale_nearest<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 6: _scale_nearest<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 8: _scale_nearest<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 2:
+ _scale_nearest<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 4:
+ _scale_nearest<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 6:
+ _scale_nearest<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 8:
+ _scale_nearest<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
}
@@ -1013,24 +1120,48 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) {
switch (get_format_pixel_size(format)) {
- case 1: _scale_bilinear<1, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 2: _scale_bilinear<2, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 3: _scale_bilinear<3, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 4: _scale_bilinear<4, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
+ case 1:
+ _scale_bilinear<1, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 2:
+ _scale_bilinear<2, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 3:
+ _scale_bilinear<3, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 4:
+ _scale_bilinear<4, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
}
} else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) {
switch (get_format_pixel_size(format)) {
- case 4: _scale_bilinear<1, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 8: _scale_bilinear<2, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 12: _scale_bilinear<3, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 16: _scale_bilinear<4, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
+ case 4:
+ _scale_bilinear<1, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 8:
+ _scale_bilinear<2, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 12:
+ _scale_bilinear<3, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 16:
+ _scale_bilinear<4, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
}
} else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) {
switch (get_format_pixel_size(format)) {
- case 2: _scale_bilinear<1, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 4: _scale_bilinear<2, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 6: _scale_bilinear<3, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 8: _scale_bilinear<4, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
+ case 2:
+ _scale_bilinear<1, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 4:
+ _scale_bilinear<2, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 6:
+ _scale_bilinear<3, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 8:
+ _scale_bilinear<4, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
}
}
}
@@ -1046,24 +1177,48 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) {
switch (get_format_pixel_size(format)) {
- case 1: _scale_cubic<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 2: _scale_cubic<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 3: _scale_cubic<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 4: _scale_cubic<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 1:
+ _scale_cubic<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 2:
+ _scale_cubic<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 3:
+ _scale_cubic<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 4:
+ _scale_cubic<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
} else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) {
switch (get_format_pixel_size(format)) {
- case 4: _scale_cubic<1, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 8: _scale_cubic<2, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 12: _scale_cubic<3, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 16: _scale_cubic<4, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 4:
+ _scale_cubic<1, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 8:
+ _scale_cubic<2, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 12:
+ _scale_cubic<3, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 16:
+ _scale_cubic<4, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
} else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) {
switch (get_format_pixel_size(format)) {
- case 2: _scale_cubic<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 4: _scale_cubic<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 6: _scale_cubic<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 8: _scale_cubic<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 2:
+ _scale_cubic<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 4:
+ _scale_cubic<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 6:
+ _scale_cubic<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 8:
+ _scale_cubic<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
}
} break;
@@ -1071,24 +1226,48 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) {
switch (get_format_pixel_size(format)) {
- case 1: _scale_lanczos<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 2: _scale_lanczos<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 3: _scale_lanczos<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 4: _scale_lanczos<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 1:
+ _scale_lanczos<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 2:
+ _scale_lanczos<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 3:
+ _scale_lanczos<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 4:
+ _scale_lanczos<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
} else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) {
switch (get_format_pixel_size(format)) {
- case 4: _scale_lanczos<1, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 8: _scale_lanczos<2, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 12: _scale_lanczos<3, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 16: _scale_lanczos<4, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 4:
+ _scale_lanczos<1, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 8:
+ _scale_lanczos<2, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 12:
+ _scale_lanczos<3, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 16:
+ _scale_lanczos<4, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
} else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) {
switch (get_format_pixel_size(format)) {
- case 2: _scale_lanczos<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 4: _scale_lanczos<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 6: _scale_lanczos<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 8: _scale_lanczos<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 2:
+ _scale_lanczos<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 4:
+ _scale_lanczos<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 6:
+ _scale_lanczos<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 8:
+ _scale_lanczos<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
}
} break;
@@ -1403,23 +1582,51 @@ void Image::shrink_x2() {
switch (format) {
case FORMAT_L8:
- case FORMAT_R8: _generate_po2_mipmap<uint8_t, 1, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height); break;
- case FORMAT_LA8: _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height); break;
- case FORMAT_RG8: _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height); break;
- case FORMAT_RGB8: _generate_po2_mipmap<uint8_t, 3, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height); break;
- case FORMAT_RGBA8: _generate_po2_mipmap<uint8_t, 4, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height); break;
-
- case FORMAT_RF: _generate_po2_mipmap<float, 1, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height); break;
- case FORMAT_RGF: _generate_po2_mipmap<float, 2, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height); break;
- case FORMAT_RGBF: _generate_po2_mipmap<float, 3, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height); break;
- case FORMAT_RGBAF: _generate_po2_mipmap<float, 4, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height); break;
-
- case FORMAT_RH: _generate_po2_mipmap<uint16_t, 1, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height); break;
- case FORMAT_RGH: _generate_po2_mipmap<uint16_t, 2, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height); break;
- case FORMAT_RGBH: _generate_po2_mipmap<uint16_t, 3, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height); break;
- case FORMAT_RGBAH: _generate_po2_mipmap<uint16_t, 4, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height); break;
-
- case FORMAT_RGBE9995: _generate_po2_mipmap<uint32_t, 1, false, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(r), reinterpret_cast<uint32_t *>(w), width, height); break;
+ case FORMAT_R8:
+ _generate_po2_mipmap<uint8_t, 1, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height);
+ break;
+ case FORMAT_LA8:
+ _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height);
+ break;
+ case FORMAT_RG8:
+ _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height);
+ break;
+ case FORMAT_RGB8:
+ _generate_po2_mipmap<uint8_t, 3, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height);
+ break;
+ case FORMAT_RGBA8:
+ _generate_po2_mipmap<uint8_t, 4, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height);
+ break;
+
+ case FORMAT_RF:
+ _generate_po2_mipmap<float, 1, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height);
+ break;
+ case FORMAT_RGF:
+ _generate_po2_mipmap<float, 2, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height);
+ break;
+ case FORMAT_RGBF:
+ _generate_po2_mipmap<float, 3, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height);
+ break;
+ case FORMAT_RGBAF:
+ _generate_po2_mipmap<float, 4, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height);
+ break;
+
+ case FORMAT_RH:
+ _generate_po2_mipmap<uint16_t, 1, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height);
+ break;
+ case FORMAT_RGH:
+ _generate_po2_mipmap<uint16_t, 2, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height);
+ break;
+ case FORMAT_RGBH:
+ _generate_po2_mipmap<uint16_t, 3, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height);
+ break;
+ case FORMAT_RGBAH:
+ _generate_po2_mipmap<uint16_t, 4, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height);
+ break;
+
+ case FORMAT_RGBE9995:
+ _generate_po2_mipmap<uint32_t, 1, false, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(r), reinterpret_cast<uint32_t *>(w), width, height);
+ break;
default: {
}
}
@@ -1485,9 +1692,13 @@ Error Image::generate_mipmaps(bool p_renormalize) {
switch (format) {
case FORMAT_L8:
- case FORMAT_R8: _generate_po2_mipmap<uint8_t, 1, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); break;
+ case FORMAT_R8:
+ _generate_po2_mipmap<uint8_t, 1, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
+ break;
case FORMAT_LA8:
- case FORMAT_RG8: _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); break;
+ case FORMAT_RG8:
+ _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
+ break;
case FORMAT_RGB8:
if (p_renormalize)
_generate_po2_mipmap<uint8_t, 3, true, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
@@ -1911,12 +2122,24 @@ void Image::create(const char **p_xpm) {
break;
switch (i) {
- case 0: col_r = v << 4; break;
- case 1: col_r |= v; break;
- case 2: col_g = v << 4; break;
- case 3: col_g |= v; break;
- case 4: col_b = v << 4; break;
- case 5: col_b |= v; break;
+ case 0:
+ col_r = v << 4;
+ break;
+ case 1:
+ col_r |= v;
+ break;
+ case 2:
+ col_g = v << 4;
+ break;
+ case 3:
+ col_g |= v;
+ break;
+ case 4:
+ col_b = v << 4;
+ break;
+ case 5:
+ col_b |= v;
+ break;
};
}
@@ -2901,12 +3124,24 @@ Image::UsedChannels Image::detect_used_channels(CompressSource p_source) {
void Image::optimize_channels() {
switch (detect_used_channels()) {
- case USED_CHANNELS_L: convert(FORMAT_L8); break;
- case USED_CHANNELS_LA: convert(FORMAT_LA8); break;
- case USED_CHANNELS_R: convert(FORMAT_R8); break;
- case USED_CHANNELS_RG: convert(FORMAT_RG8); break;
- case USED_CHANNELS_RGB: convert(FORMAT_RGB8); break;
- case USED_CHANNELS_RGBA: convert(FORMAT_RGBA8); break;
+ case USED_CHANNELS_L:
+ convert(FORMAT_L8);
+ break;
+ case USED_CHANNELS_LA:
+ convert(FORMAT_LA8);
+ break;
+ case USED_CHANNELS_R:
+ convert(FORMAT_R8);
+ break;
+ case USED_CHANNELS_RG:
+ convert(FORMAT_RG8);
+ break;
+ case USED_CHANNELS_RGB:
+ convert(FORMAT_RGB8);
+ break;
+ case USED_CHANNELS_RGBA:
+ convert(FORMAT_RGBA8);
+ break;
}
}
@@ -3152,11 +3387,13 @@ void Image::bumpmap_to_normalmap(float bump_scale) {
for (int ty = 0; ty < height; ty++) {
int py = ty + 1;
- if (py >= height) py -= height;
+ if (py >= height)
+ py -= height;
for (int tx = 0; tx < width; tx++) {
int px = tx + 1;
- if (px >= width) px -= width;
+ if (px >= width)
+ px -= width;
float here = read_ptr[ty * width + tx];
float to_right = read_ptr[ty * width + px];
float above = read_ptr[py * width + tx];
@@ -3431,6 +3668,10 @@ Ref<Resource> Image::duplicate(bool p_subresources) const {
return copy;
}
+void Image::set_as_black() {
+ zeromem(data.ptrw(), data.size());
+}
+
Image::Image() {
width = 0;
diff --git a/core/image.h b/core/image.h
index 5bd73fa677..07b4f49751 100644
--- a/core/image.h
+++ b/core/image.h
@@ -376,6 +376,8 @@ public:
void set_pixelv(const Point2 &p_dst, const Color &p_color);
void set_pixel(int p_x, int p_y, const Color &p_color);
+ void set_as_black();
+
void copy_internals_from(const Ref<Image> &p_image) {
ERR_FAIL_COND_MSG(p_image.is_null(), "It's not a reference to a valid Image object.");
format = p_image->format;
diff --git a/core/input/godotcontrollerdb.txt b/core/input/godotcontrollerdb.txt
index adc3649d64..51ddda1e4e 100644
--- a/core/input/godotcontrollerdb.txt
+++ b/core/input/godotcontrollerdb.txt
@@ -4,6 +4,9 @@
# Windows
__XINPUT_DEVICE__,XInput Gamepad,a:b12,b:b13,x:b14,y:b15,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpdown:b1,dpleft:b2,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Windows,
+# Android
+Default Android Gamepad,Default Controller,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,back:b4,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,platform:Android,
+
# Javascript
Default HTML5 Gamepad, Default Mapping,leftx:a0,lefty:a1,dpdown:b13,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:b14,lefttrigger:a6,x:b2,dpup:b12,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b0,dpright:b15,righttrigger:a7,b:b1,platform:Javascript,
c2a94d6963726f736f66742058626f78,Wireless X360 Controller,leftx:a0,lefty:a1,dpdown:b14,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:b11,lefttrigger:a2,x:b2,dpup:b13,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:b12,righttrigger:a5,b:b1,platform:Javascript,
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index 0a7dee9444..fd9b83eaf9 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -414,7 +414,8 @@ Error DirAccessPack::change_dir(String p_dir) {
nd = nd.simplify_path();
- if (nd == "") nd = ".";
+ if (nd == "")
+ nd = ".";
if (nd.begins_with("/")) {
nd = nd.replace_first("/", "");
diff --git a/core/io/ip_address.h b/core/io/ip_address.h
index 89cf37ff8f..a59178063d 100644
--- a/core/io/ip_address.h
+++ b/core/io/ip_address.h
@@ -52,16 +52,20 @@ protected:
public:
//operator Variant() const;
bool operator==(const IP_Address &p_ip) const {
- if (p_ip.valid != valid) return false;
- if (!valid) return false;
+ if (p_ip.valid != valid)
+ return false;
+ if (!valid)
+ return false;
for (int i = 0; i < 4; i++)
if (field32[i] != p_ip.field32[i])
return false;
return true;
}
bool operator!=(const IP_Address &p_ip) const {
- if (p_ip.valid != valid) return true;
- if (!valid) return true;
+ if (p_ip.valid != valid)
+ return true;
+ if (!valid)
+ return true;
for (int i = 0; i < 4; i++)
if (field32[i] != p_ip.field32[i])
return true;
diff --git a/core/io/json.cpp b/core/io/json.cpp
index 3a0edceb81..0186547dd2 100644
--- a/core/io/json.cpp
+++ b/core/io/json.cpp
@@ -67,10 +67,14 @@ String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_
switch (p_var.get_type()) {
- case Variant::NIL: return "null";
- case Variant::BOOL: return p_var.operator bool() ? "true" : "false";
- case Variant::INT: return itos(p_var);
- case Variant::FLOAT: return rtos(p_var);
+ case Variant::NIL:
+ return "null";
+ case Variant::BOOL:
+ return p_var.operator bool() ? "true" : "false";
+ case Variant::INT:
+ return itos(p_var);
+ case Variant::FLOAT:
+ return rtos(p_var);
case Variant::PACKED_INT32_ARRAY:
case Variant::PACKED_INT64_ARRAY:
case Variant::PACKED_FLOAT32_ARRAY:
@@ -116,7 +120,8 @@ String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_
s += end_statement + _make_indent(p_indent, p_cur_indent) + "}";
return s;
};
- default: return "\"" + String(p_var).json_escape() + "\"";
+ default:
+ return "\"" + String(p_var).json_escape() + "\"";
}
}
@@ -199,11 +204,21 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
switch (next) {
- case 'b': res = 8; break;
- case 't': res = 9; break;
- case 'n': res = 10; break;
- case 'f': res = 12; break;
- case 'r': res = 13; break;
+ case 'b':
+ res = 8;
+ break;
+ case 't':
+ res = 9;
+ break;
+ case 'n':
+ res = 10;
+ break;
+ case 'f':
+ res = 12;
+ break;
+ case 'r':
+ res = 13;
+ break;
case 'u': {
// hex number
for (int j = 0; j < 4; j++) {
diff --git a/core/io/logger.cpp b/core/io/logger.cpp
index ad0cc81023..02cc78538e 100644
--- a/core/io/logger.cpp
+++ b/core/io/logger.cpp
@@ -49,11 +49,21 @@ void Logger::log_error(const char *p_function, const char *p_file, int p_line, c
const char *err_type = "ERROR";
switch (p_type) {
- case ERR_ERROR: err_type = "ERROR"; break;
- case ERR_WARNING: err_type = "WARNING"; break;
- case ERR_SCRIPT: err_type = "SCRIPT ERROR"; break;
- case ERR_SHADER: err_type = "SHADER ERROR"; break;
- default: ERR_PRINT("Unknown error type"); break;
+ case ERR_ERROR:
+ err_type = "ERROR";
+ break;
+ case ERR_WARNING:
+ err_type = "WARNING";
+ break;
+ case ERR_SCRIPT:
+ err_type = "SCRIPT ERROR";
+ break;
+ case ERR_SHADER:
+ err_type = "SHADER ERROR";
+ break;
+ default:
+ ERR_PRINT("Unknown error type");
+ break;
}
const char *err_details;
diff --git a/core/io/marshalls.h b/core/io/marshalls.h
index d029ed238c..650c95364a 100644
--- a/core/io/marshalls.h
+++ b/core/io/marshalls.h
@@ -121,7 +121,8 @@ static inline int encode_cstring(const char *p_string, uint8_t *p_data) {
len++;
};
- if (p_data) *p_data = 0;
+ if (p_data)
+ *p_data = 0;
return len + 1;
}
diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp
index 3bec52416e..94e2fdb72c 100644
--- a/core/io/multiplayer_api.cpp
+++ b/core/io/multiplayer_api.cpp
@@ -144,7 +144,8 @@ void MultiplayerAPI::set_root_node(Node *p_node) {
void MultiplayerAPI::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_peer) {
- if (p_peer == network_peer) return; // Nothing to do
+ if (p_peer == network_peer)
+ return; // Nothing to do
ERR_FAIL_COND_MSG(p_peer.is_valid() && p_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED,
"Supplied NetworkedMultiplayerPeer must be connecting or connected.");
@@ -787,8 +788,9 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
int ofs = 0;
-#define MAKE_ROOM(m_amount) \
- if (packet_cache.size() < m_amount) packet_cache.resize(m_amount);
+#define MAKE_ROOM(m_amount) \
+ if (packet_cache.size() < m_amount) \
+ packet_cache.resize(m_amount);
// Encode meta.
// The meta is composed by a single byte that contains (starting from the least segnificant bit):
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 8c7559479b..e0fea143bb 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -337,10 +337,14 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case OBJECT_INTERNAL_RESOURCE: {
uint32_t index = f->get_32();
+ String path = res_path + "::" + itos(index);
+
if (use_nocache) {
- r_v = internal_resources[index].cache;
+ if (!internal_index_cache.has(path)) {
+ WARN_PRINT(String("Couldn't load resource (no cache): " + path).utf8().get_data());
+ }
+ r_v = internal_index_cache[path];
} else {
- String path = res_path + "::" + itos(index);
RES res = ResourceLoader::load(path);
if (res.is_null()) {
WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
@@ -720,13 +724,15 @@ Error ResourceLoaderBinary::load() {
if (!main) {
+ path = internal_resources[i].path;
+
+ if (path.begins_with("local://")) {
+ path = path.replace_first("local://", "");
+ subindex = path.to_int();
+ path = res_path + "::" + path;
+ }
+
if (!use_nocache) {
- path = internal_resources[i].path;
- if (path.begins_with("local://")) {
- path = path.replace_first("local://", "");
- subindex = path.to_int();
- path = res_path + "::" + path;
- }
if (ResourceCache::has(path)) {
//already loaded, don't do anything
@@ -769,7 +775,7 @@ Error ResourceLoaderBinary::load() {
r->set_subindex(subindex);
if (!main) {
- internal_resources.write[i].cache = res;
+ internal_index_cache[path] = res;
}
int pc = f->get_32();
diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h
index 0f8fc9445b..3c8d916c0a 100644
--- a/core/io/resource_format_binary.h
+++ b/core/io/resource_format_binary.h
@@ -68,10 +68,10 @@ class ResourceLoaderBinary {
struct IntResource {
String path;
uint64_t offset;
- RES cache;
};
Vector<IntResource> internal_resources;
+ Map<String, RES> internal_index_cache;
String get_unicode_string();
void _advance_padding(uint32_t p_len);
diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp
index 643df53f8c..9e22bdced7 100644
--- a/core/io/resource_importer.cpp
+++ b/core/io/resource_importer.cpp
@@ -91,7 +91,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
r_path_and_type.path = value;
path_found = true; //first match must have priority
} else if (assign == "type") {
- r_path_and_type.type = value;
+ r_path_and_type.type = ClassDB::get_compatibility_remapped_class(value);
} else if (assign == "importer") {
r_path_and_type.importer = value;
} else if (assign == "group_file") {
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 2d95d5545f..b10c08d693 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -160,7 +160,8 @@ public:
static bool get_timestamp_on_load() { return timestamp_on_load; }
static void notify_load_error(const String &p_err) {
- if (err_notify) err_notify(err_notify_ud, p_err);
+ if (err_notify)
+ err_notify(err_notify_ud, p_err);
}
static void set_error_notify_func(void *p_ud, ResourceLoadErrorNotify p_err_notify) {
err_notify = p_err_notify;
@@ -168,7 +169,8 @@ public:
}
static void notify_dependency_error(const String &p_path, const String &p_dependency, const String &p_type) {
- if (dep_err_notify) dep_err_notify(dep_err_notify_ud, p_path, p_dependency, p_type);
+ if (dep_err_notify)
+ dep_err_notify(dep_err_notify_ud, p_path, p_dependency, p_type);
}
static void set_dependency_error_notify_func(void *p_ud, DependencyErrorNotify p_err_notify) {
dep_err_notify = p_err_notify;
diff --git a/core/list.h b/core/list.h
index be2dccd876..65d45ffdfc 100644
--- a/core/list.h
+++ b/core/list.h
@@ -353,7 +353,8 @@ public:
Element *it = front();
while (it) {
- if (it->value == p_val) return it;
+ if (it->value == p_val)
+ return it;
it = it->next();
};
diff --git a/core/local_vector.h b/core/local_vector.h
new file mode 100644
index 0000000000..0b0ef6dfdc
--- /dev/null
+++ b/core/local_vector.h
@@ -0,0 +1,246 @@
+/*************************************************************************/
+/* local_vector.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 LOCAL_VECTOR_H
+#define LOCAL_VECTOR_H
+
+#include "core/error_macros.h"
+#include "core/os/copymem.h"
+#include "core/os/memory.h"
+#include "core/sort_array.h"
+#include "core/vector.h"
+
+template <class T, class U = uint32_t, bool force_trivial = false>
+class LocalVector {
+private:
+ U count = 0;
+ U capacity = 0;
+ T *data = nullptr;
+
+public:
+ _FORCE_INLINE_ void push_back(T p_elem) {
+ if (unlikely(count == capacity)) {
+ if (capacity == 0) {
+ capacity = 1;
+ } else {
+ capacity <<= 1;
+ }
+ data = (T *)memrealloc(data, capacity * sizeof(T));
+ CRASH_COND_MSG(!data, "Out of memory");
+ }
+
+ if (!__has_trivial_constructor(T) && !force_trivial) {
+ memnew_placement(&data[count++], T(p_elem));
+ } else {
+ data[count++] = p_elem;
+ }
+ }
+
+ void remove(U p_index) {
+ ERR_FAIL_UNSIGNED_INDEX(p_index, count);
+ for (U i = p_index; i < count; i++) {
+ data[i] = data[i + 1];
+ }
+ count--;
+ if (!__has_trivial_destructor(T) && !force_trivial) {
+ data[count].~T();
+ }
+ }
+
+ void erase(const T &p_val) {
+ U idx = find(p_val);
+ if (idx >= 0)
+ remove(idx);
+ }
+
+ void invert() {
+
+ for (U i = 0; i < count / 2; i++) {
+ SWAP(data[i], data[count - i - 1]);
+ }
+ }
+
+ _FORCE_INLINE_ void clear() { resize(0); }
+ _FORCE_INLINE_ void reset() {
+ clear();
+ if (data) {
+ memfree(data);
+ data = nullptr;
+ capacity = 0;
+ }
+ }
+ _FORCE_INLINE_ bool empty() const { return count == 0; }
+ _FORCE_INLINE_ void reserve(U p_size) {
+ p_size = nearest_power_of_2_templated(p_size);
+ if (p_size > capacity) {
+ capacity = p_size;
+ data = (T *)memrealloc(data, capacity * sizeof(T));
+ CRASH_COND_MSG(!data, "Out of memory");
+ }
+ }
+
+ _FORCE_INLINE_ U size() const { return count; }
+ void resize(U p_size) {
+
+ if (p_size < count) {
+
+ if (!__has_trivial_destructor(T) && !force_trivial) {
+ for (U i = p_size; i < count; i++) {
+ data[i].~T();
+ }
+ }
+ count = p_size;
+ } else if (p_size > count) {
+
+ if (unlikely(p_size > capacity)) {
+ if (capacity == 0) {
+ capacity = 1;
+ }
+ while (capacity < p_size) {
+ capacity <<= 1;
+ }
+ data = (T *)memrealloc(data, capacity * sizeof(T));
+ CRASH_COND_MSG(!data, "Out of memory");
+ }
+ if (!__has_trivial_constructor(T) && !force_trivial) {
+ for (U i = count; i < p_size; i++) {
+ memnew_placement(&data[i], T);
+ }
+ }
+ count = p_size;
+ }
+ }
+ _FORCE_INLINE_ const T &operator[](U p_index) const {
+ CRASH_BAD_UNSIGNED_INDEX(p_index, count);
+ return data[p_index];
+ }
+ _FORCE_INLINE_ T &operator[](U p_index) {
+ CRASH_BAD_UNSIGNED_INDEX(p_index, count);
+ return data[p_index];
+ }
+
+ void insert(U p_pos, T p_val) {
+ ERR_FAIL_UNSIGNED_INDEX(p_pos, count + 1);
+ if (p_pos == count) {
+ push_back(p_val);
+ } else {
+ resize(count + 1);
+ for (U i = count; i > p_pos; i--) {
+ data[i] = data[i - 1];
+ }
+ data[p_pos] = p_val;
+ }
+ }
+
+ int64_t find(const T &p_val, U p_from = 0) const {
+
+ for (U i = 0; i < count; i++) {
+ if (data[i] == p_val) {
+ return int64_t(i);
+ }
+ }
+ return -1;
+ }
+
+ template <class C>
+ void sort_custom() {
+
+ U len = count;
+ if (len == 0)
+ return;
+
+ SortArray<T, C> sorter;
+ sorter.sort(data, len);
+ }
+
+ void sort() {
+
+ sort_custom<_DefaultComparator<T>>();
+ }
+
+ void ordered_insert(T p_val) {
+
+ U i;
+ for (i = 0; i < count; i++) {
+
+ if (p_val < data[i]) {
+ break;
+ };
+ };
+ insert(i, p_val);
+ }
+
+ operator Vector<T>() const {
+ Vector<T> ret;
+ ret.resize(size());
+ T *w = ret.ptrw();
+ copymem(w, data, sizeof(T) * count);
+ return ret;
+ }
+
+ Vector<uint8_t> to_byte_array() const { //useful to pass stuff to gpu or variant
+ Vector<uint8_t> ret;
+ ret.resize(count * sizeof(T));
+ uint8_t *w = ret.ptrw();
+ copymem(w, data, sizeof(T) * count);
+ return ret;
+ }
+
+ _FORCE_INLINE_ LocalVector() {}
+ _FORCE_INLINE_ LocalVector(const LocalVector &p_from) {
+ resize(p_from.size());
+ for (U i = 0; i < p_from.count; i++) {
+ data[i] = p_from.data[i];
+ }
+ }
+ inline LocalVector &operator=(const LocalVector &p_from) {
+ resize(p_from.size());
+ for (U i = 0; i < p_from.count; i++) {
+ data[i] = p_from.data[i];
+ }
+ return *this;
+ }
+ inline LocalVector &operator=(const Vector<T> &p_from) {
+ resize(p_from.size());
+ for (U i = 0; i < count; i++) {
+ data[i] = p_from[i];
+ }
+ return *this;
+ }
+
+ _FORCE_INLINE_ ~LocalVector() {
+
+ if (data) {
+ reset();
+ }
+ }
+};
+
+#endif // LOCAL_VECTOR_H
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index 3e3e6c50a7..3aba753f51 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -164,7 +164,8 @@ void AStar::connect_points(int p_id, int p_with_id, bool bidirectional) {
}
Segment s(p_id, p_with_id);
- if (bidirectional) s.direction = Segment::BIDIRECTIONAL;
+ if (bidirectional)
+ s.direction = Segment::BIDIRECTIONAL;
Set<Segment>::Element *element = segments.find(s);
if (element != nullptr) {
@@ -290,7 +291,8 @@ int AStar::get_closest_point(const Vector3 &p_point, bool p_include_disabled) co
for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
- if (!p_include_disabled && !(*it.value)->enabled) continue; // Disabled points should not be considered.
+ if (!p_include_disabled && !(*it.value)->enabled)
+ continue; // Disabled points should not be considered.
real_t d = p_point.distance_squared_to((*it.value)->pos);
if (closest_id < 0 || d < closest_dist) {
@@ -340,7 +342,8 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
pass++;
- if (!end_point->enabled) return false;
+ if (!end_point->enabled)
+ return false;
bool found_route = false;
@@ -451,7 +454,8 @@ Vector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
- if (!found_route) return Vector<Vector3>();
+ if (!found_route)
+ return Vector<Vector3>();
Point *p = end_point;
int pc = 1; // Begin point
@@ -499,7 +503,8 @@ Vector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
- if (!found_route) return Vector<int>();
+ if (!found_route)
+ return Vector<int>();
Point *p = end_point;
int pc = 1; // Begin point
@@ -729,7 +734,8 @@ Vector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) {
AStar::Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
- if (!found_route) return Vector<Vector2>();
+ if (!found_route)
+ return Vector<Vector2>();
AStar::Point *p = end_point;
int pc = 1; // Begin point
@@ -777,7 +783,8 @@ Vector<int> AStar2D::get_id_path(int p_from_id, int p_to_id) {
AStar::Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
- if (!found_route) return Vector<int>();
+ if (!found_route)
+ return Vector<int>();
AStar::Point *p = end_point;
int pc = 1; // Begin point
@@ -809,7 +816,8 @@ bool AStar2D::_solve(AStar::Point *begin_point, AStar::Point *end_point) {
astar.pass++;
- if (!end_point->enabled) return false;
+ if (!end_point->enabled)
+ return false;
bool found_route = false;
diff --git a/core/math/aabb.h b/core/math/aabb.h
index 7fdad07c89..f87fced12d 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -177,14 +177,22 @@ Vector3 AABB::get_support(const Vector3 &p_normal) const {
Vector3 AABB::get_endpoint(int p_point) const {
switch (p_point) {
- case 0: return Vector3(position.x, position.y, position.z);
- case 1: return Vector3(position.x, position.y, position.z + size.z);
- case 2: return Vector3(position.x, position.y + size.y, position.z);
- case 3: return Vector3(position.x, position.y + size.y, position.z + size.z);
- case 4: return Vector3(position.x + size.x, position.y, position.z);
- case 5: return Vector3(position.x + size.x, position.y, position.z + size.z);
- case 6: return Vector3(position.x + size.x, position.y + size.y, position.z);
- case 7: return Vector3(position.x + size.x, position.y + size.y, position.z + size.z);
+ case 0:
+ return Vector3(position.x, position.y, position.z);
+ case 1:
+ return Vector3(position.x, position.y, position.z + size.z);
+ case 2:
+ return Vector3(position.x, position.y + size.y, position.z);
+ case 3:
+ return Vector3(position.x, position.y + size.y, position.z + size.z);
+ case 4:
+ return Vector3(position.x + size.x, position.y, position.z);
+ case 5:
+ return Vector3(position.x + size.x, position.y, position.z + size.z);
+ case 6:
+ return Vector3(position.x + size.x, position.y + size.y, position.z);
+ case 7:
+ return Vector3(position.x + size.x, position.y + size.y, position.z + size.z);
};
ERR_FAIL_V(Vector3());
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index 0f519a20d8..6218b7e248 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -783,7 +783,8 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
real_t s = Math::sqrt((elements[1][2] - elements[2][1]) * (elements[1][2] - elements[2][1]) + (elements[2][0] - elements[0][2]) * (elements[2][0] - elements[0][2]) + (elements[0][1] - elements[1][0]) * (elements[0][1] - elements[1][0])); // s=|axis||sin(angle)|, used to normalise
angle = Math::acos((elements[0][0] + elements[1][1] + elements[2][2] - 1) / 2);
- if (angle < 0) s = -s;
+ if (angle < 0)
+ s = -s;
x = (elements[2][1] - elements[1][2]) / s;
y = (elements[0][2] - elements[2][0]) / s;
z = (elements[1][0] - elements[0][1]) / s;
@@ -877,3 +878,114 @@ Basis Basis::slerp(const Basis &target, const real_t &t) const {
return b;
}
+
+void Basis::rotate_sh(real_t *p_values) {
+
+ // code by John Hable
+ // http://filmicworlds.com/blog/simple-and-fast-spherical-harmonic-rotation/
+ // this code is Public Domain
+
+ const static real_t s_c3 = 0.94617469575; // (3*sqrt(5))/(4*sqrt(pi))
+ const static real_t s_c4 = -0.31539156525; // (-sqrt(5))/(4*sqrt(pi))
+ const static real_t s_c5 = 0.54627421529; // (sqrt(15))/(4*sqrt(pi))
+
+ const static real_t s_c_scale = 1.0 / 0.91529123286551084;
+ const static real_t s_c_scale_inv = 0.91529123286551084;
+
+ const static real_t s_rc2 = 1.5853309190550713 * s_c_scale;
+ const static real_t s_c4_div_c3 = s_c4 / s_c3;
+ const static real_t s_c4_div_c3_x2 = (s_c4 / s_c3) * 2.0;
+
+ const static real_t s_scale_dst2 = s_c3 * s_c_scale_inv;
+ const static real_t s_scale_dst4 = s_c5 * s_c_scale_inv;
+
+ real_t src[9] = { p_values[0], p_values[1], p_values[2], p_values[3], p_values[4], p_values[5], p_values[6], p_values[7], p_values[8] };
+
+ real_t m00 = elements[0][0];
+ real_t m01 = elements[0][1];
+ real_t m02 = elements[0][2];
+ real_t m10 = elements[1][0];
+ real_t m11 = elements[1][1];
+ real_t m12 = elements[1][2];
+ real_t m20 = elements[2][0];
+ real_t m21 = elements[2][1];
+ real_t m22 = elements[2][2];
+
+ p_values[0] = src[0];
+ p_values[1] = m11 * src[1] - m12 * src[2] + m10 * src[3];
+ p_values[2] = -m21 * src[1] + m22 * src[2] - m20 * src[3];
+ p_values[3] = m01 * src[1] - m02 * src[2] + m00 * src[3];
+
+ real_t sh0 = src[7] + src[8] + src[8] - src[5];
+ real_t sh1 = src[4] + s_rc2 * src[6] + src[7] + src[8];
+ real_t sh2 = src[4];
+ real_t sh3 = -src[7];
+ real_t sh4 = -src[5];
+
+ // Rotations. R0 and R1 just use the raw matrix columns
+ real_t r2x = m00 + m01;
+ real_t r2y = m10 + m11;
+ real_t r2z = m20 + m21;
+
+ real_t r3x = m00 + m02;
+ real_t r3y = m10 + m12;
+ real_t r3z = m20 + m22;
+
+ real_t r4x = m01 + m02;
+ real_t r4y = m11 + m12;
+ real_t r4z = m21 + m22;
+
+ // dense matrix multiplication one column at a time
+
+ // column 0
+ real_t sh0_x = sh0 * m00;
+ real_t sh0_y = sh0 * m10;
+ real_t d0 = sh0_x * m10;
+ real_t d1 = sh0_y * m20;
+ real_t d2 = sh0 * (m20 * m20 + s_c4_div_c3);
+ real_t d3 = sh0_x * m20;
+ real_t d4 = sh0_x * m00 - sh0_y * m10;
+
+ // column 1
+ real_t sh1_x = sh1 * m02;
+ real_t sh1_y = sh1 * m12;
+ d0 += sh1_x * m12;
+ d1 += sh1_y * m22;
+ d2 += sh1 * (m22 * m22 + s_c4_div_c3);
+ d3 += sh1_x * m22;
+ d4 += sh1_x * m02 - sh1_y * m12;
+
+ // column 2
+ real_t sh2_x = sh2 * r2x;
+ real_t sh2_y = sh2 * r2y;
+ d0 += sh2_x * r2y;
+ d1 += sh2_y * r2z;
+ d2 += sh2 * (r2z * r2z + s_c4_div_c3_x2);
+ d3 += sh2_x * r2z;
+ d4 += sh2_x * r2x - sh2_y * r2y;
+
+ // column 3
+ real_t sh3_x = sh3 * r3x;
+ real_t sh3_y = sh3 * r3y;
+ d0 += sh3_x * r3y;
+ d1 += sh3_y * r3z;
+ d2 += sh3 * (r3z * r3z + s_c4_div_c3_x2);
+ d3 += sh3_x * r3z;
+ d4 += sh3_x * r3x - sh3_y * r3y;
+
+ // column 4
+ real_t sh4_x = sh4 * r4x;
+ real_t sh4_y = sh4 * r4y;
+ d0 += sh4_x * r4y;
+ d1 += sh4_y * r4z;
+ d2 += sh4 * (r4z * r4z + s_c4_div_c3_x2);
+ d3 += sh4_x * r4z;
+ d4 += sh4_x * r4x - sh4_y * r4y;
+
+ // extra multipliers
+ p_values[4] = d0;
+ p_values[5] = -d1;
+ p_values[6] = d2 * s_scale_dst2;
+ p_values[7] = -d3;
+ p_values[8] = d4 * s_scale_dst4;
+}
diff --git a/core/math/basis.h b/core/math/basis.h
index 0261cf67c6..2924a0ddbd 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -159,6 +159,7 @@ public:
bool is_rotation() const;
Basis slerp(const Basis &target, const real_t &t) const;
+ void rotate_sh(real_t *p_values);
operator String() const;
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index c36070e47f..5d3ebc9f6d 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -33,6 +33,22 @@
#include "core/math/math_funcs.h"
#include "core/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] -
+ matrix[0][3] * matrix[1][1] * matrix[2][2] * matrix[3][0] + matrix[0][1] * matrix[1][3] * matrix[2][2] * matrix[3][0] +
+ matrix[0][2] * matrix[1][1] * matrix[2][3] * matrix[3][0] - matrix[0][1] * matrix[1][2] * matrix[2][3] * matrix[3][0] -
+ matrix[0][3] * matrix[1][2] * matrix[2][0] * matrix[3][1] + matrix[0][2] * matrix[1][3] * matrix[2][0] * matrix[3][1] +
+ matrix[0][3] * matrix[1][0] * matrix[2][2] * matrix[3][1] - matrix[0][0] * matrix[1][3] * matrix[2][2] * matrix[3][1] -
+ matrix[0][2] * matrix[1][0] * matrix[2][3] * matrix[3][1] + matrix[0][0] * matrix[1][2] * matrix[2][3] * matrix[3][1] +
+ matrix[0][3] * matrix[1][1] * matrix[2][0] * matrix[3][2] - matrix[0][1] * matrix[1][3] * matrix[2][0] * matrix[3][2] -
+ matrix[0][3] * matrix[1][0] * matrix[2][1] * matrix[3][2] + matrix[0][0] * matrix[1][3] * matrix[2][1] * matrix[3][2] +
+ matrix[0][1] * matrix[1][0] * matrix[2][3] * matrix[3][2] - matrix[0][0] * matrix[1][1] * matrix[2][3] * matrix[3][2] -
+ matrix[0][2] * matrix[1][1] * matrix[2][0] * matrix[3][3] + matrix[0][1] * matrix[1][2] * matrix[2][0] * matrix[3][3] +
+ matrix[0][2] * matrix[1][0] * matrix[2][1] * matrix[3][3] - matrix[0][0] * matrix[1][2] * matrix[2][1] * matrix[3][3] -
+ matrix[0][1] * matrix[1][0] * matrix[2][2] * matrix[3][3] + matrix[0][0] * matrix[1][1] * matrix[2][2] * matrix[3][3];
+}
+
void CameraMatrix::set_identity() {
for (int i = 0; i < 4; i++) {
@@ -473,20 +489,23 @@ void CameraMatrix::invert() {
/** Divide column by minus pivot value **/
for (i = 0; i < 4; i++) {
- if (i != k) matrix[i][k] /= (-pvt_val);
+ if (i != k)
+ matrix[i][k] /= (-pvt_val);
}
/** Reduce the matrix **/
for (i = 0; i < 4; i++) {
hold = matrix[i][k];
for (j = 0; j < 4; j++) {
- if (i != k && j != k) matrix[i][j] += hold * matrix[k][j];
+ if (i != k && j != k)
+ matrix[i][j] += hold * matrix[k][j];
}
}
/** Divide row by pivot **/
for (j = 0; j < 4; j++) {
- if (j != k) matrix[k][j] /= pvt_val;
+ if (j != k)
+ matrix[k][j] /= pvt_val;
}
/** Replace pivot by reciprocal (at last we can touch it). **/
diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h
index c10193bc84..5420fa2984 100644
--- a/core/math/camera_matrix.h
+++ b/core/math/camera_matrix.h
@@ -47,6 +47,7 @@ struct CameraMatrix {
real_t matrix[4][4];
+ float determinant() const;
void set_identity();
void set_zero();
void set_light_bias();
diff --git a/core/math/delaunay.h b/core/math/delaunay_2d.h
index 29f84210d2..b8252e9d16 100644
--- a/core/math/delaunay.h
+++ b/core/math/delaunay_2d.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* delaunay.h */
+/* delaunay_2d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef DELAUNAY_H
-#define DELAUNAY_H
+#ifndef DELAUNAY_2D_H
+#define DELAUNAY_2D_H
#include "core/math/rect2.h"
@@ -115,8 +115,6 @@ public:
triangles.push_back(Triangle(p_points.size() + 0, p_points.size() + 1, p_points.size() + 2));
for (int i = 0; i < p_points.size(); i++) {
- //std::cout << "Traitement du point " << *p << std::endl;
- //std::cout << "_triangles contains " << _triangles.size() << " elements" << std::endl;
Vector<Edge> polygon;
@@ -172,4 +170,4 @@ public:
}
};
-#endif // DELAUNAY_H
+#endif // DELAUNAY_2D_H
diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h
new file mode 100644
index 0000000000..57f3a78d35
--- /dev/null
+++ b/core/math/delaunay_3d.h
@@ -0,0 +1,387 @@
+#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 "thirdparty/misc/r128.h"
+
+class Delaunay3D {
+ struct Simplex;
+
+ enum {
+ ACCEL_GRID_SIZE = 16
+ };
+ struct GridPos {
+ Vector3i pos;
+ List<Simplex *>::Element *E = nullptr;
+ };
+
+ struct Simplex {
+
+ uint32_t points[4];
+ R128 circum_center_x;
+ R128 circum_center_y;
+ R128 circum_center_z;
+ R128 circum_r2;
+ LocalVector<GridPos> grid_positions;
+ List<Simplex *>::Element *SE = nullptr;
+
+ _FORCE_INLINE_ Simplex() {}
+ _FORCE_INLINE_ Simplex(uint32_t p_a, uint32_t p_b, uint32_t p_c, uint32_t p_d) {
+ points[0] = p_a;
+ points[1] = p_b;
+ points[2] = p_c;
+ points[3] = p_d;
+ }
+ };
+
+ struct Triangle {
+ uint32_t triangle[3];
+ bool bad;
+ _FORCE_INLINE_ bool operator==(const Triangle &p_triangle) const {
+ return triangle[0] == p_triangle.triangle[0] && triangle[1] == p_triangle.triangle[1] && triangle[2] == p_triangle.triangle[2];
+ }
+
+ _FORCE_INLINE_ Triangle() { bad = false; }
+ _FORCE_INLINE_ Triangle(uint32_t p_a, uint32_t p_b, uint32_t p_c) {
+ if (p_a > p_b)
+ SWAP(p_a, p_b);
+ if (p_b > p_c)
+ SWAP(p_b, p_c);
+ if (p_a > p_b)
+ SWAP(p_a, p_b);
+
+ bad = false;
+ triangle[0] = p_a;
+ triangle[1] = p_b;
+ triangle[2] = p_c;
+ }
+ };
+
+ struct TriangleHasher {
+ _FORCE_INLINE_ static uint32_t hash(const Triangle &p_triangle) {
+ uint32_t h = hash_djb2_one_32(p_triangle.triangle[0]);
+ h = hash_djb2_one_32(p_triangle.triangle[1], h);
+ return hash_djb2_one_32(p_triangle.triangle[2], h);
+ }
+ };
+
+ struct FPVal {
+ };
+
+ _FORCE_INLINE_ static void circum_sphere_compute(const Vector3 *p_points, Simplex *p_simplex) {
+
+ // the only part in the algorithm where there may be precision errors is this one, so ensure that
+ // we do it as maximum precision as possible
+
+ R128 v0_x = p_points[p_simplex->points[0]].x;
+ R128 v0_y = p_points[p_simplex->points[0]].y;
+ R128 v0_z = p_points[p_simplex->points[0]].z;
+ R128 v1_x = p_points[p_simplex->points[1]].x;
+ R128 v1_y = p_points[p_simplex->points[1]].y;
+ R128 v1_z = p_points[p_simplex->points[1]].z;
+ R128 v2_x = p_points[p_simplex->points[2]].x;
+ R128 v2_y = p_points[p_simplex->points[2]].y;
+ R128 v2_z = p_points[p_simplex->points[2]].z;
+ R128 v3_x = p_points[p_simplex->points[3]].x;
+ R128 v3_y = p_points[p_simplex->points[3]].y;
+ R128 v3_z = p_points[p_simplex->points[3]].z;
+
+ //Create the rows of our "unrolled" 3x3 matrix
+ R128 row1_x = v1_x - v0_x;
+ R128 row1_y = v1_y - v0_y;
+ R128 row1_z = v1_z - v0_z;
+
+ R128 row2_x = v2_x - v0_x;
+ R128 row2_y = v2_y - v0_y;
+ R128 row2_z = v2_z - v0_z;
+
+ R128 row3_x = v3_x - v0_x;
+ R128 row3_y = v3_y - v0_y;
+ R128 row3_z = v3_z - v0_z;
+
+ R128 sq_lenght1 = row1_x * row1_x + row1_y * row1_y + row1_z * row1_z;
+ R128 sq_lenght2 = row2_x * row2_x + row2_y * row2_y + row2_z * row2_z;
+ R128 sq_lenght3 = row3_x * row3_x + row3_y * row3_y + row3_z * row3_z;
+
+ //Compute the determinant of said matrix
+ R128 determinant = row1_x * (row2_y * row3_z - row3_y * row2_z) - row2_x * (row1_y * row3_z - row3_y * row1_z) + row3_x * (row1_y * row2_z - row2_y * row1_z);
+
+ // Compute the volume of the tetrahedron, and precompute a scalar quantity for re-use in the formula
+ R128 volume = determinant / R128(6.f);
+ R128 i12volume = R128(1.f) / (volume * R128(12.f));
+
+ R128 center_x = v0_x + i12volume * ((row2_y * row3_z - row3_y * row2_z) * sq_lenght1 - (row1_y * row3_z - row3_y * row1_z) * sq_lenght2 + (row1_y * row2_z - row2_y * row1_z) * sq_lenght3);
+ R128 center_y = v0_y + i12volume * (-(row2_x * row3_z - row3_x * row2_z) * sq_lenght1 + (row1_x * row3_z - row3_x * row1_z) * sq_lenght2 - (row1_x * row2_z - row2_x * row1_z) * sq_lenght3);
+ R128 center_z = v0_z + i12volume * ((row2_x * row3_y - row3_x * row2_y) * sq_lenght1 - (row1_x * row3_y - row3_x * row1_y) * sq_lenght2 + (row1_x * row2_y - row2_x * row1_y) * sq_lenght3);
+
+ //Once we know the center, the radius is clearly the distance to any vertex
+
+ R128 rel1_x = center_x - v0_x;
+ R128 rel1_y = center_y - v0_y;
+ R128 rel1_z = center_z - v0_z;
+
+ R128 radius1 = rel1_x * rel1_x + rel1_y * rel1_y + rel1_z * rel1_z;
+
+ p_simplex->circum_center_x = center_x;
+ p_simplex->circum_center_y = center_y;
+ p_simplex->circum_center_z = center_z;
+ p_simplex->circum_r2 = radius1;
+ }
+
+ _FORCE_INLINE_ static bool simplex_contains(const Vector3 *p_points, const Simplex &p_simplex, uint32_t p_vertex) {
+
+ R128 v_x = p_points[p_vertex].x;
+ R128 v_y = p_points[p_vertex].y;
+ R128 v_z = p_points[p_vertex].z;
+
+ R128 rel2_x = p_simplex.circum_center_x - v_x;
+ R128 rel2_y = p_simplex.circum_center_y - v_y;
+ R128 rel2_z = p_simplex.circum_center_z - v_z;
+
+ R128 radius2 = rel2_x * rel2_x + rel2_y * rel2_y + rel2_z * rel2_z;
+
+ return radius2 < (p_simplex.circum_r2 - R128(0.00001));
+ }
+
+ static bool simplex_is_coplanar(const Vector3 *p_points, const Simplex &p_simplex) {
+
+ Plane p(p_points[p_simplex.points[0]], p_points[p_simplex.points[1]], p_points[p_simplex.points[2]]);
+ if (ABS(p.distance_to(p_points[p_simplex.points[3]])) < CMP_EPSILON) {
+ return true;
+ }
+
+ CameraMatrix cm;
+
+ cm.matrix[0][0] = p_points[p_simplex.points[0]].x;
+ cm.matrix[0][1] = p_points[p_simplex.points[1]].x;
+ cm.matrix[0][2] = p_points[p_simplex.points[2]].x;
+ cm.matrix[0][3] = p_points[p_simplex.points[3]].x;
+
+ cm.matrix[1][0] = p_points[p_simplex.points[0]].y;
+ cm.matrix[1][1] = p_points[p_simplex.points[1]].y;
+ cm.matrix[1][2] = p_points[p_simplex.points[2]].y;
+ cm.matrix[1][3] = p_points[p_simplex.points[3]].y;
+
+ cm.matrix[2][0] = p_points[p_simplex.points[0]].z;
+ cm.matrix[2][1] = p_points[p_simplex.points[1]].z;
+ cm.matrix[2][2] = p_points[p_simplex.points[2]].z;
+ cm.matrix[2][3] = p_points[p_simplex.points[3]].z;
+
+ cm.matrix[3][0] = 1.0;
+ cm.matrix[3][1] = 1.0;
+ cm.matrix[3][2] = 1.0;
+ cm.matrix[3][3] = 1.0;
+
+ return ABS(cm.determinant()) <= CMP_EPSILON;
+ }
+
+public:
+ struct OutputSimplex {
+ uint32_t points[4];
+ };
+
+ static Vector<OutputSimplex> tetrahedralize(const Vector<Vector3> &p_points) {
+
+ uint32_t point_count = p_points.size();
+ Vector3 *points = (Vector3 *)memalloc(sizeof(Vector3) * (point_count + 4));
+
+ {
+ const Vector3 *src_points = p_points.ptr();
+ AABB rect;
+ for (uint32_t i = 0; i < point_count; i++) {
+ Vector3 point = src_points[i];
+ if (i == 0) {
+ rect.position = point;
+ } else {
+ rect.expand_to(point);
+ }
+ points[i] = point;
+ }
+
+ for (uint32_t i = 0; i < point_count; i++) {
+ points[i] = (points[i] - rect.position) / rect.size;
+ }
+
+ float delta_max = Math::sqrt(2.0) * 20.0;
+ Vector3 center = Vector3(0.5, 0.5, 0.5);
+
+ // any simplex that contains everything is good
+ points[point_count + 0] = center + Vector3(0, 1, 0) * delta_max;
+ points[point_count + 1] = center + Vector3(0, -1, 1) * delta_max;
+ points[point_count + 2] = center + Vector3(1, -1, -1) * delta_max;
+ points[point_count + 3] = center + Vector3(-1, -1, -1) * delta_max;
+ }
+
+ List<Simplex *> acceleration_grid[ACCEL_GRID_SIZE][ACCEL_GRID_SIZE][ACCEL_GRID_SIZE];
+
+ List<Simplex *> simplex_list;
+ {
+ //create root simplex
+ Simplex *root = memnew(Simplex(point_count + 0, point_count + 1, point_count + 2, point_count + 3));
+ root->SE = simplex_list.push_back(root);
+
+ for (uint32_t i = 0; i < ACCEL_GRID_SIZE; i++) {
+ for (uint32_t j = 0; j < ACCEL_GRID_SIZE; j++) {
+ for (uint32_t k = 0; k < ACCEL_GRID_SIZE; k++) {
+ GridPos gp;
+ gp.E = acceleration_grid[i][j][k].push_back(root);
+ gp.pos = Vector3i(i, j, k);
+ root->grid_positions.push_back(gp);
+ }
+ }
+ }
+
+ circum_sphere_compute(points, root);
+ }
+
+ OAHashMap<Triangle, uint32_t, TriangleHasher> triangles_inserted;
+ LocalVector<Triangle> triangles;
+
+ for (uint32_t i = 0; i < point_count; i++) {
+
+ bool unique = true;
+ for (uint32_t j = i + 1; j < point_count; j++) {
+ if (points[i].is_equal_approx(points[j])) {
+ unique = false;
+ break;
+ }
+ }
+ if (!unique) {
+ continue;
+ }
+
+ Vector3i grid_pos = Vector3i(points[i] * ACCEL_GRID_SIZE);
+ grid_pos.x = CLAMP(grid_pos.x, 0, ACCEL_GRID_SIZE - 1);
+ grid_pos.y = CLAMP(grid_pos.y, 0, ACCEL_GRID_SIZE - 1);
+ grid_pos.z = CLAMP(grid_pos.z, 0, ACCEL_GRID_SIZE - 1);
+
+ for (List<Simplex *>::Element *E = acceleration_grid[grid_pos.x][grid_pos.y][grid_pos.z].front(); E;) {
+ List<Simplex *>::Element *N = E->next(); //may be deleted
+
+ Simplex *simplex = E->get();
+
+ if (simplex_contains(points, *simplex, i)) {
+
+ static const uint32_t triangle_order[4][3] = {
+ { 0, 1, 2 },
+ { 0, 1, 3 },
+ { 0, 2, 3 },
+ { 1, 2, 3 },
+ };
+
+ for (uint32_t k = 0; k < 4; k++) {
+ Triangle t = Triangle(simplex->points[triangle_order[k][0]], simplex->points[triangle_order[k][1]], simplex->points[triangle_order[k][2]]);
+ uint32_t *p = triangles_inserted.lookup_ptr(t);
+ if (p) {
+ triangles[*p].bad = true;
+ } else {
+ triangles_inserted.insert(t, triangles.size());
+ triangles.push_back(t);
+ }
+ }
+
+ //remove simplex and continue
+ simplex_list.erase(simplex->SE);
+
+ for (uint32_t k = 0; k < simplex->grid_positions.size(); k++) {
+ Vector3i p = simplex->grid_positions[k].pos;
+ acceleration_grid[p.x][p.y][p.z].erase(simplex->grid_positions[k].E);
+ }
+ memdelete(simplex);
+ }
+ E = N;
+ }
+
+ uint32_t good_triangles = 0;
+ for (uint32_t j = 0; j < triangles.size(); j++) {
+
+ if (triangles[j].bad) {
+ continue;
+ }
+ Simplex *new_simplex = memnew(Simplex(triangles[j].triangle[0], triangles[j].triangle[1], triangles[j].triangle[2], i));
+ circum_sphere_compute(points, new_simplex);
+ new_simplex->SE = simplex_list.push_back(new_simplex);
+ {
+ Vector3 center;
+ center.x = double(new_simplex->circum_center_x);
+ center.y = double(new_simplex->circum_center_y);
+ center.z = double(new_simplex->circum_center_z);
+
+ float radius2 = Math::sqrt(double(new_simplex->circum_r2));
+ radius2 += 0.0001; //
+ Vector3 extents = Vector3(radius2, radius2, radius2);
+ Vector3i from = Vector3i((center - extents) * ACCEL_GRID_SIZE);
+ Vector3i to = Vector3i((center + extents) * ACCEL_GRID_SIZE);
+ from.x = CLAMP(from.x, 0, ACCEL_GRID_SIZE - 1);
+ from.y = CLAMP(from.y, 0, ACCEL_GRID_SIZE - 1);
+ from.z = CLAMP(from.z, 0, ACCEL_GRID_SIZE - 1);
+ to.x = CLAMP(to.x, 0, ACCEL_GRID_SIZE - 1);
+ to.y = CLAMP(to.y, 0, ACCEL_GRID_SIZE - 1);
+ to.z = CLAMP(to.z, 0, ACCEL_GRID_SIZE - 1);
+
+ for (int32_t x = from.x; x <= to.x; x++) {
+ for (int32_t y = from.y; y <= to.y; y++) {
+ for (int32_t z = from.z; z <= to.z; z++) {
+ GridPos gp;
+ gp.pos = Vector3(x, y, z);
+ gp.E = acceleration_grid[x][y][z].push_back(new_simplex);
+ new_simplex->grid_positions.push_back(gp);
+ }
+ }
+ }
+ }
+
+ good_triangles++;
+ }
+
+ //print_line("at point " + itos(i) + "/" + itos(point_count) + " simplices added " + itos(good_triangles) + "/" + itos(simplex_list.size()) + " - triangles: " + itos(triangles.size()));
+ triangles.clear();
+ triangles_inserted.clear();
+ }
+
+ //print_line("end with simplices: " + itos(simplex_list.size()));
+ Vector<OutputSimplex> ret_simplices;
+ ret_simplices.resize(simplex_list.size());
+ OutputSimplex *ret_simplicesw = ret_simplices.ptrw();
+ uint32_t simplices_written = 0;
+
+ for (List<Simplex *>::Element *E = simplex_list.front(); E; E = E->next()) {
+ Simplex *simplex = E->get();
+ bool invalid = false;
+ for (int j = 0; j < 4; j++) {
+ if (simplex->points[j] >= point_count) {
+ invalid = true;
+ break;
+ }
+ }
+ if (invalid || simplex_is_coplanar(points, *simplex)) {
+ memdelete(simplex);
+ continue;
+ }
+
+ ret_simplicesw[simplices_written].points[0] = simplex->points[0];
+ ret_simplicesw[simplices_written].points[1] = simplex->points[1];
+ ret_simplicesw[simplices_written].points[2] = simplex->points[2];
+ ret_simplicesw[simplices_written].points[3] = simplex->points[3];
+ simplices_written++;
+ memdelete(simplex);
+ }
+
+ ret_simplices.resize(simplices_written);
+
+ memfree(points);
+
+ return ret_simplices;
+ }
+};
+
+#endif // DELAUNAY_3D_H
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index 859b9be8c5..f7a124eae3 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -1023,11 +1023,21 @@ Error Expression::_get_token(Token &r_token) {
switch (next) {
- case 'b': res = 8; break;
- case 't': res = 9; break;
- case 'n': res = 10; break;
- case 'f': res = 12; break;
- case 'r': res = 13; break;
+ case 'b':
+ res = 8;
+ break;
+ case 't':
+ res = 9;
+ break;
+ case 'n':
+ res = 10;
+ break;
+ case 'f':
+ res = 12;
+ break;
+ case 'r':
+ res = 13;
+ break;
case 'u': {
// hex number
for (int j = 0; j < 4; j++) {
@@ -1703,27 +1713,69 @@ Expression::ENode *Expression::_parse_expression() {
Variant::Operator op = Variant::OP_MAX;
switch (tk.type) {
- case TK_OP_IN: op = Variant::OP_IN; break;
- case TK_OP_EQUAL: op = Variant::OP_EQUAL; break;
- case TK_OP_NOT_EQUAL: op = Variant::OP_NOT_EQUAL; break;
- case TK_OP_LESS: op = Variant::OP_LESS; break;
- case TK_OP_LESS_EQUAL: op = Variant::OP_LESS_EQUAL; break;
- case TK_OP_GREATER: op = Variant::OP_GREATER; break;
- case TK_OP_GREATER_EQUAL: op = Variant::OP_GREATER_EQUAL; break;
- case TK_OP_AND: op = Variant::OP_AND; break;
- case TK_OP_OR: op = Variant::OP_OR; break;
- case TK_OP_NOT: op = Variant::OP_NOT; break;
- case TK_OP_ADD: op = Variant::OP_ADD; break;
- case TK_OP_SUB: op = Variant::OP_SUBTRACT; break;
- case TK_OP_MUL: op = Variant::OP_MULTIPLY; break;
- case TK_OP_DIV: op = Variant::OP_DIVIDE; break;
- case TK_OP_MOD: op = Variant::OP_MODULE; break;
- case TK_OP_SHIFT_LEFT: op = Variant::OP_SHIFT_LEFT; break;
- case TK_OP_SHIFT_RIGHT: op = Variant::OP_SHIFT_RIGHT; break;
- case TK_OP_BIT_AND: op = Variant::OP_BIT_AND; break;
- case TK_OP_BIT_OR: op = Variant::OP_BIT_OR; break;
- case TK_OP_BIT_XOR: op = Variant::OP_BIT_XOR; break;
- case TK_OP_BIT_INVERT: op = Variant::OP_BIT_NEGATE; break;
+ case TK_OP_IN:
+ op = Variant::OP_IN;
+ break;
+ case TK_OP_EQUAL:
+ op = Variant::OP_EQUAL;
+ break;
+ case TK_OP_NOT_EQUAL:
+ op = Variant::OP_NOT_EQUAL;
+ break;
+ case TK_OP_LESS:
+ op = Variant::OP_LESS;
+ break;
+ case TK_OP_LESS_EQUAL:
+ op = Variant::OP_LESS_EQUAL;
+ break;
+ case TK_OP_GREATER:
+ op = Variant::OP_GREATER;
+ break;
+ case TK_OP_GREATER_EQUAL:
+ op = Variant::OP_GREATER_EQUAL;
+ break;
+ case TK_OP_AND:
+ op = Variant::OP_AND;
+ break;
+ case TK_OP_OR:
+ op = Variant::OP_OR;
+ break;
+ case TK_OP_NOT:
+ op = Variant::OP_NOT;
+ break;
+ case TK_OP_ADD:
+ op = Variant::OP_ADD;
+ break;
+ case TK_OP_SUB:
+ op = Variant::OP_SUBTRACT;
+ break;
+ case TK_OP_MUL:
+ op = Variant::OP_MULTIPLY;
+ break;
+ case TK_OP_DIV:
+ op = Variant::OP_DIVIDE;
+ break;
+ case TK_OP_MOD:
+ op = Variant::OP_MODULE;
+ break;
+ case TK_OP_SHIFT_LEFT:
+ op = Variant::OP_SHIFT_LEFT;
+ break;
+ case TK_OP_SHIFT_RIGHT:
+ op = Variant::OP_SHIFT_RIGHT;
+ break;
+ case TK_OP_BIT_AND:
+ op = Variant::OP_BIT_AND;
+ break;
+ case TK_OP_BIT_OR:
+ op = Variant::OP_BIT_OR;
+ break;
+ case TK_OP_BIT_XOR:
+ op = Variant::OP_BIT_XOR;
+ break;
+ case TK_OP_BIT_INVERT:
+ op = Variant::OP_BIT_NEGATE;
+ break;
default: {
};
}
@@ -1772,36 +1824,74 @@ Expression::ENode *Expression::_parse_expression() {
unary = true;
break;
- case Variant::OP_MULTIPLY: priority = 2; break;
- case Variant::OP_DIVIDE: priority = 2; break;
- case Variant::OP_MODULE: priority = 2; break;
+ case Variant::OP_MULTIPLY:
+ priority = 2;
+ break;
+ case Variant::OP_DIVIDE:
+ priority = 2;
+ break;
+ case Variant::OP_MODULE:
+ priority = 2;
+ break;
- case Variant::OP_ADD: priority = 3; break;
- case Variant::OP_SUBTRACT: priority = 3; break;
+ case Variant::OP_ADD:
+ priority = 3;
+ break;
+ case Variant::OP_SUBTRACT:
+ priority = 3;
+ break;
- case Variant::OP_SHIFT_LEFT: priority = 4; break;
- case Variant::OP_SHIFT_RIGHT: priority = 4; break;
+ case Variant::OP_SHIFT_LEFT:
+ priority = 4;
+ break;
+ case Variant::OP_SHIFT_RIGHT:
+ priority = 4;
+ break;
- case Variant::OP_BIT_AND: priority = 5; break;
- case Variant::OP_BIT_XOR: priority = 6; break;
- case Variant::OP_BIT_OR: priority = 7; break;
+ case Variant::OP_BIT_AND:
+ priority = 5;
+ break;
+ case Variant::OP_BIT_XOR:
+ priority = 6;
+ break;
+ case Variant::OP_BIT_OR:
+ priority = 7;
+ break;
- case Variant::OP_LESS: priority = 8; break;
- case Variant::OP_LESS_EQUAL: priority = 8; break;
- case Variant::OP_GREATER: priority = 8; break;
- case Variant::OP_GREATER_EQUAL: priority = 8; break;
+ case Variant::OP_LESS:
+ priority = 8;
+ break;
+ case Variant::OP_LESS_EQUAL:
+ priority = 8;
+ break;
+ case Variant::OP_GREATER:
+ priority = 8;
+ break;
+ case Variant::OP_GREATER_EQUAL:
+ priority = 8;
+ break;
- case Variant::OP_EQUAL: priority = 8; break;
- case Variant::OP_NOT_EQUAL: priority = 8; break;
+ case Variant::OP_EQUAL:
+ priority = 8;
+ break;
+ case Variant::OP_NOT_EQUAL:
+ priority = 8;
+ break;
- case Variant::OP_IN: priority = 10; break;
+ case Variant::OP_IN:
+ priority = 10;
+ break;
case Variant::OP_NOT:
priority = 11;
unary = true;
break;
- case Variant::OP_AND: priority = 12; break;
- case Variant::OP_OR: priority = 13; break;
+ case Variant::OP_AND:
+ priority = 12;
+ break;
+ case Variant::OP_OR:
+ priority = 13;
+ break;
default: {
_set_error("Parser bug, invalid operator in expression: " + itos(expression[i].op));
diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp
index fa96fc4535..b0a46036f9 100644
--- a/core/math/geometry.cpp
+++ b/core/math/geometry.cpp
@@ -31,8 +31,11 @@
#include "geometry.h"
#include "core/print_string.h"
+
#include "thirdparty/misc/clipper.hpp"
#include "thirdparty/misc/triangulator.h"
+#define STB_RECT_PACK_IMPLEMENTATION
+#include "thirdparty/misc/stb_rect_pack.h"
#define SCALE_FACTOR 100000.0 // Based on CMP_EPSILON.
@@ -445,7 +448,8 @@ static inline void _mark_outside(uint8_t ***p_cell_status, int x, int y, int z,
next_z--;
prev = _CELL_PREV_Z_POS;
} break;
- default: ERR_FAIL();
+ default:
+ ERR_FAIL();
}
if (next_x < 0 || next_x >= len_x)
@@ -1083,10 +1087,18 @@ Vector<Vector<Point2>> Geometry::_polypaths_do_operation(PolyBooleanOperation p_
ClipType op = ctUnion;
switch (p_op) {
- case OPERATION_UNION: op = ctUnion; break;
- case OPERATION_DIFFERENCE: op = ctDifference; break;
- case OPERATION_INTERSECTION: op = ctIntersection; break;
- case OPERATION_XOR: op = ctXor; break;
+ case OPERATION_UNION:
+ op = ctUnion;
+ break;
+ case OPERATION_DIFFERENCE:
+ op = ctDifference;
+ break;
+ case OPERATION_INTERSECTION:
+ op = ctIntersection;
+ break;
+ case OPERATION_XOR:
+ op = ctXor;
+ break;
}
Path path_a, path_b;
@@ -1135,19 +1147,35 @@ Vector<Vector<Point2>> Geometry::_polypath_offset(const Vector<Point2> &p_polypa
JoinType jt = jtSquare;
switch (p_join_type) {
- case JOIN_SQUARE: jt = jtSquare; break;
- case JOIN_ROUND: jt = jtRound; break;
- case JOIN_MITER: jt = jtMiter; break;
+ case JOIN_SQUARE:
+ jt = jtSquare;
+ break;
+ case JOIN_ROUND:
+ jt = jtRound;
+ break;
+ case JOIN_MITER:
+ jt = jtMiter;
+ break;
}
EndType et = etClosedPolygon;
switch (p_end_type) {
- case END_POLYGON: et = etClosedPolygon; break;
- case END_JOINED: et = etClosedLine; break;
- case END_BUTT: et = etOpenButt; break;
- case END_SQUARE: et = etOpenSquare; break;
- case END_ROUND: et = etOpenRound; break;
+ case END_POLYGON:
+ et = etClosedPolygon;
+ break;
+ case END_JOINED:
+ et = etClosedLine;
+ break;
+ case END_BUTT:
+ et = etOpenButt;
+ break;
+ case END_SQUARE:
+ et = etOpenSquare;
+ break;
+ case END_ROUND:
+ et = etOpenRound;
+ break;
}
ClipperOffset co(2.0, 0.25 * SCALE_FACTOR); // Defaults from ClipperOffset.
Path path;
@@ -1217,3 +1245,195 @@ Vector<Vector3> Geometry::compute_convex_mesh_points(const Plane *p_planes, int
return points;
}
+
+Vector<Point2i> Geometry::pack_rects(const Vector<Size2i> &p_sizes, const Size2i &p_atlas_size) {
+
+ Vector<stbrp_node> nodes;
+ nodes.resize(p_atlas_size.width);
+
+ stbrp_context context;
+ stbrp_init_target(&context, p_atlas_size.width, p_atlas_size.height, nodes.ptrw(), p_atlas_size.width);
+
+ Vector<stbrp_rect> rects;
+ rects.resize(p_sizes.size());
+
+ for (int i = 0; i < p_sizes.size(); i++) {
+ rects.write[i].id = 0;
+ rects.write[i].w = p_sizes[i].width;
+ rects.write[i].h = p_sizes[i].height;
+ rects.write[i].x = 0;
+ rects.write[i].y = 0;
+ rects.write[i].was_packed = 0;
+ }
+
+ int res = stbrp_pack_rects(&context, rects.ptrw(), rects.size());
+ if (res == 0) { //pack failed
+ return Vector<Point2i>();
+ }
+
+ Vector<Point2i> ret;
+ ret.resize(p_sizes.size());
+
+ for (int i = 0; i < p_sizes.size(); i++) {
+ Point2i r(rects[i].x, rects[i].y);
+ ret.write[i] = r;
+ }
+
+ return ret;
+}
+
+Vector<Vector3i> Geometry::partial_pack_rects(const Vector<Vector2i> &p_sizes, const Size2i &p_atlas_size) {
+
+ Vector<stbrp_node> nodes;
+ nodes.resize(p_atlas_size.width);
+ zeromem(nodes.ptrw(), sizeof(stbrp_node) * nodes.size());
+
+ stbrp_context context;
+ stbrp_init_target(&context, p_atlas_size.width, p_atlas_size.height, nodes.ptrw(), p_atlas_size.width);
+
+ Vector<stbrp_rect> rects;
+ rects.resize(p_sizes.size());
+
+ for (int i = 0; i < p_sizes.size(); i++) {
+ rects.write[i].id = i;
+ rects.write[i].w = p_sizes[i].width;
+ rects.write[i].h = p_sizes[i].height;
+ rects.write[i].x = 0;
+ rects.write[i].y = 0;
+ rects.write[i].was_packed = 0;
+ }
+
+ stbrp_pack_rects(&context, rects.ptrw(), rects.size());
+
+ Vector<Vector3i> ret;
+ ret.resize(p_sizes.size());
+
+ for (int i = 0; i < p_sizes.size(); i++) {
+ ret.write[rects[i].id] = Vector3i(rects[i].x, rects[i].y, rects[i].was_packed != 0 ? 1 : 0);
+ }
+
+ return ret;
+}
+
+#define square(m_s) ((m_s) * (m_s))
+#define INF 1e20
+
+/* dt of 1d function using squared distance */
+static void edt(float *f, int stride, int n) {
+
+ float *d = (float *)alloca(sizeof(float) * n + sizeof(int) * n + sizeof(float) * (n + 1));
+ int *v = (int *)&(d[n]);
+ float *z = (float *)&v[n];
+
+ int k = 0;
+ v[0] = 0;
+ z[0] = -INF;
+ z[1] = +INF;
+ for (int q = 1; q <= n - 1; q++) {
+ float s = ((f[q * stride] + square(q)) - (f[v[k] * stride] + square(v[k]))) / (2 * q - 2 * v[k]);
+ while (s <= z[k]) {
+ k--;
+ s = ((f[q * stride] + square(q)) - (f[v[k] * stride] + square(v[k]))) / (2 * q - 2 * v[k]);
+ }
+ k++;
+ v[k] = q;
+
+ z[k] = s;
+ z[k + 1] = +INF;
+ }
+
+ k = 0;
+ for (int q = 0; q <= n - 1; q++) {
+ while (z[k + 1] < q)
+ k++;
+ d[q] = square(q - v[k]) + f[v[k] * stride];
+ }
+
+ for (int i = 0; i < n; i++) {
+ f[i * stride] = d[i];
+ }
+}
+
+#undef square
+
+Vector<uint32_t> Geometry::generate_edf(const Vector<bool> &p_voxels, const Vector3i &p_size, bool p_negative) {
+
+ uint32_t float_count = p_size.x * p_size.y * p_size.z;
+
+ ERR_FAIL_COND_V((uint32_t)p_voxels.size() != float_count, Vector<uint32_t>());
+
+ float *work_memory = memnew_arr(float, float_count);
+ for (uint32_t i = 0; i < float_count; i++) {
+ work_memory[i] = INF;
+ }
+
+ uint32_t y_mult = p_size.x;
+ uint32_t z_mult = y_mult * p_size.y;
+
+ //plot solid cells
+ {
+ const bool *voxr = p_voxels.ptr();
+ for (uint32_t i = 0; i < float_count; i++) {
+
+ bool plot = voxr[i];
+ if (p_negative) {
+ plot = !plot;
+ }
+ if (plot) {
+ work_memory[i] = 0;
+ }
+ }
+ }
+
+ //process in each direction
+
+ //xy->z
+
+ for (int i = 0; i < p_size.x; i++) {
+ for (int j = 0; j < p_size.y; j++) {
+ edt(&work_memory[i + j * y_mult], z_mult, p_size.z);
+ }
+ }
+
+ //xz->y
+
+ for (int i = 0; i < p_size.x; i++) {
+ for (int j = 0; j < p_size.z; j++) {
+ edt(&work_memory[i + j * z_mult], y_mult, p_size.y);
+ }
+ }
+
+ //yz->x
+ for (int i = 0; i < p_size.y; i++) {
+ for (int j = 0; j < p_size.z; j++) {
+ edt(&work_memory[i * y_mult + j * z_mult], 1, p_size.x);
+ }
+ }
+
+ Vector<uint32_t> ret;
+ ret.resize(float_count);
+ {
+ uint32_t *w = ret.ptrw();
+ for (uint32_t i = 0; i < float_count; i++) {
+ w[i] = uint32_t(Math::sqrt(work_memory[i]));
+ }
+ }
+
+ return ret;
+}
+
+Vector<int8_t> Geometry::generate_sdf8(const Vector<uint32_t> &p_positive, const Vector<uint32_t> &p_negative) {
+ ERR_FAIL_COND_V(p_positive.size() != p_negative.size(), Vector<int8_t>());
+ Vector<int8_t> sdf8;
+ int s = p_positive.size();
+ sdf8.resize(s);
+
+ const uint32_t *rpos = p_positive.ptr();
+ const uint32_t *rneg = p_negative.ptr();
+ int8_t *wsdf = sdf8.ptrw();
+ for (int i = 0; i < s; i++) {
+ int32_t diff = int32_t(rpos[i]) - int32_t(rneg[i]);
+ wsdf[i] = CLAMP(diff, -128, 127);
+ }
+ return sdf8;
+}
diff --git a/core/math/geometry.h b/core/math/geometry.h
index ea063a8a59..45c8558fac 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -31,13 +31,12 @@
#ifndef GEOMETRY_H
#define GEOMETRY_H
-#include "core/math/delaunay.h"
+#include "core/math/delaunay_2d.h"
#include "core/math/face3.h"
#include "core/math/rect2.h"
#include "core/math/triangulate.h"
#include "core/math/vector3.h"
#include "core/object.h"
-
#include "core/print_string.h"
#include "core/vector.h"
@@ -113,10 +112,14 @@ public:
real_t mub = (d_of(p1, q1, q2, q1) + mua * d_of(q2, q1, p2, p1)) / d_of(q2, q1, q2, q1);
// Clip the value between [0..1] constraining the solution to lie on the original curves.
- if (mua < 0) mua = 0;
- if (mub < 0) mub = 0;
- if (mua > 1) mua = 1;
- if (mub > 1) mub = 1;
+ if (mua < 0)
+ mua = 0;
+ if (mub < 0)
+ mub = 0;
+ if (mua > 1)
+ mua = 1;
+ if (mub > 1)
+ mub = 1;
c1 = p1.lerp(p2, mua);
c2 = q1.lerp(q2, mub);
}
@@ -497,7 +500,8 @@ public:
bool orientation = an.cross(bn) > 0;
- if ((bn.cross(cn) > 0) != orientation) return false;
+ if ((bn.cross(cn) > 0) != orientation)
+ return false;
return (cn.cross(an) > 0) == orientation;
}
@@ -683,7 +687,8 @@ public:
// If the term we intend to square root is less than 0 then the answer won't be real,
// so it definitely won't be t in the range 0 to 1.
- if (sqrtterm < 0) return -1;
+ if (sqrtterm < 0)
+ return -1;
// If we can assume that the line segment starts outside the circle (e.g. for continuous time collision detection)
// then the following can be skipped and we can just return the equivalent of res1.
@@ -691,8 +696,10 @@ public:
real_t res1 = (-b - sqrtterm) / (2 * a);
real_t res2 = (-b + sqrtterm) / (2 * a);
- if (res1 >= 0 && res1 <= 1) return res1;
- if (res2 >= 0 && res2 <= 1) return res2;
+ if (res1 >= 0 && res1 <= 1)
+ return res1;
+ if (res2 >= 0 && res2 <= 1)
+ return res2;
return -1;
}
@@ -1016,6 +1023,249 @@ public:
static Vector<Vector3> compute_convex_mesh_points(const Plane *p_planes, int p_plane_count);
+#define FINDMINMAX(x0, x1, x2, min, max) \
+ min = max = x0; \
+ if (x1 < min) \
+ min = x1; \
+ if (x1 > max) \
+ max = x1; \
+ if (x2 < min) \
+ min = x2; \
+ if (x2 > max) \
+ max = x2;
+
+ _FORCE_INLINE_ static bool planeBoxOverlap(Vector3 normal, float d, Vector3 maxbox) {
+ int q;
+ Vector3 vmin, vmax;
+ for (q = 0; q <= 2; q++) {
+ if (normal[q] > 0.0f) {
+ vmin[q] = -maxbox[q];
+ vmax[q] = maxbox[q];
+ } else {
+ vmin[q] = maxbox[q];
+ vmax[q] = -maxbox[q];
+ }
+ }
+ if (normal.dot(vmin) + d > 0.0f)
+ return false;
+ if (normal.dot(vmax) + d >= 0.0f)
+ return true;
+
+ return false;
+ }
+
+/*======================== X-tests ========================*/
+#define AXISTEST_X01(a, b, fa, fb) \
+ p0 = a * v0.y - b * v0.z; \
+ p2 = a * v2.y - b * v2.z; \
+ if (p0 < p2) { \
+ min = p0; \
+ max = p2; \
+ } else { \
+ min = p2; \
+ max = p0; \
+ } \
+ rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \
+ if (min > rad || max < -rad) \
+ return false;
+
+#define AXISTEST_X2(a, b, fa, fb) \
+ p0 = a * v0.y - b * v0.z; \
+ p1 = a * v1.y - b * v1.z; \
+ if (p0 < p1) { \
+ min = p0; \
+ max = p1; \
+ } else { \
+ min = p1; \
+ max = p0; \
+ } \
+ rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \
+ if (min > rad || max < -rad) \
+ return false;
+
+/*======================== Y-tests ========================*/
+#define AXISTEST_Y02(a, b, fa, fb) \
+ p0 = -a * v0.x + b * v0.z; \
+ p2 = -a * v2.x + b * v2.z; \
+ if (p0 < p2) { \
+ min = p0; \
+ max = p2; \
+ } else { \
+ min = p2; \
+ max = p0; \
+ } \
+ rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
+ if (min > rad || max < -rad) \
+ return false;
+
+#define AXISTEST_Y1(a, b, fa, fb) \
+ p0 = -a * v0.x + b * v0.z; \
+ p1 = -a * v1.x + b * v1.z; \
+ if (p0 < p1) { \
+ min = p0; \
+ max = p1; \
+ } else { \
+ min = p1; \
+ max = p0; \
+ } \
+ rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
+ if (min > rad || max < -rad) \
+ return false;
+
+ /*======================== Z-tests ========================*/
+
+#define AXISTEST_Z12(a, b, fa, fb) \
+ p1 = a * v1.x - b * v1.y; \
+ p2 = a * v2.x - b * v2.y; \
+ if (p2 < p1) { \
+ min = p2; \
+ max = p1; \
+ } else { \
+ min = p1; \
+ max = p2; \
+ } \
+ rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \
+ if (min > rad || max < -rad) \
+ return false;
+
+#define AXISTEST_Z0(a, b, fa, fb) \
+ p0 = a * v0.x - b * v0.y; \
+ p1 = a * v1.x - b * v1.y; \
+ if (p0 < p1) { \
+ min = p0; \
+ max = p1; \
+ } else { \
+ min = p1; \
+ max = p0; \
+ } \
+ rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \
+ if (min > rad || max < -rad) \
+ return false;
+
+ _FORCE_INLINE_ static bool triangle_box_overlap(const Vector3 &boxcenter, const Vector3 boxhalfsize, const Vector3 *triverts) {
+
+ /* use separating axis theorem to test overlap between triangle and box */
+ /* need to test for overlap in these directions: */
+ /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */
+ /* we do not even need to test these) */
+ /* 2) normal of the triangle */
+ /* 3) crossproduct(edge from tri, {x,y,z}-directin) */
+ /* this gives 3x3=9 more tests */
+ Vector3 v0, v1, v2;
+ float min, max, d, p0, p1, p2, rad, fex, fey, fez;
+ Vector3 normal, e0, e1, e2;
+
+ /* This is the fastest branch on Sun */
+ /* move everything so that the boxcenter is in (0,0,0) */
+
+ v0 = triverts[0] - boxcenter;
+ v1 = triverts[1] - boxcenter;
+ v2 = triverts[2] - boxcenter;
+
+ /* compute triangle edges */
+ e0 = v1 - v0; /* tri edge 0 */
+ e1 = v2 - v1; /* tri edge 1 */
+ e2 = v0 - v2; /* tri edge 2 */
+
+ /* Bullet 3: */
+ /* test the 9 tests first (this was faster) */
+ fex = Math::abs(e0.x);
+ fey = Math::abs(e0.y);
+ fez = Math::abs(e0.z);
+ AXISTEST_X01(e0.z, e0.y, fez, fey);
+ AXISTEST_Y02(e0.z, e0.x, fez, fex);
+ AXISTEST_Z12(e0.y, e0.x, fey, fex);
+
+ fex = Math::abs(e1.x);
+ fey = Math::abs(e1.y);
+ fez = Math::abs(e1.z);
+ AXISTEST_X01(e1.z, e1.y, fez, fey);
+ AXISTEST_Y02(e1.z, e1.x, fez, fex);
+ AXISTEST_Z0(e1.y, e1.x, fey, fex);
+
+ fex = Math::abs(e2.x);
+ fey = Math::abs(e2.y);
+ fez = Math::abs(e2.z);
+ AXISTEST_X2(e2.z, e2.y, fez, fey);
+ AXISTEST_Y1(e2.z, e2.x, fez, fex);
+ AXISTEST_Z12(e2.y, e2.x, fey, fex);
+
+ /* Bullet 1: */
+ /* first test overlap in the {x,y,z}-directions */
+ /* find min, max of the triangle each direction, and test for overlap in */
+ /* that direction -- this is equivalent to testing a minimal AABB around */
+ /* the triangle against the AABB */
+
+ /* test in X-direction */
+ FINDMINMAX(v0.x, v1.x, v2.x, min, max);
+ if (min > boxhalfsize.x || max < -boxhalfsize.x)
+ return false;
+
+ /* test in Y-direction */
+ FINDMINMAX(v0.y, v1.y, v2.y, min, max);
+ if (min > boxhalfsize.y || max < -boxhalfsize.y)
+ return false;
+
+ /* test in Z-direction */
+ FINDMINMAX(v0.z, v1.z, v2.z, min, max);
+ if (min > boxhalfsize.z || max < -boxhalfsize.z)
+ return false;
+
+ /* Bullet 2: */
+ /* test if the box intersects the plane of the triangle */
+ /* compute plane equation of triangle: normal*x+d=0 */
+ normal = e0.cross(e1);
+ d = -normal.dot(v0); /* plane eq: normal.x+d=0 */
+ return planeBoxOverlap(normal, d, boxhalfsize); /* if true, box and triangle overlaps */
+ }
+
+ static Vector<Point2i> pack_rects(const Vector<Size2i> &p_sizes, const Size2i &p_atlas_size);
+ static Vector<Vector3i> partial_pack_rects(const Vector<Vector2i> &p_sizes, const Size2i &p_atlas_size);
+
+ static Vector<uint32_t> generate_edf(const Vector<bool> &p_voxels, const Vector3i &p_size, bool p_negative);
+ static Vector<int8_t> generate_sdf8(const Vector<uint32_t> &p_positive, const Vector<uint32_t> &p_negative);
+
+ static Vector3 triangle_get_barycentric_coords(const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_c, const Vector3 &p_pos) {
+ Vector3 v0 = p_b - p_a;
+ Vector3 v1 = p_c - p_a;
+ Vector3 v2 = p_pos - p_a;
+
+ float d00 = v0.dot(v0);
+ float d01 = v0.dot(v1);
+ float d11 = v1.dot(v1);
+ float d20 = v2.dot(v0);
+ float d21 = v2.dot(v1);
+ float denom = (d00 * d11 - d01 * d01);
+ if (denom == 0) {
+ return Vector3(); //invalid triangle, return empty
+ }
+ float v = (d11 * d20 - d01 * d21) / denom;
+ float w = (d00 * d21 - d01 * d20) / denom;
+ float u = 1.0f - v - w;
+ return Vector3(u, v, w);
+ }
+
+ static Color tetrahedron_get_barycentric_coords(const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_c, const Vector3 &p_d, const Vector3 &p_pos) {
+ Vector3 vap = p_pos - p_a;
+ Vector3 vbp = p_pos - p_b;
+
+ Vector3 vab = p_b - p_a;
+ Vector3 vac = p_c - p_a;
+ Vector3 vad = p_d - p_a;
+
+ Vector3 vbc = p_c - p_b;
+ Vector3 vbd = p_d - p_b;
+ // ScTP computes the scalar triple product
+#define STP(m_a, m_b, m_c) ((m_a).dot((m_b).cross((m_c))))
+ float va6 = STP(vbp, vbd, vbc);
+ float vb6 = STP(vap, vac, vad);
+ float vc6 = STP(vap, vad, vab);
+ float vd6 = STP(vap, vab, vac);
+ float v6 = 1 / STP(vab, vac, vad);
+ return Color(va6 * v6, vb6 * v6, vc6 * v6, vd6 * v6);
+#undef STP
+ }
+
private:
static Vector<Vector<Point2>> _polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open = false);
static Vector<Vector<Point2>> _polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type);
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 3e1eb14a6a..bd13c82894 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -233,12 +233,14 @@ public:
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) {
- if (is_equal_approx(p_from, p_to)) return p_from;
+ 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);
}
static _ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_weight) {
- if (is_equal_approx(p_from, p_to)) return p_from;
+ 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);
}
diff --git a/core/math/plane.cpp b/core/math/plane.cpp
index a3818698bc..26ac0aac47 100644
--- a/core/math/plane.cpp
+++ b/core/math/plane.cpp
@@ -153,6 +153,10 @@ bool Plane::intersects_segment(const Vector3 &p_begin, const Vector3 &p_end, Vec
/* misc */
+bool Plane::is_equal_approx_any_side(const Plane &p_plane) const {
+ return (normal.is_equal_approx(p_plane.normal) && Math::is_equal_approx(d, p_plane.d)) || (normal.is_equal_approx(-p_plane.normal) && Math::is_equal_approx(d, -p_plane.d));
+}
+
bool Plane::is_equal_approx(const Plane &p_plane) const {
return normal.is_equal_approx(p_plane.normal) && Math::is_equal_approx(d, p_plane.d);
diff --git a/core/math/plane.h b/core/math/plane.h
index 771c8fc705..d4f23ff2b6 100644
--- a/core/math/plane.h
+++ b/core/math/plane.h
@@ -69,6 +69,7 @@ public:
Plane operator-() const { return Plane(-normal, -d); }
bool is_equal_approx(const Plane &p_plane) const;
+ bool is_equal_approx_any_side(const Plane &p_plane) const;
_FORCE_INLINE_ bool operator==(const Plane &p_plane) const;
_FORCE_INLINE_ bool operator!=(const Plane &p_plane) const;
diff --git a/core/math/quat.cpp b/core/math/quat.cpp
index 61cd41b23d..6fbea70279 100644
--- a/core/math/quat.cpp
+++ b/core/math/quat.cpp
@@ -206,7 +206,8 @@ Quat Quat::slerpni(const Quat &q, const real_t &t) const {
real_t dot = from.dot(q);
- if (Math::absf(dot) > 0.9999) return from;
+ if (Math::absf(dot) > 0.9999)
+ return from;
real_t theta = Math::acos(dot),
sinT = 1.0 / Math::sin(theta),
diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp
index 5c66721b9d..0f7350a260 100644
--- a/core/math/triangle_mesh.cpp
+++ b/core/math/triangle_mesh.cpp
@@ -558,14 +558,16 @@ bool TriangleMesh::intersect_convex_shape(const Plane *p_planes, int p_plane_cou
if (p.intersects_segment(point, next_point, &res)) {
bool inisde = true;
for (int k = 0; k < p_plane_count; k++) {
- if (k == i) continue;
+ if (k == i)
+ continue;
const Plane &pp = p_planes[k];
if (pp.is_point_over(res)) {
inisde = false;
break;
}
}
- if (inisde) return true;
+ if (inisde)
+ return true;
}
if (p.is_point_over(point)) {
@@ -573,7 +575,8 @@ bool TriangleMesh::intersect_convex_shape(const Plane *p_planes, int p_plane_cou
break;
}
}
- if (over) return true;
+ if (over)
+ return true;
}
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
@@ -652,7 +655,8 @@ bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count,
case TEST_AABB_BIT: {
bool intersects = scale.xform(b.aabb).intersects_convex_shape(p_planes, p_plane_count, p_points, p_point_count);
- if (!intersects) return false;
+ if (!intersects)
+ return false;
bool inside = scale.xform(b.aabb).inside_convex_shape(p_planes, p_plane_count);
if (inside) {
@@ -667,7 +671,8 @@ bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count,
Vector3 point = scale.xform(vertexptr[s.indices[j]]);
for (int i = 0; i < p_plane_count; i++) {
const Plane &p = p_planes[i];
- if (p.is_point_over(point)) return false;
+ if (p.is_point_over(point))
+ return false;
}
}
diff --git a/core/math/triangulate.cpp b/core/math/triangulate.cpp
index cbcb232745..ae278b034d 100644
--- a/core/math/triangulate.cpp
+++ b/core/math/triangulate.cpp
@@ -103,13 +103,16 @@ bool Triangulate::snip(const Vector<Vector2> &p_contour, int u, int v, int w, in
// To avoid that we allow zero-area triangles if all else failed.
float threshold = relaxed ? -CMP_EPSILON : CMP_EPSILON;
- if (threshold > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax)))) return false;
+ if (threshold > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax))))
+ return false;
for (p = 0; p < n; p++) {
- if ((p == u) || (p == v) || (p == w)) continue;
+ if ((p == u) || (p == v) || (p == w))
+ continue;
Px = contour[V[p]].x;
Py = contour[V[p]].y;
- if (is_inside_triangle(Ax, Ay, Bx, By, Cx, Cy, Px, Py, relaxed)) return false;
+ if (is_inside_triangle(Ax, Ay, Bx, By, Cx, Cy, Px, Py, relaxed))
+ return false;
}
return true;
@@ -119,7 +122,8 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul
/* allocate and initialize list of Vertices in polygon */
int n = contour.size();
- if (n < 3) return false;
+ if (n < 3)
+ return false;
Vector<int> V;
V.resize(n);
@@ -161,11 +165,14 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul
/* three consecutive vertices in current polygon, <u,v,w> */
int u = v;
- if (nv <= u) u = 0; /* previous */
+ if (nv <= u)
+ u = 0; /* previous */
v = u + 1;
- if (nv <= v) v = 0; /* new v */
+ if (nv <= v)
+ v = 0; /* new v */
int w = v + 1;
- if (nv <= w) w = 0; /* next */
+ if (nv <= w)
+ w = 0; /* next */
if (snip(contour, u, v, w, nv, V, relaxed)) {
int a, b, c, s, t;
diff --git a/core/method_bind.h b/core/method_bind.h
index d39f107ba6..b3d4f1bf9b 100644
--- a/core/method_bind.h
+++ b/core/method_bind.h
@@ -165,7 +165,8 @@ struct VariantObjectClassChecker<Control *> {
#define CHECK_NOARG(m_arg) \
{ \
if (p_arg##m_arg.get_type() != Variant::NIL) { \
- if (r_argerror) *r_argerror = (m_arg - 1); \
+ if (r_argerror) \
+ *r_argerror = (m_arg - 1); \
return CALL_ERROR_EXTRA_ARGUMENT; \
} \
}
diff --git a/core/node_path.cpp b/core/node_path.cpp
index 83233622a0..25f1b38346 100644
--- a/core/node_path.cpp
+++ b/core/node_path.cpp
@@ -373,7 +373,8 @@ NodePath::NodePath(const String &p_path) {
String str = path.substr(from, i - from);
if (str == "") {
- if (path[i] == 0) continue; // Allow end-of-path :
+ if (path[i] == 0)
+ continue; // Allow end-of-path :
ERR_FAIL_MSG("Invalid NodePath '" + p_path + "'.");
}
diff --git a/core/object.cpp b/core/object.cpp
index b0e6f2bdae..94d957f3af 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -543,7 +543,8 @@ void Object::set_indexed(const Vector<StringName> &p_names, const Variant &p_val
}
bool valid = false;
- if (!r_valid) r_valid = &valid;
+ if (!r_valid)
+ r_valid = &valid;
List<Variant> value_stack;
diff --git a/core/object.h b/core/object.h
index b40aef2a42..3dec8a0480 100644
--- a/core/object.h
+++ b/core/object.h
@@ -346,7 +346,8 @@ protected:
return (bool (Object::*)(const StringName &, const Variant &)) & m_class::_set; \
} \
virtual bool _setv(const StringName &p_name, const Variant &p_property) { \
- if (m_inherits::_setv(p_name, p_property)) return true; \
+ if (m_inherits::_setv(p_name, p_property)) \
+ return true; \
if (m_class::_get_set() != m_inherits::_get_set()) { \
return _set(p_name, p_property); \
} \
diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp
index 94c8cd5d73..b26cd46fd8 100644
--- a/core/os/dir_access.cpp
+++ b/core/os/dir_access.cpp
@@ -39,18 +39,24 @@ String DirAccess::_get_root_path() const {
switch (_access_type) {
- case ACCESS_RESOURCES: return ProjectSettings::get_singleton()->get_resource_path();
- case ACCESS_USERDATA: return OS::get_singleton()->get_user_data_dir();
- default: return "";
+ case ACCESS_RESOURCES:
+ return ProjectSettings::get_singleton()->get_resource_path();
+ case ACCESS_USERDATA:
+ return OS::get_singleton()->get_user_data_dir();
+ default:
+ return "";
}
}
String DirAccess::_get_root_string() const {
switch (_access_type) {
- case ACCESS_RESOURCES: return "res://";
- case ACCESS_USERDATA: return "user://";
- default: return "";
+ case ACCESS_RESOURCES:
+ return "res://";
+ case ACCESS_USERDATA:
+ return "user://";
+ default:
+ return "";
}
}
@@ -220,7 +226,8 @@ String DirAccess::fix_path(String p_path) const {
return p_path;
} break;
- case ACCESS_MAX: break; // Can't happen, but silences warning
+ case ACCESS_MAX:
+ break; // Can't happen, but silences warning
}
return p_path;
diff --git a/core/os/dir_access.h b/core/os/dir_access.h
index 60eb553968..6c876cde5a 100644
--- a/core/os/dir_access.h
+++ b/core/os/dir_access.h
@@ -145,7 +145,8 @@ struct DirAccessRef {
DirAccess *f;
DirAccessRef(DirAccess *fa) { f = fa; }
~DirAccessRef() {
- if (f) memdelete(f);
+ if (f)
+ memdelete(f);
}
};
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index 3922f031b7..7055780f34 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -163,7 +163,8 @@ String FileAccess::fix_path(const String &p_path) const {
return r_path;
} break;
- case ACCESS_MAX: break; // Can't happen, but silences warning
+ case ACCESS_MAX:
+ break; // Can't happen, but silences warning
}
return r_path;
diff --git a/core/os/file_access.h b/core/os/file_access.h
index 010cc74a87..0f85c447b6 100644
--- a/core/os/file_access.h
+++ b/core/os/file_access.h
@@ -192,7 +192,8 @@ struct FileAccessRef {
operator FileAccess *() { return f; }
FileAccessRef(FileAccess *fa) { f = fa; }
~FileAccessRef() {
- if (f) memdelete(f);
+ if (f)
+ memdelete(f);
}
};
diff --git a/core/os/memory.h b/core/os/memory.h
index dcaedd92ba..d377d54fad 100644
--- a/core/os/memory.h
+++ b/core/os/memory.h
@@ -130,9 +130,10 @@ void memdelete_allocator(T *p_class) {
A::free(p_class);
}
-#define memdelete_notnull(m_v) \
- { \
- if (m_v) memdelete(m_v); \
+#define memdelete_notnull(m_v) \
+ { \
+ if (m_v) \
+ memdelete(m_v); \
}
#define memnew_arr(m_class, m_count) memnew_arr_template<m_class>(m_count)
diff --git a/core/os/rw_lock.h b/core/os/rw_lock.h
index 64dfbef20c..2ef4df9b70 100644
--- a/core/os/rw_lock.h
+++ b/core/os/rw_lock.h
@@ -58,10 +58,12 @@ class RWLockRead {
public:
RWLockRead(const RWLock *p_lock) {
lock = const_cast<RWLock *>(p_lock);
- if (lock) lock->read_lock();
+ if (lock)
+ lock->read_lock();
}
~RWLockRead() {
- if (lock) lock->read_unlock();
+ if (lock)
+ lock->read_unlock();
}
};
@@ -72,10 +74,12 @@ class RWLockWrite {
public:
RWLockWrite(RWLock *p_lock) {
lock = p_lock;
- if (lock) lock->write_lock();
+ if (lock)
+ lock->write_lock();
}
~RWLockWrite() {
- if (lock) lock->write_unlock();
+ if (lock)
+ lock->write_unlock();
}
};
diff --git a/core/pool_allocator.cpp b/core/pool_allocator.cpp
index b74540395c..8fd67a47d2 100644
--- a/core/pool_allocator.cpp
+++ b/core/pool_allocator.cpp
@@ -182,7 +182,8 @@ PoolAllocator::ID PoolAllocator::alloc(int p_size) {
ERR_FAIL_COND_V(p_size < 1, POOL_ALLOCATOR_INVALID_ID);
#ifdef DEBUG_ENABLED
- if (p_size > free_mem) OS::get_singleton()->debug_break();
+ if (p_size > free_mem)
+ OS::get_singleton()->debug_break();
#endif
ERR_FAIL_COND_V(p_size > free_mem, POOL_ALLOCATOR_INVALID_ID);
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index 23f549be1a..4cf7e45205 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -233,8 +233,8 @@ void register_core_settings() {
GLOBAL_DEF_RST("network/limits/packet_peer_stream/max_buffer_po2", (16));
ProjectSettings::get_singleton()->set_custom_property_info("network/limits/packet_peer_stream/max_buffer_po2", PropertyInfo(Variant::INT, "network/limits/packet_peer_stream/max_buffer_po2", PROPERTY_HINT_RANGE, "0,64,1,or_greater"));
- GLOBAL_DEF("network/ssl/certificates", "");
- ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt"));
+ GLOBAL_DEF("network/ssl/certificate_bundle_override", "");
+ ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificate_bundle_override", PropertyInfo(Variant::STRING, "network/ssl/certificate_bundle_override", PROPERTY_HINT_FILE, "*.crt"));
}
void register_core_singletons() {
diff --git a/core/self_list.h b/core/self_list.h
index 19d2783208..2c44b0caec 100644
--- a/core/self_list.h
+++ b/core/self_list.h
@@ -120,6 +120,10 @@ private:
public:
_FORCE_INLINE_ bool in_list() const { return _root; }
+ _FORCE_INLINE_ void remove_from_list() {
+ if (_root)
+ _root->remove(this);
+ }
_FORCE_INLINE_ SelfList<T> *next() { return _next; }
_FORCE_INLINE_ SelfList<T> *prev() { return _prev; }
_FORCE_INLINE_ const SelfList<T> *next() const { return _next; }
diff --git a/core/translation.cpp b/core/translation.cpp
index 3f45bb17c9..5f31bc7399 100644
--- a/core/translation.cpp
+++ b/core/translation.cpp
@@ -989,7 +989,8 @@ String TranslationServer::get_locale() const {
String TranslationServer::get_locale_name(const String &p_locale) const {
- if (!locale_name_map.has(p_locale)) return String();
+ if (!locale_name_map.has(p_locale))
+ return String();
return locale_name_map[p_locale];
}
diff --git a/core/typed_array.cpp b/core/typed_array.cpp
index 55e45f0b3f..a655a1b563 100644
--- a/core/typed_array.cpp
+++ b/core/typed_array.cpp
@@ -1 +1,31 @@
+/*************************************************************************/
+/* typed_array.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 "typed_array.h"
diff --git a/core/typed_array.h b/core/typed_array.h
index 5e95e81ea3..2c7b7e0384 100644
--- a/core/typed_array.h
+++ b/core/typed_array.h
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* typed_array.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 TYPED_ARRAY_H
#define TYPED_ARRAY_H
diff --git a/core/ustring.cpp b/core/ustring.cpp
index fbe3fcb1b2..3e8a1ddbe3 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -548,8 +548,8 @@ signed char String::naturalnocasecmp_to(const String &p_str) const {
return -1;
/* Compare the numbers */
- this_int = to_int(this_str);
- that_int = to_int(that_str);
+ this_int = to_int(this_str, -1, true);
+ that_int = to_int(that_str, -1, true);
if (this_int < that_int)
return -1;
@@ -1882,7 +1882,8 @@ bool String::is_numeric() const {
};
int s = 0;
- if (operator[](0) == '-') ++s;
+ if (operator[](0) == '-')
+ ++s;
bool dot = false;
for (int i = s; i < length(); i++) {
@@ -2137,7 +2138,7 @@ double String::to_double(const CharType *p_str, const CharType **r_end) {
return built_in_strtod<CharType>(p_str, (CharType **)r_end);
}
-int64_t String::to_int(const CharType *p_str, int p_len) {
+int64_t String::to_int(const CharType *p_str, int p_len, bool p_clamp) {
if (p_len == 0 || !p_str[0])
return 0;
@@ -2181,7 +2182,15 @@ int64_t String::to_int(const CharType *p_str, int p_len) {
while (*str && str != limit) {
number += *(str++);
}
- ERR_FAIL_V_MSG(sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + number + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
+ if (p_clamp) {
+ if (sign == 1) {
+ return INT64_MAX;
+ } else {
+ return INT64_MIN;
+ }
+ } else {
+ ERR_FAIL_V_MSG(sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + number + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
+ }
}
integer *= 10;
integer += c - '0';
@@ -4182,9 +4191,14 @@ String String::sprintf(const Array &values, bool *error) const {
int base = 16;
bool capitalize = false;
switch (c) {
- case 'd': base = 10; break;
- case 'o': base = 8; break;
- case 'x': break;
+ case 'd':
+ base = 10;
+ break;
+ case 'o':
+ base = 8;
+ break;
+ case 'x':
+ break;
case 'X':
base = 16;
capitalize = true;
diff --git a/core/ustring.h b/core/ustring.h
index ee7e3b1e16..15bc2b323c 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -254,7 +254,7 @@ public:
static int to_int(const char *p_str, int p_len = -1);
static double to_double(const char *p_str);
static double to_double(const CharType *p_str, const CharType **r_end = nullptr);
- static int64_t to_int(const CharType *p_str, int p_len = -1);
+ static int64_t to_int(const CharType *p_str, int p_len = -1, bool p_clamp = false);
String capitalize() const;
String camelcase_to_underscore(bool lowercase = true) const;
diff --git a/core/variant.cpp b/core/variant.cpp
index a91876dd98..2eacb5d58c 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -1406,20 +1406,47 @@ void Variant::reference(const Variant &p_variant) {
void Variant::zero() {
switch (type) {
- case NIL: break;
- case BOOL: this->_data._bool = false; break;
- case INT: this->_data._int = 0; break;
- case FLOAT: this->_data._float = 0; break;
- case VECTOR2: *reinterpret_cast<Vector2 *>(this->_data._mem) = Vector2(); break;
- case VECTOR2I: *reinterpret_cast<Vector2i *>(this->_data._mem) = Vector2i(); break;
- case RECT2: *reinterpret_cast<Rect2 *>(this->_data._mem) = Rect2(); break;
- case RECT2I: *reinterpret_cast<Rect2i *>(this->_data._mem) = Rect2i(); break;
- case VECTOR3: *reinterpret_cast<Vector3 *>(this->_data._mem) = Vector3(); break;
- case VECTOR3I: *reinterpret_cast<Vector3i *>(this->_data._mem) = Vector3i(); break;
- case PLANE: *reinterpret_cast<Plane *>(this->_data._mem) = Plane(); break;
- case QUAT: *reinterpret_cast<Quat *>(this->_data._mem) = Quat(); break;
- case COLOR: *reinterpret_cast<Color *>(this->_data._mem) = Color(); break;
- default: this->clear(); break;
+ case NIL:
+ break;
+ case BOOL:
+ this->_data._bool = false;
+ break;
+ case INT:
+ this->_data._int = 0;
+ break;
+ case FLOAT:
+ this->_data._float = 0;
+ break;
+ case VECTOR2:
+ *reinterpret_cast<Vector2 *>(this->_data._mem) = Vector2();
+ break;
+ case VECTOR2I:
+ *reinterpret_cast<Vector2i *>(this->_data._mem) = Vector2i();
+ break;
+ case RECT2:
+ *reinterpret_cast<Rect2 *>(this->_data._mem) = Rect2();
+ break;
+ case RECT2I:
+ *reinterpret_cast<Rect2i *>(this->_data._mem) = Rect2i();
+ break;
+ case VECTOR3:
+ *reinterpret_cast<Vector3 *>(this->_data._mem) = Vector3();
+ break;
+ case VECTOR3I:
+ *reinterpret_cast<Vector3i *>(this->_data._mem) = Vector3i();
+ break;
+ case PLANE:
+ *reinterpret_cast<Plane *>(this->_data._mem) = Plane();
+ break;
+ case QUAT:
+ *reinterpret_cast<Quat *>(this->_data._mem) = Quat();
+ break;
+ case COLOR:
+ *reinterpret_cast<Color *>(this->_data._mem) = Color();
+ break;
+ default:
+ this->clear();
+ break;
}
}
@@ -1545,11 +1572,16 @@ Variant::operator signed int() const {
switch (type) {
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_int();
default: {
return 0;
@@ -1560,11 +1592,16 @@ Variant::operator unsigned int() const {
switch (type) {
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_int();
default: {
return 0;
@@ -1576,11 +1613,16 @@ Variant::operator int64_t() const {
switch (type) {
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_int64();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_int64();
default: {
return 0;
@@ -1612,11 +1654,16 @@ Variant::operator uint64_t() const {
switch (type) {
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_int();
default: {
return 0;
@@ -1639,11 +1686,16 @@ Variant::operator signed long() const {
switch (type) {
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._real;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._real;
+ case STRING:
+ return operator String().to_int();
default: {
return 0;
@@ -1657,11 +1709,16 @@ Variant::operator unsigned long() const {
switch (type) {
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._real;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._real;
+ case STRING:
+ return operator String().to_int();
default: {
return 0;
@@ -1676,11 +1733,16 @@ Variant::operator signed short() const {
switch (type) {
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_int();
default: {
return 0;
@@ -1691,11 +1753,16 @@ Variant::operator unsigned short() const {
switch (type) {
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_int();
default: {
return 0;
@@ -1706,11 +1773,16 @@ Variant::operator signed char() const {
switch (type) {
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_int();
default: {
return 0;
@@ -1721,11 +1793,16 @@ Variant::operator unsigned char() const {
switch (type) {
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_int();
default: {
return 0;
@@ -1742,11 +1819,16 @@ Variant::operator float() const {
switch (type) {
- case NIL: return 0;
- case BOOL: return _data._bool ? 1.0 : 0.0;
- case INT: return (float)_data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_double();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1.0 : 0.0;
+ case INT:
+ return (float)_data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_double();
default: {
return 0;
@@ -1757,11 +1839,16 @@ Variant::operator double() const {
switch (type) {
- case NIL: return 0;
- case BOOL: return _data._bool ? 1.0 : 0.0;
- case INT: return (double)_data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_double();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1.0 : 0.0;
+ case INT:
+ return (double)_data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_double();
default: {
return 0;
@@ -1800,27 +1887,40 @@ Variant::operator String() const {
String Variant::stringify(List<const void *> &stack) const {
switch (type) {
- case NIL: return "Null";
- case BOOL: return _data._bool ? "True" : "False";
- case INT: return itos(_data._int);
- case FLOAT: return rtos(_data._float);
- case STRING: return *reinterpret_cast<const String *>(_data._mem);
- case VECTOR2: return "(" + operator Vector2() + ")";
- case VECTOR2I: return "(" + operator Vector2i() + ")";
- case RECT2: return "(" + operator Rect2() + ")";
- case RECT2I: return "(" + operator Rect2i() + ")";
+ case NIL:
+ return "Null";
+ case BOOL:
+ return _data._bool ? "True" : "False";
+ case INT:
+ return itos(_data._int);
+ case FLOAT:
+ return rtos(_data._float);
+ case STRING:
+ return *reinterpret_cast<const String *>(_data._mem);
+ case VECTOR2:
+ return "(" + operator Vector2() + ")";
+ case VECTOR2I:
+ return "(" + operator Vector2i() + ")";
+ case RECT2:
+ return "(" + operator Rect2() + ")";
+ case RECT2I:
+ return "(" + operator Rect2i() + ")";
case TRANSFORM2D: {
Transform2D mat32 = operator Transform2D();
return "(" + Variant(mat32.elements[0]).operator String() + ", " + Variant(mat32.elements[1]).operator String() + ", " + Variant(mat32.elements[2]).operator String() + ")";
} break;
- case VECTOR3: return "(" + operator Vector3() + ")";
- case VECTOR3I: return "(" + operator Vector3i() + ")";
+ case VECTOR3:
+ return "(" + operator Vector3() + ")";
+ case VECTOR3I:
+ return "(" + operator Vector3i() + ")";
case PLANE:
return operator Plane();
//case QUAT:
- case AABB: return operator ::AABB();
- case QUAT: return "(" + operator Quat() + ")";
+ case AABB:
+ return operator ::AABB();
+ case QUAT:
+ return "(" + operator Quat() + ")";
case BASIS: {
Basis mat3 = operator Basis();
@@ -1846,10 +1946,14 @@ String Variant::stringify(List<const void *> &stack) const {
return mtx + ")";
} break;
- case TRANSFORM: return operator Transform();
- case STRING_NAME: return operator StringName();
- case NODE_PATH: return operator NodePath();
- case COLOR: return String::num(operator Color().r) + "," + String::num(operator Color().g) + "," + String::num(operator Color().b) + "," + String::num(operator Color().a);
+ case TRANSFORM:
+ return operator Transform();
+ case STRING_NAME:
+ return operator StringName();
+ case NODE_PATH:
+ return operator NodePath();
+ case COLOR:
+ return String::num(operator Color().r) + "," + String::num(operator Color().g) + "," + String::num(operator Color().b) + "," + String::num(operator Color().a);
case DICTIONARY: {
const Dictionary &d = *reinterpret_cast<const Dictionary *>(_data._mem);
@@ -3676,9 +3780,12 @@ bool Variant::is_shared() const {
switch (type) {
- case OBJECT: return true;
- case ARRAY: return true;
- case DICTIONARY: return true;
+ case OBJECT:
+ return true;
+ case ARRAY:
+ return true;
+ case DICTIONARY:
+ return true;
default: {
}
}
diff --git a/core/variant.h b/core/variant.h
index 1ae09ad82f..8e924be00a 100644
--- a/core/variant.h
+++ b/core/variant.h
@@ -474,7 +474,8 @@ public:
type = NIL;
}
_FORCE_INLINE_ ~Variant() {
- if (type != Variant::NIL) clear();
+ if (type != Variant::NIL)
+ clear();
}
};
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 9fffb42ff6..416a1a5fb8 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -262,6 +262,7 @@ struct _VariantCall {
VCALL_LOCALMEM3R(String, split);
VCALL_LOCALMEM3R(String, rsplit);
VCALL_LOCALMEM2R(String, split_floats);
+ VCALL_LOCALMEM1R(String, join);
VCALL_LOCALMEM0R(String, to_upper);
VCALL_LOCALMEM0R(String, to_lower);
VCALL_LOCALMEM1R(String, left);
@@ -861,9 +862,15 @@ struct _VariantCall {
static void _call_Transform2D_xform(Variant &r_ret, Variant &p_self, const Variant **p_args) {
switch (p_args[0]->type) {
- case Variant::VECTOR2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator Vector2()); return;
- case Variant::RECT2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator Rect2()); return;
- case Variant::PACKED_VECTOR2_ARRAY: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator PackedVector2Array()); return;
+ case Variant::VECTOR2:
+ r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator Vector2());
+ return;
+ case Variant::RECT2:
+ r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator Rect2());
+ return;
+ case Variant::PACKED_VECTOR2_ARRAY:
+ r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator PackedVector2Array());
+ return;
default:
r_ret = Variant();
ERR_PRINT("Invalid type in function 'xform' in base 'Transform2D'. Valid types are Vector2, Rect2, and PackedVector2Array.");
@@ -872,9 +879,15 @@ struct _VariantCall {
static void _call_Transform2D_xform_inv(Variant &r_ret, Variant &p_self, const Variant **p_args) {
switch (p_args[0]->type) {
- case Variant::VECTOR2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Vector2()); return;
- case Variant::RECT2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Rect2()); return;
- case Variant::PACKED_VECTOR2_ARRAY: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator PackedVector2Array()); return;
+ case Variant::VECTOR2:
+ r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Vector2());
+ return;
+ case Variant::RECT2:
+ r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Rect2());
+ return;
+ case Variant::PACKED_VECTOR2_ARRAY:
+ r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator PackedVector2Array());
+ return;
default:
r_ret = Variant();
ERR_PRINT("Invalid type in function 'xform_inv' in base 'Transform2D'. Valid types are Vector2, Rect2, and PackedVector2Array.");
@@ -883,7 +896,9 @@ struct _VariantCall {
static void _call_Transform2D_basis_xform(Variant &r_ret, Variant &p_self, const Variant **p_args) {
switch (p_args[0]->type) {
- case Variant::VECTOR2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->basis_xform(p_args[0]->operator Vector2()); return;
+ case Variant::VECTOR2:
+ r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->basis_xform(p_args[0]->operator Vector2());
+ return;
default:
r_ret = Variant();
ERR_PRINT("Invalid type in function 'basis_xform' in base 'Transform2D'. Only Vector2 is valid.");
@@ -892,7 +907,9 @@ struct _VariantCall {
static void _call_Transform2D_basis_xform_inv(Variant &r_ret, Variant &p_self, const Variant **p_args) {
switch (p_args[0]->type) {
- case Variant::VECTOR2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->basis_xform_inv(p_args[0]->operator Vector2()); return;
+ case Variant::VECTOR2:
+ r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->basis_xform_inv(p_args[0]->operator Vector2());
+ return;
default:
r_ret = Variant();
ERR_PRINT("Invalid type in function 'basis_xform_inv' in base 'Transform2D'. Only Vector2 is valid.");
@@ -929,10 +946,18 @@ struct _VariantCall {
static void _call_Transform_xform(Variant &r_ret, Variant &p_self, const Variant **p_args) {
switch (p_args[0]->type) {
- case Variant::VECTOR3: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Vector3()); return;
- case Variant::PLANE: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Plane()); return;
- case Variant::AABB: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator ::AABB()); return;
- case Variant::PACKED_VECTOR3_ARRAY: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator ::PackedVector3Array()); return;
+ case Variant::VECTOR3:
+ r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Vector3());
+ return;
+ case Variant::PLANE:
+ r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Plane());
+ return;
+ case Variant::AABB:
+ r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator ::AABB());
+ return;
+ case Variant::PACKED_VECTOR3_ARRAY:
+ r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator ::PackedVector3Array());
+ return;
default:
r_ret = Variant();
ERR_PRINT("Invalid type in function 'xform' in base 'Transform'. Valid types are Vector3, Plane, AABB, and PackedVector3Array.");
@@ -941,10 +966,18 @@ struct _VariantCall {
static void _call_Transform_xform_inv(Variant &r_ret, Variant &p_self, const Variant **p_args) {
switch (p_args[0]->type) {
- case Variant::VECTOR3: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Vector3()); return;
- case Variant::PLANE: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Plane()); return;
- case Variant::AABB: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator ::AABB()); return;
- case Variant::PACKED_VECTOR3_ARRAY: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator ::PackedVector3Array()); return;
+ case Variant::VECTOR3:
+ r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Vector3());
+ return;
+ case Variant::PLANE:
+ r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Plane());
+ return;
+ case Variant::AABB:
+ r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator ::AABB());
+ return;
+ case Variant::PACKED_VECTOR3_ARRAY:
+ r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator ::PackedVector3Array());
+ return;
default:
r_ret = Variant();
ERR_PRINT("Invalid type in function 'xform_inv' in base 'Transform'. Valid types are Vector3, Plane, AABB, and PackedVector3Array.");
@@ -1280,50 +1313,74 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
return Variant();
// atomic types
- case BOOL: return Variant(false);
- case INT: return 0;
- case FLOAT: return 0.0f;
+ case BOOL:
+ return Variant(false);
+ case INT:
+ return 0;
+ case FLOAT:
+ return 0.0f;
case STRING:
return String();
// math types
case VECTOR2:
return Vector2();
- case RECT2: return Rect2();
- case VECTOR3: return Vector3();
- case TRANSFORM2D: return Transform2D();
- case PLANE: return Plane();
- case QUAT: return Quat();
+ case RECT2:
+ return Rect2();
+ case VECTOR3:
+ return Vector3();
+ case TRANSFORM2D:
+ return Transform2D();
+ case PLANE:
+ return Plane();
+ case QUAT:
+ return Quat();
case AABB:
return ::AABB();
- case BASIS: return Basis();
+ case BASIS:
+ return Basis();
case TRANSFORM:
return Transform();
// misc types
- case COLOR: return Color();
+ case COLOR:
+ return Color();
case STRING_NAME:
return StringName();
case NODE_PATH:
return NodePath();
- case _RID: return RID();
- case OBJECT: return (Object *)nullptr;
- case CALLABLE: return Callable();
- case SIGNAL: return Signal();
- case DICTIONARY: return Dictionary();
+ case _RID:
+ return RID();
+ case OBJECT:
+ return (Object *)nullptr;
+ case CALLABLE:
+ return Callable();
+ case SIGNAL:
+ return Signal();
+ case DICTIONARY:
+ return Dictionary();
case ARRAY:
return Array();
- case PACKED_BYTE_ARRAY: return PackedByteArray();
- case PACKED_INT32_ARRAY: return PackedInt32Array();
- case PACKED_INT64_ARRAY: return PackedInt64Array();
- case PACKED_FLOAT32_ARRAY: return PackedFloat32Array();
- case PACKED_FLOAT64_ARRAY: return PackedFloat64Array();
- case PACKED_STRING_ARRAY: return PackedStringArray();
+ case PACKED_BYTE_ARRAY:
+ return PackedByteArray();
+ case PACKED_INT32_ARRAY:
+ return PackedInt32Array();
+ case PACKED_INT64_ARRAY:
+ return PackedInt64Array();
+ case PACKED_FLOAT32_ARRAY:
+ return PackedFloat32Array();
+ case PACKED_FLOAT64_ARRAY:
+ return PackedFloat64Array();
+ case PACKED_STRING_ARRAY:
+ return PackedStringArray();
case PACKED_VECTOR2_ARRAY:
return PackedVector2Array();
- case PACKED_VECTOR3_ARRAY: return PackedVector3Array();
- case PACKED_COLOR_ARRAY: return PackedColorArray();
- default: return Variant();
+ case PACKED_VECTOR3_ARRAY:
+ return PackedVector3Array();
+ case PACKED_COLOR_ARRAY:
+ return PackedColorArray();
+ default:
+ return Variant();
}
} else if (p_argcount == 1 && p_args[0]->type == p_type) {
@@ -1354,46 +1411,68 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
case VECTOR2I: {
return Vector2i(*p_args[0]);
}
- case RECT2: return (Rect2(*p_args[0]));
- case RECT2I: return (Rect2i(*p_args[0]));
- case VECTOR3: return (Vector3(*p_args[0]));
- case VECTOR3I: return (Vector3i(*p_args[0]));
+ case RECT2:
+ return (Rect2(*p_args[0]));
+ case RECT2I:
+ return (Rect2i(*p_args[0]));
+ case VECTOR3:
+ return (Vector3(*p_args[0]));
+ case VECTOR3I:
+ return (Vector3i(*p_args[0]));
case TRANSFORM2D:
return (Transform2D(p_args[0]->operator Transform2D()));
- case PLANE: return (Plane(*p_args[0]));
- case QUAT: return (p_args[0]->operator Quat());
+ case PLANE:
+ return (Plane(*p_args[0]));
+ case QUAT:
+ return (p_args[0]->operator Quat());
case AABB:
return (::AABB(*p_args[0]));
- case BASIS: return (Basis(p_args[0]->operator Basis()));
+ case BASIS:
+ return (Basis(p_args[0]->operator Basis()));
case TRANSFORM:
return (Transform(p_args[0]->operator Transform()));
// misc types
- case COLOR: return p_args[0]->type == Variant::STRING ? Color::html(*p_args[0]) : Color::hex(*p_args[0]);
+ case COLOR:
+ return p_args[0]->type == Variant::STRING ? Color::html(*p_args[0]) : Color::hex(*p_args[0]);
case STRING_NAME:
return (StringName(p_args[0]->operator StringName()));
case NODE_PATH:
return (NodePath(p_args[0]->operator NodePath()));
- case _RID: return (RID(*p_args[0]));
- case OBJECT: return ((Object *)(p_args[0]->operator Object *()));
- case CALLABLE: return ((Callable)(p_args[0]->operator Callable()));
- case SIGNAL: return ((Signal)(p_args[0]->operator Signal()));
- case DICTIONARY: return p_args[0]->operator Dictionary();
+ case _RID:
+ return (RID(*p_args[0]));
+ case OBJECT:
+ return ((Object *)(p_args[0]->operator Object *()));
+ case CALLABLE:
+ return ((Callable)(p_args[0]->operator Callable()));
+ case SIGNAL:
+ return ((Signal)(p_args[0]->operator Signal()));
+ case DICTIONARY:
+ return p_args[0]->operator Dictionary();
case ARRAY:
return p_args[0]->operator Array();
// arrays
- case PACKED_BYTE_ARRAY: return (PackedByteArray(*p_args[0]));
- case PACKED_INT32_ARRAY: return (PackedInt32Array(*p_args[0]));
- case PACKED_INT64_ARRAY: return (PackedInt64Array(*p_args[0]));
- case PACKED_FLOAT32_ARRAY: return (PackedFloat32Array(*p_args[0]));
- case PACKED_FLOAT64_ARRAY: return (PackedFloat64Array(*p_args[0]));
- case PACKED_STRING_ARRAY: return (PackedStringArray(*p_args[0]));
+ case PACKED_BYTE_ARRAY:
+ return (PackedByteArray(*p_args[0]));
+ case PACKED_INT32_ARRAY:
+ return (PackedInt32Array(*p_args[0]));
+ case PACKED_INT64_ARRAY:
+ return (PackedInt64Array(*p_args[0]));
+ case PACKED_FLOAT32_ARRAY:
+ return (PackedFloat32Array(*p_args[0]));
+ case PACKED_FLOAT64_ARRAY:
+ return (PackedFloat64Array(*p_args[0]));
+ case PACKED_STRING_ARRAY:
+ return (PackedStringArray(*p_args[0]));
case PACKED_VECTOR2_ARRAY:
return (PackedVector2Array(*p_args[0]));
- case PACKED_VECTOR3_ARRAY: return (PackedVector3Array(*p_args[0]));
- case PACKED_COLOR_ARRAY: return (PackedColorArray(*p_args[0]));
- default: return Variant();
+ case PACKED_VECTOR3_ARRAY:
+ return (PackedVector3Array(*p_args[0]));
+ case PACKED_COLOR_ARRAY:
+ return (PackedColorArray(*p_args[0]));
+ default:
+ return Variant();
}
} else if (p_argcount >= 1) {
@@ -1738,6 +1817,7 @@ void register_variant_methods() {
ADDFUNC3R(STRING, PACKED_STRING_ARRAY, String, split, STRING, "delimiter", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0));
ADDFUNC3R(STRING, PACKED_STRING_ARRAY, String, rsplit, STRING, "delimiter", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0));
ADDFUNC2R(STRING, PACKED_FLOAT32_ARRAY, String, split_floats, STRING, "delimiter", BOOL, "allow_empty", varray(true));
+ ADDFUNC1R(STRING, STRING, String, join, PACKED_STRING_ARRAY, "parts", varray());
ADDFUNC0R(STRING, STRING, String, to_upper, varray());
ADDFUNC0R(STRING, STRING, String, to_lower, varray());
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index 27624b81ee..4c9848f26a 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -78,38 +78,38 @@
#define TYPE(PREFIX, OP, TYPE) &&PREFIX##_##OP##_##TYPE
/* clang-format off */
-#define TYPES(PREFIX, OP) { \
- TYPE(PREFIX, OP, NIL), \
- TYPE(PREFIX, OP, BOOL), \
- TYPE(PREFIX, OP, INT), \
- TYPE(PREFIX, OP, FLOAT), \
- TYPE(PREFIX, OP, STRING), \
- TYPE(PREFIX, OP, VECTOR2), \
- TYPE(PREFIX, OP, VECTOR2I), \
- TYPE(PREFIX, OP, RECT2), \
- TYPE(PREFIX, OP, RECT2I), \
- TYPE(PREFIX, OP, VECTOR3), \
- TYPE(PREFIX, OP, VECTOR3I), \
- TYPE(PREFIX, OP, TRANSFORM2D), \
- TYPE(PREFIX, OP, PLANE), \
- TYPE(PREFIX, OP, QUAT), \
- TYPE(PREFIX, OP, AABB), \
- TYPE(PREFIX, OP, BASIS), \
- TYPE(PREFIX, OP, TRANSFORM), \
- TYPE(PREFIX, OP, COLOR), \
+#define TYPES(PREFIX, OP) { \
+ TYPE(PREFIX, OP, NIL), \
+ TYPE(PREFIX, OP, BOOL), \
+ TYPE(PREFIX, OP, INT), \
+ TYPE(PREFIX, OP, FLOAT), \
+ TYPE(PREFIX, OP, STRING), \
+ TYPE(PREFIX, OP, VECTOR2), \
+ TYPE(PREFIX, OP, VECTOR2I), \
+ TYPE(PREFIX, OP, RECT2), \
+ TYPE(PREFIX, OP, RECT2I), \
+ TYPE(PREFIX, OP, VECTOR3), \
+ TYPE(PREFIX, OP, VECTOR3I), \
+ TYPE(PREFIX, OP, TRANSFORM2D), \
+ TYPE(PREFIX, OP, PLANE), \
+ TYPE(PREFIX, OP, QUAT), \
+ TYPE(PREFIX, OP, AABB), \
+ TYPE(PREFIX, OP, BASIS), \
+ TYPE(PREFIX, OP, TRANSFORM), \
+ TYPE(PREFIX, OP, COLOR), \
TYPE(PREFIX, OP, STRING_NAME), \
- TYPE(PREFIX, OP, NODE_PATH), \
- TYPE(PREFIX, OP, _RID), \
- TYPE(PREFIX, OP, OBJECT), \
+ TYPE(PREFIX, OP, NODE_PATH), \
+ TYPE(PREFIX, OP, _RID), \
+ TYPE(PREFIX, OP, OBJECT), \
TYPE(PREFIX, OP, CALLABLE), \
- TYPE(PREFIX, OP, SIGNAL), \
- TYPE(PREFIX, OP, DICTIONARY), \
- TYPE(PREFIX, OP, ARRAY), \
+ TYPE(PREFIX, OP, SIGNAL), \
+ TYPE(PREFIX, OP, DICTIONARY), \
+ TYPE(PREFIX, OP, ARRAY), \
TYPE(PREFIX, OP, PACKED_BYTE_ARRAY), \
- TYPE(PREFIX, OP, PACKED_INT32_ARRAY), \
- TYPE(PREFIX, OP, PACKED_INT64_ARRAY), \
- TYPE(PREFIX, OP, PACKED_FLOAT32_ARRAY), \
- TYPE(PREFIX, OP, PACKED_FLOAT64_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_INT32_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_INT64_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_FLOAT32_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_FLOAT64_ARRAY), \
TYPE(PREFIX, OP, PACKED_STRING_ARRAY), \
TYPE(PREFIX, OP, PACKED_VECTOR2_ARRAY), \
TYPE(PREFIX, OP, PACKED_VECTOR3_ARRAY), \
@@ -181,21 +181,26 @@ bool Variant::booleanize() const {
return; \
}
-#define DEFAULT_OP_NUM(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == INT) _RETURN(p_a._data.m_type m_op p_b._data._int); \
- if (p_b.type == FLOAT) _RETURN(p_a._data.m_type m_op p_b._data._float); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_NUM(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == INT) \
+ _RETURN(p_a._data.m_type m_op p_b._data._int); \
+ if (p_b.type == FLOAT) \
+ _RETURN(p_a._data.m_type m_op p_b._data._float); \
+ \
+ _RETURN_FAIL \
};
-#define DEFAULT_OP_NUM_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == INT) _RETURN(p_a._data.m_type m_op p_b._data._int); \
- if (p_b.type == FLOAT) _RETURN(p_a._data.m_type m_op p_b._data._float); \
- if (p_b.type == NIL) _RETURN(!(p_b.type m_op NIL)); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_NUM_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == INT) \
+ _RETURN(p_a._data.m_type m_op p_b._data._int); \
+ if (p_b.type == FLOAT) \
+ _RETURN(p_a._data.m_type m_op p_b._data._float); \
+ if (p_b.type == NIL) \
+ _RETURN(!(p_b.type m_op NIL)); \
+ \
+ _RETURN_FAIL \
};
#ifdef DEBUG_ENABLED
@@ -219,12 +224,14 @@ bool Variant::booleanize() const {
_RETURN_FAIL \
};
#else
-#define DEFAULT_OP_NUM_DIV(m_prefix, m_op_name, m_name, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == INT) _RETURN(p_a._data.m_type / p_b._data._int); \
- if (p_b.type == FLOAT) _RETURN(p_a._data.m_type / p_b._data._float); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_NUM_DIV(m_prefix, m_op_name, m_name, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == INT) \
+ _RETURN(p_a._data.m_type / p_b._data._int); \
+ if (p_b.type == FLOAT) \
+ _RETURN(p_a._data.m_type / p_b._data._float); \
+ \
+ _RETURN_FAIL \
};
#endif
@@ -238,62 +245,84 @@ bool Variant::booleanize() const {
_RETURN(p_a._data.m_type); \
};
-#define DEFAULT_OP_NUM_VEC(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == INT) _RETURN(p_a._data.m_type m_op p_b._data._int); \
- if (p_b.type == FLOAT) _RETURN(p_a._data.m_type m_op p_b._data._float); \
- if (p_b.type == VECTOR2) _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \
- if (p_b.type == VECTOR3) _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \
- if (p_b.type == VECTOR2I) _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \
- if (p_b.type == VECTOR3I) _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_NUM_VEC(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == INT) \
+ _RETURN(p_a._data.m_type m_op p_b._data._int); \
+ if (p_b.type == FLOAT) \
+ _RETURN(p_a._data.m_type m_op p_b._data._float); \
+ if (p_b.type == VECTOR2) \
+ _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \
+ if (p_b.type == VECTOR3) \
+ _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \
+ if (p_b.type == VECTOR2I) \
+ _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \
+ if (p_b.type == VECTOR3I) \
+ _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \
+ \
+ _RETURN_FAIL \
};
-#define DEFAULT_OP_STR_REV(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const String *>(p_a._data._mem)); \
- if (p_b.type == STRING_NAME) _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const StringName *>(p_a._data._mem)); \
- if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const NodePath *>(p_a._data._mem)); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_STR_REV(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == STRING) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const String *>(p_a._data._mem)); \
+ if (p_b.type == STRING_NAME) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const StringName *>(p_a._data._mem)); \
+ if (p_b.type == NODE_PATH) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const NodePath *>(p_a._data._mem)); \
+ \
+ _RETURN_FAIL \
};
-#define DEFAULT_OP_STR(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
- if (p_b.type == STRING_NAME) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
- if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_STR(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == STRING) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
+ if (p_b.type == STRING_NAME) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
+ if (p_b.type == NODE_PATH) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
+ \
+ _RETURN_FAIL \
};
-#define DEFAULT_OP_STR_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
- if (p_b.type == STRING_NAME) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
- if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
- if (p_b.type == NIL) _RETURN(!(p_b.type m_op NIL)); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_STR_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == STRING) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
+ if (p_b.type == STRING_NAME) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
+ if (p_b.type == NODE_PATH) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
+ if (p_b.type == NIL) \
+ _RETURN(!(p_b.type m_op NIL)); \
+ \
+ _RETURN_FAIL \
};
-#define DEFAULT_OP_STR_NULL_NP(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
- if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
- if (p_b.type == NIL) _RETURN(!(p_b.type m_op NIL)); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_STR_NULL_NP(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == STRING) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
+ if (p_b.type == NODE_PATH) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
+ if (p_b.type == NIL) \
+ _RETURN(!(p_b.type m_op NIL)); \
+ \
+ _RETURN_FAIL \
};
-#define DEFAULT_OP_STR_NULL_SN(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
- if (p_b.type == STRING_NAME) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
- if (p_b.type == NIL) _RETURN(!(p_b.type m_op NIL)); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_STR_NULL_SN(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == STRING) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
+ if (p_b.type == STRING_NAME) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
+ if (p_b.type == NIL) \
+ _RETURN(!(p_b.type m_op NIL)); \
+ \
+ _RETURN_FAIL \
};
#define DEFAULT_OP_LOCALMEM_REV(m_prefix, m_op_name, m_name, m_op, m_type) \
@@ -332,13 +361,16 @@ bool Variant::booleanize() const {
_RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem)); \
}
-#define DEFAULT_OP_LOCALMEM_NUM(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == m_name) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const m_type *>(p_b._data._mem)); \
- if (p_b.type == INT) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._int); \
- if (p_b.type == FLOAT) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._float); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_LOCALMEM_NUM(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == m_name) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const m_type *>(p_b._data._mem)); \
+ if (p_b.type == INT) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._int); \
+ if (p_b.type == FLOAT) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._float); \
+ \
+ _RETURN_FAIL \
}
#define DEFAULT_OP_PTR(m_op, m_name, m_sub) \
@@ -436,7 +468,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
SWITCH(math, p_op, p_a.type) {
SWITCH_OP(math, OP_EQUAL, p_a.type) {
CASE_TYPE(math, OP_EQUAL, NIL) {
- if (p_b.type == NIL) _RETURN(true);
+ if (p_b.type == NIL)
+ _RETURN(true);
if (p_b.type == OBJECT)
_RETURN(p_b._get_obj().obj == nullptr);
@@ -532,7 +565,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
SWITCH_OP(math, OP_NOT_EQUAL, p_a.type) {
CASE_TYPE(math, OP_NOT_EQUAL, NIL) {
- if (p_b.type == NIL) _RETURN(false);
+ if (p_b.type == NIL)
+ _RETURN(false);
if (p_b.type == OBJECT)
_RETURN(p_b._get_obj().obj != nullptr);
@@ -981,7 +1015,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
case VECTOR2: {
_RETURN(p_a._data._transform2d->xform(*(const Vector2 *)p_b._data._mem));
}
- default: _RETURN_FAIL;
+ default:
+ _RETURN_FAIL;
}
}
@@ -996,7 +1031,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
case FLOAT: {
_RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) * p_b._data._float);
}
- default: _RETURN_FAIL;
+ default:
+ _RETURN_FAIL;
}
}
@@ -1008,7 +1044,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
case BASIS: {
_RETURN(*p_a._data._basis * *p_b._data._basis);
}
- default: _RETURN_FAIL;
+ default:
+ _RETURN_FAIL;
}
}
@@ -1020,7 +1057,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
case TRANSFORM: {
_RETURN(*p_a._data._transform * *p_b._data._transform);
}
- default: _RETURN_FAIL;
+ default:
+ _RETURN_FAIL;
}
}
@@ -1983,7 +2021,8 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
#define DEFAULT_OP_DVECTOR_SET(m_name, m_type, skip_cond) \
case m_name: { \
- if (skip_cond) return; \
+ if (skip_cond) \
+ return; \
\
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { \
int index = p_index; \
@@ -3458,17 +3497,39 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
return _data._float > 0.0;
} break;
case VECTOR2: {
- int64_t from = reinterpret_cast<const Vector2 *>(_data._mem)->x;
- int64_t to = reinterpret_cast<const Vector2 *>(_data._mem)->y;
+ double from = reinterpret_cast<const Vector2 *>(_data._mem)->x;
+ double to = reinterpret_cast<const Vector2 *>(_data._mem)->y;
+
+ r_iter = from;
+
+ return from < to;
+ } break;
+ case VECTOR2I: {
+ int64_t from = reinterpret_cast<const Vector2i *>(_data._mem)->x;
+ int64_t to = reinterpret_cast<const Vector2i *>(_data._mem)->y;
r_iter = from;
return from < to;
} break;
case VECTOR3: {
- int64_t from = reinterpret_cast<const Vector3 *>(_data._mem)->x;
- int64_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y;
- int64_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z;
+ double from = reinterpret_cast<const Vector3 *>(_data._mem)->x;
+ double to = reinterpret_cast<const Vector3 *>(_data._mem)->y;
+ double step = reinterpret_cast<const Vector3 *>(_data._mem)->z;
+
+ r_iter = from;
+
+ if (from == to) {
+ return false;
+ } else if (from < to) {
+ return step > 0;
+ }
+ return step < 0;
+ } break;
+ case VECTOR3I: {
+ int64_t from = reinterpret_cast<const Vector3i *>(_data._mem)->x;
+ int64_t to = reinterpret_cast<const Vector3i *>(_data._mem)->y;
+ int64_t step = reinterpret_cast<const Vector3i *>(_data._mem)->z;
r_iter = from;
@@ -3476,10 +3537,8 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
return false;
} else if (from < to) {
return step > 0;
- } else {
- return step < 0;
}
- //return true;
+ return step < 0;
} break;
case OBJECT: {
@@ -3640,7 +3699,19 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
return true;
} break;
case VECTOR2: {
- int64_t to = reinterpret_cast<const Vector2 *>(_data._mem)->y;
+ double to = reinterpret_cast<const Vector2 *>(_data._mem)->y;
+
+ double idx = r_iter;
+ idx++;
+
+ if (idx >= to)
+ return false;
+
+ r_iter = idx;
+ return true;
+ } break;
+ case VECTOR2I: {
+ int64_t to = reinterpret_cast<const Vector2i *>(_data._mem)->y;
int64_t idx = r_iter;
idx++;
@@ -3652,8 +3723,24 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
return true;
} break;
case VECTOR3: {
- int64_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y;
- int64_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z;
+ double to = reinterpret_cast<const Vector3 *>(_data._mem)->y;
+ double step = reinterpret_cast<const Vector3 *>(_data._mem)->z;
+
+ double idx = r_iter;
+ idx += step;
+
+ if (step < 0 && idx <= to)
+ return false;
+
+ if (step > 0 && idx >= to)
+ return false;
+
+ r_iter = idx;
+ return true;
+ } break;
+ case VECTOR3I: {
+ int64_t to = reinterpret_cast<const Vector3i *>(_data._mem)->y;
+ int64_t step = reinterpret_cast<const Vector3i *>(_data._mem)->z;
int64_t idx = r_iter;
idx += step;
@@ -3844,10 +3931,18 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
return r_iter;
} break;
+ case VECTOR2I: {
+
+ return r_iter;
+ } break;
case VECTOR3: {
return r_iter;
} break;
+ case VECTOR3I: {
+
+ return r_iter;
+ } break;
case OBJECT: {
if (!_get_obj().obj) {
diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp
index 0a578faf78..c9678c9933 100644
--- a/core/variant_parser.cpp
+++ b/core/variant_parser.cpp
@@ -243,11 +243,21 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
switch (next) {
- case 'b': res = 8; break;
- case 't': res = 9; break;
- case 'n': res = 10; break;
- case 'f': res = 12; break;
- case 'r': res = 13; break;
+ case 'b':
+ res = 8;
+ break;
+ case 't':
+ res = 9;
+ break;
+ case 'n':
+ res = 10;
+ break;
+ case 'f':
+ res = 12;
+ break;
+ case 'r':
+ res = 13;
+ break;
case 'u': {
//hex number
for (int j = 0; j < 4; j++) {
diff --git a/core/vector.h b/core/vector.h
index 7277179621..74e0ab91c0 100644
--- a/core/vector.h
+++ b/core/vector.h
@@ -39,6 +39,7 @@
#include "core/cowdata.h"
#include "core/error_macros.h"
+#include "core/os/copymem.h"
#include "core/os/memory.h"
#include "core/sort_array.h"
@@ -69,7 +70,8 @@ public:
void remove(int p_index) { _cowdata.remove(p_index); }
void erase(const T &p_val) {
int idx = find(p_val);
- if (idx >= 0) remove(idx);
+ if (idx >= 0)
+ remove(idx);
}
void invert();
@@ -124,6 +126,13 @@ public:
return *this;
}
+ Vector<uint8_t> to_byte_array() const {
+ Vector<uint8_t> ret;
+ ret.resize(size() * sizeof(T));
+ copymem(ret.ptrw(), ptr(), sizeof(T) * size());
+ return ret;
+ }
+
Vector<T> subarray(int p_from, int p_to) const {
if (p_from < 0) {