summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.pre-commit-config.yaml4
-rw-r--r--COPYRIGHT.txt66
-rw-r--r--core/core_bind.cpp5
-rw-r--r--core/core_bind.h2
-rw-r--r--core/io/resource.cpp19
-rw-r--r--core/io/resource.h5
-rw-r--r--core/object/object.cpp19
-rw-r--r--core/object/object.h1
-rw-r--r--core/variant/callable.cpp7
-rw-r--r--core/variant/callable.h1
-rw-r--r--core/variant/variant_call.cpp1
-rw-r--r--core/variant/variant_op.h30
-rw-r--r--doc/classes/EditorSettings.xml3
-rw-r--r--doc/classes/ExternalTexture.xml36
-rw-r--r--doc/classes/Object.xml8
-rw-r--r--doc/classes/ProjectSettings.xml1
-rw-r--r--doc/classes/RenderingServer.xml5
-rw-r--r--doc/classes/Resource.xml49
-rw-r--r--doc/classes/ResourceSaver.xml8
-rw-r--r--doc/classes/ScrollContainer.xml3
-rw-r--r--doc/classes/Signal.xml6
-rw-r--r--doc/classes/TextEdit.xml3
-rwxr-xr-xdoc/tools/make_rst.py2
-rw-r--r--drivers/gles3/shader_gles3.cpp8
-rw-r--r--drivers/gles3/shaders/canvas.glsl4
-rw-r--r--drivers/gles3/storage/config.cpp8
-rw-r--r--drivers/gles3/storage/config.h3
-rw-r--r--drivers/gles3/storage/material_storage.cpp11
-rw-r--r--drivers/gles3/storage/texture_storage.cpp63
-rw-r--r--drivers/gles3/storage/texture_storage.h3
-rw-r--r--editor/code_editor.cpp3
-rw-r--r--editor/editor_autoload_settings.cpp9
-rw-r--r--editor/editor_help_search.cpp4
-rw-r--r--editor/editor_help_search.h2
-rw-r--r--editor/editor_node.cpp35
-rw-r--r--editor/editor_settings.cpp3
-rw-r--r--editor/import/3d/resource_importer_obj.cpp34
-rw-r--r--editor/renames_map_3_to_4.cpp1
-rw-r--r--main/main.cpp11
-rw-r--r--modules/godot_physics_3d/SCsub7
-rw-r--r--modules/godot_physics_3d/config.py6
-rw-r--r--modules/godot_physics_3d/gjk_epa.cpp (renamed from servers/physics_3d/gjk_epa.cpp)0
-rw-r--r--modules/godot_physics_3d/gjk_epa.h (renamed from servers/physics_3d/gjk_epa.h)0
-rw-r--r--modules/godot_physics_3d/godot_area_3d.cpp (renamed from servers/physics_3d/godot_area_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/godot_area_3d.h (renamed from servers/physics_3d/godot_area_3d.h)0
-rw-r--r--modules/godot_physics_3d/godot_area_pair_3d.cpp (renamed from servers/physics_3d/godot_area_pair_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/godot_area_pair_3d.h (renamed from servers/physics_3d/godot_area_pair_3d.h)0
-rw-r--r--modules/godot_physics_3d/godot_body_3d.cpp (renamed from servers/physics_3d/godot_body_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/godot_body_3d.h (renamed from servers/physics_3d/godot_body_3d.h)0
-rw-r--r--modules/godot_physics_3d/godot_body_direct_state_3d.cpp (renamed from servers/physics_3d/godot_body_direct_state_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/godot_body_direct_state_3d.h (renamed from servers/physics_3d/godot_body_direct_state_3d.h)0
-rw-r--r--modules/godot_physics_3d/godot_body_pair_3d.cpp (renamed from servers/physics_3d/godot_body_pair_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/godot_body_pair_3d.h (renamed from servers/physics_3d/godot_body_pair_3d.h)0
-rw-r--r--modules/godot_physics_3d/godot_broad_phase_3d.cpp (renamed from servers/physics_3d/godot_broad_phase_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/godot_broad_phase_3d.h (renamed from servers/physics_3d/godot_broad_phase_3d.h)0
-rw-r--r--modules/godot_physics_3d/godot_broad_phase_3d_bvh.cpp (renamed from servers/physics_3d/godot_broad_phase_3d_bvh.cpp)0
-rw-r--r--modules/godot_physics_3d/godot_broad_phase_3d_bvh.h (renamed from servers/physics_3d/godot_broad_phase_3d_bvh.h)0
-rw-r--r--modules/godot_physics_3d/godot_collision_object_3d.cpp (renamed from servers/physics_3d/godot_collision_object_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/godot_collision_object_3d.h (renamed from servers/physics_3d/godot_collision_object_3d.h)0
-rw-r--r--modules/godot_physics_3d/godot_collision_solver_3d.cpp (renamed from servers/physics_3d/godot_collision_solver_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/godot_collision_solver_3d.h (renamed from servers/physics_3d/godot_collision_solver_3d.h)0
-rw-r--r--modules/godot_physics_3d/godot_collision_solver_3d_sat.cpp (renamed from servers/physics_3d/godot_collision_solver_3d_sat.cpp)0
-rw-r--r--modules/godot_physics_3d/godot_collision_solver_3d_sat.h (renamed from servers/physics_3d/godot_collision_solver_3d_sat.h)0
-rw-r--r--modules/godot_physics_3d/godot_constraint_3d.h (renamed from servers/physics_3d/godot_constraint_3d.h)0
-rw-r--r--modules/godot_physics_3d/godot_joint_3d.h (renamed from servers/physics_3d/godot_joint_3d.h)0
-rw-r--r--modules/godot_physics_3d/godot_physics_server_3d.cpp (renamed from servers/physics_3d/godot_physics_server_3d.cpp)6
-rw-r--r--modules/godot_physics_3d/godot_physics_server_3d.h (renamed from servers/physics_3d/godot_physics_server_3d.h)0
-rw-r--r--modules/godot_physics_3d/godot_shape_3d.cpp (renamed from servers/physics_3d/godot_shape_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/godot_shape_3d.h (renamed from servers/physics_3d/godot_shape_3d.h)0
-rw-r--r--modules/godot_physics_3d/godot_soft_body_3d.cpp (renamed from servers/physics_3d/godot_soft_body_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/godot_soft_body_3d.h (renamed from servers/physics_3d/godot_soft_body_3d.h)0
-rw-r--r--modules/godot_physics_3d/godot_space_3d.cpp (renamed from servers/physics_3d/godot_space_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/godot_space_3d.h (renamed from servers/physics_3d/godot_space_3d.h)0
-rw-r--r--modules/godot_physics_3d/godot_step_3d.cpp (renamed from servers/physics_3d/godot_step_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/godot_step_3d.h (renamed from servers/physics_3d/godot_step_3d.h)0
-rw-r--r--modules/godot_physics_3d/joints/SCsub5
-rw-r--r--modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.cpp (renamed from servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.h (renamed from servers/physics_3d/joints/godot_cone_twist_joint_3d.h)4
-rw-r--r--modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.cpp (renamed from servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.h (renamed from servers/physics_3d/joints/godot_generic_6dof_joint_3d.h)4
-rw-r--r--modules/godot_physics_3d/joints/godot_hinge_joint_3d.cpp (renamed from servers/physics_3d/joints/godot_hinge_joint_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/joints/godot_hinge_joint_3d.h (renamed from servers/physics_3d/joints/godot_hinge_joint_3d.h)4
-rw-r--r--modules/godot_physics_3d/joints/godot_jacobian_entry_3d.h (renamed from servers/physics_3d/joints/godot_jacobian_entry_3d.h)0
-rw-r--r--modules/godot_physics_3d/joints/godot_pin_joint_3d.cpp (renamed from servers/physics_3d/joints/godot_pin_joint_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/joints/godot_pin_joint_3d.h (renamed from servers/physics_3d/joints/godot_pin_joint_3d.h)4
-rw-r--r--modules/godot_physics_3d/joints/godot_slider_joint_3d.cpp (renamed from servers/physics_3d/joints/godot_slider_joint_3d.cpp)0
-rw-r--r--modules/godot_physics_3d/joints/godot_slider_joint_3d.h (renamed from servers/physics_3d/joints/godot_slider_joint_3d.h)4
-rw-r--r--modules/godot_physics_3d/register_types.cpp61
-rw-r--r--modules/godot_physics_3d/register_types.h39
-rw-r--r--modules/mono/editor/bindings_generator.cpp26
-rw-r--r--modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml9
-rw-r--r--modules/openxr/extensions/openxr_composition_layer_extension.cpp11
-rw-r--r--modules/openxr/extensions/openxr_extension_wrapper.h3
-rw-r--r--modules/openxr/extensions/openxr_extension_wrapper_extension.cpp13
-rw-r--r--modules/openxr/extensions/openxr_extension_wrapper_extension.h4
-rw-r--r--modules/openxr/openxr_api.cpp2
-rw-r--r--modules/raycast/godot_update_embree.py14
-rw-r--r--modules/upnp/upnp.cpp4
-rw-r--r--platform/linuxbsd/wayland/display_server_wayland.cpp32
-rw-r--r--platform/windows/detect.py16
-rw-r--r--pyproject.toml1
-rw-r--r--scene/gui/code_edit.cpp3
-rw-r--r--scene/gui/scroll_container.cpp32
-rw-r--r--scene/gui/scroll_container.h4
-rw-r--r--scene/gui/text_edit.cpp22
-rw-r--r--scene/gui/text_edit.h4
-rw-r--r--scene/main/node.cpp5
-rw-r--r--scene/main/node.h1
-rw-r--r--scene/register_scene_types.cpp2
-rw-r--r--scene/resources/external_texture.cpp89
-rw-r--r--scene/resources/external_texture.h66
-rw-r--r--scu_builders.py4
-rw-r--r--servers/SCsub1
-rw-r--r--servers/physics_3d/SCsub7
-rw-r--r--servers/physics_3d/joints/SCsub5
-rw-r--r--servers/physics_server_3d.cpp4
-rw-r--r--servers/physics_server_3d_dummy.h436
-rw-r--r--servers/register_server_types.cpp17
-rw-r--r--servers/rendering/dummy/storage/texture_storage.h2
-rw-r--r--servers/rendering/renderer_rd/shader_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas.glsl4
-rw-r--r--servers/rendering/renderer_rd/storage_rd/material_storage.cpp1
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h2
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.cpp6
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.h2
-rw-r--r--servers/rendering/rendering_server_default.h13
-rw-r--r--servers/rendering/shader_compiler.cpp2
-rw-r--r--servers/rendering/shader_language.cpp26
-rw-r--r--servers/rendering/shader_language.h2
-rw-r--r--servers/rendering/storage/texture_storage.h2
-rw-r--r--servers/rendering_server.cpp1
-rw-r--r--servers/rendering_server.h3
-rw-r--r--tests/scene/test_code_edit.h25
-rw-r--r--tests/scene/test_text_edit.h48
-rw-r--r--tests/test_main.cpp4
-rw-r--r--thirdparty/README.md2
-rw-r--r--thirdparty/miniupnpc/include/miniupnpc.h19
-rw-r--r--thirdparty/miniupnpc/src/addr_is_reserved.c11
-rw-r--r--thirdparty/miniupnpc/src/minisoap.c7
-rw-r--r--thirdparty/miniupnpc/src/minissdpc.c9
-rw-r--r--thirdparty/miniupnpc/src/miniupnpc.c93
-rw-r--r--thirdparty/miniupnpc/src/miniupnpcstrings.h2
-rw-r--r--thirdparty/miniupnpc/src/miniwget.c44
-rw-r--r--thirdparty/miniupnpc/src/win32_snprintf.h4
144 files changed, 1492 insertions, 311 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index cb25337fad..8cfb00fd8e 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -39,14 +39,14 @@ repos:
stages: [manual] # Not automatically triggered, invoked via `pre-commit run --hook-stage manual clang-tidy`
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.4.4
+ rev: v0.6.6
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: v0.971
+ rev: v1.11.2
hooks:
- id: mypy
files: \.py$
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
index 5b6dcbb567..c0bb756d2e 100644
--- a/COPYRIGHT.txt
+++ b/COPYRIGHT.txt
@@ -63,6 +63,39 @@ Copyright: 2011, Ole Kniemeyer, MAXON, www.maxon.net
2007-2014, Juan Linietsky, Ariel Manzur
License: Expat and Zlib
+Files: ./modules/godot_physics_3d/gjk_epa.cpp
+ ./modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.cpp
+ ./modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.h
+ ./modules/godot_physics_3d/joints/godot_hinge_joint_3d.cpp
+ ./modules/godot_physics_3d/joints/godot_hinge_joint_3d_sw.h
+ ./modules/godot_physics_3d/joints/godot_jacobian_entry_3d_sw.h
+ ./modules/godot_physics_3d/joints/godot_pin_joint_3d.cpp
+ ./modules/godot_physics_3d/joints/godot_pin_joint_3d.h
+ ./modules/godot_physics_3d/joints/godot_slider_joint_3d.cpp
+ ./modules/godot_physics_3d/joints/godot_slider_joint_3d.h
+ ./modules/godot_physics_3d/godot_soft_body_3d.cpp
+ ./modules/godot_physics_3d/godot_soft_body_3d.h
+ ./modules/godot_physics_3d/godot_shape_3d.cpp
+ ./modules/godot_physics_3d/godot_shape_3d.h
+Comment: Bullet Continuous Collision Detection and Physics Library
+Copyright: 2003-2008, Erwin Coumans
+ 2014-present, Godot Engine contributors
+ 2007-2014, Juan Linietsky, Ariel Manzur
+License: Expat and Zlib
+
+Files: ./modules/godot_physics_3d/godot_collision_solver_3d_sat.cpp
+Comment: Open Dynamics Engine
+Copyright: 2001-2003, Russell L. Smith, Alen Ladavac, Nguyen Binh
+License: BSD-3-clause
+
+Files: ./modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.cpp
+ ./modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.h
+Comment: Bullet Continuous Collision Detection and Physics Library
+Copyright: 2007, Starbreeze Studios
+ 2014-present, Godot Engine contributors
+ 2007-2014, Juan Linietsky, Ariel Manzur
+License: Expat and Zlib
+
Files: ./modules/lightmapper_rd/lm_compute.glsl
Comment: Joint Non-Local Means (JNLM) denoiser
Copyright: 2020, Manuel Prandini
@@ -98,39 +131,6 @@ Comment: Chipmunk2D Joint Constraints
Copyright: 2007, Scott Lembcke
License: Expat
-Files: ./servers/physics_3d/collision_solver_3d_sat.cpp
-Comment: Open Dynamics Engine
-Copyright: 2001-2003, Russell L. Smith, Alen Ladavac, Nguyen Binh
-License: BSD-3-clause
-
-Files: ./servers/physics_3d/gjk_epa.cpp
- ./servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp
- ./servers/physics_3d/joints/generic_6dof_joint_3d_sw.h
- ./servers/physics_3d/joints/hinge_joint_3d_sw.cpp
- ./servers/physics_3d/joints/hinge_joint_3d_sw.h
- ./servers/physics_3d/joints/jacobian_entry_3d_sw.h
- ./servers/physics_3d/joints/pin_joint_3d_sw.cpp
- ./servers/physics_3d/joints/pin_joint_3d_sw.h
- ./servers/physics_3d/joints/slider_joint_3d_sw.cpp
- ./servers/physics_3d/joints/slider_joint_3d_sw.h
- ./servers/physics_3d/soft_body_3d_sw.cpp
- ./servers/physics_3d/soft_body_3d_sw.h
- ./servers/physics_3d/shape_3d_sw.cpp
- ./servers/physics_3d/shape_3d_sw.h
-Comment: Bullet Continuous Collision Detection and Physics Library
-Copyright: 2003-2008, Erwin Coumans
- 2014-present, Godot Engine contributors
- 2007-2014, Juan Linietsky, Ariel Manzur
-License: Expat and Zlib
-
-Files: ./servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp
- ./servers/physics_3d/joints/cone_twist_joint_3d_sw.h
-Comment: Bullet Continuous Collision Detection and Physics Library
-Copyright: 2007, Starbreeze Studios
- 2014-present, Godot Engine contributors
- 2007-2014, Juan Linietsky, Ariel Manzur
-License: Expat and Zlib
-
Files: ./servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl
./servers/rendering/renderer_rd/shaders/ssao_blur.glsl
./servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl
diff --git a/core/core_bind.cpp b/core/core_bind.cpp
index bbfbb6e3cd..6a2da8aafb 100644
--- a/core/core_bind.cpp
+++ b/core/core_bind.cpp
@@ -184,6 +184,10 @@ void ResourceSaver::remove_resource_format_saver(Ref<ResourceFormatSaver> p_form
::ResourceSaver::remove_resource_format_saver(p_format_saver);
}
+ResourceUID::ID ResourceSaver::get_resource_id_for_path(const String &p_path, bool p_generate) {
+ return ::ResourceSaver::get_resource_id_for_path(p_path, p_generate);
+}
+
ResourceSaver *ResourceSaver::singleton = nullptr;
void ResourceSaver::_bind_methods() {
@@ -191,6 +195,7 @@ void ResourceSaver::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_recognized_extensions", "type"), &ResourceSaver::get_recognized_extensions);
ClassDB::bind_method(D_METHOD("add_resource_format_saver", "format_saver", "at_front"), &ResourceSaver::add_resource_format_saver, DEFVAL(false));
ClassDB::bind_method(D_METHOD("remove_resource_format_saver", "format_saver"), &ResourceSaver::remove_resource_format_saver);
+ ClassDB::bind_method(D_METHOD("get_resource_id_for_path", "path", "generate"), &ResourceSaver::get_resource_id_for_path, DEFVAL(false));
BIND_BITFIELD_FLAG(FLAG_NONE);
BIND_BITFIELD_FLAG(FLAG_RELATIVE_PATHS);
diff --git a/core/core_bind.h b/core/core_bind.h
index 2a31e64425..a9311f6268 100644
--- a/core/core_bind.h
+++ b/core/core_bind.h
@@ -116,6 +116,8 @@ public:
void add_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver, bool p_at_front);
void remove_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver);
+ ResourceUID::ID get_resource_id_for_path(const String &p_path, bool p_generate = false);
+
ResourceSaver() { singleton = this; }
};
diff --git a/core/io/resource.cpp b/core/io/resource.cpp
index 6177cba6a4..5f8a4b85a4 100644
--- a/core/io/resource.cpp
+++ b/core/io/resource.cpp
@@ -96,6 +96,7 @@ String Resource::get_path() const {
void Resource::set_path_cache(const String &p_path) {
path_cache = p_path;
+ GDVIRTUAL_CALL(_set_path_cache, p_path);
}
String Resource::generate_scene_unique_id() {
@@ -188,6 +189,7 @@ void Resource::disconnect_changed(const Callable &p_callable) {
}
void Resource::reset_state() {
+ GDVIRTUAL_CALL(_reset_state);
}
Error Resource::copy_from(const Ref<Resource> &p_resource) {
@@ -495,9 +497,9 @@ void Resource::set_as_translation_remapped(bool p_remapped) {
}
}
-#ifdef TOOLS_ENABLED
//helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored
void Resource::set_id_for_path(const String &p_path, const String &p_id) {
+#ifdef TOOLS_ENABLED
if (p_id.is_empty()) {
ResourceCache::path_cache_lock.write_lock();
ResourceCache::resource_path_cache[p_path].erase(get_path());
@@ -507,9 +509,11 @@ void Resource::set_id_for_path(const String &p_path, const String &p_id) {
ResourceCache::resource_path_cache[p_path][get_path()] = p_id;
ResourceCache::path_cache_lock.write_unlock();
}
+#endif
}
String Resource::get_id_for_path(const String &p_path) const {
+#ifdef TOOLS_ENABLED
ResourceCache::path_cache_lock.read_lock();
if (ResourceCache::resource_path_cache[p_path].has(get_path())) {
String result = ResourceCache::resource_path_cache[p_path][get_path()];
@@ -519,13 +523,16 @@ String Resource::get_id_for_path(const String &p_path) const {
ResourceCache::path_cache_lock.read_unlock();
return "";
}
-}
+#else
+ return "";
#endif
+}
void Resource::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_path", "path"), &Resource::_set_path);
ClassDB::bind_method(D_METHOD("take_over_path", "path"), &Resource::_take_over_path);
ClassDB::bind_method(D_METHOD("get_path"), &Resource::get_path);
+ ClassDB::bind_method(D_METHOD("set_path_cache", "path"), &Resource::set_path_cache);
ClassDB::bind_method(D_METHOD("set_name", "name"), &Resource::set_name);
ClassDB::bind_method(D_METHOD("get_name"), &Resource::get_name);
ClassDB::bind_method(D_METHOD("get_rid"), &Resource::get_rid);
@@ -533,6 +540,12 @@ void Resource::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_local_to_scene"), &Resource::is_local_to_scene);
ClassDB::bind_method(D_METHOD("get_local_scene"), &Resource::get_local_scene);
ClassDB::bind_method(D_METHOD("setup_local_to_scene"), &Resource::setup_local_to_scene);
+ ClassDB::bind_method(D_METHOD("reset_state"), &Resource::reset_state);
+
+ ClassDB::bind_method(D_METHOD("set_id_for_path", "path", "id"), &Resource::set_id_for_path);
+ ClassDB::bind_method(D_METHOD("get_id_for_path", "path"), &Resource::get_id_for_path);
+
+ ClassDB::bind_method(D_METHOD("is_built_in"), &Resource::is_built_in);
ClassDB::bind_static_method("Resource", D_METHOD("generate_scene_unique_id"), &Resource::generate_scene_unique_id);
ClassDB::bind_method(D_METHOD("set_scene_unique_id", "id"), &Resource::set_scene_unique_id);
@@ -552,6 +565,8 @@ void Resource::_bind_methods() {
GDVIRTUAL_BIND(_setup_local_to_scene);
GDVIRTUAL_BIND(_get_rid);
+ GDVIRTUAL_BIND(_reset_state);
+ GDVIRTUAL_BIND(_set_path_cache, "path");
}
Resource::Resource() :
diff --git a/core/io/resource.h b/core/io/resource.h
index 2c1a431255..8966c0233c 100644
--- a/core/io/resource.h
+++ b/core/io/resource.h
@@ -89,6 +89,9 @@ protected:
GDVIRTUAL0RC(RID, _get_rid);
+ GDVIRTUAL1C(_set_path_cache, String);
+ GDVIRTUAL0(_reset_state);
+
public:
static Node *(*_get_local_scene_func)(); //used by editor
static void (*_update_configuration_warning)(); //used by editor
@@ -144,11 +147,9 @@ public:
virtual RID get_rid() const; // some resources may offer conversion to RID
-#ifdef TOOLS_ENABLED
//helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored
void set_id_for_path(const String &p_path, const String &p_id);
String get_id_for_path(const String &p_path) const;
-#endif
Resource();
~Resource();
diff --git a/core/object/object.cpp b/core/object/object.cpp
index 2d9d468d38..b3a4ec6e2e 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -1457,6 +1457,24 @@ bool Object::is_connected(const StringName &p_signal, const Callable &p_callable
return s->slot_map.has(*p_callable.get_base_comparator());
}
+bool Object::has_connections(const StringName &p_signal) const {
+ const SignalData *s = signal_map.getptr(p_signal);
+ if (!s) {
+ bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal);
+ if (signal_is_valid) {
+ return false;
+ }
+
+ if (!script.is_null() && Ref<Script>(script)->has_script_signal(p_signal)) {
+ return false;
+ }
+
+ ERR_FAIL_V_MSG(false, "Nonexistent signal: " + p_signal + ".");
+ }
+
+ return !s->slot_map.is_empty();
+}
+
void Object::disconnect(const StringName &p_signal, const Callable &p_callable) {
_disconnect(p_signal, p_callable);
}
@@ -1697,6 +1715,7 @@ void Object::_bind_methods() {
ClassDB::bind_method(D_METHOD("connect", "signal", "callable", "flags"), &Object::connect, DEFVAL(0));
ClassDB::bind_method(D_METHOD("disconnect", "signal", "callable"), &Object::disconnect);
ClassDB::bind_method(D_METHOD("is_connected", "signal", "callable"), &Object::is_connected);
+ ClassDB::bind_method(D_METHOD("has_connections", "signal"), &Object::has_connections);
ClassDB::bind_method(D_METHOD("set_block_signals", "enable"), &Object::set_block_signals);
ClassDB::bind_method(D_METHOD("is_blocking_signals"), &Object::is_blocking_signals);
diff --git a/core/object/object.h b/core/object/object.h
index 1274247d71..763e2974b9 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -932,6 +932,7 @@ public:
MTVIRTUAL Error connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags = 0);
MTVIRTUAL void disconnect(const StringName &p_signal, const Callable &p_callable);
MTVIRTUAL bool is_connected(const StringName &p_signal, const Callable &p_callable) const;
+ MTVIRTUAL bool has_connections(const StringName &p_signal) const;
template <typename... VarArgs>
void call_deferred(const StringName &p_name, VarArgs... p_args) {
diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp
index 9dff5c1e91..bb2d0313f6 100644
--- a/core/variant/callable.cpp
+++ b/core/variant/callable.cpp
@@ -545,6 +545,13 @@ bool Signal::is_connected(const Callable &p_callable) const {
return obj->is_connected(name, p_callable);
}
+bool Signal::has_connections() const {
+ Object *obj = get_object();
+ ERR_FAIL_NULL_V(obj, false);
+
+ return obj->has_connections(name);
+}
+
Array Signal::get_connections() const {
Object *obj = get_object();
if (!obj) {
diff --git a/core/variant/callable.h b/core/variant/callable.h
index 63757d9d6e..e3c940a0e5 100644
--- a/core/variant/callable.h
+++ b/core/variant/callable.h
@@ -192,6 +192,7 @@ public:
Error connect(const Callable &p_callable, uint32_t p_flags = 0);
void disconnect(const Callable &p_callable);
bool is_connected(const Callable &p_callable) const;
+ bool has_connections() const;
Array get_connections() const;
Signal(const Object *p_object, const StringName &p_name);
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 178c0bc4ec..63fb5e8d94 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -2121,6 +2121,7 @@ static void _register_variant_builtin_methods_misc() {
bind_method(Signal, disconnect, sarray("callable"), varray());
bind_method(Signal, is_connected, sarray("callable"), varray());
bind_method(Signal, get_connections, sarray(), varray());
+ bind_method(Signal, has_connections, sarray(), varray());
bind_custom(Signal, emit, _VariantCall::func_Signal_emit, false, Variant);
diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h
index ac39a4135f..0bd8b830e0 100644
--- a/core/variant/variant_op.h
+++ b/core/variant/variant_op.h
@@ -923,7 +923,10 @@ public:
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
bool valid = true;
String result = do_mod(*VariantGetInternalPtr<S>::get_ptr(left), &valid);
- ERR_FAIL_COND_MSG(!valid, result);
+ if (unlikely(!valid)) {
+ *VariantGetInternalPtr<String>::get_ptr(r_ret) = *VariantGetInternalPtr<S>::get_ptr(left);
+ ERR_FAIL_MSG(vformat("String formatting error: %s.", result));
+ }
*VariantGetInternalPtr<String>::get_ptr(r_ret) = result;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
@@ -948,7 +951,10 @@ public:
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
bool valid = true;
String result = do_mod(*VariantGetInternalPtr<S>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right), &valid);
- ERR_FAIL_COND_MSG(!valid, result);
+ if (unlikely(!valid)) {
+ *VariantGetInternalPtr<String>::get_ptr(r_ret) = *VariantGetInternalPtr<S>::get_ptr(left);
+ ERR_FAIL_MSG(vformat("String formatting error: %s.", result));
+ }
*VariantGetInternalPtr<String>::get_ptr(r_ret) = result;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
@@ -976,7 +982,10 @@ public:
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
bool valid = true;
String result = do_mod(*VariantGetInternalPtr<S>::get_ptr(left), right->get_validated_object(), &valid);
- ERR_FAIL_COND_MSG(!valid, result);
+ if (unlikely(!valid)) {
+ *VariantGetInternalPtr<String>::get_ptr(r_ret) = *VariantGetInternalPtr<S>::get_ptr(left);
+ ERR_FAIL_MSG(vformat("String formatting error: %s.", result));
+ }
*VariantGetInternalPtr<String>::get_ptr(r_ret) = result;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
@@ -1003,7 +1012,10 @@ public:
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
bool valid = true;
String result = do_mod(*VariantGetInternalPtr<S>::get_ptr(left), *VariantGetInternalPtr<T>::get_ptr(right), &valid);
- ERR_FAIL_COND_MSG(!valid, result);
+ if (unlikely(!valid)) {
+ *VariantGetInternalPtr<String>::get_ptr(r_ret) = *VariantGetInternalPtr<S>::get_ptr(left);
+ ERR_FAIL_MSG(vformat("String formatting error: %s.", result));
+ }
*VariantGetInternalPtr<String>::get_ptr(r_ret) = result;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
@@ -1492,7 +1504,10 @@ public:
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
Object *l = right->get_validated_object();
- ERR_FAIL_NULL(l);
+ if (unlikely(!l)) {
+ *VariantGetInternalPtr<bool>::get_ptr(r_ret) = false;
+ ERR_FAIL_MSG("Invalid base object for 'in'.");
+ }
const String &a = *VariantGetInternalPtr<String>::get_ptr(left);
bool valid;
@@ -1526,7 +1541,10 @@ public:
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
Object *l = right->get_validated_object();
- ERR_FAIL_NULL(l);
+ if (unlikely(!l)) {
+ *VariantGetInternalPtr<bool>::get_ptr(r_ret) = false;
+ ERR_FAIL_MSG("Invalid base object for 'in'.");
+ }
const StringName &a = *VariantGetInternalPtr<StringName>::get_ptr(left);
bool valid;
diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml
index 940fec4688..5eb8ac6199 100644
--- a/doc/classes/EditorSettings.xml
+++ b/doc/classes/EditorSettings.xml
@@ -1200,6 +1200,9 @@
<member name="text_editor/behavior/files/trim_trailing_whitespace_on_save" type="bool" setter="" getter="">
If [code]true[/code], trims trailing whitespace when saving a script. Trailing whitespace refers to tab and space characters placed at the end of lines. Since these serve no practical purpose, they can and should be removed to make version control diffs less noisy.
</member>
+ <member name="text_editor/behavior/general/empty_selection_clipboard" type="bool" setter="" getter="">
+ If [code]true[/code], copying or cutting without a selection is performed on all lines with a caret. Otherwise, copy and cut require a selection.
+ </member>
<member name="text_editor/behavior/indent/auto_indent" type="bool" setter="" getter="">
If [code]true[/code], automatically indents code when pressing the [kbd]Enter[/kbd] key based on blocks above the new line.
</member>
diff --git a/doc/classes/ExternalTexture.xml b/doc/classes/ExternalTexture.xml
new file mode 100644
index 0000000000..6f27b62f24
--- /dev/null
+++ b/doc/classes/ExternalTexture.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="ExternalTexture" inherits="Texture2D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+ <brief_description>
+ Texture which displays the content of an external buffer.
+ </brief_description>
+ <description>
+ Displays the content of an external buffer provided by the platform.
+ Requires the [url=https://registry.khronos.org/OpenGL/extensions/OES/OES_EGL_image_external.txt]OES_EGL_image_external[/url] extension (OpenGL) or [url=https://registry.khronos.org/vulkan/specs/1.1-extensions/html/vkspec.html#VK_ANDROID_external_memory_android_hardware_buffer]VK_ANDROID_external_memory_android_hardware_buffer[/url] extension (Vulkan).
+ [b]Note:[/b] This is currently only supported in Android builds.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="get_external_texture_id" qualifiers="const">
+ <return type="int" />
+ <description>
+ Returns the external texture ID.
+ Depending on your use case, you may need to pass this to platform APIs, for example, when creating an [code]android.graphics.SurfaceTexture[/code] on Android.
+ </description>
+ </method>
+ <method name="set_external_buffer_id">
+ <return type="void" />
+ <param index="0" name="external_buffer_id" type="int" />
+ <description>
+ Sets the external buffer ID.
+ Depending on your use case, you may need to call this with data received from a platform API, for example, [code]SurfaceTexture.getHardwareBuffer()[/code] on Android.
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" />
+ <member name="size" type="Vector2" setter="set_size" getter="get_size" default="Vector2(256, 256)">
+ External texture size.
+ </member>
+ </members>
+</class>
diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml
index d0d0876108..2767a11e80 100644
--- a/doc/classes/Object.xml
+++ b/doc/classes/Object.xml
@@ -824,6 +824,14 @@
Returns the name of the translation domain used by [method tr] and [method tr_n]. See also [TranslationServer].
</description>
</method>
+ <method name="has_connections" qualifiers="const">
+ <return type="bool" />
+ <param index="0" name="signal" type="StringName" />
+ <description>
+ Returns [code]true[/code] if any connection exists on the given [param signal] name.
+ [b]Note:[/b] In C#, [param signal] must be in snake_case when referring to built-in Godot methods. Prefer using the names exposed in the [code]SignalName[/code] class to avoid allocating a new [StringName] on each call.
+ </description>
+ </method>
<method name="has_meta" qualifiers="const">
<return type="bool" />
<param index="0" name="name" type="StringName" />
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 758e98ad85..85a25b05af 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -2293,6 +2293,7 @@
<member name="physics/3d/physics_engine" type="String" setter="" getter="" default="&quot;DEFAULT&quot;">
Sets which physics engine to use for 3D physics.
"DEFAULT" and "GodotPhysics3D" are the same, as there is currently no alternative 3D physics server implemented.
+ "Dummy" is a 3D physics server that does nothing and returns only dummy values, effectively disabling all 3D physics functionality.
</member>
<member name="physics/3d/run_on_separate_thread" type="bool" setter="" getter="" default="false">
If [code]true[/code], the 3D physics server runs on a separate thread, making better use of multi-core CPUs. If [code]false[/code], the 3D physics server runs on the main thread. Running the physics server on a separate thread can increase performance, but restricts API access to only physics process.
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index 7a0893268a..144f78349f 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -5660,7 +5660,10 @@
<constant name="GLOBAL_VAR_TYPE_SAMPLERCUBE" value="27" enum="GlobalShaderParameterType">
Cubemap sampler global shader parameter ([code]global uniform samplerCube ...[/code]). Exposed as a [Cubemap] in the editor UI.
</constant>
- <constant name="GLOBAL_VAR_TYPE_MAX" value="28" enum="GlobalShaderParameterType">
+ <constant name="GLOBAL_VAR_TYPE_SAMPLEREXT" value="28" enum="GlobalShaderParameterType">
+ External sampler global shader parameter ([code]global uniform samplerExternalOES ...[/code]). Exposed as a [ExternalTexture] in the editor UI.
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_MAX" value="29" enum="GlobalShaderParameterType">
Represents the size of the [enum GlobalShaderParameterType] enum.
</constant>
<constant name="RENDERING_INFO_TOTAL_OBJECTS_IN_FRAME" value="0" enum="RenderingInfo">
diff --git a/doc/classes/Resource.xml b/doc/classes/Resource.xml
index fe09472c14..18d4047339 100644
--- a/doc/classes/Resource.xml
+++ b/doc/classes/Resource.xml
@@ -20,6 +20,19 @@
Override this method to return a custom [RID] when [method get_rid] is called.
</description>
</method>
+ <method name="_reset_state" qualifiers="virtual">
+ <return type="void" />
+ <description>
+ For resources that use a variable number of properties, either via [method Object._validate_property] or [method Object._get_property_list], this method should be implemented to correctly clear the resource's state.
+ </description>
+ </method>
+ <method name="_set_path_cache" qualifiers="virtual const">
+ <return type="void" />
+ <param index="0" name="path" type="String" />
+ <description>
+ Sets the resource's path to [param path] without involving the resource cache.
+ </description>
+ </method>
<method name="_setup_local_to_scene" qualifiers="virtual">
<return type="void" />
<description>
@@ -68,6 +81,14 @@
Generates a unique identifier for a resource to be contained inside a [PackedScene], based on the current date, time, and a random value. The returned string is only composed of letters ([code]a[/code] to [code]y[/code]) and numbers ([code]0[/code] to [code]8[/code]). See also [member resource_scene_unique_id].
</description>
</method>
+ <method name="get_id_for_path" qualifiers="const">
+ <return type="String" />
+ <param index="0" name="path" type="String" />
+ <description>
+ Returns the unique identifier for the resource with the given [param path] from the resource cache. If the resource is not loaded and cached, an empty string is returned.
+ [b]Note:[/b] This method is only implemented when running in an editor context. At runtime, it returns an empty string.
+ </description>
+ </method>
<method name="get_local_scene" qualifiers="const">
<return type="Node" />
<description>
@@ -80,6 +101,34 @@
Returns the [RID] of this resource (or an empty RID). Many resources (such as [Texture2D], [Mesh], and so on) are high-level abstractions of resources stored in a specialized server ([DisplayServer], [RenderingServer], etc.), so this function will return the original [RID].
</description>
</method>
+ <method name="is_built_in" qualifiers="const">
+ <return type="bool" />
+ <description>
+ Returns [code]true[/code] if the resource is built-in (from the engine) or [code]false[/code] if it is user-defined.
+ </description>
+ </method>
+ <method name="reset_state">
+ <return type="void" />
+ <description>
+ For resources that use a variable number of properties, either via [method Object._validate_property] or [method Object._get_property_list], override [method _reset_state] to correctly clear the resource's state.
+ </description>
+ </method>
+ <method name="set_id_for_path">
+ <return type="void" />
+ <param index="0" name="path" type="String" />
+ <param index="1" name="id" type="String" />
+ <description>
+ Sets the unique identifier to [param id] for the resource with the given [param path] in the resource cache. If the unique identifier is empty, the cache entry using [param path] is removed if it exists.
+ [b]Note:[/b] This method is only implemented when running in an editor context.
+ </description>
+ </method>
+ <method name="set_path_cache">
+ <return type="void" />
+ <param index="0" name="path" type="String" />
+ <description>
+ Sets the resource's path to [param path] without involving the resource cache.
+ </description>
+ </method>
<method name="setup_local_to_scene" deprecated="This method should only be called internally.">
<return type="void" />
<description>
diff --git a/doc/classes/ResourceSaver.xml b/doc/classes/ResourceSaver.xml
index 42c9bd7a3c..05c749bc24 100644
--- a/doc/classes/ResourceSaver.xml
+++ b/doc/classes/ResourceSaver.xml
@@ -26,6 +26,14 @@
Returns the list of extensions available for saving a resource of a given type.
</description>
</method>
+ <method name="get_resource_id_for_path">
+ <return type="int" />
+ <param index="0" name="path" type="String" />
+ <param index="1" name="generate" type="bool" default="false" />
+ <description>
+ Returns the resource ID for the given path. If [param generate] is [code]true[/code], a new resource ID will be generated if one for the path is not found. If [param generate] is [code]false[/code] and the path is not found, [constant ResourceUID.INVALID_ID] is returned.
+ </description>
+ </method>
<method name="remove_resource_format_saver">
<return type="void" />
<param index="0" name="format_saver" type="ResourceFormatSaver" />
diff --git a/doc/classes/ScrollContainer.xml b/doc/classes/ScrollContainer.xml
index 2181194fd4..405bba3564 100644
--- a/doc/classes/ScrollContainer.xml
+++ b/doc/classes/ScrollContainer.xml
@@ -102,6 +102,9 @@
<constant name="SCROLL_MODE_SHOW_NEVER" value="3" enum="ScrollMode">
Scrolling enabled, scrollbar will be hidden.
</constant>
+ <constant name="SCROLL_MODE_RESERVE" value="4" enum="ScrollMode">
+ Combines [constant SCROLL_MODE_AUTO] and [constant SCROLL_MODE_SHOW_ALWAYS]. The scrollbar is only visible if necessary, but the content size is adjusted as if it was always visible. It's useful for ensuring that content size stays the same regardless if the scrollbar is visible.
+ </constant>
</constants>
<theme_items>
<theme_item name="panel" data_type="style" type="StyleBox">
diff --git a/doc/classes/Signal.xml b/doc/classes/Signal.xml
index 7d6ff1e9b0..65168d6980 100644
--- a/doc/classes/Signal.xml
+++ b/doc/classes/Signal.xml
@@ -109,6 +109,12 @@
Returns the ID of the object emitting this signal (see [method Object.get_instance_id]).
</description>
</method>
+ <method name="has_connections" qualifiers="const">
+ <return type="bool" />
+ <description>
+ Returns [code]true[/code] if any [Callable] is connected to this signal.
+ </description>
+ </method>
<method name="is_connected" qualifiers="const">
<return type="bool" />
<param index="0" name="callable" type="Callable" />
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index 9fada9db35..42558bf992 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -1299,6 +1299,9 @@
<member name="editable" type="bool" setter="set_editable" getter="is_editable" default="true" keywords="readonly, disabled, enabled">
If [code]false[/code], existing text cannot be modified and new text cannot be added.
</member>
+ <member name="empty_selection_clipboard_enabled" type="bool" setter="set_empty_selection_clipboard_enabled" getter="is_empty_selection_clipboard_enabled" default="true">
+ If [code]true[/code], copying or cutting without a selection is performed on all lines with a caret. Otherwise, copy and cut require a selection.
+ </member>
<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="2" />
<member name="highlight_all_occurrences" type="bool" setter="set_highlight_all_occurrences" getter="is_highlight_all_occurrences_enabled" default="false">
If [code]true[/code], all occurrences of the selected text will be highlighted.
diff --git a/doc/tools/make_rst.py b/doc/tools/make_rst.py
index 101660881b..766aa95c4f 100755
--- a/doc/tools/make_rst.py
+++ b/doc/tools/make_rst.py
@@ -150,7 +150,7 @@ PACKED_ARRAY_TYPES: List[str] = [
"PackedByteArray",
"PackedColorArray",
"PackedFloat32Array",
- "Packedfloat64Array",
+ "PackedFloat64Array",
"PackedInt32Array",
"PackedInt64Array",
"PackedStringArray",
diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp
index 5a0f394db0..b73debf04a 100644
--- a/drivers/gles3/shader_gles3.cpp
+++ b/drivers/gles3/shader_gles3.cpp
@@ -189,6 +189,14 @@ void ShaderGLES3::_build_variant_code(StringBuilder &builder, uint32_t p_variant
}
builder.append("\n"); //make sure defines begin at newline
+ // Optional support for external textures.
+ if (GLES3::Config::get_singleton()->external_texture_supported) {
+ builder.append("#extension GL_OES_EGL_image_external : enable\n");
+ builder.append("#extension GL_OES_EGL_image_external_essl3 : enable\n");
+ } else {
+ builder.append("#define samplerExternalOES sampler2D\n");
+ }
+
// Insert multiview extension loading, because it needs to appear before
// any non-preprocessor code (like the "precision highp..." lines below).
builder.append("#ifdef USE_MULTIVIEW\n");
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index e358230747..76881c8032 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -262,6 +262,8 @@ void main() {
color_interp = color;
+ vertex = (canvas_transform * vec4(vertex, 0.0, 1.0)).xy;
+
if (use_pixel_snap) {
vertex = floor(vertex + 0.5);
// precision issue on some hardware creates artifacts within texture
@@ -269,8 +271,6 @@ void main() {
uv += 1e-5;
}
- vertex = (canvas_transform * vec4(vertex, 0.0, 1.0)).xy;
-
vertex_interp = vertex;
uv_interp = uv;
diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp
index d6472c44c1..4947d5d4ce 100644
--- a/drivers/gles3/storage/config.cpp
+++ b/drivers/gles3/storage/config.cpp
@@ -138,6 +138,7 @@ Config::Config() {
// These are GLES only
rt_msaa_supported = extensions.has("GL_EXT_multisampled_render_to_texture");
rt_msaa_multiview_supported = extensions.has("GL_OVR_multiview_multisampled_render_to_texture");
+ external_texture_supported = extensions.has("GL_OES_EGL_image_external_essl3");
if (multiview_supported) {
eglFramebufferTextureMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC)eglGetProcAddress("glFramebufferTextureMultiviewOVR");
@@ -166,6 +167,13 @@ Config::Config() {
rt_msaa_multiview_supported = false;
}
}
+
+ if (external_texture_supported) {
+ eglEGLImageTargetTexture2DOES = (PFNEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
+ if (eglEGLImageTargetTexture2DOES == nullptr) {
+ external_texture_supported = false;
+ }
+ }
#endif
force_vertex_shading = false; //GLOBAL_GET("rendering/quality/shading/force_vertex_shading");
diff --git a/drivers/gles3/storage/config.h b/drivers/gles3/storage/config.h
index ff72fc5b58..1de00094f0 100644
--- a/drivers/gles3/storage/config.h
+++ b/drivers/gles3/storage/config.h
@@ -45,6 +45,7 @@ typedef void (*PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC)(GLenum, GLenum, GLuint,
typedef void (*PFNGLTEXSTORAGE3DMULTISAMPLEPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei, GLboolean);
typedef void (*PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)(GLenum, GLenum, GLenum, GLuint, GLint, GLsizei);
typedef void (*PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC)(GLenum, GLenum, GLuint, GLint, GLsizei, GLint, GLsizei);
+typedef void (*PFNEGLIMAGETARGETTEXTURE2DOESPROC)(GLenum, void *);
#endif
namespace GLES3 {
@@ -91,6 +92,7 @@ public:
bool rt_msaa_supported = false;
bool rt_msaa_multiview_supported = false;
bool multiview_supported = false;
+ bool external_texture_supported = false;
// Adreno 3XX compatibility
bool disable_particles_workaround = false; // set to 'true' to disable 'GPUParticles'
@@ -104,6 +106,7 @@ public:
PFNGLTEXSTORAGE3DMULTISAMPLEPROC eglTexStorage3DMultisample = nullptr;
PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC eglFramebufferTexture2DMultisampleEXT = nullptr;
PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC eglFramebufferTextureMultisampleMultiviewOVR = nullptr;
+ PFNEGLIMAGETARGETTEXTURE2DOESPROC eglEGLImageTargetTexture2DOES = nullptr;
#endif
static Config *get_singleton() { return singleton; };
diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp
index 7d5af48384..c29c741c2a 100644
--- a/drivers/gles3/storage/material_storage.cpp
+++ b/drivers/gles3/storage/material_storage.cpp
@@ -675,6 +675,7 @@ static const GLenum target_from_type[ShaderLanguage::TYPE_MAX] = {
GL_TEXTURE_3D, // TYPE_USAMPLER3D,
GL_TEXTURE_CUBE_MAP, // TYPE_SAMPLERCUBE,
GL_TEXTURE_CUBE_MAP, // TYPE_SAMPLERCUBEARRAY,
+ _GL_TEXTURE_EXTERNAL_OES, // TYPE_SAMPLEREXT
GL_TEXTURE_2D, // TYPE_STRUCT
};
@@ -946,6 +947,9 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet
case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: {
ERR_PRINT_ONCE("Type: SamplerCubeArray not supported in GL Compatibility rendering backend, please use another type.");
} break;
+ case ShaderLanguage::TYPE_SAMPLEREXT: {
+ gl_texture = texture_storage->texture_gl_get_default(DEFAULT_GL_TEXTURE_EXT);
+ } break;
case ShaderLanguage::TYPE_ISAMPLER3D:
case ShaderLanguage::TYPE_USAMPLER3D:
@@ -1949,6 +1953,7 @@ void MaterialStorage::global_shader_parameters_load_settings(bool p_load_texture
"sampler2DArray",
"sampler3D",
"samplerCube",
+ "samplerExternalOES"
};
RS::GlobalShaderParameterType gvtype = RS::GLOBAL_VAR_TYPE_MAX;
@@ -2661,7 +2666,11 @@ static void bind_uniforms_generic(const Vector<RID> &p_textures, const Vector<Sh
const ShaderCompiler::GeneratedCode::Texture &texture_uniform = texture_uniforms[texture_uniform_index];
if (texture) {
glActiveTexture(GL_TEXTURE0 + texture_offset + ti);
- glBindTexture(target_from_type[texture_uniform.type], texture->tex_id);
+ GLenum target = target_from_type[texture_uniform.type];
+ if (target == _GL_TEXTURE_EXTERNAL_OES && !GLES3::Config::get_singleton()->external_texture_supported) {
+ target = GL_TEXTURE_2D;
+ }
+ glBindTexture(target, texture->tex_id);
if (texture->render_target) {
texture->render_target->used_in_frame = true;
}
diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp
index bd824a076e..27ba89aa5f 100644
--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -153,6 +153,11 @@ TextureStorage::TextureStorage() {
}
{
+ default_gl_textures[DEFAULT_GL_TEXTURE_EXT] = texture_allocate();
+ texture_external_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_EXT], 1, 1, 0);
+ }
+
+ {
unsigned char pixel_data[4 * 4 * 4];
for (int i = 0; i < 16; i++) {
pixel_data[i * 4 + 0] = 0;
@@ -769,6 +774,48 @@ void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_im
texture_set_data(p_texture, p_image);
}
+void TextureStorage::texture_external_initialize(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) {
+ Texture texture;
+ texture.active = true;
+ texture.alloc_width = texture.width = p_width;
+ texture.alloc_height = texture.height = p_height;
+ texture.real_format = texture.format = Image::FORMAT_RGB8;
+ texture.type = Texture::TYPE_2D;
+
+ if (GLES3::Config::get_singleton()->external_texture_supported) {
+ texture.target = _GL_TEXTURE_EXTERNAL_OES;
+ } else {
+ texture.target = GL_TEXTURE_2D;
+ }
+
+ glGenTextures(1, &texture.tex_id);
+ glBindTexture(texture.target, texture.tex_id);
+
+#ifdef ANDROID_ENABLED
+ if (texture.target == _GL_TEXTURE_EXTERNAL_OES) {
+ if (p_external_buffer) {
+ GLES3::Config::get_singleton()->eglEGLImageTargetTexture2DOES(_GL_TEXTURE_EXTERNAL_OES, reinterpret_cast<void *>(p_external_buffer));
+ }
+ texture.total_data_size = 0;
+ } else
+#endif
+ {
+ // If external textures aren't supported, allocate an empty 1x1 texture.
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
+ texture.total_data_size = 3;
+ }
+
+ glTexParameteri(texture.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(texture.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(texture.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(texture.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture External");
+ texture_owner.initialize_rid(p_texture, texture);
+
+ glBindTexture(texture.target, 0);
+}
+
void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) {
ERR_FAIL_COND(p_layers.is_empty());
@@ -930,6 +977,22 @@ void TextureStorage::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &
GLES3::Utilities::get_singleton()->texture_resize_data(tex->tex_id, tex->total_data_size);
}
+void TextureStorage::texture_external_update(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) {
+ Texture *tex = texture_owner.get_or_null(p_texture);
+ ERR_FAIL_NULL(tex);
+
+ tex->alloc_width = tex->width = p_width;
+ tex->alloc_height = tex->height = p_height;
+
+#ifdef ANDROID_ENABLED
+ if (tex->target == _GL_TEXTURE_EXTERNAL_OES && p_external_buffer) {
+ glBindTexture(_GL_TEXTURE_EXTERNAL_OES, tex->tex_id);
+ GLES3::Config::get_singleton()->eglEGLImageTargetTexture2DOES(_GL_TEXTURE_EXTERNAL_OES, reinterpret_cast<void *>(p_external_buffer));
+ glBindTexture(_GL_TEXTURE_EXTERNAL_OES, 0);
+ }
+#endif
+}
+
void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) {
Texture *tex = texture_owner.get_or_null(p_texture);
ERR_FAIL_NULL(tex);
diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h
index b1d4630978..2bf8546c0f 100644
--- a/drivers/gles3/storage/texture_storage.h
+++ b/drivers/gles3/storage/texture_storage.h
@@ -126,6 +126,7 @@ enum DefaultGLTexture {
DEFAULT_GL_TEXTURE_3D_BLACK,
DEFAULT_GL_TEXTURE_2D_ARRAY_WHITE,
DEFAULT_GL_TEXTURE_2D_UINT,
+ DEFAULT_GL_TEXTURE_EXT,
DEFAULT_GL_TEXTURE_MAX
};
@@ -512,12 +513,14 @@ public:
virtual void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) override;
virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override;
virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override;
+ virtual void texture_external_initialize(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) override;
virtual void texture_proxy_initialize(RID p_texture, RID p_base) override; //all slices, then all the mipmaps, must be coherent
virtual RID texture_create_from_native_handle(RS::TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers = 1, RS::TextureLayeredType p_layered_type = RS::TEXTURE_LAYERED_2D_ARRAY) override;
virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override;
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override;
+ virtual void texture_external_update(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) override;
virtual void texture_proxy_update(RID p_proxy, RID p_base) override;
//these two APIs can be used together or in combination with the others.
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index d97293329a..40b58d2c62 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -1090,6 +1090,9 @@ void CodeTextEditor::update_editor_settings() {
text_editor->set_draw_spaces(EDITOR_GET("text_editor/appearance/whitespace/draw_spaces"));
text_editor->add_theme_constant_override("line_spacing", EDITOR_GET("text_editor/appearance/whitespace/line_spacing"));
+ // Behavior: General
+ text_editor->set_empty_selection_clipboard_enabled(EDITOR_GET("text_editor/behavior/general/empty_selection_clipboard"));
+
// Behavior: Navigation
text_editor->set_scroll_past_end_of_file_enabled(EDITOR_GET("text_editor/behavior/navigation/scroll_past_end_of_file"));
text_editor->set_smooth_scroll_enabled(EDITOR_GET("text_editor/behavior/navigation/smooth_scrolling"));
diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp
index 0eabe53360..1613d1d62f 100644
--- a/editor/editor_autoload_settings.cpp
+++ b/editor/editor_autoload_settings.cpp
@@ -88,14 +88,9 @@ void EditorAutoloadSettings::_notification(int p_what) {
}
bool EditorAutoloadSettings::_autoload_name_is_valid(const String &p_name, String *r_error) {
- if (!p_name.is_valid_ascii_identifier()) {
+ if (!p_name.is_valid_unicode_identifier()) {
if (r_error) {
- *r_error = TTR("Invalid name.") + " ";
- if (p_name.size() > 0 && p_name.left(1).is_numeric()) {
- *r_error += TTR("Cannot begin with a digit.");
- } else {
- *r_error += TTR("Valid characters:") + " a-z, A-Z, 0-9 or _";
- }
+ *r_error = TTR("Invalid name.") + " " + TTR("Must be a valid Unicode identifier.");
}
return false;
diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp
index 47ff21bc82..47f16f219f 100644
--- a/editor/editor_help_search.cpp
+++ b/editor/editor_help_search.cpp
@@ -530,7 +530,7 @@ bool EditorHelpSearch::Runner::_phase_fill_member_items_init() {
return true;
}
-TreeItem *EditorHelpSearch::Runner::_create_category_item(TreeItem *p_parent, const String &p_class, const StringName &p_icon, const String &p_metatype, const String &p_text) {
+TreeItem *EditorHelpSearch::Runner::_create_category_item(TreeItem *p_parent, const String &p_class, const StringName &p_icon, const String &p_text, const String &p_metatype) {
const String item_meta = "class_" + p_metatype + ":" + p_class;
TreeItem *item = nullptr;
@@ -620,7 +620,7 @@ bool EditorHelpSearch::Runner::_phase_fill_member_items() {
if ((search_flags & SEARCH_PROPERTIES) && !class_doc->properties.is_empty()) {
TreeItem *parent_item = item;
if (search_all) {
- parent_item = _create_category_item(parent_item, class_doc->name, SNAME("MemberProperty"), TTRC("Prtoperties"), "propertiess");
+ parent_item = _create_category_item(parent_item, class_doc->name, SNAME("MemberProperty"), TTRC("Properties"), "properties");
}
for (const DocData::PropertyDoc &property_doc : class_doc->properties) {
_create_property_item(parent_item, class_doc, &property_doc);
diff --git a/editor/editor_help_search.h b/editor/editor_help_search.h
index b8b3c26b41..f4d0c6c89e 100644
--- a/editor/editor_help_search.h
+++ b/editor/editor_help_search.h
@@ -198,7 +198,7 @@ class EditorHelpSearch::Runner : public RefCounted {
TreeItem *_create_class_hierarchy(const ClassMatch &p_match);
TreeItem *_create_class_hierarchy(const DocData::ClassDoc *p_class_doc, const String &p_matching_keyword, bool p_gray);
TreeItem *_create_class_item(TreeItem *p_parent, const DocData::ClassDoc *p_doc, bool p_gray, const String &p_matching_keyword);
- TreeItem *_create_category_item(TreeItem *p_parent, const String &p_class, const StringName &p_icon, const String &p_metatype, const String &p_type);
+ TreeItem *_create_category_item(TreeItem *p_parent, const String &p_class, const StringName &p_icon, const String &p_text, const String &p_metatype);
TreeItem *_create_method_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const MemberMatch<DocData::MethodDoc> &p_match);
TreeItem *_create_constructor_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const MemberMatch<DocData::MethodDoc> &p_match);
TreeItem *_create_operator_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const MemberMatch<DocData::MethodDoc> &p_match);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 44292b4185..184176391a 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -4952,8 +4952,10 @@ String EditorNode::_get_system_info() const {
godot_version += " " + hash;
}
+ String display_session_type;
#ifdef LINUXBSD_ENABLED
- const String display_server = OS::get_singleton()->get_environment("XDG_SESSION_TYPE").capitalize().replace(" ", ""); // `replace` is necessary, because `capitalize` introduces a whitespace between "x" and "11".
+ // `replace` is necessary, because `capitalize` introduces a whitespace between "x" and "11".
+ display_session_type = OS::get_singleton()->get_environment("XDG_SESSION_TYPE").capitalize().replace(" ", "");
#endif // LINUXBSD_ENABLED
String driver_name = OS::get_singleton()->get_current_rendering_driver_name().to_lower();
String rendering_method = OS::get_singleton()->get_current_rendering_method().to_lower();
@@ -5014,16 +5016,33 @@ String EditorNode::_get_system_info() const {
// Join info.
Vector<String> info;
info.push_back(godot_version);
+ String distribution_display_session_type = distribution_name;
if (!distribution_version.is_empty()) {
- info.push_back(distribution_name + " " + distribution_version);
- } else {
- info.push_back(distribution_name);
+ distribution_display_session_type += " " + distribution_version;
}
-#ifdef LINUXBSD_ENABLED
- if (!display_server.is_empty()) {
- info.push_back(display_server);
+ if (!display_session_type.is_empty()) {
+ distribution_display_session_type += " on " + display_session_type;
}
+ info.push_back(distribution_display_session_type);
+
+ String display_driver_window_mode;
+#ifdef LINUXBSD_ENABLED
+ // `replace` is necessary, because `capitalize` introduces a whitespace between "x" and "11".
+ display_driver_window_mode = DisplayServer::get_singleton()->get_name().capitalize().replace(" ", "") + " display driver";
#endif // LINUXBSD_ENABLED
+ if (!display_driver_window_mode.is_empty()) {
+ display_driver_window_mode += ", ";
+ }
+ display_driver_window_mode += get_viewport()->is_embedding_subwindows() ? "Single-window" : "Multi-window";
+
+ if (DisplayServer::get_singleton()->get_screen_count() == 1) {
+ display_driver_window_mode += ", " + itos(DisplayServer::get_singleton()->get_screen_count()) + " monitor";
+ } else {
+ display_driver_window_mode += ", " + itos(DisplayServer::get_singleton()->get_screen_count()) + " monitors";
+ }
+
+ info.push_back(display_driver_window_mode);
+
info.push_back(vformat("%s (%s)", driver_name, rendering_method));
String graphics;
@@ -5042,7 +5061,7 @@ String EditorNode::_get_system_info() const {
}
info.push_back(graphics);
- info.push_back(vformat("%s (%d Threads)", processor_name, processor_count));
+ info.push_back(vformat("%s (%d threads)", processor_name, processor_count));
return String(" - ").join(info);
}
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 963c45b573..c972a6ab27 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -668,6 +668,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "text_editor/appearance/whitespace/line_spacing", 4, "0,50,1")
// Behavior
+ // Behavior: General
+ _initial_set("text_editor/behavior/general/empty_selection_clipboard", true);
+
// Behavior: Navigation
_initial_set("text_editor/behavior/navigation/move_caret_on_right_click", true, true);
_initial_set("text_editor/behavior/navigation/scroll_past_end_of_file", false, true);
diff --git a/editor/import/3d/resource_importer_obj.cpp b/editor/import/3d/resource_importer_obj.cpp
index f3770adcb7..a579224ecd 100644
--- a/editor/import/3d/resource_importer_obj.cpp
+++ b/editor/import/3d/resource_importer_obj.cpp
@@ -246,6 +246,8 @@ static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes,
bool smoothing = true;
const uint32_t no_smoothing_smooth_group = (uint32_t)-1;
+ bool uses_uvs = false;
+
while (true) {
String l = f->get_line().strip_edges();
while (l.length() && l[l.length() - 1] == '\\') {
@@ -320,6 +322,17 @@ static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes,
idx = 1 ^ idx;
}
+ // Check UVs before faces as we may need to generate dummy tangents if there are no UVs.
+ if (face[idx].size() >= 2 && !face[idx][1].is_empty()) {
+ int uv = face[idx][1].to_int() - 1;
+ if (uv < 0) {
+ uv += uvs.size() + 1;
+ }
+ ERR_FAIL_INDEX_V(uv, uvs.size(), ERR_FILE_CORRUPT);
+ surf_tool->set_uv(uvs[uv]);
+ uses_uvs = true;
+ }
+
if (face[idx].size() == 3) {
int norm = face[idx][2].to_int() - 1;
if (norm < 0) {
@@ -327,28 +340,19 @@ static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes,
}
ERR_FAIL_INDEX_V(norm, normals.size(), ERR_FILE_CORRUPT);
surf_tool->set_normal(normals[norm]);
- if (generate_tangents && uvs.is_empty()) {
+ if (generate_tangents && !uses_uvs) {
// We can't generate tangents without UVs, so create dummy tangents.
Vector3 tan = Vector3(normals[norm].z, -normals[norm].x, normals[norm].y).cross(normals[norm].normalized()).normalized();
surf_tool->set_tangent(Plane(tan.x, tan.y, tan.z, 1.0));
}
} else {
// No normals, use a dummy tangent since normals and tangents will be generated.
- if (generate_tangents && uvs.is_empty()) {
+ if (generate_tangents && !uses_uvs) {
// We can't generate tangents without UVs, so create dummy tangents.
surf_tool->set_tangent(Plane(1.0, 0.0, 0.0, 1.0));
}
}
- if (face[idx].size() >= 2 && !face[idx][1].is_empty()) {
- int uv = face[idx][1].to_int() - 1;
- if (uv < 0) {
- uv += uvs.size() + 1;
- }
- ERR_FAIL_INDEX_V(uv, uvs.size(), ERR_FILE_CORRUPT);
- surf_tool->set_uv(uvs[uv]);
- }
-
int vtx = face[idx][0].to_int() - 1;
if (vtx < 0) {
vtx += vertices.size() + 1;
@@ -407,7 +411,7 @@ static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes,
surf_tool->generate_normals();
}
- if (generate_tangents && uvs.size()) {
+ if (generate_tangents && uses_uvs) {
surf_tool->generate_tangents();
}
@@ -426,10 +430,11 @@ static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes,
Array array = surf_tool->commit_to_arrays();
- if (mesh_flags & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES && generate_tangents) {
- // Compression is enabled, so let's validate that the normals and tangents are correct.
+ if (mesh_flags & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES && generate_tangents && uses_uvs) {
+ // Compression is enabled, so let's validate that the normals and generated tangents are correct.
Vector<Vector3> norms = array[Mesh::ARRAY_NORMAL];
Vector<float> tangents = array[Mesh::ARRAY_TANGENT];
+ ERR_FAIL_COND_V(tangents.is_empty(), ERR_FILE_CORRUPT);
for (int vert = 0; vert < norms.size(); vert++) {
Vector3 tan = Vector3(tangents[vert * 4 + 0], tangents[vert * 4 + 1], tangents[vert * 4 + 2]);
if (abs(tan.dot(norms[vert])) > 0.0001) {
@@ -454,6 +459,7 @@ static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes,
surf_tool->clear();
surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES);
+ uses_uvs = false;
}
if (l.begins_with("o ") || f->eof_reached()) {
diff --git a/editor/renames_map_3_to_4.cpp b/editor/renames_map_3_to_4.cpp
index 8eab3fbea9..ae7c86a5e5 100644
--- a/editor/renames_map_3_to_4.cpp
+++ b/editor/renames_map_3_to_4.cpp
@@ -1518,7 +1518,6 @@ const char *RenamesMap3To4::class_renames[][2] = {
{ "EditorSceneImporterGLTF", "EditorSceneFormatImporterGLTF" },
{ "EditorSpatialGizmo", "EditorNode3DGizmo" },
{ "EditorSpatialGizmoPlugin", "EditorNode3DGizmoPlugin" },
- { "ExternalTexture", "ImageTexture" },
{ "GIProbe", "VoxelGI" },
{ "GIProbeData", "VoxelGIData" },
{ "Generic6DOFJoint", "Generic6DOFJoint3D" },
diff --git a/main/main.cpp b/main/main.cpp
index fa50a3039f..439cd385c0 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -83,6 +83,7 @@
#ifndef _3D_DISABLED
#include "servers/physics_server_3d.h"
+#include "servers/physics_server_3d_dummy.h"
#include "servers/xr_server.h"
#endif // _3D_DISABLED
@@ -320,7 +321,15 @@ void initialize_physics() {
// Physics server not found, Use the default physics
physics_server_3d = PhysicsServer3DManager::get_singleton()->new_default_server();
}
- ERR_FAIL_NULL(physics_server_3d);
+
+ // Fall back to dummy if no default server has been registered.
+ if (!physics_server_3d) {
+ WARN_PRINT(vformat("Falling back to dummy PhysicsServer3D; 3D physics functionality will be disabled. If this is intended, set the %s project setting to Dummy.", PhysicsServer3DManager::setting_property_name));
+ physics_server_3d = memnew(PhysicsServer3DDummy);
+ }
+
+ // Should be impossible, but make sure it's not null.
+ ERR_FAIL_NULL_MSG(physics_server_3d, "Failed to initialize PhysicsServer3D.");
physics_server_3d->init();
#endif // _3D_DISABLED
diff --git a/modules/godot_physics_3d/SCsub b/modules/godot_physics_3d/SCsub
new file mode 100644
index 0000000000..41a59cd24e
--- /dev/null
+++ b/modules/godot_physics_3d/SCsub
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+
+Import('env')
+
+env.add_source_files(env.modules_sources, "*.cpp")
+
+SConscript("joints/SCsub")
diff --git a/modules/godot_physics_3d/config.py b/modules/godot_physics_3d/config.py
new file mode 100644
index 0000000000..a42f27fbe1
--- /dev/null
+++ b/modules/godot_physics_3d/config.py
@@ -0,0 +1,6 @@
+def can_build(env, platform):
+ return not env["disable_3d"]
+
+
+def configure(env):
+ pass
diff --git a/servers/physics_3d/gjk_epa.cpp b/modules/godot_physics_3d/gjk_epa.cpp
index e5678914fe..e5678914fe 100644
--- a/servers/physics_3d/gjk_epa.cpp
+++ b/modules/godot_physics_3d/gjk_epa.cpp
diff --git a/servers/physics_3d/gjk_epa.h b/modules/godot_physics_3d/gjk_epa.h
index 48fda9969f..48fda9969f 100644
--- a/servers/physics_3d/gjk_epa.h
+++ b/modules/godot_physics_3d/gjk_epa.h
diff --git a/servers/physics_3d/godot_area_3d.cpp b/modules/godot_physics_3d/godot_area_3d.cpp
index d0b287b058..d0b287b058 100644
--- a/servers/physics_3d/godot_area_3d.cpp
+++ b/modules/godot_physics_3d/godot_area_3d.cpp
diff --git a/servers/physics_3d/godot_area_3d.h b/modules/godot_physics_3d/godot_area_3d.h
index 2c1a782630..2c1a782630 100644
--- a/servers/physics_3d/godot_area_3d.h
+++ b/modules/godot_physics_3d/godot_area_3d.h
diff --git a/servers/physics_3d/godot_area_pair_3d.cpp b/modules/godot_physics_3d/godot_area_pair_3d.cpp
index aaa96f5a28..aaa96f5a28 100644
--- a/servers/physics_3d/godot_area_pair_3d.cpp
+++ b/modules/godot_physics_3d/godot_area_pair_3d.cpp
diff --git a/servers/physics_3d/godot_area_pair_3d.h b/modules/godot_physics_3d/godot_area_pair_3d.h
index a2c5df0f7a..a2c5df0f7a 100644
--- a/servers/physics_3d/godot_area_pair_3d.h
+++ b/modules/godot_physics_3d/godot_area_pair_3d.h
diff --git a/servers/physics_3d/godot_body_3d.cpp b/modules/godot_physics_3d/godot_body_3d.cpp
index 669c4b985b..669c4b985b 100644
--- a/servers/physics_3d/godot_body_3d.cpp
+++ b/modules/godot_physics_3d/godot_body_3d.cpp
diff --git a/servers/physics_3d/godot_body_3d.h b/modules/godot_physics_3d/godot_body_3d.h
index 81b668122a..81b668122a 100644
--- a/servers/physics_3d/godot_body_3d.h
+++ b/modules/godot_physics_3d/godot_body_3d.h
diff --git a/servers/physics_3d/godot_body_direct_state_3d.cpp b/modules/godot_physics_3d/godot_body_direct_state_3d.cpp
index 0af746c68d..0af746c68d 100644
--- a/servers/physics_3d/godot_body_direct_state_3d.cpp
+++ b/modules/godot_physics_3d/godot_body_direct_state_3d.cpp
diff --git a/servers/physics_3d/godot_body_direct_state_3d.h b/modules/godot_physics_3d/godot_body_direct_state_3d.h
index 8066050c9f..8066050c9f 100644
--- a/servers/physics_3d/godot_body_direct_state_3d.h
+++ b/modules/godot_physics_3d/godot_body_direct_state_3d.h
diff --git a/servers/physics_3d/godot_body_pair_3d.cpp b/modules/godot_physics_3d/godot_body_pair_3d.cpp
index 84fae73616..84fae73616 100644
--- a/servers/physics_3d/godot_body_pair_3d.cpp
+++ b/modules/godot_physics_3d/godot_body_pair_3d.cpp
diff --git a/servers/physics_3d/godot_body_pair_3d.h b/modules/godot_physics_3d/godot_body_pair_3d.h
index a8f5180dd5..a8f5180dd5 100644
--- a/servers/physics_3d/godot_body_pair_3d.h
+++ b/modules/godot_physics_3d/godot_body_pair_3d.h
diff --git a/servers/physics_3d/godot_broad_phase_3d.cpp b/modules/godot_physics_3d/godot_broad_phase_3d.cpp
index ebd11fb51f..ebd11fb51f 100644
--- a/servers/physics_3d/godot_broad_phase_3d.cpp
+++ b/modules/godot_physics_3d/godot_broad_phase_3d.cpp
diff --git a/servers/physics_3d/godot_broad_phase_3d.h b/modules/godot_physics_3d/godot_broad_phase_3d.h
index f70321be64..f70321be64 100644
--- a/servers/physics_3d/godot_broad_phase_3d.h
+++ b/modules/godot_physics_3d/godot_broad_phase_3d.h
diff --git a/servers/physics_3d/godot_broad_phase_3d_bvh.cpp b/modules/godot_physics_3d/godot_broad_phase_3d_bvh.cpp
index 0faa56b52e..0faa56b52e 100644
--- a/servers/physics_3d/godot_broad_phase_3d_bvh.cpp
+++ b/modules/godot_physics_3d/godot_broad_phase_3d_bvh.cpp
diff --git a/servers/physics_3d/godot_broad_phase_3d_bvh.h b/modules/godot_physics_3d/godot_broad_phase_3d_bvh.h
index 63968dea64..63968dea64 100644
--- a/servers/physics_3d/godot_broad_phase_3d_bvh.h
+++ b/modules/godot_physics_3d/godot_broad_phase_3d_bvh.h
diff --git a/servers/physics_3d/godot_collision_object_3d.cpp b/modules/godot_physics_3d/godot_collision_object_3d.cpp
index 283614a43d..283614a43d 100644
--- a/servers/physics_3d/godot_collision_object_3d.cpp
+++ b/modules/godot_physics_3d/godot_collision_object_3d.cpp
diff --git a/servers/physics_3d/godot_collision_object_3d.h b/modules/godot_physics_3d/godot_collision_object_3d.h
index bf28bcc45a..bf28bcc45a 100644
--- a/servers/physics_3d/godot_collision_object_3d.h
+++ b/modules/godot_physics_3d/godot_collision_object_3d.h
diff --git a/servers/physics_3d/godot_collision_solver_3d.cpp b/modules/godot_physics_3d/godot_collision_solver_3d.cpp
index db48111eea..db48111eea 100644
--- a/servers/physics_3d/godot_collision_solver_3d.cpp
+++ b/modules/godot_physics_3d/godot_collision_solver_3d.cpp
diff --git a/servers/physics_3d/godot_collision_solver_3d.h b/modules/godot_physics_3d/godot_collision_solver_3d.h
index 36ea79576e..36ea79576e 100644
--- a/servers/physics_3d/godot_collision_solver_3d.h
+++ b/modules/godot_physics_3d/godot_collision_solver_3d.h
diff --git a/servers/physics_3d/godot_collision_solver_3d_sat.cpp b/modules/godot_physics_3d/godot_collision_solver_3d_sat.cpp
index c53c8481f4..c53c8481f4 100644
--- a/servers/physics_3d/godot_collision_solver_3d_sat.cpp
+++ b/modules/godot_physics_3d/godot_collision_solver_3d_sat.cpp
diff --git a/servers/physics_3d/godot_collision_solver_3d_sat.h b/modules/godot_physics_3d/godot_collision_solver_3d_sat.h
index 49fcab3933..49fcab3933 100644
--- a/servers/physics_3d/godot_collision_solver_3d_sat.h
+++ b/modules/godot_physics_3d/godot_collision_solver_3d_sat.h
diff --git a/servers/physics_3d/godot_constraint_3d.h b/modules/godot_physics_3d/godot_constraint_3d.h
index a833aba93f..a833aba93f 100644
--- a/servers/physics_3d/godot_constraint_3d.h
+++ b/modules/godot_physics_3d/godot_constraint_3d.h
diff --git a/servers/physics_3d/godot_joint_3d.h b/modules/godot_physics_3d/godot_joint_3d.h
index 3207723cb4..3207723cb4 100644
--- a/servers/physics_3d/godot_joint_3d.h
+++ b/modules/godot_physics_3d/godot_joint_3d.h
diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/modules/godot_physics_3d/godot_physics_server_3d.cpp
index 8a7b4e0f07..6d0949acbe 100644
--- a/servers/physics_3d/godot_physics_server_3d.cpp
+++ b/modules/godot_physics_3d/godot_physics_server_3d.cpp
@@ -1629,8 +1629,6 @@ void GodotPhysicsServer3D::init() {
}
void GodotPhysicsServer3D::step(real_t p_step) {
-#ifndef _3D_DISABLED
-
if (!active) {
return;
}
@@ -1646,7 +1644,6 @@ void GodotPhysicsServer3D::step(real_t p_step) {
active_objects += E->get_active_objects();
collision_pairs += E->get_collision_pairs();
}
-#endif
}
void GodotPhysicsServer3D::sync() {
@@ -1654,8 +1651,6 @@ void GodotPhysicsServer3D::sync() {
}
void GodotPhysicsServer3D::flush_queries() {
-#ifndef _3D_DISABLED
-
if (!active) {
return;
}
@@ -1703,7 +1698,6 @@ void GodotPhysicsServer3D::flush_queries() {
values.push_front("physics_3d");
EngineDebugger::profiler_add_frame_data("servers", values);
}
-#endif
}
void GodotPhysicsServer3D::end_sync() {
diff --git a/servers/physics_3d/godot_physics_server_3d.h b/modules/godot_physics_3d/godot_physics_server_3d.h
index 040e673dcd..040e673dcd 100644
--- a/servers/physics_3d/godot_physics_server_3d.h
+++ b/modules/godot_physics_3d/godot_physics_server_3d.h
diff --git a/servers/physics_3d/godot_shape_3d.cpp b/modules/godot_physics_3d/godot_shape_3d.cpp
index 70b6bcf19e..70b6bcf19e 100644
--- a/servers/physics_3d/godot_shape_3d.cpp
+++ b/modules/godot_physics_3d/godot_shape_3d.cpp
diff --git a/servers/physics_3d/godot_shape_3d.h b/modules/godot_physics_3d/godot_shape_3d.h
index dbd58ead68..dbd58ead68 100644
--- a/servers/physics_3d/godot_shape_3d.h
+++ b/modules/godot_physics_3d/godot_shape_3d.h
diff --git a/servers/physics_3d/godot_soft_body_3d.cpp b/modules/godot_physics_3d/godot_soft_body_3d.cpp
index 7284076a47..7284076a47 100644
--- a/servers/physics_3d/godot_soft_body_3d.cpp
+++ b/modules/godot_physics_3d/godot_soft_body_3d.cpp
diff --git a/servers/physics_3d/godot_soft_body_3d.h b/modules/godot_physics_3d/godot_soft_body_3d.h
index e23f4bb9f5..e23f4bb9f5 100644
--- a/servers/physics_3d/godot_soft_body_3d.h
+++ b/modules/godot_physics_3d/godot_soft_body_3d.h
diff --git a/servers/physics_3d/godot_space_3d.cpp b/modules/godot_physics_3d/godot_space_3d.cpp
index 9a6ba776b4..9a6ba776b4 100644
--- a/servers/physics_3d/godot_space_3d.cpp
+++ b/modules/godot_physics_3d/godot_space_3d.cpp
diff --git a/servers/physics_3d/godot_space_3d.h b/modules/godot_physics_3d/godot_space_3d.h
index f476be5934..f476be5934 100644
--- a/servers/physics_3d/godot_space_3d.h
+++ b/modules/godot_physics_3d/godot_space_3d.h
diff --git a/servers/physics_3d/godot_step_3d.cpp b/modules/godot_physics_3d/godot_step_3d.cpp
index d09a3b4e6d..d09a3b4e6d 100644
--- a/servers/physics_3d/godot_step_3d.cpp
+++ b/modules/godot_physics_3d/godot_step_3d.cpp
diff --git a/servers/physics_3d/godot_step_3d.h b/modules/godot_physics_3d/godot_step_3d.h
index 1c9b0af422..1c9b0af422 100644
--- a/servers/physics_3d/godot_step_3d.h
+++ b/modules/godot_physics_3d/godot_step_3d.h
diff --git a/modules/godot_physics_3d/joints/SCsub b/modules/godot_physics_3d/joints/SCsub
new file mode 100644
index 0000000000..5d93da5ecf
--- /dev/null
+++ b/modules/godot_physics_3d/joints/SCsub
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+Import('env')
+
+env.add_source_files(env.modules_sources, "*.cpp")
diff --git a/servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp b/modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.cpp
index 4091422789..4091422789 100644
--- a/servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp
+++ b/modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.cpp
diff --git a/servers/physics_3d/joints/godot_cone_twist_joint_3d.h b/modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.h
index 8b749e4914..f3b683a8f3 100644
--- a/servers/physics_3d/joints/godot_cone_twist_joint_3d.h
+++ b/modules/godot_physics_3d/joints/godot_cone_twist_joint_3d.h
@@ -52,8 +52,8 @@ subject to the following restrictions:
Written by: Marcus Hennix
*/
-#include "servers/physics_3d/godot_joint_3d.h"
-#include "servers/physics_3d/joints/godot_jacobian_entry_3d.h"
+#include "../godot_joint_3d.h"
+#include "godot_jacobian_entry_3d.h"
// GodotConeTwistJoint3D can be used to simulate ragdoll joints (upper arm, leg etc).
class GodotConeTwistJoint3D : public GodotJoint3D {
diff --git a/servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp b/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.cpp
index 226f8a0f7f..226f8a0f7f 100644
--- a/servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp
+++ b/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.cpp
diff --git a/servers/physics_3d/joints/godot_generic_6dof_joint_3d.h b/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.h
index 69a5266438..9ee6dd2791 100644
--- a/servers/physics_3d/joints/godot_generic_6dof_joint_3d.h
+++ b/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.h
@@ -35,8 +35,8 @@
Adapted to Godot from the Bullet library.
*/
-#include "servers/physics_3d/godot_joint_3d.h"
-#include "servers/physics_3d/joints/godot_jacobian_entry_3d.h"
+#include "../godot_joint_3d.h"
+#include "godot_jacobian_entry_3d.h"
/*
Bullet Continuous Collision Detection and Physics Library
diff --git a/servers/physics_3d/joints/godot_hinge_joint_3d.cpp b/modules/godot_physics_3d/joints/godot_hinge_joint_3d.cpp
index 3d423f70e2..3d423f70e2 100644
--- a/servers/physics_3d/joints/godot_hinge_joint_3d.cpp
+++ b/modules/godot_physics_3d/joints/godot_hinge_joint_3d.cpp
diff --git a/servers/physics_3d/joints/godot_hinge_joint_3d.h b/modules/godot_physics_3d/joints/godot_hinge_joint_3d.h
index eab60c1909..7f83509468 100644
--- a/servers/physics_3d/joints/godot_hinge_joint_3d.h
+++ b/modules/godot_physics_3d/joints/godot_hinge_joint_3d.h
@@ -35,8 +35,8 @@
Adapted to Godot from the Bullet library.
*/
-#include "servers/physics_3d/godot_joint_3d.h"
-#include "servers/physics_3d/joints/godot_jacobian_entry_3d.h"
+#include "../godot_joint_3d.h"
+#include "godot_jacobian_entry_3d.h"
/*
Bullet Continuous Collision Detection and Physics Library
diff --git a/servers/physics_3d/joints/godot_jacobian_entry_3d.h b/modules/godot_physics_3d/joints/godot_jacobian_entry_3d.h
index d0c3c48ae6..d0c3c48ae6 100644
--- a/servers/physics_3d/joints/godot_jacobian_entry_3d.h
+++ b/modules/godot_physics_3d/joints/godot_jacobian_entry_3d.h
diff --git a/servers/physics_3d/joints/godot_pin_joint_3d.cpp b/modules/godot_physics_3d/joints/godot_pin_joint_3d.cpp
index 05ae0839e4..05ae0839e4 100644
--- a/servers/physics_3d/joints/godot_pin_joint_3d.cpp
+++ b/modules/godot_physics_3d/joints/godot_pin_joint_3d.cpp
diff --git a/servers/physics_3d/joints/godot_pin_joint_3d.h b/modules/godot_physics_3d/joints/godot_pin_joint_3d.h
index 2d19bcb626..62d3068e09 100644
--- a/servers/physics_3d/joints/godot_pin_joint_3d.h
+++ b/modules/godot_physics_3d/joints/godot_pin_joint_3d.h
@@ -35,8 +35,8 @@
Adapted to Godot from the Bullet library.
*/
-#include "servers/physics_3d/godot_joint_3d.h"
-#include "servers/physics_3d/joints/godot_jacobian_entry_3d.h"
+#include "../godot_joint_3d.h"
+#include "godot_jacobian_entry_3d.h"
/*
Bullet Continuous Collision Detection and Physics Library
diff --git a/servers/physics_3d/joints/godot_slider_joint_3d.cpp b/modules/godot_physics_3d/joints/godot_slider_joint_3d.cpp
index b9dca94b37..b9dca94b37 100644
--- a/servers/physics_3d/joints/godot_slider_joint_3d.cpp
+++ b/modules/godot_physics_3d/joints/godot_slider_joint_3d.cpp
diff --git a/servers/physics_3d/joints/godot_slider_joint_3d.h b/modules/godot_physics_3d/joints/godot_slider_joint_3d.h
index ad79fc51b0..99fabf8638 100644
--- a/servers/physics_3d/joints/godot_slider_joint_3d.h
+++ b/modules/godot_physics_3d/joints/godot_slider_joint_3d.h
@@ -35,8 +35,8 @@
Adapted to Godot from the Bullet library.
*/
-#include "servers/physics_3d/godot_joint_3d.h"
-#include "servers/physics_3d/joints/godot_jacobian_entry_3d.h"
+#include "../godot_joint_3d.h"
+#include "godot_jacobian_entry_3d.h"
/*
Bullet Continuous Collision Detection and Physics Library
diff --git a/modules/godot_physics_3d/register_types.cpp b/modules/godot_physics_3d/register_types.cpp
new file mode 100644
index 0000000000..1b1690cf59
--- /dev/null
+++ b/modules/godot_physics_3d/register_types.cpp
@@ -0,0 +1,61 @@
+/**************************************************************************/
+/* register_types.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "register_types.h"
+
+#include "godot_physics_server_3d.h"
+#include "servers/physics_server_3d.h"
+#include "servers/physics_server_3d_wrap_mt.h"
+
+static PhysicsServer3D *_createGodotPhysics3DCallback() {
+#ifdef THREADS_ENABLED
+ bool using_threads = GLOBAL_GET("physics/3d/run_on_separate_thread");
+#else
+ bool using_threads = false;
+#endif
+
+ PhysicsServer3D *physics_server_3d = memnew(GodotPhysicsServer3D(using_threads));
+
+ return memnew(PhysicsServer3DWrapMT(physics_server_3d, using_threads));
+}
+
+void initialize_godot_physics_3d_module(ModuleInitializationLevel p_level) {
+ if (p_level != MODULE_INITIALIZATION_LEVEL_SERVERS) {
+ return;
+ }
+ PhysicsServer3DManager::get_singleton()->register_server("GodotPhysics3D", callable_mp_static(_createGodotPhysics3DCallback));
+ PhysicsServer3DManager::get_singleton()->set_default_server("GodotPhysics3D");
+}
+
+void uninitialize_godot_physics_3d_module(ModuleInitializationLevel p_level) {
+ if (p_level != MODULE_INITIALIZATION_LEVEL_SERVERS) {
+ return;
+ }
+}
diff --git a/modules/godot_physics_3d/register_types.h b/modules/godot_physics_3d/register_types.h
new file mode 100644
index 0000000000..998fb4a1ee
--- /dev/null
+++ b/modules/godot_physics_3d/register_types.h
@@ -0,0 +1,39 @@
+/**************************************************************************/
+/* register_types.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef GODOT_PHYSICS_3D_REGISTER_TYPES_H
+#define GODOT_PHYSICS_3D_REGISTER_TYPES_H
+
+#include "modules/register_module_types.h"
+
+void initialize_godot_physics_3d_module(ModuleInitializationLevel p_level);
+void uninitialize_godot_physics_3d_module(ModuleInitializationLevel p_level);
+
+#endif // GODOT_PHYSICS_3D_REGISTER_TYPES_H
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index d0adf39fb2..8081c21ea0 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -2934,11 +2934,6 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::SignalInterface &p_isignal, StringBuilder &p_output) {
String arguments_sig;
- String delegate_type_params;
-
- if (!p_isignal.arguments.is_empty()) {
- delegate_type_params += "<";
- }
// Retrieve information from the arguments
const ArgumentInterface &first = p_isignal.arguments.front()->get();
@@ -2959,18 +2954,13 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
if (&iarg != &first) {
arguments_sig += ", ";
- delegate_type_params += ", ";
}
- arguments_sig += arg_type->cs_type;
+ String arg_cs_type = arg_type->cs_type + _get_generic_type_parameters(*arg_type, iarg.type.generic_type_parameters);
+
+ arguments_sig += arg_cs_type;
arguments_sig += " ";
arguments_sig += iarg.name;
-
- delegate_type_params += arg_type->cs_type;
- }
-
- if (!p_isignal.arguments.is_empty()) {
- delegate_type_params += ">";
}
// Generate signal
@@ -3019,8 +3009,14 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
p_output << ", ";
}
- p_output << sformat(arg_type->cs_variant_to_managed,
- "args[" + itos(idx) + "]", arg_type->cs_type, arg_type->name);
+ if (arg_type->cname == name_cache.type_Array_generic || arg_type->cname == name_cache.type_Dictionary_generic) {
+ String arg_cs_type = arg_type->cs_type + _get_generic_type_parameters(*arg_type, iarg.type.generic_type_parameters);
+
+ p_output << "new " << arg_cs_type << "(" << sformat(arg_type->cs_variant_to_managed, "args[" + itos(idx) + "]", arg_type->cs_type, arg_type->name) << ")";
+ } else {
+ p_output << sformat(arg_type->cs_variant_to_managed,
+ "args[" + itos(idx) + "]", arg_type->cs_type, arg_type->name);
+ }
idx++;
}
diff --git a/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml b/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml
index 338d632524..813c9d582e 100644
--- a/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml
+++ b/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml
@@ -178,6 +178,15 @@
[param layer] is a pointer to an [code]XrCompositionLayerBaseHeader[/code] struct.
</description>
</method>
+ <method name="_set_android_surface_swapchain_create_info_and_get_next_pointer" qualifiers="virtual">
+ <return type="int" />
+ <param index="0" name="property_values" type="Dictionary" />
+ <param index="1" name="next_pointer" type="void*" />
+ <description>
+ Adds additional data structures to Android surface swapchains created by [OpenXRCompositionLayer].
+ [param property_values] contains the values of the properties returned by [method _get_viewport_composition_layer_extension_properties].
+ </description>
+ </method>
<method name="_set_hand_joint_locations_and_get_next_pointer" qualifiers="virtual">
<return type="int" />
<param index="0" name="hand_index" type="int" />
diff --git a/modules/openxr/extensions/openxr_composition_layer_extension.cpp b/modules/openxr/extensions/openxr_composition_layer_extension.cpp
index 83e45ffe7f..dc30b95b27 100644
--- a/modules/openxr/extensions/openxr_composition_layer_extension.cpp
+++ b/modules/openxr/extensions/openxr_composition_layer_extension.cpp
@@ -144,7 +144,6 @@ bool OpenXRCompositionLayerExtension::create_android_surface_swapchain(XrSwapcha
OpenXRAPI *openxr_api = OpenXRAPI::get_singleton();
ERR_FAIL_NULL_V(openxr_api, false);
- // @todo We need a way to add to the next pointer chain.
XrResult result = xrCreateSwapchainAndroidSurfaceKHR(openxr_api->get_session(), p_info, r_swapchain, r_surface);
if (XR_FAILED(result)) {
print_line("OpenXR: Failed to create Android surface swapchain [", openxr_api->get_error_string(result), "]");
@@ -254,11 +253,19 @@ void OpenXRViewportCompositionLayerProvider::create_android_surface() {
ERR_FAIL_COND(android_surface.swapchain != XR_NULL_HANDLE || android_surface.surface.is_valid());
ERR_FAIL_COND(!openxr_api || !openxr_api->is_running());
+ void *next_pointer = nullptr;
+ for (OpenXRExtensionWrapper *wrapper : openxr_api->get_registered_extension_wrappers()) {
+ void *np = wrapper->set_android_surface_swapchain_create_info_and_get_next_pointer(extension_property_values, next_pointer);
+ if (np != nullptr) {
+ next_pointer = np;
+ }
+ }
+
// The XR_FB_android_surface_swapchain_create extension mandates that format, sampleCount,
// faceCount, arraySize, and mipCount must be zero.
XrSwapchainCreateInfo info = {
XR_TYPE_SWAPCHAIN_CREATE_INFO, // type
- nullptr, // next
+ next_pointer, // next
0, // createFlags
XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, // usageFlags
0, // format
diff --git a/modules/openxr/extensions/openxr_extension_wrapper.h b/modules/openxr/extensions/openxr_extension_wrapper.h
index 09a9556dfa..95b537d1b4 100644
--- a/modules/openxr/extensions/openxr_extension_wrapper.h
+++ b/modules/openxr/extensions/openxr_extension_wrapper.h
@@ -97,10 +97,11 @@ public:
virtual void on_state_loss_pending() {} // `on_state_loss_pending` is called when the OpenXR session state is changed to loss pending.
virtual void on_state_exiting() {} // `on_state_exiting` is called when the OpenXR session state is changed to exiting.
- virtual void *set_viewport_composition_layer_and_get_next_pointer(const XrCompositionLayerBaseHeader *p_layer, Dictionary p_property_values, void *p_next_pointer) { return p_next_pointer; } // Add additional data structures to composition layers created via OpenXRCompositionLayer.
+ virtual void *set_viewport_composition_layer_and_get_next_pointer(const XrCompositionLayerBaseHeader *p_layer, const Dictionary &p_property_values, void *p_next_pointer) { return p_next_pointer; } // Add additional data structures to composition layers created via OpenXRCompositionLayer.
virtual void on_viewport_composition_layer_destroyed(const XrCompositionLayerBaseHeader *p_layer) {} // `on_viewport_composition_layer_destroyed` is called when a composition layer created via OpenXRCompositionLayer is destroyed.
virtual void get_viewport_composition_layer_extension_properties(List<PropertyInfo> *p_property_list) {} // Get additional property definitions for OpenXRCompositionLayer.
virtual Dictionary get_viewport_composition_layer_extension_property_defaults() { return Dictionary(); } // Get the default values for the additional property definitions for OpenXRCompositionLayer.
+ virtual void *set_android_surface_swapchain_create_info_and_get_next_pointer(const Dictionary &p_property_values, void *p_next_pointer) { return p_next_pointer; }
// `on_event_polled` is called when there is an OpenXR event to process.
// Should return true if the event was handled, false otherwise.
diff --git a/modules/openxr/extensions/openxr_extension_wrapper_extension.cpp b/modules/openxr/extensions/openxr_extension_wrapper_extension.cpp
index e09ca484d5..07ca476421 100644
--- a/modules/openxr/extensions/openxr_extension_wrapper_extension.cpp
+++ b/modules/openxr/extensions/openxr_extension_wrapper_extension.cpp
@@ -65,6 +65,7 @@ void OpenXRExtensionWrapperExtension::_bind_methods() {
GDVIRTUAL_BIND(_get_viewport_composition_layer_extension_properties);
GDVIRTUAL_BIND(_get_viewport_composition_layer_extension_property_defaults);
GDVIRTUAL_BIND(_on_viewport_composition_layer_destroyed, "layer");
+ GDVIRTUAL_BIND(_set_android_surface_swapchain_create_info_and_get_next_pointer, "property_values", "next_pointer");
ClassDB::bind_method(D_METHOD("get_openxr_api"), &OpenXRExtensionWrapperExtension::get_openxr_api);
ClassDB::bind_method(D_METHOD("register_extension_wrapper"), &OpenXRExtensionWrapperExtension::register_extension_wrapper);
@@ -249,7 +250,7 @@ bool OpenXRExtensionWrapperExtension::on_event_polled(const XrEventDataBuffer &p
return false;
}
-void *OpenXRExtensionWrapperExtension::set_viewport_composition_layer_and_get_next_pointer(const XrCompositionLayerBaseHeader *p_layer, Dictionary p_property_values, void *p_next_pointer) {
+void *OpenXRExtensionWrapperExtension::set_viewport_composition_layer_and_get_next_pointer(const XrCompositionLayerBaseHeader *p_layer, const Dictionary &p_property_values, void *p_next_pointer) {
uint64_t pointer = 0;
if (GDVIRTUAL_CALL(_set_viewport_composition_layer_and_get_next_pointer, GDExtensionConstPtr<void>(p_layer), p_property_values, GDExtensionPtr<void>(p_next_pointer), pointer)) {
@@ -279,6 +280,16 @@ Dictionary OpenXRExtensionWrapperExtension::get_viewport_composition_layer_exten
return property_defaults;
}
+void *OpenXRExtensionWrapperExtension::set_android_surface_swapchain_create_info_and_get_next_pointer(const Dictionary &p_property_values, void *p_next_pointer) {
+ uint64_t pointer = 0;
+
+ if (GDVIRTUAL_CALL(_set_android_surface_swapchain_create_info_and_get_next_pointer, p_property_values, GDExtensionPtr<void>(p_next_pointer), pointer)) {
+ return reinterpret_cast<void *>(pointer);
+ }
+
+ return p_next_pointer;
+}
+
Ref<OpenXRAPIExtension> OpenXRExtensionWrapperExtension::get_openxr_api() {
return openxr_api;
}
diff --git a/modules/openxr/extensions/openxr_extension_wrapper_extension.h b/modules/openxr/extensions/openxr_extension_wrapper_extension.h
index e37853903b..5cdf288c93 100644
--- a/modules/openxr/extensions/openxr_extension_wrapper_extension.h
+++ b/modules/openxr/extensions/openxr_extension_wrapper_extension.h
@@ -121,15 +121,17 @@ public:
GDVIRTUAL1R(bool, _on_event_polled, GDExtensionConstPtr<void>);
- virtual void *set_viewport_composition_layer_and_get_next_pointer(const XrCompositionLayerBaseHeader *p_layer, Dictionary p_property_values, void *p_next_pointer) override;
+ virtual void *set_viewport_composition_layer_and_get_next_pointer(const XrCompositionLayerBaseHeader *p_layer, const Dictionary &p_property_values, void *p_next_pointer) override;
virtual void on_viewport_composition_layer_destroyed(const XrCompositionLayerBaseHeader *p_layer) override;
virtual void get_viewport_composition_layer_extension_properties(List<PropertyInfo> *p_property_list) override;
virtual Dictionary get_viewport_composition_layer_extension_property_defaults() override;
+ virtual void *set_android_surface_swapchain_create_info_and_get_next_pointer(const Dictionary &p_property_values, void *p_next_pointer) override;
GDVIRTUAL3R(uint64_t, _set_viewport_composition_layer_and_get_next_pointer, GDExtensionConstPtr<void>, Dictionary, GDExtensionPtr<void>);
GDVIRTUAL1(_on_viewport_composition_layer_destroyed, GDExtensionConstPtr<void>);
GDVIRTUAL0R(TypedArray<Dictionary>, _get_viewport_composition_layer_extension_properties);
GDVIRTUAL0R(Dictionary, _get_viewport_composition_layer_extension_property_defaults);
+ GDVIRTUAL2R(uint64_t, _set_android_surface_swapchain_create_info_and_get_next_pointer, Dictionary, GDExtensionPtr<void>);
Ref<OpenXRAPIExtension> get_openxr_api();
diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp
index 73b6f6c1c9..c67be5a2b3 100644
--- a/modules/openxr/openxr_api.cpp
+++ b/modules/openxr/openxr_api.cpp
@@ -1247,7 +1247,7 @@ bool OpenXRAPI::create_main_swapchains(Size2i p_size) {
return false;
}
- set_object_name(XR_OBJECT_TYPE_SWAPCHAIN, uint64_t(render_state.main_swapchains[OPENXR_SWAPCHAIN_COLOR].get_swapchain()), "Main depth swapchain");
+ set_object_name(XR_OBJECT_TYPE_SWAPCHAIN, uint64_t(render_state.main_swapchains[OPENXR_SWAPCHAIN_DEPTH].get_swapchain()), "Main depth swapchain");
}
// We create our velocity swapchain if:
diff --git a/modules/raycast/godot_update_embree.py b/modules/raycast/godot_update_embree.py
index c179060365..c4fff330c9 100644
--- a/modules/raycast/godot_update_embree.py
+++ b/modules/raycast/godot_update_embree.py
@@ -4,8 +4,8 @@ import re
import shutil
import stat
import subprocess
-from types import TracebackType
-from typing import Any, Callable, Tuple, Type
+import sys
+from typing import Any, Callable
git_tag = "v4.3.1"
@@ -100,9 +100,7 @@ subprocess.run(["git", "checkout", git_tag])
commit_hash = str(subprocess.check_output(["git", "rev-parse", "HEAD"], universal_newlines=True)).strip()
-def on_rm_error(
- function: Callable[..., Any], path: str, excinfo: Tuple[Type[Exception], Exception, TracebackType]
-) -> None:
+def on_rm_error(function: Callable[..., Any], path: str, excinfo: Exception) -> None:
"""
Error handler for `shutil.rmtree()`.
@@ -113,10 +111,12 @@ def on_rm_error(
os.unlink(path)
-# 3.12 Python and beyond should replace `onerror` with `onexc`.
# We remove the .git directory because it contains
# a lot of read-only files that are problematic on Windows.
-shutil.rmtree(".git", onerror=on_rm_error)
+if sys.version_info >= (3, 12):
+ shutil.rmtree(".git", onexc=on_rm_error)
+else:
+ shutil.rmtree(".git", onerror=on_rm_error) # type: ignore
all_files = set(cpp_files)
diff --git a/modules/upnp/upnp.cpp b/modules/upnp/upnp.cpp
index 6bdb261b50..4305bf842a 100644
--- a/modules/upnp/upnp.cpp
+++ b/modules/upnp/upnp.cpp
@@ -131,7 +131,11 @@ void UPNP::parse_igd(Ref<UPNPDevice> dev, UPNPDev *devlist) {
GetUPNPUrls(&urls, &data, dev->get_description_url().utf8().get_data(), 0);
char addr[16];
+#if MINIUPNPC_API_VERSION >= 18
+ int i = UPNP_GetValidIGD(devlist, &urls, &data, (char *)&addr, 16, nullptr, 0);
+#else
int i = UPNP_GetValidIGD(devlist, &urls, &data, (char *)&addr, 16);
+#endif
if (i != 1) {
FreeUPNPUrls(&urls);
diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp
index a36748efc1..3fbbc263a0 100644
--- a/platform/linuxbsd/wayland/display_server_wayland.cpp
+++ b/platform/linuxbsd/wayland/display_server_wayland.cpp
@@ -1344,20 +1344,28 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win
if (rendering_context->initialize() != OK) {
memdelete(rendering_context);
rendering_context = nullptr;
- r_error = ERR_CANT_CREATE;
+ bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3");
+ if (fallback_to_opengl3 && rendering_driver != "opengl3") {
+ WARN_PRINT("Your video card drivers seem not to support the required Vulkan version, switching to OpenGL 3.");
+ rendering_driver = "opengl3";
+ OS::get_singleton()->set_current_rendering_method("gl_compatibility");
+ OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
+ } else {
+ r_error = ERR_CANT_CREATE;
- if (p_rendering_driver == "vulkan") {
- OS::get_singleton()->alert(
- vformat("Your video card drivers seem not to support the required Vulkan version.\n\n"
- "If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n"
- "You can enable the OpenGL 3 driver by starting the engine from the\n"
- "command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n"
- "If you recently updated your video card drivers, try rebooting.",
- executable_name),
- "Unable to initialize Vulkan video driver");
- }
+ if (p_rendering_driver == "vulkan") {
+ OS::get_singleton()->alert(
+ vformat("Your video card drivers seem not to support the required Vulkan version.\n\n"
+ "If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n"
+ "You can enable the OpenGL 3 driver by starting the engine from the\n"
+ "command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n"
+ "If you recently updated your video card drivers, try rebooting.",
+ executable_name),
+ "Unable to initialize Vulkan video driver");
+ }
- ERR_FAIL_MSG(vformat("Could not initialize %s", rendering_driver));
+ ERR_FAIL_MSG(vformat("Could not initialize %s", rendering_driver));
+ }
}
driver_found = true;
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index db4c743595..9adab7284c 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -620,18 +620,16 @@ def configure_msvc(env: "SConsEnvironment", vcvars_msvc_config):
print("ThinLTO is only compatible with LLVM, use `use_llvm=yes` or `lto=full`.")
sys.exit(255)
- env.Append(CCFLAGS=["-flto=thin"])
- env.Append(LINKFLAGS=["-flto=thin"])
+ env.AppendUnique(CCFLAGS=["-flto=thin"])
elif env["use_llvm"]:
- env.Append(CCFLAGS=["-flto"])
- env.Append(LINKFLAGS=["-flto"])
+ env.AppendUnique(CCFLAGS=["-flto"])
else:
env.AppendUnique(CCFLAGS=["/GL"])
- env.AppendUnique(ARFLAGS=["/LTCG"])
- if env["progress"]:
- env.AppendUnique(LINKFLAGS=["/LTCG:STATUS"])
- else:
- env.AppendUnique(LINKFLAGS=["/LTCG"])
+ if env["progress"]:
+ env.AppendUnique(LINKFLAGS=["/LTCG:STATUS"])
+ else:
+ env.AppendUnique(LINKFLAGS=["/LTCG"])
+ env.AppendUnique(ARFLAGS=["/LTCG"])
if vcvars_msvc_config:
env.Prepend(CPPPATH=[p for p in str(os.getenv("INCLUDE")).split(";")])
diff --git a/pyproject.toml b/pyproject.toml
index 59b6d09a03..1cf789b460 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -10,6 +10,7 @@ warn_unreachable = true
namespace_packages = true
explicit_package_bases = true
exclude = ["thirdparty/"]
+python_version = "3.8"
[tool.ruff]
extend-exclude = ["thirdparty"]
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index c3287035ff..635228670d 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -831,6 +831,9 @@ void CodeEdit::_cut_internal(int p_caret) {
delete_selection(p_caret);
return;
}
+ if (!is_empty_selection_clipboard_enabled()) {
+ return;
+ }
if (p_caret == -1) {
delete_lines();
} else {
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index f1902bade4..2211bd76fc 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -58,7 +58,7 @@ Size2 ScrollContainer::get_minimum_size() const {
if (horizontal_scroll_mode == SCROLL_MODE_DISABLED) {
min_size.x = largest_child_min_size.x;
- bool v_scroll_show = vertical_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (vertical_scroll_mode == SCROLL_MODE_AUTO && largest_child_min_size.y > size.y);
+ bool v_scroll_show = vertical_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || vertical_scroll_mode == SCROLL_MODE_RESERVE || (vertical_scroll_mode == SCROLL_MODE_AUTO && largest_child_min_size.y > size.y);
if (v_scroll_show && v_scroll->get_parent() == this) {
min_size.x += v_scroll->get_minimum_size().x;
}
@@ -66,7 +66,7 @@ Size2 ScrollContainer::get_minimum_size() const {
if (vertical_scroll_mode == SCROLL_MODE_DISABLED) {
min_size.y = largest_child_min_size.y;
- bool h_scroll_show = horizontal_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (horizontal_scroll_mode == SCROLL_MODE_AUTO && largest_child_min_size.x > size.x);
+ bool h_scroll_show = horizontal_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || horizontal_scroll_mode == SCROLL_MODE_RESERVE || (horizontal_scroll_mode == SCROLL_MODE_AUTO && largest_child_min_size.x > size.x);
if (h_scroll_show && h_scroll->get_parent() == this) {
min_size.y += h_scroll->get_minimum_size().y;
}
@@ -92,6 +92,15 @@ void ScrollContainer::_cancel_drag() {
}
}
+bool ScrollContainer::_is_h_scroll_visible() const {
+ // Scrolls may have been moved out for reasons.
+ return h_scroll->is_visible() && h_scroll->get_parent() == this;
+}
+
+bool ScrollContainer::_is_v_scroll_visible() const {
+ return v_scroll->is_visible() && v_scroll->get_parent() == this;
+}
+
void ScrollContainer::gui_input(const Ref<InputEvent> &p_gui_input) {
ERR_FAIL_COND(p_gui_input.is_null());
@@ -298,11 +307,11 @@ void ScrollContainer::_reposition_children() {
ofs += theme_cache.panel_style->get_offset();
bool rtl = is_layout_rtl();
- if (h_scroll->is_visible_in_tree() && h_scroll->get_parent() == this) { //scrolls may have been moved out for reasons
+ if (_is_h_scroll_visible() || horizontal_scroll_mode == SCROLL_MODE_RESERVE) {
size.y -= h_scroll->get_minimum_size().y;
}
- if (v_scroll->is_visible_in_tree() && v_scroll->get_parent() == this) { //scrolls may have been moved out for reasons
+ if (_is_v_scroll_visible() || vertical_scroll_mode == SCROLL_MODE_RESERVE) {
size.x -= v_scroll->get_minimum_size().x;
}
@@ -324,7 +333,7 @@ void ScrollContainer::_reposition_children() {
r.size.height = MAX(size.height, minsize.height);
}
r.position += ofs;
- if (rtl && v_scroll->is_visible_in_tree() && v_scroll->get_parent() == this) {
+ if (rtl && _is_v_scroll_visible()) {
r.position.x += v_scroll->get_minimum_size().x;
}
r.position = r.position.floor();
@@ -436,14 +445,14 @@ void ScrollContainer::update_scrollbars() {
Size2 hmin = h_scroll->get_combined_minimum_size();
Size2 vmin = v_scroll->get_combined_minimum_size();
- h_scroll->set_visible(horizontal_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (horizontal_scroll_mode == SCROLL_MODE_AUTO && largest_child_min_size.width > size.width));
- v_scroll->set_visible(vertical_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (vertical_scroll_mode == SCROLL_MODE_AUTO && largest_child_min_size.height > size.height));
+ h_scroll->set_visible(horizontal_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || ((horizontal_scroll_mode == SCROLL_MODE_AUTO || horizontal_scroll_mode == SCROLL_MODE_RESERVE) && largest_child_min_size.width > size.width));
+ v_scroll->set_visible(vertical_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || ((vertical_scroll_mode == SCROLL_MODE_AUTO || vertical_scroll_mode == SCROLL_MODE_RESERVE) && largest_child_min_size.height > size.height));
h_scroll->set_max(largest_child_min_size.width);
- h_scroll->set_page((v_scroll->is_visible() && v_scroll->get_parent() == this) ? size.width - vmin.width : size.width);
+ h_scroll->set_page(_is_v_scroll_visible() ? size.width - vmin.width : size.width);
v_scroll->set_max(largest_child_min_size.height);
- v_scroll->set_page((h_scroll->is_visible() && h_scroll->get_parent() == this) ? size.height - hmin.height : size.height);
+ v_scroll->set_page(_is_h_scroll_visible() ? size.height - hmin.height : size.height);
// Avoid scrollbar overlapping.
_updating_scrollbars = true;
@@ -603,14 +612,15 @@ void ScrollContainer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_vertical", PROPERTY_HINT_NONE, "suffix:px"), "set_v_scroll", "get_v_scroll");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "scroll_horizontal_custom_step", PROPERTY_HINT_RANGE, "-1,4096,suffix:px"), "set_horizontal_custom_step", "get_horizontal_custom_step");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "scroll_vertical_custom_step", PROPERTY_HINT_RANGE, "-1,4096,suffix:px"), "set_vertical_custom_step", "get_vertical_custom_step");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_scroll_mode", PROPERTY_HINT_ENUM, "Disabled,Auto,Always Show,Never Show"), "set_horizontal_scroll_mode", "get_horizontal_scroll_mode");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "vertical_scroll_mode", PROPERTY_HINT_ENUM, "Disabled,Auto,Always Show,Never Show"), "set_vertical_scroll_mode", "get_vertical_scroll_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_scroll_mode", PROPERTY_HINT_ENUM, "Disabled,Auto,Always Show,Never Show,Reserve"), "set_horizontal_scroll_mode", "get_horizontal_scroll_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "vertical_scroll_mode", PROPERTY_HINT_ENUM, "Disabled,Auto,Always Show,Never Show,Reserve"), "set_vertical_scroll_mode", "get_vertical_scroll_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_deadzone"), "set_deadzone", "get_deadzone");
BIND_ENUM_CONSTANT(SCROLL_MODE_DISABLED);
BIND_ENUM_CONSTANT(SCROLL_MODE_AUTO);
BIND_ENUM_CONSTANT(SCROLL_MODE_SHOW_ALWAYS);
BIND_ENUM_CONSTANT(SCROLL_MODE_SHOW_NEVER);
+ BIND_ENUM_CONSTANT(SCROLL_MODE_RESERVE);
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, ScrollContainer, panel_style, "panel");
diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h
index 02146618cd..afd3c8bd57 100644
--- a/scene/gui/scroll_container.h
+++ b/scene/gui/scroll_container.h
@@ -44,6 +44,7 @@ public:
SCROLL_MODE_AUTO,
SCROLL_MODE_SHOW_ALWAYS,
SCROLL_MODE_SHOW_NEVER,
+ SCROLL_MODE_RESERVE,
};
private:
@@ -75,6 +76,9 @@ private:
void _cancel_drag();
+ bool _is_h_scroll_visible() const;
+ bool _is_v_scroll_visible() const;
+
protected:
Size2 get_minimum_size() const override;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 888e680219..0e8d76d294 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1265,7 +1265,7 @@ void TextEdit::_notification(int p_what) {
}
if (!clipped && lookup_symbol_word.length() != 0) { // Highlight word
- if (is_ascii_alphabet_char(lookup_symbol_word[0]) || lookup_symbol_word[0] == '_' || lookup_symbol_word[0] == '.') {
+ if (is_unicode_identifier_start(lookup_symbol_word[0]) || lookup_symbol_word[0] == '.') {
Color highlight_underline_color = !editable ? theme_cache.font_readonly_color : theme_cache.font_color;
int lookup_symbol_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0);
int lookup_symbol_word_len = lookup_symbol_word.length();
@@ -3367,6 +3367,14 @@ bool TextEdit::is_middle_mouse_paste_enabled() const {
return middle_mouse_paste_enabled;
}
+void TextEdit::set_empty_selection_clipboard_enabled(bool p_enabled) {
+ empty_selection_clipboard_enabled = p_enabled;
+}
+
+bool TextEdit::is_empty_selection_clipboard_enabled() const {
+ return empty_selection_clipboard_enabled;
+}
+
// Text manipulation
void TextEdit::clear() {
setting_text = true;
@@ -6569,6 +6577,9 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_middle_mouse_paste_enabled", "enabled"), &TextEdit::set_middle_mouse_paste_enabled);
ClassDB::bind_method(D_METHOD("is_middle_mouse_paste_enabled"), &TextEdit::is_middle_mouse_paste_enabled);
+ ClassDB::bind_method(D_METHOD("set_empty_selection_clipboard_enabled", "enabled"), &TextEdit::set_empty_selection_clipboard_enabled);
+ ClassDB::bind_method(D_METHOD("is_empty_selection_clipboard_enabled"), &TextEdit::is_empty_selection_clipboard_enabled);
+
// Text manipulation
ClassDB::bind_method(D_METHOD("clear"), &TextEdit::clear);
@@ -6962,6 +6973,7 @@ void TextEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_and_drop_selection_enabled"), "set_drag_and_drop_selection_enabled", "is_drag_and_drop_selection_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "virtual_keyboard_enabled"), "set_virtual_keyboard_enabled", "is_virtual_keyboard_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "middle_mouse_paste_enabled"), "set_middle_mouse_paste_enabled", "is_middle_mouse_paste_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "empty_selection_clipboard_enabled"), "set_empty_selection_clipboard_enabled", "is_empty_selection_clipboard_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "wrap_mode", PROPERTY_HINT_ENUM, "None,Boundary"), "set_line_wrapping_mode", "get_line_wrapping_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Arbitrary:1,Word:2,Word (Smart):3"), "set_autowrap_mode", "get_autowrap_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "indent_wrapped_lines"), "set_indent_wrapped_lines", "is_indent_wrapped_lines");
@@ -7216,6 +7228,10 @@ void TextEdit::_cut_internal(int p_caret) {
return;
}
+ if (!empty_selection_clipboard_enabled) {
+ return;
+ }
+
// Remove full lines.
begin_complex_operation();
begin_multicaret_edit();
@@ -7246,6 +7262,10 @@ void TextEdit::_copy_internal(int p_caret) {
return;
}
+ if (!empty_selection_clipboard_enabled) {
+ return;
+ }
+
// Copy full lines.
StringBuilder clipboard;
Vector<Point2i> line_ranges;
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index c5f838020b..94b105d486 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -319,6 +319,7 @@ private:
bool shortcut_keys_enabled = true;
bool virtual_keyboard_enabled = true;
bool middle_mouse_paste_enabled = true;
+ bool empty_selection_clipboard_enabled = true;
// Overridable actions.
String cut_copy_line = "";
@@ -770,6 +771,9 @@ public:
void set_middle_mouse_paste_enabled(bool p_enabled);
bool is_middle_mouse_paste_enabled() const;
+ void set_empty_selection_clipboard_enabled(bool p_enabled);
+ bool is_empty_selection_clipboard_enabled() const;
+
// Text manipulation
void clear();
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index eb3448e1a2..d921cc5b67 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -4019,4 +4019,9 @@ bool Node::is_connected(const StringName &p_signal, const Callable &p_callable)
return Object::is_connected(p_signal, p_callable);
}
+bool Node::has_connections(const StringName &p_signal) const {
+ ERR_THREAD_GUARD_V(false);
+ return Object::has_connections(p_signal);
+}
+
#endif
diff --git a/scene/main/node.h b/scene/main/node.h
index 4560ed085c..298cbc7e59 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -797,6 +797,7 @@ public:
virtual Error connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags = 0) override;
virtual void disconnect(const StringName &p_signal, const Callable &p_callable) override;
virtual bool is_connected(const StringName &p_signal, const Callable &p_callable) const override;
+ virtual bool has_connections(const StringName &p_signal) const override;
#endif
Node();
~Node();
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 76678e609a..09227e260f 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -117,6 +117,7 @@
#include "scene/resources/compressed_texture.h"
#include "scene/resources/curve_texture.h"
#include "scene/resources/environment.h"
+#include "scene/resources/external_texture.h"
#include "scene/resources/font.h"
#include "scene/resources/gradient.h"
#include "scene/resources/gradient_texture.h"
@@ -926,6 +927,7 @@ void register_scene_types() {
GDREGISTER_CLASS(GradientTexture2D);
GDREGISTER_CLASS(AnimatedTexture);
GDREGISTER_CLASS(CameraTexture);
+ GDREGISTER_CLASS(ExternalTexture);
GDREGISTER_VIRTUAL_CLASS(TextureLayered);
GDREGISTER_ABSTRACT_CLASS(ImageTextureLayered);
GDREGISTER_VIRTUAL_CLASS(Texture3D);
diff --git a/scene/resources/external_texture.cpp b/scene/resources/external_texture.cpp
new file mode 100644
index 0000000000..0552bbd081
--- /dev/null
+++ b/scene/resources/external_texture.cpp
@@ -0,0 +1,89 @@
+/**************************************************************************/
+/* external_texture.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "external_texture.h"
+
+void ExternalTexture::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_size", "size"), &ExternalTexture::set_size);
+ ClassDB::bind_method(D_METHOD("get_external_texture_id"), &ExternalTexture::get_external_texture_id);
+ ClassDB::bind_method(D_METHOD("set_external_buffer_id", "external_buffer_id"), &ExternalTexture::set_external_buffer_id);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
+}
+
+uint64_t ExternalTexture::get_external_texture_id() const {
+ return RenderingServer::get_singleton()->texture_get_native_handle(texture);
+}
+
+void ExternalTexture::set_size(const Size2 &p_size) {
+ if (p_size.width > 0 && p_size.height > 0 && p_size != size) {
+ size = p_size;
+ RenderingServer::get_singleton()->texture_external_update(texture, size.width, size.height, external_buffer);
+ emit_changed();
+ }
+}
+
+Size2 ExternalTexture::get_size() const {
+ return size;
+}
+
+void ExternalTexture::set_external_buffer_id(uint64_t p_external_buffer) {
+ if (p_external_buffer != external_buffer) {
+ external_buffer = p_external_buffer;
+ RenderingServer::get_singleton()->texture_external_update(texture, size.width, size.height, external_buffer);
+ }
+}
+
+int ExternalTexture::get_width() const {
+ return size.width;
+}
+
+int ExternalTexture::get_height() const {
+ return size.height;
+}
+
+bool ExternalTexture::has_alpha() const {
+ return false;
+}
+
+RID ExternalTexture::get_rid() const {
+ return texture;
+}
+
+ExternalTexture::ExternalTexture() {
+ texture = RenderingServer::get_singleton()->texture_external_create(size.width, size.height);
+}
+
+ExternalTexture::~ExternalTexture() {
+ if (texture.is_valid()) {
+ ERR_FAIL_NULL(RenderingServer::get_singleton());
+ RenderingServer::get_singleton()->free(texture);
+ }
+}
diff --git a/scene/resources/external_texture.h b/scene/resources/external_texture.h
new file mode 100644
index 0000000000..96bcd8d0fe
--- /dev/null
+++ b/scene/resources/external_texture.h
@@ -0,0 +1,66 @@
+/**************************************************************************/
+/* external_texture.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef EXTERNAL_TEXTURE_H
+#define EXTERNAL_TEXTURE_H
+
+#include "scene/resources/texture.h"
+
+// External textures as defined by OES_EGL_image_external (GLES) or VK_ANDROID_external_memory_android_hardware_buffer (Vulkan).
+class ExternalTexture : public Texture2D {
+ GDCLASS(ExternalTexture, Texture2D);
+
+private:
+ RID texture;
+ Size2 size = Size2(256, 256);
+ uint64_t external_buffer = 0;
+
+protected:
+ static void _bind_methods();
+
+public:
+ uint64_t get_external_texture_id() const;
+
+ virtual Size2 get_size() const override;
+ void set_size(const Size2 &p_size);
+
+ void set_external_buffer_id(uint64_t p_external_buffer);
+
+ virtual int get_width() const override;
+ virtual int get_height() const override;
+
+ virtual RID get_rid() const override;
+ virtual bool has_alpha() const override;
+
+ ExternalTexture();
+ ~ExternalTexture();
+};
+
+#endif // EXTERNAL_TEXTURE_H
diff --git a/scu_builders.py b/scu_builders.py
index fc5461196f..7fc0c15b2d 100644
--- a/scu_builders.py
+++ b/scu_builders.py
@@ -322,6 +322,8 @@ def generate_scu_files(max_includes_per_scu):
process_folder(["modules/openxr"], ["register_types"])
process_folder(["modules/openxr/action_map"])
process_folder(["modules/openxr/editor"])
+ process_folder(["modules/godot_physics_3d"])
+ process_folder(["modules/godot_physics_3d/joints"])
process_folder(["modules/csg"])
process_folder(["modules/gdscript"])
@@ -349,8 +351,6 @@ def generate_scu_files(max_includes_per_scu):
process_folder(["servers/rendering/renderer_rd/environment"])
process_folder(["servers/rendering/renderer_rd/storage_rd"])
process_folder(["servers/physics_2d"])
- process_folder(["servers/physics_3d"])
- process_folder(["servers/physics_3d/joints"])
process_folder(["servers/audio"])
process_folder(["servers/audio/effects"])
diff --git a/servers/SCsub b/servers/SCsub
index 736bed68ec..472cb096ab 100644
--- a/servers/SCsub
+++ b/servers/SCsub
@@ -28,7 +28,6 @@ SConscript("text/SCsub")
SConscript("physics_2d/SCsub")
if not env["disable_3d"]:
- SConscript("physics_3d/SCsub")
env.add_source_files(env.servers_sources, "physics_server_3d.cpp")
env.add_source_files(env.servers_sources, "physics_server_3d_wrap_mt.cpp")
SConscript("xr/SCsub")
diff --git a/servers/physics_3d/SCsub b/servers/physics_3d/SCsub
deleted file mode 100644
index df7b521693..0000000000
--- a/servers/physics_3d/SCsub
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env python
-
-Import("env")
-
-env.add_source_files(env.servers_sources, "*.cpp")
-
-SConscript("joints/SCsub")
diff --git a/servers/physics_3d/joints/SCsub b/servers/physics_3d/joints/SCsub
deleted file mode 100644
index 86681f9c74..0000000000
--- a/servers/physics_3d/joints/SCsub
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env python
-
-Import("env")
-
-env.add_source_files(env.servers_sources, "*.cpp")
diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp
index 698805bbdd..ee48151863 100644
--- a/servers/physics_server_3d.cpp
+++ b/servers/physics_server_3d.cpp
@@ -1201,7 +1201,9 @@ String PhysicsServer3DManager::get_server_name(int p_id) {
}
PhysicsServer3D *PhysicsServer3DManager::new_default_server() {
- ERR_FAIL_COND_V(default_server_id == -1, nullptr);
+ if (default_server_id == -1) {
+ return nullptr;
+ }
Variant ret;
Callable::CallError ce;
physics_servers[default_server_id].create_callback.callp(nullptr, 0, ret, ce);
diff --git a/servers/physics_server_3d_dummy.h b/servers/physics_server_3d_dummy.h
new file mode 100644
index 0000000000..209a541fea
--- /dev/null
+++ b/servers/physics_server_3d_dummy.h
@@ -0,0 +1,436 @@
+/**************************************************************************/
+/* physics_server_3d_dummy.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef PHYSICS_SERVER_3D_DUMMY_H
+#define PHYSICS_SERVER_3D_DUMMY_H
+
+#include "servers/physics_server_3d.h"
+
+class PhysicsDirectBodyState3DDummy : public PhysicsDirectBodyState3D {
+ GDCLASS(PhysicsDirectBodyState3DDummy, PhysicsDirectBodyState3D);
+
+ PhysicsDirectSpaceState3D *space_state_dummy = nullptr;
+
+public:
+ virtual Vector3 get_total_gravity() const override { return Vector3(); }
+ virtual real_t get_total_angular_damp() const override { return 0; }
+ virtual real_t get_total_linear_damp() const override { return 0; }
+
+ virtual Vector3 get_center_of_mass() const override { return Vector3(); }
+ virtual Vector3 get_center_of_mass_local() const override { return Vector3(); }
+ virtual Basis get_principal_inertia_axes() const override { return Basis(); }
+ virtual real_t get_inverse_mass() const override { return 0; }
+ virtual Vector3 get_inverse_inertia() const override { return Vector3(); }
+ virtual Basis get_inverse_inertia_tensor() const override { return Basis(); }
+
+ virtual void set_linear_velocity(const Vector3 &p_velocity) override {}
+ virtual Vector3 get_linear_velocity() const override { return Vector3(); }
+
+ virtual void set_angular_velocity(const Vector3 &p_velocity) override {}
+ virtual Vector3 get_angular_velocity() const override { return Vector3(); }
+
+ virtual void set_transform(const Transform3D &p_transform) override {}
+ virtual Transform3D get_transform() const override { return Transform3D(); }
+
+ virtual Vector3 get_velocity_at_local_position(const Vector3 &p_position) const override { return Vector3(); }
+
+ virtual void apply_central_impulse(const Vector3 &p_impulse) override {}
+ virtual void apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position = Vector3()) override {}
+ virtual void apply_torque_impulse(const Vector3 &p_impulse) override {}
+
+ virtual void apply_central_force(const Vector3 &p_force) override {}
+ virtual void apply_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) override {}
+ virtual void apply_torque(const Vector3 &p_torque) override {}
+
+ virtual void add_constant_central_force(const Vector3 &p_force) override {}
+ virtual void add_constant_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) override {}
+ virtual void add_constant_torque(const Vector3 &p_torque) override {}
+
+ virtual void set_constant_force(const Vector3 &p_force) override {}
+ virtual Vector3 get_constant_force() const override { return Vector3(); }
+
+ virtual void set_constant_torque(const Vector3 &p_torque) override {}
+ virtual Vector3 get_constant_torque() const override { return Vector3(); }
+
+ virtual void set_sleep_state(bool p_sleep) override {}
+ virtual bool is_sleeping() const override { return false; }
+
+ virtual int get_contact_count() const override { return 0; }
+
+ virtual Vector3 get_contact_local_position(int p_contact_idx) const override { return Vector3(); }
+ virtual Vector3 get_contact_local_normal(int p_contact_idx) const override { return Vector3(); }
+ virtual Vector3 get_contact_impulse(int p_contact_idx) const override { return Vector3(); }
+ virtual int get_contact_local_shape(int p_contact_idx) const override { return 0; }
+ virtual Vector3 get_contact_local_velocity_at_position(int p_contact_idx) const override { return Vector3(); }
+
+ virtual RID get_contact_collider(int p_contact_idx) const override { return RID(); }
+ virtual Vector3 get_contact_collider_position(int p_contact_idx) const override { return Vector3(); }
+ virtual ObjectID get_contact_collider_id(int p_contact_idx) const override { return ObjectID(); }
+ virtual Object *get_contact_collider_object(int p_contact_idx) const override { return nullptr; }
+ virtual int get_contact_collider_shape(int p_contact_idx) const override { return 0; }
+ virtual Vector3 get_contact_collider_velocity_at_position(int p_contact_idx) const override { return Vector3(); }
+
+ virtual real_t get_step() const override { return 0; }
+ virtual void integrate_forces() override {}
+
+ virtual PhysicsDirectSpaceState3D *get_space_state() override { return space_state_dummy; }
+
+ PhysicsDirectBodyState3DDummy(PhysicsDirectSpaceState3D *p_space_state_dummy) {
+ space_state_dummy = p_space_state_dummy;
+ }
+};
+
+class PhysicsDirectSpaceState3DDummy : public PhysicsDirectSpaceState3D {
+ GDCLASS(PhysicsDirectSpaceState3DDummy, PhysicsDirectSpaceState3D);
+
+public:
+ virtual bool intersect_ray(const RayParameters &p_parameters, RayResult &r_result) override { return false; }
+
+ virtual int intersect_point(const PointParameters &p_parameters, ShapeResult *r_results, int p_result_max) override { return 0; }
+
+ virtual int intersect_shape(const ShapeParameters &p_parameters, ShapeResult *r_results, int p_result_max) override { return 0; }
+ virtual bool cast_motion(const ShapeParameters &p_parameters, real_t &p_closest_safe, real_t &p_closest_unsafe, ShapeRestInfo *r_info = nullptr) override { return false; }
+ virtual bool collide_shape(const ShapeParameters &p_parameters, Vector3 *r_results, int p_result_max, int &r_result_count) override { return false; }
+ virtual bool rest_info(const ShapeParameters &p_parameters, ShapeRestInfo *r_info) override { return false; }
+
+ virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const override { return Vector3(); }
+};
+
+class PhysicsServer3DDummy : public PhysicsServer3D {
+ GDCLASS(PhysicsServer3DDummy, PhysicsServer3D);
+
+ PhysicsDirectBodyState3DDummy *body_state_dummy = nullptr;
+ PhysicsDirectSpaceState3DDummy *space_state_dummy = nullptr;
+
+public:
+ virtual RID world_boundary_shape_create() override { return RID(); }
+ virtual RID separation_ray_shape_create() override { return RID(); }
+ virtual RID sphere_shape_create() override { return RID(); }
+ virtual RID box_shape_create() override { return RID(); }
+ virtual RID capsule_shape_create() override { return RID(); }
+ virtual RID cylinder_shape_create() override { return RID(); }
+ virtual RID convex_polygon_shape_create() override { return RID(); }
+ virtual RID concave_polygon_shape_create() override { return RID(); }
+ virtual RID heightmap_shape_create() override { return RID(); }
+ virtual RID custom_shape_create() override { return RID(); }
+
+ virtual void shape_set_data(RID p_shape, const Variant &p_data) override {}
+ virtual void shape_set_custom_solver_bias(RID p_shape, real_t p_bias) override {}
+
+ virtual ShapeType shape_get_type(RID p_shape) const override { return SHAPE_SPHERE; }
+ virtual Variant shape_get_data(RID p_shape) const override { return Variant(); }
+
+ virtual void shape_set_margin(RID p_shape, real_t p_margin) override {}
+ virtual real_t shape_get_margin(RID p_shape) const override { return 0; }
+
+ virtual real_t shape_get_custom_solver_bias(RID p_shape) const override { return 0; }
+
+ /* SPACE API */
+
+ virtual RID space_create() override { return RID(); }
+ virtual void space_set_active(RID p_space, bool p_active) override {}
+ virtual bool space_is_active(RID p_space) const override { return false; }
+
+ virtual void space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) override {}
+ virtual real_t space_get_param(RID p_space, SpaceParameter p_param) const override { return 0; }
+
+ virtual PhysicsDirectSpaceState3D *space_get_direct_state(RID p_space) override { return space_state_dummy; }
+
+ virtual void space_set_debug_contacts(RID p_space, int p_max_contacts) override {}
+ virtual Vector<Vector3> space_get_contacts(RID p_space) const override { return Vector<Vector3>(); }
+ virtual int space_get_contact_count(RID p_space) const override { return 0; }
+
+ /* AREA API */
+
+ virtual RID area_create() override { return RID(); }
+
+ virtual void area_set_space(RID p_area, RID p_space) override {}
+ virtual RID area_get_space(RID p_area) const override { return RID(); }
+
+ virtual void area_add_shape(RID p_area, RID p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false) override {}
+ virtual void area_set_shape(RID p_area, int p_shape_idx, RID p_shape) override {}
+ virtual void area_set_shape_transform(RID p_area, int p_shape_idx, const Transform3D &p_transform) override {}
+
+ virtual int area_get_shape_count(RID p_area) const override { return 0; }
+ virtual RID area_get_shape(RID p_area, int p_shape_idx) const override { return RID(); }
+ virtual Transform3D area_get_shape_transform(RID p_area, int p_shape_idx) const override { return Transform3D(); }
+
+ virtual void area_remove_shape(RID p_area, int p_shape_idx) override {}
+ virtual void area_clear_shapes(RID p_area) override {}
+
+ virtual void area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) override {}
+
+ virtual void area_attach_object_instance_id(RID p_area, ObjectID p_id) override {}
+ virtual ObjectID area_get_object_instance_id(RID p_area) const override { return ObjectID(); }
+
+ virtual void area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) override {}
+ virtual void area_set_transform(RID p_area, const Transform3D &p_transform) override {}
+
+ virtual Variant area_get_param(RID p_parea, AreaParameter p_param) const override { return Variant(); }
+ virtual Transform3D area_get_transform(RID p_area) const override { return Transform3D(); }
+
+ virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) override {}
+ virtual uint32_t area_get_collision_layer(RID p_area) const override { return 0; }
+
+ virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override {}
+ virtual uint32_t area_get_collision_mask(RID p_area) const override { return 0; }
+
+ virtual void area_set_monitorable(RID p_area, bool p_monitorable) override {}
+
+ virtual void area_set_monitor_callback(RID p_area, const Callable &p_callback) override {}
+ virtual void area_set_area_monitor_callback(RID p_area, const Callable &p_callback) override {}
+
+ virtual void area_set_ray_pickable(RID p_area, bool p_enable) override {}
+
+ /* BODY API */
+
+ virtual RID body_create() override { return RID(); }
+
+ virtual void body_set_space(RID p_body, RID p_space) override {}
+ virtual RID body_get_space(RID p_body) const override { return RID(); }
+
+ virtual void body_set_mode(RID p_body, BodyMode p_mode) override {}
+ virtual BodyMode body_get_mode(RID p_body) const override { return BodyMode::BODY_MODE_STATIC; }
+
+ virtual void body_add_shape(RID p_body, RID p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false) override {}
+ virtual void body_set_shape(RID p_body, int p_shape_idx, RID p_shape) override {}
+ virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform3D &p_transform) override {}
+
+ virtual int body_get_shape_count(RID p_body) const override { return 0; }
+ virtual RID body_get_shape(RID p_body, int p_shape_idx) const override { return RID(); }
+ virtual Transform3D body_get_shape_transform(RID p_body, int p_shape_idx) const override { return Transform3D(); }
+
+ virtual void body_remove_shape(RID p_body, int p_shape_idx) override {}
+ virtual void body_clear_shapes(RID p_body) override {}
+
+ virtual void body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) override {}
+
+ virtual void body_attach_object_instance_id(RID p_body, ObjectID p_id) override {}
+ virtual ObjectID body_get_object_instance_id(RID p_body) const override { return ObjectID(); }
+
+ virtual void body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) override {}
+ virtual bool body_is_continuous_collision_detection_enabled(RID p_body) const override { return false; }
+
+ virtual void body_set_collision_layer(RID p_body, uint32_t p_layer) override {}
+ virtual uint32_t body_get_collision_layer(RID p_body) const override { return 0; }
+
+ virtual void body_set_collision_mask(RID p_body, uint32_t p_mask) override {}
+ virtual uint32_t body_get_collision_mask(RID p_body) const override { return 0; }
+
+ virtual void body_set_collision_priority(RID p_body, real_t p_priority) override {}
+ virtual real_t body_get_collision_priority(RID p_body) const override { return 0; }
+
+ virtual void body_set_user_flags(RID p_body, uint32_t p_flags) override {}
+ virtual uint32_t body_get_user_flags(RID p_body) const override { return 0; }
+
+ virtual void body_set_param(RID p_body, BodyParameter p_param, const Variant &p_value) override {}
+ virtual Variant body_get_param(RID p_body, BodyParameter p_param) const override { return Variant(); }
+
+ virtual void body_reset_mass_properties(RID p_body) override {}
+
+ virtual void body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) override {}
+ virtual Variant body_get_state(RID p_body, BodyState p_state) const override { return Variant(); }
+
+ virtual void body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) override {}
+ virtual void body_apply_impulse(RID p_body, const Vector3 &p_impulse, const Vector3 &p_position = Vector3()) override {}
+ virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) override {}
+
+ virtual void body_apply_central_force(RID p_body, const Vector3 &p_force) override {}
+ virtual void body_apply_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position = Vector3()) override {}
+ virtual void body_apply_torque(RID p_body, const Vector3 &p_torque) override {}
+
+ virtual void body_add_constant_central_force(RID p_body, const Vector3 &p_force) override {}
+ virtual void body_add_constant_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position = Vector3()) override {}
+ virtual void body_add_constant_torque(RID p_body, const Vector3 &p_torque) override {}
+
+ virtual void body_set_constant_force(RID p_body, const Vector3 &p_force) override {}
+ virtual Vector3 body_get_constant_force(RID p_body) const override { return Vector3(); }
+
+ virtual void body_set_constant_torque(RID p_body, const Vector3 &p_torque) override {}
+ virtual Vector3 body_get_constant_torque(RID p_body) const override { return Vector3(); }
+
+ virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) override {}
+
+ virtual void body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) override {}
+ virtual bool body_is_axis_locked(RID p_body, BodyAxis p_axis) const override { return false; }
+
+ virtual void body_add_collision_exception(RID p_body, RID p_body_b) override {}
+ virtual void body_remove_collision_exception(RID p_body, RID p_body_b) override {}
+ virtual void body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) override {}
+
+ virtual void body_set_max_contacts_reported(RID p_body, int p_contacts) override {}
+ virtual int body_get_max_contacts_reported(RID p_body) const override { return 0; }
+
+ virtual void body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) override {}
+ virtual real_t body_get_contacts_reported_depth_threshold(RID p_body) const override { return 0; }
+
+ virtual void body_set_omit_force_integration(RID p_body, bool p_omit) override {}
+ virtual bool body_is_omitting_force_integration(RID p_body) const override { return false; }
+
+ virtual void body_set_state_sync_callback(RID p_body, const Callable &p_callable) override {}
+ virtual void body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata = Variant()) override {}
+
+ virtual void body_set_ray_pickable(RID p_body, bool p_enable) override {}
+
+ virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override { return body_state_dummy; }
+
+ virtual bool body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result = nullptr) override { return false; }
+
+ /* SOFT BODY */
+
+ virtual RID soft_body_create() override { return RID(); }
+
+ virtual void soft_body_update_rendering_server(RID p_body, PhysicsServer3DRenderingServerHandler *p_rendering_server_handler) override {}
+
+ virtual void soft_body_set_space(RID p_body, RID p_space) override {}
+ virtual RID soft_body_get_space(RID p_body) const override { return RID(); }
+
+ virtual void soft_body_set_mesh(RID p_body, RID p_mesh) override {}
+
+ virtual AABB soft_body_get_bounds(RID p_body) const override { return AABB(); }
+
+ virtual void soft_body_set_collision_layer(RID p_body, uint32_t p_layer) override {}
+ virtual uint32_t soft_body_get_collision_layer(RID p_body) const override { return 0; }
+
+ virtual void soft_body_set_collision_mask(RID p_body, uint32_t p_mask) override {}
+ virtual uint32_t soft_body_get_collision_mask(RID p_body) const override { return 0; }
+
+ virtual void soft_body_add_collision_exception(RID p_body, RID p_body_b) override {}
+ virtual void soft_body_remove_collision_exception(RID p_body, RID p_body_b) override {}
+ virtual void soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) override {}
+
+ virtual void soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) override {}
+ virtual Variant soft_body_get_state(RID p_body, BodyState p_state) const override { return Variant(); }
+
+ virtual void soft_body_set_transform(RID p_body, const Transform3D &p_transform) override {}
+
+ virtual void soft_body_set_ray_pickable(RID p_body, bool p_enable) override {}
+
+ virtual void soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) override {}
+ virtual int soft_body_get_simulation_precision(RID p_body) const override { return 0; }
+
+ virtual void soft_body_set_total_mass(RID p_body, real_t p_total_mass) override {}
+ virtual real_t soft_body_get_total_mass(RID p_body) const override { return 0; }
+
+ virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) override {}
+ virtual real_t soft_body_get_linear_stiffness(RID p_body) const override { return 0; }
+
+ virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) override {}
+ virtual real_t soft_body_get_pressure_coefficient(RID p_body) const override { return 0; }
+
+ virtual void soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) override {}
+ virtual real_t soft_body_get_damping_coefficient(RID p_body) const override { return 0; }
+
+ virtual void soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) override {}
+ virtual real_t soft_body_get_drag_coefficient(RID p_body) const override { return 0; }
+
+ virtual void soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) override {}
+ virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) const override { return Vector3(); }
+
+ virtual void soft_body_remove_all_pinned_points(RID p_body) override {}
+ virtual void soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) override {}
+ virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) const override { return false; }
+
+ /* JOINT API */
+
+ virtual RID joint_create() override { return RID(); }
+
+ virtual void joint_clear(RID p_joint) override {}
+
+ virtual JointType joint_get_type(RID p_joint) const override { return JointType::JOINT_TYPE_PIN; }
+
+ virtual void joint_set_solver_priority(RID p_joint, int p_priority) override {}
+ virtual int joint_get_solver_priority(RID p_joint) const override { return 0; }
+
+ virtual void joint_disable_collisions_between_bodies(RID p_joint, bool p_disable) override {}
+ virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const override { return false; }
+
+ virtual void joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override {}
+
+ virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) override {}
+ virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const override { return 0; }
+
+ virtual void pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) override {}
+ virtual Vector3 pin_joint_get_local_a(RID p_joint) const override { return Vector3(); }
+
+ virtual void pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) override {}
+ virtual Vector3 pin_joint_get_local_b(RID p_joint) const override { return Vector3(); }
+
+ virtual void joint_make_hinge(RID p_joint, RID p_body_A, const Transform3D &p_hinge_A, RID p_body_B, const Transform3D &p_hinge_B) override {}
+ virtual void joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) override {}
+
+ virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) override {}
+ virtual real_t hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const override { return 0; }
+
+ virtual void hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_enabled) override {}
+ virtual bool hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const override { return false; }
+
+ virtual void joint_make_slider(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) override {}
+
+ virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) override {}
+ virtual real_t slider_joint_get_param(RID p_joint, SliderJointParam p_param) const override { return 0; }
+
+ virtual void joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) override {}
+
+ virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) override {}
+ virtual real_t cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const override { return 0; }
+
+ virtual void joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) override {}
+
+ virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param, real_t p_value) override {}
+ virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param) const override { return 0; }
+
+ virtual void generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag, bool p_enable) override {}
+ virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag) const override { return false; }
+
+ /* MISC */
+
+ virtual void free(RID p_rid) override {}
+
+ virtual void set_active(bool p_active) override {}
+ virtual void init() override {
+ space_state_dummy = memnew(PhysicsDirectSpaceState3DDummy);
+ body_state_dummy = memnew(PhysicsDirectBodyState3DDummy(space_state_dummy));
+ }
+ virtual void step(real_t p_step) override {}
+ virtual void sync() override {}
+ virtual void flush_queries() override {}
+ virtual void end_sync() override {}
+ virtual void finish() override {
+ memdelete(body_state_dummy);
+ memdelete(space_state_dummy);
+ }
+
+ virtual bool is_flushing_queries() const override { return false; }
+
+ virtual int get_process_info(ProcessInfo p_info) override { return 0; }
+};
+
+#endif // PHYSICS_SERVER_3D_DUMMY_H
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index fc2aae10c7..b23c77aa0a 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -89,8 +89,8 @@
// 3D physics and navigation (3D navigation is needed for 2D).
#include "navigation_server_3d.h"
#ifndef _3D_DISABLED
-#include "physics_3d/godot_physics_server_3d.h"
#include "physics_server_3d.h"
+#include "physics_server_3d_dummy.h"
#include "physics_server_3d_wrap_mt.h"
#include "servers/extensions/physics_server_3d_extension.h"
#include "xr/xr_body_tracker.h"
@@ -106,16 +106,8 @@
ShaderTypes *shader_types = nullptr;
#ifndef _3D_DISABLED
-static PhysicsServer3D *_createGodotPhysics3DCallback() {
-#ifdef THREADS_ENABLED
- bool using_threads = GLOBAL_GET("physics/3d/run_on_separate_thread");
-#else
- bool using_threads = false;
-#endif
-
- PhysicsServer3D *physics_server_3d = memnew(GodotPhysicsServer3D(using_threads));
-
- return memnew(PhysicsServer3DWrapMT(physics_server_3d, using_threads));
+static PhysicsServer3D *_create_dummy_physics_server_3d() {
+ return memnew(PhysicsServer3DDummy);
}
#endif // _3D_DISABLED
@@ -323,8 +315,7 @@ void register_server_types() {
GLOBAL_DEF(PropertyInfo(Variant::STRING, PhysicsServer3DManager::setting_property_name, PROPERTY_HINT_ENUM, "DEFAULT"), "DEFAULT");
- PhysicsServer3DManager::get_singleton()->register_server("GodotPhysics3D", callable_mp_static(_createGodotPhysics3DCallback));
- PhysicsServer3DManager::get_singleton()->set_default_server("GodotPhysics3D");
+ PhysicsServer3DManager::get_singleton()->register_server("Dummy", callable_mp_static(_create_dummy_physics_server_3d));
GDREGISTER_ABSTRACT_CLASS(XRInterface);
GDREGISTER_CLASS(XRVRS);
diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h
index 1a566b518d..6da7446e69 100644
--- a/servers/rendering/dummy/storage/texture_storage.h
+++ b/servers/rendering/dummy/storage/texture_storage.h
@@ -90,12 +90,14 @@ public:
};
virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override {}
virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override {}
+ virtual void texture_external_initialize(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) override {}
virtual void texture_proxy_initialize(RID p_texture, RID p_base) override {} //all slices, then all the mipmaps, must be coherent
virtual RID texture_create_from_native_handle(RS::TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers = 1, RS::TextureLayeredType p_layered_type = RS::TEXTURE_LAYERED_2D_ARRAY) override { return RID(); }
virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override {}
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override {}
+ virtual void texture_external_update(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) override {}
virtual void texture_proxy_update(RID p_proxy, RID p_base) override {}
//these two APIs can be used together or in combination with the others.
diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp
index e6a745d3b4..39c3e9b168 100644
--- a/servers/rendering/renderer_rd/shader_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_rd.cpp
@@ -200,6 +200,8 @@ void ShaderRD::_build_variant_code(StringBuilder &builder, uint32_t p_variant, c
#endif
builder.append(String("#define RENDER_DRIVER_") + OS::get_singleton()->get_current_rendering_driver_name().to_upper() + "\n");
+ builder.append("#define samplerExternalOES sampler2D\n");
+ builder.append("#define textureExternalOES texture2D\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/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl
index 5e19c24246..704aafdfa5 100644
--- a/servers/rendering/renderer_rd/shaders/canvas.glsl
+++ b/servers/rendering/renderer_rd/shaders/canvas.glsl
@@ -214,6 +214,8 @@ void main() {
color_interp = color;
+ vertex = (canvas_data.canvas_transform * vec4(vertex, 0.0, 1.0)).xy;
+
if (canvas_data.use_pixel_snap) {
vertex = floor(vertex + 0.5);
// precision issue on some hardware creates artifacts within texture
@@ -221,8 +223,6 @@ void main() {
uv += 1e-5;
}
- vertex = (canvas_data.canvas_transform * vec4(vertex, 0.0, 1.0)).xy;
-
vertex_interp = vertex;
uv_interp = uv;
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
index 9f390c99f9..3bfc1bd15c 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
@@ -1639,6 +1639,7 @@ void MaterialStorage::global_shader_parameters_load_settings(bool p_load_texture
"sampler2DArray",
"sampler3D",
"samplerCube",
+ "samplerExternalOES",
};
RS::GlobalShaderParameterType gvtype = RS::GLOBAL_VAR_TYPE_MAX;
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h
index c885ad52d1..0025fc5ab7 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h
@@ -128,7 +128,7 @@ private:
h = hash_murmur3_one_32(p_val.layers, h);
h = hash_murmur3_one_32(p_val.mipmap, h);
h = hash_murmur3_one_32(p_val.mipmaps, h);
- h = hash_murmur3_one_32(p_val.texture_view.format_override);
+ h = hash_murmur3_one_32(p_val.texture_view.format_override, h);
h = hash_murmur3_one_32(p_val.texture_view.swizzle_r, h);
h = hash_murmur3_one_32(p_val.texture_view.swizzle_g, h);
h = hash_murmur3_one_32(p_val.texture_view.swizzle_b, h);
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
index 81ab384edc..e5a8dbb9b2 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
@@ -1087,6 +1087,9 @@ void TextureStorage::texture_3d_initialize(RID p_texture, Image::Format p_format
texture_owner.initialize_rid(p_texture, texture);
}
+void TextureStorage::texture_external_initialize(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) {
+}
+
void TextureStorage::texture_proxy_initialize(RID p_texture, RID p_base) {
Texture *tex = texture_owner.get_or_null(p_base);
ERR_FAIL_NULL(tex);
@@ -1361,6 +1364,9 @@ void TextureStorage::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &
RD::get_singleton()->texture_update(tex->rd_texture, 0, all_data);
}
+void TextureStorage::texture_external_update(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) {
+}
+
void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) {
Texture *tex = texture_owner.get_or_null(p_texture);
ERR_FAIL_NULL(tex);
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
index d352690fff..9de4ff7b6b 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
@@ -491,12 +491,14 @@ public:
virtual void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) override;
virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override;
virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override;
+ virtual void texture_external_initialize(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) override;
virtual void texture_proxy_initialize(RID p_texture, RID p_base) override; //all slices, then all the mipmaps, must be coherent
virtual RID texture_create_from_native_handle(RS::TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers = 1, RS::TextureLayeredType p_layered_type = RS::TEXTURE_LAYERED_2D_ARRAY) override;
virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override;
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override;
+ virtual void texture_external_update(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) override;
virtual void texture_proxy_update(RID p_proxy, RID p_base) override;
//these two APIs can be used together or in combination with the others.
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index fb4f4aa756..2dcdc3f254 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -162,6 +162,17 @@ public:
return ret; \
}
+#define FUNCRIDTEX3(m_type, m_type1, m_type2, m_type3) \
+ virtual RID m_type##_create(m_type1 p1, m_type2 p2, m_type3 p3) override { \
+ RID ret = RSG::texture_storage->texture_allocate(); \
+ if (Thread::get_caller_id() == server_thread || RSG::texture_storage->can_create_resources_async()) { \
+ RSG::texture_storage->m_type##_initialize(ret, p1, p2, p3); \
+ } else { \
+ command_queue.push(RSG::texture_storage, &RendererTextureStorage::m_type##_initialize, ret, p1, p2, p3); \
+ } \
+ return ret; \
+ }
+
#define FUNCRIDTEX6(m_type, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \
virtual RID m_type##_create(m_type1 p1, m_type2 p2, m_type3 p3, m_type4 p4, m_type5 p5, m_type6 p6) override { \
RID ret = RSG::texture_storage->texture_allocate(); \
@@ -177,6 +188,7 @@ public:
FUNCRIDTEX1(texture_2d, const Ref<Image> &)
FUNCRIDTEX2(texture_2d_layered, const Vector<Ref<Image>> &, TextureLayeredType)
FUNCRIDTEX6(texture_3d, Image::Format, int, int, int, bool, const Vector<Ref<Image>> &)
+ FUNCRIDTEX3(texture_external, int, int, uint64_t)
FUNCRIDTEX1(texture_proxy, RID)
// Called directly, not through the command queue.
@@ -187,6 +199,7 @@ public:
//these go through command queue if they are in another thread
FUNC3(texture_2d_update, RID, const Ref<Image> &, int)
FUNC2(texture_3d_update, RID, const Vector<Ref<Image>> &)
+ FUNC4(texture_external_update, RID, int, int, uint64_t)
FUNC2(texture_proxy_update, RID, RID)
//these also go pass-through
diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp
index 5f97fa0c9b..3a0b9cf158 100644
--- a/servers/rendering/shader_compiler.cpp
+++ b/servers/rendering/shader_compiler.cpp
@@ -113,6 +113,8 @@ static int _get_datatype_alignment(SL::DataType p_type) {
return 16;
case SL::TYPE_SAMPLERCUBEARRAY:
return 16;
+ case SL::TYPE_SAMPLEREXT:
+ return 16;
case SL::TYPE_STRUCT:
return 0;
case SL::TYPE_MAX: {
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index 5a3c5d2fd0..14bd3841df 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -315,6 +315,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
{ TK_TYPE_USAMPLER3D, "usampler3D", KCF_SAMPLER_DATATYPE, {}, {} },
{ TK_TYPE_SAMPLERCUBE, "samplerCube", KCF_SAMPLER_DATATYPE, {}, {} },
{ TK_TYPE_SAMPLERCUBEARRAY, "samplerCubeArray", KCF_SAMPLER_DATATYPE, {}, {} },
+ { TK_TYPE_SAMPLEREXT, "samplerExternalOES", KCF_SAMPLER_DATATYPE, {}, {} },
// interpolation qualifiers
@@ -1027,7 +1028,8 @@ bool ShaderLanguage::is_token_datatype(TokenType p_type) {
p_type == TK_TYPE_ISAMPLER3D ||
p_type == TK_TYPE_USAMPLER3D ||
p_type == TK_TYPE_SAMPLERCUBE ||
- p_type == TK_TYPE_SAMPLERCUBEARRAY);
+ p_type == TK_TYPE_SAMPLERCUBEARRAY ||
+ p_type == TK_TYPE_SAMPLEREXT);
}
ShaderLanguage::DataType ShaderLanguage::get_token_datatype(TokenType p_type) {
@@ -1162,6 +1164,8 @@ String ShaderLanguage::get_datatype_name(DataType p_type) {
return "samplerCube";
case TYPE_SAMPLERCUBEARRAY:
return "samplerCubeArray";
+ case TYPE_SAMPLEREXT:
+ return "samplerExternalOES";
case TYPE_STRUCT:
return "struct";
case TYPE_MAX:
@@ -3169,6 +3173,8 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
{ "texture", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
{ "texture", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
+ { "texture", TYPE_VEC4, { TYPE_SAMPLEREXT, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "texture", TYPE_VEC4, { TYPE_SAMPLEREXT, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
// textureProj
@@ -4482,7 +4488,8 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<Scalar> &p_value,
case ShaderLanguage::TYPE_USAMPLER2D:
case ShaderLanguage::TYPE_USAMPLER3D:
case ShaderLanguage::TYPE_SAMPLERCUBE:
- case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: {
+ case ShaderLanguage::TYPE_SAMPLERCUBEARRAY:
+ case ShaderLanguage::TYPE_SAMPLEREXT: {
// Texture types, likely not relevant here.
break;
}
@@ -4707,6 +4714,17 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
pi.hint_string = "Texture3D";
}
} break;
+ case ShaderLanguage::TYPE_SAMPLEREXT: {
+ if (p_uniform.array_size > 0) {
+ pi.type = Variant::ARRAY;
+ pi.hint = PROPERTY_HINT_ARRAY_TYPE;
+ pi.hint_string = MAKE_RESOURCE_TYPE_HINT("ExternalTexture");
+ } else {
+ pi.type = Variant::OBJECT;
+ pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pi.hint_string = "ExternalTexture";
+ }
+ } break;
case ShaderLanguage::TYPE_STRUCT: {
// FIXME: Implement this.
} break;
@@ -4780,6 +4798,8 @@ uint32_t ShaderLanguage::get_datatype_size(ShaderLanguage::DataType p_type) {
return 16;
case TYPE_SAMPLERCUBEARRAY:
return 16;
+ case TYPE_SAMPLEREXT:
+ return 16;
case TYPE_STRUCT:
return 0;
case TYPE_MAX: {
@@ -4921,6 +4941,7 @@ ShaderLanguage::DataType ShaderLanguage::get_scalar_type(DataType p_type) {
TYPE_UINT,
TYPE_FLOAT,
TYPE_FLOAT,
+ TYPE_FLOAT,
TYPE_VOID,
};
@@ -4963,6 +4984,7 @@ int ShaderLanguage::get_cardinality(DataType p_type) {
1,
1,
1,
+ 1,
};
static_assert(sizeof(cardinality_table) / sizeof(*cardinality_table) == TYPE_MAX);
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index b0d579dfe7..48df77f6bb 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -91,6 +91,7 @@ public:
TK_TYPE_USAMPLER3D,
TK_TYPE_SAMPLERCUBE,
TK_TYPE_SAMPLERCUBEARRAY,
+ TK_TYPE_SAMPLEREXT,
TK_INTERPOLATION_FLAT,
TK_INTERPOLATION_SMOOTH,
TK_CONST,
@@ -235,6 +236,7 @@ public:
TYPE_USAMPLER3D,
TYPE_SAMPLERCUBE,
TYPE_SAMPLERCUBEARRAY,
+ TYPE_SAMPLEREXT,
TYPE_STRUCT,
TYPE_MAX
};
diff --git a/servers/rendering/storage/texture_storage.h b/servers/rendering/storage/texture_storage.h
index 6e1cb9eb7f..fd17b052ee 100644
--- a/servers/rendering/storage/texture_storage.h
+++ b/servers/rendering/storage/texture_storage.h
@@ -69,12 +69,14 @@ public:
virtual void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) = 0;
virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) = 0;
virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0;
+ virtual void texture_external_initialize(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) = 0;
virtual void texture_proxy_initialize(RID p_texture, RID p_base) = 0; //all slices, then all the mipmaps, must be coherent
virtual RID texture_create_from_native_handle(RS::TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers = 1, RS::TextureLayeredType p_layered_type = RS::TEXTURE_LAYERED_2D_ARRAY) = 0;
virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0;
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0;
+ virtual void texture_external_update(RID p_proxy, int p_width, int p_height, uint64_t p_external_buffer) = 0;
virtual void texture_proxy_update(RID p_proxy, RID p_base) = 0;
//these two APIs can be used together or in combination with the others.
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index a1c05fa2e7..0ad56961c0 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -3405,6 +3405,7 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_SAMPLER2DARRAY);
BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_SAMPLER3D);
BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_SAMPLERCUBE);
+ BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_SAMPLEREXT);
BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_MAX);
/* Free */
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 2b45b73f09..a130ae0ba2 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -137,12 +137,14 @@ public:
virtual RID texture_2d_create(const Ref<Image> &p_image) = 0;
virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, TextureLayeredType p_layered_type) = 0;
virtual RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0; //all slices, then all the mipmaps, must be coherent
+ virtual RID texture_external_create(int p_width, int p_height, uint64_t p_external_buffer = 0) = 0;
virtual RID texture_proxy_create(RID p_base) = 0;
virtual RID texture_create_from_native_handle(TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers = 1, TextureLayeredType p_layered_type = TEXTURE_LAYERED_2D_ARRAY) = 0;
virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0;
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0;
+ virtual void texture_external_update(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer = 0) = 0;
virtual void texture_proxy_update(RID p_texture, RID p_proxy_to) = 0;
// These two APIs can be used together or in combination with the others.
@@ -1647,6 +1649,7 @@ public:
GLOBAL_VAR_TYPE_SAMPLER2DARRAY,
GLOBAL_VAR_TYPE_SAMPLER3D,
GLOBAL_VAR_TYPE_SAMPLERCUBE,
+ GLOBAL_VAR_TYPE_SAMPLEREXT,
GLOBAL_VAR_TYPE_MAX
};
diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h
index 9ec1b812df..ef630ad4f7 100644
--- a/tests/scene/test_code_edit.h
+++ b/tests/scene/test_code_edit.h
@@ -4779,6 +4779,31 @@ TEST_CASE("[SceneTree][CodeEdit] text manipulation") {
CHECK(code_edit->get_caret_column(3) == 0);
}
+ SUBCASE("[SceneTree][CodeEdit] cut when empty selection clipboard disabled") {
+ DisplayServerMock *DS = (DisplayServerMock *)(DisplayServer::get_singleton());
+ code_edit->set_empty_selection_clipboard_enabled(false);
+ DS->clipboard_set("");
+
+ code_edit->set_text("this is\nsome\n");
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(6);
+ MessageQueue::get_singleton()->flush();
+ SIGNAL_DISCARD("text_set");
+ SIGNAL_DISCARD("text_changed");
+ SIGNAL_DISCARD("lines_edited_from");
+ SIGNAL_DISCARD("caret_changed");
+
+ code_edit->cut();
+ MessageQueue::get_singleton()->flush();
+ CHECK(DS->clipboard_get() == "");
+ CHECK(code_edit->get_text() == "this is\nsome\n");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 6);
+ SIGNAL_CHECK_FALSE("caret_changed");
+ SIGNAL_CHECK_FALSE("text_changed");
+ SIGNAL_CHECK_FALSE("lines_edited_from");
+ }
+
SUBCASE("[SceneTree][CodeEdit] new line") {
// Add a new line.
code_edit->set_text("test new line");
diff --git a/tests/scene/test_text_edit.h b/tests/scene/test_text_edit.h
index 46a5046b21..c41eebdf3a 100644
--- a/tests/scene/test_text_edit.h
+++ b/tests/scene/test_text_edit.h
@@ -3585,6 +3585,54 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
SIGNAL_CHECK_FALSE("lines_edited_from");
}
+ SUBCASE("[TextEdit] cut when empty selection clipboard disabled") {
+ text_edit->set_empty_selection_clipboard_enabled(false);
+ DS->clipboard_set("");
+
+ text_edit->set_text("this is\nsome\n");
+ text_edit->set_caret_line(0);
+ text_edit->set_caret_column(6);
+ MessageQueue::get_singleton()->flush();
+ SIGNAL_DISCARD("text_set");
+ SIGNAL_DISCARD("text_changed");
+ SIGNAL_DISCARD("lines_edited_from");
+ SIGNAL_DISCARD("caret_changed");
+
+ text_edit->cut();
+ MessageQueue::get_singleton()->flush();
+ CHECK(DS->clipboard_get() == "");
+ CHECK(text_edit->get_text() == "this is\nsome\n");
+ CHECK(text_edit->get_caret_line() == 0);
+ CHECK(text_edit->get_caret_column() == 6);
+ SIGNAL_CHECK_FALSE("caret_changed");
+ SIGNAL_CHECK_FALSE("text_changed");
+ SIGNAL_CHECK_FALSE("lines_edited_from");
+ }
+
+ SUBCASE("[TextEdit] copy when empty selection clipboard disabled") {
+ text_edit->set_empty_selection_clipboard_enabled(false);
+ DS->clipboard_set("");
+
+ text_edit->set_text("this is\nsome\n");
+ text_edit->set_caret_line(0);
+ text_edit->set_caret_column(6);
+ MessageQueue::get_singleton()->flush();
+ SIGNAL_DISCARD("text_set");
+ SIGNAL_DISCARD("text_changed");
+ SIGNAL_DISCARD("lines_edited_from");
+ SIGNAL_DISCARD("caret_changed");
+
+ text_edit->copy();
+ MessageQueue::get_singleton()->flush();
+ CHECK(DS->clipboard_get() == "");
+ CHECK(text_edit->get_text() == "this is\nsome\n");
+ CHECK(text_edit->get_caret_line() == 0);
+ CHECK(text_edit->get_caret_column() == 6);
+ SIGNAL_CHECK_FALSE("caret_changed");
+ SIGNAL_CHECK_FALSE("text_changed");
+ SIGNAL_CHECK_FALSE("lines_edited_from");
+ }
+
SIGNAL_UNWATCH(text_edit, "text_set");
SIGNAL_UNWATCH(text_edit, "text_changed");
SIGNAL_UNWATCH(text_edit, "lines_edited_from");
diff --git a/tests/test_main.cpp b/tests/test_main.cpp
index 949e4f0b33..3c184ccc5d 100644
--- a/tests/test_main.cpp
+++ b/tests/test_main.cpp
@@ -176,6 +176,7 @@
#include "servers/physics_server_2d.h"
#ifndef _3D_DISABLED
#include "servers/physics_server_3d.h"
+#include "servers/physics_server_3d_dummy.h"
#endif // _3D_DISABLED
#include "servers/rendering/rendering_server_default.h"
@@ -290,6 +291,9 @@ struct GodotTestCaseListener : public doctest::IReporter {
#ifndef _3D_DISABLED
physics_server_3d = PhysicsServer3DManager::get_singleton()->new_default_server();
+ if (!physics_server_3d) {
+ physics_server_3d = memnew(PhysicsServer3DDummy);
+ }
physics_server_3d->init();
#endif // _3D_DISABLED
diff --git a/thirdparty/README.md b/thirdparty/README.md
index a6686c539a..4c47b91c8c 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -614,7 +614,7 @@ to solve some MSVC warnings. See the patches in the `patches` directory.
## miniupnpc
- Upstream: https://github.com/miniupnp/miniupnp
-- Version: 2.2.7 (d4d5ec7d48c093b37b2ea5d7171ede21ce9d7ff2, 2024)
+- Version: 2.2.8 (b55145ec095652289a59c33603f3abafee898273, 2024)
- License: BSD-3-Clause
Files extracted from upstream source:
diff --git a/thirdparty/miniupnpc/include/miniupnpc.h b/thirdparty/miniupnpc/include/miniupnpc.h
index 808c6ad975..fd951a0836 100644
--- a/thirdparty/miniupnpc/include/miniupnpc.h
+++ b/thirdparty/miniupnpc/include/miniupnpc.h
@@ -1,9 +1,9 @@
-/* $Id: miniupnpc.h,v 1.63 2024/01/04 00:45:17 nanard Exp $ */
+/* $Id: miniupnpc.h,v 1.66 2024/06/08 22:13:14 nanard Exp $ */
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* Project: miniupnp
* http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
* Author: Thomas Bernard
- * Copyright (c) 2005-2022 Thomas Bernard
+ * Copyright (c) 2005-2024 Thomas Bernard
* This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */
#ifndef MINIUPNPC_H_INCLUDED
@@ -20,8 +20,8 @@
#define UPNPDISCOVER_MEMORY_ERROR (-102)
/* versions : */
-#define MINIUPNPC_VERSION "2.2.6"
-#define MINIUPNPC_API_VERSION 17
+#define MINIUPNPC_VERSION "2.2.8"
+#define MINIUPNPC_API_VERSION 18
/* Source port:
Using "1" as an alias for 1900 for backwards compatibility
@@ -108,9 +108,11 @@ struct UPNPUrls {
* return values :
* 0 = NO IGD found
* 1 = A valid connected IGD has been found
- * 2 = A valid IGD has been found but it reported as
+ * 2 = A valid connected IGD has been found but its
+ * IP address is reserved (non routable)
+ * 3 = A valid IGD has been found but it reported as
* not connected
- * 3 = an UPnP device has been found but was not recognized as an IGD
+ * 4 = an UPnP device has been found but was not recognized as an IGD
*
* In any non zero return case, the urls and data structures
* passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
@@ -119,8 +121,9 @@ struct UPNPUrls {
MINIUPNP_LIBSPEC int
UPNP_GetValidIGD(struct UPNPDev * devlist,
struct UPNPUrls * urls,
- struct IGDdatas * data,
- char * lanaddr, int lanaddrlen);
+ struct IGDdatas * data,
+ char * lanaddr, int lanaddrlen,
+ char * wanaddr, int wanaddrlen);
/* UPNP_GetIGDFromUrl()
* Used when skipping the discovery process.
diff --git a/thirdparty/miniupnpc/src/addr_is_reserved.c b/thirdparty/miniupnpc/src/addr_is_reserved.c
index 18c6424201..145b504823 100644
--- a/thirdparty/miniupnpc/src/addr_is_reserved.c
+++ b/thirdparty/miniupnpc/src/addr_is_reserved.c
@@ -3,7 +3,7 @@
* Project : miniupnp
* Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
* Author : Thomas BERNARD
- * copyright (c) 2005-2021 Thomas Bernard
+ * copyright (c) 2005-2024 Thomas Bernard
* This software is subjet to the conditions detailed in the
* provided LICENSE file. */
#ifdef _WIN32
@@ -21,6 +21,9 @@ typedef unsigned long uint32_t;
#include <netinet/in.h>
#include <arpa/inet.h>
#endif /* _WIN32 */
+#ifdef DEBUG
+#include <stdio.h>
+#endif
/* List of IP address blocks which are private / reserved and therefore not suitable for public external IP addresses */
#define IP(a, b, c, d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d))
@@ -71,8 +74,12 @@ int addr_is_reserved(const char * addr_str)
address = ntohl(addr_n);
for (i = 0; i < sizeof(reserved)/sizeof(reserved[0]); ++i) {
- if ((address >> reserved[i].rmask) == (reserved[i].address >> reserved[i].rmask))
+ if ((address >> reserved[i].rmask) == (reserved[i].address >> reserved[i].rmask)) {
+#ifdef DEBUG
+ printf("IP address %s is reserved\n", addr_str);
+#endif
return 1;
+ }
}
return 0;
diff --git a/thirdparty/miniupnpc/src/minisoap.c b/thirdparty/miniupnpc/src/minisoap.c
index 903ac5ffc6..5c6bf01684 100644
--- a/thirdparty/miniupnpc/src/minisoap.c
+++ b/thirdparty/miniupnpc/src/minisoap.c
@@ -2,7 +2,7 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* Project : miniupnp
* Author : Thomas Bernard
- * Copyright (c) 2005-2023 Thomas Bernard
+ * Copyright (c) 2005-2024 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
*
@@ -83,7 +83,7 @@ int soapPostSubmit(SOCKET fd,
* Using HTTP/1.1 means we need to support chunked transfer-encoding :
* When using HTTP/1.1, the router "BiPAC 7404VNOX" always use chunked
* transfer encoding. */
- /* Connection: Close is normally there only in HTTP/1.1 but who knows */
+ /* Connection: close is normally there only in HTTP/1.1 but who knows */
portstr[0] = '\0';
if(port != 80)
snprintf(portstr, sizeof(portstr), ":%hu", port);
@@ -98,9 +98,8 @@ int soapPostSubmit(SOCKET fd,
"Content-Type: text/xml; charset=\"utf-8\"\r\n"
#endif
"SOAPAction: \"%s\"\r\n"
- "Connection: Close\r\n"
+ "Connection: close\r\n"
"Cache-Control: no-cache\r\n" /* ??? */
- "Pragma: no-cache\r\n"
"\r\n",
url, httpversion, host, portstr, bodysize, action);
if ((unsigned int)headerssize >= sizeof(headerbuf))
diff --git a/thirdparty/miniupnpc/src/minissdpc.c b/thirdparty/miniupnpc/src/minissdpc.c
index 98c5b37463..57cb99962e 100644
--- a/thirdparty/miniupnpc/src/minissdpc.c
+++ b/thirdparty/miniupnpc/src/minissdpc.c
@@ -1,9 +1,9 @@
-/* $Id: minissdpc.c,v 1.49 2021/05/13 11:00:36 nanard Exp $ */
+/* $Id: minissdpc.c,v 1.51 2024/05/16 00:12:05 nanard Exp $ */
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* Project : miniupnp
* Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
* Author : Thomas BERNARD
- * copyright (c) 2005-2021 Thomas Bernard
+ * copyright (c) 2005-2024 Thomas Bernard
* This software is subjet to the conditions detailed in the
* provided LICENCE file. */
#include <stdio.h>
@@ -548,7 +548,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[],
#ifdef _WIN32
unsigned long _ttl = (unsigned long)ttl;
#endif
- int linklocal = 1;
+ int linklocal = 0; /* try first with site-local multicast */
int sentok;
if(error)
@@ -1007,9 +1007,10 @@ ssdpDiscoverDevices(const char * const deviceTypes[],
/* switch linklocal flag */
if(linklocal) {
linklocal = 0;
- --deviceIndex;
} else {
+ /* try again with linklocal multicast */
linklocal = 1;
+ --deviceIndex;
}
}
}
diff --git a/thirdparty/miniupnpc/src/miniupnpc.c b/thirdparty/miniupnpc/src/miniupnpc.c
index 696af93237..9da1496b37 100644
--- a/thirdparty/miniupnpc/src/miniupnpc.c
+++ b/thirdparty/miniupnpc/src/miniupnpc.c
@@ -3,7 +3,7 @@
* Project : miniupnp
* Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
* Author : Thomas BERNARD
- * copyright (c) 2005-2021 Thomas Bernard
+ * copyright (c) 2005-2024 Thomas Bernard
* This software is subjet to the conditions detailed in the
* provided LICENSE file. */
#include <stdlib.h>
@@ -92,15 +92,15 @@ MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGD
#endif
}
-/* simpleUPnPcommand2 :
+/* simpleUPnPcommand :
* not so simple !
* return values :
* pointer - OK
* NULL - error */
-static char *
-simpleUPnPcommand2(SOCKET s, const char * url, const char * service,
- const char * action, struct UPNParg * args,
- int * bufsize, const char * httpversion)
+char *
+simpleUPnPcommand(int s, const char * url, const char * service,
+ const char * action, struct UPNParg * args,
+ int * bufsize)
{
char hostname[MAXHOSTNAMELEN+1];
unsigned short port = 0;
@@ -197,15 +197,15 @@ simpleUPnPcommand2(SOCKET s, const char * url, const char * service,
return NULL;
}
if(!parseURL(url, hostname, &port, &path, NULL)) return NULL;
- if(ISINVALID(s)) {
+ if(ISINVALID((SOCKET)s)) {
s = connecthostport(hostname, port, 0);
- if(ISINVALID(s)) {
+ if(ISINVALID((SOCKET)s)) {
/* failed to connect */
return NULL;
}
}
- n = soapPostSubmit(s, path, hostname, port, soapact, soapbody, httpversion);
+ n = soapPostSubmit(s, path, hostname, port, soapact, soapbody, "1.1");
if(n<=0) {
#ifdef DEBUG
printf("Error sending SOAP request\n");
@@ -229,33 +229,6 @@ simpleUPnPcommand2(SOCKET s, const char * url, const char * service,
return buf;
}
-/* simpleUPnPcommand :
- * not so simple !
- * return values :
- * pointer - OK
- * NULL - error */
-char *
-simpleUPnPcommand(int s, const char * url, const char * service,
- const char * action, struct UPNParg * args,
- int * bufsize)
-{
- char * buf;
-
-#if 1
- buf = simpleUPnPcommand2((SOCKET)s, url, service, action, args, bufsize, "1.1");
-#else
- buf = simpleUPnPcommand2((SOCKET)s, url, service, action, args, bufsize, "1.0");
- if (!buf || *bufsize == 0)
- {
-#if DEBUG
- printf("Error or no result from SOAP request; retrying with HTTP/1.1\n");
-#endif
- buf = simpleUPnPcommand2((SOCKET)s, url, service, action, args, bufsize, "1.1");
- }
-#endif
- return buf;
-}
-
/* upnpDiscoverDevices() :
* return a chained list of all devices found or NULL if
* no devices was found.
@@ -534,9 +507,11 @@ UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data)
* -1 = Internal error
* 0 = NO IGD found
* 1 = A valid connected IGD has been found
- * 2 = A valid IGD has been found but it reported as
+ * 2 = A valid connected IGD has been found but its
+ * IP address is reserved (non routable)
+ * 3 = A valid IGD has been found but it reported as
* not connected
- * 3 = an UPnP device has been found but was not recognized as an IGD
+ * 4 = an UPnP device has been found but was not recognized as an IGD
*
* In any positive non zero return case, the urls and data structures
* passed as parameters are set. Don't forget to call FreeUPNPUrls(urls) to
@@ -545,11 +520,13 @@ UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data)
MINIUPNP_LIBSPEC int
UPNP_GetValidIGD(struct UPNPDev * devlist,
struct UPNPUrls * urls,
- struct IGDdatas * data,
- char * lanaddr, int lanaddrlen)
+ struct IGDdatas * data,
+ char * lanaddr, int lanaddrlen,
+ char * wanaddr, int wanaddrlen)
{
struct xml_desc {
char lanaddr[40];
+ char wanaddr[40];
char * xml;
int size;
int is_igd;
@@ -557,8 +534,8 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
struct UPNPDev * dev;
int ndev = 0;
int i;
- int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
- char extIpAddr[16];
+ int state = -1; /* state 1 : IGD connected. State 2 : connected with reserved IP.
+ * State 3 : IGD. State 4 : anything */
int status_code = -1;
if(!devlist)
@@ -602,7 +579,7 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
}
}
/* iterate the list to find a device depending on state */
- for(state = 1; state <= 3; state++)
+ for(state = 1; state <= 4; state++)
{
for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
{
@@ -611,14 +588,14 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
memset(data, 0, sizeof(struct IGDdatas));
memset(urls, 0, sizeof(struct UPNPUrls));
parserootdesc(desc[i].xml, desc[i].size, data);
- if(desc[i].is_igd || state >= 3 )
+ if(desc[i].is_igd || state >= 4 )
{
int is_connected;
GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
- /* in state 2 and 3 we don't test if device is connected ! */
- if(state >= 2)
+ /* in state 3 and 4 we don't test if device is connected ! */
+ if(state >= 3)
goto free_and_return;
is_connected = UPNPIGD_IsConnected(urls, data);
#ifdef DEBUG
@@ -626,9 +603,11 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
urls->controlURL, is_connected);
#endif
/* checks that status is connected AND there is a external IP address assigned */
- if(is_connected &&
- (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) {
- if(!addr_is_reserved(extIpAddr))
+ if(is_connected) {
+ if(state >= 2)
+ goto free_and_return;
+ if(UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, desc[i].wanaddr) == 0
+ && !addr_is_reserved(desc[i].wanaddr))
goto free_and_return;
}
FreeUPNPUrls(urls);
@@ -647,9 +626,11 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
printf("UPNPIGD_IsConnected(%s) = %d\n",
urls->controlURL, is_connected);
#endif
- if(is_connected &&
- (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) {
- if(!addr_is_reserved(extIpAddr))
+ if(is_connected) {
+ if(state >= 2)
+ goto free_and_return;
+ if(UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, desc[i].wanaddr) == 0
+ && !addr_is_reserved(desc[i].wanaddr))
goto free_and_return;
}
FreeUPNPUrls(urls);
@@ -661,8 +642,12 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
}
state = 0;
free_and_return:
- if (lanaddr != NULL && state >= 1 && state <= 3 && i < ndev)
- strncpy(lanaddr, desc[i].lanaddr, lanaddrlen);
+ if (state >= 1 && state <= 4 && i < ndev) {
+ if (lanaddr != NULL)
+ strncpy(lanaddr, desc[i].lanaddr, lanaddrlen);
+ if (wanaddr != NULL)
+ strncpy(wanaddr, desc[i].wanaddr, wanaddrlen);
+ }
for(i = 0; i < ndev; i++)
free(desc[i].xml);
free(desc);
diff --git a/thirdparty/miniupnpc/src/miniupnpcstrings.h b/thirdparty/miniupnpc/src/miniupnpcstrings.h
index f5730111af..d40c2455ba 100644
--- a/thirdparty/miniupnpc/src/miniupnpcstrings.h
+++ b/thirdparty/miniupnpc/src/miniupnpcstrings.h
@@ -2,7 +2,7 @@
#define MINIUPNPCSTRINGS_H_INCLUDED
#define OS_STRING "Godot Engine/1.0"
-#define MINIUPNPC_VERSION_STRING "2.2.7"
+#define MINIUPNPC_VERSION_STRING "2.2.8"
#if 0
/* according to "UPnP Device Architecture 1.0" */
diff --git a/thirdparty/miniupnpc/src/miniwget.c b/thirdparty/miniupnpc/src/miniwget.c
index e76a5e516b..a7a32dfdba 100644
--- a/thirdparty/miniupnpc/src/miniwget.c
+++ b/thirdparty/miniupnpc/src/miniwget.c
@@ -2,7 +2,7 @@
/* Project : miniupnp
* Website : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
* Author : Thomas Bernard
- * Copyright (c) 2005-2023 Thomas Bernard
+ * Copyright (c) 2005-2024 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */
@@ -443,9 +443,8 @@ miniwget3(const char * host,
len = snprintf(buf, sizeof(buf),
"GET %s HTTP/%s\r\n"
"Host: %s:%d\r\n"
- "Connection: Close\r\n"
+ "Connection: close\r\n"
"User-Agent: " OS_STRING " " UPNP_VERSION_STRING " MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
-
"\r\n",
path, httpversion, host, port);
if ((unsigned int)len >= sizeof(buf))
@@ -474,41 +473,6 @@ miniwget3(const char * host,
return content;
}
-/* miniwget2() :
- * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */
-static void *
-miniwget2(const char * host,
- unsigned short port, const char * path,
- int * size, char * addr_str, int addr_str_len,
- unsigned int scope_id, int * status_code)
-{
- char * respbuffer;
-
-#if 1
- respbuffer = miniwget3(host, port, path, size,
- addr_str, addr_str_len, "1.1",
- scope_id, status_code);
-#else
- respbuffer = miniwget3(host, port, path, size,
- addr_str, addr_str_len, "1.0",
- scope_id, status_code);
- if (*size == 0)
- {
-#ifdef DEBUG
- printf("Retrying with HTTP/1.1\n");
-#endif
- free(respbuffer);
- respbuffer = miniwget3(host, port, path, size,
- addr_str, addr_str_len, "1.1",
- scope_id, status_code);
- }
-#endif
- return respbuffer;
-}
-
-
-
-
/* parseURL()
* arguments :
* url : source string not modified
@@ -639,7 +603,7 @@ miniwget(const char * url, int * size,
printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
hostname, port, path, scope_id);
#endif
- return miniwget2(hostname, port, path, size, 0, 0, scope_id, status_code);
+ return miniwget3(hostname, port, path, size, 0, 0, "1.1", scope_id, status_code);
}
void *
@@ -660,5 +624,5 @@ miniwget_getaddr(const char * url, int * size,
printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
hostname, port, path, scope_id);
#endif
- return miniwget2(hostname, port, path, size, addr, addrlen, scope_id, status_code);
+ return miniwget3(hostname, port, path, size, addr, addrlen, "1.1", scope_id, status_code);
}
diff --git a/thirdparty/miniupnpc/src/win32_snprintf.h b/thirdparty/miniupnpc/src/win32_snprintf.h
index 1fc284ecff..5064df63bc 100644
--- a/thirdparty/miniupnpc/src/win32_snprintf.h
+++ b/thirdparty/miniupnpc/src/win32_snprintf.h
@@ -23,9 +23,9 @@
(defined(_MSC_VER) && _MSC_VER < 1900) /* Visual Studio older than 2015 */ || \
(defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) && defined(__NO_ISOCEXT)) /* mingw32 without iso c ext */ || \
(defined(__MINGW64_VERSION_MAJOR) && /* mingw-w64 not ... */ !( \
- (defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO != 0)) /* ... with ansi stdio */ || \
+ (defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO != 0) /* ... with ansi stdio */ || \
(__MINGW64_VERSION_MAJOR >= 6 && defined(_UCRT)) /* ... at least 6.0.0 with ucrt */ || \
- (__MINGW64_VERSION_MAJOR >= 8 && !defined(__NO_ISOCEXT)) /* ... at least 8.0.0 with iso c ext */ || \
+ (__MINGW64_VERSION_MAJOR >= 8 && !defined(__NO_ISOCEXT))) /* ... at least 8.0.0 with iso c ext */ || \
0) || \
0)