summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/csg/csg_shape.cpp9
-rw-r--r--modules/csg/icons/CSGBox3D.svg2
-rw-r--r--modules/csg/icons/CSGCapsule3D.svg2
-rw-r--r--modules/csg/icons/CSGCylinder3D.svg2
-rw-r--r--modules/csg/icons/CSGPolygon3D.svg2
-rw-r--r--modules/csg/icons/CSGSphere3D.svg2
-rw-r--r--modules/csg/icons/CSGTorus3D.svg2
-rw-r--r--modules/gdscript/SCsub2
-rw-r--r--modules/gdscript/gdscript_cache.cpp25
-rw-r--r--modules/gdscript/gdscript_vm.cpp8
-rw-r--r--modules/gltf/editor/editor_scene_importer_blend.cpp4
-rw-r--r--modules/gltf/editor/editor_scene_importer_gltf.cpp13
-rw-r--r--modules/gltf/editor/editor_scene_importer_gltf.h1
-rw-r--r--modules/gltf/gltf_document.cpp70
-rw-r--r--modules/gltf/gltf_document.h3
-rw-r--r--modules/mono/csharp_script.cpp31
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs25
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs2
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs18
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs11
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs8
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs8
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs8
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp6
-rw-r--r--modules/noise/fastnoise_lite.cpp4
-rw-r--r--modules/noise/noise.cpp6
-rw-r--r--modules/openxr/SCsub2
-rw-r--r--modules/openxr/openxr_api.cpp7
-rw-r--r--modules/text_server_adv/gdextension_build/methods.py4
-rw-r--r--modules/text_server_adv/text_server_adv.cpp10
-rw-r--r--modules/text_server_adv/text_server_adv.h6
-rw-r--r--modules/text_server_fb/gdextension_build/methods.py4
-rw-r--r--modules/text_server_fb/text_server_fb.cpp8
-rw-r--r--modules/vorbis/audio_stream_ogg_vorbis.cpp6
35 files changed, 238 insertions, 85 deletions
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp
index 0656f8224c..9c178997c5 100644
--- a/modules/csg/csg_shape.cpp
+++ b/modules/csg/csg_shape.cpp
@@ -488,7 +488,9 @@ bool CSGShape3D::_is_debug_collision_shape_visible() {
}
void CSGShape3D::_update_debug_collision_shape() {
- // NOTE: This is called only for the root shape with collision, when root_collision_shape is valid.
+ if (!use_collision || !is_root_shape() || !root_collision_shape.is_valid() || !_is_debug_collision_shape_visible()) {
+ return;
+ }
ERR_FAIL_NULL(RenderingServer::get_singleton());
@@ -573,6 +575,11 @@ void CSGShape3D::_notification(int p_what) {
// Update this node's parent only if its own visibility has changed, not the visibility of parent nodes
parent_shape->_make_dirty();
}
+ if (is_visible()) {
+ _update_debug_collision_shape();
+ } else {
+ _clear_debug_collision_shape();
+ }
last_visible = is_visible();
} break;
diff --git a/modules/csg/icons/CSGBox3D.svg b/modules/csg/icons/CSGBox3D.svg
index bb3a1f357a..d425180cf5 100644
--- a/modules/csg/icons/CSGBox3D.svg
+++ b/modules/csg/icons/CSGBox3D.svg
@@ -1 +1 @@
-<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="m8 2 6 3v6l-6 3-6-3V5zm0 12V8l6-3M8 8 2 5" fill="none" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg>
+<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fefefe"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="m8 2 6 3v6l-6 3-6-3V5zm0 12V8l6-3M8 8 2 5" fill="none" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg>
diff --git a/modules/csg/icons/CSGCapsule3D.svg b/modules/csg/icons/CSGCapsule3D.svg
index 33a2d4a115..3c2657999c 100644
--- a/modules/csg/icons/CSGCapsule3D.svg
+++ b/modules/csg/icons/CSGCapsule3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="M4 6a4 4 0 0 1 8 0v4a4 4 0 0 1-8 0zm0 1.25a2.5 1 0 0 0 8 0m-4-5v12" fill="none" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fefefe"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="M4 6a4 4 0 0 1 8 0v4a4 4 0 0 1-8 0zm0 1.25a2.5 1 0 0 0 8 0m-4-5v12" fill="none" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg>
diff --git a/modules/csg/icons/CSGCylinder3D.svg b/modules/csg/icons/CSGCylinder3D.svg
index 29d658dc46..19e48b4dba 100644
--- a/modules/csg/icons/CSGCylinder3D.svg
+++ b/modules/csg/icons/CSGCylinder3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="M2 4v8a6 2 0 0 0 12 0V4A6 2 0 0 0 2 4a6 2 0 0 0 12 0" stroke-width="2" fill="none" stroke="#fc7f7f" mask="url(#a)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fefefe"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="M2 4v8a6 2 0 0 0 12 0V4A6 2 0 0 0 2 4a6 2 0 0 0 12 0" stroke-width="2" fill="none" stroke="#fc7f7f" mask="url(#a)"/></svg>
diff --git a/modules/csg/icons/CSGPolygon3D.svg b/modules/csg/icons/CSGPolygon3D.svg
index 8d4b61e039..090047248b 100644
--- a/modules/csg/icons/CSGPolygon3D.svg
+++ b/modules/csg/icons/CSGPolygon3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="m8 2 6 3.5v5L8 14l-6-3.5v-5h6zm6 3.5L8 9 2 5.5M8 9v5" fill="none" stroke-linejoin="round" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fefefe"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="m8 2 6 3.5v5L8 14l-6-3.5v-5h6zm6 3.5L8 9 2 5.5M8 9v5" fill="none" stroke-linejoin="round" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg>
diff --git a/modules/csg/icons/CSGSphere3D.svg b/modules/csg/icons/CSGSphere3D.svg
index 16d45b3c99..a677ffaf5c 100644
--- a/modules/csg/icons/CSGSphere3D.svg
+++ b/modules/csg/icons/CSGSphere3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="M8 2a6 6 0 0 0 0 12A6 6 0 0 0 8 2v12M2.05 7.4a6 2 0 0 0 11.9 0" fill="none" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fefefe"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="M8 2a6 6 0 0 0 0 12A6 6 0 0 0 8 2v12M2.05 7.4a6 2 0 0 0 11.9 0" fill="none" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg>
diff --git a/modules/csg/icons/CSGTorus3D.svg b/modules/csg/icons/CSGTorus3D.svg
index 27a6b422f9..60c56bd1ca 100644
--- a/modules/csg/icons/CSGTorus3D.svg
+++ b/modules/csg/icons/CSGTorus3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><g fill="none" stroke="#fc7f7f" mask="url(#a)"><path d="M2.5 10a6 4 0 0 0 11 0 4 4 0 0 0 0-4 6 4 0 0 0-11 0 4 4 0 0 0 0 4z" stroke-width="2"/><path d="M6.2 7.2a2 1 0 1 0 3.6 0" stroke-width="1.75" stroke-linecap="round"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fefefe"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><g fill="none" stroke="#fc7f7f" mask="url(#a)"><path d="M2.5 10a6 4 0 0 0 11 0 4 4 0 0 0 0-4 6 4 0 0 0-11 0 4 4 0 0 0 0 4z" stroke-width="2"/><path d="M6.2 7.2a2 1 0 1 0 3.6 0" stroke-width="1.75" stroke-linecap="round"/></g></svg>
diff --git a/modules/gdscript/SCsub b/modules/gdscript/SCsub
index 1dc4768186..61accd4fc9 100644
--- a/modules/gdscript/SCsub
+++ b/modules/gdscript/SCsub
@@ -19,6 +19,8 @@ if env.editor_build:
# Using a define in the disabled case, to avoid having an extra define
# in regular builds where all modules are enabled.
env_gdscript.Append(CPPDEFINES=["GDSCRIPT_NO_LSP"])
+ # Also needed in main env to unexpose --lsp-port option.
+ env.Append(CPPDEFINES=["GDSCRIPT_NO_LSP"])
if env["tests"]:
diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp
index 26f01ec218..76f4e69ab9 100644
--- a/modules/gdscript/gdscript_cache.cpp
+++ b/modules/gdscript/gdscript_cache.cpp
@@ -364,28 +364,33 @@ void GDScriptCache::remove_static_script(const String &p_fqcn) {
Ref<PackedScene> GDScriptCache::get_packed_scene(const String &p_path, Error &r_error, const String &p_owner) {
MutexLock lock(singleton->mutex);
- if (singleton->packed_scene_cache.has(p_path)) {
- singleton->packed_scene_dependencies[p_path].insert(p_owner);
- return singleton->packed_scene_cache[p_path];
+ String path = p_path;
+ if (path.begins_with("uid://")) {
+ path = ResourceUID::get_singleton()->get_id_path(ResourceUID::get_singleton()->text_to_id(path));
}
- Ref<PackedScene> scene = ResourceCache::get_ref(p_path);
+ if (singleton->packed_scene_cache.has(path)) {
+ singleton->packed_scene_dependencies[path].insert(p_owner);
+ return singleton->packed_scene_cache[path];
+ }
+
+ Ref<PackedScene> scene = ResourceCache::get_ref(path);
if (scene.is_valid()) {
- singleton->packed_scene_cache[p_path] = scene;
- singleton->packed_scene_dependencies[p_path].insert(p_owner);
+ singleton->packed_scene_cache[path] = scene;
+ singleton->packed_scene_dependencies[path].insert(p_owner);
return scene;
}
scene.instantiate();
r_error = OK;
- if (p_path.is_empty()) {
+ if (path.is_empty()) {
r_error = ERR_FILE_BAD_PATH;
return scene;
}
- scene->set_path(p_path);
- singleton->packed_scene_cache[p_path] = scene;
- singleton->packed_scene_dependencies[p_path].insert(p_owner);
+ scene->set_path(path);
+ singleton->packed_scene_cache[path] = scene;
+ singleton->packed_scene_dependencies[path].insert(p_owner);
scene->reload_from_file();
return scene;
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp
index b723ecc185..d31411b26b 100644
--- a/modules/gdscript/gdscript_vm.cpp
+++ b/modules/gdscript/gdscript_vm.cpp
@@ -662,6 +662,14 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
uint32_t op_signature = _code_ptr[ip + 5];
uint32_t actual_signature = (a->get_type() << 8) | (b->get_type());
+#ifdef DEBUG_ENABLED
+ if (op == Variant::OP_DIVIDE || op == Variant::OP_MODULE) {
+ // Don't optimize division and modulo since there's not check for division by zero with validated calls.
+ op_signature = 0xFFFF;
+ _code_ptr[ip + 5] = op_signature;
+ }
+#endif
+
// Check if this is the first run. If so, store the current signature for the optimized path.
if (unlikely(op_signature == 0)) {
static Mutex initializer_mutex;
diff --git a/modules/gltf/editor/editor_scene_importer_blend.cpp b/modules/gltf/editor/editor_scene_importer_blend.cpp
index cb45a6589e..2fad475e92 100644
--- a/modules/gltf/editor/editor_scene_importer_blend.cpp
+++ b/modules/gltf/editor/editor_scene_importer_blend.cpp
@@ -130,8 +130,9 @@ Node *EditorSceneFormatImporterBlend::import_scene(const String &p_path, uint32_
// Get global paths for source and sink.
// Escape paths to be valid Python strings to embed in the script.
const String source_global = ProjectSettings::get_singleton()->globalize_path(p_path).c_escape();
+ const String blend_basename = p_path.get_file().get_basename();
const String sink = ProjectSettings::get_singleton()->get_imported_files_path().path_join(
- vformat("%s-%s.gltf", p_path.get_file().get_basename(), p_path.md5_text()));
+ vformat("%s-%s.gltf", blend_basename, p_path.md5_text()));
const String sink_global = ProjectSettings::get_singleton()->globalize_path(sink).c_escape();
// Handle configuration options.
@@ -282,6 +283,7 @@ Node *EditorSceneFormatImporterBlend::import_scene(const String &p_path, uint32_
if (p_options.has(SNAME("blender/materials/unpack_enabled")) && p_options[SNAME("blender/materials/unpack_enabled")]) {
base_dir = sink.get_base_dir();
}
+ state->set_scene_name(blend_basename);
err = gltf->append_from_file(sink.get_basename() + ".gltf", state, p_flags, base_dir);
if (err != OK) {
if (r_err) {
diff --git a/modules/gltf/editor/editor_scene_importer_gltf.cpp b/modules/gltf/editor/editor_scene_importer_gltf.cpp
index ae2bd1f580..e35c0e9b9b 100644
--- a/modules/gltf/editor/editor_scene_importer_gltf.cpp
+++ b/modules/gltf/editor/editor_scene_importer_gltf.cpp
@@ -51,6 +51,10 @@ Node *EditorSceneFormatImporterGLTF::import_scene(const String &p_path, uint32_t
gltf.instantiate();
Ref<GLTFState> state;
state.instantiate();
+ if (p_options.has("gltf/naming_version")) {
+ int naming_version = p_options["gltf/naming_version"];
+ gltf->set_naming_version(naming_version);
+ }
if (p_options.has("gltf/embedded_image_handling")) {
int32_t enum_option = p_options["gltf/embedded_image_handling"];
state->set_handle_binary_image(enum_option);
@@ -77,7 +81,16 @@ Node *EditorSceneFormatImporterGLTF::import_scene(const String &p_path, uint32_t
void EditorSceneFormatImporterGLTF::get_import_options(const String &p_path,
List<ResourceImporter::ImportOption> *r_options) {
+ r_options->push_back(ResourceImporterScene::ImportOption(PropertyInfo(Variant::INT, "gltf/naming_version", PROPERTY_HINT_ENUM, "Godot 4.1 or 4.0,Godot 4.2 or later"), 1));
r_options->push_back(ResourceImporterScene::ImportOption(PropertyInfo(Variant::INT, "gltf/embedded_image_handling", PROPERTY_HINT_ENUM, "Discard All Textures,Extract Textures,Embed as Basis Universal,Embed as Uncompressed", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), GLTFState::HANDLE_BINARY_EXTRACT_TEXTURES));
}
+void EditorSceneFormatImporterGLTF::handle_compatibility_options(HashMap<StringName, Variant> &p_import_params) const {
+ if (!p_import_params.has("gltf/naming_version")) {
+ // If an existing import file is missing the glTF
+ // compatibility version, we need to use version 0.
+ p_import_params["gltf/naming_version"] = 0;
+ }
+}
+
#endif // TOOLS_ENABLED
diff --git a/modules/gltf/editor/editor_scene_importer_gltf.h b/modules/gltf/editor/editor_scene_importer_gltf.h
index ed57ec8cdb..7726c845bf 100644
--- a/modules/gltf/editor/editor_scene_importer_gltf.h
+++ b/modules/gltf/editor/editor_scene_importer_gltf.h
@@ -49,6 +49,7 @@ public:
List<String> *r_missing_deps, Error *r_err = nullptr) override;
virtual void get_import_options(const String &p_path,
List<ResourceImporter::ImportOption> *r_options) override;
+ virtual void handle_compatibility_options(HashMap<StringName, Variant> &p_import_params) const override;
};
#endif // TOOLS_ENABLED
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 47fc58fe43..4060f7f626 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -573,9 +573,12 @@ Error GLTFDocument::_parse_scenes(Ref<GLTFState> p_state) {
// Determine what to use for the scene name.
if (scene_dict.has("name") && !String(scene_dict["name"]).is_empty() && !((String)scene_dict["name"]).begins_with("Scene")) {
p_state->scene_name = scene_dict["name"];
- } else {
+ } else if (p_state->scene_name.is_empty()) {
p_state->scene_name = p_state->filename;
}
+ if (_naming_version == 0) {
+ p_state->scene_name = _gen_unique_name(p_state, p_state->scene_name);
+ }
}
return OK;
@@ -2797,9 +2800,26 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) {
array[Mesh::ARRAY_INDEX] = indices;
}
- bool generate_tangents = p_state->force_generate_tangents && (primitive == Mesh::PRIMITIVE_TRIANGLES && !a.has("TANGENT") && a.has("TEXCOORD_0") && a.has("NORMAL"));
+ bool generate_tangents = p_state->force_generate_tangents && (primitive == Mesh::PRIMITIVE_TRIANGLES && !a.has("TANGENT") && a.has("NORMAL"));
+
+ if (generate_tangents && !a.has("TEXCOORD_0")) {
+ // If we don't have UVs we provide a dummy tangent array.
+ Vector<float> tangents;
+ tangents.resize(vertex_num * 4);
+ float *tangentsw = tangents.ptrw();
+
+ Vector<Vector3> normals = array[Mesh::ARRAY_NORMAL];
+ for (int k = 0; k < vertex_num; k++) {
+ Vector3 tan = Vector3(0.0, 1.0, 0.0).cross(normals[k]);
+ tangentsw[k * 4 + 0] = tan.x;
+ tangentsw[k * 4 + 1] = tan.y;
+ tangentsw[k * 4 + 2] = tan.z;
+ tangentsw[k * 4 + 3] = 1.0;
+ }
+ array[Mesh::ARRAY_TANGENT] = tangents;
+ }
- if (p_state->force_disable_compression || !a.has("POSITION") || !a.has("NORMAL") || !(a.has("TANGENT") || generate_tangents) || p.has("targets") || (a.has("JOINTS_0") || a.has("JOINTS_1"))) {
+ if (p_state->force_disable_compression || !a.has("POSITION") || !a.has("NORMAL") || p.has("targets") || (a.has("JOINTS_0") || a.has("JOINTS_1"))) {
flags &= ~RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES;
}
@@ -2810,7 +2830,7 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) {
mesh_surface_tool->set_skin_weight_count(SurfaceTool::SKIN_8_WEIGHTS);
}
mesh_surface_tool->index();
- if (generate_tangents) {
+ if (generate_tangents && a.has("TEXCOORD_0")) {
//must generate mikktspace tangents.. ergh..
mesh_surface_tool->generate_tangents();
}
@@ -3006,6 +3026,14 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) {
return OK;
}
+void GLTFDocument::set_naming_version(int p_version) {
+ _naming_version = p_version;
+}
+
+int GLTFDocument::get_naming_version() const {
+ return _naming_version;
+}
+
void GLTFDocument::set_image_format(const String &p_image_format) {
_image_format = p_image_format;
}
@@ -5341,12 +5369,22 @@ void GLTFDocument::_assign_node_names(Ref<GLTFState> p_state) {
}
String gltf_node_name = gltf_node->get_name();
if (gltf_node_name.is_empty()) {
- if (gltf_node->mesh >= 0) {
- gltf_node_name = "Mesh";
- } else if (gltf_node->camera >= 0) {
- gltf_node_name = "Camera";
+ if (_naming_version == 0) {
+ if (gltf_node->mesh >= 0) {
+ gltf_node_name = _gen_unique_name(p_state, "Mesh");
+ } else if (gltf_node->camera >= 0) {
+ gltf_node_name = _gen_unique_name(p_state, "Camera3D");
+ } else {
+ gltf_node_name = _gen_unique_name(p_state, "Node");
+ }
} else {
- gltf_node_name = "Node";
+ if (gltf_node->mesh >= 0) {
+ gltf_node_name = "Mesh";
+ } else if (gltf_node->camera >= 0) {
+ gltf_node_name = "Camera";
+ } else {
+ gltf_node_name = "Node";
+ }
}
}
gltf_node->set_name(_gen_unique_name(p_state, gltf_node_name));
@@ -5846,6 +5884,10 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIn
BoneAttachment3D *bone_attachment = _generate_bone_attachment(p_state, active_skeleton, p_node_index, gltf_node->parent);
p_scene_parent->add_child(bone_attachment, true);
+
+ // Find the correct bone_idx so we can properly serialize it.
+ bone_attachment->set_bone_idx(active_skeleton->find_bone(gltf_node->get_name()));
+
bone_attachment->set_owner(p_scene_root);
// There is no gltf_node that represent this, so just directly create a unique name
@@ -5949,6 +5991,10 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> p_state, const GL
BoneAttachment3D *bone_attachment = _generate_bone_attachment(p_state, active_skeleton, p_node_index, p_node_index);
p_scene_parent->add_child(bone_attachment, true);
+
+ // Find the correct bone_idx so we can properly serialize it.
+ bone_attachment->set_bone_idx(active_skeleton->find_bone(gltf_node->get_name()));
+
bone_attachment->set_owner(p_scene_root);
// There is no gltf_node that represent this, so just directly create a unique name
@@ -7380,7 +7426,11 @@ Node *GLTFDocument::_generate_scene_node_tree(Ref<GLTFState> p_state) {
if (unlikely(p_state->scene_name.is_empty())) {
p_state->scene_name = single_root->get_name();
} else if (single_root->get_name() == StringName()) {
- single_root->set_name(_gen_unique_name(p_state, p_state->scene_name));
+ if (_naming_version == 0) {
+ single_root->set_name(p_state->scene_name);
+ } else {
+ single_root->set_name(_gen_unique_name(p_state, p_state->scene_name));
+ }
}
return single_root;
}
diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h
index 828d650cff..7e378fe94d 100644
--- a/modules/gltf/gltf_document.h
+++ b/modules/gltf/gltf_document.h
@@ -73,6 +73,7 @@ public:
private:
const float BAKE_FPS = 30.0f;
+ int _naming_version = 1;
String _image_format = "PNG";
float _lossy_quality = 0.75f;
Ref<GLTFDocumentExtension> _image_save_extension;
@@ -86,6 +87,8 @@ public:
static void unregister_gltf_document_extension(Ref<GLTFDocumentExtension> p_extension);
static void unregister_all_gltf_document_extensions();
+ void set_naming_version(int p_version);
+ int get_naming_version() const;
void set_image_format(const String &p_image_format);
String get_image_format() const;
void set_lossy_quality(float p_lossy_quality);
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 44bcd4cfe4..56e4fa53d0 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -142,6 +142,10 @@ void CSharpLanguage::finalize() {
return;
}
+ if (gdmono && gdmono->is_runtime_initialized() && GDMonoCache::godot_api_cache_updated) {
+ GDMonoCache::managed_callbacks.DisposablesTracker_OnGodotShuttingDown();
+ }
+
finalizing = true;
// Make sure all script binding gchandles are released before finalizing GDMono
@@ -1985,24 +1989,31 @@ const Variant CSharpInstance::get_rpc_config() const {
void CSharpInstance::notification(int p_notification, bool p_reversed) {
if (p_notification == Object::NOTIFICATION_PREDELETE) {
- // When NOTIFICATION_PREDELETE is sent, we also take the chance to call Dispose().
- // It's safe to call Dispose() multiple times and NOTIFICATION_PREDELETE is guaranteed
+ if (base_ref_counted) {
+ // At this point, Dispose() was already called (manually or from the finalizer).
+ // The RefCounted wouldn't have reached 0 otherwise, since the managed side
+ // references it and Dispose() needs to be called to release it.
+ // However, this means C# RefCounted scripts can't receive NOTIFICATION_PREDELETE, but
+ // this is likely the case with GDScript as well: https://github.com/godotengine/godot/issues/6784
+ return;
+ }
+ } else if (p_notification == Object::NOTIFICATION_PREDELETE_CLEANUP) {
+ // When NOTIFICATION_PREDELETE_CLEANUP is sent, we also take the chance to call Dispose().
+ // It's safe to call Dispose() multiple times and NOTIFICATION_PREDELETE_CLEANUP is guaranteed
// to be sent at least once, which happens right before the call to the destructor.
predelete_notified = true;
if (base_ref_counted) {
- // It's not safe to proceed if the owner derives RefCounted and the refcount reached 0.
- // At this point, Dispose() was already called (manually or from the finalizer) so
- // that's not a problem. The refcount wouldn't have reached 0 otherwise, since the
- // managed side references it and Dispose() needs to be called to release it.
- // However, this means C# RefCounted scripts can't receive NOTIFICATION_PREDELETE, but
- // this is likely the case with GDScript as well: https://github.com/godotengine/godot/issues/6784
+ // At this point, Dispose() was already called (manually or from the finalizer).
+ // The RefCounted wouldn't have reached 0 otherwise, since the managed side
+ // references it and Dispose() needs to be called to release it.
return;
}
- _call_notification(p_notification, p_reversed);
-
+ // NOTIFICATION_PREDELETE_CLEANUP is not sent to scripts.
+ // After calling Dispose() the C# instance can no longer be used,
+ // so it should be the last thing we do.
GDMonoCache::managed_callbacks.CSharpInstanceBridge_CallDispose(
gchandle.get_intptr(), /* okIfNull */ false);
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs
index df35091596..147ef852b3 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs
@@ -230,6 +230,31 @@ namespace Godot.SourceGenerators
location?.SourceTree?.FilePath));
}
+ public static void ReportOnlyNodesShouldExportNodes(
+ GeneratorExecutionContext context,
+ ISymbol exportedMemberSymbol
+ )
+ {
+ var locations = exportedMemberSymbol.Locations;
+ var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault();
+ bool isField = exportedMemberSymbol is IFieldSymbol;
+
+ string message = $"Types not derived from Node should not export Node {(isField ? "fields" : "properties")}";
+
+ string description = $"{message}. Node export is only supported in Node-derived classes.";
+
+ context.ReportDiagnostic(Diagnostic.Create(
+ new DiagnosticDescriptor(id: "GD0107",
+ title: message,
+ messageFormat: message,
+ category: "Usage",
+ DiagnosticSeverity.Error,
+ isEnabledByDefault: true,
+ description),
+ location,
+ location?.SourceTree?.FilePath));
+ }
+
public static void ReportSignalDelegateMissingSuffix(
GeneratorExecutionContext context,
INamedTypeSymbol delegateSymbol)
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
index 5866db5144..c7fd45238d 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
@@ -32,7 +32,7 @@ namespace Godot.SourceGenerators
disabledGenerators != null &&
disabledGenerators.Split(';').Contains(generatorName));
- public static bool InheritsFrom(this INamedTypeSymbol? symbol, string assemblyName, string typeFullName)
+ public static bool InheritsFrom(this ITypeSymbol? symbol, string assemblyName, string typeFullName)
{
while (symbol != null)
{
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
index fc0bfbf084..253e24f092 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
@@ -170,6 +170,15 @@ namespace Godot.SourceGenerators
continue;
}
+ if (marshalType == MarshalType.GodotObjectOrDerived)
+ {
+ if (!symbol.InheritsFrom("GodotSharp", "Godot.Node") &&
+ propertyType.InheritsFrom("GodotSharp", "Godot.Node"))
+ {
+ Common.ReportOnlyNodesShouldExportNodes(context, property);
+ }
+ }
+
var propertyDeclarationSyntax = property.DeclaringSyntaxReferences
.Select(r => r.GetSyntax() as PropertyDeclarationSyntax).FirstOrDefault();
@@ -265,6 +274,15 @@ namespace Godot.SourceGenerators
continue;
}
+ if (marshalType == MarshalType.GodotObjectOrDerived)
+ {
+ if (!symbol.InheritsFrom("GodotSharp", "Godot.Node") &&
+ fieldType.InheritsFrom("GodotSharp", "Godot.Node"))
+ {
+ Common.ReportOnlyNodesShouldExportNodes(context, field);
+ }
+ }
+
EqualsValueClauseSyntax? initializer = field.DeclaringSyntaxReferences
.Select(r => r.GetSyntax())
.OfType<VariableDeclaratorSyntax>()
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index 413f6f0029..650afb4cdf 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -497,7 +497,10 @@ namespace GodotTools
AddChild(new HotReloadAssemblyWatcher { Name = "HotReloadAssemblyWatcher" });
- _menuPopup = new PopupMenu();
+ _menuPopup = new PopupMenu
+ {
+ Name = "CSharpTools",
+ };
_menuPopup.Hide();
AddToolSubmenuItem("C#", _menuPopup);
@@ -626,6 +629,12 @@ namespace GodotTools
_editorSettings.SettingsChanged -= OnSettingsChanged;
}
+ public override void _ExitTree()
+ {
+ _errorDialog?.QueueFree();
+ _confirmCreateSlnDialog?.QueueFree();
+ }
+
private void OnSettingsChanged()
{
// We want to force NoConsoleLogging to true when the VerbosityLevel is at Detailed or above.
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs
index 93a83b701b..0cc89d78af 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs
@@ -259,7 +259,7 @@ namespace Godot.NativeInterop
}
return new godot_callable(method /* Takes ownership of disposable */,
- p_managed_callable.Target.GetInstanceId());
+ p_managed_callable.Target?.GetInstanceId() ?? 0);
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs
index 4ee452455e..215bb4df8c 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs
@@ -182,8 +182,8 @@ namespace Godot
}
// Constants
- private static readonly Vector2I _min = new Vector2I(int.MinValue, int.MinValue);
- private static readonly Vector2I _max = new Vector2I(int.MaxValue, int.MaxValue);
+ private static readonly Vector2I _minValue = new Vector2I(int.MinValue, int.MinValue);
+ private static readonly Vector2I _maxValue = new Vector2I(int.MaxValue, int.MaxValue);
private static readonly Vector2I _zero = new Vector2I(0, 0);
private static readonly Vector2I _one = new Vector2I(1, 1);
@@ -197,12 +197,12 @@ namespace Godot
/// Min vector, a vector with all components equal to <see cref="int.MinValue"/>. Can be used as a negative integer equivalent of <see cref="Vector2.Inf"/>.
/// </summary>
/// <value>Equivalent to <c>new Vector2I(int.MinValue, int.MinValue)</c>.</value>
- public static Vector2I Min { get { return _min; } }
+ public static Vector2I MinValue { get { return _minValue; } }
/// <summary>
/// Max vector, a vector with all components equal to <see cref="int.MaxValue"/>. Can be used as an integer equivalent of <see cref="Vector2.Inf"/>.
/// </summary>
/// <value>Equivalent to <c>new Vector2I(int.MaxValue, int.MaxValue)</c>.</value>
- public static Vector2I Max { get { return _max; } }
+ public static Vector2I MaxValue { get { return _maxValue; } }
/// <summary>
/// Zero vector, a vector with all components set to <c>0</c>.
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs
index db8ceb30e9..fe74ec8884 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs
@@ -193,8 +193,8 @@ namespace Godot
}
// Constants
- private static readonly Vector3I _min = new Vector3I(int.MinValue, int.MinValue, int.MinValue);
- private static readonly Vector3I _max = new Vector3I(int.MaxValue, int.MaxValue, int.MaxValue);
+ private static readonly Vector3I _minValue = new Vector3I(int.MinValue, int.MinValue, int.MinValue);
+ private static readonly Vector3I _maxValue = new Vector3I(int.MaxValue, int.MaxValue, int.MaxValue);
private static readonly Vector3I _zero = new Vector3I(0, 0, 0);
private static readonly Vector3I _one = new Vector3I(1, 1, 1);
@@ -210,12 +210,12 @@ namespace Godot
/// Min vector, a vector with all components equal to <see cref="int.MinValue"/>. Can be used as a negative integer equivalent of <see cref="Vector3.Inf"/>.
/// </summary>
/// <value>Equivalent to <c>new Vector3I(int.MinValue, int.MinValue, int.MinValue)</c>.</value>
- public static Vector3I Min { get { return _min; } }
+ public static Vector3I MinValue { get { return _minValue; } }
/// <summary>
/// Max vector, a vector with all components equal to <see cref="int.MaxValue"/>. Can be used as an integer equivalent of <see cref="Vector3.Inf"/>.
/// </summary>
/// <value>Equivalent to <c>new Vector3I(int.MaxValue, int.MaxValue, int.MaxValue)</c>.</value>
- public static Vector3I Max { get { return _max; } }
+ public static Vector3I MaxValue { get { return _maxValue; } }
/// <summary>
/// Zero vector, a vector with all components set to <c>0</c>.
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs
index e75e996b04..a0a4393523 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs
@@ -228,8 +228,8 @@ namespace Godot
}
// Constants
- private static readonly Vector4I _min = new Vector4I(int.MinValue, int.MinValue, int.MinValue, int.MinValue);
- private static readonly Vector4I _max = new Vector4I(int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue);
+ private static readonly Vector4I _minValue = new Vector4I(int.MinValue, int.MinValue, int.MinValue, int.MinValue);
+ private static readonly Vector4I _maxValue = new Vector4I(int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue);
private static readonly Vector4I _zero = new Vector4I(0, 0, 0, 0);
private static readonly Vector4I _one = new Vector4I(1, 1, 1, 1);
@@ -238,12 +238,12 @@ namespace Godot
/// Min vector, a vector with all components equal to <see cref="int.MinValue"/>. Can be used as a negative integer equivalent of <see cref="Vector4.Inf"/>.
/// </summary>
/// <value>Equivalent to <c>new Vector4I(int.MinValue, int.MinValue, int.MinValue, int.MinValue)</c>.</value>
- public static Vector4I Min { get { return _min; } }
+ public static Vector4I MinValue { get { return _minValue; } }
/// <summary>
/// Max vector, a vector with all components equal to <see cref="int.MaxValue"/>. Can be used as an integer equivalent of <see cref="Vector4.Inf"/>.
/// </summary>
/// <value>Equivalent to <c>new Vector4I(int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue)</c>.</value>
- public static Vector4I Max { get { return _max; } }
+ public static Vector4I MaxValue { get { return _maxValue; } }
/// <summary>
/// Zero vector, a vector with all components set to <c>0</c>.
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index ca2ad315a7..3eb746677d 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -556,12 +556,6 @@ GDMono::GDMono() {
GDMono::~GDMono() {
finalizing_scripts_domain = true;
- if (is_runtime_initialized()) {
- if (GDMonoCache::godot_api_cache_updated) {
- GDMonoCache::managed_callbacks.DisposablesTracker_OnGodotShuttingDown();
- }
- }
-
if (hostfxr_dll_handle) {
OS::get_singleton()->close_dynamic_library(hostfxr_dll_handle);
}
diff --git a/modules/noise/fastnoise_lite.cpp b/modules/noise/fastnoise_lite.cpp
index 4aea98c4de..1b0ef6506b 100644
--- a/modules/noise/fastnoise_lite.cpp
+++ b/modules/noise/fastnoise_lite.cpp
@@ -416,8 +416,8 @@ void FastNoiseLite::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "noise_type", PROPERTY_HINT_ENUM, "Simplex,Simplex Smooth,Cellular,Perlin,Value Cubic,Value"), "set_noise_type", "get_noise_type");
ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "frequency", PROPERTY_HINT_RANGE, ".0001,1,.0001"), "set_frequency", "get_frequency");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "offset", PROPERTY_HINT_RANGE, "-999999999,999999999,0.01"), "set_offset", "get_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "frequency", PROPERTY_HINT_RANGE, ".0001,1,.0001,exp"), "set_frequency", "get_frequency");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "offset", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_offset", "get_offset");
ADD_GROUP("Fractal", "fractal_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "fractal_type", PROPERTY_HINT_ENUM, "None,FBM,Ridged,Ping-Pong"), "set_fractal_type", "get_fractal_type");
diff --git a/modules/noise/noise.cpp b/modules/noise/noise.cpp
index 1115d92f58..9b9fd640f4 100644
--- a/modules/noise/noise.cpp
+++ b/modules/noise/noise.cpp
@@ -54,6 +54,9 @@ Vector<Ref<Image>> Noise::_get_seamless_image(int p_width, int p_height, int p_d
Ref<Image> Noise::get_seamless_image(int p_width, int p_height, bool p_invert, bool p_in_3d_space, real_t p_blend_skirt, bool p_normalize) const {
Vector<Ref<Image>> images = _get_seamless_image(p_width, p_height, 1, p_invert, p_in_3d_space, p_blend_skirt, p_normalize);
+ if (images.size() == 0) {
+ return Ref<Image>();
+ }
return images[0];
}
@@ -163,6 +166,9 @@ Vector<Ref<Image>> Noise::_get_image(int p_width, int p_height, int p_depth, boo
Ref<Image> Noise::get_image(int p_width, int p_height, bool p_invert, bool p_in_3d_space, bool p_normalize) const {
Vector<Ref<Image>> images = _get_image(p_width, p_height, 1, p_invert, p_in_3d_space, p_normalize);
+ if (images.is_empty()) {
+ return Ref<Image>();
+ }
return images[0];
}
diff --git a/modules/openxr/SCsub b/modules/openxr/SCsub
index 73a3723ea4..c64b6de78c 100644
--- a/modules/openxr/SCsub
+++ b/modules/openxr/SCsub
@@ -70,7 +70,7 @@ if env["builtin_openxr"]:
# On Android the openxr_loader is provided by separate plugins for each device
# Build the engine using object files
khrloader_obj = []
- env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/xr_generated_dispatch_table.c")
+ env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/xr_generated_dispatch_table_core.c")
env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/common/filesystem_utils.cpp")
env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/common/object_info.cpp")
diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp
index d0e958164d..3c606de670 100644
--- a/modules/openxr/openxr_api.cpp
+++ b/modules/openxr/openxr_api.cpp
@@ -289,7 +289,7 @@ bool OpenXRAPI::create_instance() {
for (KeyValue<String, bool *> &requested_extension : requested_extensions) {
if (!is_extension_supported(requested_extension.key)) {
if (requested_extension.value == nullptr) {
- // Null means this is a manditory extension so we fail.
+ // Null means this is a mandatory extension so we fail.
ERR_FAIL_V_MSG(false, String("OpenXR: OpenXR Runtime does not support ") + requested_extension.key + String(" extension!"));
} else {
// Set this extension as not supported.
@@ -804,6 +804,7 @@ bool OpenXRAPI::create_swapchains() {
*/
Size2 recommended_size = get_recommended_target_size();
+ uint32_t sample_count = 1;
// We start with our color swapchain...
{
@@ -827,7 +828,7 @@ bool OpenXRAPI::create_swapchains() {
print_verbose(String("Using color swap chain format:") + get_swapchain_format_name(swapchain_format_to_use));
}
- if (!create_swapchain(XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, swapchain_format_to_use, recommended_size.width, recommended_size.height, view_configuration_views[0].recommendedSwapchainSampleCount, view_count, swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain, &swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain_graphics_data)) {
+ if (!create_swapchain(XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, swapchain_format_to_use, recommended_size.width, recommended_size.height, sample_count, view_count, swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain, &swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain_graphics_data)) {
return false;
}
}
@@ -863,7 +864,7 @@ bool OpenXRAPI::create_swapchains() {
// Note, if VK_FORMAT_D32_SFLOAT is used here but we're using the forward+ renderer, we should probably output a warning.
- if (!create_swapchain(XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, swapchain_format_to_use, recommended_size.width, recommended_size.height, view_configuration_views[0].recommendedSwapchainSampleCount, view_count, swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain, &swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain_graphics_data)) {
+ if (!create_swapchain(XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, swapchain_format_to_use, recommended_size.width, recommended_size.height, sample_count, view_count, swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain, &swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain_graphics_data)) {
return false;
}
diff --git a/modules/text_server_adv/gdextension_build/methods.py b/modules/text_server_adv/gdextension_build/methods.py
index 3c5229462c..e58bc3abec 100644
--- a/modules/text_server_adv/gdextension_build/methods.py
+++ b/modules/text_server_adv/gdextension_build/methods.py
@@ -99,8 +99,8 @@ def make_icu_data(target, source, env):
def write_macos_plist(target, binary_name, identifier, name):
- os.makedirs(f"{target}/Resourece/", exist_ok=True)
- f = open(f"{target}/Resourece/Info.plist", "w")
+ os.makedirs(f"{target}/Resource/", exist_ok=True)
+ f = open(f"{target}/Resource/Info.plist", "w")
f.write(f'<?xml version="1.0" encoding="UTF-8"?>\n')
f.write(f'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n')
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index 8987a491cb..6d0a398218 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -1113,14 +1113,14 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma
case FT_PIXEL_MODE_LCD: {
int ofs_color = i * bitmap.pitch + (j * 3);
if (p_bgra) {
- wr[ofs + 0] = bitmap.buffer[ofs_color + 0];
+ wr[ofs + 0] = bitmap.buffer[ofs_color + 2];
wr[ofs + 1] = bitmap.buffer[ofs_color + 1];
- wr[ofs + 2] = bitmap.buffer[ofs_color + 2];
+ wr[ofs + 2] = bitmap.buffer[ofs_color + 0];
wr[ofs + 3] = 255;
} else {
- wr[ofs + 0] = bitmap.buffer[ofs_color + 2];
+ wr[ofs + 0] = bitmap.buffer[ofs_color + 0];
wr[ofs + 1] = bitmap.buffer[ofs_color + 1];
- wr[ofs + 2] = bitmap.buffer[ofs_color + 0];
+ wr[ofs + 2] = bitmap.buffer[ofs_color + 2];
wr[ofs + 3] = 255;
}
} break;
@@ -4312,6 +4312,8 @@ bool TextServerAdvanced::_shaped_text_resize_object(const RID &p_shaped, const V
sd->width += gl.advance * gl.repeat;
}
}
+ sd->sort_valid = false;
+ sd->glyphs_logical.clear();
_realign(sd);
}
return true;
diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h
index 6ce2692fd3..cbd2911aaf 100644
--- a/modules/text_server_adv/text_server_adv.h
+++ b/modules/text_server_adv/text_server_adv.h
@@ -681,11 +681,7 @@ class TextServerAdvanced : public TextServerExtension {
_FORCE_INLINE_ bool operator()(const Glyph &l, const Glyph &r) const {
if (l.start == r.start) {
if (l.count == r.count) {
- if ((l.flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL) {
- return false;
- } else {
- return true;
- }
+ return (l.flags & TextServer::GRAPHEME_IS_VIRTUAL) < (r.flags & TextServer::GRAPHEME_IS_VIRTUAL);
}
return l.count > r.count; // Sort first glyph with count & flags, order of the rest are irrelevant.
} else {
diff --git a/modules/text_server_fb/gdextension_build/methods.py b/modules/text_server_fb/gdextension_build/methods.py
index 3c5229462c..e58bc3abec 100644
--- a/modules/text_server_fb/gdextension_build/methods.py
+++ b/modules/text_server_fb/gdextension_build/methods.py
@@ -99,8 +99,8 @@ def make_icu_data(target, source, env):
def write_macos_plist(target, binary_name, identifier, name):
- os.makedirs(f"{target}/Resourece/", exist_ok=True)
- f = open(f"{target}/Resourece/Info.plist", "w")
+ os.makedirs(f"{target}/Resource/", exist_ok=True)
+ f = open(f"{target}/Resource/Info.plist", "w")
f.write(f'<?xml version="1.0" encoding="UTF-8"?>\n')
f.write(f'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n')
diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp
index eb247cdcbe..f12275d10c 100644
--- a/modules/text_server_fb/text_server_fb.cpp
+++ b/modules/text_server_fb/text_server_fb.cpp
@@ -548,14 +548,14 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitma
case FT_PIXEL_MODE_LCD: {
int ofs_color = i * bitmap.pitch + (j * 3);
if (p_bgra) {
- wr[ofs + 0] = bitmap.buffer[ofs_color + 0];
+ wr[ofs + 0] = bitmap.buffer[ofs_color + 2];
wr[ofs + 1] = bitmap.buffer[ofs_color + 1];
- wr[ofs + 2] = bitmap.buffer[ofs_color + 2];
+ wr[ofs + 2] = bitmap.buffer[ofs_color + 0];
wr[ofs + 3] = 255;
} else {
- wr[ofs + 0] = bitmap.buffer[ofs_color + 2];
+ wr[ofs + 0] = bitmap.buffer[ofs_color + 0];
wr[ofs + 1] = bitmap.buffer[ofs_color + 1];
- wr[ofs + 2] = bitmap.buffer[ofs_color + 0];
+ wr[ofs + 2] = bitmap.buffer[ofs_color + 2];
wr[ofs + 3] = 255;
}
} break;
diff --git a/modules/vorbis/audio_stream_ogg_vorbis.cpp b/modules/vorbis/audio_stream_ogg_vorbis.cpp
index 8a265ffaf3..7ec0b697bf 100644
--- a/modules/vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/vorbis/audio_stream_ogg_vorbis.cpp
@@ -144,7 +144,7 @@ int AudioStreamPlaybackOggVorbis::_mix_internal(AudioFrame *p_buffer, int p_fram
}
int AudioStreamPlaybackOggVorbis::_mix_frames_vorbis(AudioFrame *p_buffer, int p_frames) {
- ERR_FAIL_COND_V(!ready, 0);
+ ERR_FAIL_COND_V(!ready, p_frames);
if (!have_samples_left) {
ogg_packet *packet = nullptr;
int err;
@@ -156,10 +156,10 @@ int AudioStreamPlaybackOggVorbis::_mix_frames_vorbis(AudioFrame *p_buffer, int p
}
err = vorbis_synthesis(&block, packet);
- ERR_FAIL_COND_V_MSG(err != 0, 0, "Error during vorbis synthesis " + itos(err));
+ ERR_FAIL_COND_V_MSG(err != 0, p_frames, "Error during vorbis synthesis " + itos(err));
err = vorbis_synthesis_blockin(&dsp_state, &block);
- ERR_FAIL_COND_V_MSG(err != 0, 0, "Error during vorbis block processing " + itos(err));
+ ERR_FAIL_COND_V_MSG(err != 0, p_frames, "Error during vorbis block processing " + itos(err));
have_packets_left = !packet->e_o_s;
}