summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConstruct28
-rw-r--r--core/extension/extension_api_dump.cpp39
-rw-r--r--core/extension/gdnative_interface.h1
-rw-r--r--core/io/resource_format_binary.cpp7
-rw-r--r--core/math/aabb.cpp4
-rw-r--r--core/math/aabb.h1
-rw-r--r--core/math/basis.cpp4
-rw-r--r--core/math/basis.h1
-rw-r--r--core/math/math_funcs.h3
-rw-r--r--core/math/plane.cpp4
-rw-r--r--core/math/plane.h1
-rw-r--r--core/math/quaternion.cpp4
-rw-r--r--core/math/quaternion.h1
-rw-r--r--core/math/rect2.cpp4
-rw-r--r--core/math/rect2.h1
-rw-r--r--core/math/transform_2d.cpp4
-rw-r--r--core/math/transform_2d.h1
-rw-r--r--core/math/transform_3d.cpp4
-rw-r--r--core/math/transform_3d.h1
-rw-r--r--core/math/vector2.cpp4
-rw-r--r--core/math/vector2.h1
-rw-r--r--core/math/vector3.cpp4
-rw-r--r--core/math/vector3.h1
-rw-r--r--core/math/vector4.cpp4
-rw-r--r--core/math/vector4.h1
-rw-r--r--core/object/method_bind.h48
-rw-r--r--core/object/script_language_extension.h4
-rw-r--r--core/string/ustring.cpp23
-rw-r--r--core/variant/variant.cpp345
-rw-r--r--core/variant/variant_call.cpp10
-rw-r--r--core/variant/variant_destruct.cpp5
-rw-r--r--core/variant/variant_destruct.h5
-rw-r--r--core/variant/variant_internal.h25
-rw-r--r--core/variant/variant_utility.cpp5
-rw-r--r--doc/classes/@GlobalScope.xml7
-rw-r--r--doc/classes/AABB.xml6
-rw-r--r--doc/classes/AnimationPlayer.xml5
-rw-r--r--doc/classes/Basis.xml6
-rw-r--r--doc/classes/DisplayServer.xml4
-rw-r--r--doc/classes/Plane.xml6
-rw-r--r--doc/classes/ProjectSettings.xml4
-rw-r--r--doc/classes/Quaternion.xml6
-rw-r--r--doc/classes/Rect2.xml6
-rw-r--r--doc/classes/Transform2D.xml6
-rw-r--r--doc/classes/Transform3D.xml6
-rw-r--r--doc/classes/TreeItem.xml9
-rw-r--r--doc/classes/Vector2.xml6
-rw-r--r--doc/classes/Vector3.xml6
-rw-r--r--doc/classes/Vector4.xml6
-rw-r--r--drivers/SCsub2
-rw-r--r--drivers/unix/net_socket_posix.cpp4
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp12
-rw-r--r--editor/create_dialog.cpp4
-rw-r--r--editor/editor_file_system.cpp14
-rw-r--r--editor/editor_node.cpp7
-rw-r--r--editor/export/project_export.cpp4
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp29
-rw-r--r--editor/plugins/animation_player_editor_plugin.h1
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp5
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.cpp4
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.h2
-rw-r--r--editor/scene_tree_dock.cpp9
-rw-r--r--modules/gltf/gltf_document.cpp5
-rw-r--r--modules/openxr/openxr_api.cpp107
-rw-r--r--platform/android/api/jni_singleton.h5
-rw-r--r--platform/android/jni_utils.cpp5
-rw-r--r--platform/linuxbsd/display_server_x11.cpp10
-rw-r--r--platform/linuxbsd/display_server_x11.h1
-rw-r--r--platform/macos/display_server_macos.h2
-rw-r--r--platform/macos/display_server_macos.mm22
-rw-r--r--platform/macos/godot_button_view.h5
-rw-r--r--platform/macos/godot_button_view.mm22
-rw-r--r--platform/web/js/libs/library_godot_javascript_singleton.js4
-rw-r--r--platform/windows/display_server_windows.cpp14
-rw-r--r--platform/windows/display_server_windows.h4
-rw-r--r--platform/windows/joypad_windows.h2
-rw-r--r--scene/2d/light_2d.cpp2
-rw-r--r--scene/2d/skeleton_2d.cpp6
-rw-r--r--scene/2d/sprite_2d.cpp6
-rw-r--r--scene/3d/light_3d.cpp14
-rw-r--r--scene/3d/light_3d.h1
-rw-r--r--scene/3d/sprite_3d.cpp2
-rw-r--r--scene/animation/animation_player.cpp32
-rw-r--r--scene/gui/code_edit.cpp32
-rw-r--r--scene/gui/color_picker.cpp4
-rw-r--r--scene/gui/text_edit.cpp21
-rw-r--r--scene/gui/tree.cpp1
-rw-r--r--scene/main/node.cpp4
-rw-r--r--scene/resources/animation.cpp16
-rw-r--r--scene/resources/mesh.cpp5
-rw-r--r--scene/resources/resource_format_text.cpp7
-rw-r--r--scene/resources/visual_shader.cpp5
-rw-r--r--servers/display_server.h2
-rw-r--r--servers/rendering/renderer_rd/pipeline_cache_rd.cpp5
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp5
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.cpp6
-rw-r--r--servers/rendering/renderer_rd/shader_rd.cpp1
-rw-r--r--servers/rendering/renderer_rd/storage_rd/particles_storage.cpp6
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.cpp5
-rw-r--r--servers/rendering/renderer_scene_cull.cpp7
-rw-r--r--servers/rendering_server.cpp5
-rw-r--r--tests/core/math/test_aabb.h21
-rw-r--r--tests/core/math/test_basis.h34
-rw-r--r--tests/core/math/test_plane.h23
-rw-r--r--tests/core/math/test_quaternion.h57
-rw-r--r--tests/core/math/test_rect2.h21
-rw-r--r--tests/core/math/test_transform_2d.h34
-rw-r--r--tests/core/math/test_transform_3d.h23
-rw-r--r--tests/core/math/test_vector2.h26
-rw-r--r--tests/core/math/test_vector3.h45
-rw-r--r--tests/core/math/test_vector4.h78
-rw-r--r--tests/scene/test_text_edit.h17
113 files changed, 987 insertions, 586 deletions
diff --git a/SConstruct b/SConstruct
index 1eb6bdcbfd..7009cb8fbe 100644
--- a/SConstruct
+++ b/SConstruct
@@ -182,8 +182,8 @@ opts.Add(BoolVariable("deprecated", "Enable compatibility code for deprecated an
opts.Add(EnumVariable("float", "Floating-point precision", "32", ("32", "64")))
opts.Add(BoolVariable("minizip", "Enable ZIP archive support using minizip", True))
opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver", False))
-opts.Add(BoolVariable("vulkan", "Enable the vulkan video driver", True))
-opts.Add(BoolVariable("opengl3", "Enable the OpenGL/GLES3 video driver", True))
+opts.Add(BoolVariable("vulkan", "Enable the vulkan rendering driver", True))
+opts.Add(BoolVariable("opengl3", "Enable the OpenGL/GLES3 rendering driver", True))
opts.Add(BoolVariable("openxr", "Enable the OpenXR driver", True))
opts.Add(BoolVariable("use_volk", "Use the volk library to load the Vulkan loader dynamically", True))
opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "")
@@ -687,6 +687,14 @@ if selected_platform in platform_list:
if methods.using_gcc(env):
common_warnings += ["-Wshadow-local", "-Wno-misleading-indentation"]
+ if cc_version_major == 7: # Bogus warning fixed in 8+.
+ common_warnings += ["-Wno-strict-overflow"]
+ if cc_version_major < 11:
+ # Regression in GCC 9/10, spams so much in our variadic templates
+ # that we need to outright disable it.
+ common_warnings += ["-Wno-type-limits"]
+ if cc_version_major >= 12: # False positives in our error macros, see GH-58747.
+ common_warnings += ["-Wno-return-type"]
elif methods.using_clang(env) or methods.using_emcc(env):
# We often implement `operator<` for structs of pointers as a requirement
# for putting them in `Set` or `Map`. We don't mind about unreliable ordering.
@@ -702,13 +710,16 @@ if selected_platform in platform_list:
"-Wduplicated-branches",
"-Wduplicated-cond",
"-Wstringop-overflow=4",
- "-Wlogical-op",
]
)
- # -Wnoexcept was removed temporarily due to GH-36325.
env.Append(CXXFLAGS=["-Wplacement-new=1"])
+ # Need to fix a warning with AudioServer lambdas before enabling.
+ # if cc_version_major != 9: # GCC 9 had a regression (GH-36325).
+ # env.Append(CXXFLAGS=["-Wnoexcept"])
if cc_version_major >= 9:
env.Append(CCFLAGS=["-Wattribute-alias=2"])
+ if cc_version_major >= 11: # Broke on MethodBind templates before GCC 11.
+ env.Append(CCFLAGS=["-Wlogical-op"])
elif methods.using_clang(env) or methods.using_emcc(env):
env.Append(CCFLAGS=["-Wimplicit-fallthrough"])
elif env["warnings"] == "all":
@@ -720,15 +731,6 @@ if selected_platform in platform_list:
if env["werror"]:
env.Append(CCFLAGS=["-Werror"])
- # FIXME: Temporary workaround after the Vulkan merge, remove once warnings are fixed.
- if methods.using_gcc(env):
- env.Append(CXXFLAGS=["-Wno-error=cpp"])
- if cc_version_major == 7: # Bogus warning fixed in 8+.
- env.Append(CCFLAGS=["-Wno-error=strict-overflow"])
- if cc_version_major >= 12: # False positives in our error macros, see GH-58747.
- env.Append(CCFLAGS=["-Wno-error=return-type"])
- elif methods.using_clang(env) or methods.using_emcc(env):
- env.Append(CXXFLAGS=["-Wno-error=#warnings"])
if hasattr(detect, "get_program_suffix"):
suffix = "." + detect.get_program_suffix()
diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp
index e6e0fff266..96b396caa9 100644
--- a/core/extension/extension_api_dump.cpp
+++ b/core/extension/extension_api_dump.cpp
@@ -38,7 +38,15 @@
#ifdef TOOLS_ENABLED
-static String get_type_name(const PropertyInfo &p_info) {
+static String get_builtin_or_variant_type_name(const Variant::Type p_type) {
+ if (p_type == Variant::NIL) {
+ return "Variant";
+ } else {
+ return Variant::get_type_name(p_type);
+ }
+}
+
+static String get_property_info_type_name(const PropertyInfo &p_info) {
if (p_info.type == Variant::INT && (p_info.hint == PROPERTY_HINT_INT_IS_POINTER)) {
if (p_info.hint_string.is_empty()) {
return "void*";
@@ -70,7 +78,7 @@ static String get_type_name(const PropertyInfo &p_info) {
if (p_info.type == Variant::NIL) {
return "void";
}
- return Variant::get_type_name(p_info.type);
+ return get_builtin_or_variant_type_name(p_info.type);
}
Dictionary NativeExtensionAPIDump::generate_extension_api() {
@@ -430,8 +438,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
Dictionary arg;
String argname = vararg ? "arg" + itos(i + 1) : Variant::get_utility_function_argument_name(name, i);
arg["name"] = argname;
- Variant::Type argtype = Variant::get_utility_function_argument_type(name, i);
- arg["type"] = argtype == Variant::NIL ? String("Variant") : Variant::get_type_name(argtype);
+ arg["type"] = get_builtin_or_variant_type_name(Variant::get_utility_function_argument_type(name, i));
//no default value support in utility functions
arguments.push_back(arg);
}
@@ -461,8 +468,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
Dictionary d;
d["name"] = Variant::get_type_name(type);
if (Variant::has_indexing(type)) {
- Variant::Type index_type = Variant::get_indexed_element_type(type);
- d["indexing_return_type"] = index_type == Variant::NIL ? String("Variant") : Variant::get_type_name(index_type);
+ d["indexing_return_type"] = get_builtin_or_variant_type_name(Variant::get_indexed_element_type(type));
}
d["is_keyed"] = Variant::is_keyed(type);
@@ -476,7 +482,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
for (const StringName &member_name : member_names) {
Dictionary d2;
d2["name"] = String(member_name);
- d2["type"] = Variant::get_type_name(Variant::get_member_type(type, member_name));
+ d2["type"] = get_builtin_or_variant_type_name(Variant::get_member_type(type, member_name));
members.push_back(d2);
}
if (members.size()) {
@@ -493,7 +499,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
Dictionary d2;
d2["name"] = String(constant_name);
Variant constant = Variant::get_constant_value(type, constant_name);
- d2["type"] = Variant::get_type_name(constant.get_type());
+ d2["type"] = get_builtin_or_variant_type_name(constant.get_type());
d2["value"] = constant.get_construct_string();
constants.push_back(d2);
}
@@ -544,9 +550,9 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
Dictionary d2;
d2["name"] = Variant::get_operator_name(Variant::Operator(k));
if (k != Variant::OP_NEGATE && k != Variant::OP_POSITIVE && k != Variant::OP_NOT && k != Variant::OP_BIT_NEGATE) {
- d2["right_type"] = Variant::get_type_name(Variant::Type(j));
+ d2["right_type"] = get_builtin_or_variant_type_name(Variant::Type(j));
}
- d2["return_type"] = Variant::get_type_name(Variant::get_operator_return_type(Variant::Operator(k), type, Variant::Type(j)));
+ d2["return_type"] = get_builtin_or_variant_type_name(Variant::get_operator_return_type(Variant::Operator(k), type, Variant::Type(j)));
operators.push_back(d2);
}
}
@@ -580,8 +586,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
for (int j = 0; j < argcount; j++) {
Dictionary d3;
d3["name"] = Variant::get_builtin_method_argument_name(type, method_name, j);
- Variant::Type argtype = Variant::get_builtin_method_argument_type(type, method_name, j);
- d3["type"] = argtype == Variant::NIL ? String("Variant") : Variant::get_type_name(argtype);
+ d3["type"] = get_builtin_or_variant_type_name(Variant::get_builtin_method_argument_type(type, method_name, j));
if (j >= (argcount - default_args.size())) {
int dargidx = j - (argcount - default_args.size());
@@ -613,7 +618,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
for (int k = 0; k < argcount; k++) {
Dictionary d3;
d3["name"] = Variant::get_constructor_argument_name(type, j, k);
- d3["type"] = Variant::get_type_name(Variant::get_constructor_argument_type(type, j, k));
+ d3["type"] = get_builtin_or_variant_type_name(Variant::get_constructor_argument_type(type, j, k));
arguments.push_back(d3);
}
if (arguments.size()) {
@@ -741,7 +746,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
d3["name"] = pinfo.name;
}
- d3["type"] = get_type_name(pinfo);
+ d3["type"] = get_property_info_type_name(pinfo);
if (i == -1) {
d2["return_value"] = d3;
@@ -784,7 +789,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
if (i >= 0) {
d3["name"] = pinfo.name;
}
- d3["type"] = get_type_name(pinfo);
+ d3["type"] = get_property_info_type_name(pinfo);
if (method->get_argument_meta(i) > 0) {
static const char *argmeta[11] = { "none", "int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", "uint64", "float", "double" };
@@ -831,7 +836,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
for (int i = 0; i < F.arguments.size(); i++) {
Dictionary d3;
d3["name"] = F.arguments[i].name;
- d3["type"] = get_type_name(F.arguments[i]);
+ d3["type"] = get_property_info_type_name(F.arguments[i]);
arguments.push_back(d3);
}
if (arguments.size()) {
@@ -863,7 +868,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
}
StringName property_name = F.name;
Dictionary d2;
- d2["type"] = get_type_name(F);
+ d2["type"] = get_property_info_type_name(F);
d2["name"] = String(property_name);
d2["setter"] = ClassDB::get_property_setter(class_name, F.name);
d2["getter"] = ClassDB::get_property_getter(class_name, F.name);
diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h
index 39378d8261..9ac5cc9398 100644
--- a/core/extension/gdnative_interface.h
+++ b/core/extension/gdnative_interface.h
@@ -231,7 +231,6 @@ typedef void (*GDNativeExtensionClassUnreference)(GDExtensionClassInstancePtr p_
typedef void (*GDNativeExtensionClassCallVirtual)(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);
typedef GDNativeObjectPtr (*GDNativeExtensionClassCreateInstance)(void *p_userdata);
typedef void (*GDNativeExtensionClassFreeInstance)(void *p_userdata, GDExtensionClassInstancePtr p_instance);
-typedef void (*GDNativeExtensionClassObjectInstance)(GDExtensionClassInstancePtr p_instance, GDNativeObjectPtr p_object_instance);
typedef GDNativeExtensionClassCallVirtual (*GDNativeExtensionClassGetVirtual)(void *p_userdata, const char *p_name);
typedef struct {
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 2a79067e02..4611528db7 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -1042,7 +1042,14 @@ void ResourceLoaderBinary::open(Ref<FileAccess> p_f, bool p_no_resources, bool p
// If a UID is found and the path is valid, it will be used, otherwise, it falls back to the path.
er.path = ResourceUID::get_singleton()->get_id_path(er.uid);
} else {
+#ifdef TOOLS_ENABLED
+ // Silence a warning that can happen during the initial filesystem scan due to cache being regenerated.
+ if (ResourceLoader::get_resource_uid(res_path) != er.uid) {
+ WARN_PRINT(String(res_path + ": In external resource #" + itos(i) + ", invalid UUID: " + ResourceUID::get_singleton()->id_to_text(er.uid) + " - using text path instead: " + er.path).utf8().get_data());
+ }
+#else
WARN_PRINT(String(res_path + ": In external resource #" + itos(i) + ", invalid UUID: " + ResourceUID::get_singleton()->id_to_text(er.uid) + " - using text path instead: " + er.path).utf8().get_data());
+#endif
}
}
}
diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp
index 026f179445..fcf245d2ad 100644
--- a/core/math/aabb.cpp
+++ b/core/math/aabb.cpp
@@ -76,6 +76,10 @@ bool AABB::is_equal_approx(const AABB &p_aabb) const {
return position.is_equal_approx(p_aabb.position) && size.is_equal_approx(p_aabb.size);
}
+bool AABB::is_finite() const {
+ return position.is_finite() && size.is_finite();
+}
+
AABB AABB::intersection(const AABB &p_aabb) const {
#ifdef MATH_CHECKS
if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
diff --git a/core/math/aabb.h b/core/math/aabb.h
index b9f777c6cf..9d5837ad37 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -63,6 +63,7 @@ struct _NO_DISCARD_ AABB {
bool operator!=(const AABB &p_rval) const;
bool is_equal_approx(const AABB &p_aabb) const;
+ bool is_finite() const;
_FORCE_INLINE_ bool intersects(const AABB &p_aabb) const; /// Both AABBs overlap
_FORCE_INLINE_ bool intersects_inclusive(const AABB &p_aabb) const; /// Both AABBs (or their faces) overlap
_FORCE_INLINE_ bool encloses(const AABB &p_aabb) const; /// p_aabb is completely inside this
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index 845686f339..9b8188eed8 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -691,6 +691,10 @@ bool Basis::is_equal_approx(const Basis &p_basis) const {
return rows[0].is_equal_approx(p_basis.rows[0]) && rows[1].is_equal_approx(p_basis.rows[1]) && rows[2].is_equal_approx(p_basis.rows[2]);
}
+bool Basis::is_finite() const {
+ return rows[0].is_finite() && rows[1].is_finite() && rows[2].is_finite();
+}
+
bool Basis::operator==(const Basis &p_matrix) const {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
diff --git a/core/math/basis.h b/core/math/basis.h
index cc2924f5ff..69bef5a7be 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -134,6 +134,7 @@ struct _NO_DISCARD_ Basis {
}
bool is_equal_approx(const Basis &p_basis) const;
+ bool is_finite() const;
bool operator==(const Basis &p_matrix) const;
bool operator!=(const Basis &p_matrix) const;
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 7fa674a23d..0af529ad98 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -184,6 +184,9 @@ public:
#endif
}
+ static _ALWAYS_INLINE_ bool is_finite(double p_val) { return isfinite(p_val); }
+ static _ALWAYS_INLINE_ bool is_finite(float p_val) { return isfinite(p_val); }
+
static _ALWAYS_INLINE_ double abs(double g) { return absd(g); }
static _ALWAYS_INLINE_ float abs(float g) { return absf(g); }
static _ALWAYS_INLINE_ int abs(int g) { return g > 0 ? g : -g; }
diff --git a/core/math/plane.cpp b/core/math/plane.cpp
index 3b2eab4ae2..a5d2fe5628 100644
--- a/core/math/plane.cpp
+++ b/core/math/plane.cpp
@@ -176,6 +176,10 @@ 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);
}
+bool Plane::is_finite() const {
+ return normal.is_finite() && Math::is_finite(d);
+}
+
Plane::operator String() const {
return "[N: " + normal.operator String() + ", D: " + String::num_real(d, false) + "]";
}
diff --git a/core/math/plane.h b/core/math/plane.h
index 73babfa496..77da59fb27 100644
--- a/core/math/plane.h
+++ b/core/math/plane.h
@@ -74,6 +74,7 @@ struct _NO_DISCARD_ Plane {
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;
+ bool is_finite() const;
_FORCE_INLINE_ bool operator==(const Plane &p_plane) const;
_FORCE_INLINE_ bool operator!=(const Plane &p_plane) const;
diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp
index 4a8d29e402..6a5f29f3d8 100644
--- a/core/math/quaternion.cpp
+++ b/core/math/quaternion.cpp
@@ -79,6 +79,10 @@ bool Quaternion::is_equal_approx(const Quaternion &p_quaternion) const {
return Math::is_equal_approx(x, p_quaternion.x) && Math::is_equal_approx(y, p_quaternion.y) && Math::is_equal_approx(z, p_quaternion.z) && Math::is_equal_approx(w, p_quaternion.w);
}
+bool Quaternion::is_finite() const {
+ return Math::is_finite(x) && Math::is_finite(y) && Math::is_finite(z) && Math::is_finite(w);
+}
+
real_t Quaternion::length() const {
return Math::sqrt(length_squared());
}
diff --git a/core/math/quaternion.h b/core/math/quaternion.h
index 178cfaca70..7aa400aa8c 100644
--- a/core/math/quaternion.h
+++ b/core/math/quaternion.h
@@ -55,6 +55,7 @@ struct _NO_DISCARD_ Quaternion {
}
_FORCE_INLINE_ real_t length_squared() const;
bool is_equal_approx(const Quaternion &p_quaternion) const;
+ bool is_finite() const;
real_t length() const;
void normalize();
Quaternion normalized() const;
diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp
index 9e78ead816..facf4eb3c4 100644
--- a/core/math/rect2.cpp
+++ b/core/math/rect2.cpp
@@ -38,6 +38,10 @@ bool Rect2::is_equal_approx(const Rect2 &p_rect) const {
return position.is_equal_approx(p_rect.position) && size.is_equal_approx(p_rect.size);
}
+bool Rect2::is_finite() const {
+ return position.is_finite() && size.is_finite();
+}
+
bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos, Point2 *r_normal) const {
#ifdef MATH_CHECKS
if (unlikely(size.x < 0 || size.y < 0)) {
diff --git a/core/math/rect2.h b/core/math/rect2.h
index 50dd2dc1df..9863405d8e 100644
--- a/core/math/rect2.h
+++ b/core/math/rect2.h
@@ -207,6 +207,7 @@ struct _NO_DISCARD_ Rect2 {
}
bool is_equal_approx(const Rect2 &p_rect) const;
+ bool is_finite() const;
bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; }
bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; }
diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp
index 2bfefe979f..548a82d254 100644
--- a/core/math/transform_2d.cpp
+++ b/core/math/transform_2d.cpp
@@ -168,6 +168,10 @@ bool Transform2D::is_equal_approx(const Transform2D &p_transform) const {
return columns[0].is_equal_approx(p_transform.columns[0]) && columns[1].is_equal_approx(p_transform.columns[1]) && columns[2].is_equal_approx(p_transform.columns[2]);
}
+bool Transform2D::is_finite() const {
+ return columns[0].is_finite() && columns[1].is_finite() && columns[2].is_finite();
+}
+
Transform2D Transform2D::looking_at(const Vector2 &p_target) const {
Transform2D return_trans = Transform2D(get_rotation(), get_origin());
Vector2 target_position = affine_inverse().xform(p_target);
diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h
index f23f32867a..2b11f36535 100644
--- a/core/math/transform_2d.h
+++ b/core/math/transform_2d.h
@@ -98,6 +98,7 @@ struct _NO_DISCARD_ Transform2D {
void orthonormalize();
Transform2D orthonormalized() const;
bool is_equal_approx(const Transform2D &p_transform) const;
+ bool is_finite() const;
Transform2D looking_at(const Vector2 &p_target) const;
diff --git a/core/math/transform_3d.cpp b/core/math/transform_3d.cpp
index 6741ef4034..3285cbd664 100644
--- a/core/math/transform_3d.cpp
+++ b/core/math/transform_3d.cpp
@@ -174,6 +174,10 @@ bool Transform3D::is_equal_approx(const Transform3D &p_transform) const {
return basis.is_equal_approx(p_transform.basis) && origin.is_equal_approx(p_transform.origin);
}
+bool Transform3D::is_finite() const {
+ return basis.is_finite() && origin.is_finite();
+}
+
bool Transform3D::operator==(const Transform3D &p_transform) const {
return (basis == p_transform.basis && origin == p_transform.origin);
}
diff --git a/core/math/transform_3d.h b/core/math/transform_3d.h
index 44d6d826f3..cb347aa1c1 100644
--- a/core/math/transform_3d.h
+++ b/core/math/transform_3d.h
@@ -75,6 +75,7 @@ struct _NO_DISCARD_ Transform3D {
void orthogonalize();
Transform3D orthogonalized() const;
bool is_equal_approx(const Transform3D &p_transform) const;
+ bool is_finite() const;
bool operator==(const Transform3D &p_transform) const;
bool operator!=(const Transform3D &p_transform) const;
diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp
index 56dbba393a..5366587126 100644
--- a/core/math/vector2.cpp
+++ b/core/math/vector2.cpp
@@ -186,6 +186,10 @@ bool Vector2::is_zero_approx() const {
return Math::is_zero_approx(x) && Math::is_zero_approx(y);
}
+bool Vector2::is_finite() const {
+ return Math::is_finite(x) && Math::is_finite(y);
+}
+
Vector2::operator String() const {
return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ")";
}
diff --git a/core/math/vector2.h b/core/math/vector2.h
index 75364f72f0..5775d8e735 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -121,6 +121,7 @@ struct _NO_DISCARD_ Vector2 {
bool is_equal_approx(const Vector2 &p_v) const;
bool is_zero_approx() const;
+ bool is_finite() const;
Vector2 operator+(const Vector2 &p_v) const;
void operator+=(const Vector2 &p_v);
diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp
index 55ba509144..b106200c4a 100644
--- a/core/math/vector3.cpp
+++ b/core/math/vector3.cpp
@@ -139,6 +139,10 @@ bool Vector3::is_zero_approx() const {
return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z);
}
+bool Vector3::is_finite() const {
+ return Math::is_finite(x) && Math::is_finite(y) && Math::is_finite(z);
+}
+
Vector3::operator String() const {
return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ")";
}
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 62e810fb4d..19771eb312 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -136,6 +136,7 @@ struct _NO_DISCARD_ Vector3 {
bool is_equal_approx(const Vector3 &p_v) const;
bool is_zero_approx() const;
+ bool is_finite() const;
/* Operators */
diff --git a/core/math/vector4.cpp b/core/math/vector4.cpp
index 9fd980aaff..3b189f7ed4 100644
--- a/core/math/vector4.cpp
+++ b/core/math/vector4.cpp
@@ -64,6 +64,10 @@ bool Vector4::is_zero_approx() const {
return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z) && Math::is_zero_approx(w);
}
+bool Vector4::is_finite() const {
+ return Math::is_finite(x) && Math::is_finite(y) && Math::is_finite(z) && Math::is_finite(w);
+}
+
real_t Vector4::length() const {
return Math::sqrt(length_squared());
}
diff --git a/core/math/vector4.h b/core/math/vector4.h
index ac7b6c3aee..7c4bdc1788 100644
--- a/core/math/vector4.h
+++ b/core/math/vector4.h
@@ -71,6 +71,7 @@ struct _NO_DISCARD_ Vector4 {
_FORCE_INLINE_ real_t length_squared() const;
bool is_equal_approx(const Vector4 &p_vec4) const;
bool is_zero_approx() const;
+ bool is_finite() const;
real_t length() const;
void normalize();
Vector4 normalized() const;
diff --git a/core/object/method_bind.h b/core/object/method_bind.h
index 0d3e40f709..598e8a224d 100644
--- a/core/object/method_bind.h
+++ b/core/object/method_bind.h
@@ -292,11 +292,6 @@ class MethodBindT : public MethodBind {
void (MB_T::*method)(P...);
protected:
-// GCC raises warnings in the case P = {} as the comparison is always false...
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wlogical-op"
-#endif
virtual Variant::Type _gen_argument_type(int p_arg) const override {
if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
return call_get_argument_type<P...>(p_arg);
@@ -304,9 +299,6 @@ protected:
return Variant::NIL;
}
}
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
PropertyInfo pi;
@@ -367,11 +359,6 @@ class MethodBindTC : public MethodBind {
void (MB_T::*method)(P...) const;
protected:
-// GCC raises warnings in the case P = {} as the comparison is always false...
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wlogical-op"
-#endif
virtual Variant::Type _gen_argument_type(int p_arg) const override {
if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
return call_get_argument_type<P...>(p_arg);
@@ -379,9 +366,6 @@ protected:
return Variant::NIL;
}
}
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
PropertyInfo pi;
@@ -444,11 +428,6 @@ class MethodBindTR : public MethodBind {
(P...);
protected:
-// GCC raises warnings in the case P = {} as the comparison is always false...
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wlogical-op"
-#endif
virtual Variant::Type _gen_argument_type(int p_arg) const override {
if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
return call_get_argument_type<P...>(p_arg);
@@ -466,9 +445,6 @@ protected:
return GetTypeInfo<R>::get_class_info();
}
}
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
public:
#ifdef DEBUG_METHODS_ENABLED
@@ -531,11 +507,6 @@ class MethodBindTRC : public MethodBind {
(P...) const;
protected:
-// GCC raises warnings in the case P = {} as the comparison is always false...
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wlogical-op"
-#endif
virtual Variant::Type _gen_argument_type(int p_arg) const override {
if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
return call_get_argument_type<P...>(p_arg);
@@ -553,9 +524,6 @@ protected:
return GetTypeInfo<R>::get_class_info();
}
}
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
public:
#ifdef DEBUG_METHODS_ENABLED
@@ -615,11 +583,6 @@ class MethodBindTS : public MethodBind {
void (*function)(P...);
protected:
-// GCC raises warnings in the case P = {} as the comparison is always false...
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wlogical-op"
-#endif
virtual Variant::Type _gen_argument_type(int p_arg) const override {
if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
return call_get_argument_type<P...>(p_arg);
@@ -627,9 +590,6 @@ protected:
return Variant::NIL;
}
}
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
PropertyInfo pi;
@@ -678,11 +638,6 @@ class MethodBindTRS : public MethodBind {
(P...);
protected:
-// GCC raises warnings in the case P = {} as the comparison is always false...
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wlogical-op"
-#endif
virtual Variant::Type _gen_argument_type(int p_arg) const override {
if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
return call_get_argument_type<P...>(p_arg);
@@ -690,9 +645,6 @@ protected:
return GetTypeInfo<R>::VARIANT_TYPE;
}
}
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h
index 7e74f6a2be..15e2d57a3a 100644
--- a/core/object/script_language_extension.h
+++ b/core/object/script_language_extension.h
@@ -82,9 +82,7 @@ public:
GDVIRTUAL_REQUIRED_CALL(_get_documentation, doc);
Vector<DocData::ClassDoc> class_doc;
-#ifndef _MSC_VER
-#warning missing conversion from documentation to ClassDoc
-#endif
+ // TODO: Missing conversion from documentation to ClassDoc.
return class_doc;
}
#endif // TOOLS_ENABLED
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index 6218c21cde..872c8357ae 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -3669,13 +3669,16 @@ String String::simplify_path() const {
String drive;
if (s.begins_with("local://")) {
drive = "local://";
- s = s.substr(8, s.length());
+ s = s.substr(8);
} else if (s.begins_with("res://")) {
drive = "res://";
- s = s.substr(6, s.length());
+ s = s.substr(6);
} else if (s.begins_with("user://")) {
drive = "user://";
- s = s.substr(7, s.length());
+ s = s.substr(7);
+ } else if (s.begins_with("uid://")) {
+ drive = "uid://";
+ s = s.substr(6);
} else if (is_network_share_path()) {
drive = s.substr(0, 2);
s = s.substr(2, s.length() - 2);
@@ -3689,7 +3692,7 @@ String String::simplify_path() const {
}
if (p != -1 && p < s.find("/")) {
drive = s.substr(0, p + 2);
- s = s.substr(p + 2, s.length());
+ s = s.substr(p + 2);
}
}
@@ -4651,10 +4654,10 @@ String String::sprintf(const Array &values, bool *error) const {
double value = values[value_index];
bool is_negative = (value < 0);
String str = String::num(ABS(value), min_decimals);
- bool not_numeric = isinf(value) || isnan(value);
+ const bool is_finite = Math::is_finite(value);
// Pad decimals out.
- if (!not_numeric) {
+ if (is_finite) {
str = str.pad_decimals(min_decimals);
}
@@ -4662,7 +4665,7 @@ String String::sprintf(const Array &values, bool *error) const {
// Padding. Leave room for sign later if required.
int pad_chars_count = (is_negative || show_sign) ? min_chars - 1 : min_chars;
- String pad_char = (pad_with_zeros && !not_numeric) ? String("0") : String(" "); // Never pad NaN or inf with zeros
+ String pad_char = (pad_with_zeros && is_finite) ? String("0") : String(" "); // Never pad NaN or inf with zeros
if (left_justified) {
str = str.rpad(pad_chars_count, pad_char);
} else {
@@ -4713,10 +4716,10 @@ String String::sprintf(const Array &values, bool *error) const {
for (int i = 0; i < count; i++) {
double val = vec[i];
String number_str = String::num(ABS(val), min_decimals);
- bool not_numeric = isinf(val) || isnan(val);
+ const bool is_finite = Math::is_finite(val);
// Pad decimals out.
- if (!not_numeric) {
+ if (is_finite) {
number_str = number_str.pad_decimals(min_decimals);
}
@@ -4724,7 +4727,7 @@ String String::sprintf(const Array &values, bool *error) const {
// Padding. Leave room for sign later if required.
int pad_chars_count = val < 0 ? min_chars - 1 : min_chars;
- String pad_char = (pad_with_zeros && !not_numeric) ? String("0") : String(" "); // Never pad NaN or inf with zeros
+ String pad_char = (pad_with_zeros && is_finite) ? String("0") : String(" "); // Never pad NaN or inf with zeros
if (left_justified) {
number_str = number_str.rpad(pad_chars_count, pad_char);
} else {
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index 4eae23b0fb..c14df58281 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -47,146 +47,126 @@ String Variant::get_type_name(Variant::Type p_type) {
switch (p_type) {
case NIL: {
return "Nil";
- } break;
+ }
- // atomic types
+ // Atomic types.
case BOOL: {
return "bool";
- } break;
+ }
case INT: {
return "int";
-
- } break;
+ }
case FLOAT: {
return "float";
-
- } break;
+ }
case STRING: {
return "String";
- } break;
+ }
- // math types
+ // Math types.
case VECTOR2: {
return "Vector2";
- } break;
+ }
case VECTOR2I: {
return "Vector2i";
- } break;
+ }
case RECT2: {
return "Rect2";
- } break;
+ }
case RECT2I: {
return "Rect2i";
- } break;
+ }
case TRANSFORM2D: {
return "Transform2D";
- } break;
+ }
case VECTOR3: {
return "Vector3";
- } break;
+ }
case VECTOR3I: {
return "Vector3i";
- } break;
+ }
case VECTOR4: {
return "Vector4";
- } break;
+ }
case VECTOR4I: {
return "Vector4i";
- } break;
+ }
case PLANE: {
return "Plane";
-
- } break;
+ }
case AABB: {
return "AABB";
- } break;
+ }
case QUATERNION: {
return "Quaternion";
-
- } break;
+ }
case BASIS: {
return "Basis";
-
- } break;
+ }
case TRANSFORM3D: {
return "Transform3D";
-
- } break;
+ }
case PROJECTION: {
return "Projection";
+ }
- } break;
-
- // misc types
+ // Miscellaneous types.
case COLOR: {
return "Color";
-
- } break;
+ }
case RID: {
return "RID";
- } break;
+ }
case OBJECT: {
return "Object";
- } break;
+ }
case CALLABLE: {
return "Callable";
- } break;
+ }
case SIGNAL: {
return "Signal";
- } break;
+ }
case STRING_NAME: {
return "StringName";
-
- } break;
+ }
case NODE_PATH: {
return "NodePath";
-
- } break;
+ }
case DICTIONARY: {
return "Dictionary";
-
- } break;
+ }
case ARRAY: {
return "Array";
+ }
- } break;
-
- // arrays
+ // Arrays.
case PACKED_BYTE_ARRAY: {
return "PackedByteArray";
-
- } break;
+ }
case PACKED_INT32_ARRAY: {
return "PackedInt32Array";
-
- } break;
+ }
case PACKED_INT64_ARRAY: {
return "PackedInt64Array";
-
- } break;
+ }
case PACKED_FLOAT32_ARRAY: {
return "PackedFloat32Array";
-
- } break;
+ }
case PACKED_FLOAT64_ARRAY: {
return "PackedFloat64Array";
-
- } break;
+ }
case PACKED_STRING_ARRAY: {
return "PackedStringArray";
- } break;
+ }
case PACKED_VECTOR2_ARRAY: {
return "PackedVector2Array";
-
- } break;
+ }
case PACKED_VECTOR3_ARRAY: {
return "PackedVector3Array";
-
- } break;
+ }
case PACKED_COLOR_ARRAY: {
return "PackedColorArray";
-
- } break;
+ }
default: {
}
}
@@ -880,157 +860,126 @@ bool Variant::is_zero() const {
switch (type) {
case NIL: {
return true;
- } break;
+ }
- // atomic types
+ // Atomic types.
case BOOL: {
return !(_data._bool);
- } break;
+ }
case INT: {
return _data._int == 0;
-
- } break;
+ }
case FLOAT: {
return _data._float == 0;
-
- } break;
+ }
case STRING: {
return *reinterpret_cast<const String *>(_data._mem) == String();
+ }
- } break;
-
- // math types
+ // Math types.
case VECTOR2: {
return *reinterpret_cast<const Vector2 *>(_data._mem) == Vector2();
-
- } break;
+ }
case VECTOR2I: {
return *reinterpret_cast<const Vector2i *>(_data._mem) == Vector2i();
-
- } break;
+ }
case RECT2: {
return *reinterpret_cast<const Rect2 *>(_data._mem) == Rect2();
-
- } break;
+ }
case RECT2I: {
return *reinterpret_cast<const Rect2i *>(_data._mem) == Rect2i();
-
- } break;
+ }
case TRANSFORM2D: {
return *_data._transform2d == Transform2D();
-
- } break;
+ }
case VECTOR3: {
return *reinterpret_cast<const Vector3 *>(_data._mem) == Vector3();
-
- } break;
+ }
case VECTOR3I: {
return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i();
-
- } break;
+ }
case VECTOR4: {
return *reinterpret_cast<const Vector4 *>(_data._mem) == Vector4();
-
- } break;
+ }
case VECTOR4I: {
return *reinterpret_cast<const Vector4i *>(_data._mem) == Vector4i();
-
- } break;
+ }
case PLANE: {
return *reinterpret_cast<const Plane *>(_data._mem) == Plane();
-
- } break;
+ }
case AABB: {
return *_data._aabb == ::AABB();
- } break;
+ }
case QUATERNION: {
return *reinterpret_cast<const Quaternion *>(_data._mem) == Quaternion();
-
- } break;
+ }
case BASIS: {
return *_data._basis == Basis();
-
- } break;
+ }
case TRANSFORM3D: {
return *_data._transform3d == Transform3D();
-
- } break;
+ }
case PROJECTION: {
return *_data._projection == Projection();
+ }
- } break;
-
- // misc types
+ // Miscellaneous types.
case COLOR: {
return *reinterpret_cast<const Color *>(_data._mem) == Color();
-
- } break;
+ }
case RID: {
return *reinterpret_cast<const ::RID *>(_data._mem) == ::RID();
- } break;
+ }
case OBJECT: {
return _get_obj().obj == nullptr;
- } break;
+ }
case CALLABLE: {
return reinterpret_cast<const Callable *>(_data._mem)->is_null();
- } break;
+ }
case SIGNAL: {
return reinterpret_cast<const Signal *>(_data._mem)->is_null();
- } break;
+ }
case STRING_NAME: {
return *reinterpret_cast<const StringName *>(_data._mem) != StringName();
-
- } break;
+ }
case NODE_PATH: {
return reinterpret_cast<const NodePath *>(_data._mem)->is_empty();
-
- } break;
+ }
case DICTIONARY: {
return reinterpret_cast<const Dictionary *>(_data._mem)->is_empty();
-
- } break;
+ }
case ARRAY: {
return reinterpret_cast<const Array *>(_data._mem)->is_empty();
+ }
- } break;
-
- // arrays
+ // Arrays.
case PACKED_BYTE_ARRAY: {
return PackedArrayRef<uint8_t>::get_array(_data.packed_array).size() == 0;
-
- } break;
+ }
case PACKED_INT32_ARRAY: {
return PackedArrayRef<int32_t>::get_array(_data.packed_array).size() == 0;
-
- } break;
+ }
case PACKED_INT64_ARRAY: {
return PackedArrayRef<int64_t>::get_array(_data.packed_array).size() == 0;
-
- } break;
+ }
case PACKED_FLOAT32_ARRAY: {
return PackedArrayRef<float>::get_array(_data.packed_array).size() == 0;
-
- } break;
+ }
case PACKED_FLOAT64_ARRAY: {
return PackedArrayRef<double>::get_array(_data.packed_array).size() == 0;
-
- } break;
+ }
case PACKED_STRING_ARRAY: {
return PackedArrayRef<String>::get_array(_data.packed_array).size() == 0;
-
- } break;
+ }
case PACKED_VECTOR2_ARRAY: {
return PackedArrayRef<Vector2>::get_array(_data.packed_array).size() == 0;
-
- } break;
+ }
case PACKED_VECTOR3_ARRAY: {
return PackedArrayRef<Vector3>::get_array(_data.packed_array).size() == 0;
-
- } break;
+ }
case PACKED_COLOR_ARRAY: {
return PackedArrayRef<Color>::get_array(_data.packed_array).size() == 0;
-
- } break;
+ }
default: {
}
}
@@ -1042,60 +991,49 @@ bool Variant::is_one() const {
switch (type) {
case NIL: {
return true;
- } break;
+ }
- // atomic types
case BOOL: {
return _data._bool;
- } break;
+ }
case INT: {
return _data._int == 1;
-
- } break;
+ }
case FLOAT: {
return _data._float == 1;
+ }
- } break;
case VECTOR2: {
return *reinterpret_cast<const Vector2 *>(_data._mem) == Vector2(1, 1);
-
- } break;
+ }
case VECTOR2I: {
return *reinterpret_cast<const Vector2i *>(_data._mem) == Vector2i(1, 1);
-
- } break;
+ }
case RECT2: {
return *reinterpret_cast<const Rect2 *>(_data._mem) == Rect2(1, 1, 1, 1);
-
- } break;
+ }
case RECT2I: {
return *reinterpret_cast<const Rect2i *>(_data._mem) == Rect2i(1, 1, 1, 1);
-
- } break;
+ }
case VECTOR3: {
return *reinterpret_cast<const Vector3 *>(_data._mem) == Vector3(1, 1, 1);
-
- } break;
+ }
case VECTOR3I: {
return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i(1, 1, 1);
-
- } break;
+ }
case VECTOR4: {
return *reinterpret_cast<const Vector4 *>(_data._mem) == Vector4(1, 1, 1, 1);
-
- } break;
+ }
case VECTOR4I: {
return *reinterpret_cast<const Vector4i *>(_data._mem) == Vector4i(1, 1, 1, 1);
-
- } break;
+ }
case PLANE: {
return *reinterpret_cast<const Plane *>(_data._mem) == Plane(1, 1, 1, 1);
+ }
- } break;
case COLOR: {
return *reinterpret_cast<const Color *>(_data._mem) == Color(1, 1, 1, 1);
-
- } break;
+ }
default: {
return !is_zero();
@@ -1133,10 +1071,10 @@ void Variant::reference(const Variant &p_variant) {
switch (p_variant.type) {
case NIL: {
- // none
+ // None.
} break;
- // atomic types
+ // Atomic types.
case BOOL: {
_data._bool = p_variant._data._bool;
} break;
@@ -1150,7 +1088,7 @@ void Variant::reference(const Variant &p_variant) {
memnew_placement(_data._mem, String(*reinterpret_cast<const String *>(p_variant._data._mem)));
} break;
- // math types
+ // Math types.
case VECTOR2: {
memnew_placement(_data._mem, Vector2(*reinterpret_cast<const Vector2 *>(p_variant._data._mem)));
} break;
@@ -1202,10 +1140,9 @@ void Variant::reference(const Variant &p_variant) {
memnew_placement(_data._projection, Projection(*p_variant._data._projection));
} break;
- // misc types
+ // Miscellaneous types.
case COLOR: {
memnew_placement(_data._mem, Color(*reinterpret_cast<const Color *>(p_variant._data._mem)));
-
} break;
case RID: {
memnew_placement(_data._mem, ::RID(*reinterpret_cast<const ::RID *>(p_variant._data._mem)));
@@ -1224,7 +1161,6 @@ void Variant::reference(const Variant &p_variant) {
_get_obj().obj = const_cast<Object *>(p_variant._get_obj().obj);
_get_obj().id = p_variant._get_obj().id;
-
} break;
case CALLABLE: {
memnew_placement(_data._mem, Callable(*reinterpret_cast<const Callable *>(p_variant._data._mem)));
@@ -1234,84 +1170,71 @@ void Variant::reference(const Variant &p_variant) {
} break;
case STRING_NAME: {
memnew_placement(_data._mem, StringName(*reinterpret_cast<const StringName *>(p_variant._data._mem)));
-
} break;
case NODE_PATH: {
memnew_placement(_data._mem, NodePath(*reinterpret_cast<const NodePath *>(p_variant._data._mem)));
-
} break;
case DICTIONARY: {
memnew_placement(_data._mem, Dictionary(*reinterpret_cast<const Dictionary *>(p_variant._data._mem)));
-
} break;
case ARRAY: {
memnew_placement(_data._mem, Array(*reinterpret_cast<const Array *>(p_variant._data._mem)));
-
} break;
- // arrays
+ // Arrays.
case PACKED_BYTE_ARRAY: {
_data.packed_array = static_cast<PackedArrayRef<uint8_t> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<uint8_t>::create();
}
-
} break;
case PACKED_INT32_ARRAY: {
_data.packed_array = static_cast<PackedArrayRef<int32_t> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<int32_t>::create();
}
-
} break;
case PACKED_INT64_ARRAY: {
_data.packed_array = static_cast<PackedArrayRef<int64_t> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<int64_t>::create();
}
-
} break;
case PACKED_FLOAT32_ARRAY: {
_data.packed_array = static_cast<PackedArrayRef<float> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<float>::create();
}
-
} break;
case PACKED_FLOAT64_ARRAY: {
_data.packed_array = static_cast<PackedArrayRef<double> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<double>::create();
}
-
} break;
case PACKED_STRING_ARRAY: {
_data.packed_array = static_cast<PackedArrayRef<String> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<String>::create();
}
-
} break;
case PACKED_VECTOR2_ARRAY: {
_data.packed_array = static_cast<PackedArrayRef<Vector2> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<Vector2>::create();
}
-
} break;
case PACKED_VECTOR3_ARRAY: {
_data.packed_array = static_cast<PackedArrayRef<Vector3> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<Vector3>::create();
}
-
} break;
case PACKED_COLOR_ARRAY: {
_data.packed_array = static_cast<PackedArrayRef<Color> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<Color>::create();
}
-
} break;
default: {
}
@@ -1331,6 +1254,7 @@ void Variant::zero() {
case FLOAT:
this->_data._float = 0;
break;
+
case VECTOR2:
*reinterpret_cast<Vector2 *>(this->_data._mem) = Vector2();
break;
@@ -1361,9 +1285,11 @@ void Variant::zero() {
case QUATERNION:
*reinterpret_cast<Quaternion *>(this->_data._mem) = Quaternion();
break;
+
case COLOR:
*reinterpret_cast<Color *>(this->_data._mem) = Color();
break;
+
default:
this->clear();
break;
@@ -1375,15 +1301,8 @@ void Variant::_clear_internal() {
case STRING: {
reinterpret_cast<String *>(_data._mem)->~String();
} break;
- /*
- // no point, they don't allocate memory
- VECTOR3,
- PLANE,
- QUATERNION,
- COLOR,
- VECTOR2,
- RECT2
- */
+
+ // Math types.
case TRANSFORM2D: {
if (_data._transform2d) {
_data._transform2d->~Transform2D();
@@ -1419,7 +1338,8 @@ void Variant::_clear_internal() {
_data._projection = nullptr;
}
} break;
- // misc types
+
+ // Miscellaneous types.
case STRING_NAME: {
reinterpret_cast<StringName *>(_data._mem)->~StringName();
} break;
@@ -1428,7 +1348,7 @@ void Variant::_clear_internal() {
} break;
case OBJECT: {
if (_get_obj().id.is_ref_counted()) {
- //we are safe that there is a reference here
+ // We are safe that there is a reference here.
RefCounted *ref_counted = static_cast<RefCounted *>(_get_obj().obj);
if (ref_counted->unreference()) {
memdelete(ref_counted);
@@ -1438,8 +1358,8 @@ void Variant::_clear_internal() {
_get_obj().id = ObjectID();
} break;
case RID: {
- // not much need probably
- // Can't seem to use destructor + scoping operator, so hack.
+ // Not much need probably.
+ // HACK: Can't seem to use destructor + scoping operator, so hack.
typedef ::RID RID_Class;
reinterpret_cast<RID_Class *>(_data._mem)->~RID_Class();
} break;
@@ -1455,7 +1375,8 @@ void Variant::_clear_internal() {
case ARRAY: {
reinterpret_cast<Array *>(_data._mem)->~Array();
} break;
- // arrays
+
+ // Arrays.
case PACKED_BYTE_ARRAY: {
PackedArrayRefBase::destroy(_data.packed_array);
} break;
@@ -1484,7 +1405,9 @@ void Variant::_clear_internal() {
PackedArrayRefBase::destroy(_data.packed_array);
} break;
default: {
- } /* not needed */
+ // Not needed, there is no point. The following do not allocate memory:
+ // VECTOR2, VECTOR3, RECT2, PLANE, QUATERNION, COLOR.
+ }
}
}
@@ -1863,34 +1786,34 @@ String Variant::stringify(int recursion_count) const {
str += " }";
return str;
- } break;
+ }
case PACKED_VECTOR2_ARRAY: {
return stringify_vector(operator Vector<Vector2>(), recursion_count);
- } break;
+ }
case PACKED_VECTOR3_ARRAY: {
return stringify_vector(operator Vector<Vector3>(), recursion_count);
- } break;
+ }
case PACKED_COLOR_ARRAY: {
return stringify_vector(operator Vector<Color>(), recursion_count);
- } break;
+ }
case PACKED_STRING_ARRAY: {
return stringify_vector(operator Vector<String>(), recursion_count);
- } break;
+ }
case PACKED_BYTE_ARRAY: {
return stringify_vector(operator Vector<uint8_t>(), recursion_count);
- } break;
+ }
case PACKED_INT32_ARRAY: {
return stringify_vector(operator Vector<int32_t>(), recursion_count);
- } break;
+ }
case PACKED_INT64_ARRAY: {
return stringify_vector(operator Vector<int64_t>(), recursion_count);
- } break;
+ }
case PACKED_FLOAT32_ARRAY: {
return stringify_vector(operator Vector<float>(), recursion_count);
- } break;
+ }
case PACKED_FLOAT64_ARRAY: {
return stringify_vector(operator Vector<double>(), recursion_count);
- } break;
+ }
case ARRAY: {
Array arr = operator Array();
if (recursion_count > MAX_RECURSION) {
@@ -1899,8 +1822,7 @@ String Variant::stringify(int recursion_count) const {
}
return stringify_vector(arr, recursion_count);
-
- } break;
+ }
case OBJECT: {
if (_get_obj().obj) {
if (!_get_obj().id.is_ref_counted() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
@@ -1911,20 +1833,19 @@ String Variant::stringify(int recursion_count) const {
} else {
return "<Object#null>";
}
-
- } break;
+ }
case CALLABLE: {
const Callable &c = *reinterpret_cast<const Callable *>(_data._mem);
return c;
- } break;
+ }
case SIGNAL: {
const Signal &s = *reinterpret_cast<const Signal *>(_data._mem);
return s;
- } break;
+ }
case RID: {
const ::RID &s = *reinterpret_cast<const ::RID *>(_data._mem);
return "RID(" + itos(s.get_id()) + ")";
- } break;
+ }
default: {
return "<" + get_type_name(type) + ">";
}
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 1831f7b72a..900e3d8e77 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1606,6 +1606,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector2, is_normalized, sarray(), varray());
bind_method(Vector2, is_equal_approx, sarray("to"), varray());
bind_method(Vector2, is_zero_approx, sarray(), varray());
+ bind_method(Vector2, is_finite, sarray(), varray());
bind_method(Vector2, posmod, sarray("mod"), varray());
bind_method(Vector2, posmodv, sarray("modv"), varray());
bind_method(Vector2, project, sarray("b"), varray());
@@ -1653,6 +1654,7 @@ static void _register_variant_builtin_methods() {
bind_method(Rect2, has_area, sarray(), varray());
bind_method(Rect2, has_point, sarray("point"), varray());
bind_method(Rect2, is_equal_approx, sarray("rect"), varray());
+ bind_method(Rect2, is_finite, sarray(), varray());
bind_method(Rect2, intersects, sarray("b", "include_borders"), varray(false));
bind_method(Rect2, encloses, sarray("b"), varray());
bind_method(Rect2, intersection, sarray("b"), varray());
@@ -1695,6 +1697,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector3, is_normalized, sarray(), varray());
bind_method(Vector3, is_equal_approx, sarray("to"), varray());
bind_method(Vector3, is_zero_approx, sarray(), varray());
+ bind_method(Vector3, is_finite, sarray(), varray());
bind_method(Vector3, inverse, sarray(), varray());
bind_method(Vector3, clamp, sarray("min", "max"), varray());
bind_method(Vector3, snapped, sarray("step"), varray());
@@ -1759,6 +1762,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector4, inverse, sarray(), varray());
bind_method(Vector4, is_equal_approx, sarray("with"), varray());
bind_method(Vector4, is_zero_approx, sarray(), varray());
+ bind_method(Vector4, is_finite, sarray(), varray());
/* Vector4i */
@@ -1775,6 +1779,7 @@ static void _register_variant_builtin_methods() {
bind_method(Plane, normalized, sarray(), varray());
bind_method(Plane, center, sarray(), varray());
bind_method(Plane, is_equal_approx, sarray("to_plane"), varray());
+ bind_method(Plane, is_finite, sarray(), varray());
bind_method(Plane, is_point_over, sarray("point"), varray());
bind_method(Plane, distance_to, sarray("point"), varray());
bind_method(Plane, has_point, sarray("point", "tolerance"), varray(CMP_EPSILON));
@@ -1790,6 +1795,7 @@ static void _register_variant_builtin_methods() {
bind_method(Quaternion, normalized, sarray(), varray());
bind_method(Quaternion, is_normalized, sarray(), varray());
bind_method(Quaternion, is_equal_approx, sarray("to"), varray());
+ bind_method(Quaternion, is_finite, sarray(), varray());
bind_method(Quaternion, inverse, sarray(), varray());
bind_method(Quaternion, log, sarray(), varray());
bind_method(Quaternion, exp, sarray(), varray());
@@ -1909,6 +1915,7 @@ static void _register_variant_builtin_methods() {
bind_method(Transform2D, basis_xform_inv, sarray("v"), varray());
bind_method(Transform2D, interpolate_with, sarray("xform", "weight"), varray());
bind_method(Transform2D, is_equal_approx, sarray("xform"), varray());
+ bind_method(Transform2D, is_finite, sarray(), varray());
bind_method(Transform2D, set_rotation, sarray("rotation"), varray());
bind_method(Transform2D, set_scale, sarray("scale"), varray());
bind_method(Transform2D, set_skew, sarray("skew"), varray());
@@ -1929,6 +1936,7 @@ static void _register_variant_builtin_methods() {
bind_method(Basis, tdotz, sarray("with"), varray());
bind_method(Basis, slerp, sarray("to", "weight"), varray());
bind_method(Basis, is_equal_approx, sarray("b"), varray());
+ bind_method(Basis, is_finite, sarray(), varray());
bind_method(Basis, get_rotation_quaternion, sarray(), varray());
bind_static_method(Basis, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0)));
bind_static_method(Basis, from_scale, sarray("scale"), varray());
@@ -1943,6 +1951,7 @@ static void _register_variant_builtin_methods() {
bind_method(AABB, has_surface, sarray(), varray());
bind_method(AABB, has_point, sarray("point"), varray());
bind_method(AABB, is_equal_approx, sarray("aabb"), varray());
+ bind_method(AABB, is_finite, sarray(), varray());
bind_method(AABB, intersects, sarray("with"), varray());
bind_method(AABB, encloses, sarray("with"), varray());
bind_method(AABB, intersects_plane, sarray("plane"), varray());
@@ -1975,6 +1984,7 @@ static void _register_variant_builtin_methods() {
bind_method(Transform3D, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0)));
bind_method(Transform3D, interpolate_with, sarray("xform", "weight"), varray());
bind_method(Transform3D, is_equal_approx, sarray("xform"), varray());
+ bind_method(Transform3D, is_finite, sarray(), varray());
/* Projection */
diff --git a/core/variant/variant_destruct.cpp b/core/variant/variant_destruct.cpp
index ab8303f3ae..5117c33e2b 100644
--- a/core/variant/variant_destruct.cpp
+++ b/core/variant/variant_destruct.cpp
@@ -41,13 +41,8 @@ static void add_destructor() {
void Variant::_register_variant_destructors() {
add_destructor<VariantDestruct<String>>();
- add_destructor<VariantDestruct<Transform2D>>();
- add_destructor<VariantDestruct<::AABB>>();
- add_destructor<VariantDestruct<Basis>>();
- add_destructor<VariantDestruct<Transform3D>>();
add_destructor<VariantDestruct<StringName>>();
add_destructor<VariantDestruct<NodePath>>();
- add_destructor<VariantDestruct<::RID>>();
add_destructor<VariantDestruct<Callable>>();
add_destructor<VariantDestruct<Signal>>();
add_destructor<VariantDestruct<Dictionary>>();
diff --git a/core/variant/variant_destruct.h b/core/variant/variant_destruct.h
index 5e3478635d..2730110c0f 100644
--- a/core/variant/variant_destruct.h
+++ b/core/variant/variant_destruct.h
@@ -50,13 +50,8 @@ struct VariantDestruct {};
}
MAKE_PTRDESTRUCT(String);
-MAKE_PTRDESTRUCT(Transform2D);
-MAKE_PTRDESTRUCT(AABB);
-MAKE_PTRDESTRUCT(Basis);
-MAKE_PTRDESTRUCT(Transform3D);
MAKE_PTRDESTRUCT(StringName);
MAKE_PTRDESTRUCT(NodePath);
-MAKE_PTRDESTRUCT(RID);
MAKE_PTRDESTRUCT(Callable);
MAKE_PTRDESTRUCT(Signal);
MAKE_PTRDESTRUCT(Dictionary);
diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h
index 874a183d29..7ae2368fe4 100644
--- a/core/variant/variant_internal.h
+++ b/core/variant/variant_internal.h
@@ -1047,7 +1047,7 @@ struct VariantInternalAccessor<PackedColorArray> {
template <>
struct VariantInternalAccessor<Object *> {
static _FORCE_INLINE_ Object *get(const Variant *v) { return const_cast<Object *>(*VariantInternal::get_object(v)); }
- static _FORCE_INLINE_ void set(Variant *v, const Object *p_value) { *VariantInternal::get_object(v) = const_cast<Object *>(p_value); }
+ static _FORCE_INLINE_ void set(Variant *v, const Object *p_value) { VariantInternal::object_assign(v, p_value); }
};
template <>
@@ -1532,27 +1532,4 @@ struct VariantTypeConstructor {
}
};
-template <>
-struct VariantTypeConstructor<Object *> {
- _FORCE_INLINE_ static void variant_from_type(void *p_variant, void *p_value) {
- Variant *variant = reinterpret_cast<Variant *>(p_variant);
- VariantInitializer<Object *>::init(variant);
- Object *object = *(reinterpret_cast<Object **>(p_value));
- if (object) {
- if (object->is_ref_counted()) {
- if (!VariantInternal::initialize_ref(object)) {
- return;
- }
- }
- VariantInternalAccessor<Object *>::set(variant, object);
- VariantInternalAccessor<ObjectID>::set(variant, object->get_instance_id());
- }
- }
-
- _FORCE_INLINE_ static void type_from_variant(void *p_value, void *p_variant) {
- Object **value = reinterpret_cast<Object **>(p_value);
- *value = VariantInternalAccessor<Object *>::get(reinterpret_cast<Variant *>(p_variant));
- }
-};
-
#endif // VARIANT_INTERNAL_H
diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp
index 670b66d53e..3843c32bcc 100644
--- a/core/variant/variant_utility.cpp
+++ b/core/variant/variant_utility.cpp
@@ -310,6 +310,10 @@ struct VariantUtilityFunctions {
return Math::is_zero_approx(x);
}
+ static inline bool is_finite(double x) {
+ return Math::is_finite(x);
+ }
+
static inline double ease(float x, float curve) {
return Math::ease(x, curve);
}
@@ -1420,6 +1424,7 @@ void Variant::_register_variant_utility_functions() {
FUNCBINDR(is_equal_approx, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(is_zero_approx, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
+ FUNCBINDR(is_finite, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(ease, sarray("x", "curve"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(step_decimals, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 6e9e82bbf0..43f85fcdbc 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -476,6 +476,13 @@
Infinity values of the same sign are considered equal.
</description>
</method>
+ <method name="is_finite">
+ <return type="bool" />
+ <param index="0" name="x" type="float" />
+ <description>
+ Returns whether [code]x[/code] is a finite value, i.e. it is not [constant @GDScript.NAN], positive infinity, or negative infinity.
+ </description>
+ </method>
<method name="is_inf">
<return type="bool" />
<param index="0" name="x" type="float" />
diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml
index 23dd41f275..1ac3e6b64c 100644
--- a/doc/classes/AABB.xml
+++ b/doc/classes/AABB.xml
@@ -205,6 +205,12 @@
Returns [code]true[/code] if this [AABB] and [param aabb] are approximately equal, by calling [method @GlobalScope.is_equal_approx] on each component.
</description>
</method>
+ <method name="is_finite" qualifiers="const">
+ <return type="bool" />
+ <description>
+ Returns [code]true[/code] if this [AABB] is finite, by calling [method @GlobalScope.is_finite] on each component.
+ </description>
+ </method>
<method name="merge" qualifiers="const">
<return type="AABB" />
<param index="0" name="with" type="AABB" />
diff --git a/doc/classes/AnimationPlayer.xml b/doc/classes/AnimationPlayer.xml
index b7ac1ff7f8..c32cc5c5b8 100644
--- a/doc/classes/AnimationPlayer.xml
+++ b/doc/classes/AnimationPlayer.xml
@@ -268,6 +268,11 @@
[b]Note:[/b] This signal is not emitted if an animation is looping.
</description>
</signal>
+ <signal name="animation_libraries_updated">
+ <description>
+ Notifies when the animation libraries have changed.
+ </description>
+ </signal>
<signal name="animation_list_changed">
<description>
Notifies when an animation list is changed.
diff --git a/doc/classes/Basis.xml b/doc/classes/Basis.xml
index 6d9b679fbc..f499be34a0 100644
--- a/doc/classes/Basis.xml
+++ b/doc/classes/Basis.xml
@@ -112,6 +112,12 @@
Returns [code]true[/code] if this basis and [param b] are approximately equal, by calling [code]is_equal_approx[/code] on each component.
</description>
</method>
+ <method name="is_finite" qualifiers="const">
+ <return type="bool" />
+ <description>
+ Returns [code]true[/code] if this basis is finite, by calling [method @GlobalScope.is_finite] on each component.
+ </description>
+ </method>
<method name="looking_at" qualifiers="static">
<return type="Basis" />
<param index="0" name="target" type="Vector3" />
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index 0dbaa9c86f..85d9fd34ca 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -1116,10 +1116,10 @@
</description>
</method>
<method name="window_get_safe_title_margins" qualifiers="const">
- <return type="Vector2i" />
+ <return type="Vector3i" />
<param index="0" name="window_id" type="int" default="0" />
<description>
- Returns left and right margins of the title that are safe to use (contains no buttons or other elements) when [constant WINDOW_FLAG_EXTEND_TO_TITLE] flag is set.
+ Returns left margins ([code]x[/code]), right margins ([code]y[/code]) adn height ([code]z[/code]) of the title that are safe to use (contains no buttons or other elements) when [constant WINDOW_FLAG_EXTEND_TO_TITLE] flag is set.
</description>
</method>
<method name="window_get_size" qualifiers="const">
diff --git a/doc/classes/Plane.xml b/doc/classes/Plane.xml
index e51e3753fc..fbe8afa8d1 100644
--- a/doc/classes/Plane.xml
+++ b/doc/classes/Plane.xml
@@ -119,6 +119,12 @@
Returns [code]true[/code] if this plane and [param to_plane] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component.
</description>
</method>
+ <method name="is_finite" qualifiers="const">
+ <return type="bool" />
+ <description>
+ Returns [code]true[/code] if this plane is finite, by calling [method @GlobalScope.is_finite] on each component.
+ </description>
+ </method>
<method name="is_point_over" qualifiers="const">
<return type="bool" />
<param index="0" name="point" type="Vector3" />
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 214f087d78..f86ab17b08 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -2100,8 +2100,6 @@
<member name="rendering/renderer/rendering_method.web" type="String" setter="" getter="" default="&quot;gl_compatibility&quot;">
Override for [member rendering/renderer/rendering_method] on web.
</member>
- <member name="rendering/rendering_device/descriptor_pools/max_descriptors_per_pool" type="int" setter="" getter="" default="64">
- </member>
<member name="rendering/rendering_device/driver" type="String" setter="" getter="" default="&quot;vulkan&quot;">
Sets the driver to be used by the renderer when using a RenderingDevice-based renderer like the clustered renderer or the mobile renderer. This property can not be edited directly, instead, set the driver using the platform-specific overrides.
</member>
@@ -2126,6 +2124,8 @@
</member>
<member name="rendering/rendering_device/staging_buffer/texture_upload_region_size_px" type="int" setter="" getter="" default="64">
</member>
+ <member name="rendering/rendering_device/vulkan/max_descriptors_per_pool" type="int" setter="" getter="" default="64">
+ </member>
<member name="rendering/scaling_3d/fsr_sharpness" type="float" setter="" getter="" default="0.2">
Determines how sharp the upscaled image will be when using the FSR upscaling mode. Sharpness halves with every whole number. Values go from 0.0 (sharpest) to 2.0. Values above 2.0 won't make a visible difference.
</member>
diff --git a/doc/classes/Quaternion.xml b/doc/classes/Quaternion.xml
index f21ebf57e2..99dffeff9d 100644
--- a/doc/classes/Quaternion.xml
+++ b/doc/classes/Quaternion.xml
@@ -115,6 +115,12 @@
Returns [code]true[/code] if this quaternion and [param to] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component.
</description>
</method>
+ <method name="is_finite" qualifiers="const">
+ <return type="bool" />
+ <description>
+ Returns [code]true[/code] if this quaternion is finite, by calling [method @GlobalScope.is_finite] on each component.
+ </description>
+ </method>
<method name="is_normalized" qualifiers="const">
<return type="bool" />
<description>
diff --git a/doc/classes/Rect2.xml b/doc/classes/Rect2.xml
index ac012e9604..28fe42afae 100644
--- a/doc/classes/Rect2.xml
+++ b/doc/classes/Rect2.xml
@@ -165,6 +165,12 @@
Returns [code]true[/code] if this [Rect2] and [param rect] are approximately equal, by calling [code]is_equal_approx[/code] on each component.
</description>
</method>
+ <method name="is_finite" qualifiers="const">
+ <return type="bool" />
+ <description>
+ Returns [code]true[/code] if this [Rect2] is finite, by calling [method @GlobalScope.is_finite] on each component.
+ </description>
+ </method>
<method name="merge" qualifiers="const">
<return type="Rect2" />
<param index="0" name="b" type="Rect2" />
diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml
index 905b3d77af..23d20a5a75 100644
--- a/doc/classes/Transform2D.xml
+++ b/doc/classes/Transform2D.xml
@@ -123,6 +123,12 @@
Returns [code]true[/code] if this transform and [code]transform[/code] are approximately equal, by calling [code]is_equal_approx[/code] on each component.
</description>
</method>
+ <method name="is_finite" qualifiers="const">
+ <return type="bool" />
+ <description>
+ Returns [code]true[/code] if this transform is finite, by calling [method @GlobalScope.is_finite] on each component.
+ </description>
+ </method>
<method name="looking_at" qualifiers="const">
<return type="Transform2D" />
<param index="0" name="target" type="Vector2" default="Vector2(0, 0)" />
diff --git a/doc/classes/Transform3D.xml b/doc/classes/Transform3D.xml
index 18b4f9e6f9..b3145ea022 100644
--- a/doc/classes/Transform3D.xml
+++ b/doc/classes/Transform3D.xml
@@ -82,6 +82,12 @@
Returns [code]true[/code] if this transform and [code]transform[/code] are approximately equal, by calling [code]is_equal_approx[/code] on each component.
</description>
</method>
+ <method name="is_finite" qualifiers="const">
+ <return type="bool" />
+ <description>
+ Returns [code]true[/code] if this transform is finite, by calling [method @GlobalScope.is_finite] on each component.
+ </description>
+ </method>
<method name="looking_at" qualifiers="const">
<return type="Transform3D" />
<param index="0" name="target" type="Vector3" />
diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml
index c109dc57f7..a8ffef427f 100644
--- a/doc/classes/TreeItem.xml
+++ b/doc/classes/TreeItem.xml
@@ -425,6 +425,15 @@
Sets the given column's button [Texture2D] at index [param button_idx] to [param button].
</description>
</method>
+ <method name="set_button_color">
+ <return type="void" />
+ <param index="0" name="column" type="int" />
+ <param index="1" name="button_idx" type="int" />
+ <param index="2" name="color" type="Color" />
+ <description>
+ Sets the given column's button color at index [param button_idx] to [param color].
+ </description>
+ </method>
<method name="set_button_disabled">
<return type="void" />
<param index="0" name="column" type="int" />
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index e1852340c0..5590f82336 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -206,6 +206,12 @@
Returns [code]true[/code] if this vector and [code]v[/code] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component.
</description>
</method>
+ <method name="is_finite" qualifiers="const">
+ <return type="bool" />
+ <description>
+ Returns [code]true[/code] if this vector is finite, by calling [method @GlobalScope.is_finite] on each component.
+ </description>
+ </method>
<method name="is_normalized" qualifiers="const">
<return type="bool" />
<description>
diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml
index 1ef84050cd..81e8dd2260 100644
--- a/doc/classes/Vector3.xml
+++ b/doc/classes/Vector3.xml
@@ -174,6 +174,12 @@
Returns [code]true[/code] if this vector and [param to] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component.
</description>
</method>
+ <method name="is_finite" qualifiers="const">
+ <return type="bool" />
+ <description>
+ Returns [code]true[/code] if this vector is finite, by calling [method @GlobalScope.is_finite] on each component.
+ </description>
+ </method>
<method name="is_normalized" qualifiers="const">
<return type="bool" />
<description>
diff --git a/doc/classes/Vector4.xml b/doc/classes/Vector4.xml
index fdc93f82ec..662d0bce3a 100644
--- a/doc/classes/Vector4.xml
+++ b/doc/classes/Vector4.xml
@@ -135,6 +135,12 @@
Returns [code]true[/code] if this vector and [param with] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component.
</description>
</method>
+ <method name="is_finite" qualifiers="const">
+ <return type="bool" />
+ <description>
+ Returns [code]true[/code] if this vector is finite, by calling [method @GlobalScope.is_finite] on each component.
+ </description>
+ </method>
<method name="is_normalized" qualifiers="const">
<return type="bool" />
<description>
diff --git a/drivers/SCsub b/drivers/SCsub
index dd81fc645c..6cfcb1d18c 100644
--- a/drivers/SCsub
+++ b/drivers/SCsub
@@ -24,6 +24,7 @@ SConscript("winmidi/SCsub")
# Graphics drivers
if env["vulkan"]:
+ SConscript("spirv-reflect/SCsub")
SConscript("vulkan/SCsub")
if env["opengl3"]:
SConscript("gl_context/SCsub")
@@ -31,7 +32,6 @@ if env["opengl3"]:
# Core dependencies
SConscript("png/SCsub")
-SConscript("spirv-reflect/SCsub")
env.add_source_files(env.drivers_sources, "*.cpp")
diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp
index 72ae609fb4..c6b327eeee 100644
--- a/drivers/unix/net_socket_posix.cpp
+++ b/drivers/unix/net_socket_posix.cpp
@@ -179,8 +179,8 @@ NetSocketPosix::~NetSocketPosix() {
close();
}
-// Silent a warning reported in #27594
-
+// Silence a warning reported in GH-27594.
+// EAGAIN and EWOULDBLOCK have the same value on most platforms, but it's not guaranteed.
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wlogical-op"
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 9b193056c2..036489a9bc 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -1655,9 +1655,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
image_create_info.pNext = nullptr;
image_create_info.flags = 0;
-#ifndef _MSC_VER
-#warning TODO check for support via RenderingDevice to enable on mobile when possible
-#endif
+ // TODO: Check for support via RenderingDevice to enable on mobile when possible.
#ifndef ANDROID_ENABLED
@@ -5172,9 +5170,9 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
uint32_t offset = 0;
uint8_t *binptr = ret.ptrw();
binptr[0] = 'G';
- binptr[1] = 'V';
+ binptr[1] = 'S';
binptr[2] = 'B';
- binptr[3] = 'D'; // Godot vulkan binary data.
+ binptr[3] = 'D'; // Godot Shader Binary Data.
offset += 4;
encode_uint32(SHADER_BINARY_VERSION, binptr + offset);
offset += sizeof(uint32_t);
@@ -5235,7 +5233,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_
uint32_t read_offset = 0;
// Consistency check.
ERR_FAIL_COND_V(binsize < sizeof(uint32_t) * 3 + sizeof(RenderingDeviceVulkanShaderBinaryData), RID());
- ERR_FAIL_COND_V(binptr[0] != 'G' || binptr[1] != 'V' || binptr[2] != 'B' || binptr[3] != 'D', RID());
+ ERR_FAIL_COND_V(binptr[0] != 'G' || binptr[1] != 'S' || binptr[2] != 'B' || binptr[3] != 'D', RID());
uint32_t bin_version = decode_uint32(binptr + 4);
ERR_FAIL_COND_V(bin_version != SHADER_BINARY_VERSION, RID());
@@ -9393,7 +9391,7 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de
ERR_CONTINUE(err != OK);
}
- max_descriptors_per_pool = GLOBAL_DEF("rendering/rendering_device/descriptor_pools/max_descriptors_per_pool", 64);
+ max_descriptors_per_pool = GLOBAL_DEF("rendering/rendering_device/vulkan/max_descriptors_per_pool", 64);
// Check to make sure DescriptorPoolKey is good.
static_assert(sizeof(uint64_t) * 3 >= UNIFORM_TYPE_MAX * sizeof(uint16_t));
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index ceca428306..7a4e58c6f9 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -752,9 +752,7 @@ CreateDialog::CreateDialog() {
favorites->connect("cell_selected", callable_mp(this, &CreateDialog::_favorite_selected));
favorites->connect("item_activated", callable_mp(this, &CreateDialog::_favorite_activated));
favorites->add_theme_constant_override("draw_guides", 1);
-#ifndef _MSC_VER
-#warning cannot forward drag data to a non control, must be fixed
-#endif
+ // Cannot forward drag data to a non control, must be fixed.
//favorites->set_drag_forwarding(this);
fav_vb->add_margin_child(TTR("Favorites:"), favorites, true);
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index 6f34c677db..c28bb18891 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -2259,7 +2259,7 @@ void EditorFileSystem::move_group_file(const String &p_path, const String &p_new
ResourceUID::ID EditorFileSystem::_resource_saver_get_resource_id_for_path(const String &p_path, bool p_generate) {
if (!p_path.is_resource_file() || p_path.begins_with(ProjectSettings::get_singleton()->get_project_data_path())) {
- //saved externally (configuration file) or internal file, do not assign an ID.
+ // Saved externally (configuration file) or internal file, do not assign an ID.
return ResourceUID::INVALID_ID;
}
@@ -2267,15 +2267,21 @@ ResourceUID::ID EditorFileSystem::_resource_saver_get_resource_id_for_path(const
int cpos = -1;
if (!singleton->_find_file(p_path, &fs, cpos)) {
+ // Fallback to ResourceLoader if filesystem cache fails (can happen during scanning etc.).
+ ResourceUID::ID fallback = ResourceLoader::get_resource_uid(p_path);
+ if (fallback != ResourceUID::INVALID_ID) {
+ return fallback;
+ }
+
if (p_generate) {
- return ResourceUID::get_singleton()->create_id(); //just create a new one, we will be notified of save anyway and fetch the right UUID at that time, to keep things simple.
+ return ResourceUID::get_singleton()->create_id(); // Just create a new one, we will be notified of save anyway and fetch the right UUID at that time, to keep things simple.
} else {
return ResourceUID::INVALID_ID;
}
} else if (fs->files[cpos]->uid != ResourceUID::INVALID_ID) {
return fs->files[cpos]->uid;
} else if (p_generate) {
- return ResourceUID::get_singleton()->create_id(); //just create a new one, we will be notified of save anyway and fetch the right UUID at that time, to keep things simple.
+ return ResourceUID::get_singleton()->create_id(); // Just create a new one, we will be notified of save anyway and fetch the right UUID at that time, to keep things simple.
} else {
return ResourceUID::INVALID_ID;
}
@@ -2422,7 +2428,7 @@ EditorFileSystem::EditorFileSystem() {
scan_total = 0;
update_script_classes_queued.clear();
- ResourceUID::get_singleton()->clear(); //will be updated on scan
+ MessageQueue::get_singleton()->push_callable(callable_mp(ResourceUID::get_singleton(), &ResourceUID::clear)); // Will be updated on scan.
ResourceSaver::set_get_resource_id_for_path(_resource_saver_get_resource_id_for_path);
}
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 288ee4fa8f..7aca8fde6f 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -1181,7 +1181,8 @@ void EditorNode::_vp_resized() {
}
void EditorNode::_titlebar_resized() {
- const Size2 &margin = DisplayServer::get_singleton()->window_get_safe_title_margins(DisplayServer::MAIN_WINDOW_ID);
+ DisplayServer::get_singleton()->window_set_window_buttons_offset(Vector2i(menu_hb->get_global_position().y + menu_hb->get_size().y / 2, menu_hb->get_global_position().y + menu_hb->get_size().y / 2), DisplayServer::MAIN_WINDOW_ID);
+ const Vector3i &margin = DisplayServer::get_singleton()->window_get_safe_title_margins(DisplayServer::MAIN_WINDOW_ID);
if (left_menu_spacer) {
int w = (gui_base->is_layout_rtl()) ? margin.y : margin.x;
left_menu_spacer->set_custom_minimum_size(Size2(w, 0));
@@ -1190,6 +1191,9 @@ void EditorNode::_titlebar_resized() {
int w = (gui_base->is_layout_rtl()) ? margin.x : margin.y;
right_menu_spacer->set_custom_minimum_size(Size2(w, 0));
}
+ if (menu_hb) {
+ menu_hb->set_custom_minimum_size(Size2(0, margin.z - menu_hb->get_global_position().y));
+ }
}
void EditorNode::_version_button_pressed() {
@@ -7560,7 +7564,6 @@ EditorNode::EditorNode() {
// Extend menu bar to window title.
if (can_expand) {
- DisplayServer::get_singleton()->window_set_window_buttons_offset(Vector2i(menu_hb->get_minimum_size().y / 2, menu_hb->get_minimum_size().y / 2), DisplayServer::MAIN_WINDOW_ID);
DisplayServer::get_singleton()->window_set_flag(DisplayServer::WINDOW_FLAG_EXTEND_TO_TITLE, true, DisplayServer::MAIN_WINDOW_ID);
menu_hb->set_can_move_window(true);
}
diff --git a/editor/export/project_export.cpp b/editor/export/project_export.cpp
index 05a17c9951..9b5e76bcd7 100644
--- a/editor/export/project_export.cpp
+++ b/editor/export/project_export.cpp
@@ -1015,9 +1015,7 @@ ProjectExportDialog::ProjectExportDialog() {
preset_vb->add_child(mc);
mc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
presets = memnew(ItemList);
-#ifndef _MSC_VER
-#warning must reimplement drag forward
-#endif
+ // TODO: Must reimplement drag forwarding.
//presets->set_drag_forwarding(this);
mc->add_child(presets);
presets->connect("item_selected", callable_mp(this, &ProjectExportDialog::_edit_preset));
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index dc84c08506..a48990779b 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -302,6 +302,8 @@ void AnimationPlayerEditor::_animation_selected(int p_which) {
AnimationPlayerEditor::get_singleton()->get_track_editor()->update_keying();
_animation_key_editor_seek(timeline_position, false);
+
+ emit_signal("animation_selected", current);
}
void AnimationPlayerEditor::_animation_new() {
@@ -720,7 +722,18 @@ void AnimationPlayerEditor::set_state(const Dictionary &p_state) {
if (p_state.has("player")) {
Node *n = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["player"]);
if (Object::cast_to<AnimationPlayer>(n) && EditorNode::get_singleton()->get_editor_selection()->is_selected(n)) {
+ if (player) {
+ if (player->is_connected("animation_libraries_updated", callable_mp(this, &AnimationPlayerEditor::_animation_libraries_updated))) {
+ player->disconnect("animation_libraries_updated", callable_mp(this, &AnimationPlayerEditor::_animation_libraries_updated));
+ }
+ }
player = Object::cast_to<AnimationPlayer>(n);
+ if (player) {
+ if (!player->is_connected("animation_libraries_updated", callable_mp(this, &AnimationPlayerEditor::_animation_libraries_updated))) {
+ player->connect("animation_libraries_updated", callable_mp(this, &AnimationPlayerEditor::_animation_libraries_updated));
+ }
+ }
+
_update_player();
EditorNode::get_singleton()->make_bottom_panel_item_visible(this);
set_process(true);
@@ -982,9 +995,18 @@ void AnimationPlayerEditor::edit(AnimationPlayer *p_player) {
if (player && pin->is_pressed()) {
return; // Ignore, pinned.
}
+
+ if (player) {
+ if (player->is_connected("animation_libraries_updated", callable_mp(this, &AnimationPlayerEditor::_animation_libraries_updated))) {
+ player->disconnect("animation_libraries_updated", callable_mp(this, &AnimationPlayerEditor::_animation_libraries_updated));
+ }
+ }
player = p_player;
if (player) {
+ if (!player->is_connected("animation_libraries_updated", callable_mp(this, &AnimationPlayerEditor::_animation_libraries_updated))) {
+ player->connect("animation_libraries_updated", callable_mp(this, &AnimationPlayerEditor::_animation_libraries_updated));
+ }
_update_player();
if (onion.enabled) {
@@ -1151,6 +1173,10 @@ void AnimationPlayerEditor::_animation_player_changed(Object *p_pl) {
}
}
+void AnimationPlayerEditor::_animation_libraries_updated() {
+ _animation_player_changed(player);
+}
+
void AnimationPlayerEditor::_list_changed() {
if (is_visible_in_tree()) {
_update_player();
@@ -1545,6 +1571,7 @@ void AnimationPlayerEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_animation_edit"), &AnimationPlayerEditor::_animation_edit);
ClassDB::bind_method(D_METHOD("_animation_resource_edit"), &AnimationPlayerEditor::_animation_resource_edit);
ClassDB::bind_method(D_METHOD("_animation_player_changed"), &AnimationPlayerEditor::_animation_player_changed);
+ ClassDB::bind_method(D_METHOD("_animation_libraries_updated"), &AnimationPlayerEditor::_animation_libraries_updated);
ClassDB::bind_method(D_METHOD("_list_changed"), &AnimationPlayerEditor::_list_changed);
ClassDB::bind_method(D_METHOD("_animation_duplicate"), &AnimationPlayerEditor::_animation_duplicate);
@@ -1552,6 +1579,8 @@ void AnimationPlayerEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_prepare_onion_layers_2"), &AnimationPlayerEditor::_prepare_onion_layers_2);
ClassDB::bind_method(D_METHOD("_start_onion_skinning"), &AnimationPlayerEditor::_start_onion_skinning);
ClassDB::bind_method(D_METHOD("_stop_onion_skinning"), &AnimationPlayerEditor::_stop_onion_skinning);
+
+ ADD_SIGNAL(MethodInfo("animation_selected", PropertyInfo(Variant::STRING, "name")));
}
AnimationPlayerEditor *AnimationPlayerEditor::singleton = nullptr;
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index 448a0639b1..ae570e53f3 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -195,6 +195,7 @@ class AnimationPlayerEditor : public VBoxContainer {
void _blend_edited();
void _animation_player_changed(Object *p_pl);
+ void _animation_libraries_updated();
void _animation_key_editor_seek(float p_pos, bool p_drag, bool p_timeline_only = false);
void _animation_key_editor_anim_len_changed(float p_len);
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 6e108a9a72..4c792d0dca 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -5316,7 +5316,7 @@ CanvasItemEditor::CanvasItemEditor() {
p->add_shortcut(ED_SHORTCUT("canvas_item_editor/frame_selection", TTR("Frame Selection"), KeyModifierMask::SHIFT | Key::F), VIEW_FRAME_TO_SELECTION);
p->add_shortcut(ED_SHORTCUT("canvas_item_editor/clear_guides", TTR("Clear Guides")), CLEAR_GUIDES);
p->add_separator();
- p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/preview_canvas_scale", TTR("Preview Canvas Scale"), KeyModifierMask::SHIFT | KeyModifierMask::CMD_OR_CTRL | Key::P), PREVIEW_CANVAS_SCALE);
+ p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/preview_canvas_scale", TTR("Preview Canvas Scale")), PREVIEW_CANVAS_SCALE);
main_menu_hbox->add_child(memnew(VSeparator));
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 4430877b8a..7a21397910 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -4773,9 +4773,8 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p
view_menu->get_popup()->connect("id_pressed", callable_mp(this, &Node3DEditorViewport::_menu_option));
display_submenu->connect("id_pressed", callable_mp(this, &Node3DEditorViewport::_menu_option));
view_menu->set_disable_shortcuts(true);
-#ifndef _MSC_VER
-#warning this needs to be fixed
-#endif
+
+ // TODO: Re-evaluate with new OpenGL3 renderer, and implement.
//if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) {
if (false) {
// Alternate display modes only work when using the Vulkan renderer; make this explicit.
diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp
index 68bc4389a2..364c3b7246 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.cpp
+++ b/editor/plugins/tiles/tiles_editor_plugin.cpp
@@ -268,8 +268,8 @@ List<int> TilesEditorPlugin::get_sorted_sources(const Ref<TileSet> p_tile_set) c
SourceNameComparator::tile_set = p_tile_set;
List<int> source_ids;
- for (int i = 0; i < tile_set->get_source_count(); i++) {
- source_ids.push_back(tile_set->get_source_id(i));
+ for (int i = 0; i < p_tile_set->get_source_count(); i++) {
+ source_ids.push_back(p_tile_set->get_source_id(i));
}
switch (source_sort) {
diff --git a/editor/plugins/tiles/tiles_editor_plugin.h b/editor/plugins/tiles/tiles_editor_plugin.h
index b1fe6f8df6..bdada9ec90 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.h
+++ b/editor/plugins/tiles/tiles_editor_plugin.h
@@ -122,7 +122,7 @@ public:
// Sorting.
void set_sorting_option(int p_option);
- List<int> get_sorted_sources(const Ref<TileSet> tile_set) const;
+ List<int> get_sorted_sources(const Ref<TileSet> p_tile_set) const;
virtual void edit(Object *p_object) override;
virtual bool handles(Object *p_object) const override;
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index acaa4ec3c9..ee358a8064 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -2176,11 +2176,15 @@ void SceneTreeDock::_selection_changed() {
void SceneTreeDock::_do_create(Node *p_parent) {
Variant c = create_dialog->instance_selected();
-
- ERR_FAIL_COND(!c);
Node *child = Object::cast_to<Node>(c);
ERR_FAIL_COND(!child);
+ String new_name = p_parent->validate_child_name(child);
+ if (GLOBAL_GET("editor/node_naming/name_casing").operator int() != NAME_CASING_PASCAL_CASE) {
+ new_name = adjust_name_casing(new_name);
+ }
+ child->set_name(new_name);
+
editor_data->get_undo_redo()->create_action_for_history(TTR("Create Node"), editor_data->get_current_edited_scene_history_id());
if (edited_scene) {
@@ -2191,7 +2195,6 @@ void SceneTreeDock::_do_create(Node *p_parent) {
editor_data->get_undo_redo()->add_do_reference(child);
editor_data->get_undo_redo()->add_undo_method(p_parent, "remove_child", child);
- String new_name = p_parent->validate_child_name(child);
EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
editor_data->get_undo_redo()->add_do_method(ed, "live_debug_create_node", edited_scene->get_path_to(p_parent), child->get_class(), new_name);
editor_data->get_undo_redo()->add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(p_parent)).path_join(new_name)));
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 8272db9018..6700b6de0a 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -2590,10 +2590,7 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
Mesh::PRIMITIVE_TRIANGLES, // 4 TRIANGLES
Mesh::PRIMITIVE_TRIANGLE_STRIP, // 5 TRIANGLE_STRIP
Mesh::PRIMITIVE_TRIANGLES, // 6 TRIANGLE_FAN fan not supported, should be converted
-#ifndef _MSC_VER
-#warning line loop and triangle fan are not supported and need to be converted to lines and triangles
-#endif
-
+ // TODO: Line loop and triangle fan are not supported and need to be converted to lines and triangles.
};
primitive = primitives2[mode];
diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp
index 01107ebcc9..8a67462613 100644
--- a/modules/openxr/openxr_api.cpp
+++ b/modules/openxr/openxr_api.cpp
@@ -131,11 +131,9 @@ bool OpenXRAPI::load_layer_properties() {
result = xrEnumerateApiLayerProperties(num_layer_properties, &num_layer_properties, layer_properties);
ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate api layer properties");
-#ifdef DEBUG
for (uint32_t i = 0; i < num_layer_properties; i++) {
- print_line("OpenXR: Found OpenXR layer ", layer_properties[i].layerName);
+ print_verbose(String("OpenXR: Found OpenXR layer ") + layer_properties[i].layerName);
}
-#endif
return true;
}
@@ -163,11 +161,9 @@ bool OpenXRAPI::load_supported_extensions() {
result = xrEnumerateInstanceExtensionProperties(nullptr, num_supported_extensions, &num_supported_extensions, supported_extensions);
ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate extension properties");
-#ifdef DEBUG
for (uint32_t i = 0; i < num_supported_extensions; i++) {
- print_line("OpenXR: Found OpenXR extension ", supported_extensions[i].extensionName);
+ print_verbose(String("OpenXR: Found OpenXR extension ") + supported_extensions[i].extensionName);
}
-#endif
return true;
}
@@ -175,17 +171,10 @@ bool OpenXRAPI::load_supported_extensions() {
bool OpenXRAPI::is_extension_supported(const String &p_extension) const {
for (uint32_t i = 0; i < num_supported_extensions; i++) {
if (supported_extensions[i].extensionName == p_extension) {
-#ifdef DEBUG
- print_line("OpenXR: requested extension", p_extension, "is supported");
-#endif
return true;
}
}
-#ifdef DEBUG
- print_line("OpenXR: requested extension", p_extension, "is not supported");
-#endif
-
return false;
}
@@ -401,11 +390,9 @@ bool OpenXRAPI::load_supported_view_configuration_types() {
result = xrEnumerateViewConfigurations(instance, system_id, num_view_configuration_types, &num_view_configuration_types, supported_view_configuration_types);
ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerateview configurations");
-#ifdef DEBUG
for (uint32_t i = 0; i < num_view_configuration_types; i++) {
- print_line("OpenXR: Found supported view configuration ", OpenXRUtil::get_view_configuration_name(supported_view_configuration_types[i]));
+ print_verbose(String("OpenXR: Found supported view configuration ") + OpenXRUtil::get_view_configuration_name(supported_view_configuration_types[i]));
}
-#endif
return true;
}
@@ -454,17 +441,15 @@ bool OpenXRAPI::load_supported_view_configuration_views(XrViewConfigurationType
result = xrEnumerateViewConfigurationViews(instance, system_id, p_configuration_type, view_count, &view_count, view_configuration_views);
ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate view configurations");
-#ifdef DEBUG
for (uint32_t i = 0; i < view_count; i++) {
- print_line("OpenXR: Found supported view configuration view");
- print_line(" - width: ", view_configuration_views[i].maxImageRectWidth);
- print_line(" - height: ", view_configuration_views[i].maxImageRectHeight);
- print_line(" - sample count: ", view_configuration_views[i].maxSwapchainSampleCount);
- print_line(" - recommended render width: ", view_configuration_views[i].recommendedImageRectWidth);
- print_line(" - recommended render height: ", view_configuration_views[i].recommendedImageRectHeight);
- print_line(" - recommended render sample count: ", view_configuration_views[i].recommendedSwapchainSampleCount);
+ print_verbose("OpenXR: Found supported view configuration view");
+ print_verbose(String(" - width: ") + view_configuration_views[i].maxImageRectWidth);
+ print_verbose(String(" - height: ") + view_configuration_views[i].maxImageRectHeight);
+ print_verbose(String(" - sample count: ") + view_configuration_views[i].maxSwapchainSampleCount);
+ print_verbose(String(" - recommended render width: ") + view_configuration_views[i].recommendedImageRectWidth);
+ print_verbose(String(" - recommended render height: ") + view_configuration_views[i].recommendedImageRectHeight);
+ print_verbose(String(" - recommended render sample count: ") + view_configuration_views[i].recommendedSwapchainSampleCount);
}
-#endif
return true;
}
@@ -546,11 +531,9 @@ bool OpenXRAPI::load_supported_reference_spaces() {
result = xrEnumerateReferenceSpaces(session, num_reference_spaces, &num_reference_spaces, supported_reference_spaces);
ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate reference spaces");
- // #ifdef DEBUG
for (uint32_t i = 0; i < num_reference_spaces; i++) {
- print_line("OpenXR: Found supported reference space ", OpenXRUtil::get_reference_space_name(supported_reference_spaces[i]));
+ print_verbose(String("OpenXR: Found supported reference space ") + OpenXRUtil::get_reference_space_name(supported_reference_spaces[i]));
}
- // #endif
return true;
}
@@ -643,11 +626,9 @@ bool OpenXRAPI::load_supported_swapchain_formats() {
result = xrEnumerateSwapchainFormats(session, num_swapchain_formats, &num_swapchain_formats, supported_swapchain_formats);
ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate swapchain formats");
- // #ifdef DEBUG
for (uint32_t i = 0; i < num_swapchain_formats; i++) {
- print_line("OpenXR: Found supported swapchain format ", get_swapchain_format_name(supported_swapchain_formats[i]));
+ print_verbose(String("OpenXR: Found supported swapchain format ") + get_swapchain_format_name(supported_swapchain_formats[i]));
}
- // #endif
return true;
}
@@ -706,7 +687,7 @@ bool OpenXRAPI::create_swapchains() {
swapchain_format_to_use = usable_swapchain_formats[0]; // just use the first one and hope for the best...
print_line("Couldn't find usable color swap chain format, using", get_swapchain_format_name(swapchain_format_to_use), "instead.");
} else {
- print_line("Using color swap chain format:", get_swapchain_format_name(swapchain_format_to_use));
+ print_verbose(String("Using color swap chain format:") + get_swapchain_format_name(swapchain_format_to_use));
}
if (!create_swapchain(XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT, swapchain_format_to_use, recommended_size.width, recommended_size.height, view_configuration_views[0].recommendedSwapchainSampleCount, view_count, swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain, &swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain_graphics_data)) {
@@ -741,7 +722,7 @@ bool OpenXRAPI::create_swapchains() {
swapchain_format_to_use = usable_swapchain_formats[0]; // just use the first one and hope for the best...
print_line("Couldn't find usable depth swap chain format, using", get_swapchain_format_name(swapchain_format_to_use), "instead.");
} else {
- print_line("Using depth swap chain format:", get_swapchain_format_name(swapchain_format_to_use));
+ print_verbose(String("Using depth swap chain format:") + get_swapchain_format_name(swapchain_format_to_use));
}
if (!create_swapchain(XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, swapchain_format_to_use, recommended_size.width, recommended_size.height, view_configuration_views[0].recommendedSwapchainSampleCount, view_count, swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain, &swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain_graphics_data)) {
@@ -900,9 +881,7 @@ bool OpenXRAPI::create_swapchain(XrSwapchainUsageFlags p_usage_flags, int64_t p_
}
bool OpenXRAPI::on_state_idle() {
-#ifdef DEBUG
- print_line("On state idle");
-#endif
+ print_verbose("On state idle");
for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
wrapper->on_state_idle();
@@ -912,9 +891,7 @@ bool OpenXRAPI::on_state_idle() {
}
bool OpenXRAPI::on_state_ready() {
-#ifdef DEBUG
- print_line("On state ready");
-#endif
+ print_verbose("On state ready");
// begin session
XrSessionBeginInfo session_begin_info = {
@@ -957,9 +934,7 @@ bool OpenXRAPI::on_state_ready() {
}
bool OpenXRAPI::on_state_synchronized() {
-#ifdef DEBUG
- print_line("On state synchronized");
-#endif
+ print_verbose("On state synchronized");
// Just in case, see if we already have active trackers...
List<RID> trackers;
@@ -976,9 +951,7 @@ bool OpenXRAPI::on_state_synchronized() {
}
bool OpenXRAPI::on_state_visible() {
-#ifdef DEBUG
- print_line("On state visible");
-#endif
+ print_verbose("On state visible");
for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
wrapper->on_state_visible();
@@ -992,9 +965,7 @@ bool OpenXRAPI::on_state_visible() {
}
bool OpenXRAPI::on_state_focused() {
-#ifdef DEBUG
- print_line("On state focused");
-#endif
+ print_verbose("On state focused");
for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
wrapper->on_state_focused();
@@ -1008,9 +979,7 @@ bool OpenXRAPI::on_state_focused() {
}
bool OpenXRAPI::on_state_stopping() {
-#ifdef DEBUG
- print_line("On state stopping");
-#endif
+ print_verbose("On state stopping");
if (xr_interface) {
xr_interface->on_state_stopping();
@@ -1036,9 +1005,7 @@ bool OpenXRAPI::on_state_stopping() {
}
bool OpenXRAPI::on_state_loss_pending() {
-#ifdef DEBUG
- print_line("On state loss pending");
-#endif
+ print_verbose("On state loss pending");
for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
wrapper->on_state_loss_pending();
@@ -1050,9 +1017,7 @@ bool OpenXRAPI::on_state_loss_pending() {
}
bool OpenXRAPI::on_state_exiting() {
-#ifdef DEBUG
- print_line("On state existing");
-#endif
+ print_verbose("On state existing");
for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
wrapper->on_state_exiting();
@@ -1324,12 +1289,10 @@ XRPose::TrackingConfidence OpenXRAPI::get_head_center(Transform3D &r_transform,
head_pose_confidence = confidence;
if (head_pose_confidence == XRPose::XR_TRACKING_CONFIDENCE_NONE) {
print_line("OpenXR head space location not valid (check tracking?)");
-#ifdef DEBUG
} else if (head_pose_confidence == XRPose::XR_TRACKING_CONFIDENCE_LOW) {
- print_line("OpenVR Head pose now tracking with low confidence");
+ print_verbose("OpenVR Head pose now tracking with low confidence");
} else {
- print_line("OpenVR Head pose now tracking with high confidence");
-#endif
+ print_verbose("OpenVR Head pose now tracking with high confidence");
}
}
@@ -1417,7 +1380,7 @@ bool OpenXRAPI::poll_events() {
// TODO We get this event if we're about to loose our OpenXR instance.
// We should queue exiting Godot at this point.
- print_verbose("OpenXR EVENT: instance loss pending at " + itos(event->lossTime));
+ print_verbose(String("OpenXR EVENT: instance loss pending at ") + itos(event->lossTime));
return false;
} break;
case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: {
@@ -1425,9 +1388,9 @@ bool OpenXRAPI::poll_events() {
session_state = event->state;
if (session_state >= XR_SESSION_STATE_MAX_ENUM) {
- print_verbose("OpenXR EVENT: session state changed to UNKNOWN - " + itos(session_state));
+ print_verbose(String("OpenXR EVENT: session state changed to UNKNOWN - ") + itos(session_state));
} else {
- print_verbose("OpenXR EVENT: session state changed to " + OpenXRUtil::get_session_state_name(session_state));
+ print_verbose(String("OpenXR EVENT: session state changed to ") + OpenXRUtil::get_session_state_name(session_state));
switch (session_state) {
case XR_SESSION_STATE_IDLE:
@@ -1462,7 +1425,7 @@ bool OpenXRAPI::poll_events() {
case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING: {
XrEventDataReferenceSpaceChangePending *event = (XrEventDataReferenceSpaceChangePending *)&runtimeEvent;
- print_verbose("OpenXR EVENT: reference space type " + OpenXRUtil::get_reference_space_name(event->referenceSpaceType) + " change pending!");
+ print_verbose(String("OpenXR EVENT: reference space type ") + OpenXRUtil::get_reference_space_name(event->referenceSpaceType) + " change pending!");
if (event->poseValid && xr_interface) {
xr_interface->on_pose_recentered();
}
@@ -1481,7 +1444,7 @@ bool OpenXRAPI::poll_events() {
} break;
default:
if (!handled) {
- print_verbose("OpenXR Unhandled event type " + OpenXRUtil::get_structure_type_name(runtimeEvent.type));
+ print_verbose(String("OpenXR Unhandled event type ") + OpenXRUtil::get_structure_type_name(runtimeEvent.type));
}
break;
}
@@ -1589,7 +1552,7 @@ void OpenXRAPI::pre_render() {
if (frame_state.predictedDisplayPeriod > 500000000) {
// display period more then 0.5 seconds? must be wrong data
- print_verbose("OpenXR resetting invalid display period " + rtos(frame_state.predictedDisplayPeriod));
+ print_verbose(String("OpenXR resetting invalid display period ") + rtos(frame_state.predictedDisplayPeriod));
frame_state.predictedDisplayPeriod = 0;
}
@@ -1636,13 +1599,11 @@ void OpenXRAPI::pre_render() {
}
if (view_pose_valid != pose_valid) {
view_pose_valid = pose_valid;
-#ifdef DEBUG
if (!view_pose_valid) {
- print_line("OpenXR View pose became invalid");
+ print_verbose("OpenXR View pose became invalid");
} else {
- print_line("OpenXR View pose became valid");
+ print_verbose("OpenXR View pose became valid");
}
-#endif
}
// let's start our frame..
@@ -2081,8 +2042,6 @@ RID OpenXRAPI::action_set_create(const String p_name, const String p_localized_n
copy_string_to_char_buffer(p_name, action_set_info.actionSetName, XR_MAX_ACTION_SET_NAME_SIZE);
copy_string_to_char_buffer(p_localized_name, action_set_info.localizedActionSetName, XR_MAX_LOCALIZED_ACTION_SET_NAME_SIZE);
- // print_line("Creating action set ", action_set_info.actionSetName, " - ", action_set_info.localizedActionSetName, " (", itos(action_set_info.priority), ")");
-
XrResult result = xrCreateActionSet(instance, &action_set_info, &action_set.handle);
if (XR_FAILED(result)) {
print_line("OpenXR: failed to create action set ", p_name, "! [", get_error_string(result), "]");
@@ -2236,8 +2195,6 @@ RID OpenXRAPI::action_create(RID p_action_set, const String p_name, const String
copy_string_to_char_buffer(p_name, action_info.actionName, XR_MAX_ACTION_NAME_SIZE);
copy_string_to_char_buffer(p_localized_name, action_info.localizedActionName, XR_MAX_LOCALIZED_ACTION_NAME_SIZE);
- // print_line("Creating action ", action_info.actionName, action_info.localizedActionName, action_info.countSubactionPaths);
-
XrResult result = xrCreateAction(action_set->handle, &action_info, &action.handle);
if (XR_FAILED(result)) {
print_line("OpenXR: failed to create action ", p_name, "! [", get_error_string(result), "]");
diff --git a/platform/android/api/jni_singleton.h b/platform/android/api/jni_singleton.h
index 690fddae21..895bc70103 100644
--- a/platform/android/api/jni_singleton.h
+++ b/platform/android/api/jni_singleton.h
@@ -150,9 +150,8 @@ public:
env->DeleteLocalRef(arr);
} break;
-#ifndef _MSC_VER
-#warning This is missing 64 bits arrays, I have no idea how to do it in JNI
-#endif
+ // TODO: This is missing 64 bits arrays, I have no idea how to do it in JNI.
+
case Variant::DICTIONARY: {
jobject obj = env->CallObjectMethodA(instance, E->get().method, v);
ret = _jobject_to_variant(env, obj);
diff --git a/platform/android/jni_utils.cpp b/platform/android/jni_utils.cpp
index 193ef61264..d46b4f39de 100644
--- a/platform/android/jni_utils.cpp
+++ b/platform/android/jni_utils.cpp
@@ -167,9 +167,8 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a
v.obj = arr;
} break;
-#ifndef _MSC_VER
-#warning This is missing 64 bits arrays, I have no idea how to do it in JNI
-#endif
+
+ // TODO: This is missing 64 bits arrays, I have no idea how to do it in JNI.
default: {
v.val.i = 0;
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index 5256d91a80..e0963f42ce 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -1202,16 +1202,6 @@ float DisplayServerX11::screen_get_refresh_rate(int p_screen) const {
return SCREEN_REFRESH_RATE_FALLBACK;
}
-bool DisplayServerX11::screen_is_touchscreen(int p_screen) const {
- _THREAD_SAFE_METHOD_
-
-#ifndef _MSC_VER
-#warning Need to get from proper window
-#endif
-
- return DisplayServer::screen_is_touchscreen(p_screen);
-}
-
#ifdef DBUS_ENABLED
void DisplayServerX11::screen_set_keep_on(bool p_enable) {
if (screen_is_kept_on() == p_enable) {
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index a5fa7613bc..5723abc751 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -349,7 +349,6 @@ public:
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
- virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
#if defined(DBUS_ENABLED)
virtual void screen_set_keep_on(bool p_enable) override;
diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h
index e72273a681..484b8ffebc 100644
--- a/platform/macos/display_server_macos.h
+++ b/platform/macos/display_server_macos.h
@@ -401,7 +401,7 @@ public:
virtual bool window_minimize_on_title_dbl_click() const override;
virtual void window_set_window_buttons_offset(const Vector2i &p_offset, WindowID p_window = MAIN_WINDOW_ID) override;
- virtual Vector2i window_get_safe_title_margins(WindowID p_window = MAIN_WINDOW_ID) const override;
+ virtual Vector3i window_get_safe_title_margins(WindowID p_window = MAIN_WINDOW_ID) const override;
virtual Point2i ime_get_selection() const override;
virtual String ime_get_text() const override;
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index f980129081..f4692abc92 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -2655,25 +2655,33 @@ void DisplayServerMacOS::window_set_window_buttons_offset(const Vector2i &p_offs
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
- wd.wb_offset = p_offset;
+ float scale = screen_get_max_scale();
+ wd.wb_offset = p_offset / scale;
+ wd.wb_offset.x = MAX(wd.wb_offset.x, 12);
+ wd.wb_offset.y = MAX(wd.wb_offset.y, 12);
+ if (wd.window_button_view) {
+ [wd.window_button_view setOffset:NSMakePoint(wd.wb_offset.x, wd.wb_offset.y)];
+ }
}
-Vector2i DisplayServerMacOS::window_get_safe_title_margins(WindowID p_window) const {
+Vector3i DisplayServerMacOS::window_get_safe_title_margins(WindowID p_window) const {
_THREAD_SAFE_METHOD_
- ERR_FAIL_COND_V(!windows.has(p_window), Vector2i());
+ ERR_FAIL_COND_V(!windows.has(p_window), Vector3i());
const WindowData &wd = windows[p_window];
if (!wd.window_button_view) {
- return Vector2i();
+ return Vector3i();
}
- float max_x = wd.wb_offset.x + [wd.window_button_view frame].size.width;
+ float scale = screen_get_max_scale();
+ float max_x = [wd.window_button_view getOffset].x + [wd.window_button_view frame].size.width;
+ float max_y = [wd.window_button_view getOffset].y + [wd.window_button_view frame].size.height;
if ([wd.window_object windowTitlebarLayoutDirection] == NSUserInterfaceLayoutDirectionRightToLeft) {
- return Vector2i(0, max_x * screen_get_max_scale());
+ return Vector3i(0, max_x * scale, max_y * scale);
} else {
- return Vector2i(max_x * screen_get_max_scale(), 0);
+ return Vector3i(max_x * scale, 0, max_y * scale);
}
}
diff --git a/platform/macos/godot_button_view.h b/platform/macos/godot_button_view.h
index e7627a9e9b..ef1d5fe412 100644
--- a/platform/macos/godot_button_view.h
+++ b/platform/macos/godot_button_view.h
@@ -42,10 +42,15 @@
CGFloat spacing;
bool mouse_in_group;
bool rtl;
+ NSButton *close_button;
+ NSButton *miniaturize_button;
+ NSButton *zoom_button;
}
- (void)initButtons:(CGFloat)button_spacing offset:(NSPoint)button_offset rtl:(bool)is_rtl;
- (void)displayButtons;
+- (void)setOffset:(NSPoint)button_offset;
+- (NSPoint)getOffset;
@end
diff --git a/platform/macos/godot_button_view.mm b/platform/macos/godot_button_view.mm
index 9106f0b0db..7d380cbe11 100644
--- a/platform/macos/godot_button_view.mm
+++ b/platform/macos/godot_button_view.mm
@@ -40,6 +40,9 @@
spacing = 20;
mouse_in_group = false;
rtl = false;
+ close_button = nullptr;
+ miniaturize_button = nullptr;
+ zoom_button = nullptr;
return self;
}
@@ -48,15 +51,15 @@
spacing = button_spacing;
rtl = is_rtl;
- NSButton *close_button = [NSWindow standardWindowButton:NSWindowCloseButton forStyleMask:NSWindowStyleMaskTitled];
+ close_button = [NSWindow standardWindowButton:NSWindowCloseButton forStyleMask:NSWindowStyleMaskTitled];
[close_button setFrameOrigin:NSMakePoint(rtl ? spacing * 2 : 0, 0)];
[self addSubview:close_button];
- NSButton *miniaturize_button = [NSWindow standardWindowButton:NSWindowMiniaturizeButton forStyleMask:NSWindowStyleMaskTitled];
+ miniaturize_button = [NSWindow standardWindowButton:NSWindowMiniaturizeButton forStyleMask:NSWindowStyleMaskTitled];
[miniaturize_button setFrameOrigin:NSMakePoint(spacing, 0)];
[self addSubview:miniaturize_button];
- NSButton *zoom_button = [NSWindow standardWindowButton:NSWindowZoomButton forStyleMask:NSWindowStyleMaskTitled];
+ zoom_button = [NSWindow standardWindowButton:NSWindowZoomButton forStyleMask:NSWindowStyleMaskTitled];
[zoom_button setFrameOrigin:NSMakePoint(rtl ? 0 : spacing * 2, 0)];
[self addSubview:zoom_button];
@@ -71,6 +74,19 @@
[self displayButtons];
}
+- (void)setOffset:(NSPoint)button_offset {
+ if (zoom_button) {
+ offset.y = button_offset.y - zoom_button.frame.size.height / 2;
+ offset.x = button_offset.x - zoom_button.frame.size.width / 2;
+
+ [self viewDidMoveToWindow];
+ }
+}
+
+- (NSPoint)getOffset {
+ return offset;
+}
+
- (void)viewDidMoveToWindow {
if (!self.window) {
return;
diff --git a/platform/web/js/libs/library_godot_javascript_singleton.js b/platform/web/js/libs/library_godot_javascript_singleton.js
index 692f27676a..c86cbbae45 100644
--- a/platform/web/js/libs/library_godot_javascript_singleton.js
+++ b/platform/web/js/libs/library_godot_javascript_singleton.js
@@ -88,7 +88,7 @@ const GodotJSWrapper = {
return GodotRuntime.getHeapValue(val, 'double');
case 4:
return GodotRuntime.parseString(GodotRuntime.getHeapValue(val, '*'));
- case 21: // OBJECT
+ case 24: // OBJECT
return GodotJSWrapper.get_proxied_value(GodotRuntime.getHeapValue(val, 'i64'));
default:
return undefined;
@@ -117,7 +117,7 @@ const GodotJSWrapper = {
}
const id = GodotJSWrapper.get_proxied(p_val);
GodotRuntime.setHeapValue(p_exchange, id, 'i64');
- return 21;
+ return 24; // OBJECT
},
},
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 16853a0be7..3b773685c3 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -561,20 +561,6 @@ float DisplayServerWindows::screen_get_refresh_rate(int p_screen) const {
return data.rate;
}
-bool DisplayServerWindows::screen_is_touchscreen(int p_screen) const {
-#ifndef _MSC_VER
-#warning touchscreen not working
-#endif
- return DisplayServer::screen_is_touchscreen(p_screen);
-}
-
-void DisplayServerWindows::screen_set_orientation(ScreenOrientation p_orientation, int p_screen) {
-}
-
-DisplayServer::ScreenOrientation DisplayServerWindows::screen_get_orientation(int p_screen) const {
- return SCREEN_LANDSCAPE;
-}
-
void DisplayServerWindows::screen_set_keep_on(bool p_enable) {
if (keep_screen_on == p_enable) {
return;
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index 3523e8b3d1..6403b57d8d 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -516,10 +516,6 @@ public:
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
- virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
-
- virtual void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW) override;
- virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual void screen_set_keep_on(bool p_enable) override; //disable screensaver
virtual bool screen_is_kept_on() const override;
diff --git a/platform/windows/joypad_windows.h b/platform/windows/joypad_windows.h
index d239471a5c..56a9f3e9c9 100644
--- a/platform/windows/joypad_windows.h
+++ b/platform/windows/joypad_windows.h
@@ -85,6 +85,8 @@ private:
last_pad = -1;
attached = false;
confirmed = false;
+ di_joy = nullptr;
+ guid = {};
for (int i = 0; i < MAX_JOY_BUTTONS; i++) {
last_buttons[i] = false;
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp
index 90402260ed..80169bc80c 100644
--- a/scene/2d/light_2d.cpp
+++ b/scene/2d/light_2d.cpp
@@ -454,7 +454,7 @@ void DirectionalLight2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_max_distance", "pixels"), &DirectionalLight2D::set_max_distance);
ClassDB::bind_method(D_METHOD("get_max_distance"), &DirectionalLight2D::get_max_distance);
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0,1,0.01,suffix:px"), "set_height", "get_height");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_height", "get_height");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_RANGE, "0,16384.0,1.0,or_greater,suffix:px"), "set_max_distance", "get_max_distance");
}
diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp
index dd016d5e92..f80b2a07c9 100644
--- a/scene/2d/skeleton_2d.cpp
+++ b/scene/2d/skeleton_2d.cpp
@@ -192,10 +192,8 @@ void Bone2D::_notification(int p_what) {
cache_transform = tmp_trans;
} break;
- // Bone2D Editor gizmo drawing:
-#ifndef _MSC_VER
-#warning TODO Bone2D gizmo drawing needs to be moved to an editor plugin
-#endif
+ // Bone2D Editor gizmo drawing.
+ // TODO: Bone2D gizmo drawing needs to be moved to an editor plugin.
case NOTIFICATION_DRAW: {
// Only draw the gizmo in the editor!
if (Engine::get_singleton()->is_editor_hint() == false) {
diff --git a/scene/2d/sprite_2d.cpp b/scene/2d/sprite_2d.cpp
index 0ecf8333a0..0784318442 100644
--- a/scene/2d/sprite_2d.cpp
+++ b/scene/2d/sprite_2d.cpp
@@ -309,9 +309,7 @@ bool Sprite2D::is_pixel_opaque(const Point2 &p_point) const {
q.y = 1.0f - q.y;
}
q = q * src_rect.size + src_rect.position;
-#ifndef _MSC_VER
-#warning this need to be obtained from CanvasItem new repeat mode (but it needs to guess it from hierarchy, need to add a function for that)
-#endif
+ // TODO: This need to be obtained from CanvasItem new repeat mode (but it needs to guess it from hierarchy, need to add a function for that).
bool is_repeat = false;
bool is_mirrored_repeat = false;
if (is_repeat) {
@@ -446,7 +444,7 @@ void Sprite2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes");
ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes");
ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "frame_coords", PROPERTY_HINT_NONE, "suffix:px", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords");
ADD_GROUP("Region", "region_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region_enabled", "is_region_enabled");
diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp
index 23fd091be6..198dba7811 100644
--- a/scene/3d/light_3d.cpp
+++ b/scene/3d/light_3d.cpp
@@ -165,6 +165,16 @@ AABB Light3D::get_aabb() const {
return AABB();
}
+PackedStringArray Light3D::get_configuration_warnings() const {
+ PackedStringArray warnings = VisualInstance3D::get_configuration_warnings();
+
+ if (!get_scale().is_equal_approx(Vector3(1, 1, 1))) {
+ warnings.push_back(RTR("A light's scale does not affect the visual size of the light."));
+ }
+
+ return warnings;
+}
+
void Light3D::set_bake_mode(BakeMode p_mode) {
bake_mode = p_mode;
RS::get_singleton()->light_set_bake_mode(light, RS::LightBakeMode(p_mode));
@@ -579,7 +589,7 @@ OmniLight3D::ShadowMode OmniLight3D::get_shadow_mode() const {
}
PackedStringArray OmniLight3D::get_configuration_warnings() const {
- PackedStringArray warnings = Node::get_configuration_warnings();
+ PackedStringArray warnings = Light3D::get_configuration_warnings();
if (!has_shadow() && get_projector().is_valid()) {
warnings.push_back(RTR("Projector texture only works with shadows active."));
@@ -609,7 +619,7 @@ OmniLight3D::OmniLight3D() :
}
PackedStringArray SpotLight3D::get_configuration_warnings() const {
- PackedStringArray warnings = Node::get_configuration_warnings();
+ PackedStringArray warnings = Light3D::get_configuration_warnings();
if (has_shadow() && get_param(PARAM_SPOT_ANGLE) >= 90.0) {
warnings.push_back(RTR("A SpotLight3D with an angle wider than 90 degrees cannot cast shadows."));
diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h
index 8da45bee79..84d214030b 100644
--- a/scene/3d/light_3d.h
+++ b/scene/3d/light_3d.h
@@ -147,6 +147,7 @@ public:
Color get_correlated_color() const;
virtual AABB get_aabb() const override;
+ virtual PackedStringArray get_configuration_warnings() const override;
Light3D();
~Light3D();
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index cc69a1cc51..be6eab2178 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -810,7 +810,7 @@ void Sprite3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes");
ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes");
ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frame_coords", PROPERTY_HINT_NONE, "suffix:px", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords");
ADD_GROUP("Region", "region_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region_enabled", "is_region_enabled");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect", PROPERTY_HINT_NONE, "suffix:px"), "set_region_rect", "get_region_rect");
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index fe67c0886f..2e3d0a26c2 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -109,7 +109,7 @@ bool AnimationPlayer::_set(const StringName &p_name, const Variant &p_value) {
Ref<AnimationLibrary> lib = d[lib_name];
add_animation_library(lib_name, lib);
}
-
+ emit_signal("animation_libraries_updated");
} else if (name.begins_with("next/")) {
String which = name.get_slicec('/', 1);
animation_set_next(which, p_value);
@@ -1274,6 +1274,23 @@ void AnimationPlayer::_animation_set_cache_update() {
}
void AnimationPlayer::_animation_added(const StringName &p_name, const StringName &p_library) {
+ {
+ int at_pos = -1;
+
+ for (uint32_t i = 0; i < animation_libraries.size(); i++) {
+ if (animation_libraries[i].name == p_library) {
+ at_pos = i;
+ break;
+ }
+ }
+
+ ERR_FAIL_COND(at_pos == -1);
+
+ ERR_FAIL_COND(!animation_libraries[at_pos].library->animations.has(p_name));
+
+ _ref_anim(animation_libraries[at_pos].library->animations[p_name]);
+ }
+
_animation_set_cache_update();
}
@@ -1283,6 +1300,12 @@ void AnimationPlayer::_animation_removed(const StringName &p_name, const StringN
if (!animation_set.has(name)) {
return; // No need to update because not the one from the library being used.
}
+
+ AnimationData animation_data = animation_set[name];
+ if (animation_data.animation_library == p_library) {
+ _unref_anim(animation_data.animation);
+ }
+
_animation_set_cache_update();
// Erase blends if needed
@@ -1379,6 +1402,10 @@ Error AnimationPlayer::add_animation_library(const StringName &p_name, const Ref
ald.library->connect(SNAME("animation_removed"), callable_mp(this, &AnimationPlayer::_animation_added).bind(p_name));
ald.library->connect(SNAME("animation_renamed"), callable_mp(this, &AnimationPlayer::_animation_renamed).bind(p_name));
+ for (const KeyValue<StringName, Ref<Animation>> &K : ald.library->animations) {
+ _ref_anim(K.value);
+ }
+
_animation_set_cache_update();
notify_property_list_changed();
@@ -1399,7 +1426,7 @@ void AnimationPlayer::remove_animation_library(const StringName &p_name) {
ERR_FAIL_COND(at_pos == -1);
animation_libraries[at_pos].library->disconnect(SNAME("animation_added"), callable_mp(this, &AnimationPlayer::_animation_added));
- animation_libraries[at_pos].library->disconnect(SNAME("animation_removed"), callable_mp(this, &AnimationPlayer::_animation_added));
+ animation_libraries[at_pos].library->disconnect(SNAME("animation_removed"), callable_mp(this, &AnimationPlayer::_animation_removed));
animation_libraries[at_pos].library->disconnect(SNAME("animation_renamed"), callable_mp(this, &AnimationPlayer::_animation_renamed));
stop();
@@ -2151,6 +2178,7 @@ void AnimationPlayer::_bind_methods() {
ADD_SIGNAL(MethodInfo("animation_changed", PropertyInfo(Variant::STRING_NAME, "old_name"), PropertyInfo(Variant::STRING_NAME, "new_name")));
ADD_SIGNAL(MethodInfo("animation_started", PropertyInfo(Variant::STRING_NAME, "anim_name")));
ADD_SIGNAL(MethodInfo("animation_list_changed"));
+ ADD_SIGNAL(MethodInfo("animation_libraries_updated"));
ADD_SIGNAL(MethodInfo("caches_cleared"));
BIND_ENUM_CONSTANT(ANIMATION_PROCESS_PHYSICS);
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index 70707dba11..8a5d04f49c 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -1248,37 +1248,41 @@ bool CodeEdit::is_drawing_executing_lines_gutter() const {
}
void CodeEdit::_main_gutter_draw_callback(int p_line, int p_gutter, const Rect2 &p_region) {
- bool shift_pressed = Input::get_singleton()->is_key_pressed(Key::SHIFT);
-
if (draw_breakpoints && breakpoint_icon.is_valid()) {
- bool hovering = p_region.has_point(get_local_mouse_pos());
bool breakpointed = is_line_breakpointed(p_line);
+ bool hovering = p_region.has_point(get_local_mouse_pos());
+ bool shift_pressed = Input::get_singleton()->is_key_pressed(Key::SHIFT);
if (breakpointed || (hovering && !is_dragging_cursor() && !shift_pressed)) {
int padding = p_region.size.x / 6;
+
+ Color use_color = breakpoint_color;
+ if (hovering && !shift_pressed) {
+ use_color = breakpointed ? use_color.lightened(0.3) : use_color.darkened(0.5);
+ }
Rect2 icon_region = p_region;
icon_region.position += Point2(padding, padding);
icon_region.size -= Point2(padding, padding) * 2;
-
- // Darken icon when hovering, shift not pressed & not yet breakpointed.
- Color use_color = hovering && !breakpointed && !shift_pressed ? breakpoint_color.darkened(0.4) : breakpoint_color;
breakpoint_icon->draw_rect(get_canvas_item(), icon_region, false, use_color);
}
}
if (draw_bookmarks && bookmark_icon.is_valid()) {
- bool hovering = p_region.has_point(get_local_mouse_pos());
bool bookmarked = is_line_bookmarked(p_line);
+ bool hovering = p_region.has_point(get_local_mouse_pos());
+ bool shift_pressed = Input::get_singleton()->is_key_pressed(Key::SHIFT);
if (bookmarked || (hovering && !is_dragging_cursor() && shift_pressed)) {
int horizontal_padding = p_region.size.x / 2;
int vertical_padding = p_region.size.y / 4;
+
+ Color use_color = bookmark_color;
+ if (hovering && shift_pressed) {
+ use_color = bookmarked ? use_color.lightened(0.3) : use_color.darkened(0.5);
+ }
Rect2 icon_region = p_region;
icon_region.position += Point2(horizontal_padding, 0);
icon_region.size -= Point2(horizontal_padding * 1.1, vertical_padding);
-
- // Darken icon when hovering, shift pressed & not yet bookmarked.
- Color use_color = hovering && !bookmarked && shift_pressed ? bookmark_color.darkened(0.4) : bookmark_color;
bookmark_icon->draw_rect(get_canvas_item(), icon_region, false, use_color);
}
}
@@ -1287,10 +1291,10 @@ void CodeEdit::_main_gutter_draw_callback(int p_line, int p_gutter, const Rect2
int horizontal_padding = p_region.size.x / 10;
int vertical_padding = p_region.size.y / 4;
- Rect2 executing_line_region = p_region;
- executing_line_region.position += Point2(horizontal_padding, vertical_padding);
- executing_line_region.size -= Point2(horizontal_padding, vertical_padding) * 2;
- executing_line_icon->draw_rect(get_canvas_item(), executing_line_region, false, executing_line_color);
+ Rect2 icon_region = p_region;
+ icon_region.position += Point2(horizontal_padding, vertical_padding);
+ icon_region.size -= Point2(horizontal_padding, vertical_padding) * 2;
+ executing_line_icon->draw_rect(get_canvas_item(), icon_region, false, executing_line_color);
}
}
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index f1e18640e6..a2c138c0b2 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -1403,9 +1403,7 @@ void ColorPicker::_screen_pick_pressed() {
screen->show();
}
screen->move_to_front();
-#ifndef _MSC_VER
-#warning show modal no longer works, needs to be converted to a popup
-#endif
+ // TODO: show modal no longer works, needs to be converted to a popup.
//screen->show_modal();
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 2e7f650fc2..598420da37 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1692,7 +1692,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
continue;
}
- if (mpos.x > left_margin && mpos.x <= (left_margin + gutters[i].width) - 3) {
+ if (mpos.x >= left_margin && mpos.x <= left_margin + gutters[i].width) {
emit_signal(SNAME("gutter_clicked"), row, i);
return;
}
@@ -1933,7 +1933,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
continue;
}
- if (mpos.x > left_margin && mpos.x <= (left_margin + gutters[i].width) - 3) {
+ if (mpos.x >= left_margin && mpos.x < left_margin + gutters[i].width) {
// We are in this gutter i's horizontal area.
current_hovered_gutter = Vector2i(i, hovered_row);
break;
@@ -2192,8 +2192,17 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
return;
}
- // Handle Unicode (if no modifiers active). Tab has a value of 0x09.
- if (allow_unicode_handling && editable && (k->get_unicode() >= 32 || k->get_keycode() == Key::TAB)) {
+ // Handle tab as it has no set unicode value.
+ if (k->is_action("ui_text_indent", true)) {
+ if (editable) {
+ insert_text_at_caret("\t");
+ }
+ accept_event();
+ return;
+ }
+
+ // Handle Unicode (if no modifiers active).
+ if (allow_unicode_handling && editable && k->get_unicode() >= 32) {
handle_unicode_input(k->get_unicode());
accept_event();
return;
@@ -2997,7 +3006,7 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
continue;
}
- if (p_pos.x > left_margin && p_pos.x <= (left_margin + gutters[i].width) - 3) {
+ if (p_pos.x >= left_margin && p_pos.x < left_margin + gutters[i].width) {
if (gutters[i].clickable || is_line_gutter_clickable(row, i)) {
return CURSOR_POINTING_HAND;
}
@@ -4380,7 +4389,7 @@ int TextEdit::add_caret(int p_line, int p_col) {
}
void TextEdit::remove_caret(int p_caret) {
- ERR_FAIL_COND(carets.size() <= 0);
+ ERR_FAIL_COND_MSG(carets.size() <= 1, "The main caret should not be removed.");
ERR_FAIL_INDEX(p_caret, carets.size());
carets.remove_at(p_caret);
caret_index_edit_dirty = true;
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index acf398305c..2e8fa1e606 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -1504,6 +1504,7 @@ void TreeItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_button", "column", "button_idx", "button"), &TreeItem::set_button);
ClassDB::bind_method(D_METHOD("erase_button", "column", "button_idx"), &TreeItem::erase_button);
ClassDB::bind_method(D_METHOD("set_button_disabled", "column", "button_idx", "disabled"), &TreeItem::set_button_disabled);
+ ClassDB::bind_method(D_METHOD("set_button_color", "column", "button_idx", "color"), &TreeItem::set_button_color);
ClassDB::bind_method(D_METHOD("is_button_disabled", "column", "button_idx"), &TreeItem::is_button_disabled);
ClassDB::bind_method(D_METHOD("set_tooltip_text", "column", "tooltip"), &TreeItem::set_tooltip_text);
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 101a63db1b..6ab27853f1 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -1024,11 +1024,9 @@ String increase_numeric_string(const String &s) {
void Node::_generate_serial_child_name(const Node *p_child, StringName &name) const {
if (name == StringName()) {
- //no name and a new name is needed, create one.
+ // No name and a new name is needed, create one.
name = p_child->get_class();
- // Adjust casing according to project setting.
- name = adjust_name_casing(name);
}
//quickly test if proposed name exists
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 2bcf569f4e..dfd9c6eb2f 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -5239,9 +5239,7 @@ bool Animation::_fetch_compressed(uint32_t p_compressed_track, double p_time, Ve
double page_base_time = compression.pages[page_index].time_offset;
const uint8_t *page_data = compression.pages[page_index].data.ptr();
-#ifndef _MSC_VER
-#warning Little endian assumed. No major big endian hardware exists any longer, but in case it does it will need to be supported
-#endif
+ // Little endian assumed. No major big endian hardware exists any longer, but in case it does it will need to be supported.
const uint32_t *indices = (const uint32_t *)page_data;
const uint16_t *time_keys = (const uint16_t *)&page_data[indices[p_compressed_track * 3 + 0]];
uint32_t time_key_count = indices[p_compressed_track * 3 + 1];
@@ -5384,9 +5382,7 @@ void Animation::_get_compressed_key_indices_in_range(uint32_t p_compressed_track
double page_base_time = compression.pages[page_index].time_offset;
const uint8_t *page_data = compression.pages[page_index].data.ptr();
-#ifndef _MSC_VER
-#warning Little endian assumed. No major big endian hardware exists any longer, but in case it does it will need to be supported
-#endif
+ // Little endian assumed. No major big endian hardware exists any longer, but in case it does it will need to be supported.
const uint32_t *indices = (const uint32_t *)page_data;
const uint16_t *time_keys = (const uint16_t *)&page_data[indices[p_compressed_track * 3 + 0]];
uint32_t time_key_count = indices[p_compressed_track * 3 + 1];
@@ -5456,9 +5452,7 @@ int Animation::_get_compressed_key_count(uint32_t p_compressed_track) const {
for (uint32_t i = 0; i < compression.pages.size(); i++) {
const uint8_t *page_data = compression.pages[i].data.ptr();
-#ifndef _MSC_VER
-#warning Little endian assumed. No major big endian hardware exists any longer, but in case it does it will need to be supported
-#endif
+ // Little endian assumed. No major big endian hardware exists any longer, but in case it does it will need to be supported.
const uint32_t *indices = (const uint32_t *)page_data;
const uint16_t *time_keys = (const uint16_t *)&page_data[indices[p_compressed_track * 3 + 0]];
uint32_t time_key_count = indices[p_compressed_track * 3 + 1];
@@ -5492,9 +5486,7 @@ bool Animation::_fetch_compressed_by_index(uint32_t p_compressed_track, int p_in
for (uint32_t i = 0; i < compression.pages.size(); i++) {
const uint8_t *page_data = compression.pages[i].data.ptr();
-#ifndef _MSC_VER
-#warning Little endian assumed. No major big endian hardware exists any longer, but in case it does it will need to be supported
-#endif
+ // Little endian assumed. No major big endian hardware exists any longer, but in case it does it will need to be supported.
const uint32_t *indices = (const uint32_t *)page_data;
const uint16_t *time_keys = (const uint16_t *)&page_data[indices[p_compressed_track * 3 + 0]];
uint32_t time_key_count = indices[p_compressed_track * 3 + 1];
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 03ccae5b74..706db3af16 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -1576,9 +1576,8 @@ void ArrayMesh::_recompute_aabb() {
}
}
}
-#ifndef _MSC_VER
-#warning need to add binding to add_surface using future MeshSurfaceData object
-#endif
+
+// TODO: Need to add binding to add_surface using future MeshSurfaceData object.
void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, const Vector<uint8_t> &p_attribute_array, const Vector<uint8_t> &p_skin_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<uint8_t> &p_blend_shape_data, const Vector<AABB> &p_bone_aabbs, const Vector<RS::SurfaceData::LOD> &p_lods) {
_create_if_empty();
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index c0d65fb445..85b538b1d9 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -445,7 +445,14 @@ Error ResourceLoaderText::load() {
// If a UID is found and the path is valid, it will be used, otherwise, it falls back to the path.
path = ResourceUID::get_singleton()->get_id_path(uid);
} else {
+#ifdef TOOLS_ENABLED
+ // Silence a warning that can happen during the initial filesystem scan due to cache being regenerated.
+ if (ResourceLoader::get_resource_uid(path) != uid) {
+ WARN_PRINT(String(res_path + ":" + itos(lines) + " - ext_resource, invalid UUID: " + uidt + " - using text path instead: " + path).utf8().get_data());
+ }
+#else
WARN_PRINT(String(res_path + ":" + itos(lines) + " - ext_resource, invalid UUID: " + uidt + " - using text path instead: " + path).utf8().get_data());
+#endif
}
}
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index df9addb6bb..640f6dfcb7 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -1509,11 +1509,10 @@ bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const {
}
void VisualShader::reset_state() {
-#ifndef _MSC_VER
-#warning everything needs to be cleared here
-#endif
+ // TODO: Everything needs to be cleared here.
emit_changed();
}
+
void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
//mode
p_list->push_back(PropertyInfo(Variant::INT, PNAME("mode"), PROPERTY_HINT_ENUM, "Node3D,CanvasItem,Particles,Sky,Fog"));
diff --git a/servers/display_server.h b/servers/display_server.h
index 8eafccc040..31ebf12531 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -382,7 +382,7 @@ public:
virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) = 0;
virtual void window_set_window_buttons_offset(const Vector2i &p_offset, WindowID p_window = MAIN_WINDOW_ID) {}
- virtual Vector2i window_get_safe_title_margins(WindowID p_window = MAIN_WINDOW_ID) const { return Vector2i(); }
+ virtual Vector3i window_get_safe_title_margins(WindowID p_window = MAIN_WINDOW_ID) const { return Vector3i(); }
virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const = 0;
diff --git a/servers/rendering/renderer_rd/pipeline_cache_rd.cpp b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
index 9151c53823..7a2336970b 100644
--- a/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
+++ b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "pipeline_cache_rd.h"
+
#include "core/os/memory.h"
RID PipelineCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe, uint32_t p_render_pass, uint32_t p_bool_specializations) {
@@ -70,9 +71,7 @@ RID PipelineCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD
}
void PipelineCacheRD::_clear() {
-#ifndef _MSC_VER
-#warning Clear should probably recompile all the variants already compiled instead to avoid stalls? needs discussion
-#endif
+ // TODO: Clear should probably recompile all the variants already compiled instead to avoid stalls? Needs discussion.
if (versions) {
for (uint32_t i = 0; i < version_count; i++) {
//shader may be gone, so this may not be valid
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index e5e82552f4..5728444312 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -1075,10 +1075,7 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co
clear_colors.push_back(texture_storage->render_target_get_clear_request_color(p_to_render_target));
texture_storage->render_target_disable_clear_request(p_to_render_target);
}
-#ifndef _MSC_VER
-#warning TODO obtain from framebuffer format eventually when this is implemented
-#endif
-
+ // TODO: Obtain from framebuffer format eventually when this is implemented.
fb_uniform_set = texture_storage->render_target_get_framebuffer_uniform_set(p_to_render_target);
}
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
index dd3f62e509..3289bfb0ea 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
@@ -102,10 +102,8 @@ void RendererCompositorRD::begin_frame(double frame_step) {
}
void RendererCompositorRD::end_frame(bool p_swap_buffers) {
-#ifndef _MSC_VER
-#warning TODO: likely pass a bool to swap buffers to avoid display?
-#endif
- RD::get_singleton()->swap_buffers(); //probably should pass some bool to avoid display?
+ // TODO: Likely pass a bool to swap buffers to avoid display?
+ RD::get_singleton()->swap_buffers();
}
void RendererCompositorRD::initialize() {
diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp
index 0f2dea6fe9..5e9eadadd9 100644
--- a/servers/rendering/renderer_rd/shader_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_rd.cpp
@@ -180,6 +180,7 @@ void ShaderRD::_build_variant_code(StringBuilder &builder, uint32_t p_variant, c
#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
builder.append("#define MOLTENVK_USED\n");
#endif
+ builder.append(String("#define RENDER_DRIVER_") + OS::get_singleton()->get_current_rendering_driver_name().to_upper() + "\n");
} break;
case StageTemplate::Chunk::TYPE_MATERIAL_UNIFORMS: {
builder.append(p_version->uniforms.get_data()); //uniforms (same for vertex and fragment)
diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
index 78f4c410c3..240f743387 100644
--- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "particles_storage.h"
+
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "servers/rendering/rendering_server_globals.h"
#include "texture_storage.h"
@@ -1334,10 +1335,7 @@ void ParticlesStorage::update_particles() {
}
}
-#ifndef _MSC_VER
-#warning Should use display refresh rate for all this
-#endif
-
+ // TODO: Should use display refresh rate for all this.
float screen_hz = 60;
int fixed_fps = 0;
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
index b3a7e05ff5..add3e03389 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "texture_storage.h"
+
#include "../effects/copy_effects.h"
#include "../framebuffer_cache_rd.h"
#include "material_storage.h"
@@ -1496,9 +1497,7 @@ Ref<Image> TextureStorage::_validate_texture_format(const Ref<Image> &p_image, T
} break;
case Image::FORMAT_RGBE9995: {
r_format.format = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32;
-#ifndef _MSC_VER
-#warning TODO need to make a function in Image to swap bits for this
-#endif
+ // TODO: Need to make a function in Image to swap bits for this.
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_IDENTITY;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_IDENTITY;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_IDENTITY;
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
index 2b25e8962f..d0cb46dee9 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -869,12 +869,7 @@ void RendererSceneCull::instance_set_transform(RID p_instance, const Transform3D
for (int i = 0; i < 4; i++) {
const Vector3 &v = i < 3 ? p_transform.basis.rows[i] : p_transform.origin;
- ERR_FAIL_COND(Math::is_inf(v.x));
- ERR_FAIL_COND(Math::is_nan(v.x));
- ERR_FAIL_COND(Math::is_inf(v.y));
- ERR_FAIL_COND(Math::is_nan(v.y));
- ERR_FAIL_COND(Math::is_inf(v.z));
- ERR_FAIL_COND(Math::is_nan(v.z));
+ ERR_FAIL_COND(!v.is_finite());
}
#endif
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 627cd9f062..e12c4fc79a 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -2868,12 +2868,13 @@ void RenderingServer::init() {
GLOBAL_DEF("rendering/2d/shadow_atlas/size", 2048);
- // Already defined in RenderingDeviceVulkan::initialize which runs before this code.
+ // Already defined in some RenderingDevice*::initialize, which run before this code.
// We re-define them here just for doctool's sake. Make sure to keep default values in sync.
GLOBAL_DEF("rendering/rendering_device/staging_buffer/block_size_kb", 256);
GLOBAL_DEF("rendering/rendering_device/staging_buffer/max_size_mb", 128);
GLOBAL_DEF("rendering/rendering_device/staging_buffer/texture_upload_region_size_px", 64);
- GLOBAL_DEF("rendering/rendering_device/descriptor_pools/max_descriptors_per_pool", 64);
+ // Vulkan-specific.
+ GLOBAL_DEF("rendering/rendering_device/vulkan/max_descriptors_per_pool", 64);
// Number of commands that can be drawn per frame.
GLOBAL_DEF_RST("rendering/gl_compatibility/item_buffer_size", 16384);
diff --git a/tests/core/math/test_aabb.h b/tests/core/math/test_aabb.h
index d5f54a139e..ebaf441abf 100644
--- a/tests/core/math/test_aabb.h
+++ b/tests/core/math/test_aabb.h
@@ -389,6 +389,27 @@ TEST_CASE("[AABB] Expanding") {
aabb.expand(Vector3(-20, 0, 0)).is_equal_approx(AABB(Vector3(-20, 0, -2.5), Vector3(22.5, 7, 6))),
"expand() with non-contained point should return the expected AABB.");
}
+
+TEST_CASE("[AABB] Finite number checks") {
+ const Vector3 x(0, 1, 2);
+ const Vector3 infinite(NAN, NAN, NAN);
+
+ CHECK_MESSAGE(
+ AABB(x, x).is_finite(),
+ "AABB with all components finite should be finite");
+
+ CHECK_FALSE_MESSAGE(
+ AABB(infinite, x).is_finite(),
+ "AABB with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ AABB(x, infinite).is_finite(),
+ "AABB with one component infinite should not be finite.");
+
+ CHECK_FALSE_MESSAGE(
+ AABB(infinite, infinite).is_finite(),
+ "AABB with two components infinite should not be finite.");
+}
+
} // namespace TestAABB
#endif // TEST_AABB_H
diff --git a/tests/core/math/test_basis.h b/tests/core/math/test_basis.h
index b6493c5726..a65020597a 100644
--- a/tests/core/math/test_basis.h
+++ b/tests/core/math/test_basis.h
@@ -334,6 +334,40 @@ TEST_CASE("[Basis] Set axis angle") {
bugNan.get_axis_angle(axis, angle);
CHECK(!Math::is_nan(angle));
}
+
+TEST_CASE("[Basis] Finite number checks") {
+ const Vector3 x(0, 1, 2);
+ const Vector3 infinite(NAN, NAN, NAN);
+
+ CHECK_MESSAGE(
+ Basis(x, x, x).is_finite(),
+ "Basis with all components finite should be finite");
+
+ CHECK_FALSE_MESSAGE(
+ Basis(infinite, x, x).is_finite(),
+ "Basis with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Basis(x, infinite, x).is_finite(),
+ "Basis with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Basis(x, x, infinite).is_finite(),
+ "Basis with one component infinite should not be finite.");
+
+ CHECK_FALSE_MESSAGE(
+ Basis(infinite, infinite, x).is_finite(),
+ "Basis with two components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Basis(infinite, x, infinite).is_finite(),
+ "Basis with two components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Basis(x, infinite, infinite).is_finite(),
+ "Basis with two components infinite should not be finite.");
+
+ CHECK_FALSE_MESSAGE(
+ Basis(infinite, infinite, infinite).is_finite(),
+ "Basis with three components infinite should not be finite.");
+}
+
} // namespace TestBasis
#endif // TEST_BASIS_H
diff --git a/tests/core/math/test_plane.h b/tests/core/math/test_plane.h
index d81a5af1ce..84d9a0ff7d 100644
--- a/tests/core/math/test_plane.h
+++ b/tests/core/math/test_plane.h
@@ -167,6 +167,29 @@ TEST_CASE("[Plane] Intersection") {
vec_out.is_equal_approx(Vector3(1, 1, 1)),
"intersects_segment() should modify vec_out to the expected result.");
}
+
+TEST_CASE("[Plane] Finite number checks") {
+ const Vector3 x(0, 1, 2);
+ const Vector3 infinite_vec(NAN, NAN, NAN);
+ const real_t y = 0;
+ const real_t infinite_y = NAN;
+
+ CHECK_MESSAGE(
+ Plane(x, y).is_finite(),
+ "Plane with all components finite should be finite");
+
+ CHECK_FALSE_MESSAGE(
+ Plane(x, infinite_y).is_finite(),
+ "Plane with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Plane(infinite_vec, y).is_finite(),
+ "Plane with one component infinite should not be finite.");
+
+ CHECK_FALSE_MESSAGE(
+ Plane(infinite_vec, infinite_y).is_finite(),
+ "Plane with two components infinite should not be finite.");
+}
+
} // namespace TestPlane
#endif // TEST_PLANE_H
diff --git a/tests/core/math/test_quaternion.h b/tests/core/math/test_quaternion.h
index 63d30759bb..d1912cbf42 100644
--- a/tests/core/math/test_quaternion.h
+++ b/tests/core/math/test_quaternion.h
@@ -384,6 +384,63 @@ TEST_CASE("[Stress][Quaternion] Many vector xforms") {
}
}
+TEST_CASE("[Quaternion] Finite number checks") {
+ const real_t x = NAN;
+
+ CHECK_MESSAGE(
+ Quaternion(0, 1, 2, 3).is_finite(),
+ "Quaternion with all components finite should be finite");
+
+ CHECK_FALSE_MESSAGE(
+ Quaternion(x, 1, 2, 3).is_finite(),
+ "Quaternion with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Quaternion(0, x, 2, 3).is_finite(),
+ "Quaternion with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Quaternion(0, 1, x, 3).is_finite(),
+ "Quaternion with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Quaternion(0, 1, 2, x).is_finite(),
+ "Quaternion with one component infinite should not be finite.");
+
+ CHECK_FALSE_MESSAGE(
+ Quaternion(x, x, 2, 3).is_finite(),
+ "Quaternion with two components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Quaternion(x, 1, x, 3).is_finite(),
+ "Quaternion with two components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Quaternion(x, 1, 2, x).is_finite(),
+ "Quaternion with two components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Quaternion(0, x, x, 3).is_finite(),
+ "Quaternion with two components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Quaternion(0, x, 2, x).is_finite(),
+ "Quaternion with two components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Quaternion(0, 1, x, x).is_finite(),
+ "Quaternion with two components infinite should not be finite.");
+
+ CHECK_FALSE_MESSAGE(
+ Quaternion(0, x, x, x).is_finite(),
+ "Quaternion with three components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Quaternion(x, 1, x, x).is_finite(),
+ "Quaternion with three components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Quaternion(x, x, 2, x).is_finite(),
+ "Quaternion with three components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Quaternion(x, x, x, 3).is_finite(),
+ "Quaternion with three components infinite should not be finite.");
+
+ CHECK_FALSE_MESSAGE(
+ Quaternion(x, x, x, x).is_finite(),
+ "Quaternion with four components infinite should not be finite.");
+}
+
} // namespace TestQuaternion
#endif // TEST_QUATERNION_H
diff --git a/tests/core/math/test_rect2.h b/tests/core/math/test_rect2.h
index 6323b214db..d784875c1c 100644
--- a/tests/core/math/test_rect2.h
+++ b/tests/core/math/test_rect2.h
@@ -300,6 +300,27 @@ TEST_CASE("[Rect2] Merging") {
Rect2(0, 100, 1280, 720).merge(Rect2(-4000, -4000, 100, 100)).is_equal_approx(Rect2(-4000, -4000, 5280, 4820)),
"merge() with non-enclosed Rect2 should return the expected result.");
}
+
+TEST_CASE("[Rect2] Finite number checks") {
+ const Vector2 x(0, 1);
+ const Vector2 infinite(NAN, NAN);
+
+ CHECK_MESSAGE(
+ Rect2(x, x).is_finite(),
+ "Rect2 with all components finite should be finite");
+
+ CHECK_FALSE_MESSAGE(
+ Rect2(infinite, x).is_finite(),
+ "Rect2 with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Rect2(x, infinite).is_finite(),
+ "Rect2 with one component infinite should not be finite.");
+
+ CHECK_FALSE_MESSAGE(
+ Rect2(infinite, infinite).is_finite(),
+ "Rect2 with two components infinite should not be finite.");
+}
+
} // namespace TestRect2
#endif // TEST_RECT2_H
diff --git a/tests/core/math/test_transform_2d.h b/tests/core/math/test_transform_2d.h
index 697bf63fc5..ab51bcd7da 100644
--- a/tests/core/math/test_transform_2d.h
+++ b/tests/core/math/test_transform_2d.h
@@ -83,6 +83,40 @@ TEST_CASE("[Transform2D] rotation") {
CHECK(orig.rotated(phi) == R * orig);
CHECK(orig.rotated_local(phi) == orig * R);
}
+
+TEST_CASE("[Transform2D] Finite number checks") {
+ const Vector2 x(0, 1);
+ const Vector2 infinite(NAN, NAN);
+
+ CHECK_MESSAGE(
+ Transform2D(x, x, x).is_finite(),
+ "Transform2D with all components finite should be finite");
+
+ CHECK_FALSE_MESSAGE(
+ Transform2D(infinite, x, x).is_finite(),
+ "Transform2D with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Transform2D(x, infinite, x).is_finite(),
+ "Transform2D with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Transform2D(x, x, infinite).is_finite(),
+ "Transform2D with one component infinite should not be finite.");
+
+ CHECK_FALSE_MESSAGE(
+ Transform2D(infinite, infinite, x).is_finite(),
+ "Transform2D with two components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Transform2D(infinite, x, infinite).is_finite(),
+ "Transform2D with two components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Transform2D(x, infinite, infinite).is_finite(),
+ "Transform2D with two components infinite should not be finite.");
+
+ CHECK_FALSE_MESSAGE(
+ Transform2D(infinite, infinite, infinite).is_finite(),
+ "Transform2D with three components infinite should not be finite.");
+}
+
} // namespace TestTransform2D
#endif // TEST_TRANSFORM_2D_H
diff --git a/tests/core/math/test_transform_3d.h b/tests/core/math/test_transform_3d.h
index da166b43f7..d2730f3577 100644
--- a/tests/core/math/test_transform_3d.h
+++ b/tests/core/math/test_transform_3d.h
@@ -84,6 +84,29 @@ TEST_CASE("[Transform3D] rotation") {
CHECK(orig.rotated(axis, phi) == R * orig);
CHECK(orig.rotated_local(axis, phi) == orig * R);
}
+
+TEST_CASE("[Transform3D] Finite number checks") {
+ const Vector3 y(0, 1, 2);
+ const Vector3 infinite_vec(NAN, NAN, NAN);
+ const Basis x(y, y, y);
+ const Basis infinite_basis(infinite_vec, infinite_vec, infinite_vec);
+
+ CHECK_MESSAGE(
+ Transform3D(x, y).is_finite(),
+ "Transform3D with all components finite should be finite");
+
+ CHECK_FALSE_MESSAGE(
+ Transform3D(x, infinite_vec).is_finite(),
+ "Transform3D with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Transform3D(infinite_basis, y).is_finite(),
+ "Transform3D with one component infinite should not be finite.");
+
+ CHECK_FALSE_MESSAGE(
+ Transform3D(infinite_basis, infinite_vec).is_finite(),
+ "Transform3D with two components infinite should not be finite.");
+}
+
} // namespace TestTransform3D
#endif // TEST_TRANSFORM_3D_H
diff --git a/tests/core/math/test_vector2.h b/tests/core/math/test_vector2.h
index 0d7f1163e4..a87b9ffc02 100644
--- a/tests/core/math/test_vector2.h
+++ b/tests/core/math/test_vector2.h
@@ -465,6 +465,32 @@ TEST_CASE("[Vector2] Linear algebra methods") {
Math::is_equal_approx(Vector2(-a.x, a.y).dot(Vector2(b.x, -b.y)), (real_t)-57.3),
"Vector2 dot should return expected value.");
}
+
+TEST_CASE("[Vector2] Finite number checks") {
+ const double infinite[] = { NAN, INFINITY, -INFINITY };
+
+ CHECK_MESSAGE(
+ Vector2(0, 1).is_finite(),
+ "Vector2(0, 1) should be finite");
+
+ for (double x : infinite) {
+ CHECK_FALSE_MESSAGE(
+ Vector2(x, 1).is_finite(),
+ "Vector2 with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Vector2(0, x).is_finite(),
+ "Vector2 with one component infinite should not be finite.");
+ }
+
+ for (double x : infinite) {
+ for (double y : infinite) {
+ CHECK_FALSE_MESSAGE(
+ Vector2(x, y).is_finite(),
+ "Vector2 with two components infinite should not be finite.");
+ }
+ }
+}
+
} // namespace TestVector2
#endif // TEST_VECTOR2_H
diff --git a/tests/core/math/test_vector3.h b/tests/core/math/test_vector3.h
index be271bad1f..4932cd04db 100644
--- a/tests/core/math/test_vector3.h
+++ b/tests/core/math/test_vector3.h
@@ -479,6 +479,51 @@ TEST_CASE("[Vector3] Linear algebra methods") {
Math::is_equal_approx(Vector3(-a.x, a.y, -a.z).dot(Vector3(b.x, -b.y, b.z)), (real_t)-75.24),
"Vector3 dot should return expected value.");
}
+
+TEST_CASE("[Vector3] Finite number checks") {
+ const double infinite[] = { NAN, INFINITY, -INFINITY };
+
+ CHECK_MESSAGE(
+ Vector3(0, 1, 2).is_finite(),
+ "Vector3(0, 1, 2) should be finite");
+
+ for (double x : infinite) {
+ CHECK_FALSE_MESSAGE(
+ Vector3(x, 1, 2).is_finite(),
+ "Vector3 with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Vector3(0, x, 2).is_finite(),
+ "Vector3 with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Vector3(0, 1, x).is_finite(),
+ "Vector3 with one component infinite should not be finite.");
+ }
+
+ for (double x : infinite) {
+ for (double y : infinite) {
+ CHECK_FALSE_MESSAGE(
+ Vector3(x, y, 2).is_finite(),
+ "Vector3 with two components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Vector3(x, 1, y).is_finite(),
+ "Vector3 with two components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Vector3(0, x, y).is_finite(),
+ "Vector3 with two components infinite should not be finite.");
+ }
+ }
+
+ for (double x : infinite) {
+ for (double y : infinite) {
+ for (double z : infinite) {
+ CHECK_FALSE_MESSAGE(
+ Vector3(x, y, z).is_finite(),
+ "Vector3 with three components infinite should not be finite.");
+ }
+ }
+ }
+}
+
} // namespace TestVector3
#endif // TEST_VECTOR3_H
diff --git a/tests/core/math/test_vector4.h b/tests/core/math/test_vector4.h
index 3f50f16635..b31db56f67 100644
--- a/tests/core/math/test_vector4.h
+++ b/tests/core/math/test_vector4.h
@@ -314,6 +314,84 @@ TEST_CASE("[Vector4] Linear algebra methods") {
Math::is_equal_approx((vector1 * 2).dot(vector2 * 4), (real_t)-25.9 * 8),
"Vector4 dot product should work as expected.");
}
+
+TEST_CASE("[Vector4] Finite number checks") {
+ const double infinite[] = { NAN, INFINITY, -INFINITY };
+
+ CHECK_MESSAGE(
+ Vector4(0, 1, 2, 3).is_finite(),
+ "Vector4(0, 1, 2, 3) should be finite");
+
+ for (double x : infinite) {
+ CHECK_FALSE_MESSAGE(
+ Vector4(x, 1, 2, 3).is_finite(),
+ "Vector4 with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Vector4(0, x, 2, 3).is_finite(),
+ "Vector4 with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Vector4(0, 1, x, 3).is_finite(),
+ "Vector4 with one component infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Vector4(0, 1, 2, x).is_finite(),
+ "Vector4 with one component infinite should not be finite.");
+ }
+
+ for (double x : infinite) {
+ for (double y : infinite) {
+ CHECK_FALSE_MESSAGE(
+ Vector4(x, y, 2, 3).is_finite(),
+ "Vector4 with two components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Vector4(x, 1, y, 3).is_finite(),
+ "Vector4 with two components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Vector4(x, 1, 2, y).is_finite(),
+ "Vector4 with two components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Vector4(0, x, y, 3).is_finite(),
+ "Vector4 with two components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Vector4(0, x, 2, y).is_finite(),
+ "Vector4 with two components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Vector4(0, 1, x, y).is_finite(),
+ "Vector4 with two components infinite should not be finite.");
+ }
+ }
+
+ for (double x : infinite) {
+ for (double y : infinite) {
+ for (double z : infinite) {
+ CHECK_FALSE_MESSAGE(
+ Vector4(0, x, y, z).is_finite(),
+ "Vector4 with three components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Vector4(x, 1, y, z).is_finite(),
+ "Vector4 with three components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Vector4(x, y, 2, z).is_finite(),
+ "Vector4 with three components infinite should not be finite.");
+ CHECK_FALSE_MESSAGE(
+ Vector4(x, y, z, 3).is_finite(),
+ "Vector4 with three components infinite should not be finite.");
+ }
+ }
+ }
+
+ for (double x : infinite) {
+ for (double y : infinite) {
+ for (double z : infinite) {
+ for (double w : infinite) {
+ CHECK_FALSE_MESSAGE(
+ Vector4(x, y, z, w).is_finite(),
+ "Vector4 with four components infinite should not be finite.");
+ }
+ }
+ }
+ }
+}
+
} // namespace TestVector4
#endif // TEST_VECTOR4_H
diff --git a/tests/scene/test_text_edit.h b/tests/scene/test_text_edit.h
index 6b831bc9c7..9514178c61 100644
--- a/tests/scene/test_text_edit.h
+++ b/tests/scene/test_text_edit.h
@@ -2944,6 +2944,18 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
SIGNAL_CHECK("lines_edited_from", lines_edited_args);
text_edit->set_overtype_mode_enabled(false);
CHECK_FALSE(text_edit->is_overtype_mode_enabled());
+
+ lines_edited_args.remove_at(0);
+ lines_edited_args.remove_at(1);
+
+ SEND_GUI_KEY_EVENT(text_edit, Key::TAB);
+ CHECK(text_edit->get_viewport()->is_input_handled());
+ CHECK(text_edit->get_text() == "A\tB\nA\tB");
+ CHECK(text_edit->get_caret_column() == 2);
+ CHECK(text_edit->get_caret_column(1) == 2);
+ SIGNAL_CHECK("caret_changed", empty_signal_args);
+ SIGNAL_CHECK("text_changed", empty_signal_args);
+ SIGNAL_CHECK("lines_edited_from", lines_edited_args);
}
SIGNAL_UNWATCH(text_edit, "text_set");
@@ -3321,6 +3333,11 @@ TEST_CASE("[SceneTree][TextEdit] muiticaret") {
CHECK(text_edit->get_caret_count() == 1);
CHECK(text_edit->get_caret_line(0) == 0);
CHECK(text_edit->get_caret_column(0) == 1);
+
+ ERR_PRINT_OFF;
+ text_edit->remove_caret(0);
+ CHECK(text_edit->get_caret_count() == 1);
+ ERR_PRINT_ON;
}
SUBCASE("[TextEdit] caret index edit order") {