From 81162cb0abf0b6805ed00d37122dc994ec66a865 Mon Sep 17 00:00:00 2001 From: Julian Todd Date: Wed, 5 Mar 2025 15:32:13 +0000 Subject: [PATCH 001/111] new override_speaker_channels option --- doc/classes/ProjectSettings.xml | 10 ++++++ .../pulseaudio/audio_driver_pulseaudio.cpp | 33 ++++++++++++++----- drivers/pulseaudio/audio_driver_pulseaudio.h | 2 ++ servers/audio_server.cpp | 3 ++ 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 4d922684460d..64aadeb9f4a7 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -393,6 +393,16 @@ Safer override for [member audio/driver/mix_rate] in the Web platform. Here [code]0[/code] means "let the browser choose" (since some browsers do not like forcing the mix rate). + + If [code]true[/code], the number of output channels will be set by [code]override_speaker_channels[/code] instead of the speaker mode of the output device. + Applies only to PulseAudio. + + + The number of channels to use when [code]override_channels[/code] is set to [code]true[/code]. + + + The channel index to send to the stereo output when [code]override_speaker_channels[/code] has forced there to be a higher number of actual channels. + Specifies the preferred output latency in milliseconds for audio. Lower values will result in lower audio latency at the cost of increased CPU usage. Low values may result in audible crackling on slower hardware. Audio output latency may be constrained by the host operating system and audio hardware drivers. If the host can not provide the specified audio output latency then Godot will attempt to use the nearest latency allowed by the host. As such you should always use [method AudioServer.get_output_latency] to determine the actual audio output latency. diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index 7198f4dd0d08..a940f095ddfe 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -175,7 +175,6 @@ Error AudioDriverPulseAudio::detect_channels(bool input) { ERR_PRINT("pa_context_get_sink_info_by_name error"); } } - return OK; } @@ -200,23 +199,31 @@ Error AudioDriverPulseAudio::init_output_device() { return err; } - switch (pa_map.channels) { + print_verbose("PulseAudio: detected " + itos(pa_map.channels) + " output channels"); + pa_channels = pa_map.channels; + if (GLOBAL_GET("audio/driver/override_channels") && (pa_map.channels == 2)) { + pa_channels = GLOBAL_GET("audio/driver/override_speaker_channels"); + pa_channel0 = GLOBAL_GET("audio/driver/override_channel_out"); + print_verbose("PulseAudio: forcing " + itos(pa_channels) + " output channels, but outputting to " + itos(pa_channel0) + "," + itos(pa_channel0+1)); + } + + switch (pa_channels) { case 1: // Mono case 3: // Surround 2.1 case 5: // Surround 5.0 case 7: // Surround 7.0 - channels = pa_map.channels + 1; + channels = pa_channels + 1; break; case 2: // Stereo case 4: // Surround 4.0 case 6: // Surround 5.1 case 8: // Surround 7.1 - channels = pa_map.channels; + channels = pa_channels; break; default: - WARN_PRINT("PulseAudio: Unsupported number of output channels: " + itos(pa_map.channels)); + WARN_PRINT("PulseAudio: Unsupported number of output channels: " + itos(pa_channels)); pa_channel_map_init_stereo(&pa_map); channels = 2; break; @@ -226,7 +233,7 @@ Error AudioDriverPulseAudio::init_output_device() { buffer_frames = closest_power_of_2(tmp_latency * mix_rate / 1000); pa_buffer_size = buffer_frames * pa_map.channels; - print_verbose("PulseAudio: detected " + itos(pa_map.channels) + " output channels"); + print_verbose("PulseAudio: reserving " + itos(channels) + " bus channels"); print_verbose("PulseAudio: audio buffer frames: " + itos(buffer_frames) + " calculated output latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms"); pa_sample_spec spec; @@ -416,11 +423,10 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) { for (unsigned int i = 0; i < ad->pa_buffer_size; i++) { out_ptr[i] = ad->samples_in[i] >> 16; } - } else { + } else if (ad->channels == ad->pa_map.channels + 1) { // Uneven amount of channels unsigned int in_idx = 0; unsigned int out_idx = 0; - for (unsigned int i = 0; i < ad->buffer_frames; i++) { for (int j = 0; j < ad->pa_map.channels - 1; j++) { out_ptr[out_idx++] = ad->samples_in[in_idx++] >> 16; @@ -429,6 +435,17 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) { uint32_t r = ad->samples_in[in_idx++] >> 16; out_ptr[out_idx++] = (l + r) / 2; } + } else { + // override_channels case + unsigned int in_idx = 0; + unsigned int out_idx = 0; + for (unsigned int i = 0; i < ad->buffer_frames; i++) { + in_idx += ad->pa_channel0; + for (int j = 0; j < ad->pa_map.channels; j++) { + out_ptr[out_idx++] = ad->samples_in[in_idx++] >> 16; + } + in_idx += ad->channels - ad->pa_map.channels - ad->pa_channel0; + } } } diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h index 6456467cb9a6..49f401b38e07 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.h +++ b/drivers/pulseaudio/audio_driver_pulseaudio.h @@ -54,6 +54,8 @@ class AudioDriverPulseAudio : public AudioDriver { pa_stream *pa_rec_str = nullptr; pa_channel_map pa_map = {}; pa_channel_map pa_rec_map = {}; + unsigned int pa_channels = 2; + unsigned int pa_channel0 = 0; String output_device_name = "Default"; String new_output_device = "Default"; diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 98440b0c81fa..1bf9658a4d3c 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -216,6 +216,9 @@ void AudioDriverManager::initialize(int p_driver) { GLOBAL_DEF_RST("audio/driver/enable_input", false); GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "audio/driver/mix_rate", PROPERTY_HINT_RANGE, "11025,192000,1,or_greater,suffix:Hz"), DEFAULT_MIX_RATE); GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "audio/driver/mix_rate.web", PROPERTY_HINT_RANGE, "0,192000,1,or_greater,suffix:Hz"), 0); // Safer default output_latency for web (use browser default). + GLOBAL_DEF_RST("audio/driver/override_channels", false); + GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "audio/driver/override_speaker_channels", PROPERTY_HINT_RANGE, "2,8,1"), 8); + GLOBAL_DEF(PropertyInfo(Variant::INT, "audio/driver/override_channel_out", PROPERTY_HINT_RANGE, "0,6,1"), 0); int failed_driver = -1; From 4ebd44c4f3b49a0570898c6c402add09acf6ba99 Mon Sep 17 00:00:00 2001 From: Julian Todd Date: Wed, 5 Mar 2025 21:34:49 +0000 Subject: [PATCH 002/111] add spaces around a + --- drivers/pulseaudio/audio_driver_pulseaudio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index a940f095ddfe..54370940a54e 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -204,7 +204,7 @@ Error AudioDriverPulseAudio::init_output_device() { if (GLOBAL_GET("audio/driver/override_channels") && (pa_map.channels == 2)) { pa_channels = GLOBAL_GET("audio/driver/override_speaker_channels"); pa_channel0 = GLOBAL_GET("audio/driver/override_channel_out"); - print_verbose("PulseAudio: forcing " + itos(pa_channels) + " output channels, but outputting to " + itos(pa_channel0) + "," + itos(pa_channel0+1)); + print_verbose("PulseAudio: forcing " + itos(pa_channels) + " output channels, but outputting to " + itos(pa_channel0) + "," + itos(pa_channel0 + 1)); } switch (pa_channels) { From e3ca38b49100e31bf7e18a60c3955a0f6afdea6f Mon Sep 17 00:00:00 2001 From: Julian Todd Date: Wed, 5 Mar 2025 21:49:18 +0000 Subject: [PATCH 003/111] doctool seems to have rearranged the xml entries --- doc/classes/ProjectSettings.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 64aadeb9f4a7..97ed7b8dc0b7 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -393,16 +393,6 @@ Safer override for [member audio/driver/mix_rate] in the Web platform. Here [code]0[/code] means "let the browser choose" (since some browsers do not like forcing the mix rate). - - If [code]true[/code], the number of output channels will be set by [code]override_speaker_channels[/code] instead of the speaker mode of the output device. - Applies only to PulseAudio. - - - The number of channels to use when [code]override_channels[/code] is set to [code]true[/code]. - - - The channel index to send to the stereo output when [code]override_speaker_channels[/code] has forced there to be a higher number of actual channels. - Specifies the preferred output latency in milliseconds for audio. Lower values will result in lower audio latency at the cost of increased CPU usage. Low values may result in audible crackling on slower hardware. Audio output latency may be constrained by the host operating system and audio hardware drivers. If the host can not provide the specified audio output latency then Godot will attempt to use the nearest latency allowed by the host. As such you should always use [method AudioServer.get_output_latency] to determine the actual audio output latency. @@ -412,6 +402,16 @@ Safer override for [member audio/driver/output_latency] in the Web platform, to avoid audio issues especially on mobile devices. + + The channel index to send to the stereo output when [code]override_speaker_channels[/code] has forced there to be a higher number of actual channels. + + + If [code]true[/code], the number of output channels will be set by [code]override_speaker_channels[/code] instead of the speaker mode of the output device. + Applies only to PulseAudio. + + + The number of channels to use when [code]override_channels[/code] is set to [code]true[/code]. + The base strength of the panning effect for all [AudioStreamPlayer2D] nodes. The panning strength can be further scaled on each Node using [member AudioStreamPlayer2D.panning_strength]. A value of [code]0.0[/code] disables stereo panning entirely, leaving only volume attenuation in place. A value of [code]1.0[/code] completely mutes one of the channels if the sound is located exactly to the left (or right) of the listener. The default value of [code]0.5[/code] is tuned for headphones. When using speakers, you may find lower values to sound better as speakers have a lower stereo separation compared to headphones. From ba211e166f69f139419163b48fbd8ecb3ea90dd2 Mon Sep 17 00:00:00 2001 From: Julian Todd Date: Thu, 6 Mar 2025 07:12:31 +0000 Subject: [PATCH 004/111] Update doc/classes/ProjectSettings.xml Co-authored-by: Hugo Locurcio --- doc/classes/ProjectSettings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 97ed7b8dc0b7..e807debe2c61 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -407,7 +407,7 @@ If [code]true[/code], the number of output channels will be set by [code]override_speaker_channels[/code] instead of the speaker mode of the output device. - Applies only to PulseAudio. + [b]Note:[/b] This is only implemented in the PulseAudio audio driver on Linux. Other platforms are unaffected by this project setting. The number of channels to use when [code]override_channels[/code] is set to [code]true[/code]. From 03fb3f68c7ed4d59dfb00b47d4ab501703a3e468 Mon Sep 17 00:00:00 2001 From: Julian Todd Date: Thu, 3 Apr 2025 14:08:44 +0100 Subject: [PATCH 005/111] clamp the values to prevent access to out of bounds memory --- drivers/pulseaudio/audio_driver_pulseaudio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index 06cd87d44470..5c06a5d293a8 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -203,7 +203,7 @@ Error AudioDriverPulseAudio::init_output_device() { pa_channels = pa_map.channels; if (GLOBAL_GET("audio/driver/override_channels") && (pa_map.channels == 2)) { pa_channels = GLOBAL_GET("audio/driver/override_speaker_channels"); - pa_channel0 = GLOBAL_GET("audio/driver/override_channel_out"); + pa_channel0 = CLAMP((unsigned int)(GLOBAL_GET("audio/driver/override_channel_out")), 0, pa_channels - 2); print_verbose("PulseAudio: forcing " + itos(pa_channels) + " output channels, but outputting to " + itos(pa_channel0) + "," + itos(pa_channel0 + 1)); } From 05d8ffea139cca41f20166db2a26022d6000d29c Mon Sep 17 00:00:00 2001 From: Eric M Date: Sun, 23 Mar 2025 00:04:56 +1000 Subject: [PATCH 006/111] Fix EditorProperty shortcuts being global and unintentionally triggering --- editor/editor_inspector.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index d9bead1e7832..5611d00814f3 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -579,6 +579,12 @@ void EditorProperty::_notification(int p_what) { } } break; case NOTIFICATION_ENTER_TREE: { + EditorInspector *inspector = get_parent_inspector(); + if (inspector) { + inspector = inspector->get_root_inspector(); + } + set_shortcut_context(inspector); + if (has_borders) { get_parent()->connect(SceneStringName(theme_changed), callable_mp(this, &EditorProperty::_update_property_bg)); _update_property_bg(); From e8b2955d08391bf62ee0bc421be610110f87199c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Mon, 31 Mar 2025 15:37:47 +0200 Subject: [PATCH 007/111] SCons: Only set GCC `-Wvirtual-inheritance` for C++ and `warnings=extra` --- SConstruct | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/SConstruct b/SConstruct index 65a293c00ef1..7c8f4c4e775a 100644 --- a/SConstruct +++ b/SConstruct @@ -862,12 +862,7 @@ else: # GCC, Clang common_warnings = [] if methods.using_gcc(env): - common_warnings += [ - "-Wshadow", - "-Wno-misleading-indentation", - # For optimized Object::cast_to / object.inherits_from() - "-Wvirtual-inheritance", - ] + common_warnings += ["-Wshadow", "-Wno-misleading-indentation"] if cc_version_major < 11: # Regression in GCC 9/10, spams so much in our variadic templates # that we need to outright disable it. @@ -895,7 +890,7 @@ else: # GCC, Clang "-Wstringop-overflow=4", ] ) - env.Append(CXXFLAGS=["-Wplacement-new=1"]) + env.Append(CXXFLAGS=["-Wplacement-new=1", "-Wvirtual-inheritance"]) # Need to fix a warning with AudioServer lambdas before enabling. # if cc_version_major != 9: # GCC 9 had a regression (GH-36325). # env.Append(CXXFLAGS=["-Wnoexcept"]) From f3a0cf3290791f01f8c3eef1f2f33c4dfff6ddac Mon Sep 17 00:00:00 2001 From: Martin Riesz Date: Sat, 1 Feb 2025 12:04:09 +0000 Subject: [PATCH 008/111] Fix LogMultiplayer example in docs Fixes issues: - `server_disconnected` signal not being emitted - `multiplayer.get_remote_sender_id()` returning `0` --- doc/classes/MultiplayerAPIExtension.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/classes/MultiplayerAPIExtension.xml b/doc/classes/MultiplayerAPIExtension.xml index acb6a2c17657..579014916174 100644 --- a/doc/classes/MultiplayerAPIExtension.xml +++ b/doc/classes/MultiplayerAPIExtension.xml @@ -18,10 +18,12 @@ # Just passthrough base signals (copied to var to avoid cyclic reference) var cts = connected_to_server var cf = connection_failed + var sd = server_disconnected var pc = peer_connected var pd = peer_disconnected base_multiplayer.connected_to_server.connect(func(): cts.emit()) base_multiplayer.connection_failed.connect(func(): cf.emit()) + base_multiplayer.server_disconnected.connect(func(): sd.emit()) base_multiplayer.peer_connected.connect(func(id): pc.emit(id)) base_multiplayer.peer_disconnected.connect(func(id): pd.emit(id)) @@ -59,6 +61,9 @@ func _get_unique_id() -> int: return base_multiplayer.get_unique_id() + func _get_remote_sender_id() -> int: + return base_multiplayer.get_remote_sender_id() + func _get_peer_ids() -> PackedInt32Array: return base_multiplayer.get_peers() [/gdscript] From 0646b7f835b31a9b523f0bcdf8acd8484cfc81b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Tue, 1 Apr 2025 13:36:10 +0300 Subject: [PATCH 009/111] Add font import flag to toggle modulation of colored glyphs. --- doc/classes/FontFile.xml | 3 ++ doc/classes/ResourceImporterDynamicFont.xml | 3 ++ doc/classes/SystemFont.xml | 3 ++ doc/classes/TextServer.xml | 15 +++++++ doc/classes/TextServerExtension.xml | 17 ++++++++ .../import/dynamic_font_import_settings.cpp | 5 +++ .../import/resource_importer_dynamic_font.cpp | 3 ++ editor/import/resource_importer_imagefont.cpp | 1 + modules/text_server_adv/text_server_adv.cpp | 20 ++++++++- modules/text_server_adv/text_server_adv.h | 4 ++ modules/text_server_fb/text_server_fb.cpp | 20 ++++++++- modules/text_server_fb/text_server_fb.h | 4 ++ scene/resources/font.cpp | 42 +++++++++++++++++++ scene/resources/font.h | 8 ++++ servers/text/text_server_extension.cpp | 13 ++++++ servers/text/text_server_extension.h | 5 +++ servers/text_server.cpp | 3 ++ servers/text_server.h | 3 ++ 18 files changed, 170 insertions(+), 2 deletions(-) diff --git a/doc/classes/FontFile.xml b/doc/classes/FontFile.xml index e7a724cecd46..c3e744fa5752 100644 --- a/doc/classes/FontFile.xml +++ b/doc/classes/FontFile.xml @@ -634,6 +634,9 @@ If set to [code]true[/code], when aligning glyphs to the pixel boundaries rounding remainders are accumulated to ensure more uniform glyph distribution. This setting has no effect if subpixel positioning is enabled. + + If set to [code]true[/code], color modulation is applied when drawing colored glyphs, otherwise it's applied to the monochrome glyphs only. + The width of the range around the shape between the minimum and maximum representable signed distance. If using font outlines, [member msdf_pixel_range] must be set to at least [i]twice[/i] the size of the largest font outline. The default [member msdf_pixel_range] value of [code]16[/code] allows outline sizes up to [code]8[/code] to look correct. diff --git a/doc/classes/ResourceImporterDynamicFont.xml b/doc/classes/ResourceImporterDynamicFont.xml index ee7504aed894..47184aa0f3e3 100644 --- a/doc/classes/ResourceImporterDynamicFont.xml +++ b/doc/classes/ResourceImporterDynamicFont.xml @@ -50,6 +50,9 @@ Override the list of languages supported by this font. If left empty, this is supplied by the font metadata. There is usually no need to change this. See also [member script_support]. + + If set to [code]true[/code], color modulation is applied when drawing colored glyphs, otherwise it's applied to the monochrome glyphs only. + The width of the range around the shape between the minimum and maximum representable signed distance. If using font outlines, [member msdf_pixel_range] must be set to at least [i]twice[/i] the size of the largest font outline. The default [member msdf_pixel_range] value of [code]8[/code] allows outline sizes up to [code]4[/code] to look correct. diff --git a/doc/classes/SystemFont.xml b/doc/classes/SystemFont.xml index b91ae74eae8c..636779f81b07 100644 --- a/doc/classes/SystemFont.xml +++ b/doc/classes/SystemFont.xml @@ -46,6 +46,9 @@ If set to [code]true[/code], when aligning glyphs to the pixel boundaries rounding remainders are accumulated to ensure more uniform glyph distribution. This setting has no effect if subpixel positioning is enabled. + + If set to [code]true[/code], color modulation is applied when drawing colored glyphs, otherwise it's applied to the monochrome glyphs only. + The width of the range around the shape between the minimum and maximum representable signed distance. If using font outlines, [member msdf_pixel_range] must be set to at least [i]twice[/i] the size of the largest font outline. The default [member msdf_pixel_range] value of [code]16[/code] allows outline sizes up to [code]8[/code] to look correct. diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml index 9098a01e9d8a..2d6c3445aa0e 100644 --- a/doc/classes/TextServer.xml +++ b/doc/classes/TextServer.xml @@ -571,6 +571,13 @@ Returns [code]true[/code], if font supports given language ([url=https://en.wikipedia.org/wiki/ISO_639-1]ISO 639[/url] code). + + + + + Returns [code]true[/code], if color modulation is applied when drawing colored glyphs. + + @@ -858,6 +865,14 @@ Adds override for [method font_is_language_supported]. + + + + + + If set to [code]true[/code], color modulation is applied when drawing colored glyphs, otherwise it's applied to the monochrome glyphs only. + + diff --git a/doc/classes/TextServerExtension.xml b/doc/classes/TextServerExtension.xml index 37f4984ad367..22bc39a4f184 100644 --- a/doc/classes/TextServerExtension.xml +++ b/doc/classes/TextServerExtension.xml @@ -617,6 +617,14 @@ Returns [code]true[/code], if font supports given language ([url=https://en.wikipedia.org/wiki/ISO_639-1]ISO 639[/url] code). + + + + + [b]Optional.[/b] + Returns [code]true[/code], if color modulation is applied when drawing colored glyphs. + + @@ -942,6 +950,15 @@ Adds override for [method _font_is_language_supported]. + + + + + + [b]Optional.[/b] + If set to [code]true[/code], color modulation is applied when drawing colored glyphs, otherwise it's applied to the monochrome glyphs only. + + diff --git a/editor/import/dynamic_font_import_settings.cpp b/editor/import/dynamic_font_import_settings.cpp index 3150258175c9..06dc5398e707 100644 --- a/editor/import/dynamic_font_import_settings.cpp +++ b/editor/import/dynamic_font_import_settings.cpp @@ -490,6 +490,8 @@ void DynamicFontImportSettingsDialog::_main_prop_changed(const String &p_edited_ font_preview->set_allow_system_fallback(import_settings_data->get("allow_system_fallback")); } else if (p_edited_property == "force_autohinter") { font_preview->set_force_autohinter(import_settings_data->get("force_autohinter")); + } else if (p_edited_property == "modulate_color_glyphs") { + font_preview->set_modulate_color_glyphs(import_settings_data->get("modulate_color_glyphs")); } else if (p_edited_property == "hinting") { font_preview->set_hinting((TextServer::Hinting)import_settings_data->get("hinting").operator int()); } else if (p_edited_property == "subpixel_positioning") { @@ -977,6 +979,7 @@ void DynamicFontImportSettingsDialog::_re_import() { main_settings["msdf_size"] = import_settings_data->get("msdf_size"); main_settings["allow_system_fallback"] = import_settings_data->get("allow_system_fallback"); main_settings["force_autohinter"] = import_settings_data->get("force_autohinter"); + main_settings["modulate_color_glyphs"] = import_settings_data->get("modulate_color_glyphs"); main_settings["hinting"] = import_settings_data->get("hinting"); main_settings["subpixel_positioning"] = import_settings_data->get("subpixel_positioning"); main_settings["keep_rounding_remainders"] = import_settings_data->get("keep_rounding_remainders"); @@ -1281,6 +1284,7 @@ void DynamicFontImportSettingsDialog::open_settings(const String &p_path) { font_preview->set_msdf_size(import_settings_data->get("msdf_size")); font_preview->set_allow_system_fallback(import_settings_data->get("allow_system_fallback")); font_preview->set_force_autohinter(import_settings_data->get("force_autohinter")); + font_preview->set_modulate_color_glyphs(import_settings_data->get("modulate_color_glyphs")); font_preview->set_hinting((TextServer::Hinting)import_settings_data->get("hinting").operator int()); int font_subpixel_positioning = import_settings_data->get("subpixel_positioning").operator int(); if (font_subpixel_positioning == 4 /* Auto (Except Pixel Fonts) */) { @@ -1322,6 +1326,7 @@ DynamicFontImportSettingsDialog::DynamicFontImportSettingsDialog() { options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "msdf_size", PROPERTY_HINT_RANGE, "1,250,1"), 48)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "allow_system_fallback"), true)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "force_autohinter"), false)); + options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "modulate_color_glyphs"), false)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), 1)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One Half of a Pixel,One Quarter of a Pixel,Auto (Except Pixel Fonts)"), 4)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "keep_rounding_remainders"), true)); diff --git a/editor/import/resource_importer_dynamic_font.cpp b/editor/import/resource_importer_dynamic_font.cpp index f4b98d488e1d..91409bae0f2d 100644 --- a/editor/import/resource_importer_dynamic_font.cpp +++ b/editor/import/resource_importer_dynamic_font.cpp @@ -116,6 +116,7 @@ void ResourceImporterDynamicFont::get_import_options(const String &p_path, List< r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "allow_system_fallback"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force_autohinter"), false)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "modulate_color_glyphs"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), 1)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One Half of a Pixel,One Quarter of a Pixel,Auto (Except Pixel Fonts)"), 4)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "keep_rounding_remainders"), true)); @@ -153,6 +154,7 @@ Error ResourceImporterDynamicFont::import(ResourceUID::ID p_source_id, const Str Dictionary ot_ov = p_options["opentype_features"]; bool autohinter = p_options["force_autohinter"]; + bool modulate_color_glyphs = p_options["modulate_color_glyphs"]; bool allow_system_fallback = p_options["allow_system_fallback"]; int hinting = p_options["hinting"]; int subpixel_positioning = p_options["subpixel_positioning"]; @@ -176,6 +178,7 @@ Error ResourceImporterDynamicFont::import(ResourceUID::ID p_source_id, const Str font->set_opentype_feature_overrides(ot_ov); font->set_fixed_size(0); font->set_force_autohinter(autohinter); + font->set_modulate_color_glyphs(modulate_color_glyphs); font->set_allow_system_fallback(allow_system_fallback); font->set_hinting((TextServer::Hinting)hinting); font->set_oversampling(oversampling); diff --git a/editor/import/resource_importer_imagefont.cpp b/editor/import/resource_importer_imagefont.cpp index 07682f5a3684..3e735042e293 100644 --- a/editor/import/resource_importer_imagefont.cpp +++ b/editor/import/resource_importer_imagefont.cpp @@ -114,6 +114,7 @@ Error ResourceImporterImageFont::import(ResourceUID::ID p_source_id, const Strin font->set_subpixel_positioning(TextServer::SUBPIXEL_POSITIONING_DISABLED); font->set_keep_rounding_remainders(true); font->set_force_autohinter(false); + font->set_modulate_color_glyphs(false); font->set_allow_system_fallback(false); font->set_hinting(TextServer::HINTING_NONE); font->set_oversampling(1.0f); diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 971578557556..8a06293fcdfa 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -2440,6 +2440,24 @@ bool TextServerAdvanced::_font_is_force_autohinter(const RID &p_font_rid) const return fd->force_autohinter; } +void TextServerAdvanced::_font_set_modulate_color_glyphs(const RID &p_font_rid, bool p_modulate) { + FontAdvanced *fd = _get_font_data(p_font_rid); + ERR_FAIL_NULL(fd); + + MutexLock lock(fd->mutex); + if (fd->modulate_color_glyphs != p_modulate) { + fd->modulate_color_glyphs = p_modulate; + } +} + +bool TextServerAdvanced::_font_is_modulate_color_glyphs(const RID &p_font_rid) const { + FontAdvanced *fd = _get_font_data(p_font_rid); + ERR_FAIL_NULL_V(fd, false); + + MutexLock lock(fd->mutex); + return fd->modulate_color_glyphs; +} + void TextServerAdvanced::_font_set_hinting(const RID &p_font_rid, TextServer::Hinting p_hinting) { FontAdvanced *fd = _get_font_data(p_font_rid); ERR_FAIL_NULL(fd); @@ -3800,7 +3818,7 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca if (fgl.texture_idx != -1) { Color modulate = p_color; #ifdef MODULE_FREETYPE_ENABLED - if (!fgl.from_svg && ffsd->face && ffsd->textures[fgl.texture_idx].image.is_valid() && (ffsd->textures[fgl.texture_idx].image->get_format() == Image::FORMAT_RGBA8) && !lcd_aa && !fd->msdf) { + if (!fd->modulate_color_glyphs && ffsd->face && ffsd->textures[fgl.texture_idx].image.is_valid() && (ffsd->textures[fgl.texture_idx].image->get_format() == Image::FORMAT_RGBA8) && !lcd_aa && !fd->msdf) { modulate.r = modulate.g = modulate.b = 1.0; } #endif diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 315bb426784d..a7c1e40d5502 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -330,6 +330,7 @@ class TextServerAdvanced : public TextServerExtension { int fixed_size = 0; bool allow_system_fallback = true; bool force_autohinter = false; + bool modulate_color_glyphs = false; TextServer::Hinting hinting = TextServer::HINTING_LIGHT; TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO; bool keep_rounding_remainders = true; @@ -807,6 +808,9 @@ class TextServerAdvanced : public TextServerExtension { MODBIND2(font_set_force_autohinter, const RID &, bool); MODBIND1RC(bool, font_is_force_autohinter, const RID &); + MODBIND2(font_set_modulate_color_glyphs, const RID &, bool); + MODBIND1RC(bool, font_is_modulate_color_glyphs, const RID &); + MODBIND2(font_set_subpixel_positioning, const RID &, SubpixelPositioning); MODBIND1RC(SubpixelPositioning, font_get_subpixel_positioning, const RID &); diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index c010a1242fa0..0f6d877af4ae 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -1442,6 +1442,24 @@ bool TextServerFallback::_font_is_force_autohinter(const RID &p_font_rid) const return fd->force_autohinter; } +void TextServerFallback::_font_set_modulate_color_glyphs(const RID &p_font_rid, bool p_modulate) { + FontFallback *fd = _get_font_data(p_font_rid); + ERR_FAIL_NULL(fd); + + MutexLock lock(fd->mutex); + if (fd->modulate_color_glyphs != p_modulate) { + fd->modulate_color_glyphs = p_modulate; + } +} + +bool TextServerFallback::_font_is_modulate_color_glyphs(const RID &p_font_rid) const { + FontFallback *fd = _get_font_data(p_font_rid); + ERR_FAIL_NULL_V(fd, false); + + MutexLock lock(fd->mutex); + return fd->modulate_color_glyphs; +} + void TextServerFallback::_font_set_hinting(const RID &p_font_rid, TextServer::Hinting p_hinting) { FontFallback *fd = _get_font_data(p_font_rid); ERR_FAIL_NULL(fd); @@ -2741,7 +2759,7 @@ void TextServerFallback::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca if (fgl.texture_idx != -1) { Color modulate = p_color; #ifdef MODULE_FREETYPE_ENABLED - if (!fgl.from_svg && ffsd->face && ffsd->textures[fgl.texture_idx].image.is_valid() && (ffsd->textures[fgl.texture_idx].image->get_format() == Image::FORMAT_RGBA8) && !lcd_aa && !fd->msdf) { + if (!fd->modulate_color_glyphs && ffsd->face && ffsd->textures[fgl.texture_idx].image.is_valid() && (ffsd->textures[fgl.texture_idx].image->get_format() == Image::FORMAT_RGBA8) && !lcd_aa && !fd->msdf) { modulate.r = modulate.g = modulate.b = 1.0; } #endif diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index 2c7a27da6a52..971ae2cb7f81 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -268,6 +268,7 @@ class TextServerFallback : public TextServerExtension { int fixed_size = 0; bool force_autohinter = false; bool allow_system_fallback = true; + bool modulate_color_glyphs = false; TextServer::Hinting hinting = TextServer::HINTING_LIGHT; TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO; bool keep_rounding_remainders = true; @@ -662,6 +663,9 @@ class TextServerFallback : public TextServerExtension { MODBIND2(font_set_force_autohinter, const RID &, bool); MODBIND1RC(bool, font_is_force_autohinter, const RID &); + MODBIND2(font_set_modulate_color_glyphs, const RID &, bool); + MODBIND1RC(bool, font_is_modulate_color_glyphs, const RID &); + MODBIND2(font_set_subpixel_positioning, const RID &, SubpixelPositioning); MODBIND1RC(SubpixelPositioning, font_get_subpixel_positioning, const RID &); diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 91d825ee2ef9..ce8739b8d541 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -602,6 +602,7 @@ _FORCE_INLINE_ void FontFile::_ensure_rid(int p_cache_index, int p_make_linked_f TS->font_set_fixed_size(cache[p_cache_index], fixed_size); TS->font_set_fixed_size_scale_mode(cache[p_cache_index], fixed_size_scale_mode); TS->font_set_force_autohinter(cache[p_cache_index], force_autohinter); + TS->font_set_modulate_color_glyphs(cache[p_cache_index], modulate_color_glyphs); TS->font_set_allow_system_fallback(cache[p_cache_index], allow_system_fallback); TS->font_set_hinting(cache[p_cache_index], hinting); TS->font_set_subpixel_positioning(cache[p_cache_index], subpixel_positioning); @@ -929,6 +930,9 @@ void FontFile::_bind_methods() { ClassDB::bind_method(D_METHOD("set_force_autohinter", "force_autohinter"), &FontFile::set_force_autohinter); ClassDB::bind_method(D_METHOD("is_force_autohinter"), &FontFile::is_force_autohinter); + ClassDB::bind_method(D_METHOD("set_modulate_color_glyphs", "modulate"), &FontFile::set_modulate_color_glyphs); + ClassDB::bind_method(D_METHOD("is_modulate_color_glyphs"), &FontFile::is_modulate_color_glyphs); + ClassDB::bind_method(D_METHOD("set_hinting", "hinting"), &FontFile::set_hinting); ClassDB::bind_method(D_METHOD("get_hinting"), &FontFile::get_hinting); @@ -1054,6 +1058,7 @@ void FontFile::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_size", "get_msdf_size"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_system_fallback", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_allow_system_fallback", "is_allow_system_fallback"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_autohinter", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_force_autohinter", "is_force_autohinter"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "modulate_color_glyphs", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_modulate_color_glyphs", "is_modulate_color_glyphs"); ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_STORAGE), "set_hinting", "get_hinting"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_oversampling", "get_oversampling"); ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_fixed_size", "get_fixed_size"); @@ -1413,6 +1418,7 @@ void FontFile::reset_state() { disable_embedded_bitmaps = true; msdf = false; force_autohinter = false; + modulate_color_glyphs = false; allow_system_fallback = true; hinting = TextServer::HINTING_LIGHT; subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_DISABLED; @@ -1453,6 +1459,7 @@ Error FontFile::_load_bitmap_font(const String &p_path, List *r_image_fi disable_embedded_bitmaps = true; msdf = false; force_autohinter = false; + modulate_color_glyphs = false; allow_system_fallback = true; hinting = TextServer::HINTING_NONE; oversampling = 1.0f; @@ -2271,6 +2278,21 @@ bool FontFile::is_force_autohinter() const { return force_autohinter; } +void FontFile::set_modulate_color_glyphs(bool p_modulate) { + if (modulate_color_glyphs != p_modulate) { + modulate_color_glyphs = p_modulate; + for (int i = 0; i < cache.size(); i++) { + _ensure_rid(i); + TS->font_set_modulate_color_glyphs(cache[i], modulate_color_glyphs); + } + emit_changed(); + } +} + +bool FontFile::is_modulate_color_glyphs() const { + return modulate_color_glyphs; +} + void FontFile::set_hinting(TextServer::Hinting p_hinting) { if (hinting != p_hinting) { hinting = p_hinting; @@ -3100,6 +3122,9 @@ void SystemFont::_bind_methods() { ClassDB::bind_method(D_METHOD("set_force_autohinter", "force_autohinter"), &SystemFont::set_force_autohinter); ClassDB::bind_method(D_METHOD("is_force_autohinter"), &SystemFont::is_force_autohinter); + ClassDB::bind_method(D_METHOD("set_modulate_color_glyphs", "modulate"), &SystemFont::set_modulate_color_glyphs); + ClassDB::bind_method(D_METHOD("is_modulate_color_glyphs"), &SystemFont::is_modulate_color_glyphs); + ClassDB::bind_method(D_METHOD("set_hinting", "hinting"), &SystemFont::set_hinting); ClassDB::bind_method(D_METHOD("get_hinting"), &SystemFont::get_hinting); @@ -3138,6 +3163,7 @@ void SystemFont::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_embedded_bitmaps"), "set_disable_embedded_bitmaps", "get_disable_embedded_bitmaps"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_system_fallback"), "set_allow_system_fallback", "is_allow_system_fallback"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_autohinter"), "set_force_autohinter", "is_force_autohinter"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "modulate_color_glyphs"), "set_modulate_color_glyphs", "is_modulate_color_glyphs"); ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), "set_hinting", "get_hinting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One Half of a Pixel,One Quarter of a Pixel"), "set_subpixel_positioning", "get_subpixel_positioning"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_rounding_remainders"), "set_keep_rounding_remainders", "get_keep_rounding_remainders"); @@ -3243,6 +3269,7 @@ void SystemFont::_update_base_font() { file->set_generate_mipmaps(mipmaps); file->set_disable_embedded_bitmaps(disable_embedded_bitmaps); file->set_force_autohinter(force_autohinter); + file->set_modulate_color_glyphs(modulate_color_glyphs); file->set_allow_system_fallback(allow_system_fallback); file->set_hinting(hinting); file->set_subpixel_positioning(subpixel_positioning); @@ -3287,6 +3314,7 @@ void SystemFont::reset_state() { mipmaps = false; disable_embedded_bitmaps = true; force_autohinter = false; + modulate_color_glyphs = false; allow_system_fallback = true; hinting = TextServer::HINTING_LIGHT; subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_DISABLED; @@ -3416,6 +3444,20 @@ bool SystemFont::is_force_autohinter() const { return force_autohinter; } +void SystemFont::set_modulate_color_glyphs(bool p_modulate) { + if (modulate_color_glyphs != p_modulate) { + modulate_color_glyphs = p_modulate; + if (base_font.is_valid()) { + base_font->set_modulate_color_glyphs(modulate_color_glyphs); + } + emit_changed(); + } +} + +bool SystemFont::is_modulate_color_glyphs() const { + return modulate_color_glyphs; +} + void SystemFont::set_hinting(TextServer::Hinting p_hinting) { if (hinting != p_hinting) { hinting = p_hinting; diff --git a/scene/resources/font.h b/scene/resources/font.h index faf42d998652..a3afeacb8cc0 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -192,6 +192,7 @@ class FontFile : public Font { int fixed_size = 0; TextServer::FixedSizeScaleMode fixed_size_scale_mode = TextServer::FIXED_SIZE_SCALE_DISABLE; bool force_autohinter = false; + bool modulate_color_glyphs = false; bool allow_system_fallback = true; TextServer::Hinting hinting = TextServer::HINTING_LIGHT; TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO; @@ -273,6 +274,9 @@ class FontFile : public Font { virtual void set_force_autohinter(bool p_force_autohinter); virtual bool is_force_autohinter() const; + virtual void set_modulate_color_glyphs(bool p_modulate); + virtual bool is_modulate_color_glyphs() const; + virtual void set_hinting(TextServer::Hinting p_hinting); virtual TextServer::Hinting get_hinting() const; @@ -479,6 +483,7 @@ class SystemFont : public Font { bool mipmaps = false; bool disable_embedded_bitmaps = true; bool force_autohinter = false; + bool modulate_color_glyphs = false; bool allow_system_fallback = true; TextServer::Hinting hinting = TextServer::HINTING_LIGHT; TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO; @@ -515,6 +520,9 @@ class SystemFont : public Font { virtual void set_force_autohinter(bool p_force_autohinter); virtual bool is_force_autohinter() const; + virtual void set_modulate_color_glyphs(bool p_modulate); + virtual bool is_modulate_color_glyphs() const; + virtual void set_hinting(TextServer::Hinting p_hinting); virtual TextServer::Hinting get_hinting() const; diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp index b26dd4ea6a5a..81c49d0cb4c8 100644 --- a/servers/text/text_server_extension.cpp +++ b/servers/text/text_server_extension.cpp @@ -108,6 +108,9 @@ void TextServerExtension::_bind_methods() { GDVIRTUAL_BIND(_font_set_force_autohinter, "font_rid", "force_autohinter"); GDVIRTUAL_BIND(_font_is_force_autohinter, "font_rid"); + GDVIRTUAL_BIND(_font_set_modulate_color_glyphs, "font_rid", "modulate"); + GDVIRTUAL_BIND(_font_is_modulate_color_glyphs, "font_rid"); + GDVIRTUAL_BIND(_font_set_hinting, "font_rid", "hinting"); GDVIRTUAL_BIND(_font_get_hinting, "font_rid"); @@ -631,6 +634,16 @@ bool TextServerExtension::font_is_force_autohinter(const RID &p_font_rid) const return ret; } +void TextServerExtension::font_set_modulate_color_glyphs(const RID &p_font_rid, bool p_modulate) { + GDVIRTUAL_CALL(_font_set_modulate_color_glyphs, p_font_rid, p_modulate); +} + +bool TextServerExtension::font_is_modulate_color_glyphs(const RID &p_font_rid) const { + bool ret = false; + GDVIRTUAL_CALL(_font_is_modulate_color_glyphs, p_font_rid, ret); + return ret; +} + void TextServerExtension::font_set_hinting(const RID &p_font_rid, TextServer::Hinting p_hinting) { GDVIRTUAL_CALL(_font_set_hinting, p_font_rid, p_hinting); } diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h index 824bc3172de0..4d9b8a92f8f3 100644 --- a/servers/text/text_server_extension.h +++ b/servers/text/text_server_extension.h @@ -204,6 +204,11 @@ class TextServerExtension : public TextServer { GDVIRTUAL2(_font_set_force_autohinter, RID, bool); GDVIRTUAL1RC(bool, _font_is_force_autohinter, RID); + virtual void font_set_modulate_color_glyphs(const RID &p_font_rid, bool p_modulate) override; + virtual bool font_is_modulate_color_glyphs(const RID &p_font_rid) const override; + GDVIRTUAL2(_font_set_modulate_color_glyphs, RID, bool); + GDVIRTUAL1RC(bool, _font_is_modulate_color_glyphs, RID); + virtual void font_set_hinting(const RID &p_font_rid, Hinting p_hinting) override; virtual Hinting font_get_hinting(const RID &p_font_rid) const override; GDVIRTUAL2(_font_set_hinting, RID, Hinting); diff --git a/servers/text_server.cpp b/servers/text_server.cpp index 653653971cb7..8302bd89ebe3 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -264,6 +264,9 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("font_set_force_autohinter", "font_rid", "force_autohinter"), &TextServer::font_set_force_autohinter); ClassDB::bind_method(D_METHOD("font_is_force_autohinter", "font_rid"), &TextServer::font_is_force_autohinter); + ClassDB::bind_method(D_METHOD("font_set_modulate_color_glyphs", "font_rid", "force_autohinter"), &TextServer::font_set_modulate_color_glyphs); + ClassDB::bind_method(D_METHOD("font_is_modulate_color_glyphs", "font_rid"), &TextServer::font_is_modulate_color_glyphs); + ClassDB::bind_method(D_METHOD("font_set_hinting", "font_rid", "hinting"), &TextServer::font_set_hinting); ClassDB::bind_method(D_METHOD("font_get_hinting", "font_rid"), &TextServer::font_get_hinting); diff --git a/servers/text_server.h b/servers/text_server.h index e9ee5c0909cc..390653a2fc12 100644 --- a/servers/text_server.h +++ b/servers/text_server.h @@ -318,6 +318,9 @@ class TextServer : public RefCounted { virtual void font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) = 0; virtual bool font_is_force_autohinter(const RID &p_font_rid) const = 0; + virtual void font_set_modulate_color_glyphs(const RID &p_font_rid, bool p_modulate) = 0; + virtual bool font_is_modulate_color_glyphs(const RID &p_font_rid) const = 0; + virtual void font_set_hinting(const RID &p_font_rid, Hinting p_hinting) = 0; virtual Hinting font_get_hinting(const RID &p_font_rid) const = 0; From aaea07a029fa52cbd1e68cb3a26f6426e38b2aad Mon Sep 17 00:00:00 2001 From: Anish Mishra Date: Mon, 31 Mar 2025 21:11:41 +0530 Subject: [PATCH 010/111] Fix input config dialog overflow on Android Editor --- editor/input_event_configuration_dialog.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/editor/input_event_configuration_dialog.cpp b/editor/input_event_configuration_dialog.cpp index 8d9617bc90fd..41a41e68f09a 100644 --- a/editor/input_event_configuration_dialog.cpp +++ b/editor/input_event_configuration_dialog.cpp @@ -674,7 +674,6 @@ InputEventConfigurationDialog::InputEventConfigurationDialog() { input_list_tree = memnew(Tree); input_list_tree->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); - input_list_tree->set_custom_minimum_size(Size2(0, 300 * EDSCALE)); // Min height for tree input_list_tree->connect("item_activated", callable_mp(this, &InputEventConfigurationDialog::_input_list_item_activated)); input_list_tree->connect(SceneStringName(item_selected), callable_mp(this, &InputEventConfigurationDialog::_input_list_item_selected)); input_list_tree->set_v_size_flags(Control::SIZE_EXPAND_FILL); From a2a7d2645dba7e284d62e6730dc079850bb49241 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Tue, 11 Mar 2025 10:55:53 -0700 Subject: [PATCH 011/111] Directly use segment points in Geometry2D/3D function parameters --- core/core_bind.cpp | 12 ++--- core/math/a_star.cpp | 7 +-- core/math/geometry_2d.h | 40 ++++++++++---- core/math/geometry_3d.h | 54 ++++++++++++------- editor/plugins/abstract_polygon_2d_editor.cpp | 8 +-- .../animation_state_machine_editor.cpp | 12 +---- .../navigation_obstacle_3d_editor_plugin.cpp | 20 +++---- editor/plugins/node_3d_editor_gizmos.cpp | 15 +++--- editor/plugins/path_3d_editor_plugin.cpp | 7 ++- editor/plugins/polygon_3d_editor_plugin.cpp | 10 ++-- editor/plugins/tiles/tile_data_editors.cpp | 10 ++-- .../godot_collision_solver_2d_sat.cpp | 2 +- .../godot_collision_solver_3d_sat.cpp | 13 +++-- modules/godot_physics_3d/godot_shape_3d.cpp | 46 ++++++---------- .../navigation_3d/3d/nav_mesh_queries_3d.cpp | 11 ++-- scene/2d/light_occluder_2d.cpp | 2 +- scene/2d/line_2d.cpp | 6 +-- scene/2d/navigation_agent_2d.cpp | 7 ++- scene/2d/navigation_link_2d.cpp | 4 +- scene/2d/path_2d.cpp | 9 ++-- scene/3d/navigation_agent_3d.cpp | 11 ++-- scene/animation/animation_blend_space_2d.cpp | 20 +++---- scene/gui/graph_edit.cpp | 2 +- .../resources/2d/concave_polygon_shape_2d.cpp | 2 +- scene/resources/2d/polygon_path_finder.cpp | 27 ++++------ scene/resources/2d/segment_shape_2d.cpp | 3 +- .../resources/2d/world_boundary_shape_2d.cpp | 23 ++++---- scene/resources/gradient_texture.cpp | 5 +- tests/core/math/test_geometry_2d.h | 25 +++++---- tests/core/math/test_geometry_3d.h | 18 +++---- 30 files changed, 206 insertions(+), 225 deletions(-) diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 7c5ca60465ca..17faac8651a7 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -806,13 +806,11 @@ Vector Geometry2D::get_closest_points_between_segments(const Vector2 &p } Vector2 Geometry2D::get_closest_point_to_segment(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b) { - Vector2 s[2] = { p_a, p_b }; - return ::Geometry2D::get_closest_point_to_segment(p_point, s); + return ::Geometry2D::get_closest_point_to_segment(p_point, p_a, p_b); } Vector2 Geometry2D::get_closest_point_to_segment_uncapped(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b) { - Vector2 s[2] = { p_a, p_b }; - return ::Geometry2D::get_closest_point_to_segment_uncapped(p_point, s); + return ::Geometry2D::get_closest_point_to_segment_uncapped(p_point, p_a, p_b); } bool Geometry2D::point_is_inside_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) const { @@ -1069,13 +1067,11 @@ Vector Geometry3D::get_closest_points_between_segments(const Vector3 &p } Vector3 Geometry3D::get_closest_point_to_segment(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b) { - Vector3 s[2] = { p_a, p_b }; - return ::Geometry3D::get_closest_point_to_segment(p_point, s); + return ::Geometry3D::get_closest_point_to_segment(p_point, p_a, p_b); } Vector3 Geometry3D::get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b) { - Vector3 s[2] = { p_a, p_b }; - return ::Geometry3D::get_closest_point_to_segment_uncapped(p_point, s); + return ::Geometry3D::get_closest_point_to_segment_uncapped(p_point, p_a, p_b); } Vector3 Geometry3D::get_triangle_barycentric_coords(const Vector3 &p_point, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2) { diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index 060b1bb1e53e..9b6717c693de 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -302,12 +302,7 @@ Vector3 AStar3D::get_closest_position_in_segment(const Vector3 &p_point) const { continue; } - Vector3 segment[2] = { - from_point->pos, - to_point->pos, - }; - - Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, segment); + Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, from_point->pos, to_point->pos); real_t d = p_point.distance_squared_to(p); if (d < closest_dist) { closest_point = p; diff --git a/core/math/geometry_2d.h b/core/math/geometry_2d.h index c5aaed062720..3619ce27ccf6 100644 --- a/core/math/geometry_2d.h +++ b/core/math/geometry_2d.h @@ -99,27 +99,39 @@ class Geometry2D { return Math::sqrt((c1 - c2).dot(c1 - c2)); } +#ifndef DISABLE_DEPRECATED static Vector2 get_closest_point_to_segment(const Vector2 &p_point, const Vector2 *p_segment) { - Vector2 p = p_point - p_segment[0]; - Vector2 n = p_segment[1] - p_segment[0]; + return get_closest_point_to_segment(p_point, p_segment[0], p_segment[1]); + } +#endif // DISABLE_DEPRECATED + + static Vector2 get_closest_point_to_segment(const Vector2 &p_point, const Vector2 &p_segment_a, const Vector2 &p_segment_b) { + Vector2 p = p_point - p_segment_a; + Vector2 n = p_segment_b - p_segment_a; real_t l2 = n.length_squared(); if (l2 < 1e-20f) { - return p_segment[0]; // Both points are the same, just give any. + return p_segment_a; // Both points are the same, just give any. } real_t d = n.dot(p) / l2; if (d <= 0.0f) { - return p_segment[0]; // Before first point. + return p_segment_a; // Before first point. } else if (d >= 1.0f) { - return p_segment[1]; // After first point. + return p_segment_b; // After first point. } else { - return p_segment[0] + n * d; // Inside. + return p_segment_a + n * d; // Inside. } } +#ifndef DISABLE_DEPRECATED static real_t get_distance_to_segment(const Vector2 &p_point, const Vector2 *p_segment) { - return p_point.distance_to(get_closest_point_to_segment(p_point, p_segment)); + return get_distance_to_segment(p_point, p_segment[0], p_segment[1]); + } +#endif // DISABLE_DEPRECATED + + static real_t get_distance_to_segment(const Vector2 &p_point, const Vector2 &p_segment_a, const Vector2 &p_segment_b) { + return p_point.distance_to(get_closest_point_to_segment(p_point, p_segment_a, p_segment_b)); } static bool is_point_in_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) { @@ -136,17 +148,23 @@ class Geometry2D { return (cn.cross(an) > 0) == orientation; } +#ifndef DISABLE_DEPRECATED static Vector2 get_closest_point_to_segment_uncapped(const Vector2 &p_point, const Vector2 *p_segment) { - Vector2 p = p_point - p_segment[0]; - Vector2 n = p_segment[1] - p_segment[0]; + return get_closest_point_to_segment_uncapped(p_point, p_segment[0], p_segment[1]); + } +#endif // DISABLE_DEPRECATED + + static Vector2 get_closest_point_to_segment_uncapped(const Vector2 &p_point, const Vector2 &p_segment_a, const Vector2 &p_segment_b) { + Vector2 p = p_point - p_segment_a; + Vector2 n = p_segment_b - p_segment_a; real_t l2 = n.length_squared(); if (l2 < 1e-20f) { - return p_segment[0]; // Both points are the same, just give any. + return p_segment_a; // Both points are the same, just give any. } real_t d = n.dot(p) / l2; - return p_segment[0] + n * d; // Inside. + return p_segment_a + n * d; // Inside. } // Disable False Positives in MSVC compiler; we correctly check for 0 here to prevent a division by 0. diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h index c79cf74f771e..3c3eb6c962ff 100644 --- a/core/math/geometry_3d.h +++ b/core/math/geometry_3d.h @@ -272,7 +272,7 @@ class Geometry3D { return true; } - static bool segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Plane *p_planes, int p_plane_count, Vector3 *p_res, Vector3 *p_norm) { + static bool segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Plane *p_planes, int p_plane_count, Vector3 *r_res, Vector3 *r_norm) { real_t min = -1e20, max = 1e20; Vector3 rel = p_to - p_from; @@ -315,46 +315,58 @@ class Geometry3D { return false; // No intersection. } - if (p_res) { - *p_res = p_from + dir * min; + if (r_res) { + *r_res = p_from + dir * min; } - if (p_norm) { - *p_norm = p_planes[min_index].normal; + if (r_norm) { + *r_norm = p_planes[min_index].normal; } return true; } +#ifndef DISABLE_DEPRECATED static Vector3 get_closest_point_to_segment(const Vector3 &p_point, const Vector3 *p_segment) { - Vector3 p = p_point - p_segment[0]; - Vector3 n = p_segment[1] - p_segment[0]; + return get_closest_point_to_segment(p_point, p_segment[0], p_segment[1]); + } +#endif // DISABLE_DEPRECATED + + static Vector3 get_closest_point_to_segment(const Vector3 &p_point, const Vector3 &p_segment_a, const Vector3 &p_segment_b) { + Vector3 p = p_point - p_segment_a; + Vector3 n = p_segment_b - p_segment_a; real_t l2 = n.length_squared(); if (l2 < 1e-20f) { - return p_segment[0]; // Both points are the same, just give any. + return p_segment_a; // Both points are the same, just give any. } real_t d = n.dot(p) / l2; if (d <= 0.0f) { - return p_segment[0]; // Before first point. + return p_segment_a; // Before first point. } else if (d >= 1.0f) { - return p_segment[1]; // After first point. + return p_segment_b; // After first point. } else { - return p_segment[0] + n * d; // Inside. + return p_segment_a + n * d; // Inside. } } +#ifndef DISABLE_DEPRECATED static Vector3 get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 *p_segment) { - Vector3 p = p_point - p_segment[0]; - Vector3 n = p_segment[1] - p_segment[0]; + return get_closest_point_to_segment_uncapped(p_point, p_segment[0], p_segment[1]); + } +#endif // DISABLE_DEPRECATED + + static Vector3 get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 &p_segment_a, const Vector3 &p_segment_b) { + Vector3 p = p_point - p_segment_a; + Vector3 n = p_segment_b - p_segment_a; real_t l2 = n.length_squared(); if (l2 < 1e-20f) { - return p_segment[0]; // Both points are the same, just give any. + return p_segment_a; // Both points are the same, just give any. } real_t d = n.dot(p) / l2; - return p_segment[0] + n * d; // Inside. + return p_segment_a + n * d; // Inside. } static inline bool point_in_projected_triangle(const Vector3 &p_point, const Vector3 &p_v1, const Vector3 &p_v2, const Vector3 &p_v3) { @@ -381,8 +393,14 @@ class Geometry3D { return true; } +#ifndef DISABLE_DEPRECATED static inline bool triangle_sphere_intersection_test(const Vector3 *p_triangle, const Vector3 &p_normal, const Vector3 &p_sphere_pos, real_t p_sphere_radius, Vector3 &r_triangle_contact, Vector3 &r_sphere_contact) { - real_t d = p_normal.dot(p_sphere_pos) - p_normal.dot(p_triangle[0]); + return triangle_sphere_intersection_test(p_triangle[0], p_triangle[1], p_triangle[2], p_normal, p_sphere_pos, p_sphere_radius, r_triangle_contact, r_sphere_contact); + } +#endif // DISABLE_DEPRECATED + + static inline bool triangle_sphere_intersection_test(const Vector3 &p_triangle_a, const Vector3 &p_triangle_b, const Vector3 &p_triangle_c, const Vector3 &p_normal, const Vector3 &p_sphere_pos, real_t p_sphere_radius, Vector3 &r_triangle_contact, Vector3 &r_sphere_contact) { + real_t d = p_normal.dot(p_sphere_pos) - p_normal.dot(p_triangle_a); if (d > p_sphere_radius || d < -p_sphere_radius) { // Not touching the plane of the face, return. @@ -393,7 +411,7 @@ class Geometry3D { /** 2nd) TEST INSIDE TRIANGLE **/ - if (Geometry3D::point_in_projected_triangle(contact, p_triangle[0], p_triangle[1], p_triangle[2])) { + if (Geometry3D::point_in_projected_triangle(contact, p_triangle_a, p_triangle_b, p_triangle_c)) { r_triangle_contact = contact; r_sphere_contact = p_sphere_pos - p_normal * p_sphere_radius; //printf("solved inside triangle\n"); @@ -402,7 +420,7 @@ class Geometry3D { /** 3rd TEST INSIDE EDGE CYLINDERS **/ - const Vector3 verts[4] = { p_triangle[0], p_triangle[1], p_triangle[2], p_triangle[0] }; // for() friendly + const Vector3 verts[4] = { p_triangle_a, p_triangle_b, p_triangle_c, p_triangle_a }; // for() friendly for (int i = 0; i < 3; i++) { // Check edge cylinder. diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index 416073eae1ad..6cdfb08e7fd8 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -707,12 +707,12 @@ AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_edge_point(c const int n_segments = n_points - (_is_line() ? 1 : 0); for (int i = 0; i < n_segments; i++) { - Vector2 segment[2] = { xform.xform(points[i] + offset), - xform.xform(points[(i + 1) % n_points] + offset) }; + const Vector2 segment_a = xform.xform(points[i] + offset); + const Vector2 segment_b = xform.xform(points[(i + 1) % n_points] + offset); - Vector2 cp = Geometry2D::get_closest_point_to_segment(p_pos, segment); + Vector2 cp = Geometry2D::get_closest_point_to_segment(p_pos, segment_a, segment_b); - if (cp.distance_squared_to(segment[0]) < eps2 || cp.distance_squared_to(segment[1]) < eps2) { + if (cp.distance_squared_to(segment_a) < eps2 || cp.distance_squared_to(segment_b) < eps2) { continue; //not valid to reuse point } diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index 528c70e19317..88bc4a2f8d4c 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -232,11 +232,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Refget_position(), s); + Vector2 cpoint = Geometry2D::get_closest_point_to_segment(mb->get_position(), transition_lines[i].from, transition_lines[i].to); float d = cpoint.distance_to(mb->get_position()); if (d > transition_lines[i].width) { @@ -545,11 +541,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Refget_position(), s); + Vector2 cpoint = Geometry2D::get_closest_point_to_segment(mm->get_position(), transition_lines[i].from, transition_lines[i].to); float d = cpoint.distance_to(mm->get_position()); if (d > transition_lines[i].width) { continue; diff --git a/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp b/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp index f82e320da82c..01305fdf8c57 100644 --- a/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp +++ b/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp @@ -466,13 +466,11 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditorPlugin::forward_3d_gui_inp Vector2 closest_edge_point; real_t closest_dist = 1e10; for (int i = 0; i < obstacle_vertices.size(); i++) { - Vector2 points[2] = { - p_camera->unproject_position(gt.xform(obstacle_vertices[i])), - p_camera->unproject_position(gt.xform(obstacle_vertices[(i + 1) % obstacle_vertices.size()])) - }; + const Vector2 a = p_camera->unproject_position(gt.xform(obstacle_vertices[i])); + const Vector2 b = p_camera->unproject_position(gt.xform(obstacle_vertices[(i + 1) % obstacle_vertices.size()])); - Vector2 cp = Geometry2D::get_closest_point_to_segment(mouse_position, points); - if (cp.distance_squared_to(points[0]) < grab_threshold || cp.distance_squared_to(points[1]) < grab_threshold) { + Vector2 cp = Geometry2D::get_closest_point_to_segment(mouse_position, a, b); + if (cp.distance_squared_to(a) < grab_threshold || cp.distance_squared_to(b) < grab_threshold) { continue; // Skip edge as clicked point is too close to existing vertex. } @@ -548,13 +546,11 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditorPlugin::forward_3d_gui_inp Vector2 closest_pos; real_t closest_dist = 1e10; for (int i = 0; i < obstacle_vertices.size(); i++) { - Vector2 points[2] = { - p_camera->unproject_position(gt.xform(obstacle_vertices[i])), - p_camera->unproject_position(gt.xform(obstacle_vertices[(i + 1) % obstacle_vertices.size()])) - }; + const Vector2 a = p_camera->unproject_position(gt.xform(obstacle_vertices[i])); + const Vector2 b = p_camera->unproject_position(gt.xform(obstacle_vertices[(i + 1) % obstacle_vertices.size()])); - Vector2 cp = Geometry2D::get_closest_point_to_segment(mouse_position, points); - if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2) { + Vector2 cp = Geometry2D::get_closest_point_to_segment(mouse_position, a, b); + if (cp.distance_squared_to(a) < CMP_EPSILON2 || cp.distance_squared_to(b) < CMP_EPSILON2) { continue; //not valid to reuse point } diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp index 3b08684502eb..f45546854503 100644 --- a/editor/plugins/node_3d_editor_gizmos.cpp +++ b/editor/plugins/node_3d_editor_gizmos.cpp @@ -715,21 +715,20 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point, float cpd = 1e20; for (int i = 0; i < vc / 2; i++) { - Vector3 a = t.xform(vptr[i * 2 + 0]); - Vector3 b = t.xform(vptr[i * 2 + 1]); - Vector2 s[2]; - s[0] = p_camera->unproject_position(a); - s[1] = p_camera->unproject_position(b); + const Vector3 a = t.xform(vptr[i * 2 + 0]); + const Vector3 b = t.xform(vptr[i * 2 + 1]); + const Vector2 segment_a = p_camera->unproject_position(a); + const Vector2 segment_b = p_camera->unproject_position(b); - Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, s); + Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, segment_a, segment_b); float pd = p.distance_to(p_point); if (pd < cpd) { - float d = s[0].distance_to(s[1]); + float d = segment_a.distance_to(segment_b); Vector3 tcp; if (d > 0) { - float d2 = s[0].distance_to(p) / d; + float d2 = segment_a.distance_to(p) / d; tcp = a + (b - a) * d2; } else { diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp index edf60afd35b5..3ff97ca63d99 100644 --- a/editor/plugins/path_3d_editor_plugin.cpp +++ b/editor/plugins/path_3d_editor_plugin.cpp @@ -620,10 +620,9 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p from = gt.xform(from); to = gt.xform(to); if (cdist > 0) { - Vector2 s[2]; - s[0] = viewport->point_to_screen(from); - s[1] = viewport->point_to_screen(to); - Vector2 inters = Geometry2D::get_closest_point_to_segment(mbpos, s); + const Vector2 segment_a = viewport->point_to_screen(from); + const Vector2 segment_b = viewport->point_to_screen(to); + Vector2 inters = Geometry2D::get_closest_point_to_segment(mbpos, segment_a, segment_b); float d = inters.distance_to(mbpos); if (d < 10 && d < closest_d) { diff --git a/editor/plugins/polygon_3d_editor_plugin.cpp b/editor/plugins/polygon_3d_editor_plugin.cpp index af8d974d0175..bce060db9cf2 100644 --- a/editor/plugins/polygon_3d_editor_plugin.cpp +++ b/editor/plugins/polygon_3d_editor_plugin.cpp @@ -200,13 +200,11 @@ EditorPlugin::AfterGUIInput Polygon3DEditor::forward_3d_gui_input(Camera3D *p_ca Vector2 closest_pos; real_t closest_dist = 1e10; for (int i = 0; i < poly.size(); i++) { - Vector2 points[2] = { - p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth))), - p_camera->unproject_position(gt.xform(Vector3(poly[(i + 1) % poly.size()].x, poly[(i + 1) % poly.size()].y, depth))) - }; + const Vector2 segment_a = p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth))); + const Vector2 segment_b = p_camera->unproject_position(gt.xform(Vector3(poly[(i + 1) % poly.size()].x, poly[(i + 1) % poly.size()].y, depth))); - Vector2 cp = Geometry2D::get_closest_point_to_segment(gpoint, points); - if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2) { + Vector2 cp = Geometry2D::get_closest_point_to_segment(gpoint, segment_a, segment_b); + if (cp.distance_squared_to(segment_a) < CMP_EPSILON2 || cp.distance_squared_to(segment_b) < CMP_EPSILON2) { continue; //not valid to reuse point } diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp index 3a20db5620b9..7cbc134e9f1e 100644 --- a/editor/plugins/tiles/tile_data_editors.cpp +++ b/editor/plugins/tiles/tile_data_editors.cpp @@ -438,8 +438,9 @@ void GenericTilePolygonEditor::_grab_polygon_segment_point(Vector2 p_pos, const for (unsigned int i = 0; i < polygons.size(); i++) { const Vector &polygon = polygons[i]; for (int j = 0; j < polygon.size(); j++) { - Vector2 segment[2] = { polygon[j], polygon[(j + 1) % polygon.size()] }; - Vector2 closest_point = Geometry2D::get_closest_point_to_segment(point, segment); + const Vector2 segment_a = polygon[j]; + const Vector2 segment_b = polygon[(j + 1) % polygon.size()]; + Vector2 closest_point = Geometry2D::get_closest_point_to_segment(point, segment_a, segment_b); float distance = closest_point.distance_to(point); if (distance < grab_threshold / editor_zoom_widget->get_zoom() && distance < closest_distance) { r_polygon_index = i; @@ -474,8 +475,9 @@ void GenericTilePolygonEditor::_snap_to_tile_shape(Point2 &r_point, float &r_cur // Snap to edges if we did not snap to vertices. if (!snapped) { for (int i = 0; i < polygon.size(); i++) { - Point2 segment[2] = { polygon[i], polygon[(i + 1) % polygon.size()] }; - Point2 point = Geometry2D::get_closest_point_to_segment(r_point, segment); + const Vector2 segment_a = polygon[i]; + const Vector2 segment_b = polygon[(i + 1) % polygon.size()]; + Point2 point = Geometry2D::get_closest_point_to_segment(r_point, segment_a, segment_b); float distance = r_point.distance_to(point); if (distance < p_snap_dist && distance < r_current_snapped_dist) { snapped_point = point; diff --git a/modules/godot_physics_2d/godot_collision_solver_2d_sat.cpp b/modules/godot_physics_2d/godot_collision_solver_2d_sat.cpp index daa9982b2ee9..ba86ffb8e6ef 100644 --- a/modules/godot_physics_2d/godot_collision_solver_2d_sat.cpp +++ b/modules/godot_physics_2d/godot_collision_solver_2d_sat.cpp @@ -66,7 +66,7 @@ _FORCE_INLINE_ static void _generate_contacts_point_edge(const Vector2 *p_points ERR_FAIL_COND(p_point_count_B != 2); #endif - Vector2 closest_B = Geometry2D::get_closest_point_to_segment_uncapped(*p_points_A, p_points_B); + Vector2 closest_B = Geometry2D::get_closest_point_to_segment_uncapped(*p_points_A, p_points_B[0], p_points_B[1]); p_collector->call(*p_points_A, closest_B); } diff --git a/modules/godot_physics_3d/godot_collision_solver_3d_sat.cpp b/modules/godot_physics_3d/godot_collision_solver_3d_sat.cpp index 2adbb51297d2..785fc3a65502 100644 --- a/modules/godot_physics_3d/godot_collision_solver_3d_sat.cpp +++ b/modules/godot_physics_3d/godot_collision_solver_3d_sat.cpp @@ -104,7 +104,7 @@ static void _generate_contacts_point_edge(const Vector3 *p_points_A, int p_point ERR_FAIL_COND(p_point_count_B != 2); #endif - Vector3 closest_B = Geometry3D::get_closest_point_to_segment_uncapped(*p_points_A, p_points_B); + Vector3 closest_B = Geometry3D::get_closest_point_to_segment_uncapped(*p_points_A, p_points_B[0], p_points_B[1]); p_callback->call(*p_points_A, closest_B, p_callback->normal); } @@ -171,8 +171,8 @@ static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_ d = 1.0; } - Vector3 closest_A = p_points_A[0] + rel_A * d; - Vector3 closest_B = Geometry3D::get_closest_point_to_segment_uncapped(closest_A, p_points_B); + const Vector3 closest_A = p_points_A[0] + rel_A * d; + const Vector3 closest_B = Geometry3D::get_closest_point_to_segment_uncapped(closest_A, p_points_B[0], p_points_B[1]); // The normal should be perpendicular to both edges. Vector3 normal = rel_A.cross(rel_B); real_t normal_len = normal.length(); @@ -885,13 +885,12 @@ static void _collision_sphere_capsule(const GodotShape3D *p_a, const Transform3D real_t scale_B = p_transform_b.basis[0].length(); // Construct the capsule segment (ball-center to ball-center) - Vector3 capsule_segment[2]; Vector3 capsule_axis = p_transform_b.basis.get_column(1) * (capsule_B->get_height() * 0.5 - capsule_B->get_radius()); - capsule_segment[0] = p_transform_b.origin + capsule_axis; - capsule_segment[1] = p_transform_b.origin - capsule_axis; + const Vector3 capsule_segment_a = p_transform_b.origin + capsule_axis; + const Vector3 capsule_segment_b = p_transform_b.origin - capsule_axis; // Get the capsules closest segment-point to the sphere - Vector3 capsule_closest = Geometry3D::get_closest_point_to_segment(p_transform_a.origin, capsule_segment); + Vector3 capsule_closest = Geometry3D::get_closest_point_to_segment(p_transform_a.origin, capsule_segment_a, capsule_segment_b); // Perform an analytic sphere collision between the sphere and the sphere-collider in the capsule analytic_sphere_collision( diff --git a/modules/godot_physics_3d/godot_shape_3d.cpp b/modules/godot_physics_3d/godot_shape_3d.cpp index 84f3e9bfe306..f7f2c405a825 100644 --- a/modules/godot_physics_3d/godot_shape_3d.cpp +++ b/modules/godot_physics_3d/godot_shape_3d.cpp @@ -216,12 +216,7 @@ bool GodotSeparationRayShape3D::intersect_point(const Vector3 &p_point) const { } Vector3 GodotSeparationRayShape3D::get_closest_point_to(const Vector3 &p_point) const { - Vector3 s[2] = { - Vector3(0, 0, 0), - Vector3(0, 0, length) - }; - - return Geometry3D::get_closest_point_to_segment(p_point, s); + return Geometry3D::get_closest_point_to_segment(p_point, Vector3(0, 0, 0), Vector3(0, 0, length)); } Vector3 GodotSeparationRayShape3D::get_moment_of_inertia(real_t p_mass) const { @@ -455,19 +450,14 @@ Vector3 GodotBoxShape3D::get_closest_point_to(const Vector3 &p_point) const { //check segments real_t min_distance = 1e20; - Vector3 closest_vertex = half_extents * p_point.sign(); - Vector3 s[2] = { - closest_vertex, - closest_vertex - }; - + const Vector3 closest_vertex = half_extents * p_point.sign(); for (int i = 0; i < 3; i++) { - s[1] = closest_vertex; - s[1][i] = -s[1][i]; //edge + Vector3 segment_b = closest_vertex; + segment_b[i] = -segment_b[i]; //edge - Vector3 closest_edge = Geometry3D::get_closest_point_to_segment(p_point, s); + const Vector3 closest_edge = Geometry3D::get_closest_point_to_segment(p_point, closest_vertex, segment_b); - real_t d = p_point.distance_to(closest_edge); + const real_t d = p_point.distance_to(closest_edge); if (d < min_distance) { min_point = closest_edge; min_distance = d; @@ -618,12 +608,10 @@ bool GodotCapsuleShape3D::intersect_point(const Vector3 &p_point) const { } Vector3 GodotCapsuleShape3D::get_closest_point_to(const Vector3 &p_point) const { - Vector3 s[2] = { - Vector3(0, -height * 0.5 + radius, 0), - Vector3(0, height * 0.5 - radius, 0), - }; + const Vector3 segment_a = Vector3(0, -height * 0.5 + radius, 0); + const Vector3 segment_b = Vector3(0, height * 0.5 - radius, 0); - Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, s); + const Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, segment_a, segment_b); if (p.distance_to(p_point) < radius) { return p_point; @@ -772,12 +760,10 @@ Vector3 GodotCylinderShape3D::get_closest_point_to(const Vector3 &p_point) const return proj_point; } else { - Vector3 s[2] = { - Vector3(0, -height * 0.5, 0), - Vector3(0, height * 0.5, 0), - }; + const Vector3 segment_a = Vector3(0, -height * 0.5, 0); + const Vector3 segment_b = Vector3(0, height * 0.5, 0); - Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, s); + const Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, segment_a, segment_b); if (p.distance_to(p_point) < radius) { return p_point; @@ -1068,12 +1054,10 @@ Vector3 GodotConvexPolygonShape3D::get_closest_point_to(const Vector3 &p_point) const Geometry3D::MeshData::Edge *edges = mesh.edges.ptr(); int ec = mesh.edges.size(); for (int i = 0; i < ec; i++) { - Vector3 s[2] = { - vertices[edges[i].vertex_a], - vertices[edges[i].vertex_b] - }; + const Vector3 segment_a = vertices[edges[i].vertex_a]; + const Vector3 segment_b = vertices[edges[i].vertex_b]; - Vector3 closest = Geometry3D::get_closest_point_to_segment(p_point, s); + Vector3 closest = Geometry3D::get_closest_point_to_segment(p_point, segment_a, segment_b); real_t d = closest.distance_to(p_point); if (d < min_distance) { min_distance = d; diff --git a/modules/navigation_3d/3d/nav_mesh_queries_3d.cpp b/modules/navigation_3d/3d/nav_mesh_queries_3d.cpp index c2bec10e779f..761fe9dfd14e 100644 --- a/modules/navigation_3d/3d/nav_mesh_queries_3d.cpp +++ b/modules/navigation_3d/3d/nav_mesh_queries_3d.cpp @@ -328,8 +328,7 @@ void NavMeshQueries3D::_query_task_build_path_corridor(NavMeshPathQueryTask3D &p continue; } - Vector3 pathway[2] = { connection.pathway_start, connection.pathway_end }; - const Vector3 new_entry = Geometry3D::get_closest_point_to_segment(least_cost_poly.entry, pathway); + const Vector3 new_entry = Geometry3D::get_closest_point_to_segment(least_cost_poly.entry, connection.pathway_start, connection.pathway_end); const real_t new_traveled_distance = least_cost_poly.entry.distance_to(new_entry) * poly_travel_cost + poly_enter_cost + least_cost_poly.traveled_distance; // Check if the neighbor polygon has already been processed. @@ -585,8 +584,7 @@ void NavMeshQueries3D::_query_task_post_process_corridorfunnel(NavMeshPathQueryT // Set the apex poly/point to the end point NavigationPoly *apex_poly = &navigation_polys[least_cost_id]; - Vector3 back_pathway[2] = { apex_poly->back_navigation_edge_pathway_start, apex_poly->back_navigation_edge_pathway_end }; - const Vector3 back_edge_closest_point = Geometry3D::get_closest_point_to_segment(end_point, back_pathway); + const Vector3 back_edge_closest_point = Geometry3D::get_closest_point_to_segment(end_point, apex_poly->back_navigation_edge_pathway_start, apex_poly->back_navigation_edge_pathway_end); if (end_point.is_equal_approx(back_edge_closest_point)) { // The end point is basically on top of the last crossed edge, funneling around the corners would at best do nothing. // At worst it would add an unwanted path point before the last point due to precision issues so skip to the next polygon. @@ -1178,7 +1176,8 @@ LocalVector NavMeshQueries3D::get_simplified_path_indices(const LocalV } void NavMeshQueries3D::simplify_path_segment(int p_start_inx, int p_end_inx, const LocalVector &p_points, real_t p_epsilon, LocalVector &r_simplified_path_indices) { - Vector3 path_segment[2] = { p_points[p_start_inx], p_points[p_end_inx] }; + const Vector3 path_segment_a = p_points[p_start_inx]; + const Vector3 path_segment_b = p_points[p_end_inx]; real_t point_max_distance = 0.0; int point_max_index = 0; @@ -1186,7 +1185,7 @@ void NavMeshQueries3D::simplify_path_segment(int p_start_inx, int p_end_inx, con for (int i = p_start_inx; i < p_end_inx; i++) { const Vector3 &checked_point = p_points[i]; - const Vector3 closest_point = Geometry3D::get_closest_point_to_segment(checked_point, path_segment); + const Vector3 closest_point = Geometry3D::get_closest_point_to_segment(checked_point, path_segment_a, path_segment_b); real_t distance_squared = closest_point.distance_squared_to(checked_point); if (distance_squared > point_max_distance) { diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index 4bf97a591d64..63b95f8bf4fb 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -74,7 +74,7 @@ bool OccluderPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double const real_t d = LINE_GRAB_WIDTH / 2 + p_tolerance; const Vector2 *points = polygon.ptr(); for (int i = 0; i < polygon.size() - 1; i++) { - Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, &points[i]); + Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, points[i], points[i + 1]); if (p.distance_to(p_point) <= d) { return true; } diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index f27d729e21d2..90fdaa94f19d 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -58,14 +58,14 @@ bool Line2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc const real_t d = _width / 2 + p_tolerance; const Vector2 *points = _points.ptr(); for (int i = 0; i < _points.size() - 1; i++) { - Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, &points[i]); + Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, points[i], points[i + 1]); if (p_point.distance_to(p) <= d) { return true; } } + // Closing segment between the first and last point. if (_closed && _points.size() > 2) { - const Vector2 closing_segment[2] = { points[0], points[_points.size() - 1] }; - Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, closing_segment); + Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, points[0], points[_points.size() - 1]); if (p_point.distance_to(p) <= d) { return true; } diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index 786598f01a3a..29253cd12cc8 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -692,10 +692,9 @@ void NavigationAgent2D::_update_navigation() { if (navigation_path_index > 0) { const Vector &navigation_path = navigation_result->get_path(); - Vector2 segment[2]; - segment[0] = navigation_path[navigation_path_index - 1]; - segment[1] = navigation_path[navigation_path_index]; - Vector2 p = Geometry2D::get_closest_point_to_segment(origin, segment); + const Vector2 segment_a = navigation_path[navigation_path_index - 1]; + const Vector2 segment_b = navigation_path[navigation_path_index]; + Vector2 p = Geometry2D::get_closest_point_to_segment(origin, segment_a, segment_b); if (origin.distance_to(p) >= path_max_distance) { // To faraway, reload path reload_path = true; diff --git a/scene/2d/navigation_link_2d.cpp b/scene/2d/navigation_link_2d.cpp index 790b9f3e232e..96d7b4338485 100644 --- a/scene/2d/navigation_link_2d.cpp +++ b/scene/2d/navigation_link_2d.cpp @@ -146,9 +146,7 @@ Rect2 NavigationLink2D::_edit_get_rect() const { } bool NavigationLink2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - Point2 segment[2] = { get_start_position(), get_end_position() }; - - Vector2 closest_point = Geometry2D::get_closest_point_to_segment(p_point, segment); + Vector2 closest_point = Geometry2D::get_closest_point_to_segment(p_point, get_start_position(), get_end_position()); return p_point.distance_to(closest_point) < p_tolerance; } #endif // DEBUG_ENABLED diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index 9f528715e255..31fbfd265322 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -66,19 +66,18 @@ bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc } for (int i = 0; i < curve->get_point_count(); i++) { - Vector2 s[2]; - s[0] = curve->get_point_position(i); + Vector2 segment_a = curve->get_point_position(i); for (int j = 1; j <= 8; j++) { real_t frac = j / 8.0; - s[1] = curve->sample(i, frac); + const Vector2 segment_b = curve->sample(i, frac); - Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, s); + Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, segment_a, segment_b); if (p.distance_to(p_point) <= p_tolerance) { return true; } - s[0] = s[1]; + segment_a = segment_b; } } diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index fbdb061ae532..ec796baed604 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -758,12 +758,11 @@ void NavigationAgent3D::_update_navigation() { if (navigation_path_index > 0) { const Vector &navigation_path = navigation_result->get_path(); - Vector3 segment[2]; - segment[0] = navigation_path[navigation_path_index - 1]; - segment[1] = navigation_path[navigation_path_index]; - segment[0].y -= path_height_offset; - segment[1].y -= path_height_offset; - Vector3 p = Geometry3D::get_closest_point_to_segment(origin, segment); + Vector3 segment_a = navigation_path[navigation_path_index - 1]; + Vector3 segment_b = navigation_path[navigation_path_index]; + segment_a.y -= path_height_offset; + segment_b.y -= path_height_offset; + Vector3 p = Geometry3D::get_closest_point_to_segment(origin, segment_a, segment_b); if (origin.distance_to(p) >= path_max_distance) { // To faraway, reload path reload_path = true; diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp index ee1d4121d595..682334cc8fc7 100644 --- a/scene/animation/animation_blend_space_2d.cpp +++ b/scene/animation/animation_blend_space_2d.cpp @@ -385,11 +385,9 @@ Vector2 AnimationNodeBlendSpace2D::get_closest_point(const Vector2 &p_point) { } for (int j = 0; j < 3; j++) { - Vector2 s[2] = { - points[j], - points[(j + 1) % 3] - }; - Vector2 closest_point = Geometry2D::get_closest_point_to_segment(p_point, s); + const Vector2 segment_a = points[j]; + const Vector2 segment_b = points[(j + 1) % 3]; + Vector2 closest_point = Geometry2D::get_closest_point_to_segment(p_point, segment_a, segment_b); if (first || closest_point.distance_to(p_point) < best_point.distance_to(p_point)) { best_point = closest_point; first = false; @@ -481,22 +479,20 @@ AnimationNode::NodeTimeInfo AnimationNodeBlendSpace2D::_process(const AnimationM } for (int j = 0; j < 3; j++) { - Vector2 s[2] = { - points[j], - points[(j + 1) % 3] - }; - Vector2 closest2 = Geometry2D::get_closest_point_to_segment(blend_pos, s); + const Vector2 segment_a = points[j]; + const Vector2 segment_b = points[(j + 1) % 3]; + Vector2 closest2 = Geometry2D::get_closest_point_to_segment(blend_pos, segment_a, segment_b); if (first || closest2.distance_to(blend_pos) < best_point.distance_to(blend_pos)) { best_point = closest2; blend_triangle = i; first = false; - float d = s[0].distance_to(s[1]); + const real_t d = segment_a.distance_to(segment_b); if (d == 0.0) { blend_weights[j] = 1.0; blend_weights[(j + 1) % 3] = 0.0; blend_weights[(j + 2) % 3] = 0.0; } else { - float c = s[0].distance_to(closest2) / d; + const real_t c = segment_a.distance_to(closest2) / d; blend_weights[j] = 1.0 - c; blend_weights[(j + 1) % 3] = c; diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 92b92dd8bb4a..ccca775f0a91 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -1316,7 +1316,7 @@ Ref GraphEdit::get_closest_connection_at_point(const Vect Vector points = get_connection_line(conn->_cache.from_pos * zoom, conn->_cache.to_pos * zoom); for (int i = 0; i < points.size() - 1; i++) { - float distance = Geometry2D::get_distance_to_segment(transformed_point, &points[i]); + const real_t distance = Geometry2D::get_distance_to_segment(transformed_point, points[i], points[i + 1]); if (distance <= lines_thickness * 0.5 + p_max_distance && distance < closest_distance) { closest_connection = conn; closest_distance = distance; diff --git a/scene/resources/2d/concave_polygon_shape_2d.cpp b/scene/resources/2d/concave_polygon_shape_2d.cpp index 56734a8f0bb6..c1673e791749 100644 --- a/scene/resources/2d/concave_polygon_shape_2d.cpp +++ b/scene/resources/2d/concave_polygon_shape_2d.cpp @@ -43,7 +43,7 @@ bool ConcavePolygonShape2D::_edit_is_selected_on_click(const Point2 &p_point, do const Vector2 *r = s.ptr(); for (int i = 0; i < len; i += 2) { - Vector2 closest = Geometry2D::get_closest_point_to_segment(p_point, &r[i]); + Vector2 closest = Geometry2D::get_closest_point_to_segment(p_point, r[i], r[i + 1]); if (p_point.distance_to(closest) < p_tolerance) { return true; } diff --git a/scene/resources/2d/polygon_path_finder.cpp b/scene/resources/2d/polygon_path_finder.cpp index 3aa292431d9d..31cd54058bee 100644 --- a/scene/resources/2d/polygon_path_finder.cpp +++ b/scene/resources/2d/polygon_path_finder.cpp @@ -141,12 +141,9 @@ Vector PolygonPathFinder::find_path(const Vector2 &p_from, const Vector for (const Edge &E : edges) { const Edge &e = E; - Vector2 seg[2] = { - points[e.points[0]].pos, - points[e.points[1]].pos - }; - - Vector2 closest = Geometry2D::get_closest_point_to_segment(from, seg); + const Vector2 segment_a = points[e.points[0]].pos; + const Vector2 segment_b = points[e.points[1]].pos; + Vector2 closest = Geometry2D::get_closest_point_to_segment(from, segment_a, segment_b); float d = from.distance_squared_to(closest); if (d < closest_dist) { @@ -165,12 +162,9 @@ Vector PolygonPathFinder::find_path(const Vector2 &p_from, const Vector for (const Edge &E : edges) { const Edge &e = E; - Vector2 seg[2] = { - points[e.points[0]].pos, - points[e.points[1]].pos - }; - - Vector2 closest = Geometry2D::get_closest_point_to_segment(to, seg); + const Vector2 segment_a = points[e.points[0]].pos; + const Vector2 segment_b = points[e.points[1]].pos; + Vector2 closest = Geometry2D::get_closest_point_to_segment(to, segment_a, segment_b); float d = to.distance_squared_to(closest); if (d < closest_dist) { @@ -493,12 +487,9 @@ Vector2 PolygonPathFinder::get_closest_point(const Vector2 &p_point) const { for (const Edge &E : edges) { const Edge &e = E; - Vector2 seg[2] = { - points[e.points[0]].pos, - points[e.points[1]].pos - }; - - Vector2 closest = Geometry2D::get_closest_point_to_segment(p_point, seg); + const Vector2 segment_a = points[e.points[0]].pos; + const Vector2 segment_b = points[e.points[1]].pos; + Vector2 closest = Geometry2D::get_closest_point_to_segment(p_point, segment_a, segment_b); float d = p_point.distance_squared_to(closest); if (d < closest_dist) { diff --git a/scene/resources/2d/segment_shape_2d.cpp b/scene/resources/2d/segment_shape_2d.cpp index 75d62df885ee..9b58306d95e9 100644 --- a/scene/resources/2d/segment_shape_2d.cpp +++ b/scene/resources/2d/segment_shape_2d.cpp @@ -35,8 +35,7 @@ #include "servers/rendering_server.h" bool SegmentShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - Vector2 l[2] = { a, b }; - Vector2 closest = Geometry2D::get_closest_point_to_segment(p_point, l); + Vector2 closest = Geometry2D::get_closest_point_to_segment(p_point, a, b); return p_point.distance_to(closest) < p_tolerance; } diff --git a/scene/resources/2d/world_boundary_shape_2d.cpp b/scene/resources/2d/world_boundary_shape_2d.cpp index 842a8cb4e016..276935da138d 100644 --- a/scene/resources/2d/world_boundary_shape_2d.cpp +++ b/scene/resources/2d/world_boundary_shape_2d.cpp @@ -35,16 +35,21 @@ #include "servers/rendering_server.h" bool WorldBoundaryShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - Vector2 point = distance * normal; - Vector2 l[2][2] = { { point - normal.orthogonal() * 100, point + normal.orthogonal() * 100 }, { point, point + normal * 30 } }; - - for (int i = 0; i < 2; i++) { - Vector2 closest = Geometry2D::get_closest_point_to_segment(p_point, l[i]); - if (p_point.distance_to(closest) < p_tolerance) { - return true; - } + const Vector2 shape_center = distance * normal; + // Orthogonal part of the shape editor gizmo (the flat line). + const Vector2 ortho_segment_a = shape_center - normal.orthogonal() * 100; + const Vector2 ortho_segment_b = shape_center + normal.orthogonal() * 100; + const Vector2 ortho_closest = Geometry2D::get_closest_point_to_segment(p_point, ortho_segment_a, ortho_segment_b); + if (p_point.distance_to(ortho_closest) < p_tolerance) { + return true; + } + // Normal part of the shape editor gizmo (the arrow). + const Vector2 normal_segment_a = shape_center; + const Vector2 normal_segment_b = shape_center + normal * 30; + const Vector2 normal_closest = Geometry2D::get_closest_point_to_segment(p_point, normal_segment_a, normal_segment_b); + if (p_point.distance_to(normal_closest) < p_tolerance) { + return true; } - return false; } diff --git a/scene/resources/gradient_texture.cpp b/scene/resources/gradient_texture.cpp index 2b0e455efb28..07e7de0cef6a 100644 --- a/scene/resources/gradient_texture.cpp +++ b/scene/resources/gradient_texture.cpp @@ -292,10 +292,7 @@ float GradientTexture2D::_get_gradient_offset_at(int x, int y) const { pos.y = static_cast(y) / (height - 1); } if (fill == Fill::FILL_LINEAR) { - Vector2 segment[2]; - segment[0] = fill_from; - segment[1] = fill_to; - Vector2 closest = Geometry2D::get_closest_point_to_segment_uncapped(pos, &segment[0]); + const Vector2 closest = Geometry2D::get_closest_point_to_segment_uncapped(pos, fill_from, fill_to); ofs = (closest - fill_from).length() / (fill_to - fill_from).length(); if ((closest - fill_from).dot(fill_to - fill_from) < 0) { ofs *= -1; diff --git a/tests/core/math/test_geometry_2d.h b/tests/core/math/test_geometry_2d.h index 8af9711e8c6d..415912fe9e22 100644 --- a/tests/core/math/test_geometry_2d.h +++ b/tests/core/math/test_geometry_2d.h @@ -261,22 +261,25 @@ TEST_CASE("[Geometry2D] Segment intersection with polygon") { } TEST_CASE("[Geometry2D] Closest point to segment") { - constexpr Vector2 s[] = { Vector2(-4, -4), Vector2(4, 4) }; - CHECK(Geometry2D::get_closest_point_to_segment(Vector2(4.1, 4.1), s).is_equal_approx(Vector2(4, 4))); - CHECK(Geometry2D::get_closest_point_to_segment(Vector2(-4.1, -4.1), s).is_equal_approx(Vector2(-4, -4))); - CHECK(Geometry2D::get_closest_point_to_segment(Vector2(-1, 1), s).is_equal_approx(Vector2(0, 0))); - - constexpr Vector2 t[] = { Vector2(1, -2), Vector2(1, -2) }; + Vector2 a = Vector2(-4, -4); + Vector2 b = Vector2(4, 4); + CHECK(Geometry2D::get_closest_point_to_segment(Vector2(4.1, 4.1), a, b).is_equal_approx(Vector2(4, 4))); + CHECK(Geometry2D::get_closest_point_to_segment(Vector2(-4.1, -4.1), a, b).is_equal_approx(Vector2(-4, -4))); + CHECK(Geometry2D::get_closest_point_to_segment(Vector2(-1, 1), a, b).is_equal_approx(Vector2(0, 0))); + + a = Vector2(1, -2); + b = Vector2(1, -2); CHECK_MESSAGE( - Geometry2D::get_closest_point_to_segment(Vector2(-3, 4), t).is_equal_approx(Vector2(1, -2)), + Geometry2D::get_closest_point_to_segment(Vector2(-3, 4), a, b).is_equal_approx(Vector2(1, -2)), "Line segment is only a single point. This point should be the closest."); } TEST_CASE("[Geometry2D] Closest point to uncapped segment") { - constexpr Vector2 s[] = { Vector2(-4, -4), Vector2(4, 4) }; - CHECK(Geometry2D::get_closest_point_to_segment_uncapped(Vector2(-1, 1), s).is_equal_approx(Vector2(0, 0))); - CHECK(Geometry2D::get_closest_point_to_segment_uncapped(Vector2(-4, -6), s).is_equal_approx(Vector2(-5, -5))); - CHECK(Geometry2D::get_closest_point_to_segment_uncapped(Vector2(4, 6), s).is_equal_approx(Vector2(5, 5))); + constexpr Vector2 a = Vector2(-4, -4); + constexpr Vector2 b = Vector2(4, 4); + CHECK(Geometry2D::get_closest_point_to_segment_uncapped(Vector2(-1, 1), a, b).is_equal_approx(Vector2(0, 0))); + CHECK(Geometry2D::get_closest_point_to_segment_uncapped(Vector2(-4, -6), a, b).is_equal_approx(Vector2(-5, -5))); + CHECK(Geometry2D::get_closest_point_to_segment_uncapped(Vector2(4, 6), a, b).is_equal_approx(Vector2(5, 5))); } TEST_CASE("[Geometry2D] Closest points between segments") { diff --git a/tests/core/math/test_geometry_3d.h b/tests/core/math/test_geometry_3d.h index 857cdb6c5d66..39526bb2d032 100644 --- a/tests/core/math/test_geometry_3d.h +++ b/tests/core/math/test_geometry_3d.h @@ -129,8 +129,9 @@ TEST_CASE("[Geometry3D] Compute Convex Mesh Points") { } TEST_CASE("[Geometry3D] Get Closest Point To Segment") { - constexpr Vector3 segment[2] = { Vector3(1, 1, 1), Vector3(5, 5, 5) }; - Vector3 output = Geometry3D::get_closest_point_to_segment(Vector3(2, 1, 4), segment); + constexpr Vector3 a = Vector3(1, 1, 1); + constexpr Vector3 b = Vector3(5, 5, 5); + Vector3 output = Geometry3D::get_closest_point_to_segment(Vector3(2, 1, 4), a, b); CHECK(output.is_equal_approx(Vector3(2.33333, 2.33333, 2.33333))); } @@ -189,13 +190,12 @@ TEST_CASE("[Geometry3D] Triangle and Box Overlap") { } TEST_CASE("[Geometry3D] Triangle and Sphere Intersect") { - Vector triangle; - triangle.push_back(Vector3(3, 0, 0)); - triangle.push_back(Vector3(-3, 0, 0)); - triangle.push_back(Vector3(0, 3, 0)); + constexpr Vector3 triangle_a = Vector3(3, 0, 0); + constexpr Vector3 triangle_b = Vector3(-3, 0, 0); + constexpr Vector3 triangle_c = Vector3(0, 3, 0); Vector3 triangle_contact, sphere_contact; - CHECK(Geometry3D::triangle_sphere_intersection_test(&triangle[0], Vector3(0, -1, 0), Vector3(0, 0, 0), 5, triangle_contact, sphere_contact) == true); - CHECK(Geometry3D::triangle_sphere_intersection_test(&triangle[0], Vector3(0, 1, 0), Vector3(0, 0, 0), 5, triangle_contact, sphere_contact) == true); - CHECK(Geometry3D::triangle_sphere_intersection_test(&triangle[0], Vector3(0, 1, 0), Vector3(20, 0, 0), 5, triangle_contact, sphere_contact) == false); + CHECK(Geometry3D::triangle_sphere_intersection_test(triangle_a, triangle_b, triangle_c, Vector3(0, -1, 0), Vector3(0, 0, 0), 5, triangle_contact, sphere_contact) == true); + CHECK(Geometry3D::triangle_sphere_intersection_test(triangle_a, triangle_b, triangle_c, Vector3(0, 1, 0), Vector3(0, 0, 0), 5, triangle_contact, sphere_contact) == true); + CHECK(Geometry3D::triangle_sphere_intersection_test(triangle_a, triangle_b, triangle_c, Vector3(0, 1, 0), Vector3(20, 0, 0), 5, triangle_contact, sphere_contact) == false); } } // namespace TestGeometry3D From 02061aabad2104350d3f306e06e8f3047403ed6a Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Tue, 1 Apr 2025 23:44:43 +0200 Subject: [PATCH 012/111] Change navigation module LocalVector size_t uses to uint32_t Changes navigation module LocalVector size_t uses to uint32_t. --- .../navigation_2d/2d/nav_mesh_queries_2d.cpp | 12 +++++------ .../navigation_3d/3d/nav_mesh_queries_3d.cpp | 20 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/modules/navigation_2d/2d/nav_mesh_queries_2d.cpp b/modules/navigation_2d/2d/nav_mesh_queries_2d.cpp index 650061d4417f..0487d77648fe 100644 --- a/modules/navigation_2d/2d/nav_mesh_queries_2d.cpp +++ b/modules/navigation_2d/2d/nav_mesh_queries_2d.cpp @@ -256,7 +256,7 @@ void NavMeshQueries2D::_query_task_find_start_end_positions(NavMeshPathQueryTask } // For each triangle check the distance between the origin/destination. - for (size_t point_id = 2; point_id < p.points.size(); point_id++) { + for (uint32_t point_id = 2; point_id < p.points.size(); point_id++) { const Triangle2 triangle(p.points[0].pos, p.points[point_id - 1].pos, p.points[point_id].pos); Vector2 point = triangle.get_closest_point_to(p_query_task.start_position); @@ -372,7 +372,7 @@ void NavMeshQueries2D::_query_task_build_path_corridor(NavMeshPathQueryTask2D &p // Set as end point the furthest reachable point. end_poly = reachable_end; real_t end_d = FLT_MAX; - for (size_t point_id = 2; point_id < end_poly->points.size(); point_id++) { + for (uint32_t point_id = 2; point_id < end_poly->points.size(); point_id++) { Triangle2 t(end_poly->points[0].pos, end_poly->points[point_id - 1].pos, end_poly->points[point_id].pos); Vector2 spoint = t.get_closest_point_to(p_target_position); real_t dpoint = spoint.distance_squared_to(p_target_position); @@ -384,7 +384,7 @@ void NavMeshQueries2D::_query_task_build_path_corridor(NavMeshPathQueryTask2D &p // Search all faces of start polygon as well. bool closest_point_on_start_poly = false; - for (size_t point_id = 2; point_id < begin_poly->points.size(); point_id++) { + for (uint32_t point_id = 2; point_id < begin_poly->points.size(); point_id++) { Triangle2 t(begin_poly->points[0].pos, begin_poly->points[point_id - 1].pos, begin_poly->points[point_id].pos); Vector2 spoint = t.get_closest_point_to(p_target_position); real_t dpoint = spoint.distance_squared_to(p_target_position); @@ -443,7 +443,7 @@ void NavMeshQueries2D::_query_task_build_path_corridor(NavMeshPathQueryTask2D &p if (!found_route) { real_t end_d = FLT_MAX; // Search all faces of the start polygon for the closest point to our target position. - for (size_t point_id = 2; point_id < begin_poly->points.size(); point_id++) { + for (uint32_t point_id = 2; point_id < begin_poly->points.size(); point_id++) { Triangle2 t(begin_poly->points[0].pos, begin_poly->points[point_id - 1].pos, begin_poly->points[point_id].pos); Vector2 spoint = t.get_closest_point_to(p_target_position); real_t dpoint = spoint.distance_squared_to(p_target_position); @@ -743,7 +743,7 @@ ClosestPointQueryResult NavMeshQueries2D::map_iteration_get_closest_point_info(c real_t closest = FLT_MAX; bool inside = true; Vector2 previous = polygon.points[polygon.points.size() - 1].pos; - for (size_t point_id = 0; point_id < polygon.points.size(); ++point_id) { + for (uint32_t point_id = 0; point_id < polygon.points.size(); ++point_id) { Vector2 edge = polygon.points[point_id].pos - previous; Vector2 to_point = p_point - previous; real_t edge_to_point_cross = edge.cross(to_point); @@ -875,7 +875,7 @@ ClosestPointQueryResult NavMeshQueries2D::polygons_get_closest_point_info(const real_t closest = FLT_MAX; bool inside = true; Vector2 previous = polygon.points[polygon.points.size() - 1].pos; - for (size_t point_id = 0; point_id < polygon.points.size(); ++point_id) { + for (uint32_t point_id = 0; point_id < polygon.points.size(); ++point_id) { Vector2 edge = polygon.points[point_id].pos - previous; Vector2 to_point = p_point - previous; real_t edge_to_point_cross = edge.cross(to_point); diff --git a/modules/navigation_3d/3d/nav_mesh_queries_3d.cpp b/modules/navigation_3d/3d/nav_mesh_queries_3d.cpp index 761fe9dfd14e..f625df91437c 100644 --- a/modules/navigation_3d/3d/nav_mesh_queries_3d.cpp +++ b/modules/navigation_3d/3d/nav_mesh_queries_3d.cpp @@ -255,7 +255,7 @@ void NavMeshQueries3D::_query_task_find_start_end_positions(NavMeshPathQueryTask } // For each face check the distance between the origin/destination. - for (size_t point_id = 2; point_id < p.points.size(); point_id++) { + for (uint32_t point_id = 2; point_id < p.points.size(); point_id++) { const Face3 face(p.points[0].pos, p.points[point_id - 1].pos, p.points[point_id].pos); Vector3 point = face.get_closest_point_to(p_query_task.start_position); @@ -370,7 +370,7 @@ void NavMeshQueries3D::_query_task_build_path_corridor(NavMeshPathQueryTask3D &p // Set as end point the furthest reachable point. end_poly = reachable_end; real_t end_d = FLT_MAX; - for (size_t point_id = 2; point_id < end_poly->points.size(); point_id++) { + for (uint32_t point_id = 2; point_id < end_poly->points.size(); point_id++) { Face3 f(end_poly->points[0].pos, end_poly->points[point_id - 1].pos, end_poly->points[point_id].pos); Vector3 spoint = f.get_closest_point_to(p_target_position); real_t dpoint = spoint.distance_squared_to(p_target_position); @@ -382,7 +382,7 @@ void NavMeshQueries3D::_query_task_build_path_corridor(NavMeshPathQueryTask3D &p // Search all faces of start polygon as well. bool closest_point_on_start_poly = false; - for (size_t point_id = 2; point_id < begin_poly->points.size(); point_id++) { + for (uint32_t point_id = 2; point_id < begin_poly->points.size(); point_id++) { Face3 f(begin_poly->points[0].pos, begin_poly->points[point_id - 1].pos, begin_poly->points[point_id].pos); Vector3 spoint = f.get_closest_point_to(p_target_position); real_t dpoint = spoint.distance_squared_to(p_target_position); @@ -441,7 +441,7 @@ void NavMeshQueries3D::_query_task_build_path_corridor(NavMeshPathQueryTask3D &p if (!found_route) { real_t end_d = FLT_MAX; // Search all faces of the start polygon for the closest point to our target position. - for (size_t point_id = 2; point_id < begin_poly->points.size(); point_id++) { + for (uint32_t point_id = 2; point_id < begin_poly->points.size(); point_id++) { Face3 f(begin_poly->points[0].pos, begin_poly->points[point_id - 1].pos, begin_poly->points[point_id].pos); Vector3 spoint = f.get_closest_point_to(p_target_position); real_t dpoint = spoint.distance_squared_to(p_target_position); @@ -726,7 +726,7 @@ Vector3 NavMeshQueries3D::map_iteration_get_closest_point_to_segment(const NavMa for (const NavRegionIteration3D ®ion : regions) { for (const Polygon &polygon : region.get_navmesh_polygons()) { // For each face check the distance to the segment. - for (size_t point_id = 2; point_id < polygon.points.size(); point_id += 1) { + for (uint32_t point_id = 2; point_id < polygon.points.size(); point_id += 1) { const Face3 face(polygon.points[0].pos, polygon.points[point_id - 1].pos, polygon.points[point_id].pos); Vector3 intersection_point; if (face.intersects_segment(p_from, p_to, &intersection_point)) { @@ -759,7 +759,7 @@ Vector3 NavMeshQueries3D::map_iteration_get_closest_point_to_segment(const NavMa } // Finally, check for a case when shortest distance is between some point located on a face's edge and some point located on a line segment. if (!use_collision) { - for (size_t point_id = 0; point_id < polygon.points.size(); point_id += 1) { + for (uint32_t point_id = 0; point_id < polygon.points.size(); point_id += 1) { Vector3 a, b; Geometry3D::get_closest_points_between_segments( @@ -810,7 +810,7 @@ ClosestPointQueryResult NavMeshQueries3D::map_iteration_get_closest_point_info(c real_t closest = FLT_MAX; bool inside = true; Vector3 previous = polygon.points[polygon.points.size() - 1].pos; - for (size_t point_id = 0; point_id < polygon.points.size(); ++point_id) { + for (uint32_t point_id = 0; point_id < polygon.points.size(); ++point_id) { Vector3 edge = polygon.points[point_id].pos - previous; Vector3 to_point = p_point - previous; Vector3 edge_to_point_pormal = edge.cross(to_point); @@ -941,7 +941,7 @@ Vector3 NavMeshQueries3D::polygons_get_closest_point_to_segment(const LocalVecto for (const Polygon &polygon : p_polygons) { // For each face check the distance to the segment. - for (size_t point_id = 2; point_id < polygon.points.size(); point_id += 1) { + for (uint32_t point_id = 2; point_id < polygon.points.size(); point_id += 1) { const Face3 face(polygon.points[0].pos, polygon.points[point_id - 1].pos, polygon.points[point_id].pos); Vector3 intersection_point; if (face.intersects_segment(p_from, p_to, &intersection_point)) { @@ -974,7 +974,7 @@ Vector3 NavMeshQueries3D::polygons_get_closest_point_to_segment(const LocalVecto } // Finally, check for a case when shortest distance is between some point located on a face's edge and some point located on a line segment. if (!use_collision) { - for (size_t point_id = 0; point_id < polygon.points.size(); point_id += 1) { + for (uint32_t point_id = 0; point_id < polygon.points.size(); point_id += 1) { Vector3 a, b; Geometry3D::get_closest_points_between_segments( @@ -1017,7 +1017,7 @@ ClosestPointQueryResult NavMeshQueries3D::polygons_get_closest_point_info(const real_t closest = FLT_MAX; bool inside = true; Vector3 previous = polygon.points[polygon.points.size() - 1].pos; - for (size_t point_id = 0; point_id < polygon.points.size(); ++point_id) { + for (uint32_t point_id = 0; point_id < polygon.points.size(); ++point_id) { Vector3 edge = polygon.points[point_id].pos - previous; Vector3 to_point = p_point - previous; Vector3 edge_to_point_pormal = edge.cross(to_point); From 453baf353a73b34b8dba96f62a213cbfa16adb5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Tue, 1 Apr 2025 11:59:04 +0300 Subject: [PATCH 013/111] Enable TTS on demand, instead of fully disabling it when project setting is not set. --- doc/classes/DisplayServer.xml | 9 -- doc/classes/ProjectSettings.xml | 2 +- platform/android/tts_android.cpp | 93 +++++++++++++------ platform/android/tts_android.h | 2 + platform/ios/display_server_ios.h | 2 + platform/ios/display_server_ios.mm | 40 ++++++-- .../wayland/display_server_wayland.cpp | 30 +++++- .../linuxbsd/wayland/display_server_wayland.h | 2 + platform/linuxbsd/x11/display_server_x11.cpp | 41 ++++++-- platform/linuxbsd/x11/display_server_x11.h | 2 + platform/macos/display_server_macos.h | 2 + platform/macos/display_server_macos.mm | 41 ++++++-- platform/web/display_server_web.cpp | 10 +- platform/web/display_server_web.h | 1 - platform/windows/display_server_windows.cpp | 41 ++++++-- platform/windows/display_server_windows.h | 2 + 16 files changed, 238 insertions(+), 82 deletions(-) diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index 7e6e579114e8..2922ebe3d2ba 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -1325,7 +1325,6 @@ - [code]language[/code] is language code in [code]lang_Variant[/code] format. The [code]lang[/code] part is a 2 or 3-letter code based on the ISO-639 standard, in lowercase. The [code skip-lint]Variant[/code] part is an engine-dependent string describing country, region or/and dialect. Note that Godot depends on system libraries for text-to-speech functionality. These libraries are installed by default on Windows and macOS, but not on all Linux distributions. If they are not present, this method will return an empty list. This applies to both Godot users on Linux, as well as end-users on Linux running Godot games that use text-to-speech. [b]Note:[/b] This method is implemented on Android, iOS, Web, Linux (X11/Wayland), macOS, and Windows. - [b]Note:[/b] [member ProjectSettings.audio/general/text_to_speech] should be [code]true[/code] to use text-to-speech. @@ -1334,7 +1333,6 @@ Returns an [PackedStringArray] of voice identifiers for the [param language]. [b]Note:[/b] This method is implemented on Android, iOS, Web, Linux (X11/Wayland), macOS, and Windows. - [b]Note:[/b] [member ProjectSettings.audio/general/text_to_speech] should be [code]true[/code] to use text-to-speech. @@ -1342,7 +1340,6 @@ Returns [code]true[/code] if the synthesizer is in a paused state. [b]Note:[/b] This method is implemented on Android, iOS, Web, Linux (X11/Wayland), macOS, and Windows. - [b]Note:[/b] [member ProjectSettings.audio/general/text_to_speech] should be [code]true[/code] to use text-to-speech. @@ -1350,7 +1347,6 @@ Returns [code]true[/code] if the synthesizer is generating speech, or have utterance waiting in the queue. [b]Note:[/b] This method is implemented on Android, iOS, Web, Linux (X11/Wayland), macOS, and Windows. - [b]Note:[/b] [member ProjectSettings.audio/general/text_to_speech] should be [code]true[/code] to use text-to-speech. @@ -1358,7 +1354,6 @@ Puts the synthesizer into a paused state. [b]Note:[/b] This method is implemented on Android, iOS, Web, Linux (X11/Wayland), macOS, and Windows. - [b]Note:[/b] [member ProjectSettings.audio/general/text_to_speech] should be [code]true[/code] to use text-to-speech. @@ -1366,7 +1361,6 @@ Resumes the synthesizer if it was paused. [b]Note:[/b] This method is implemented on Android, iOS, Web, Linux (X11/Wayland), macOS, and Windows. - [b]Note:[/b] [member ProjectSettings.audio/general/text_to_speech] should be [code]true[/code] to use text-to-speech. @@ -1379,7 +1373,6 @@ - [constant TTS_UTTERANCE_BOUNDARY] callable's method should take two [int] parameters, the index of the character and the utterance ID. [b]Note:[/b] The granularity of the boundary callbacks is engine dependent. [b]Note:[/b] This method is implemented on Android, iOS, Web, Linux (X11/Wayland), macOS, and Windows. - [b]Note:[/b] [member ProjectSettings.audio/general/text_to_speech] should be [code]true[/code] to use text-to-speech. @@ -1401,7 +1394,6 @@ [b]Note:[/b] On Windows and Linux (X11/Wayland), utterance [param text] can use SSML markup. SSML support is engine and voice dependent. If the engine does not support SSML, you should strip out all XML markup before calling [method tts_speak]. [b]Note:[/b] The granularity of pitch, rate, and volume is engine and voice dependent. Values may be truncated. [b]Note:[/b] This method is implemented on Android, iOS, Web, Linux (X11/Wayland), macOS, and Windows. - [b]Note:[/b] [member ProjectSettings.audio/general/text_to_speech] should be [code]true[/code] to use text-to-speech. @@ -1409,7 +1401,6 @@ Stops synthesis in progress and removes all utterances from the queue. [b]Note:[/b] This method is implemented on Android, iOS, Web, Linux (X11/Linux), macOS, and Windows. - [b]Note:[/b] [member ProjectSettings.audio/general/text_to_speech] should be [code]true[/code] to use text-to-speech. diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index cb145e866da7..05d8d617bc7e 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -437,7 +437,7 @@ Sets the [url=https://developer.apple.com/documentation/avfaudio/avaudiosessioncategory]AVAudioSessionCategory[/url] on iOS. Use the [code]Playback[/code] category to get sound output, even if the phone is in silent mode. - If [code]true[/code], text-to-speech support is enabled, see [method DisplayServer.tts_get_voices] and [method DisplayServer.tts_speak]. + If [code]true[/code], text-to-speech support is enabled on startup, otherwise it is enabled first time TTS method is used, see [method DisplayServer.tts_get_voices] and [method DisplayServer.tts_speak]. [b]Note:[/b] Enabling TTS can cause addition idle CPU usage and interfere with the sleep mode, so consider disabling it if TTS is not used. diff --git a/platform/android/tts_android.cpp b/platform/android/tts_android.cpp index d560f853f82d..3dd9ff7b3029 100644 --- a/platform/android/tts_android.cpp +++ b/platform/android/tts_android.cpp @@ -49,30 +49,37 @@ jmethodID TTS_Android::_stop_speaking = nullptr; HashMap TTS_Android::ids; +void TTS_Android::initialize_tts() { + JNIEnv *env = get_jni_env(); + ERR_FAIL_NULL(env); + + if (_init) { + env->CallVoidMethod(tts, _init); + initialized = true; + } +} + void TTS_Android::setup(jobject p_tts) { - bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech"); - if (tts_enabled) { - JNIEnv *env = get_jni_env(); - ERR_FAIL_NULL(env); + JNIEnv *env = get_jni_env(); + ERR_FAIL_NULL(env); - tts = env->NewGlobalRef(p_tts); + tts = env->NewGlobalRef(p_tts); - jclass c = env->GetObjectClass(tts); - cls = (jclass)env->NewGlobalRef(c); + jclass c = env->GetObjectClass(tts); + cls = (jclass)env->NewGlobalRef(c); - _init = env->GetMethodID(cls, "init", "()V"); - _is_speaking = env->GetMethodID(cls, "isSpeaking", "()Z"); - _is_paused = env->GetMethodID(cls, "isPaused", "()Z"); - _get_voices = env->GetMethodID(cls, "getVoices", "()[Ljava/lang/String;"); - _speak = env->GetMethodID(cls, "speak", "(Ljava/lang/String;Ljava/lang/String;IFFIZ)V"); - _pause_speaking = env->GetMethodID(cls, "pauseSpeaking", "()V"); - _resume_speaking = env->GetMethodID(cls, "resumeSpeaking", "()V"); - _stop_speaking = env->GetMethodID(cls, "stopSpeaking", "()V"); + _init = env->GetMethodID(cls, "init", "()V"); + _is_speaking = env->GetMethodID(cls, "isSpeaking", "()Z"); + _is_paused = env->GetMethodID(cls, "isPaused", "()Z"); + _get_voices = env->GetMethodID(cls, "getVoices", "()[Ljava/lang/String;"); + _speak = env->GetMethodID(cls, "speak", "(Ljava/lang/String;Ljava/lang/String;IFFIZ)V"); + _pause_speaking = env->GetMethodID(cls, "pauseSpeaking", "()V"); + _resume_speaking = env->GetMethodID(cls, "resumeSpeaking", "()V"); + _stop_speaking = env->GetMethodID(cls, "stopSpeaking", "()V"); - if (_init) { - env->CallVoidMethod(tts, _init); - initialized = true; - } + bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech"); + if (tts_enabled) { + initialize_tts(); } } @@ -80,12 +87,19 @@ void TTS_Android::terminate() { JNIEnv *env = get_jni_env(); ERR_FAIL_NULL(env); - env->DeleteGlobalRef(cls); - env->DeleteGlobalRef(tts); + if (cls) { + env->DeleteGlobalRef(cls); + } + if (tts) { + env->DeleteGlobalRef(tts); + } } void TTS_Android::_java_utterance_callback(int p_event, int p_id, int p_pos) { - ERR_FAIL_COND_MSG(!initialized, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!initialized)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); if (ids.has(p_id)) { int pos = 0; if ((DisplayServer::TTSUtteranceEvent)p_event == DisplayServer::TTS_UTTERANCE_BOUNDARY) { @@ -106,7 +120,10 @@ void TTS_Android::_java_utterance_callback(int p_event, int p_id, int p_pos) { } bool TTS_Android::is_speaking() { - ERR_FAIL_COND_V_MSG(!initialized, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!initialized)) { + initialize_tts(); + } + ERR_FAIL_NULL_V(tts, false); if (_is_speaking) { JNIEnv *env = get_jni_env(); @@ -118,7 +135,10 @@ bool TTS_Android::is_speaking() { } bool TTS_Android::is_paused() { - ERR_FAIL_COND_V_MSG(!initialized, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!initialized)) { + initialize_tts(); + } + ERR_FAIL_NULL_V(tts, false); if (_is_paused) { JNIEnv *env = get_jni_env(); @@ -130,7 +150,10 @@ bool TTS_Android::is_paused() { } Array TTS_Android::get_voices() { - ERR_FAIL_COND_V_MSG(!initialized, Array(), "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!initialized)) { + initialize_tts(); + } + ERR_FAIL_NULL_V(tts, Array()); Array list; if (_get_voices) { JNIEnv *env = get_jni_env(); @@ -158,7 +181,10 @@ Array TTS_Android::get_voices() { } void TTS_Android::speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) { - ERR_FAIL_COND_MSG(!initialized, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!initialized)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); if (p_interrupt) { stop(); } @@ -183,7 +209,10 @@ void TTS_Android::speak(const String &p_text, const String &p_voice, int p_volum } void TTS_Android::pause() { - ERR_FAIL_COND_MSG(!initialized, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!initialized)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); if (_pause_speaking) { JNIEnv *env = get_jni_env(); @@ -193,7 +222,10 @@ void TTS_Android::pause() { } void TTS_Android::resume() { - ERR_FAIL_COND_MSG(!initialized, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!initialized)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); if (_resume_speaking) { JNIEnv *env = get_jni_env(); @@ -203,7 +235,10 @@ void TTS_Android::resume() { } void TTS_Android::stop() { - ERR_FAIL_COND_MSG(!initialized, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!initialized)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); for (const KeyValue &E : ids) { DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_CANCELED, E.key); } diff --git a/platform/android/tts_android.h b/platform/android/tts_android.h index 86068e20c4f9..063af55271ef 100644 --- a/platform/android/tts_android.h +++ b/platform/android/tts_android.h @@ -54,6 +54,8 @@ class TTS_Android { static HashMap ids; + static void initialize_tts(); + public: static void setup(jobject p_tts); static void terminate(); diff --git a/platform/ios/display_server_ios.h b/platform/ios/display_server_ios.h index b88e41156102..f0cd2fceda6a 100644 --- a/platform/ios/display_server_ios.h +++ b/platform/ios/display_server_ios.h @@ -83,6 +83,8 @@ class DisplayServerIOS : public DisplayServer { void perform_event(const Ref &p_event); + void initialize_tts() const; + DisplayServerIOS(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error); ~DisplayServerIOS(); diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm index 3fbc7f467d5d..4a5a05d0eced 100644 --- a/platform/ios/display_server_ios.mm +++ b/platform/ios/display_server_ios.mm @@ -61,7 +61,7 @@ // Init TTS bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech"); if (tts_enabled) { - tts = [[TTS_IOS alloc] init]; + initialize_tts(); } native_menu = memnew(NativeMenu); @@ -389,39 +389,63 @@ String DisplayServerIOS::get_name() const { return "iOS"; } +void DisplayServerIOS::initialize_tts() const { + const_cast(this)->tts = [[TTS_IOS alloc] init]; +} bool DisplayServerIOS::tts_is_speaking() const { - ERR_FAIL_NULL_V_MSG(tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL_V(tts, false); return [tts isSpeaking]; } bool DisplayServerIOS::tts_is_paused() const { - ERR_FAIL_NULL_V_MSG(tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL_V(tts, false); return [tts isPaused]; } TypedArray DisplayServerIOS::tts_get_voices() const { - ERR_FAIL_NULL_V_MSG(tts, TypedArray(), "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL_V(tts, TypedArray()); return [tts getVoices]; } void DisplayServerIOS::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) { - ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); [tts speak:p_text voice:p_voice volume:p_volume pitch:p_pitch rate:p_rate utterance_id:p_utterance_id interrupt:p_interrupt]; } void DisplayServerIOS::tts_pause() { - ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); [tts pauseSpeaking]; } void DisplayServerIOS::tts_resume() { - ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); [tts resumeSpeaking]; } void DisplayServerIOS::tts_stop() { - ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); [tts stopSpeaking]; } diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index 160b1a364b48..1fe5df1d7709 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -245,37 +245,62 @@ String DisplayServerWayland::get_name() const { #ifdef SPEECHD_ENABLED +void DisplayServerWayland::initialize_tts() const { + const_cast(this)->tts = memnew(TTS_Linux); +} + bool DisplayServerWayland::tts_is_speaking() const { + if (unlikely(!tts)) { + initialize_tts(); + } ERR_FAIL_NULL_V(tts, false); return tts->is_speaking(); } bool DisplayServerWayland::tts_is_paused() const { + if (unlikely(!tts)) { + initialize_tts(); + } ERR_FAIL_NULL_V(tts, false); return tts->is_paused(); } TypedArray DisplayServerWayland::tts_get_voices() const { + if (unlikely(!tts)) { + initialize_tts(); + } ERR_FAIL_NULL_V(tts, TypedArray()); return tts->get_voices(); } void DisplayServerWayland::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) { + if (unlikely(!tts)) { + initialize_tts(); + } ERR_FAIL_NULL(tts); tts->speak(p_text, p_voice, p_volume, p_pitch, p_rate, p_utterance_id, p_interrupt); } void DisplayServerWayland::tts_pause() { + if (unlikely(!tts)) { + initialize_tts(); + } ERR_FAIL_NULL(tts); tts->pause(); } void DisplayServerWayland::tts_resume() { + if (unlikely(!tts)) { + initialize_tts(); + } ERR_FAIL_NULL(tts); tts->resume(); } void DisplayServerWayland::tts_stop() { + if (unlikely(!tts)) { + initialize_tts(); + } ERR_FAIL_NULL(tts); tts->stop(); } @@ -1439,7 +1464,10 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win #ifdef SPEECHD_ENABLED // Init TTS - tts = memnew(TTS_Linux); + bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech"); + if (tts_enabled) { + initialize_tts(); + } #endif rendering_driver = p_rendering_driver; diff --git a/platform/linuxbsd/wayland/display_server_wayland.h b/platform/linuxbsd/wayland/display_server_wayland.h index 1b32cb75f371..c5f7e0548d24 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.h +++ b/platform/linuxbsd/wayland/display_server_wayland.h @@ -165,6 +165,8 @@ class DisplayServerWayland : public DisplayServer { void try_suspend(); + void initialize_tts() const; + public: virtual bool has_feature(Feature p_feature) const override; diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index 577e2d19593b..edc6f8488098 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -340,38 +340,63 @@ void DisplayServerX11::_flush_mouse_motion() { #ifdef SPEECHD_ENABLED +void DisplayServerX11::initialize_tts() const { + const_cast(this)->tts = memnew(TTS_Linux); +} + bool DisplayServerX11::tts_is_speaking() const { - ERR_FAIL_NULL_V_MSG(tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL_V(tts, false); return tts->is_speaking(); } bool DisplayServerX11::tts_is_paused() const { - ERR_FAIL_NULL_V_MSG(tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL_V(tts, false); return tts->is_paused(); } TypedArray DisplayServerX11::tts_get_voices() const { - ERR_FAIL_NULL_V_MSG(tts, TypedArray(), "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL_V(tts, TypedArray()); return tts->get_voices(); } void DisplayServerX11::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) { - ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); tts->speak(p_text, p_voice, p_volume, p_pitch, p_rate, p_utterance_id, p_interrupt); } void DisplayServerX11::tts_pause() { - ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); tts->pause(); } void DisplayServerX11::tts_resume() { - ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); tts->resume(); } void DisplayServerX11::tts_stop() { - ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); tts->stop(); } @@ -6781,7 +6806,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode // Init TTS bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech"); if (tts_enabled) { - tts = memnew(TTS_Linux); + initialize_tts(); } #endif diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h index 56c9b0d952f3..fe9322ae5659 100644 --- a/platform/linuxbsd/x11/display_server_x11.h +++ b/platform/linuxbsd/x11/display_server_x11.h @@ -394,6 +394,8 @@ class DisplayServerX11 : public DisplayServer { void _set_window_taskbar_pager_enabled(Window p_window, bool p_enabled); Rect2i _screens_get_full_rect() const; + void initialize_tts() const; + protected: void _window_changed(XEvent *event); diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h index 8119d07a5348..e6cfd976ae43 100644 --- a/platform/macos/display_server_macos.h +++ b/platform/macos/display_server_macos.h @@ -237,6 +237,8 @@ class DisplayServerMacOS : public DisplayServer { Error _file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector &p_filters, const TypedArray &p_options, const Callable &p_callback, bool p_options_in_cb, WindowID p_window_id); + void initialize_tts() const; + public: void menu_callback(id p_sender); diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 610b2cdebb70..942d3a27e3e9 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -858,38 +858,63 @@ return help_action_callback; } +void DisplayServerMacOS::initialize_tts() const { + const_cast(this)->tts = [[TTS_MacOS alloc] init]; +} + bool DisplayServerMacOS::tts_is_speaking() const { - ERR_FAIL_NULL_V_MSG(tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL_V(tts, false); return [tts isSpeaking]; } bool DisplayServerMacOS::tts_is_paused() const { - ERR_FAIL_NULL_V_MSG(tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL_V(tts, false); return [tts isPaused]; } TypedArray DisplayServerMacOS::tts_get_voices() const { - ERR_FAIL_NULL_V_MSG(tts, Array(), "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL_V(tts, TypedArray()); return [tts getVoices]; } void DisplayServerMacOS::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) { - ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); [tts speak:p_text voice:p_voice volume:p_volume pitch:p_pitch rate:p_rate utterance_id:p_utterance_id interrupt:p_interrupt]; } void DisplayServerMacOS::tts_pause() { - ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); [tts pauseSpeaking]; } void DisplayServerMacOS::tts_resume() { - ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); [tts resumeSpeaking]; } void DisplayServerMacOS::tts_stop() { - ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); [tts stopSpeaking]; } @@ -3753,7 +3778,7 @@ // Init TTS bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech"); if (tts_enabled) { - tts = [[TTS_MacOS alloc] init]; + initialize_tts(); } native_menu = memnew(NativeMenuMacOS); diff --git a/platform/web/display_server_web.cpp b/platform/web/display_server_web.cpp index 180c05ef411d..8e99ee27d81f 100644 --- a/platform/web/display_server_web.cpp +++ b/platform/web/display_server_web.cpp @@ -384,12 +384,10 @@ const char *DisplayServerWeb::godot2dom_cursor(DisplayServer::CursorShape p_shap } bool DisplayServerWeb::tts_is_speaking() const { - ERR_FAIL_COND_V_MSG(!tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); return godot_js_tts_is_speaking(); } bool DisplayServerWeb::tts_is_paused() const { - ERR_FAIL_COND_V_MSG(!tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); return godot_js_tts_is_paused(); } @@ -424,13 +422,11 @@ void DisplayServerWeb::_update_voices_callback(const Vector &p_voices) { } TypedArray DisplayServerWeb::tts_get_voices() const { - ERR_FAIL_COND_V_MSG(!tts, TypedArray(), "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); godot_js_tts_get_voices(update_voices_callback); return voices; } void DisplayServerWeb::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) { - ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); if (p_interrupt) { tts_stop(); } @@ -447,17 +443,14 @@ void DisplayServerWeb::tts_speak(const String &p_text, const String &p_voice, in } void DisplayServerWeb::tts_pause() { - ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); godot_js_tts_pause(); } void DisplayServerWeb::tts_resume() { - ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); godot_js_tts_resume(); } void DisplayServerWeb::tts_stop() { - ERR_FAIL_COND_MSG(!tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); for (const KeyValue &E : utterance_ids) { tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_CANCELED, E.key); } @@ -1086,7 +1079,6 @@ DisplayServer *DisplayServerWeb::create_func(const String &p_rendering_driver, W DisplayServerWeb::DisplayServerWeb(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error) { r_error = OK; // Always succeeds for now. - tts = GLOBAL_GET("audio/general/text_to_speech"); native_menu = memnew(NativeMenu); // Dummy native menu. // Ensure the canvas ID. @@ -1199,7 +1191,7 @@ bool DisplayServerWeb::has_feature(Feature p_feature) const { case FEATURE_VIRTUAL_KEYBOARD: return godot_js_display_vk_available() != 0; case FEATURE_TEXT_TO_SPEECH: - return tts && (godot_js_display_tts_available() != 0); + return godot_js_display_tts_available() != 0; default: return false; } diff --git a/platform/web/display_server_web.h b/platform/web/display_server_web.h index 8eadda8539c8..858e35bfc337 100644 --- a/platform/web/display_server_web.h +++ b/platform/web/display_server_web.h @@ -102,7 +102,6 @@ class DisplayServerWeb : public DisplayServer { int key_event_pos = 0; bool swap_cancel_ok = false; - bool tts = false; NativeMenu *native_menu = nullptr; MouseMode mouse_mode_base = MOUSE_MODE_VISIBLE; diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 9a3f884aeff6..79de8c4b135e 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -254,38 +254,63 @@ void DisplayServerWindows::_register_raw_input_devices(WindowID p_target_window) } } +void DisplayServerWindows::initialize_tts() const { + const_cast(this)->tts = memnew(TTS_Windows); +} + bool DisplayServerWindows::tts_is_speaking() const { - ERR_FAIL_NULL_V_MSG(tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL_V(tts, false); return tts->is_speaking(); } bool DisplayServerWindows::tts_is_paused() const { - ERR_FAIL_NULL_V_MSG(tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL_V(tts, false); return tts->is_paused(); } TypedArray DisplayServerWindows::tts_get_voices() const { - ERR_FAIL_NULL_V_MSG(tts, TypedArray(), "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL_V(tts, TypedArray()); return tts->get_voices(); } void DisplayServerWindows::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) { - ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); tts->speak(p_text, p_voice, p_volume, p_pitch, p_rate, p_utterance_id, p_interrupt); } void DisplayServerWindows::tts_pause() { - ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); tts->pause(); } void DisplayServerWindows::tts_resume() { - ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); tts->resume(); } void DisplayServerWindows::tts_stop() { - ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech."); + if (unlikely(!tts)) { + initialize_tts(); + } + ERR_FAIL_NULL(tts); tts->stop(); } @@ -6626,7 +6651,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win // Init TTS bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech"); if (tts_enabled) { - tts = memnew(TTS_Windows); + initialize_tts(); } native_menu = memnew(NativeMenuWindows); diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 432a293d2f07..cf50408f760a 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -687,6 +687,8 @@ class DisplayServerWindows : public DisplayServer { HWND _find_window_from_process_id(OS::ProcessID p_pid, HWND p_current_hwnd); + void initialize_tts() const; + public: LRESULT WndProcFileDialog(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); From 9d7e47acfe2fd5ec6b88d9db61a7d57589c15200 Mon Sep 17 00:00:00 2001 From: Michael Alexsander Date: Sun, 30 Mar 2025 13:20:04 -0300 Subject: [PATCH 014/111] Allow to compile templates without navigation features --- SConstruct | 16 +- core/config/project_settings.cpp | 2 + editor/import/3d/resource_importer_scene.cpp | 2 +- .../navigation_link_3d_gizmo_plugin.cpp | 2 +- .../navigation_region_3d_gizmo_plugin.cpp | 2 +- .../mesh_instance_3d_editor_plugin.cpp | 2 +- editor/plugins/mesh_library_editor_plugin.cpp | 2 +- .../navigation_link_2d_editor_plugin.h | 2 +- .../navigation_obstacle_2d_editor_plugin.h | 2 +- .../navigation_obstacle_3d_editor_plugin.cpp | 2 +- .../navigation_polygon_editor_plugin.cpp | 2 +- main/main.cpp | 54 +++++- main/performance.cpp | 123 ++++++++++--- modules/csg/csg_shape.cpp | 4 + modules/csg/csg_shape.h | 2 + modules/csg/register_types.cpp | 2 + modules/gridmap/grid_map.cpp | 51 ++++-- modules/gridmap/grid_map.h | 10 +- modules/gridmap/register_types.cpp | 2 + modules/navigation_2d/config.py | 2 +- .../3d/navigation_mesh_generator.h | 2 +- modules/navigation_3d/config.py | 5 +- .../editor/navigation_mesh_editor_plugin.cpp | 2 +- scene/2d/SCsub | 2 + scene/2d/mesh_instance_2d.cpp | 5 +- scene/2d/mesh_instance_2d.h | 2 + scene/2d/multimesh_instance_2d.cpp | 5 +- scene/2d/multimesh_instance_2d.h | 2 + scene/2d/navigation/SCsub | 6 + .../{ => navigation}/navigation_agent_2d.cpp | 2 +- .../2d/{ => navigation}/navigation_agent_2d.h | 0 .../{ => navigation}/navigation_link_2d.cpp | 0 .../2d/{ => navigation}/navigation_link_2d.h | 0 .../navigation_obstacle_2d.cpp | 0 .../{ => navigation}/navigation_obstacle_2d.h | 0 .../{ => navigation}/navigation_region_2d.cpp | 0 .../{ => navigation}/navigation_region_2d.h | 0 scene/2d/physics/static_body_2d.cpp | 4 + scene/2d/physics/static_body_2d.h | 2 + scene/2d/polygon_2d.cpp | 6 + scene/2d/polygon_2d.h | 4 + scene/2d/tile_map.compat.inc | 4 + scene/2d/tile_map.cpp | 20 +++ scene/2d/tile_map.h | 16 +- scene/2d/tile_map_layer.cpp | 18 +- scene/2d/tile_map_layer.h | 8 + scene/3d/SCsub | 2 + scene/3d/mesh_instance_3d.cpp | 11 +- scene/3d/mesh_instance_3d.h | 6 + scene/3d/multimesh_instance_3d.cpp | 4 + scene/3d/multimesh_instance_3d.h | 6 + scene/3d/navigation/SCsub | 6 + .../{ => navigation}/navigation_agent_3d.cpp | 2 +- .../3d/{ => navigation}/navigation_agent_3d.h | 0 .../{ => navigation}/navigation_link_3d.cpp | 0 .../3d/{ => navigation}/navigation_link_3d.h | 0 .../navigation_obstacle_3d.cpp | 0 .../{ => navigation}/navigation_obstacle_3d.h | 0 .../{ => navigation}/navigation_region_3d.cpp | 0 .../{ => navigation}/navigation_region_3d.h | 0 scene/3d/physics/static_body_3d.cpp | 4 + scene/3d/physics/static_body_3d.h | 4 + scene/register_scene_types.cpp | 79 ++++++--- scene/resources/2d/SCsub | 7 +- scene/resources/2d/tile_set.compat.inc | 4 + scene/resources/2d/tile_set.cpp | 166 +++++++++++------- scene/resources/2d/tile_set.h | 33 ++-- scene/resources/3d/SCsub | 3 +- scene/resources/world_2d.cpp | 16 +- scene/resources/world_2d.h | 4 + servers/navigation/SCsub | 8 +- servers/register_server_types.cpp | 14 +- tests/scene/test_navigation_agent_2d.h | 2 +- tests/scene/test_navigation_agent_3d.h | 2 +- tests/scene/test_navigation_obstacle_2d.h | 2 +- tests/scene/test_navigation_obstacle_3d.h | 2 +- tests/scene/test_navigation_region_2d.h | 2 +- tests/scene/test_navigation_region_3d.h | 2 +- tests/test_main.cpp | 69 +++++--- 79 files changed, 653 insertions(+), 208 deletions(-) create mode 100644 scene/2d/navigation/SCsub rename scene/2d/{ => navigation}/navigation_agent_2d.cpp (99%) rename scene/2d/{ => navigation}/navigation_agent_2d.h (100%) rename scene/2d/{ => navigation}/navigation_link_2d.cpp (100%) rename scene/2d/{ => navigation}/navigation_link_2d.h (100%) rename scene/2d/{ => navigation}/navigation_obstacle_2d.cpp (100%) rename scene/2d/{ => navigation}/navigation_obstacle_2d.h (100%) rename scene/2d/{ => navigation}/navigation_region_2d.cpp (100%) rename scene/2d/{ => navigation}/navigation_region_2d.h (100%) create mode 100644 scene/3d/navigation/SCsub rename scene/3d/{ => navigation}/navigation_agent_3d.cpp (99%) rename scene/3d/{ => navigation}/navigation_agent_3d.h (100%) rename scene/3d/{ => navigation}/navigation_link_3d.cpp (100%) rename scene/3d/{ => navigation}/navigation_link_3d.h (100%) rename scene/3d/{ => navigation}/navigation_obstacle_3d.cpp (100%) rename scene/3d/{ => navigation}/navigation_obstacle_3d.h (100%) rename scene/3d/{ => navigation}/navigation_region_3d.cpp (100%) rename scene/3d/{ => navigation}/navigation_region_3d.h (100%) diff --git a/SConstruct b/SConstruct index 7c8f4c4e775a..0f337a6e3140 100644 --- a/SConstruct +++ b/SConstruct @@ -222,6 +222,8 @@ opts.Add(BoolVariable("disable_3d", "Disable 3D nodes for a smaller executable", opts.Add(BoolVariable("disable_advanced_gui", "Disable advanced GUI nodes and behaviors", False)) opts.Add(BoolVariable("disable_physics_2d", "Disable 2D physics nodes and server", False)) opts.Add(BoolVariable("disable_physics_3d", "Disable 3D physics nodes and server", False)) +opts.Add(BoolVariable("disable_navigation_2d", "Disable 2D navigation features", False)) +opts.Add(BoolVariable("disable_navigation_3d", "Disable 3D navigation features", False)) opts.Add(BoolVariable("disable_xr", "Disable XR nodes and server", False)) opts.Add("build_profile", "Path to a file containing a feature build profile", "") opts.Add(BoolVariable("modules_enabled_by_default", "If no, disable all modules except ones explicitly enabled", True)) @@ -934,7 +936,14 @@ sys.modules.pop("detect") if env.editor_build: unsupported_opts = [] - for disable_opt in ["disable_3d", "disable_advanced_gui", "disable_physics_2d", "disable_physics_3d"]: + for disable_opt in [ + "disable_3d", + "disable_advanced_gui", + "disable_physics_2d", + "disable_physics_3d", + "disable_navigation_2d", + "disable_navigation_3d", + ]: if env[disable_opt]: unsupported_opts.append(disable_opt) if unsupported_opts != []: @@ -948,6 +957,7 @@ if env.editor_build: if env["disable_3d"]: env.Append(CPPDEFINES=["_3D_DISABLED"]) env["disable_physics_3d"] = True + env["disable_navigation_3d"] = True env["disable_xr"] = True if env["disable_advanced_gui"]: env.Append(CPPDEFINES=["ADVANCED_GUI_DISABLED"]) @@ -955,6 +965,10 @@ if env["disable_physics_2d"]: env.Append(CPPDEFINES=["PHYSICS_2D_DISABLED"]) if env["disable_physics_3d"]: env.Append(CPPDEFINES=["PHYSICS_3D_DISABLED"]) +if env["disable_navigation_2d"]: + env.Append(CPPDEFINES=["NAVIGATION_2D_DISABLED"]) +if env["disable_navigation_3d"]: + env.Append(CPPDEFINES=["NAVIGATION_3D_DISABLED"]) if env["disable_xr"]: env.Append(CPPDEFINES=["XR_DISABLED"]) if env["minizip"]: diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index bbcb36808041..c328332387d9 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -1630,6 +1630,7 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF_INTERNAL("internationalization/locale/translations_pot_files", PackedStringArray()); GLOBAL_DEF_INTERNAL("internationalization/locale/translation_add_builtin_strings_to_pot", false); +#if !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) GLOBAL_DEF("navigation/world/map_use_async_iterations", true); GLOBAL_DEF("navigation/avoidance/thread_model/avoidance_use_multiple_threads", true); @@ -1640,6 +1641,7 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("navigation/baking/use_crash_prevention_checks", true); GLOBAL_DEF("navigation/baking/thread_model/baking_use_multiple_threads", true); GLOBAL_DEF("navigation/baking/thread_model/baking_use_high_priority_threads", true); +#endif // !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) ProjectSettings::get_singleton()->add_hidden_prefix("input/"); } diff --git a/editor/import/3d/resource_importer_scene.cpp b/editor/import/3d/resource_importer_scene.cpp index 211ee77ca197..818d3d69034b 100644 --- a/editor/import/3d/resource_importer_scene.cpp +++ b/editor/import/3d/resource_importer_scene.cpp @@ -40,7 +40,7 @@ #include "editor/import/3d/scene_import_settings.h" #include "scene/3d/importer_mesh_instance_3d.h" #include "scene/3d/mesh_instance_3d.h" -#include "scene/3d/navigation_region_3d.h" +#include "scene/3d/navigation/navigation_region_3d.h" #include "scene/3d/occluder_instance_3d.h" #include "scene/3d/physics/area_3d.h" #include "scene/3d/physics/collision_shape_3d.h" diff --git a/editor/plugins/gizmos/navigation_link_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/navigation_link_3d_gizmo_plugin.cpp index 0e47fcf0169b..cd836aae6903 100644 --- a/editor/plugins/gizmos/navigation_link_3d_gizmo_plugin.cpp +++ b/editor/plugins/gizmos/navigation_link_3d_gizmo_plugin.cpp @@ -32,7 +32,7 @@ #include "editor/editor_undo_redo_manager.h" #include "editor/plugins/node_3d_editor_plugin.h" -#include "scene/3d/navigation_link_3d.h" +#include "scene/3d/navigation/navigation_link_3d.h" #include "servers/navigation_server_3d.h" NavigationLink3DGizmoPlugin::NavigationLink3DGizmoPlugin() { diff --git a/editor/plugins/gizmos/navigation_region_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/navigation_region_3d_gizmo_plugin.cpp index a15c801bd692..0a323a508761 100644 --- a/editor/plugins/gizmos/navigation_region_3d_gizmo_plugin.cpp +++ b/editor/plugins/gizmos/navigation_region_3d_gizmo_plugin.cpp @@ -31,7 +31,7 @@ #include "navigation_region_3d_gizmo_plugin.h" #include "core/math/random_pcg.h" -#include "scene/3d/navigation_region_3d.h" +#include "scene/3d/navigation/navigation_region_3d.h" #include "servers/navigation_server_3d.h" NavigationRegion3DGizmoPlugin::NavigationRegion3DGizmoPlugin() { diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp index 5ee746e34bae..6cd44eb3db81 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp @@ -36,7 +36,7 @@ #include "editor/multi_node_edit.h" #include "editor/plugins/node_3d_editor_plugin.h" #include "editor/themes/editor_scale.h" -#include "scene/3d/navigation_region_3d.h" +#include "scene/3d/navigation/navigation_region_3d.h" #include "scene/3d/physics/collision_shape_3d.h" #include "scene/3d/physics/static_body_3d.h" #include "scene/gui/aspect_ratio_container.h" diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp index 63f840cf4942..2688184caba9 100644 --- a/editor/plugins/mesh_library_editor_plugin.cpp +++ b/editor/plugins/mesh_library_editor_plugin.cpp @@ -39,7 +39,7 @@ #include "editor/plugins/node_3d_editor_plugin.h" #include "main/main.h" #include "scene/3d/mesh_instance_3d.h" -#include "scene/3d/navigation_region_3d.h" +#include "scene/3d/navigation/navigation_region_3d.h" #include "scene/3d/physics/static_body_3d.h" #include "scene/gui/menu_button.h" #include "scene/resources/packed_scene.h" diff --git a/editor/plugins/navigation_link_2d_editor_plugin.h b/editor/plugins/navigation_link_2d_editor_plugin.h index f5409dfb679f..d9715a71a04a 100644 --- a/editor/plugins/navigation_link_2d_editor_plugin.h +++ b/editor/plugins/navigation_link_2d_editor_plugin.h @@ -31,7 +31,7 @@ #pragma once #include "editor/plugins/editor_plugin.h" -#include "scene/2d/navigation_link_2d.h" +#include "scene/2d/navigation/navigation_link_2d.h" class CanvasItemEditor; diff --git a/editor/plugins/navigation_obstacle_2d_editor_plugin.h b/editor/plugins/navigation_obstacle_2d_editor_plugin.h index 78e867cf76e8..62f5520581af 100644 --- a/editor/plugins/navigation_obstacle_2d_editor_plugin.h +++ b/editor/plugins/navigation_obstacle_2d_editor_plugin.h @@ -31,7 +31,7 @@ #pragma once #include "editor/plugins/abstract_polygon_2d_editor.h" -#include "scene/2d/navigation_obstacle_2d.h" +#include "scene/2d/navigation/navigation_obstacle_2d.h" class NavigationObstacle2DEditor : public AbstractPolygon2DEditor { GDCLASS(NavigationObstacle2DEditor, AbstractPolygon2DEditor); diff --git a/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp b/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp index 01305fdf8c57..3505e66aa0a4 100644 --- a/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp +++ b/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp @@ -36,7 +36,7 @@ #include "editor/editor_string_names.h" #include "editor/editor_undo_redo_manager.h" #include "editor/plugins/node_3d_editor_plugin.h" -#include "scene/3d/navigation_obstacle_3d.h" +#include "scene/3d/navigation/navigation_obstacle_3d.h" #include "scene/gui/button.h" #include "scene/gui/dialogs.h" #include "servers/navigation_server_3d.h" diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp index 5368e1ab2358..777eb7aeeedc 100644 --- a/editor/plugins/navigation_polygon_editor_plugin.cpp +++ b/editor/plugins/navigation_polygon_editor_plugin.cpp @@ -33,7 +33,7 @@ #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" -#include "scene/2d/navigation_region_2d.h" +#include "scene/2d/navigation/navigation_region_2d.h" #include "scene/gui/dialogs.h" Ref NavigationPolygonEditor::_ensure_navpoly() const { diff --git a/main/main.cpp b/main/main.cpp index de9179fc567d..13c4bd098648 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -72,25 +72,30 @@ #include "servers/display_server.h" #include "servers/movie_writer/movie_writer.h" #include "servers/movie_writer/movie_writer_mjpeg.h" -#include "servers/navigation_server_3d.h" -#include "servers/navigation_server_3d_dummy.h" #include "servers/register_server_types.h" #include "servers/rendering/rendering_server_default.h" #include "servers/text/text_server_dummy.h" #include "servers/text_server.h" // 2D +#ifndef NAVIGATION_2D_DISABLED #include "servers/navigation_server_2d.h" #include "servers/navigation_server_2d_dummy.h" +#endif // NAVIGATION_2D_DISABLED #ifndef PHYSICS_2D_DISABLED #include "servers/physics_server_2d.h" #include "servers/physics_server_2d_dummy.h" #endif // PHYSICS_2D_DISABLED +// 3D #ifndef PHYSICS_3D_DISABLED #include "servers/physics_server_3d.h" #include "servers/physics_server_3d_dummy.h" #endif // PHYSICS_3D_DISABLED +#ifndef NAVIGATION_3D_DISABLED +#include "servers/navigation_server_3d.h" +#include "servers/navigation_server_3d_dummy.h" +#endif // NAVIGATION_3D_DISABLED #ifndef _3D_DISABLED #include "servers/xr_server.h" #endif // _3D_DISABLED @@ -754,8 +759,12 @@ Error Main::test_setup() { // Default theme will be initialized later, after modules and ScriptServer are ready. initialize_theme_db(); +#ifndef NAVIGATION_3D_DISABLED NavigationServer3DManager::initialize_server(); +#endif // NAVIGATION_3D_DISABLED +#ifndef NAVIGATION_2D_DISABLED NavigationServer2DManager::initialize_server(); +#endif // NAVIGATION_2D_DISABLED register_scene_types(); register_driver_types(); @@ -839,8 +848,12 @@ void Main::test_cleanup() { finalize_theme_db(); +#ifndef NAVIGATION_2D_DISABLED NavigationServer2DManager::finalize_server(); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED NavigationServer3DManager::finalize_server(); +#endif // NAVIGATION_3D_DISABLED GDExtensionManager::get_singleton()->deinitialize_extensions(GDExtension::INITIALIZATION_LEVEL_SERVERS); uninitialize_modules(MODULE_INITIALIZATION_LEVEL_SERVERS); @@ -3496,10 +3509,16 @@ Error Main::setup2(bool p_show_boot_logo) { // Default theme will be initialized later, after modules and ScriptServer are ready. initialize_theme_db(); +#if !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) MAIN_PRINT("Main: Load Navigation"); +#endif // !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) +#ifndef NAVIGATION_3D_DISABLED NavigationServer3DManager::initialize_server(); +#endif // NAVIGATION_3D_DISABLED +#ifndef NAVIGATION_2D_DISABLED NavigationServer2DManager::initialize_server(); +#endif // NAVIGATION_2D_DISABLED register_scene_types(); register_driver_types(); @@ -4102,20 +4121,33 @@ int Main::start() { if (debug_paths) { sml->set_debug_paths_hint(true); } + if (debug_navigation) { sml->set_debug_navigation_hint(true); +#ifndef NAVIGATION_2D_DISABLED NavigationServer2D::get_singleton()->set_debug_navigation_enabled(true); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED NavigationServer3D::get_singleton()->set_debug_navigation_enabled(true); +#endif // NAVIGATION_3D_DISABLED } if (debug_avoidance) { +#ifndef NAVIGATION_2D_DISABLED NavigationServer2D::get_singleton()->set_debug_avoidance_enabled(true); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED NavigationServer3D::get_singleton()->set_debug_avoidance_enabled(true); +#endif // NAVIGATION_3D_DISABLED } if (debug_navigation || debug_avoidance) { +#ifndef NAVIGATION_2D_DISABLED NavigationServer2D::get_singleton()->set_active(true); NavigationServer2D::get_singleton()->set_debug_enabled(true); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED NavigationServer3D::get_singleton()->set_active(true); NavigationServer3D::get_singleton()->set_debug_enabled(true); +#endif // NAVIGATION_3D_DISABLED } if (debug_canvas_item_redraw) { RenderingServer::get_singleton()->canvas_item_set_debug_redraw(true); @@ -4546,7 +4578,9 @@ bool Main::iteration() { uint64_t physics_process_ticks = 0; uint64_t process_ticks = 0; +#if !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) uint64_t navigation_process_ticks = 0; +#endif // !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) frame += ticks_elapsed; @@ -4565,8 +4599,12 @@ bool Main::iteration() { XRServer::get_singleton()->_process(); #endif // XR_DISABLED +#ifndef NAVIGATION_2D_DISABLED NavigationServer2D::get_singleton()->sync(); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED NavigationServer3D::get_singleton()->sync(); +#endif // NAVIGATION_3D_DISABLED for (int iters = 0; iters < advance.physics_steps; ++iters) { if (Input::get_singleton()->is_agile_input_event_flushing()) { @@ -4606,15 +4644,21 @@ bool Main::iteration() { break; } +#if !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) uint64_t navigation_begin = OS::get_singleton()->get_ticks_usec(); +#ifndef NAVIGATION_2D_DISABLED NavigationServer2D::get_singleton()->process(physics_step * time_scale); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED NavigationServer3D::get_singleton()->process(physics_step * time_scale); +#endif // NAVIGATION_3D_DISABLED navigation_process_ticks = MAX(navigation_process_ticks, OS::get_singleton()->get_ticks_usec() - navigation_begin); // keep the largest one for reference navigation_process_max = MAX(OS::get_singleton()->get_ticks_usec() - navigation_begin, navigation_process_max); message_queue->flush(); +#endif // !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) #ifndef PHYSICS_3D_DISABLED PhysicsServer3D::get_singleton()->end_sync(); @@ -4850,9 +4894,13 @@ void Main::cleanup(bool p_force) { finalize_theme_db(); - // Before deinitializing server extensions, finalize servers which may be loaded as extensions. +// Before deinitializing server extensions, finalize servers which may be loaded as extensions. +#ifndef NAVIGATION_2D_DISABLED NavigationServer2DManager::finalize_server(); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED NavigationServer3DManager::finalize_server(); +#endif // NAVIGATION_3D_DISABLED finalize_physics(); GDExtensionManager::get_singleton()->deinitialize_extensions(GDExtension::INITIALIZATION_LEVEL_SERVERS); diff --git a/main/performance.cpp b/main/performance.cpp index f99915cc9e60..f679d7dcdba5 100644 --- a/main/performance.cpp +++ b/main/performance.cpp @@ -35,8 +35,12 @@ #include "scene/main/node.h" #include "scene/main/scene_tree.h" #include "servers/audio_server.h" +#ifndef NAVIGATION_2D_DISABLED #include "servers/navigation_server_2d.h" +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED #include "servers/navigation_server_3d.h" +#endif // NAVIGATION_3D_DISABLED #include "servers/rendering_server.h" #ifndef PHYSICS_2D_DISABLED @@ -84,6 +88,7 @@ void Performance::_bind_methods() { BIND_ENUM_CONSTANT(PHYSICS_3D_ISLAND_COUNT); #endif // _3D_DISABLED BIND_ENUM_CONSTANT(AUDIO_OUTPUT_LATENCY); +#if !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) BIND_ENUM_CONSTANT(NAVIGATION_ACTIVE_MAPS); BIND_ENUM_CONSTANT(NAVIGATION_REGION_COUNT); BIND_ENUM_CONSTANT(NAVIGATION_AGENT_COUNT); @@ -94,11 +99,13 @@ void Performance::_bind_methods() { BIND_ENUM_CONSTANT(NAVIGATION_EDGE_CONNECTION_COUNT); BIND_ENUM_CONSTANT(NAVIGATION_EDGE_FREE_COUNT); BIND_ENUM_CONSTANT(NAVIGATION_OBSTACLE_COUNT); +#endif // !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) BIND_ENUM_CONSTANT(PIPELINE_COMPILATIONS_CANVAS); BIND_ENUM_CONSTANT(PIPELINE_COMPILATIONS_MESH); BIND_ENUM_CONSTANT(PIPELINE_COMPILATIONS_SURFACE); BIND_ENUM_CONSTANT(PIPELINE_COMPILATIONS_DRAW); BIND_ENUM_CONSTANT(PIPELINE_COMPILATIONS_SPECIALIZATION); +#ifndef NAVIGATION_2D_DISABLED BIND_ENUM_CONSTANT(NAVIGATION_2D_ACTIVE_MAPS); BIND_ENUM_CONSTANT(NAVIGATION_2D_REGION_COUNT); BIND_ENUM_CONSTANT(NAVIGATION_2D_AGENT_COUNT); @@ -109,6 +116,8 @@ void Performance::_bind_methods() { BIND_ENUM_CONSTANT(NAVIGATION_2D_EDGE_CONNECTION_COUNT); BIND_ENUM_CONSTANT(NAVIGATION_2D_EDGE_FREE_COUNT); BIND_ENUM_CONSTANT(NAVIGATION_2D_OBSTACLE_COUNT); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED BIND_ENUM_CONSTANT(NAVIGATION_3D_ACTIVE_MAPS); BIND_ENUM_CONSTANT(NAVIGATION_3D_REGION_COUNT); BIND_ENUM_CONSTANT(NAVIGATION_3D_AGENT_COUNT); @@ -119,6 +128,7 @@ void Performance::_bind_methods() { BIND_ENUM_CONSTANT(NAVIGATION_3D_EDGE_CONNECTION_COUNT); BIND_ENUM_CONSTANT(NAVIGATION_3D_EDGE_FREE_COUNT); BIND_ENUM_CONSTANT(NAVIGATION_3D_OBSTACLE_COUNT); +#endif // NAVIGATION_3D_DISABLED BIND_ENUM_CONSTANT(MONITOR_MAX); } @@ -158,6 +168,7 @@ String Performance::get_monitor_name(Monitor p_monitor) const { PNAME("physics_3d/collision_pairs"), PNAME("physics_3d/islands"), PNAME("audio/driver/output_latency"), +#if !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) PNAME("navigation/active_maps"), PNAME("navigation/regions"), PNAME("navigation/agents"), @@ -168,11 +179,13 @@ String Performance::get_monitor_name(Monitor p_monitor) const { PNAME("navigation/edges_connected"), PNAME("navigation/edges_free"), PNAME("navigation/obstacles"), +#endif // !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) PNAME("pipeline/compilations_canvas"), PNAME("pipeline/compilations_mesh"), PNAME("pipeline/compilations_surface"), PNAME("pipeline/compilations_draw"), PNAME("pipeline/compilations_specialization"), +#ifndef NAVIGATION_2D_DISABLED PNAME("navigation_2d/active_maps"), PNAME("navigation_2d/regions"), PNAME("navigation_2d/agents"), @@ -183,6 +196,8 @@ String Performance::get_monitor_name(Monitor p_monitor) const { PNAME("navigation_2d/edges_connected"), PNAME("navigation_2d/edges_free"), PNAME("navigation_2d/obstacles"), +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED PNAME("navigation_3d/active_maps"), PNAME("navigation_3d/regions"), PNAME("navigation_3d/agents"), @@ -193,6 +208,7 @@ String Performance::get_monitor_name(Monitor p_monitor) const { PNAME("navigation_3d/edges_connected"), PNAME("navigation_3d/edges_free"), PNAME("navigation_3d/obstacles"), +#endif // NAVIGATION_3D_DISABLED }; static_assert(std::size(names) == MONITOR_MAX); @@ -200,6 +216,8 @@ String Performance::get_monitor_name(Monitor p_monitor) const { } double Performance::get_monitor(Monitor p_monitor) const { + int info = 0; + switch (p_monitor) { case TIME_FPS: return Engine::get_singleton()->get_frames_per_second(); @@ -280,36 +298,96 @@ double Performance::get_monitor(Monitor p_monitor) const { return AudioServer::get_singleton()->get_output_latency(); case NAVIGATION_ACTIVE_MAPS: - return NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_ACTIVE_MAPS) + - NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_ACTIVE_MAPS); +#ifndef NAVIGATION_2D_DISABLED + info = NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_ACTIVE_MAPS); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED + info += NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_ACTIVE_MAPS); +#endif // NAVIGATION_3D_DISABLED + return info; + case NAVIGATION_REGION_COUNT: - return NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_REGION_COUNT) + - NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_REGION_COUNT); +#ifndef NAVIGATION_2D_DISABLED + info = NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_REGION_COUNT); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED + info += NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_REGION_COUNT); +#endif // NAVIGATION_3D_DISABLED + return info; + case NAVIGATION_AGENT_COUNT: - return NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_AGENT_COUNT) + - NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_AGENT_COUNT); +#ifndef NAVIGATION_2D_DISABLED + info = NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_AGENT_COUNT); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED + info += NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_AGENT_COUNT); +#endif // NAVIGATION_3D_DISABLED + return info; + case NAVIGATION_LINK_COUNT: - return NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_LINK_COUNT) + - NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_LINK_COUNT); +#ifndef NAVIGATION_2D_DISABLED + info = NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_LINK_COUNT); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED + info += NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_LINK_COUNT); +#endif // NAVIGATION_3D_DISABLED + return info; + case NAVIGATION_POLYGON_COUNT: - return NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_POLYGON_COUNT) + - NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_POLYGON_COUNT); +#ifndef NAVIGATION_2D_DISABLED + info = NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_POLYGON_COUNT); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED + info += NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_POLYGON_COUNT); +#endif // NAVIGATION_3D_DISABLED + return info; + case NAVIGATION_EDGE_COUNT: - return NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_EDGE_COUNT) + - NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_EDGE_COUNT); +#ifndef NAVIGATION_2D_DISABLED + info = NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_EDGE_COUNT); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED + info += NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_EDGE_COUNT); +#endif // NAVIGATION_3D_DISABLED + return info; + case NAVIGATION_EDGE_MERGE_COUNT: - return NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_EDGE_MERGE_COUNT) + - NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_EDGE_MERGE_COUNT); +#ifndef NAVIGATION_2D_DISABLED + info = NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_EDGE_MERGE_COUNT); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED + info += NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_EDGE_MERGE_COUNT); +#endif // NAVIGATION_3D_DISABLED + return info; + case NAVIGATION_EDGE_CONNECTION_COUNT: - return NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_EDGE_CONNECTION_COUNT) + - NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_EDGE_CONNECTION_COUNT); +#ifndef NAVIGATION_2D_DISABLED + info = NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_EDGE_CONNECTION_COUNT); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED + info += NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_EDGE_CONNECTION_COUNT); +#endif // NAVIGATION_3D_DISABLED + return info; + case NAVIGATION_EDGE_FREE_COUNT: - return NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_EDGE_FREE_COUNT) + - NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_EDGE_FREE_COUNT); - case NAVIGATION_OBSTACLE_COUNT: - return NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_OBSTACLE_COUNT) + - NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_OBSTACLE_COUNT); +#ifndef NAVIGATION_2D_DISABLED + info = NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_EDGE_FREE_COUNT); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED + info += NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_EDGE_FREE_COUNT); +#endif // NAVIGATION_3D_DISABLED + return info; + case NAVIGATION_OBSTACLE_COUNT: +#ifndef NAVIGATION_2D_DISABLED + info = NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_OBSTACLE_COUNT); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED + info += NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_OBSTACLE_COUNT); +#endif // NAVIGATION_3D_DISABLED + return info; + +#ifndef NAVIGATION_2D_DISABLED case NAVIGATION_2D_ACTIVE_MAPS: return NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_ACTIVE_MAPS); case NAVIGATION_2D_REGION_COUNT: @@ -330,7 +408,9 @@ double Performance::get_monitor(Monitor p_monitor) const { return NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_EDGE_FREE_COUNT); case NAVIGATION_2D_OBSTACLE_COUNT: return NavigationServer2D::get_singleton()->get_process_info(NavigationServer2D::INFO_OBSTACLE_COUNT); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED case NAVIGATION_3D_ACTIVE_MAPS: return NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_ACTIVE_MAPS); case NAVIGATION_3D_REGION_COUNT: @@ -351,6 +431,7 @@ double Performance::get_monitor(Monitor p_monitor) const { return NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_EDGE_FREE_COUNT); case NAVIGATION_3D_OBSTACLE_COUNT: return NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_OBSTACLE_COUNT); +#endif // NAVIGATION_3D_DISABLED default: { } diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 3f5117ff63af..4cfc69c6ee68 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -36,10 +36,13 @@ #include "core/math/geometry_2d.h" #include "scene/resources/3d/navigation_mesh_source_geometry_data_3d.h" #include "scene/resources/navigation_mesh.h" +#ifndef NAVIGATION_3D_DISABLED #include "servers/navigation_server_3d.h" +#endif // NAVIGATION_3D_DISABLED #include +#ifndef NAVIGATION_3D_DISABLED Callable CSGShape3D::_navmesh_source_geometry_parsing_callback; RID CSGShape3D::_navmesh_source_geometry_parser; @@ -76,6 +79,7 @@ void CSGShape3D::navmesh_parse_source_geometry(const Ref &p_navi } } } +#endif // NAVIGATION_3D_DISABLED #ifndef PHYSICS_3D_DISABLED void CSGShape3D::set_use_collision(bool p_enable) { diff --git a/modules/csg/csg_shape.h b/modules/csg/csg_shape.h index 94d3c2c55a5a..6eee0debd584 100644 --- a/modules/csg/csg_shape.h +++ b/modules/csg/csg_shape.h @@ -184,6 +184,7 @@ class CSGShape3D : public GeometryInstance3D { virtual Ref generate_triangle_mesh() const override; +#ifndef NAVIGATION_3D_DISABLED private: static Callable _navmesh_source_geometry_parsing_callback; static RID _navmesh_source_geometry_parser; @@ -191,6 +192,7 @@ class CSGShape3D : public GeometryInstance3D { public: static void navmesh_parse_init(); static void navmesh_parse_source_geometry(const Ref &p_navigation_mesh, Ref p_source_geometry_data, Node *p_node); +#endif // NAVIGATION_3D_DISABLED CSGShape3D(); ~CSGShape3D(); diff --git a/modules/csg/register_types.cpp b/modules/csg/register_types.cpp index 465ede4ced8d..b157e32952fd 100644 --- a/modules/csg/register_types.cpp +++ b/modules/csg/register_types.cpp @@ -47,7 +47,9 @@ void initialize_csg_module(ModuleInitializationLevel p_level) { GDREGISTER_CLASS(CSGTorus3D); GDREGISTER_CLASS(CSGPolygon3D); GDREGISTER_CLASS(CSGCombiner3D); +#ifndef NAVIGATION_3D_DISABLED CSGShape3D::navmesh_parse_init(); +#endif // NAVIGATION_3D_DISABLED } #ifdef TOOLS_ENABLED if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) { diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index c6bd82d25f86..d3d9adb24ff1 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -45,11 +45,14 @@ #include "scene/resources/3d/sphere_shape_3d.h" #include "scene/resources/physics_material.h" #include "scene/resources/surface_tool.h" -#include "servers/navigation_server_3d.h" #include "servers/rendering_server.h" +#ifndef NAVIGATION_3D_DISABLED +#include "servers/navigation_server_3d.h" + Callable GridMap::_navmesh_source_geometry_parsing_callback; RID GridMap::_navmesh_source_geometry_parser; +#endif // NAVIGATION_3D_DISABLED bool GridMap::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; @@ -247,6 +250,7 @@ bool GridMap::is_baking_navigation() { return bake_navigation; } +#ifndef NAVIGATION_3D_DISABLED void GridMap::set_navigation_map(RID p_navigation_map) { map_override = p_navigation_map; for (const KeyValue &E : octant_map) { @@ -267,6 +271,7 @@ RID GridMap::get_navigation_map() const { } return RID(); } +#endif // NAVIGATION_3D_DISABLED void GridMap::set_mesh_library(const Ref &p_mesh_library) { if (mesh_library.is_valid()) { @@ -541,6 +546,7 @@ void GridMap::_octant_transform(const OctantKey &p_key) { } #endif // PHYSICS_3D_DISABLED +#ifndef NAVIGATION_3D_DISABLED // update transform for NavigationServer regions and navigation debugmesh instances for (const KeyValue &E : g.navigation_cell_ids) { if (bake_navigation) { @@ -552,6 +558,7 @@ void GridMap::_octant_transform(const OctantKey &p_key) { } } } +#endif // NAVIGATION_3D_DISABLED for (int i = 0; i < g.multimesh_instances.size(); i++) { RS::get_singleton()->instance_set_transform(g.multimesh_instances[i].instance, get_global_transform()); @@ -575,6 +582,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { } #endif // PHYSICS_3D_DISABLED +#ifndef NAVIGATION_3D_DISABLED //erase navigation for (KeyValue &E : g.navigation_cell_ids) { if (E.value.region.is_valid()) { @@ -587,6 +595,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { } } g.navigation_cell_ids.clear(); +#endif // NAVIGATION_3D_DISABLED //erase multimeshes @@ -656,6 +665,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { } #endif // PHYSICS_3D_DISABLED +#ifndef NAVIGATION_3D_DISABLED // add the item's navigation_mesh at given xform to GridMap's Navigation ancestor Ref navigation_mesh = mesh_library->get_item_navigation_mesh(c.item); if (navigation_mesh.is_valid()) { @@ -696,13 +706,14 @@ bool GridMap::_octant_update(const OctantKey &p_key) { } g.navigation_cell_ids[E] = nm; } +#endif // NAVIGATION_3D_DISABLED } -#ifdef DEBUG_ENABLED +#if defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED) if (bake_navigation) { _update_octant_navigation_debug_edge_connections_mesh(p_key); } -#endif // DEBUG_ENABLED +#endif // defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED) //update multimeshes, only if not baked if (baked_meshes.size() == 0) { @@ -806,6 +817,7 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) { RS::get_singleton()->instance_set_transform(g.multimesh_instances[i].instance, get_global_transform()); } +#ifndef NAVIGATION_3D_DISABLED if (bake_navigation && mesh_library.is_valid()) { for (KeyValue &F : g.navigation_cell_ids) { if (cell_map.has(F.key) && F.value.region.is_valid() == false) { @@ -840,6 +852,7 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) { } #endif // DEBUG_ENABLED } +#endif // NAVIGATION_3D_DISABLED } void GridMap::_octant_exit_world(const OctantKey &p_key) { @@ -847,7 +860,9 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) { #ifndef PHYSICS_3D_DISABLED ERR_FAIL_NULL(PhysicsServer3D::get_singleton()); #endif // PHYSICS_3D_DISABLED +#ifndef NAVIGATION_3D_DISABLED ERR_FAIL_NULL(NavigationServer3D::get_singleton()); +#endif // NAVIGATION_3D_DISABLED ERR_FAIL_COND(!octant_map.has(p_key)); Octant &g = *octant_map[p_key]; @@ -865,6 +880,7 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) { RS::get_singleton()->instance_set_scenario(g.multimesh_instances[i].instance, RID()); } +#ifndef NAVIGATION_3D_DISABLED for (KeyValue &F : g.navigation_cell_ids) { if (F.value.region.is_valid()) { NavigationServer3D::get_singleton()->free(F.value.region); @@ -875,6 +891,7 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) { F.value.navigation_mesh_debug_instance = RID(); } } +#endif // NAVIGATION_3D_DISABLED #ifdef DEBUG_ENABLED if (bake_navigation) { @@ -894,7 +911,9 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) { #ifndef PHYSICS_3D_DISABLED ERR_FAIL_NULL(PhysicsServer3D::get_singleton()); #endif // PHYSICS_3D_DISABLED +#ifndef NAVIGATION_3D_DISABLED ERR_FAIL_NULL(NavigationServer3D::get_singleton()); +#endif // NAVIGATION_3D_DISABLED ERR_FAIL_COND(!octant_map.has(p_key)); Octant &g = *octant_map[p_key]; @@ -910,6 +929,7 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) { PhysicsServer3D::get_singleton()->free(g.static_body); #endif // PHYSICS_3D_DISABLED +#ifndef NAVIGATION_3D_DISABLED // Erase navigation for (const KeyValue &E : g.navigation_cell_ids) { if (E.value.region.is_valid()) { @@ -920,6 +940,7 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) { } } g.navigation_cell_ids.clear(); +#endif // NAVIGATION_3D_DISABLED #ifdef DEBUG_ENABLED if (bake_navigation) { @@ -958,11 +979,11 @@ void GridMap::_notification(int p_what) { } break; case NOTIFICATION_ENTER_TREE: { -#ifdef DEBUG_ENABLED +#if defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED) if (bake_navigation && NavigationServer3D::get_singleton()->get_debug_navigation_enabled()) { _update_navigation_debug_edge_connections(); } -#endif // DEBUG_ENABLED +#endif // defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED) _update_visibility(); } break; @@ -1109,8 +1130,10 @@ void GridMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bake_navigation", "bake_navigation"), &GridMap::set_bake_navigation); ClassDB::bind_method(D_METHOD("is_baking_navigation"), &GridMap::is_baking_navigation); +#ifndef NAVIGATION_3D_DISABLED ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &GridMap::set_navigation_map); ClassDB::bind_method(D_METHOD("get_navigation_map"), &GridMap::get_navigation_map); +#endif // NAVIGATION_3D_DISABLED ClassDB::bind_method(D_METHOD("set_mesh_library", "mesh_library"), &GridMap::set_mesh_library); ClassDB::bind_method(D_METHOD("get_mesh_library"), &GridMap::get_mesh_library); @@ -1373,12 +1396,13 @@ RID GridMap::get_bake_mesh_instance(int p_idx) { GridMap::GridMap() { set_notify_transform(true); -#ifdef DEBUG_ENABLED +#if defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED) NavigationServer3D::get_singleton()->connect("map_changed", callable_mp(this, &GridMap::_navigation_map_changed)); NavigationServer3D::get_singleton()->connect("navigation_debug_changed", callable_mp(this, &GridMap::_update_navigation_debug_edge_connections)); -#endif // DEBUG_ENABLED +#endif // defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED) } +#ifndef NAVIGATION_3D_DISABLED void GridMap::navmesh_parse_init() { ERR_FAIL_NULL(NavigationServer3D::get_singleton()); if (!_navmesh_source_geometry_parser.is_valid()) { @@ -1518,8 +1542,9 @@ void GridMap::navmesh_parse_source_geometry(const Ref &p_navigat } #endif // PHYSICS_3D_DISABLED } +#endif // NAVIGATION_3D_DISABLED -#ifdef DEBUG_ENABLED +#if defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED) void GridMap::_update_navigation_debug_edge_connections() { if (bake_navigation) { for (const KeyValue &E : octant_map) { @@ -1533,17 +1558,17 @@ void GridMap::_navigation_map_changed(RID p_map) { _update_navigation_debug_edge_connections(); } } -#endif // DEBUG_ENABLED +#endif // defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED) GridMap::~GridMap() { clear(); -#ifdef DEBUG_ENABLED +#if defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED) NavigationServer3D::get_singleton()->disconnect("map_changed", callable_mp(this, &GridMap::_navigation_map_changed)); NavigationServer3D::get_singleton()->disconnect("navigation_debug_changed", callable_mp(this, &GridMap::_update_navigation_debug_edge_connections)); -#endif // DEBUG_ENABLED +#endif // defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED) } -#ifdef DEBUG_ENABLED +#if defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED) void GridMap::_update_octant_navigation_debug_edge_connections_mesh(const OctantKey &p_key) { ERR_FAIL_COND(!octant_map.has(p_key)); Octant &g = *octant_map[p_key]; @@ -1641,4 +1666,4 @@ void GridMap::_update_octant_navigation_debug_edge_connections_mesh(const Octant RS::get_singleton()->instance_set_visible(g.navigation_debug_edge_connections_instance, false); } } -#endif // DEBUG_ENABLED +#endif // defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED) diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index 877a63521c3e..b9db20fec2e9 100644 --- a/modules/gridmap/grid_map.h +++ b/modules/gridmap/grid_map.h @@ -200,11 +200,11 @@ class GridMap : public Node3D { bool _octant_update(const OctantKey &p_key); void _octant_clean_up(const OctantKey &p_key); void _octant_transform(const OctantKey &p_key); -#ifdef DEBUG_ENABLED +#if defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED) void _update_octant_navigation_debug_edge_connections_mesh(const OctantKey &p_key); void _navigation_map_changed(RID p_map); void _update_navigation_debug_edge_connections(); -#endif // DEBUG_ENABLED +#endif // defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED) bool awaiting_update = false; void _queue_octants_dirty(); @@ -264,8 +264,10 @@ class GridMap : public Node3D { void set_bake_navigation(bool p_bake_navigation); bool is_baking_navigation(); +#ifndef NAVIGATION_3D_DISABLED void set_navigation_map(RID p_navigation_map); RID get_navigation_map() const; +#endif // NAVIGATION_3D_DISABLED void set_mesh_library(const Ref &p_mesh_library); Ref get_mesh_library() const; @@ -309,13 +311,17 @@ class GridMap : public Node3D { Array get_bake_meshes(); RID get_bake_mesh_instance(int p_idx); +#ifndef NAVIGATION_3D_DISABLED private: static Callable _navmesh_source_geometry_parsing_callback; static RID _navmesh_source_geometry_parser; +#endif // NAVIGATION_3D_DISABLED public: +#ifndef NAVIGATION_3D_DISABLED static void navmesh_parse_init(); static void navmesh_parse_source_geometry(const Ref &p_navigation_mesh, Ref p_source_geometry_data, Node *p_node); +#endif // NAVIGATION_3D_DISABLED GridMap(); ~GridMap(); diff --git a/modules/gridmap/register_types.cpp b/modules/gridmap/register_types.cpp index 0b065b306487..c98086aa0c61 100644 --- a/modules/gridmap/register_types.cpp +++ b/modules/gridmap/register_types.cpp @@ -43,7 +43,9 @@ void initialize_gridmap_module(ModuleInitializationLevel p_level) { if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) { GDREGISTER_CLASS(GridMap); +#ifndef NAVIGATION_3D_DISABLED GridMap::navmesh_parse_init(); +#endif // NAVIGATION_3D_DISABLED } #ifdef TOOLS_ENABLED if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) { diff --git a/modules/navigation_2d/config.py b/modules/navigation_2d/config.py index d22f9454ed25..17a8482580b2 100644 --- a/modules/navigation_2d/config.py +++ b/modules/navigation_2d/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return True + return not env["disable_navigation_2d"] def configure(env): diff --git a/modules/navigation_3d/3d/navigation_mesh_generator.h b/modules/navigation_3d/3d/navigation_mesh_generator.h index 7d41126a9a3f..eaf2221a28df 100644 --- a/modules/navigation_3d/3d/navigation_mesh_generator.h +++ b/modules/navigation_3d/3d/navigation_mesh_generator.h @@ -30,7 +30,7 @@ #pragma once -#include "scene/3d/navigation_region_3d.h" +#include "scene/3d/navigation/navigation_region_3d.h" #include "scene/resources/navigation_mesh.h" class NavigationMeshSourceGeometryData3D; diff --git a/modules/navigation_3d/config.py b/modules/navigation_3d/config.py index ae547836c49a..f47a63fc800a 100644 --- a/modules/navigation_3d/config.py +++ b/modules/navigation_3d/config.py @@ -1,6 +1,9 @@ def can_build(env, platform): + if env["disable_navigation_3d"]: + return False + env.module_add_dependencies("navigation", ["csg", "gridmap"], True) - return not env["disable_3d"] + return True def configure(env): diff --git a/modules/navigation_3d/editor/navigation_mesh_editor_plugin.cpp b/modules/navigation_3d/editor/navigation_mesh_editor_plugin.cpp index a0b9986ad684..f41dfa6af7ee 100644 --- a/modules/navigation_3d/editor/navigation_mesh_editor_plugin.cpp +++ b/modules/navigation_3d/editor/navigation_mesh_editor_plugin.cpp @@ -32,7 +32,7 @@ #include "editor/editor_node.h" #include "editor/editor_string_names.h" -#include "scene/3d/navigation_region_3d.h" +#include "scene/3d/navigation/navigation_region_3d.h" #include "scene/gui/box_container.h" #include "scene/gui/button.h" #include "scene/gui/dialogs.h" diff --git a/scene/2d/SCsub b/scene/2d/SCsub index fc68a2aa4daf..027026d2ec91 100644 --- a/scene/2d/SCsub +++ b/scene/2d/SCsub @@ -8,3 +8,5 @@ env.add_source_files(env.scene_sources, "*.cpp") # Chain load SCsubs if not env["disable_physics_2d"]: SConscript("physics/SCsub") +if not env["disable_navigation_2d"]: + SConscript("navigation/SCsub") diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp index a38bfac10147..76e73b691dd7 100644 --- a/scene/2d/mesh_instance_2d.cpp +++ b/scene/2d/mesh_instance_2d.cpp @@ -30,13 +30,14 @@ #include "mesh_instance_2d.h" +#ifndef NAVIGATION_2D_DISABLED #include "scene/resources/2d/navigation_mesh_source_geometry_data_2d.h" #include "scene/resources/2d/navigation_polygon.h" -#include "scene/scene_string_names.h" #include "servers/navigation_server_2d.h" #include "thirdparty/clipper2/include/clipper2/clipper.h" #include "thirdparty/misc/polypartition.h" +#endif // NAVIGATION_2D_DISABLED Callable MeshInstance2D::_navmesh_source_geometry_parsing_callback; RID MeshInstance2D::_navmesh_source_geometry_parser; @@ -117,6 +118,7 @@ bool MeshInstance2D::_edit_use_rect() const { } #endif // DEBUG_ENABLED +#ifndef NAVIGATION_2D_DISABLED void MeshInstance2D::navmesh_parse_init() { ERR_FAIL_NULL(NavigationServer2D::get_singleton()); if (!_navmesh_source_geometry_parser.is_valid()) { @@ -211,6 +213,7 @@ void MeshInstance2D::navmesh_parse_source_geometry(const Ref p_source_geometry_data->add_obstruction_outline(shape_outline); } } +#endif // NAVIGATION_2D_DISABLED MeshInstance2D::MeshInstance2D() { } diff --git a/scene/2d/mesh_instance_2d.h b/scene/2d/mesh_instance_2d.h index b023ae086894..128db834df78 100644 --- a/scene/2d/mesh_instance_2d.h +++ b/scene/2d/mesh_instance_2d.h @@ -63,8 +63,10 @@ class MeshInstance2D : public Node2D { static RID _navmesh_source_geometry_parser; public: +#ifndef NAVIGATION_2D_DISABLED static void navmesh_parse_init(); static void navmesh_parse_source_geometry(const Ref &p_navigation_mesh, Ref p_source_geometry_data, Node *p_node); +#endif // NAVIGATION_2D_DISABLED MeshInstance2D(); }; diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp index 78b8a2771086..479265225fc4 100644 --- a/scene/2d/multimesh_instance_2d.cpp +++ b/scene/2d/multimesh_instance_2d.cpp @@ -30,13 +30,14 @@ #include "multimesh_instance_2d.h" +#ifndef NAVIGATION_2D_DISABLED #include "scene/resources/2d/navigation_mesh_source_geometry_data_2d.h" #include "scene/resources/2d/navigation_polygon.h" -#include "scene/scene_string_names.h" #include "servers/navigation_server_2d.h" #include "thirdparty/clipper2/include/clipper2/clipper.h" #include "thirdparty/misc/polypartition.h" +#endif // NAVIGATION_2D_DISABLED Callable MultiMeshInstance2D::_navmesh_source_geometry_parsing_callback; RID MultiMeshInstance2D::_navmesh_source_geometry_parser; @@ -106,6 +107,7 @@ Rect2 MultiMeshInstance2D::_edit_get_rect() const { } #endif // DEBUG_ENABLED +#ifndef NAVIGATION_2D_DISABLED void MultiMeshInstance2D::navmesh_parse_init() { ERR_FAIL_NULL(NavigationServer2D::get_singleton()); if (!_navmesh_source_geometry_parser.is_valid()) { @@ -209,6 +211,7 @@ void MultiMeshInstance2D::navmesh_parse_source_geometry(const Ref &p_navigation_mesh, Ref p_source_geometry_data, Node *p_node); +#endif // NAVIGATION_2D_DISABLED MultiMeshInstance2D(); ~MultiMeshInstance2D(); diff --git a/scene/2d/navigation/SCsub b/scene/2d/navigation/SCsub new file mode 100644 index 000000000000..374dc2119dcd --- /dev/null +++ b/scene/2d/navigation/SCsub @@ -0,0 +1,6 @@ +#!/usr/bin/env python +from misc.utility.scons_hints import * + +Import("env") + +env.add_source_files(env.scene_sources, "*.cpp") diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation/navigation_agent_2d.cpp similarity index 99% rename from scene/2d/navigation_agent_2d.cpp rename to scene/2d/navigation/navigation_agent_2d.cpp index 29253cd12cc8..d288bbc97726 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation/navigation_agent_2d.cpp @@ -31,7 +31,7 @@ #include "navigation_agent_2d.h" #include "core/math/geometry_2d.h" -#include "scene/2d/navigation_link_2d.h" +#include "scene/2d/navigation/navigation_link_2d.h" #include "scene/resources/world_2d.h" #include "servers/navigation_server_2d.h" diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation/navigation_agent_2d.h similarity index 100% rename from scene/2d/navigation_agent_2d.h rename to scene/2d/navigation/navigation_agent_2d.h diff --git a/scene/2d/navigation_link_2d.cpp b/scene/2d/navigation/navigation_link_2d.cpp similarity index 100% rename from scene/2d/navigation_link_2d.cpp rename to scene/2d/navigation/navigation_link_2d.cpp diff --git a/scene/2d/navigation_link_2d.h b/scene/2d/navigation/navigation_link_2d.h similarity index 100% rename from scene/2d/navigation_link_2d.h rename to scene/2d/navigation/navigation_link_2d.h diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation/navigation_obstacle_2d.cpp similarity index 100% rename from scene/2d/navigation_obstacle_2d.cpp rename to scene/2d/navigation/navigation_obstacle_2d.cpp diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation/navigation_obstacle_2d.h similarity index 100% rename from scene/2d/navigation_obstacle_2d.h rename to scene/2d/navigation/navigation_obstacle_2d.h diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation/navigation_region_2d.cpp similarity index 100% rename from scene/2d/navigation_region_2d.cpp rename to scene/2d/navigation/navigation_region_2d.cpp diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation/navigation_region_2d.h similarity index 100% rename from scene/2d/navigation_region_2d.h rename to scene/2d/navigation/navigation_region_2d.h diff --git a/scene/2d/physics/static_body_2d.cpp b/scene/2d/physics/static_body_2d.cpp index 9ae3fa25e05a..320889102773 100644 --- a/scene/2d/physics/static_body_2d.cpp +++ b/scene/2d/physics/static_body_2d.cpp @@ -30,6 +30,7 @@ #include "static_body_2d.h" +#ifndef NAVIGATION_2D_DISABLED #include "scene/resources/2d/capsule_shape_2d.h" #include "scene/resources/2d/circle_shape_2d.h" #include "scene/resources/2d/concave_polygon_shape_2d.h" @@ -38,6 +39,7 @@ #include "scene/resources/2d/navigation_polygon.h" #include "scene/resources/2d/rectangle_shape_2d.h" #include "servers/navigation_server_2d.h" +#endif // NAVIGATION_2D_DISABLED Callable StaticBody2D::_navmesh_source_geometry_parsing_callback; RID StaticBody2D::_navmesh_source_geometry_parser; @@ -89,6 +91,7 @@ void StaticBody2D::_reload_physics_characteristics() { } } +#ifndef NAVIGATION_2D_DISABLED void StaticBody2D::navmesh_parse_init() { ERR_FAIL_NULL(NavigationServer2D::get_singleton()); if (!_navmesh_source_geometry_parser.is_valid()) { @@ -213,6 +216,7 @@ void StaticBody2D::navmesh_parse_source_geometry(const Ref &p } } } +#endif // NAVIGATION_2D_DISABLED void StaticBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_constant_linear_velocity", "vel"), &StaticBody2D::set_constant_linear_velocity); diff --git a/scene/2d/physics/static_body_2d.h b/scene/2d/physics/static_body_2d.h index c431c195b376..a0891b91c7be 100644 --- a/scene/2d/physics/static_body_2d.h +++ b/scene/2d/physics/static_body_2d.h @@ -63,9 +63,11 @@ class StaticBody2D : public PhysicsBody2D { static Callable _navmesh_source_geometry_parsing_callback; static RID _navmesh_source_geometry_parser; +#ifndef NAVIGATION_2D_DISABLED public: static void navmesh_parse_init(); static void navmesh_parse_source_geometry(const Ref &p_navigation_mesh, Ref p_source_geometry_data, Node *p_node); +#endif // NAVIGATION_2D_DISABLED private: void _reload_physics_characteristics(); diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index c5aaff3e71f8..beb86b4e463c 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -31,13 +31,17 @@ #include "polygon_2d.h" #include "core/math/geometry_2d.h" +#ifndef NAVIGATION_2D_DISABLED #include "scene/resources/2d/navigation_mesh_source_geometry_data_2d.h" #include "scene/resources/2d/navigation_polygon.h" #include "servers/navigation_server_2d.h" +#endif // NAVIGATION_2D_DISABLED #include "skeleton_2d.h" +#ifndef NAVIGATION_2D_DISABLED Callable Polygon2D::_navmesh_source_geometry_parsing_callback; RID Polygon2D::_navmesh_source_geometry_parser; +#endif // NAVIGATION_2D_DISABLED #ifdef TOOLS_ENABLED Dictionary Polygon2D::_edit_get_state() const { @@ -610,6 +614,7 @@ NodePath Polygon2D::get_skeleton() const { return skeleton; } +#ifndef NAVIGATION_2D_DISABLED void Polygon2D::navmesh_parse_init() { ERR_FAIL_NULL(NavigationServer2D::get_singleton()); if (!_navmesh_source_geometry_parser.is_valid()) { @@ -639,6 +644,7 @@ void Polygon2D::navmesh_parse_source_geometry(const Ref &p_na p_source_geometry_data->add_obstruction_outline(shape_outline); } } +#endif // NAVIGATION_2D_DISABLED void Polygon2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_polygon", "polygon"), &Polygon2D::set_polygon); diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h index f582ae024ae9..8281762958cb 100644 --- a/scene/2d/polygon_2d.h +++ b/scene/2d/polygon_2d.h @@ -152,13 +152,17 @@ class Polygon2D : public Node2D { void set_skeleton(const NodePath &p_skeleton); NodePath get_skeleton() const; +#ifndef NAVIGATION_2D_DISABLED private: static Callable _navmesh_source_geometry_parsing_callback; static RID _navmesh_source_geometry_parser; +#endif // NAVIGATION_2D_DISABLED public: +#ifndef NAVIGATION_2D_DISABLED static void navmesh_parse_init(); static void navmesh_parse_source_geometry(const Ref &p_navigation_mesh, Ref p_source_geometry_data, Node *p_node); +#endif // NAVIGATION_2D_DISABLED Polygon2D(); ~Polygon2D(); diff --git a/scene/2d/tile_map.compat.inc b/scene/2d/tile_map.compat.inc index 04937bdf7ef8..e0f99e7015f3 100644 --- a/scene/2d/tile_map.compat.inc +++ b/scene/2d/tile_map.compat.inc @@ -46,16 +46,20 @@ TileMap::VisibilityMode TileMap::_get_collision_visibility_mode_bind_compat_8711 return get_collision_visibility_mode(); } +#ifndef NAVIGATION_2D_DISABLED TileMap::VisibilityMode TileMap::_get_navigation_visibility_mode_bind_compat_87115() { return get_navigation_visibility_mode(); } +#endif // NAVIGATION_2D_DISABLED void TileMap::_bind_compatibility_methods() { ClassDB::bind_compatibility_method(D_METHOD("get_used_rect"), &TileMap::_get_used_rect_bind_compat_78328); ClassDB::bind_compatibility_method(D_METHOD("set_quadrant_size", "quadrant_size"), &TileMap::_set_quadrant_size_compat_81070); ClassDB::bind_compatibility_method(D_METHOD("get_quadrant_size"), &TileMap::_get_quadrant_size_compat_81070); ClassDB::bind_compatibility_method(D_METHOD("get_collision_visibility_mode"), &TileMap::_get_collision_visibility_mode_bind_compat_87115); +#ifndef NAVIGATION_2D_DISABLED ClassDB::bind_compatibility_method(D_METHOD("get_navigation_visibility_mode"), &TileMap::_get_navigation_visibility_mode_bind_compat_87115); +#endif // NAVIGATION_2D_DISABLED } #endif diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 6780e9a35f6b..e6057ec28472 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -32,8 +32,10 @@ #include "tile_map.compat.inc" #include "core/io/marshalls.h" +#ifndef NAVIGATION_2D_DISABLED #include "scene/resources/2d/navigation_mesh_source_geometry_data_2d.h" #include "servers/navigation_server_2d.h" +#endif // NAVIGATION_2D_DISABLED #define TILEMAP_CALL_FOR_LAYER(layer, function, ...) \ if (layer < 0) { \ @@ -49,8 +51,10 @@ ERR_FAIL_INDEX_V(layer, (int)layers.size(), err_value); \ return layers[layer]->function(__VA_ARGS__); +#ifndef NAVIGATION_2D_DISABLED Callable TileMap::_navmesh_source_geometry_parsing_callback; RID TileMap::_navmesh_source_geometry_parser; +#endif // NAVIGATION_2D_DISABLED void TileMap::_tile_set_changed() { update_configuration_warnings(); @@ -376,6 +380,7 @@ int TileMap::get_layer_z_index(int p_layer) const { TILEMAP_CALL_FOR_LAYER_V(p_layer, 0, get_z_index); } +#ifndef NAVIGATION_2D_DISABLED void TileMap::set_layer_navigation_enabled(int p_layer, bool p_enabled) { TILEMAP_CALL_FOR_LAYER(p_layer, set_navigation_enabled, p_enabled); } @@ -391,6 +396,7 @@ void TileMap::set_layer_navigation_map(int p_layer, RID p_map) { RID TileMap::get_layer_navigation_map(int p_layer) const { TILEMAP_CALL_FOR_LAYER_V(p_layer, RID(), get_navigation_map); } +#endif // NAVIGATION_2D_DISABLED void TileMap::set_collision_animatable(bool p_collision_animatable) { if (collision_animatable == p_collision_animatable) { @@ -423,6 +429,7 @@ TileMap::VisibilityMode TileMap::get_collision_visibility_mode() const { return collision_visibility_mode; } +#ifndef NAVIGATION_2D_DISABLED void TileMap::set_navigation_visibility_mode(TileMap::VisibilityMode p_show_navigation) { if (navigation_visibility_mode == p_show_navigation) { return; @@ -437,6 +444,7 @@ void TileMap::set_navigation_visibility_mode(TileMap::VisibilityMode p_show_navi TileMap::VisibilityMode TileMap::get_navigation_visibility_mode() const { return navigation_visibility_mode; } +#endif // NAVIGATION_2D_DISABLED void TileMap::set_y_sort_enabled(bool p_enable) { if (is_y_sort_enabled() == p_enable) { @@ -898,8 +906,10 @@ PackedStringArray TileMap::get_configuration_warnings() const { void TileMap::_bind_methods() { #ifndef DISABLE_DEPRECATED +#ifndef NAVIGATION_2D_DISABLED ClassDB::bind_method(D_METHOD("set_navigation_map", "layer", "map"), &TileMap::set_layer_navigation_map); ClassDB::bind_method(D_METHOD("get_navigation_map", "layer"), &TileMap::get_layer_navigation_map); +#endif // NAVIGATION_2D_DISABLED ClassDB::bind_method(D_METHOD("force_update", "layer"), &TileMap::force_update, DEFVAL(-1)); #endif // DISABLE_DEPRECATED @@ -925,18 +935,22 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("get_layer_y_sort_origin", "layer"), &TileMap::get_layer_y_sort_origin); ClassDB::bind_method(D_METHOD("set_layer_z_index", "layer", "z_index"), &TileMap::set_layer_z_index); ClassDB::bind_method(D_METHOD("get_layer_z_index", "layer"), &TileMap::get_layer_z_index); +#ifndef NAVIGATION_2D_DISABLED ClassDB::bind_method(D_METHOD("set_layer_navigation_enabled", "layer", "enabled"), &TileMap::set_layer_navigation_enabled); ClassDB::bind_method(D_METHOD("is_layer_navigation_enabled", "layer"), &TileMap::is_layer_navigation_enabled); ClassDB::bind_method(D_METHOD("set_layer_navigation_map", "layer", "map"), &TileMap::set_layer_navigation_map); ClassDB::bind_method(D_METHOD("get_layer_navigation_map", "layer"), &TileMap::get_layer_navigation_map); +#endif // NAVIGATION_2D_DISABLED ClassDB::bind_method(D_METHOD("set_collision_animatable", "enabled"), &TileMap::set_collision_animatable); ClassDB::bind_method(D_METHOD("is_collision_animatable"), &TileMap::is_collision_animatable); ClassDB::bind_method(D_METHOD("set_collision_visibility_mode", "collision_visibility_mode"), &TileMap::set_collision_visibility_mode); ClassDB::bind_method(D_METHOD("get_collision_visibility_mode"), &TileMap::get_collision_visibility_mode); +#ifndef NAVIGATION_2D_DISABLED ClassDB::bind_method(D_METHOD("set_navigation_visibility_mode", "navigation_visibility_mode"), &TileMap::set_navigation_visibility_mode); ClassDB::bind_method(D_METHOD("get_navigation_visibility_mode"), &TileMap::get_navigation_visibility_mode); +#endif // NAVIGATION_2D_DISABLED ClassDB::bind_method(D_METHOD("set_cell", "layer", "coords", "source_id", "atlas_coords", "alternative_tile"), &TileMap::set_cell, DEFVAL(TileSet::INVALID_SOURCE), DEFVAL(TileSetSource::INVALID_ATLAS_COORDS), DEFVAL(0)); ClassDB::bind_method(D_METHOD("erase_cell", "layer", "coords"), &TileMap::erase_cell); @@ -986,7 +1000,9 @@ void TileMap::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "rendering_quadrant_size", PROPERTY_HINT_RANGE, "1,128,1"), "set_rendering_quadrant_size", "get_rendering_quadrant_size"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_animatable"), "set_collision_animatable", "is_collision_animatable"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_visibility_mode", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_collision_visibility_mode", "get_collision_visibility_mode"); +#ifndef NAVIGATION_2D_DISABLED ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_visibility_mode", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_navigation_visibility_mode", "get_navigation_visibility_mode"); +#endif // NAVIGATION_2D_DISABLED ADD_ARRAY("layers", "layer_"); @@ -1021,7 +1037,9 @@ TileMap::TileMap() { base_property_helper.register_property(PropertyInfo(Variant::BOOL, "y_sort_enabled"), defaults->is_y_sort_enabled(), &TileMap::set_layer_y_sort_enabled, &TileMap::is_layer_y_sort_enabled); base_property_helper.register_property(PropertyInfo(Variant::INT, "y_sort_origin", PROPERTY_HINT_NONE, "suffix:px"), defaults->get_y_sort_origin(), &TileMap::set_layer_y_sort_origin, &TileMap::get_layer_y_sort_origin); base_property_helper.register_property(PropertyInfo(Variant::INT, "z_index"), defaults->get_z_index(), &TileMap::set_layer_z_index, &TileMap::get_layer_z_index); +#ifndef NAVIGATION_2D_DISABLED base_property_helper.register_property(PropertyInfo(Variant::BOOL, "navigation_enabled"), defaults->is_navigation_enabled(), &TileMap::set_layer_navigation_enabled, &TileMap::is_layer_navigation_enabled); +#endif // NAVIGATION_2D_DISABLED base_property_helper.register_property(PropertyInfo(Variant::PACKED_INT32_ARRAY, "tile_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), Vector(), &TileMap::_set_layer_tile_data, &TileMap::_get_tile_map_data_using_compatibility_format); PropertyListHelper::register_base_helper(&base_property_helper); @@ -1031,6 +1049,7 @@ TileMap::TileMap() { property_helper.setup_for_instance(base_property_helper, this); } +#ifndef NAVIGATION_2D_DISABLED void TileMap::navmesh_parse_init() { ERR_FAIL_NULL(NavigationServer2D::get_singleton()); if (!_navmesh_source_geometry_parser.is_valid()) { @@ -1058,6 +1077,7 @@ void TileMap::navmesh_parse_source_geometry(const Ref &p_navi } } } +#endif // NAVIGATION_2D_DISABLED #undef TILEMAP_CALL_FOR_LAYER #undef TILEMAP_CALL_FOR_LAYER_V diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index f5a81d417c46..d2331e25a273 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -35,7 +35,9 @@ #include "scene/resources/2d/tile_set.h" class Control; +#ifndef NAVIGATION_2D_DISABLED class NavigationMeshSourceGeometryData2D; +#endif // NAVIGATION_2D_DISABLED class TileMapLayer; class TerrainConstraint; @@ -58,8 +60,6 @@ class TileMap : public Node2D { }; private: - friend class TileSetPlugin; - // A compatibility enum to specify how is the data if formatted. mutable TileMapDataFormat format = TileMapDataFormat::TILE_MAP_DATA_FORMAT_3; @@ -68,7 +68,9 @@ class TileMap : public Node2D { int rendering_quadrant_size = 16; bool collision_animatable = false; VisibilityMode collision_visibility_mode = VISIBILITY_MODE_DEFAULT; +#ifndef NAVIGATION_2D_DISABLED VisibilityMode navigation_visibility_mode = VISIBILITY_MODE_DEFAULT; +#endif // NAVIGATION_2D_DISABLED // Layers. LocalVector layers; @@ -104,7 +106,9 @@ class TileMap : public Node2D { void _set_quadrant_size_compat_81070(int p_quadrant_size); int _get_quadrant_size_compat_81070() const; VisibilityMode _get_collision_visibility_mode_bind_compat_87115(); +#ifndef NAVIGATION_2D_DISABLED VisibilityMode _get_navigation_visibility_mode_bind_compat_87115(); +#endif // NAVIGATION_2D_DISABLED static void _bind_compatibility_methods(); #endif // DISABLE_DEPRECATED @@ -143,10 +147,12 @@ class TileMap : public Node2D { int get_layer_y_sort_origin(int p_layer) const; void set_layer_z_index(int p_layer, int p_z_index); int get_layer_z_index(int p_layer) const; +#ifndef NAVIGATION_2D_DISABLED void set_layer_navigation_enabled(int p_layer, bool p_enabled); bool is_layer_navigation_enabled(int p_layer) const; void set_layer_navigation_map(int p_layer, RID p_map); RID get_layer_navigation_map(int p_layer) const; +#endif // NAVIGATION_2D_DISABLED void set_collision_animatable(bool p_collision_animatable); bool is_collision_animatable() const; @@ -155,8 +161,10 @@ class TileMap : public Node2D { void set_collision_visibility_mode(VisibilityMode p_show_collision); VisibilityMode get_collision_visibility_mode() const; +#ifndef NAVIGATION_2D_DISABLED void set_navigation_visibility_mode(VisibilityMode p_show_navigation); VisibilityMode get_navigation_visibility_mode() const; +#endif // NAVIGATION_2D_DISABLED // Cells accessors. void set_cell(int p_layer, const Vector2i &p_coords, int p_source_id = TileSet::INVALID_SOURCE, const Vector2i p_atlas_coords = TileSetSource::INVALID_ATLAS_COORDS, int p_alternative_tile = 0); @@ -240,13 +248,17 @@ class TileMap : public Node2D { // Configuration warnings. PackedStringArray get_configuration_warnings() const override; +#ifndef NAVIGATION_2D_DISABLED private: static Callable _navmesh_source_geometry_parsing_callback; static RID _navmesh_source_geometry_parser; +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_2D_DISABLED public: static void navmesh_parse_init(); static void navmesh_parse_source_geometry(const Ref &p_navigation_mesh, Ref p_source_geometry_data, Node *p_node); +#endif // NAVIGATION_2D_DISABLED TileMap(); }; diff --git a/scene/2d/tile_map_layer.cpp b/scene/2d/tile_map_layer.cpp index 7cd0337c76bb..5a42c1034b9c 100644 --- a/scene/2d/tile_map_layer.cpp +++ b/scene/2d/tile_map_layer.cpp @@ -37,14 +37,16 @@ #include "scene/gui/control.h" #include "scene/resources/2d/navigation_mesh_source_geometry_data_2d.h" #include "scene/resources/world_2d.h" -#include "servers/navigation_server_2d.h" #ifndef PHYSICS_2D_DISABLED #include "servers/physics_server_2d.h" #endif // PHYSICS_3D_DISABLED +#ifndef NAVIGATION_2D_DISABLED +#include "servers/navigation_server_2d.h" Callable TileMapLayer::_navmesh_source_geometry_parsing_callback; RID TileMapLayer::_navmesh_source_geometry_parser; +#endif // NAVIGATION_2D_DISABLED Vector2i TileMapLayer::_coords_to_quadrant_coords(const Vector2i &p_coords, const int p_quadrant_size) const { return Vector2i( @@ -149,7 +151,9 @@ void TileMapLayer::_debug_update(bool p_force_cleanup) { CellData &cell_data = *cell_data_list_element->self(); if (cell_data.cell.source_id != TileSet::INVALID_SOURCE) { _rendering_draw_cell_debug(ci, quadrant_pos, cell_data); +#ifndef NAVIGATION_2D_DISABLED _navigation_draw_cell_debug(ci, quadrant_pos, cell_data); +#endif // NAVIGATION_2D_DISABLED _scenes_draw_cell_debug(ci, quadrant_pos, cell_data); debug_quadrant->drawn_to = true; } @@ -1138,6 +1142,7 @@ void TileMapLayer::_physics_draw_quadrant_debug(const RID &p_canvas_item, DebugQ #endif // DEBUG_ENABLED #endif // PHYSICS_2D_DISABLED +#ifndef NAVIGATION_2D_DISABLED /////////////////////////////// Navigation ////////////////////////////////////// void TileMapLayer::_navigation_update(bool p_force_cleanup) { @@ -1410,6 +1415,7 @@ void TileMapLayer::_navigation_draw_cell_debug(const RID &p_canvas_item, const V } } #endif // DEBUG_ENABLED +#endif // NAVIGATION_2D_DISABLED /////////////////////////////// Scenes ////////////////////////////////////// @@ -1885,7 +1891,9 @@ void TileMapLayer::_internal_update(bool p_force_cleanup) { #ifndef PHYSICS_2D_DISABLED _physics_update(p_force_cleanup); #endif // PHYSICS_2D_DISABLED +#ifndef NAVIGATION_2D_DISABLED _navigation_update(p_force_cleanup); +#endif // NAVIGATION_2D_DISABLED _scenes_update(p_force_cleanup); #ifdef DEBUG_ENABLED _debug_update(p_force_cleanup); @@ -1989,7 +1997,9 @@ void TileMapLayer::_notification(int p_what) { #ifndef PHYSICS_2D_DISABLED _physics_notification(p_what); #endif // PHYSICS_2D_DISABLED +#ifndef NAVIGATION_2D_DISABLED _navigation_notification(p_what); +#endif // NAVIGATION_2D_DISABLED } void TileMapLayer::_bind_methods() { @@ -2067,12 +2077,14 @@ void TileMapLayer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_occlusion_enabled", "enabled"), &TileMapLayer::set_occlusion_enabled); ClassDB::bind_method(D_METHOD("is_occlusion_enabled"), &TileMapLayer::is_occlusion_enabled); +#ifndef NAVIGATION_2D_DISABLED ClassDB::bind_method(D_METHOD("set_navigation_enabled", "enabled"), &TileMapLayer::set_navigation_enabled); ClassDB::bind_method(D_METHOD("is_navigation_enabled"), &TileMapLayer::is_navigation_enabled); ClassDB::bind_method(D_METHOD("set_navigation_map", "map"), &TileMapLayer::set_navigation_map); ClassDB::bind_method(D_METHOD("get_navigation_map"), &TileMapLayer::get_navigation_map); ClassDB::bind_method(D_METHOD("set_navigation_visibility_mode", "show_navigation"), &TileMapLayer::set_navigation_visibility_mode); ClassDB::bind_method(D_METHOD("get_navigation_visibility_mode"), &TileMapLayer::get_navigation_visibility_mode); +#endif // NAVIGATION_2D_DISABLED GDVIRTUAL_BIND(_use_tile_data_runtime_update, "coords"); GDVIRTUAL_BIND(_tile_data_runtime_update, "coords", "tile_data"); @@ -2092,9 +2104,11 @@ void TileMapLayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_kinematic_bodies"), "set_use_kinematic_bodies", "is_using_kinematic_bodies"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_visibility_mode", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_collision_visibility_mode", "get_collision_visibility_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "physics_quadrant_size"), "set_physics_quadrant_size", "get_physics_quadrant_size"); +#ifndef NAVIGATION_2D_DISABLED ADD_GROUP("Navigation", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "navigation_enabled"), "set_navigation_enabled", "is_navigation_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_visibility_mode", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_navigation_visibility_mode", "get_navigation_visibility_mode"); +#endif // NAVIGATION_2D_DISABLED ADD_SIGNAL(MethodInfo(CoreStringName(changed))); @@ -3233,6 +3247,7 @@ bool TileMapLayer::is_occlusion_enabled() const { return occlusion_enabled; } +#ifndef NAVIGATION_2D_DISABLED void TileMapLayer::set_navigation_enabled(bool p_enabled) { if (navigation_enabled == p_enabled) { return; @@ -3395,6 +3410,7 @@ void TileMapLayer::navmesh_parse_source_geometry(const Ref &p #endif // PHYSICS_2D_DISABLED } } +#endif // NAVIGATION_2D_DISABLED TileMapLayer::TileMapLayer() { set_notify_transform(true); diff --git a/scene/2d/tile_map_layer.h b/scene/2d/tile_map_layer.h index 6fd3a33867f7..40a9c84f62ec 100644 --- a/scene/2d/tile_map_layer.h +++ b/scene/2d/tile_map_layer.h @@ -32,7 +32,9 @@ #include "scene/resources/2d/tile_set.h" +#ifndef NAVIGATION_2D_DISABLED class NavigationMeshSourceGeometryData2D; +#endif // NAVIGATION_2D_DISABLED class TileSetAtlasSource; class TileMap; @@ -454,6 +456,7 @@ class TileMapLayer : public Node2D { #endif // DEBUG_ENABLED #endif // PHYSICS_2D_DISABLED +#ifndef NAVIGATION_2D_DISABLED bool _navigation_was_cleaned_up = false; void _navigation_update(bool p_force_cleanup); void _navigation_notification(int p_what); @@ -462,6 +465,7 @@ class TileMapLayer : public Node2D { #ifdef DEBUG_ENABLED void _navigation_draw_cell_debug(const RID &p_canvas_item, const Vector2 &p_quadrant_pos, const CellData &r_cell_data); #endif // DEBUG_ENABLED +#endif // NAVIGATION_2D_DISABLED bool _scenes_was_cleaned_up = false; void _scenes_update(bool p_force_cleanup); @@ -618,12 +622,16 @@ class TileMapLayer : public Node2D { DebugVisibilityMode get_navigation_visibility_mode() const; private: +#ifndef NAVIGATION_2D_DISABLED static Callable _navmesh_source_geometry_parsing_callback; static RID _navmesh_source_geometry_parser; +#endif // NAVIGATION_2D_DISABLED public: +#ifndef NAVIGATION_2D_DISABLED static void navmesh_parse_init(); static void navmesh_parse_source_geometry(const Ref &p_navigation_mesh, Ref p_source_geometry_data, Node *p_node); +#endif // NAVIGATION_2D_DISABLED TileMapLayer(); ~TileMapLayer(); diff --git a/scene/3d/SCsub b/scene/3d/SCsub index bbd6bd78e4d0..307c95d5c7da 100644 --- a/scene/3d/SCsub +++ b/scene/3d/SCsub @@ -8,5 +8,7 @@ env.add_source_files(env.scene_sources, "*.cpp") # Chain load SCsubs if not env["disable_physics_3d"]: SConscript("physics/SCsub") +if not env["disable_navigation_3d"]: + SConscript("navigation/SCsub") if not env["disable_xr"]: SConscript("xr/SCsub") diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index 83990273deae..20dd5f5ecc51 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -31,9 +31,6 @@ #include "mesh_instance_3d.h" #include "scene/3d/skeleton_3d.h" -#include "scene/resources/3d/navigation_mesh_source_geometry_data_3d.h" -#include "scene/resources/navigation_mesh.h" -#include "servers/navigation_server_3d.h" #ifndef PHYSICS_3D_DISABLED #include "scene/3d/physics/collision_shape_3d.h" @@ -42,8 +39,14 @@ #include "scene/resources/3d/convex_polygon_shape_3d.h" #endif // PHYSICS_3D_DISABLED +#ifndef NAVIGATION_3D_DISABLED +#include "scene/resources/3d/navigation_mesh_source_geometry_data_3d.h" +#include "scene/resources/navigation_mesh.h" +#include "servers/navigation_server_3d.h" + Callable MeshInstance3D::_navmesh_source_geometry_parsing_callback; RID MeshInstance3D::_navmesh_source_geometry_parser; +#endif // NAVIGATION_3D_DISABLED bool MeshInstance3D::_set(const StringName &p_name, const Variant &p_value) { //this is not _too_ bad performance wise, really. it only arrives here if the property was not set anywhere else. @@ -853,6 +856,7 @@ Ref MeshInstance3D::generate_triangle_mesh() const { return Ref(); } +#ifndef NAVIGATION_3D_DISABLED void MeshInstance3D::navmesh_parse_init() { ERR_FAIL_NULL(NavigationServer3D::get_singleton()); if (!_navmesh_source_geometry_parser.is_valid()) { @@ -878,6 +882,7 @@ void MeshInstance3D::navmesh_parse_source_geometry(const Ref &p_ } } } +#endif // NAVIGATION_3D_DISABLED void MeshInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &MeshInstance3D::set_mesh); diff --git a/scene/3d/mesh_instance_3d.h b/scene/3d/mesh_instance_3d.h index 83932689f234..28ca664a778b 100644 --- a/scene/3d/mesh_instance_3d.h +++ b/scene/3d/mesh_instance_3d.h @@ -33,8 +33,10 @@ #include "core/templates/local_vector.h" #include "scene/3d/visual_instance_3d.h" +#ifndef NAVIGATION_3D_DISABLED class NavigationMesh; class NavigationMeshSourceGeometryData3D; +#endif // NAVIGATION_3D_DISABLED class Skin; class SkinReference; @@ -110,13 +112,17 @@ class MeshInstance3D : public GeometryInstance3D { virtual Ref generate_triangle_mesh() const override; +#ifndef NAVIGATION_3D_DISABLED private: static Callable _navmesh_source_geometry_parsing_callback; static RID _navmesh_source_geometry_parser; +#endif // NAVIGATION_3D_DISABLED public: +#ifndef NAVIGATION_3D_DISABLED static void navmesh_parse_init(); static void navmesh_parse_source_geometry(const Ref &p_navigation_mesh, Ref p_source_geometry_data, Node *p_node); +#endif // NAVIGATION_3D_DISABLED MeshInstance3D(); ~MeshInstance3D(); diff --git a/scene/3d/multimesh_instance_3d.cpp b/scene/3d/multimesh_instance_3d.cpp index c8cc9bb309b9..abb548febfc8 100644 --- a/scene/3d/multimesh_instance_3d.cpp +++ b/scene/3d/multimesh_instance_3d.cpp @@ -30,12 +30,14 @@ #include "multimesh_instance_3d.h" +#ifndef NAVIGATION_3D_DISABLED #include "scene/resources/3d/navigation_mesh_source_geometry_data_3d.h" #include "scene/resources/navigation_mesh.h" #include "servers/navigation_server_3d.h" Callable MultiMeshInstance3D::_navmesh_source_geometry_parsing_callback; RID MultiMeshInstance3D::_navmesh_source_geometry_parser; +#endif // NAVIGATION_3D_DISABLED void MultiMeshInstance3D::_refresh_interpolated() { if (is_inside_tree() && multimesh.is_valid()) { @@ -103,6 +105,7 @@ AABB MultiMeshInstance3D::get_aabb() const { } } +#ifndef NAVIGATION_3D_DISABLED void MultiMeshInstance3D::navmesh_parse_init() { ERR_FAIL_NULL(NavigationServer3D::get_singleton()); if (!_navmesh_source_geometry_parser.is_valid()) { @@ -137,6 +140,7 @@ void MultiMeshInstance3D::navmesh_parse_source_geometry(const Ref &p_navigation_mesh, Ref p_source_geometry_data, Node *p_node); +#endif // NAVIGATION_3D_DISABLED MultiMeshInstance3D(); ~MultiMeshInstance3D(); diff --git a/scene/3d/navigation/SCsub b/scene/3d/navigation/SCsub new file mode 100644 index 000000000000..374dc2119dcd --- /dev/null +++ b/scene/3d/navigation/SCsub @@ -0,0 +1,6 @@ +#!/usr/bin/env python +from misc.utility.scons_hints import * + +Import("env") + +env.add_source_files(env.scene_sources, "*.cpp") diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation/navigation_agent_3d.cpp similarity index 99% rename from scene/3d/navigation_agent_3d.cpp rename to scene/3d/navigation/navigation_agent_3d.cpp index ec796baed604..ffb35f05c4da 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation/navigation_agent_3d.cpp @@ -30,7 +30,7 @@ #include "navigation_agent_3d.h" -#include "scene/3d/navigation_link_3d.h" +#include "scene/3d/navigation/navigation_link_3d.h" #include "servers/navigation_server_3d.h" void NavigationAgent3D::_bind_methods() { diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation/navigation_agent_3d.h similarity index 100% rename from scene/3d/navigation_agent_3d.h rename to scene/3d/navigation/navigation_agent_3d.h diff --git a/scene/3d/navigation_link_3d.cpp b/scene/3d/navigation/navigation_link_3d.cpp similarity index 100% rename from scene/3d/navigation_link_3d.cpp rename to scene/3d/navigation/navigation_link_3d.cpp diff --git a/scene/3d/navigation_link_3d.h b/scene/3d/navigation/navigation_link_3d.h similarity index 100% rename from scene/3d/navigation_link_3d.h rename to scene/3d/navigation/navigation_link_3d.h diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation/navigation_obstacle_3d.cpp similarity index 100% rename from scene/3d/navigation_obstacle_3d.cpp rename to scene/3d/navigation/navigation_obstacle_3d.cpp diff --git a/scene/3d/navigation_obstacle_3d.h b/scene/3d/navigation/navigation_obstacle_3d.h similarity index 100% rename from scene/3d/navigation_obstacle_3d.h rename to scene/3d/navigation/navigation_obstacle_3d.h diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation/navigation_region_3d.cpp similarity index 100% rename from scene/3d/navigation_region_3d.cpp rename to scene/3d/navigation/navigation_region_3d.cpp diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation/navigation_region_3d.h similarity index 100% rename from scene/3d/navigation_region_3d.h rename to scene/3d/navigation/navigation_region_3d.h diff --git a/scene/3d/physics/static_body_3d.cpp b/scene/3d/physics/static_body_3d.cpp index 491904e7e49a..37bd275c46a8 100644 --- a/scene/3d/physics/static_body_3d.cpp +++ b/scene/3d/physics/static_body_3d.cpp @@ -30,6 +30,7 @@ #include "static_body_3d.h" +#ifndef NAVIGATION_3D_DISABLED #include "core/math/convex_hull.h" #include "scene/resources/3d/box_shape_3d.h" #include "scene/resources/3d/capsule_shape_3d.h" @@ -47,6 +48,7 @@ Callable StaticBody3D::_navmesh_source_geometry_parsing_callback; RID StaticBody3D::_navmesh_source_geometry_parser; +#endif // NAVIGATION_3D_DISABLED void StaticBody3D::set_physics_material_override(const Ref &p_physics_material_override) { if (physics_material_override.is_valid()) { @@ -95,6 +97,7 @@ void StaticBody3D::_reload_physics_characteristics() { } } +#ifndef NAVIGATION_3D_DISABLED void StaticBody3D::navmesh_parse_init() { ERR_FAIL_NULL(NavigationServer3D::get_singleton()); if (!_navmesh_source_geometry_parser.is_valid()) { @@ -226,6 +229,7 @@ void StaticBody3D::navmesh_parse_source_geometry(const Ref &p_na } } } +#endif // NAVIGATION_3D_DISABLED void StaticBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_constant_linear_velocity", "vel"), &StaticBody3D::set_constant_linear_velocity); diff --git a/scene/3d/physics/static_body_3d.h b/scene/3d/physics/static_body_3d.h index abd1e5bc3044..f4869575601c 100644 --- a/scene/3d/physics/static_body_3d.h +++ b/scene/3d/physics/static_body_3d.h @@ -32,8 +32,10 @@ #include "scene/3d/physics/physics_body_3d.h" +#ifndef NAVIGATION_3D_DISABLED class NavigationMesh; class NavigationMeshSourceGeometryData3D; +#endif // NAVIGATION_3D_DISABLED class StaticBody3D : public PhysicsBody3D { GDCLASS(StaticBody3D, PhysicsBody3D); @@ -62,10 +64,12 @@ class StaticBody3D : public PhysicsBody3D { private: void _reload_physics_characteristics(); +#ifndef NAVIGATION_3D_DISABLED static Callable _navmesh_source_geometry_parsing_callback; static RID _navmesh_source_geometry_parser; public: static void navmesh_parse_init(); static void navmesh_parse_source_geometry(const Ref &p_navigation_mesh, Ref p_source_geometry_data, Node *p_node); +#endif // NAVIGATION_3D_DISABLED }; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 6574804e1a01..006f9a45a8ab 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -131,7 +131,9 @@ #include "scene/resources/mesh_data_tool.h" #include "scene/resources/mesh_texture.h" #include "scene/resources/multimesh.h" +#if !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) #include "scene/resources/navigation_mesh.h" +#endif // !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) #include "scene/resources/packed_scene.h" #include "scene/resources/particle_process_material.h" #include "scene/resources/placeholder_textures.h" @@ -174,10 +176,6 @@ #include "scene/2d/marker_2d.h" #include "scene/2d/mesh_instance_2d.h" #include "scene/2d/multimesh_instance_2d.h" -#include "scene/2d/navigation_agent_2d.h" -#include "scene/2d/navigation_link_2d.h" -#include "scene/2d/navigation_obstacle_2d.h" -#include "scene/2d/navigation_region_2d.h" #include "scene/2d/parallax_2d.h" #include "scene/2d/parallax_background.h" #include "scene/2d/parallax_layer.h" @@ -189,8 +187,6 @@ #include "scene/2d/tile_map.h" #include "scene/2d/tile_map_layer.h" #include "scene/2d/visible_on_screen_notifier_2d.h" -#include "scene/resources/2d/navigation_mesh_source_geometry_data_2d.h" -#include "scene/resources/2d/navigation_polygon.h" #include "scene/resources/2d/polygon_path_finder.h" #include "scene/resources/2d/skeleton/skeleton_modification_2d.h" #include "scene/resources/2d/skeleton/skeleton_modification_2d_ccdik.h" @@ -202,6 +198,15 @@ #include "scene/resources/2d/tile_set.h" #include "scene/resources/world_2d.h" +#ifndef NAVIGATION_2D_DISABLED +#include "scene/2d/navigation/navigation_agent_2d.h" +#include "scene/2d/navigation/navigation_link_2d.h" +#include "scene/2d/navigation/navigation_obstacle_2d.h" +#include "scene/2d/navigation/navigation_region_2d.h" +#include "scene/resources/2d/navigation_mesh_source_geometry_data_2d.h" +#include "scene/resources/2d/navigation_polygon.h" +#endif // NAVIGATION_2D_DISABLED + #ifndef _3D_DISABLED #include "scene/3d/audio_listener_3d.h" #include "scene/3d/audio_stream_player_3d.h" @@ -221,10 +226,6 @@ #include "scene/3d/marker_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/multimesh_instance_3d.h" -#include "scene/3d/navigation_agent_3d.h" -#include "scene/3d/navigation_link_3d.h" -#include "scene/3d/navigation_obstacle_3d.h" -#include "scene/3d/navigation_region_3d.h" #include "scene/3d/node_3d.h" #include "scene/3d/occluder_instance_3d.h" #include "scene/3d/path_3d.h" @@ -238,12 +239,6 @@ #include "scene/3d/visible_on_screen_notifier_3d.h" #include "scene/3d/voxel_gi.h" #include "scene/3d/world_environment.h" -#ifndef XR_DISABLED -#include "scene/3d/xr/xr_body_modifier_3d.h" -#include "scene/3d/xr/xr_face_modifier_3d.h" -#include "scene/3d/xr/xr_hand_modifier_3d.h" -#include "scene/3d/xr/xr_nodes.h" -#endif // XR_DISABLED #include "scene/animation/root_motion_view.h" #include "scene/resources/3d/fog_material.h" #include "scene/resources/3d/importer_mesh.h" @@ -252,6 +247,19 @@ #include "scene/resources/3d/primitive_meshes.h" #include "scene/resources/3d/sky_material.h" #include "scene/resources/3d/world_3d.h" +#ifndef NAVIGATION_3D_DISABLED +#include "scene/3d/navigation/navigation_agent_3d.h" +#include "scene/3d/navigation/navigation_link_3d.h" +#include "scene/3d/navigation/navigation_obstacle_3d.h" +#include "scene/3d/navigation/navigation_region_3d.h" +#include "scene/resources/3d/navigation_mesh_source_geometry_data_3d.h" +#endif // NAVIGATION_3D_DISABLED +#ifndef XR_DISABLED +#include "scene/3d/xr/xr_body_modifier_3d.h" +#include "scene/3d/xr/xr_face_modifier_3d.h" +#include "scene/3d/xr/xr_hand_modifier_3d.h" +#include "scene/3d/xr/xr_nodes.h" +#endif // XR_DISABLED #endif // _3D_DISABLED #if !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED) @@ -684,10 +692,13 @@ void register_scene_types() { GDREGISTER_CLASS(Generic6DOFJoint3D); #endif // PHYSICS_3D_DISABLED +#ifndef NAVIGATION_3D_DISABLED + GDREGISTER_CLASS(NavigationMeshSourceGeometryData3D); GDREGISTER_CLASS(NavigationRegion3D); GDREGISTER_CLASS(NavigationAgent3D); GDREGISTER_CLASS(NavigationObstacle3D); GDREGISTER_CLASS(NavigationLink3D); +#endif // NAVIGATION_3D_DISABLED OS::get_singleton()->yield(); // may take time to init #endif // _3D_DISABLED @@ -942,7 +953,6 @@ void register_scene_types() { BaseMaterial3D::init_shaders(); GDREGISTER_CLASS(MeshLibrary); - GDREGISTER_CLASS(NavigationMeshSourceGeometryData3D); OS::get_singleton()->yield(); // may take time to init @@ -1054,6 +1064,10 @@ void register_scene_types() { OS::get_singleton()->yield(); // may take time to init GDREGISTER_CLASS(AudioStreamPlayer2D); + GDREGISTER_CLASS(Curve2D); + GDREGISTER_CLASS(Path2D); + GDREGISTER_CLASS(PathFollow2D); + #ifndef PHYSICS_2D_DISABLED GDREGISTER_ABSTRACT_CLASS(Shape2D); GDREGISTER_CLASS(WorldBoundaryShape2D); @@ -1065,18 +1079,19 @@ void register_scene_types() { GDREGISTER_CLASS(ConvexPolygonShape2D); GDREGISTER_CLASS(ConcavePolygonShape2D); #endif // PHYSICS_2D_DISABLED - GDREGISTER_CLASS(Curve2D); - GDREGISTER_CLASS(Path2D); - GDREGISTER_CLASS(PathFollow2D); - GDREGISTER_CLASS(PolygonPathFinder); +#if !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) GDREGISTER_CLASS(NavigationMesh); +#endif // !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) + +#ifndef NAVIGATION_2D_DISABLED GDREGISTER_CLASS(NavigationMeshSourceGeometryData2D); GDREGISTER_CLASS(NavigationPolygon); GDREGISTER_CLASS(NavigationRegion2D); GDREGISTER_CLASS(NavigationAgent2D); GDREGISTER_CLASS(NavigationObstacle2D); GDREGISTER_CLASS(NavigationLink2D); + GDREGISTER_CLASS(PolygonPathFinder); OS::get_singleton()->yield(); // may take time to init @@ -1090,7 +1105,9 @@ void register_scene_types() { #ifndef PHYSICS_2D_DISABLED StaticBody2D::navmesh_parse_init(); #endif // PHYSICS_2D_DISABLED -#ifndef _3D_DISABLED +#endif // NAVIGATION_2D_DISABLED + +#ifndef NAVIGATION_3D_DISABLED // 3D nodes that support navmesh baking need to server register their source geometry parsers. MeshInstance3D::navmesh_parse_init(); MultiMeshInstance3D::navmesh_parse_init(); @@ -1098,9 +1115,11 @@ void register_scene_types() { #ifndef PHYSICS_3D_DISABLED StaticBody3D::navmesh_parse_init(); #endif // PHYSICS_3D_DISABLED -#endif // _3D_DISABLED +#endif // NAVIGATION_3D_DISABLED +#if !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) OS::get_singleton()->yield(); // may take time to init +#endif // !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) GDREGISTER_ABSTRACT_CLASS(SceneState); GDREGISTER_CLASS(PackedScene); @@ -1116,8 +1135,10 @@ void register_scene_types() { ClassDB::add_compatibility_class("BitmapFont", "FontFile"); ClassDB::add_compatibility_class("DynamicFont", "FontFile"); ClassDB::add_compatibility_class("DynamicFontData", "FontFile"); +#ifndef NAVIGATION_3D_DISABLED ClassDB::add_compatibility_class("Navigation3D", "Node3D"); ClassDB::add_compatibility_class("Navigation2D", "Node2D"); +#endif // NAVIGATION_3D_DISABLED ClassDB::add_compatibility_class("OpenSimplexNoise", "FastNoiseLite"); ClassDB::add_compatibility_class("ProximityGroup", "Node3D"); ClassDB::add_compatibility_class("ToolButton", "Button"); @@ -1164,13 +1185,17 @@ void register_scene_types() { ClassDB::add_compatibility_class("Listener", "AudioListener3D"); ClassDB::add_compatibility_class("MeshInstance", "MeshInstance3D"); ClassDB::add_compatibility_class("MultiMeshInstance", "MultiMeshInstance3D"); +#ifndef NAVIGATION_3D_DISABLED ClassDB::add_compatibility_class("NavigationAgent", "NavigationAgent3D"); ClassDB::add_compatibility_class("NavigationMeshInstance", "NavigationRegion3D"); ClassDB::add_compatibility_class("NavigationObstacle", "NavigationObstacle3D"); - ClassDB::add_compatibility_class("NavigationPolygonInstance", "NavigationRegion2D"); ClassDB::add_compatibility_class("NavigationRegion", "NavigationRegion3D"); - ClassDB::add_compatibility_class("Navigation2DServer", "NavigationServer2D"); ClassDB::add_compatibility_class("NavigationServer", "NavigationServer3D"); +#endif // NAVIGATION_3D_DISABLED +#ifndef NAVIGATION_2D_DISABLED + ClassDB::add_compatibility_class("NavigationPolygonInstance", "NavigationRegion2D"); + ClassDB::add_compatibility_class("Navigation2DServer", "NavigationServer2D"); +#endif // NAVIGATION_2D_DISABLED ClassDB::add_compatibility_class("OmniLight", "OmniLight3D"); ClassDB::add_compatibility_class("PanoramaSky", "Sky"); ClassDB::add_compatibility_class("Particles", "GPUParticles3D"); @@ -1306,9 +1331,13 @@ void register_scene_types() { for (int i = 0; i < 32; i++) { GLOBAL_DEF_BASIC(vformat("%s/layer_%d", PNAME("layer_names/2d_physics"), i + 1), ""); +#ifndef NAVIGATION_2D_DISABLED GLOBAL_DEF_BASIC(vformat("%s/layer_%d", PNAME("layer_names/2d_navigation"), i + 1), ""); +#endif // NAVIGATION_2D_DISABLED GLOBAL_DEF_BASIC(vformat("%s/layer_%d", PNAME("layer_names/3d_physics"), i + 1), ""); +#ifndef NAVIGATION_3D_DISABLED GLOBAL_DEF_BASIC(vformat("%s/layer_%d", PNAME("layer_names/3d_navigation"), i + 1), ""); +#endif // NAVIGATION_3D_DISABLED } for (int i = 0; i < 32; i++) { diff --git a/scene/resources/2d/SCsub b/scene/resources/2d/SCsub index 8db7b4229ace..48a5659bb7dc 100644 --- a/scene/resources/2d/SCsub +++ b/scene/resources/2d/SCsub @@ -3,9 +3,6 @@ from misc.utility.scons_hints import * Import("env") -env.add_source_files(env.scene_sources, "navigation_mesh_source_geometry_data_2d.cpp") -env.add_source_files(env.scene_sources, "navigation_polygon.cpp") -env.add_source_files(env.scene_sources, "polygon_path_finder.cpp") env.add_source_files(env.scene_sources, "tile_set.cpp") if not env["disable_physics_2d"]: @@ -18,5 +15,9 @@ if not env["disable_physics_2d"]: env.add_source_files(env.scene_sources, "separation_ray_shape_2d.cpp") env.add_source_files(env.scene_sources, "shape_2d.cpp") env.add_source_files(env.scene_sources, "world_boundary_shape_2d.cpp") +if not env["disable_navigation_2d"]: + env.add_source_files(env.scene_sources, "navigation_mesh_source_geometry_data_2d.cpp") + env.add_source_files(env.scene_sources, "navigation_polygon.cpp") + env.add_source_files(env.scene_sources, "polygon_path_finder.cpp") SConscript("skeleton/SCsub") diff --git a/scene/resources/2d/tile_set.compat.inc b/scene/resources/2d/tile_set.compat.inc index 58e33f7b357e..9eb036714657 100644 --- a/scene/resources/2d/tile_set.compat.inc +++ b/scene/resources/2d/tile_set.compat.inc @@ -32,16 +32,20 @@ #include "tile_set.h" +#ifndef NAVIGATION_2D_DISABLED Ref TileData::_get_navigation_polygon_bind_compat_84660(int p_layer_id) const { return get_navigation_polygon(p_layer_id, false, false, false); } +#endif // NAVIGATION_2D_DISABLED Ref TileData::_get_occluder_bind_compat_84660(int p_layer_id) const { return get_occluder_polygon(p_layer_id, 0, false, false, false); } void TileData::_bind_compatibility_methods() { +#ifndef NAVIGATION_2D_DISABLED ClassDB::bind_compatibility_method(D_METHOD("get_navigation_polygon"), &TileData::_get_navigation_polygon_bind_compat_84660); +#endif // NAVIGATION_2D_DISABLED ClassDB::bind_compatibility_method(D_METHOD("get_occluder"), &TileData::_get_occluder_bind_compat_84660); } diff --git a/scene/resources/2d/tile_set.cpp b/scene/resources/2d/tile_set.cpp index 2862aca11756..7196fa66fd02 100644 --- a/scene/resources/2d/tile_set.cpp +++ b/scene/resources/2d/tile_set.cpp @@ -37,7 +37,10 @@ #include "core/templates/rb_set.h" #include "scene/gui/control.h" #include "scene/resources/image_texture.h" + +#ifndef NAVIGATION_2D_DISABLED #include "servers/navigation_server_2d.h" +#endif // NAVIGATION_2D_DISABLED /////////////////////////////// TileMapPattern ////////////////////////////////////// @@ -965,6 +968,7 @@ bool TileSet::is_valid_terrain_peering_bit(int p_terrain_set, TileSet::CellNeigh return is_valid_terrain_peering_bit_for_mode(terrain_mode, p_peering_bit); } +#ifndef NAVIGATION_2D_DISABLED // Navigation int TileSet::get_navigation_layers_count() const { return navigation_layers.size(); @@ -1039,6 +1043,7 @@ bool TileSet::get_navigation_layer_layer_value(int p_layer_index, int p_layer_nu return get_navigation_layer_layers(p_layer_index) & (1 << (p_layer_number - 1)); } +#endif // NAVIGATION_2D_DISABLED // Custom data. int TileSet::get_custom_data_layers_count() const { @@ -3413,6 +3418,7 @@ void TileSet::_compatibility_conversion() { tile_data->add_occluder_polygon(0); tile_data->set_occluder_polygon(0, 0, occluder); } +#ifndef NAVIGATION_2D_DISABLED if (ctd->navigation.is_valid()) { if (get_navigation_layers_count() < 1) { add_navigation_layer(); @@ -3425,6 +3431,7 @@ void TileSet::_compatibility_conversion() { navigation->set_vertices(vertices); tile_data->set_navigation_polygon(0, navigation); } +#endif // NAVIGATION_2D_DISABLED tile_data->set_z_index(ctd->z_index); @@ -3522,6 +3529,7 @@ void TileSet::_compatibility_conversion() { tile_data->add_occluder_polygon(0); tile_data->set_occluder_polygon(0, 0, occluder); } +#ifndef NAVIGATION_2D_DISABLED if (ctd->autotile_navpoly_map.has(coords)) { if (get_navigation_layers_count() < 1) { add_navigation_layer(); @@ -3534,6 +3542,7 @@ void TileSet::_compatibility_conversion() { navigation->set_vertices(vertices); tile_data->set_navigation_polygon(0, navigation); } +#endif // NAVIGATION_2D_DISABLED if (ctd->autotile_priority_map.has(coords)) { tile_data->set_probability(ctd->autotile_priority_map[coords]); } @@ -3732,7 +3741,9 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) { if (p[0].get_type() == Variant::VECTOR2) { last_coord = p[0]; } else if (p[0].get_type() == Variant::OBJECT) { +#ifndef NAVIGATION_2D_DISABLED ctd->autotile_navpoly_map.insert(last_coord, p[0]); +#endif // NAVIGATION_2D_DISABLED } p.pop_front(); } @@ -3794,7 +3805,9 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) { } else if (what == "occluder") { ctd->occluder = p_value; } else if (what == "navigation") { +#ifndef NAVIGATION_2D_DISABLED ctd->navigation = p_value; +#endif // NAVIGATION_2D_DISABLED /* // IGNORED FOR NOW, they seem duplicated data compared to the shapes array @@ -3913,6 +3926,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) { } } } else if (components.size() == 2 && components[0].begins_with("navigation_layer_") && components[0].trim_prefix("navigation_layer_").is_valid_int()) { +#ifndef NAVIGATION_2D_DISABLED // Navigation layers. int index = components[0].trim_prefix("navigation_layer_").to_int(); ERR_FAIL_COND_V(index < 0, false); @@ -3924,6 +3938,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) { set_navigation_layer_layers(index, p_value); return true; } +#endif // NAVIGATION_2D_DISABLED } else if (components.size() == 2 && components[0].begins_with("custom_data_layer_") && components[0].trim_prefix("custom_data_layer_").is_valid_int()) { // Custom data layers. int index = components[0].trim_prefix("custom_data_layer_").to_int(); @@ -4057,10 +4072,12 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const { if (index < 0 || index >= navigation_layers.size()) { return false; } +#ifndef NAVIGATION_2D_DISABLED if (components[1] == "layers") { r_ret = get_navigation_layer_layers(index); return true; } +#endif // NAVIGATION_2D_DISABLED } else if (components.size() == 2 && components[0].begins_with("custom_data_layer_") && components[0].trim_prefix("custom_data_layer_").is_valid_int()) { // Custom data layers. int index = components[0].trim_prefix("custom_data_layer_").to_int(); @@ -4294,6 +4311,7 @@ void TileSet::_bind_methods() { ClassDB::bind_method(D_METHOD("set_terrain_color", "terrain_set", "terrain_index", "color"), &TileSet::set_terrain_color); ClassDB::bind_method(D_METHOD("get_terrain_color", "terrain_set", "terrain_index"), &TileSet::get_terrain_color); +#ifndef NAVIGATION_2D_DISABLED // Navigation ClassDB::bind_method(D_METHOD("get_navigation_layers_count"), &TileSet::get_navigation_layers_count); ClassDB::bind_method(D_METHOD("add_navigation_layer", "to_position"), &TileSet::add_navigation_layer, DEFVAL(-1)); @@ -4303,6 +4321,7 @@ void TileSet::_bind_methods() { ClassDB::bind_method(D_METHOD("get_navigation_layer_layers", "layer_index"), &TileSet::get_navigation_layer_layers); ClassDB::bind_method(D_METHOD("set_navigation_layer_layer_value", "layer_index", "layer_number", "value"), &TileSet::set_navigation_layer_layer_value); ClassDB::bind_method(D_METHOD("get_navigation_layer_layer_value", "layer_index", "layer_number"), &TileSet::get_navigation_layer_layer_value); +#endif // NAVIGATION_2D_DISABLED // Custom data ClassDB::bind_method(D_METHOD("get_custom_data_layers_count"), &TileSet::get_custom_data_layers_count); @@ -4350,7 +4369,9 @@ void TileSet::_bind_methods() { ADD_GROUP("", ""); ADD_ARRAY("physics_layers", "physics_layer_"); ADD_ARRAY("terrain_sets", "terrain_set_"); +#ifndef NAVIGATION_2D_DISABLED ADD_ARRAY("navigation_layers", "navigation_layer_"); +#endif // NAVIGATION_2D_DISABLED ADD_ARRAY("custom_data_layers", "custom_data_layer_"); // -- Enum binding -- @@ -4558,6 +4579,7 @@ void TileSetAtlasSource::remove_terrain(int p_terrain_set, int p_index) { } } +#ifndef NAVIGATION_2D_DISABLED void TileSetAtlasSource::add_navigation_layer(int p_to_pos) { for (KeyValue E_tile : tiles) { for (KeyValue E_alternative : E_tile.value.alternatives) { @@ -4581,6 +4603,7 @@ void TileSetAtlasSource::remove_navigation_layer(int p_index) { } } } +#endif // NAVIGATION_2D_DISABLED void TileSetAtlasSource::add_custom_data_layer(int p_to_pos) { for (KeyValue E_tile : tiles) { @@ -5932,7 +5955,9 @@ void TileData::notify_tile_data_properties_should_change() { terrain_peering_bits[bit_index] = -1; } } +#ifndef NAVIGATION_2D_DISABLED navigation.resize(tile_set->get_navigation_layers_count()); +#endif // NAVIGATION_2D_DISABLED // Convert custom data to the new type. custom_data.resize(tile_set->get_custom_data_layers_count()); @@ -6071,6 +6096,7 @@ void TileData::remove_terrain(int p_terrain_set, int p_index) { } } +#ifndef NAVIGATION_2D_DISABLED void TileData::add_navigation_layer(int p_to_pos) { if (p_to_pos < 0) { p_to_pos = navigation.size(); @@ -6090,6 +6116,7 @@ void TileData::remove_navigation_layer(int p_index) { ERR_FAIL_INDEX(p_index, navigation.size()); navigation.remove_at(p_index); } +#endif // NAVIGATION_2D_DISABLED void TileData::add_custom_data_layer(int p_to_pos) { if (p_to_pos < 0) { @@ -6142,8 +6169,10 @@ TileData *TileData::duplicate() { // Terrain output->terrain_set = -1; memcpy(output->terrain_peering_bits, terrain_peering_bits, 16 * sizeof(int)); +#ifndef NAVIGATION_2D_DISABLED // Navigation output->navigation = navigation; +#endif // NAVIGATION_2D_DISABLED // Misc output->probability = probability; // Custom data @@ -6531,6 +6560,7 @@ TileSet::TerrainsPattern TileData::get_terrains_pattern() const { return output; } +#ifndef NAVIGATION_2D_DISABLED // Navigation void TileData::set_navigation_polygon(int p_layer_id, Ref p_navigation_polygon) { ERR_FAIL_INDEX(p_layer_id, navigation.size()); @@ -6578,6 +6608,7 @@ Ref TileData::get_navigation_polygon(int p_layer_id, bool p_f return I->value; } } +#endif // NAVIGATION_2D_DISABLED // Misc void TileData::set_probability(float p_probability) { @@ -6706,9 +6737,9 @@ bool TileData::_set(const StringName &p_name, const Variant &p_value) { return true; } } - } else + } #ifndef PHYSICS_2D_DISABLED - if (components.size() >= 2 && components[0].begins_with("physics_layer_") && components[0].trim_prefix("physics_layer_").is_valid_int()) { + else if (components.size() >= 2 && components[0].begins_with("physics_layer_") && components[0].trim_prefix("physics_layer_").is_valid_int()) { // Physics layers. int layer_index = components[0].trim_prefix("physics_layer_").to_int(); ERR_FAIL_COND_V(layer_index < 0, false); @@ -6763,51 +6794,54 @@ bool TileData::_set(const StringName &p_name, const Variant &p_value) { return true; } } - } else + } #endif // PHYSICS_2D_DISABLED - if (components.size() == 2 && components[0].begins_with("navigation_layer_") && components[0].trim_prefix("navigation_layer_").is_valid_int()) { - // Navigation layers. - int layer_index = components[0].trim_prefix("navigation_layer_").to_int(); - ERR_FAIL_COND_V(layer_index < 0, false); - if (components[1] == "polygon") { - Ref polygon = p_value; - - if (layer_index >= navigation.size()) { - if (tile_set) { - return false; - } else { - navigation.resize(layer_index + 1); - } - } - set_navigation_polygon(layer_index, polygon); - return true; - } - } else if (components.size() == 2 && components[0] == "terrains_peering_bit") { - // Terrains. - for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { - TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); - if (components[1] == TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]) { - set_terrain_peering_bit(bit, p_value); - return true; - } - } - return false; - } else if (components.size() == 1 && components[0].begins_with("custom_data_") && components[0].trim_prefix("custom_data_").is_valid_int()) { - // Custom data layers. - int layer_index = components[0].trim_prefix("custom_data_").to_int(); - ERR_FAIL_COND_V(layer_index < 0, false); +#ifndef NAVIGATION_2D_DISABLED + else if (components.size() == 2 && components[0].begins_with("navigation_layer_") && components[0].trim_prefix("navigation_layer_").is_valid_int()) { + // Navigation layers. + int layer_index = components[0].trim_prefix("navigation_layer_").to_int(); + ERR_FAIL_COND_V(layer_index < 0, false); + if (components[1] == "polygon") { + Ref polygon = p_value; - if (layer_index >= custom_data.size()) { + if (layer_index >= navigation.size()) { if (tile_set) { return false; } else { - custom_data.resize(layer_index + 1); + navigation.resize(layer_index + 1); } } - set_custom_data_by_layer_id(layer_index, p_value); - + set_navigation_polygon(layer_index, polygon); return true; } + } +#endif // NAVIGATION_2D_DISABLED + else if (components.size() == 2 && components[0] == "terrains_peering_bit") { + // Terrains. + for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { + TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); + if (components[1] == TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]) { + set_terrain_peering_bit(bit, p_value); + return true; + } + } + return false; + } else if (components.size() == 1 && components[0].begins_with("custom_data_") && components[0].trim_prefix("custom_data_").is_valid_int()) { + // Custom data layers. + int layer_index = components[0].trim_prefix("custom_data_").to_int(); + ERR_FAIL_COND_V(layer_index < 0, false); + + if (layer_index >= custom_data.size()) { + if (tile_set) { + return false; + } else { + custom_data.resize(layer_index + 1); + } + } + set_custom_data_by_layer_id(layer_index, p_value); + + return true; + } return false; } @@ -6854,9 +6888,9 @@ bool TileData::_get(const StringName &p_name, Variant &r_ret) const { return true; } } - } else + } #ifndef PHYSICS_2D_DISABLED - if (components.size() >= 2 && components[0].begins_with("physics_layer_") && components[0].trim_prefix("physics_layer_").is_valid_int()) { + else if (components.size() >= 2 && components[0].begins_with("physics_layer_") && components[0].trim_prefix("physics_layer_").is_valid_int()) { // Physics layers. int layer_index = components[0].trim_prefix("physics_layer_").to_int(); ERR_FAIL_COND_V(layer_index < 0, false); @@ -6892,38 +6926,32 @@ bool TileData::_get(const StringName &p_name, Variant &r_ret) const { return true; } } - } else + } #endif // PHYSICS_2D_DISABLED - if (components.size() == 2 && components[0] == "terrains_peering_bit") { - // Terrains. - for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { - if (components[1] == TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]) { - r_ret = terrain_peering_bits[i]; - return true; - } - } - return false; - } else if (components.size() == 2 && components[0].begins_with("navigation_layer_") && components[0].trim_prefix("navigation_layer_").is_valid_int()) { - // Occlusion layers. - int layer_index = components[0].trim_prefix("navigation_layer_").to_int(); - ERR_FAIL_COND_V(layer_index < 0, false); - if (layer_index >= navigation.size()) { - return false; - } - if (components[1] == "polygon") { - r_ret = get_navigation_polygon(layer_index); + else if (components.size() == 2 && components[0] == "terrains_peering_bit") { + // Terrains. + for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { + if (components[1] == TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]) { + r_ret = terrain_peering_bits[i]; return true; } - } else if (components.size() == 1 && components[0].begins_with("custom_data_") && components[0].trim_prefix("custom_data_").is_valid_int()) { - // Custom data layers. - int layer_index = components[0].trim_prefix("custom_data_").to_int(); - ERR_FAIL_COND_V(layer_index < 0, false); - if (layer_index >= custom_data.size()) { - return false; - } - r_ret = get_custom_data_by_layer_id(layer_index); + } + return false; + } +#ifndef NAVIGATION_2D_DISABLED + else if (components.size() == 2 && components[0].begins_with("navigation_layer_") && components[0].trim_prefix("navigation_layer_").is_valid_int()) { + // Occlusion layers. + int layer_index = components[0].trim_prefix("navigation_layer_").to_int(); + ERR_FAIL_COND_V(layer_index < 0, false); + if (layer_index >= navigation.size()) { + return false; + } + if (components[1] == "polygon") { + r_ret = get_navigation_polygon(layer_index); return true; } + } +#endif // NAVIGATION_2D_DISABLED } return false; @@ -7007,6 +7035,7 @@ void TileData::_get_property_list(List *p_list) const { } } +#ifndef NAVIGATION_2D_DISABLED // Navigation layers. p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Navigation", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); for (int i = 0; i < navigation.size(); i++) { @@ -7016,6 +7045,7 @@ void TileData::_get_property_list(List *p_list) const { } p_list->push_back(property_info); } +#endif // NAVIGATION_2D_DISABLED // Custom data layers. p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Custom Data", "custom_data_"), PROPERTY_HINT_NONE, "custom_data_", PROPERTY_USAGE_GROUP)); @@ -7090,9 +7120,11 @@ void TileData::_bind_methods() { ClassDB::bind_method(D_METHOD("get_terrain_peering_bit", "peering_bit"), &TileData::get_terrain_peering_bit); ClassDB::bind_method(D_METHOD("is_valid_terrain_peering_bit", "peering_bit"), &TileData::is_valid_terrain_peering_bit); +#ifndef NAVIGATION_2D_DISABLED // Navigation ClassDB::bind_method(D_METHOD("set_navigation_polygon", "layer_id", "navigation_polygon"), &TileData::set_navigation_polygon); ClassDB::bind_method(D_METHOD("get_navigation_polygon", "layer_id", "flip_h", "flip_v", "transpose"), &TileData::get_navigation_polygon, DEFVAL(false), DEFVAL(false), DEFVAL(false)); +#endif // NAVIGATION_2D_DISABLED // Misc. ClassDB::bind_method(D_METHOD("set_probability", "probability"), &TileData::set_probability); diff --git a/scene/resources/2d/tile_set.h b/scene/resources/2d/tile_set.h index e76e33687137..f108ff399eb8 100644 --- a/scene/resources/2d/tile_set.h +++ b/scene/resources/2d/tile_set.h @@ -36,13 +36,17 @@ #include "core/templates/rb_set.h" #include "scene/2d/light_occluder_2d.h" #include "scene/main/canvas_item.h" +#include "scene/resources/image_texture.h" +#include "scene/resources/packed_scene.h" +#include "scene/resources/physics_material.h" + #ifndef PHYSICS_2D_DISABLED #include "scene/resources/2d/convex_polygon_shape_2d.h" #endif // PHYSICS_2D_DISABLED + +#ifndef NAVIGATION_2D_DISABLED #include "scene/resources/2d/navigation_polygon.h" -#include "scene/resources/image_texture.h" -#include "scene/resources/packed_scene.h" -#include "scene/resources/physics_material.h" +#endif // NAVIGATION_2D_DISABLED #ifndef DISABLE_DEPRECATED #include "scene/resources/shader.h" @@ -53,12 +57,6 @@ class TileSetSource; class TileSetAtlasSource; class TileData; -// Forward-declare the plugins. -class TileSetPlugin; -class TileSetPluginAtlasRendering; -class TileSetPluginAtlasPhysics; -class TileSetPluginAtlasNavigation; - union TileMapCell { struct { int16_t source_id; @@ -178,14 +176,18 @@ class TileSet : public Resource { int autotile_spacing = 0; HashMap autotile_bitmask_flags; HashMap> autotile_occluder_map; +#ifndef NAVIGATION_2D_DISABLED HashMap> autotile_navpoly_map; +#endif // NAVIGATION_2D_DISABLED HashMap autotile_priority_map; HashMap autotile_z_index_map; Vector shapes; Ref occluder; Vector2 occluder_offset; +#ifndef NAVIGATION_2D_DISABLED Ref navigation; +#endif // NAVIGATION_2D_DISABLED Vector2 navigation_offset; int z_index = 0; }; @@ -406,9 +408,6 @@ class TileSet : public Resource { static void _bind_methods(); public: - // --- Plugins --- - Vector get_tile_set_atlas_plugins() const; - // --- Accessors for TileSet data --- // -- Shape and layout -- @@ -481,6 +480,7 @@ class TileSet : public Resource { bool is_valid_terrain_peering_bit_for_mode(TileSet::TerrainMode p_terrain_mode, TileSet::CellNeighbor p_peering_bit) const; bool is_valid_terrain_peering_bit(int p_terrain_set, TileSet::CellNeighbor p_peering_bit) const; +#ifndef NAVIGATION_2D_DISABLED // Navigation int get_navigation_layers_count() const; void add_navigation_layer(int p_index = -1); @@ -490,6 +490,7 @@ class TileSet : public Resource { uint32_t get_navigation_layer_layers(int p_layer_index) const; void set_navigation_layer_layer_value(int p_layer_index, int p_layer_number, bool p_value); bool get_navigation_layer_layer_value(int p_layer_index, int p_layer_number) const; +#endif // NAVIGATION_2D_DISABLED // Custom data int get_custom_data_layers_count() const; @@ -704,9 +705,11 @@ class TileSetAtlasSource : public TileSetSource { virtual void add_terrain(int p_terrain_set, int p_index) override; virtual void move_terrain(int p_terrain_set, int p_from_index, int p_to_pos) override; virtual void remove_terrain(int p_terrain_set, int p_index) override; +#ifndef NAVIGATION_2D_DISABLED virtual void add_navigation_layer(int p_index) override; virtual void move_navigation_layer(int p_from_index, int p_to_pos) override; virtual void remove_navigation_layer(int p_index) override; +#endif // NAVIGATION_2D_DISABLED virtual void add_custom_data_layer(int p_index) override; virtual void move_custom_data_layer(int p_from_index, int p_to_pos) override; virtual void remove_custom_data_layer(int p_index) override; @@ -886,12 +889,14 @@ class TileData : public Object { int terrain = -1; int terrain_peering_bits[16] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; +#ifndef NAVIGATION_2D_DISABLED // Navigation struct NavigationLayerTileData { Ref navigation_polygon; mutable HashMap> transformed_navigation_polygon; }; Vector navigation; +#endif // NAVIGATION_2D_DISABLED // Misc double probability = 1.0; @@ -906,7 +911,9 @@ class TileData : public Object { static void _bind_methods(); #ifndef DISABLE_DEPRECATED +#ifndef NAVIGATION_2D_DISABLED Ref _get_navigation_polygon_bind_compat_84660(int p_layer_id) const; +#endif // NAVIGATION_2D_DISABLED Ref _get_occluder_bind_compat_84660(int p_layer_id) const; static void _bind_compatibility_methods(); @@ -1004,9 +1011,11 @@ class TileData : public Object { TileSet::TerrainsPattern get_terrains_pattern() const; // Not exposed. +#ifndef NAVIGATION_2D_DISABLED // Navigation void set_navigation_polygon(int p_layer_id, Ref p_navigation_polygon); Ref get_navigation_polygon(int p_layer_id, bool p_flip_h = false, bool p_flip_v = false, bool p_transpose = false) const; +#endif // NAVIGATION_2D_DISABLED // Misc void set_probability(float p_probability); diff --git a/scene/resources/3d/SCsub b/scene/resources/3d/SCsub index 48abc5faefbe..e8a11591428f 100644 --- a/scene/resources/3d/SCsub +++ b/scene/resources/3d/SCsub @@ -6,7 +6,6 @@ Import("env") env.add_source_files(env.scene_sources, "fog_material.cpp") env.add_source_files(env.scene_sources, "importer_mesh.cpp") env.add_source_files(env.scene_sources, "mesh_library.cpp") -env.add_source_files(env.scene_sources, "navigation_mesh_source_geometry_data_3d.cpp") env.add_source_files(env.scene_sources, "primitive_meshes.cpp") env.add_source_files(env.scene_sources, "skin.cpp") env.add_source_files(env.scene_sources, "sky_material.cpp") @@ -25,3 +24,5 @@ if not env["disable_physics_3d"]: env.add_source_files(env.scene_sources, "shape_3d.cpp") env.add_source_files(env.scene_sources, "sphere_shape_3d.cpp") env.add_source_files(env.scene_sources, "world_boundary_shape_3d.cpp") +if not env["disable_navigation_3d"]: + env.add_source_files(env.scene_sources, "navigation_mesh_source_geometry_data_3d.cpp") diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index 54d01383ebc7..9fb3418760cf 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -32,9 +32,12 @@ #include "core/config/project_settings.h" #include "scene/2d/visible_on_screen_notifier_2d.h" -#include "servers/navigation_server_2d.h" #include "servers/rendering_server.h" +#ifndef NAVIGATION_2D_DISABLED +#include "servers/navigation_server_2d.h" +#endif // NAVIGATION_2D_DISABLED + RID World2D::get_canvas() const { return canvas; } @@ -53,6 +56,7 @@ RID World2D::get_space() const { } #endif // PHYSICS_2D_DISABLED +#ifndef NAVIGATION_2D_DISABLED RID World2D::get_navigation_map() const { if (navigation_map.is_null()) { navigation_map = NavigationServer2D::get_singleton()->map_create(); @@ -64,6 +68,7 @@ RID World2D::get_navigation_map() const { } return navigation_map; } +#endif // NAVIGATION_2D_DISABLED #ifndef PHYSICS_2D_DISABLED PhysicsDirectSpaceState2D *World2D::get_direct_space_state() { @@ -73,14 +78,18 @@ PhysicsDirectSpaceState2D *World2D::get_direct_space_state() { void World2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_canvas"), &World2D::get_canvas); +#ifndef NAVIGATION_2D_DISABLED ClassDB::bind_method(D_METHOD("get_navigation_map"), &World2D::get_navigation_map); +#endif // NAVIGATION_2D_DISABLED #ifndef PHYSICS_2D_DISABLED ClassDB::bind_method(D_METHOD("get_space"), &World2D::get_space); ClassDB::bind_method(D_METHOD("get_direct_space_state"), &World2D::get_direct_space_state); #endif // PHYSICS_2D_DISABLED ADD_PROPERTY(PropertyInfo(Variant::RID, "canvas", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "", "get_canvas"); +#ifndef NAVIGATION_2D_DISABLED ADD_PROPERTY(PropertyInfo(Variant::RID, "navigation_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "", "get_navigation_map"); +#endif // NAVIGATION_2D_DISABLED #ifndef PHYSICS_2D_DISABLED ADD_PROPERTY(PropertyInfo(Variant::RID, "space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "", "get_space"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState2D", PROPERTY_USAGE_NONE), "", "get_direct_space_state"); @@ -104,14 +113,19 @@ World2D::~World2D() { #ifndef PHYSICS_2D_DISABLED ERR_FAIL_NULL(PhysicsServer2D::get_singleton()); #endif // PHYSICS_2D_DISABLED +#ifndef NAVIGATION_2D_DISABLED ERR_FAIL_NULL(NavigationServer2D::get_singleton()); +#endif // NAVIGATION_2D_DISABLED + RenderingServer::get_singleton()->free(canvas); #ifndef PHYSICS_2D_DISABLED if (space.is_valid()) { PhysicsServer2D::get_singleton()->free(space); } #endif // PHYSICS_2D_DISABLED +#ifndef NAVIGATION_2D_DISABLED if (navigation_map.is_valid()) { NavigationServer2D::get_singleton()->free(navigation_map); } +#endif // NAVIGATION_2D_DISABLED } diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h index 822b361a12b2..007e1ffaff5d 100644 --- a/scene/resources/world_2d.h +++ b/scene/resources/world_2d.h @@ -45,7 +45,9 @@ class World2D : public Resource { RID canvas; mutable RID space; +#ifndef NAVIGATION_2D_DISABLED mutable RID navigation_map; +#endif // NAVIGATION_2D_DISABLED HashSet viewports; @@ -55,7 +57,9 @@ class World2D : public Resource { public: RID get_canvas() const; +#ifndef NAVIGATION_2D_DISABLED RID get_navigation_map() const; +#endif // NAVIGATION_2D_DISABLED #ifndef PHYSICS_2D_DISABLED RID get_space() const; diff --git a/servers/navigation/SCsub b/servers/navigation/SCsub index 98f918b2458c..57335c928fab 100644 --- a/servers/navigation/SCsub +++ b/servers/navigation/SCsub @@ -3,4 +3,10 @@ from misc.utility.scons_hints import * Import("env") -env.add_source_files(env.servers_sources, "*.cpp") +if not env["disable_navigation_2d"]: + env.add_source_files(env.servers_sources, "navigation_path_query_parameters_2d.cpp") + env.add_source_files(env.servers_sources, "navigation_path_query_result_2d.cpp") + +if not env["disable_navigation_3d"]: + env.add_source_files(env.servers_sources, "navigation_path_query_parameters_3d.cpp") + env.add_source_files(env.servers_sources, "navigation_path_query_result_3d.cpp") diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index bfa3b814c858..b99dc72ba6e0 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -80,15 +80,19 @@ #include "text_server.h" // 2D physics and navigation. +#ifndef NAVIGATION_2D_DISABLED #include "navigation_server_2d.h" +#endif // NAVIGATION_2D_DISABLED #ifndef PHYSICS_2D_DISABLED #include "physics_server_2d.h" #include "physics_server_2d_dummy.h" #include "servers/extensions/physics_server_2d_extension.h" #endif // PHYSICS_2D_DISABLED -// 3D physics and navigation (3D navigation is needed for 2D). +// 3D physics and navigation. +#ifndef NAVIGATION_3D_DISABLED #include "navigation_server_3d.h" +#endif // NAVIGATION_3D_DISABLED #ifndef PHYSICS_3D_DISABLED #include "physics_server_3d.h" #include "physics_server_3d_dummy.h" @@ -282,9 +286,11 @@ void register_server_types() { PhysicsServer2DManager::get_singleton()->register_server("Dummy", callable_mp_static(_create_dummy_physics_server_2d)); #endif // PHYSICS_2D_DISABLED +#ifndef NAVIGATION_2D_DISABLED GDREGISTER_ABSTRACT_CLASS(NavigationServer2D); GDREGISTER_CLASS(NavigationPathQueryParameters2D); GDREGISTER_CLASS(NavigationPathQueryResult2D); +#endif // NAVIGATION_2D_DISABLED #ifndef PHYSICS_3D_DISABLED // Physics 3D @@ -330,9 +336,11 @@ void register_server_types() { GDREGISTER_ABSTRACT_CLASS(XRTracker); #endif // XR_DISABLED +#ifndef NAVIGATION_3D_DISABLED GDREGISTER_ABSTRACT_CLASS(NavigationServer3D); GDREGISTER_CLASS(NavigationPathQueryParameters3D); GDREGISTER_CLASS(NavigationPathQueryResult3D); +#endif // NAVIGATION_3D_DISABLED writer_mjpeg = memnew(MovieWriterMJPEG); MovieWriter::add_writer(writer_mjpeg); @@ -361,8 +369,12 @@ void register_server_singletons() { Engine::get_singleton()->add_singleton(Engine::Singleton("CameraServer", CameraServer::get_singleton(), "CameraServer")); Engine::get_singleton()->add_singleton(Engine::Singleton("DisplayServer", DisplayServer::get_singleton(), "DisplayServer")); Engine::get_singleton()->add_singleton(Engine::Singleton("NativeMenu", NativeMenu::get_singleton(), "NativeMenu")); +#ifndef NAVIGATION_2D_DISABLED Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer2D", NavigationServer2D::get_singleton(), "NavigationServer2D")); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer3D", NavigationServer3D::get_singleton(), "NavigationServer3D")); +#endif // NAVIGATION_3D_DISABLED Engine::get_singleton()->add_singleton(Engine::Singleton("RenderingServer", RenderingServer::get_singleton(), "RenderingServer")); #ifndef PHYSICS_2D_DISABLED diff --git a/tests/scene/test_navigation_agent_2d.h b/tests/scene/test_navigation_agent_2d.h index 301934ad3a0d..929e812756e5 100644 --- a/tests/scene/test_navigation_agent_2d.h +++ b/tests/scene/test_navigation_agent_2d.h @@ -30,7 +30,7 @@ #pragma once -#include "scene/2d/navigation_agent_2d.h" +#include "scene/2d/navigation/navigation_agent_2d.h" #include "scene/2d/node_2d.h" #include "scene/main/window.h" #include "scene/resources/world_2d.h" diff --git a/tests/scene/test_navigation_agent_3d.h b/tests/scene/test_navigation_agent_3d.h index 11b7d62fab9a..649bf61250b3 100644 --- a/tests/scene/test_navigation_agent_3d.h +++ b/tests/scene/test_navigation_agent_3d.h @@ -30,7 +30,7 @@ #pragma once -#include "scene/3d/navigation_agent_3d.h" +#include "scene/3d/navigation/navigation_agent_3d.h" #include "scene/3d/node_3d.h" #include "scene/main/window.h" diff --git a/tests/scene/test_navigation_obstacle_2d.h b/tests/scene/test_navigation_obstacle_2d.h index 16fcc642302e..8c17a696bf72 100644 --- a/tests/scene/test_navigation_obstacle_2d.h +++ b/tests/scene/test_navigation_obstacle_2d.h @@ -30,7 +30,7 @@ #pragma once -#include "scene/2d/navigation_obstacle_2d.h" +#include "scene/2d/navigation/navigation_obstacle_2d.h" #include "scene/main/window.h" #include "tests/test_macros.h" diff --git a/tests/scene/test_navigation_obstacle_3d.h b/tests/scene/test_navigation_obstacle_3d.h index f776c379b2d8..c2d9c1ce9932 100644 --- a/tests/scene/test_navigation_obstacle_3d.h +++ b/tests/scene/test_navigation_obstacle_3d.h @@ -30,7 +30,7 @@ #pragma once -#include "scene/3d/navigation_obstacle_3d.h" +#include "scene/3d/navigation/navigation_obstacle_3d.h" #include "scene/main/window.h" #include "tests/test_macros.h" diff --git a/tests/scene/test_navigation_region_2d.h b/tests/scene/test_navigation_region_2d.h index 4f6d33fe031c..8a76215a20d7 100644 --- a/tests/scene/test_navigation_region_2d.h +++ b/tests/scene/test_navigation_region_2d.h @@ -30,7 +30,7 @@ #pragma once -#include "scene/2d/navigation_region_2d.h" +#include "scene/2d/navigation/navigation_region_2d.h" #include "scene/main/window.h" #include "tests/test_macros.h" diff --git a/tests/scene/test_navigation_region_3d.h b/tests/scene/test_navigation_region_3d.h index d1f5f80ef5d9..1a5777c5d2d9 100644 --- a/tests/scene/test_navigation_region_3d.h +++ b/tests/scene/test_navigation_region_3d.h @@ -31,7 +31,7 @@ #pragma once #include "scene/3d/mesh_instance_3d.h" -#include "scene/3d/navigation_region_3d.h" +#include "scene/3d/navigation/navigation_region_3d.h" #include "scene/main/window.h" #include "scene/resources/3d/primitive_meshes.h" diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 5bbbf3f92567..bf6c9fa4d462 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -135,9 +135,6 @@ #include "tests/scene/test_parallax_2d.h" #include "tests/scene/test_path_2d.h" #include "tests/scene/test_path_follow_2d.h" -#ifndef PHYSICS_3D_DISABLED -#include "tests/scene/test_physics_material.h" -#endif // PHYSICS_3D_DISABLED #include "tests/scene/test_sprite_frames.h" #include "tests/scene/test_style_box_texture.h" #include "tests/scene/test_texture_progress_bar.h" @@ -163,6 +160,22 @@ #include "tests/scene/test_tree.h" #endif // ADVANCED_GUI_DISABLED +#ifndef _3D_DISABLED +#include "tests/scene/test_arraymesh.h" +#include "tests/scene/test_camera_3d.h" +#include "tests/scene/test_gltf_document.h" +#include "tests/scene/test_path_3d.h" +#include "tests/scene/test_path_follow_3d.h" +#include "tests/scene/test_primitives.h" +#include "tests/scene/test_skeleton_3d.h" +#include "tests/scene/test_sky.h" +#endif // _3D_DISABLED + +#ifndef PHYSICS_3D_DISABLED +#include "tests/scene/test_height_map_shape_3d.h" +#include "tests/scene/test_physics_material.h" +#endif // PHYSICS_3D_DISABLED + #ifdef MODULE_NAVIGATION_2D_ENABLED #include "tests/scene/test_navigation_agent_2d.h" #include "tests/scene/test_navigation_obstacle_2d.h" @@ -170,7 +183,6 @@ #include "tests/servers/test_navigation_server_2d.h" #endif // MODULE_NAVIGATION_2D_ENABLED -#ifndef _3D_DISABLED #ifdef MODULE_NAVIGATION_3D_ENABLED #include "tests/scene/test_navigation_agent_3d.h" #include "tests/scene/test_navigation_obstacle_3d.h" @@ -178,29 +190,20 @@ #include "tests/servers/test_navigation_server_3d.h" #endif // MODULE_NAVIGATION_3D_ENABLED -#include "tests/scene/test_arraymesh.h" -#include "tests/scene/test_camera_3d.h" -#include "tests/scene/test_gltf_document.h" -#ifndef PHYSICS_3D_DISABLED -#include "tests/scene/test_height_map_shape_3d.h" -#endif // PHYSICS_3D_DISABLED -#include "tests/scene/test_path_3d.h" -#include "tests/scene/test_path_follow_3d.h" -#include "tests/scene/test_primitives.h" -#include "tests/scene/test_skeleton_3d.h" -#include "tests/scene/test_sky.h" -#endif // _3D_DISABLED - #include "modules/modules_tests.gen.h" #include "tests/display_server_mock.h" #include "tests/test_macros.h" #include "scene/theme/theme_db.h" + +#ifndef NAVIGATION_2D_DISABLED #include "servers/navigation_server_2d.h" -#ifndef _3D_DISABLED +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED #include "servers/navigation_server_3d.h" -#endif // _3D_DISABLED +#endif // NAVIGATION_3D_DISABLED + #ifndef PHYSICS_2D_DISABLED #include "servers/physics_server_2d.h" #include "servers/physics_server_2d_dummy.h" @@ -209,6 +212,7 @@ #include "servers/physics_server_3d.h" #include "servers/physics_server_3d_dummy.h" #endif // PHYSICS_3D_DISABLED + #include "servers/rendering/rendering_server_default.h" int test_main(int argc, char *argv[]) { @@ -289,10 +293,13 @@ struct GodotTestCaseListener : public doctest::IReporter { #ifndef PHYSICS_3D_DISABLED PhysicsServer3D *physics_server_3d = nullptr; #endif // PHYSICS_3D_DISABLED -#ifndef _3D_DISABLED - NavigationServer3D *navigation_server_3d = nullptr; -#endif // _3D_DISABLED + +#ifndef NAVIGATION_2D_DISABLED NavigationServer2D *navigation_server_2d = nullptr; +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED + NavigationServer3D *navigation_server_3d = nullptr; +#endif // NAVIGATION_3D_DISABLED void test_case_start(const doctest::TestCaseData &p_in) override { reinitialize(); @@ -341,10 +348,12 @@ struct GodotTestCaseListener : public doctest::IReporter { #endif // PHYSICS_2D_DISABLED ERR_PRINT_OFF; -#ifndef _3D_DISABLED +#ifndef NAVIGATION_3D_DISABLED navigation_server_3d = NavigationServer3DManager::new_default_server(); -#endif // _3D_DISABLED +#endif // NAVIGATION_3D_DISABLED +#ifndef NAVIGATION_2D_DISABLED navigation_server_2d = NavigationServer2DManager::new_default_server(); +#endif // NAVIGATION_2D_DISABLED ERR_PRINT_ON; memnew(InputMap); @@ -376,21 +385,23 @@ struct GodotTestCaseListener : public doctest::IReporter { return; } -#ifndef _3D_DISABLED +#ifndef NAVIGATION_3D_DISABLED if (suite_name.contains("[Navigation3D]") && navigation_server_3d == nullptr) { ERR_PRINT_OFF; navigation_server_3d = NavigationServer3DManager::new_default_server(); ERR_PRINT_ON; return; } -#endif // _3D_DISABLED +#endif // NAVIGATION_3D_DISABLED +#ifndef NAVIGATION_2D_DISABLED if (suite_name.contains("[Navigation2D]") && navigation_server_2d == nullptr) { ERR_PRINT_OFF; navigation_server_2d = NavigationServer2DManager::new_default_server(); ERR_PRINT_ON; return; } +#endif // NAVIGATION_2D_DISABLED } void test_case_end(const doctest::CurrentTestCaseStats &) override { @@ -420,17 +431,19 @@ struct GodotTestCaseListener : public doctest::IReporter { memdelete(SceneTree::get_singleton()); } -#ifndef _3D_DISABLED +#ifndef NAVIGATION_3D_DISABLED if (navigation_server_3d) { memdelete(navigation_server_3d); navigation_server_3d = nullptr; } -#endif // _3D_DISABLED +#endif // NAVIGATION_3D_DISABLED +#ifndef NAVIGATION_2D_DISABLED if (navigation_server_2d) { memdelete(navigation_server_2d); navigation_server_2d = nullptr; } +#endif // NAVIGATION_2D_DISABLED #ifndef PHYSICS_3D_DISABLED if (physics_server_3d) { From 40db9c55000951a7101c063ff78227e07e9737b9 Mon Sep 17 00:00:00 2001 From: LuoZhihao Date: Tue, 1 Apr 2025 19:02:43 +0800 Subject: [PATCH 015/111] Shader: Fix `bvec` to variant conversion --- servers/rendering/shader_language.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 6748689b2e8e..fa8d5a946848 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -4222,7 +4222,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector &p_value, } value = Variant(array); } else { - value = Variant(p_value[0].boolean); + value = Variant(p_value[0].sint | (p_value[1].sint << 1)); } break; case ShaderLanguage::TYPE_BVEC3: @@ -4235,7 +4235,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector &p_value, } value = Variant(array); } else { - value = Variant(p_value[0].boolean); + value = Variant(p_value[0].sint | (p_value[1].sint << 1) | (p_value[2].sint << 2)); } break; case ShaderLanguage::TYPE_BVEC4: @@ -4248,7 +4248,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector &p_value, } value = Variant(array); } else { - value = Variant(p_value[0].boolean); + value = Variant(p_value[0].sint | (p_value[1].sint << 1) | (p_value[2].sint << 2) | (p_value[3].sint << 3)); } break; case ShaderLanguage::TYPE_INT: From 1e7a69cf88c1f0cdc8c44a711504f46a323051b2 Mon Sep 17 00:00:00 2001 From: Eole Date: Mon, 3 Mar 2025 15:08:59 +0100 Subject: [PATCH 016/111] Fix CharacterBody's wall_min_slide_angle doc Replaced slope by wall --- doc/classes/CharacterBody2D.xml | 2 +- doc/classes/CharacterBody3D.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/classes/CharacterBody2D.xml b/doc/classes/CharacterBody2D.xml index 1807d51db09b..99f7181f2c5b 100644 --- a/doc/classes/CharacterBody2D.xml +++ b/doc/classes/CharacterBody2D.xml @@ -196,7 +196,7 @@ Current velocity vector in pixels per second, used and modified during calls to [method move_and_slide]. - Minimum angle (in radians) where the body is allowed to slide when it encounters a slope. The default value equals 15 degrees. This property only affects movement when [member motion_mode] is [constant MOTION_MODE_FLOATING]. + Minimum angle (in radians) where the body is allowed to slide when it encounters a wall. The default value equals 15 degrees. This property only affects movement when [member motion_mode] is [constant MOTION_MODE_FLOATING]. diff --git a/doc/classes/CharacterBody3D.xml b/doc/classes/CharacterBody3D.xml index 3871aa3746a8..0307ea67f767 100644 --- a/doc/classes/CharacterBody3D.xml +++ b/doc/classes/CharacterBody3D.xml @@ -187,7 +187,7 @@ Current velocity vector (typically meters per second), used and modified during calls to [method move_and_slide]. - Minimum angle (in radians) where the body is allowed to slide when it encounters a slope. The default value equals 15 degrees. When [member motion_mode] is [constant MOTION_MODE_GROUNDED], it only affects movement if [member floor_block_on_wall] is [code]true[/code]. + Minimum angle (in radians) where the body is allowed to slide when it encounters a wall. The default value equals 15 degrees. When [member motion_mode] is [constant MOTION_MODE_GROUNDED], it only affects movement if [member floor_block_on_wall] is [code]true[/code]. From 8353a0adfbd4f3e090d2d40b01e36036762d5e4c Mon Sep 17 00:00:00 2001 From: MewPurPur Date: Tue, 1 Apr 2025 14:18:35 +0300 Subject: [PATCH 017/111] Optimize HTML color validation --- core/math/color.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/core/math/color.cpp b/core/math/color.cpp index 699d414cc955..04922d9a482b 100644 --- a/core/math/color.cpp +++ b/core/math/color.cpp @@ -368,22 +368,20 @@ Color Color::html(const String &p_rgba) { bool Color::html_is_valid(const String &p_color) { String color = p_color; - if (color.length() == 0) { + if (color.is_empty()) { return false; } - if (color[0] == '#') { - color = color.substr(1); - } - // Check if the amount of hex digits is valid. + int current_pos = (color[0] == '#') ? 1 : 0; int len = color.length(); - if (!(len == 3 || len == 4 || len == 6 || len == 8)) { + int num_of_digits = len - current_pos; + if (!(num_of_digits == 3 || num_of_digits == 4 || num_of_digits == 6 || num_of_digits == 8)) { return false; } // Check if each hex digit is valid. - for (int i = 0; i < len; i++) { - if (_parse_col4(color, i) == -1) { + for (int i = current_pos; i < len; i++) { + if (!is_hex_digit(p_color[i])) { return false; } } From 9ef3571dcda148696b85b1217f6666773dd86b5f Mon Sep 17 00:00:00 2001 From: kobewi Date: Tue, 1 Apr 2025 17:44:25 +0200 Subject: [PATCH 018/111] Remember last POT generator path --- editor/localization_editor.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp index 8ba000459d79..6c597f4157db 100644 --- a/editor/localization_editor.cpp +++ b/editor/localization_editor.cpp @@ -32,6 +32,7 @@ #include "core/config/project_settings.h" #include "core/string/translation_server.h" +#include "editor/editor_settings.h" #include "editor/editor_translation_parser.h" #include "editor/editor_undo_redo_manager.h" #include "editor/filesystem_dock.h" @@ -400,6 +401,7 @@ void LocalizationEditor::_pot_add_builtin_toggled() { } void LocalizationEditor::_pot_generate(const String &p_file) { + EditorSettings::get_singleton()->set_project_metadata("pot_generator", "last_pot_path", p_file); POTGenerator::get_singleton()->generate_pot(p_file); } @@ -761,6 +763,7 @@ LocalizationEditor::LocalizationEditor() { pot_generate_dialog = memnew(EditorFileDialog); pot_generate_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); + pot_generate_dialog->set_current_path(EditorSettings::get_singleton()->get_project_metadata("pot_generator", "last_pot_path", String())); pot_generate_dialog->connect("file_selected", callable_mp(this, &LocalizationEditor::_pot_generate)); add_child(pot_generate_dialog); From e949f1926021a088c4efbe8d0acf10dadd71fb66 Mon Sep 17 00:00:00 2001 From: MJacred Date: Tue, 1 Apr 2025 19:40:36 +0200 Subject: [PATCH 019/111] Update class docs: `dpi_changed` signal is supported on Linux (Wayland) --- doc/classes/DisplayServer.xml | 2 +- doc/classes/Window.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index 2922ebe3d2ba..1ff4e1a5e7d9 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -2205,7 +2205,7 @@ Sent when the window is moved to the display with different DPI, or display DPI is changed. - [b]Note:[/b] This flag is implemented only on macOS. + [b]Note:[/b] This flag is implemented only on macOS and Linux (Wayland). Sent when the window title bar decoration is changed (e.g. [constant WINDOW_FLAG_EXTEND_TO_TITLE] is set or window entered/exited full screen mode). diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml index 90eba0bdea85..d6fd57ce4436 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -734,7 +734,7 @@ Emitted when the [Window]'s DPI changes as a result of OS-level changes (e.g. moving the window from a Retina display to a lower resolution one). - [b]Note:[/b] Only implemented on macOS. + [b]Note:[/b] Only implemented on macOS and Linux (Wayland). From ffaf30487ff5d162413252be27806b41c10cd35e Mon Sep 17 00:00:00 2001 From: Zae Date: Sun, 16 Mar 2025 15:21:06 +0800 Subject: [PATCH 020/111] Fix hash issue with OptimizedTranslation caused by signed char --- core/string/optimized_translation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/string/optimized_translation.h b/core/string/optimized_translation.h index 823adaf1da8b..fc4f446831b5 100644 --- a/core/string/optimized_translation.h +++ b/core/string/optimized_translation.h @@ -64,7 +64,7 @@ class OptimizedTranslation : public Translation { d = 0x1000193; } while (*p_str) { - d = (d * 0x1000193) ^ uint32_t(*p_str); + d = (d * 0x1000193) ^ static_cast(*p_str); p_str++; } From 4ea9c5531489f0886444ca8d8c21d4d01d12269a Mon Sep 17 00:00:00 2001 From: Lukas Tenbrink Date: Tue, 1 Apr 2025 12:50:14 +0200 Subject: [PATCH 021/111] Remove bool from `Object::notification` virtual function; replace with separate functions to avoid branching. --- core/object/object.cpp | 40 ++++++++++------ core/object/object.h | 31 +++++++++---- tests/core/object/test_object.h | 81 +++++++++++++++++---------------- 3 files changed, 91 insertions(+), 61 deletions(-) diff --git a/core/object/object.cpp b/core/object/object.cpp index 899e69650dcc..e801fc58d6ff 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -911,18 +911,14 @@ Variant Object::call_const(const StringName &p_method, const Variant **p_args, i return ret; } -void Object::notification(int p_notification, bool p_reversed) { - if (p_reversed) { - if (script_instance) { - script_instance->notification(p_notification, p_reversed); - } - } else { - _notificationv(p_notification, p_reversed); - } +void Object::_notification_forward(int p_notification) { + // Notify classes starting with Object and ending with most derived subclass. + // e.g. Object -> Node -> Node3D + _notification_forwardv(p_notification); if (_extension) { if (_extension->notification2) { - _extension->notification2(_extension_instance, p_notification, static_cast(p_reversed)); + _extension->notification2(_extension_instance, p_notification, static_cast(false)); #ifndef DISABLE_DEPRECATED } else if (_extension->notification) { _extension->notification(_extension_instance, p_notification); @@ -930,13 +926,29 @@ void Object::notification(int p_notification, bool p_reversed) { } } - if (p_reversed) { - _notificationv(p_notification, p_reversed); - } else { - if (script_instance) { - script_instance->notification(p_notification, p_reversed); + if (script_instance) { + script_instance->notification(p_notification, false); + } +} + +void Object::_notification_backward(int p_notification) { + if (script_instance) { + script_instance->notification(p_notification, true); + } + + if (_extension) { + if (_extension->notification2) { + _extension->notification2(_extension_instance, p_notification, static_cast(true)); +#ifndef DISABLE_DEPRECATED + } else if (_extension->notification) { + _extension->notification(_extension_instance, p_notification); +#endif // DISABLE_DEPRECATED } } + + // Notify classes starting with most derived subclass and ending in Object. + // e.g. Node3D -> Node -> Object + _notification_backwardv(p_notification); } String Object::to_string() { diff --git a/core/object/object.h b/core/object/object.h index 17ad4e1f9829..9550b6243bfc 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -552,16 +552,17 @@ protected: _FORCE_INLINE_ void (Object::*_get_notification() const)(int) { \ return (void(Object::*)(int)) & m_class::_notification; \ } \ - virtual void _notificationv(int p_notification, bool p_reversed) override { \ - if (!p_reversed) { \ - m_inherits::_notificationv(p_notification, p_reversed); \ - } \ + virtual void _notification_forwardv(int p_notification) override { \ + m_inherits::_notification_forwardv(p_notification); \ if (m_class::_get_notification() != m_inherits::_get_notification()) { \ _notification(p_notification); \ } \ - if (p_reversed) { \ - m_inherits::_notificationv(p_notification, p_reversed); \ + } \ + virtual void _notification_backwardv(int p_notification) override { \ + if (m_class::_get_notification() != m_inherits::_get_notification()) { \ + _notification(p_notification); \ } \ + m_inherits::_notification_backwardv(p_notification); \ } \ \ private: @@ -705,7 +706,11 @@ class Object { virtual void _validate_propertyv(PropertyInfo &p_property) const {} virtual bool _property_can_revertv(const StringName &p_name) const { return false; } virtual bool _property_get_revertv(const StringName &p_name, Variant &r_property) const { return false; } - virtual void _notificationv(int p_notification, bool p_reversed) {} + + void _notification_forward(int p_notification); + void _notification_backward(int p_notification); + virtual void _notification_forwardv(int p_notification) {} + virtual void _notification_backwardv(int p_notification) {} static void _bind_methods(); static void _bind_compatibility_methods() {} @@ -889,7 +894,17 @@ class Object { return (cerr.error == Callable::CallError::CALL_OK) ? ret : Variant(); } - void notification(int p_notification, bool p_reversed = false); + // Depending on the boolean, we call either the virtual function _notification_backward or _notification_forward. + // - Forward calls subclasses in descending order (e.g. Object -> Node -> Node3D -> extension -> script). + // Backward calls subclasses in descending order (e.g. script -> extension -> Node3D -> Node -> Object). + _FORCE_INLINE_ void notification(int p_notification, bool p_reversed = false) { + if (p_reversed) { + _notification_backward(p_notification); + } else { + _notification_forward(p_notification); + } + } + virtual String to_string(); // Used mainly by script, get and set all INCLUDING string. diff --git a/tests/core/object/test_object.h b/tests/core/object/test_object.h index 46060c70392f..03119efcc288 100644 --- a/tests/core/object/test_object.h +++ b/tests/core/object/test_object.h @@ -464,72 +464,75 @@ TEST_CASE("[Object] Signals") { } } -class NotificationObject1 : public Object { - GDCLASS(NotificationObject1, Object); +class NotificationObjectSuperclass : public Object { + GDCLASS(NotificationObjectSuperclass, Object); protected: void _notification(int p_what) { - switch (p_what) { - case 12345: { - order_internal1 = order_global++; - } break; - } + order_superclass = ++order_global; } public: - static int order_global; - int order_internal1 = -1; - - void reset_order() { - order_internal1 = -1; - order_global = 1; - } + static inline int order_global = 0; + int order_superclass = -1; }; -int NotificationObject1::order_global = 1; - -class NotificationObject2 : public NotificationObject1 { - GDCLASS(NotificationObject2, NotificationObject1); +class NotificationObjectSubclass : public NotificationObjectSuperclass { + GDCLASS(NotificationObjectSubclass, NotificationObjectSuperclass); protected: void _notification(int p_what) { - switch (p_what) { - case 12345: { - order_internal2 = order_global++; - } break; - } + order_subclass = ++order_global; } public: - int order_internal2 = -1; - void reset_order() { - NotificationObject1::reset_order(); - order_internal2 = -1; + int order_subclass = -1; +}; + +class NotificationScriptInstance : public _MockScriptInstance { + void notification(int p_notification, bool p_reversed) override { + order_script = ++NotificationObjectSuperclass::order_global; } + +public: + int order_script = -1; }; TEST_CASE("[Object] Notification order") { // GH-52325 - NotificationObject2 *test_notification_object = memnew(NotificationObject2); + NotificationObjectSubclass *object = memnew(NotificationObjectSubclass); - SUBCASE("regular order") { - test_notification_object->notification(12345, false); + NotificationScriptInstance *script = memnew(NotificationScriptInstance); + object->set_script_instance(script); - CHECK_EQ(test_notification_object->order_internal1, 1); - CHECK_EQ(test_notification_object->order_internal2, 2); + SUBCASE("regular order") { + NotificationObjectSubclass::order_global = 0; + object->order_superclass = -1; + object->order_subclass = -1; + script->order_script = -1; + object->notification(12345, false); - test_notification_object->reset_order(); + CHECK_EQ(object->order_superclass, 1); + CHECK_EQ(object->order_subclass, 2); + // TODO If an extension is attached, it should come here. + CHECK_EQ(script->order_script, 3); + CHECK_EQ(NotificationObjectSubclass::order_global, 3); } SUBCASE("reverse order") { - test_notification_object->notification(12345, true); - - CHECK_EQ(test_notification_object->order_internal1, 2); - CHECK_EQ(test_notification_object->order_internal2, 1); + NotificationObjectSubclass::order_global = 0; + object->order_superclass = -1; + object->order_subclass = -1; + script->order_script = -1; + object->notification(12345, true); - test_notification_object->reset_order(); + CHECK_EQ(script->order_script, 1); + // TODO If an extension is attached, it should come here. + CHECK_EQ(object->order_subclass, 2); + CHECK_EQ(object->order_superclass, 3); + CHECK_EQ(NotificationObjectSubclass::order_global, 3); } - memdelete(test_notification_object); + memdelete(object); } TEST_CASE("[Object] Destruction at the end of the call chain is safe") { From 6a1e07890b438d8acd7c5431e8a0eccebf43e937 Mon Sep 17 00:00:00 2001 From: sora Date: Tue, 1 Apr 2025 21:12:55 +0200 Subject: [PATCH 022/111] fix: use productCategory instead of vendorName for joy name on macos --- drivers/apple/joypad_apple.mm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/apple/joypad_apple.mm b/drivers/apple/joypad_apple.mm index e7d08d7cf95a..fced2f31dcb4 100644 --- a/drivers/apple/joypad_apple.mm +++ b/drivers/apple/joypad_apple.mm @@ -503,7 +503,13 @@ int rightmost_one(int n) { } // Tell Godot about our new controller. - Input::get_singleton()->joy_connection_changed(joy_id, true, String::utf8(p_controller.vendorName.UTF8String)); + char const *device_name; + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + device_name = p_controller.productCategory.UTF8String; + } else { + device_name = p_controller.vendorName.UTF8String; + } + Input::get_singleton()->joy_connection_changed(joy_id, true, String::utf8(device_name)); // Assign our player index. joypads.insert(joy_id, memnew(GameController(joy_id, p_controller))); From 6f76a3522ee9012a7d9c2e51283a9ee7d487e8cb Mon Sep 17 00:00:00 2001 From: LuoZhihao Date: Wed, 2 Apr 2025 13:43:58 +0800 Subject: [PATCH 023/111] Navigation: Replace the deprecated `Geometry2D::get_closest_point_to_segment` --- modules/navigation_2d/2d/nav_mesh_queries_2d.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/modules/navigation_2d/2d/nav_mesh_queries_2d.cpp b/modules/navigation_2d/2d/nav_mesh_queries_2d.cpp index 0487d77648fe..4978cfa8a409 100644 --- a/modules/navigation_2d/2d/nav_mesh_queries_2d.cpp +++ b/modules/navigation_2d/2d/nav_mesh_queries_2d.cpp @@ -329,8 +329,7 @@ void NavMeshQueries2D::_query_task_build_path_corridor(NavMeshPathQueryTask2D &p continue; } - Vector2 pathway[2] = { connection.pathway_start, connection.pathway_end }; - const Vector2 new_entry = Geometry2D::get_closest_point_to_segment(least_cost_poly.entry, pathway); + const Vector2 new_entry = Geometry2D::get_closest_point_to_segment(least_cost_poly.entry, connection.pathway_start, connection.pathway_end); const real_t new_traveled_distance = least_cost_poly.entry.distance_to(new_entry) * poly_travel_cost + poly_enter_cost + least_cost_poly.traveled_distance; // Check if the neighbor polygon has already been processed. @@ -585,8 +584,7 @@ void NavMeshQueries2D::_query_task_post_process_corridorfunnel(NavMeshPathQueryT // Set the apex poly/point to the end point. NavigationPoly *apex_poly = &navigation_polys[least_cost_id]; - Vector2 back_pathway[2] = { apex_poly->back_navigation_edge_pathway_start, apex_poly->back_navigation_edge_pathway_end }; - const Vector2 back_edge_closest_point = Geometry2D::get_closest_point_to_segment(end_point, back_pathway); + const Vector2 back_edge_closest_point = Geometry2D::get_closest_point_to_segment(end_point, apex_poly->back_navigation_edge_pathway_start, apex_poly->back_navigation_edge_pathway_end); if (end_point.is_equal_approx(back_edge_closest_point)) { // The end point is basically on top of the last crossed edge, funneling around the corners would at best do nothing. // At worst it would add an unwanted path point before the last point due to precision issues so skip to the next polygon. @@ -1037,15 +1035,13 @@ LocalVector NavMeshQueries2D::get_simplified_path_indices(const LocalV } void NavMeshQueries2D::simplify_path_segment(int p_start_inx, int p_end_inx, const LocalVector &p_points, real_t p_epsilon, LocalVector &r_simplified_path_indices) { - Vector2 path_segment[2] = { p_points[p_start_inx], p_points[p_end_inx] }; - real_t point_max_distance = 0.0; int point_max_index = 0; for (int i = p_start_inx; i < p_end_inx; i++) { const Vector2 &checked_point = p_points[i]; - const Vector2 closest_point = Geometry2D::get_closest_point_to_segment(checked_point, path_segment); + const Vector2 closest_point = Geometry2D::get_closest_point_to_segment(checked_point, p_points[p_start_inx], p_points[p_end_inx]); real_t distance_squared = closest_point.distance_squared_to(checked_point); if (distance_squared > point_max_distance) { From 09f89f3d1293ca0e0d769621ed9358d373a9efb3 Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Tue, 25 Mar 2025 19:43:15 +0100 Subject: [PATCH 024/111] Expose TriangleMesh api functions wrapped for scripting Adds script wrapped TriangleMesh api functions to create and query the triangle BVH tree. --- core/math/triangle_mesh.cpp | 101 ++++++++++++++++++++++++++- core/math/triangle_mesh.h | 27 ++++--- doc/classes/TriangleMesh.xml | 51 +++++++++++++- tests/core/math/test_triangle_mesh.h | 82 ++++++++++++++++++++++ tests/test_main.cpp | 1 + 5 files changed, 250 insertions(+), 12 deletions(-) create mode 100644 tests/core/math/test_triangle_mesh.h diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 01b733183dc9..3b24b351eaa6 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -182,7 +182,11 @@ void TriangleMesh::create(const Vector &p_faces, const Vector valid = true; } -bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index) const { +bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index, int32_t *r_face_index) const { + if (!valid) { + return false; + } + uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); enum { @@ -234,6 +238,9 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en if (r_surf_index) { *r_surf_index = s.surface_index; } + if (r_face_index) { + *r_face_index = b.face_index; + } inters = true; } } @@ -283,7 +290,11 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en return inters; } -bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index) const { +bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index, int32_t *r_face_index) const { + if (!valid) { + return false; + } + uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); enum { @@ -335,6 +346,9 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V if (r_surf_index) { *r_surf_index = s.surface_index; } + if (r_face_index) { + *r_face_index = b.face_index; + } inters = true; } } @@ -385,6 +399,10 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V } bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, Vector3 p_scale) const { + if (!valid) { + return false; + } + uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); enum { @@ -503,6 +521,85 @@ Vector TriangleMesh::get_faces() const { return faces; } +bool TriangleMesh::create_from_faces(const Vector &p_faces) { + create(p_faces); + return is_valid(); +} + +Dictionary TriangleMesh::intersect_segment_scriptwrap(const Vector3 &p_begin, const Vector3 &p_end) const { + if (!valid) { + return Dictionary(); + } + + Vector3 r_point; + Vector3 r_normal; + int32_t r_face_index = -1; + + bool intersected = intersect_segment(p_begin, p_end, r_point, r_normal, nullptr, &r_face_index); + if (!intersected) { + return Dictionary(); + } + + Dictionary result; + result["position"] = r_point; + result["normal"] = r_normal; + result["face_index"] = r_face_index; + + return result; +} + +Dictionary TriangleMesh::intersect_ray_scriptwrap(const Vector3 &p_begin, const Vector3 &p_dir) const { + if (!valid) { + return Dictionary(); + } + + Vector3 r_point; + Vector3 r_normal; + int32_t r_face_index = -1; + + bool intersected = intersect_ray(p_begin, p_dir, r_point, r_normal, nullptr, &r_face_index); + if (!intersected) { + return Dictionary(); + } + + Dictionary result; + result["position"] = r_point; + result["normal"] = r_normal; + result["face_index"] = r_face_index; + + return result; +} + +Vector TriangleMesh::get_faces_scriptwrap() const { + if (!valid) { + return Vector(); + } + + Vector faces; + int ts = triangles.size(); + faces.resize(triangles.size() * 3); + + Vector3 *w = faces.ptrw(); + const Triangle *r = triangles.ptr(); + const Vector3 *rv = vertices.ptr(); + + for (int i = 0; i < ts; i++) { + for (int j = 0; j < 3; j++) { + w[i * 3 + j] = rv[r[i].indices[j]]; + } + } + + return faces; +} + +void TriangleMesh::_bind_methods() { + ClassDB::bind_method(D_METHOD("create_from_faces", "faces"), &TriangleMesh::create_from_faces); + ClassDB::bind_method(D_METHOD("get_faces"), &TriangleMesh::get_faces_scriptwrap); + + ClassDB::bind_method(D_METHOD("intersect_segment", "begin", "end"), &TriangleMesh::intersect_segment_scriptwrap); + ClassDB::bind_method(D_METHOD("intersect_ray", "begin", "dir"), &TriangleMesh::intersect_ray_scriptwrap); +} + TriangleMesh::TriangleMesh() { valid = false; max_depth = 0; diff --git a/core/math/triangle_mesh.h b/core/math/triangle_mesh.h index 28f792b4dd4e..65fd0ff9b7b9 100644 --- a/core/math/triangle_mesh.h +++ b/core/math/triangle_mesh.h @@ -40,9 +40,12 @@ class TriangleMesh : public RefCounted { struct Triangle { Vector3 normal; int indices[3]; - int32_t surface_index; + int32_t surface_index = 0; }; +protected: + static void _bind_methods(); + private: Vector triangles; Vector vertices; @@ -50,10 +53,10 @@ class TriangleMesh : public RefCounted { struct BVH { AABB aabb; Vector3 center; //used for sorting - int left; - int right; + int left = -1; + int right = -1; - int face_index; + int32_t face_index = -1; }; struct BVHCmpX { @@ -76,13 +79,13 @@ class TriangleMesh : public RefCounted { int _create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc); Vector bvh; - int max_depth; - bool valid; + int max_depth = 0; + bool valid = false; public: bool is_valid() const; - bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr) const; - bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr) const; + bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr, int32_t *r_face_index = nullptr) const; + bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr, int32_t *r_face_index = nullptr) const; bool inside_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, Vector3 p_scale = Vector3(1, 1, 1)) const; Vector get_faces() const; @@ -91,5 +94,13 @@ class TriangleMesh : public RefCounted { void get_indices(Vector *r_triangles_indices) const; void create(const Vector &p_faces, const Vector &p_surface_indices = Vector()); + + // Wrapped functions for compatibility with method bindings + // and user exposed script api that can't use more native types. + bool create_from_faces(const Vector &p_faces); + Dictionary intersect_segment_scriptwrap(const Vector3 &p_begin, const Vector3 &p_end) const; + Dictionary intersect_ray_scriptwrap(const Vector3 &p_begin, const Vector3 &p_dir) const; + Vector get_faces_scriptwrap() const; + TriangleMesh(); }; diff --git a/doc/classes/TriangleMesh.xml b/doc/classes/TriangleMesh.xml index 79bab0ece645..dc4e688b4922 100644 --- a/doc/classes/TriangleMesh.xml +++ b/doc/classes/TriangleMesh.xml @@ -1,11 +1,58 @@ - Internal mesh type. + Triangle geometry for efficient, physicsless intersection queries. - Mesh type used internally for collision calculations. + Creates a bounding volume hierarchy (BVH) tree structure around triangle geometry. + The triangle BVH tree can be used for efficient intersection queries without involving a physics engine. + For example, this can be used in editor tools to select objects with complex shapes based on the mouse cursor position. + [b]Performance:[/b] Creating the BVH tree for complex geometry is a slow process and best done in a background thread. + + + + + + Creates the BVH tree from an array of faces. Each 3 vertices of the input [param faces] array represent one triangle (face). + Returns [code]true[/code] if the tree is successfully built, [code]false[/code] otherwise. + + + + + + Returns a copy of the geometry faces. Each 3 vertices of the array represent one triangle (face). + + + + + + + + Tests for intersection with a ray starting at [param begin] and facing [param dir] and extending toward infinity. + If an intersection with a triangle happens, returns a [Dictionary] with the following fields: + [code]position[/code]: The position on the intersected triangle. + [code]normal[/code]: The normal of the intersected triangle. + [code]face_index[/code]: The index of the intersected triangle. + Returns an empty [Dictionary] if no intersection happens. + See also [method intersect_segment], which is similar but uses a finite-length segment. + + + + + + + + Tests for intersection with a segment going from [param begin] to [param end]. + If an intersection with a triangle happens returns a [Dictionary] with the following fields: + [code]position[/code]: The position on the intersected triangle. + [code]normal[/code]: The normal of the intersected triangle. + [code]face_index[/code]: The index of the intersected triangle. + Returns an empty [Dictionary] if no intersection happens. + See also [method intersect_ray], which is similar but uses an infinite-length ray. + + + diff --git a/tests/core/math/test_triangle_mesh.h b/tests/core/math/test_triangle_mesh.h new file mode 100644 index 000000000000..f138b554c372 --- /dev/null +++ b/tests/core/math/test_triangle_mesh.h @@ -0,0 +1,82 @@ +/**************************************************************************/ +/* test_triangle_mesh.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. */ +/**************************************************************************/ + +#pragma once + +#include "core/math/triangle_mesh.h" +#include "scene/resources/3d/primitive_meshes.h" + +#include "tests/test_macros.h" + +namespace TestTriangleMesh { + +TEST_CASE("[SceneTree][TriangleMesh] BVH creation and intersection") { + Ref box_mesh; + box_mesh.instantiate(); + + const Vector faces = box_mesh->get_faces(); + + Ref triangle_mesh; + triangle_mesh.instantiate(); + CHECK(triangle_mesh->create_from_faces(Variant(faces))); + + const Vector3 begin = Vector3(0.0, 2.0, 0.0); + const Vector3 end = Vector3(0.0, -2.0, 0.0); + + { + Vector3 point; + Vector3 normal; + int32_t *surf_index = nullptr; + int32_t face_index = -1; + const bool has_result = triangle_mesh->intersect_segment(begin, end, point, normal, surf_index, &face_index); + CHECK(has_result); + CHECK(point.is_equal_approx(Vector3(0.0, 0.5, 0.0))); + CHECK(normal.is_equal_approx(Vector3(0.0, 1.0, 0.0))); + CHECK(surf_index == nullptr); + REQUIRE(face_index != -1); + CHECK(face_index == 8); + } + + { + Vector3 dir = begin.direction_to(end); + Vector3 point; + Vector3 normal; + int32_t *surf_index = nullptr; + int32_t face_index = -1; + const bool has_result = triangle_mesh->intersect_ray(begin, dir, point, normal, surf_index, &face_index); + CHECK(has_result); + CHECK(point.is_equal_approx(Vector3(0.0, 0.5, 0.0))); + CHECK(normal.is_equal_approx(Vector3(0.0, 1.0, 0.0))); + CHECK(surf_index == nullptr); + REQUIRE(face_index != -1); + CHECK(face_index == 8); + } +} +} // namespace TestTriangleMesh diff --git a/tests/test_main.cpp b/tests/test_main.cpp index bf6c9fa4d462..7a3efdb5e318 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -161,6 +161,7 @@ #endif // ADVANCED_GUI_DISABLED #ifndef _3D_DISABLED +#include "tests/core/math/test_triangle_mesh.h" #include "tests/scene/test_arraymesh.h" #include "tests/scene/test_camera_3d.h" #include "tests/scene/test_gltf_document.h" From d0b6ba713dae5ad0b6571ca3650db24f6504c4c1 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Tue, 1 Apr 2025 15:45:24 +0200 Subject: [PATCH 025/111] Allow higher freelook base speed values in the 3D editor settings This is useful when working on large-scale games. --- editor/editor_settings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 0156088e6aaf..5985ff342e32 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -878,7 +878,7 @@ void EditorSettings::_load_defaults(Ref p_extra_config) { EDITOR_SETTING_BASIC(Variant::INT, PROPERTY_HINT_ENUM, "editors/3d/freelook/freelook_navigation_scheme", 0, "Default,Partially Axis-Locked (id Tech),Fully Axis-Locked (Minecraft)") EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/freelook/freelook_sensitivity", 0.25, "0.01,2,0.001") EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/freelook/freelook_inertia", 0.0, "0,1,0.001") - EDITOR_SETTING_BASIC(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/freelook/freelook_base_speed", 5.0, "0,10,0.01") + EDITOR_SETTING_BASIC(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/freelook/freelook_base_speed", 5.0, "0,10,0.01,or_greater") EDITOR_SETTING_BASIC(Variant::INT, PROPERTY_HINT_ENUM, "editors/3d/freelook/freelook_activation_modifier", 0, "None,Shift,Alt,Meta,Ctrl") _initial_set("editors/3d/freelook/freelook_speed_zoom_link", false); From d2257c88a77da33d428f2989def681b4379dccf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Wed, 2 Apr 2025 13:55:06 +0300 Subject: [PATCH 026/111] [Docs] Add note about console wrapper to `get_stdin_type`. --- doc/classes/OS.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index 9e9ba92d0f16..28d7f3da8d87 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -472,18 +472,22 @@ Returns type of the standard error device. + [b]Note:[/b] This method is implemented on Linux, macOS, and Windows. Returns type of the standard input device. + [b]Note:[/b] This method is implemented on Linux, macOS, and Windows. + [b]Note:[/b] On exported Windows builds, run the console wrapper executable to access the standard input. If you need a single executable with full console support, use a custom build compiled with the [code]windows_subsystem=console[/code] flag. Returns type of the standard output device. + [b]Note:[/b] This method is implemented on Linux, macOS, and Windows. From 2a487c35048901851debff9735dd00b798e1bc75 Mon Sep 17 00:00:00 2001 From: Yufeng Ying Date: Thu, 20 Mar 2025 00:07:31 +0800 Subject: [PATCH 027/111] Replace size() == 0 with is_empty(). --- core/debugger/local_debugger.cpp | 2 +- core/debugger/remote_debugger_peer.cpp | 2 +- core/debugger/script_debugger.cpp | 2 +- core/doc_data.h | 4 +- core/io/image.cpp | 18 ++++---- core/math/bvh.h | 2 +- core/math/convex_hull.cpp | 2 +- core/math/geometry_3d.h | 2 +- core/math/quick_hull.cpp | 2 +- core/object/message_queue.cpp | 4 +- core/object/object.cpp | 2 +- core/object/script_language_extension.h | 6 +-- core/object/worker_thread_pool.cpp | 6 +-- core/string/node_path.cpp | 6 +-- core/string/optimized_translation.cpp | 4 +- core/string/ustring.cpp | 2 +- core/variant/array.cpp | 8 ++-- core/variant/variant.cpp | 20 ++++----- drivers/gles3/rasterizer_canvas_gles3.cpp | 2 +- drivers/gles3/rasterizer_scene_gles3.cpp | 6 +-- drivers/gles3/shader_gles3.cpp | 2 +- drivers/gles3/shader_gles3.h | 2 +- editor/animation_bezier_editor.cpp | 2 +- editor/animation_track_editor.cpp | 2 +- editor/debugger/script_editor_debugger.cpp | 4 +- editor/dependency_editor.cpp | 2 +- editor/doc_tools.cpp | 2 +- editor/editor_autoload_settings.cpp | 2 +- editor/editor_file_system.cpp | 8 ++-- editor/editor_node.cpp | 4 +- editor/editor_properties.cpp | 4 +- editor/editor_resource_preview.cpp | 2 +- editor/export/editor_export_platform.cpp | 2 +- editor/filesystem_dock.cpp | 2 +- editor/find_in_files.cpp | 4 +- editor/gui/editor_file_dialog.cpp | 4 +- editor/gui/scene_tree_editor.cpp | 4 +- editor/import/3d/editor_import_collada.cpp | 4 +- editor/import/3d/resource_importer_obj.cpp | 2 +- editor/plugins/bone_map_editor_plugin.cpp | 4 +- editor/plugins/canvas_item_editor_plugin.cpp | 2 +- editor/plugins/control_editor_plugin.cpp | 2 +- .../gizmos/lightmap_gi_gizmo_plugin.cpp | 2 +- .../mesh_instance_3d_editor_plugin.cpp | 4 +- editor/plugins/multimesh_editor_plugin.cpp | 2 +- editor/plugins/particles_editor_plugin.cpp | 2 +- editor/plugins/polygon_2d_editor_plugin.cpp | 8 ++-- editor/plugins/polygon_3d_editor_plugin.cpp | 2 +- editor/plugins/script_editor_plugin.cpp | 6 +-- editor/plugins/script_text_editor.cpp | 4 +- editor/plugins/shader_editor_plugin.cpp | 2 +- editor/plugins/shader_file_editor_plugin.cpp | 2 +- .../plugins/sprite_frames_editor_plugin.cpp | 4 +- editor/plugins/text_editor.cpp | 2 +- editor/plugins/text_shader_editor.cpp | 2 +- editor/plugins/theme_editor_plugin.cpp | 4 +- editor/plugins/tiles/tile_data_editors.cpp | 2 +- editor/plugins/tiles/tile_set_editor.cpp | 2 +- ...le_set_scenes_collection_source_editor.cpp | 2 +- editor/plugins/tiles/tiles_editor_plugin.cpp | 2 +- .../plugins/visual_shader_editor_plugin.cpp | 4 +- editor/project_converter_3_to_4.cpp | 2 +- editor/project_manager.cpp | 4 +- editor/project_manager/project_list.cpp | 6 +-- editor/scene_tree_dock.cpp | 8 ++-- main/main.cpp | 2 +- modules/csg/csg_shape.cpp | 6 +-- modules/csg/editor/csg_gizmos.cpp | 2 +- modules/fbx/fbx_document.cpp | 2 +- modules/gdscript/gdscript.cpp | 2 +- modules/gltf/gltf_document.cpp | 44 +++++++++---------- modules/gltf/skin_tool.cpp | 2 +- modules/godot_physics_2d/godot_body_2d.cpp | 2 +- modules/godot_physics_2d/godot_shape_2d.cpp | 4 +- modules/godot_physics_3d/godot_body_3d.cpp | 2 +- modules/godot_physics_3d/godot_shape_3d.cpp | 6 +-- modules/gridmap/grid_map.cpp | 8 ++-- ...audio_stream_interactive_editor_plugin.cpp | 2 +- modules/lightmapper_rd/lightmapper_rd.cpp | 6 +-- modules/mono/csharp_script.cpp | 2 +- modules/mono/editor/bindings_generator.cpp | 2 +- .../multiplayer/multiplayer_synchronizer.cpp | 2 +- .../2d/nav_mesh_generator_2d.cpp | 2 +- .../3d/nav_mesh_generator_3d.cpp | 2 +- modules/noise/noise.cpp | 2 +- .../openxr/action_map/openxr_action_set.cpp | 2 +- modules/regex/regex.cpp | 2 +- modules/tinyexr/image_saver_tinyexr.cpp | 2 +- modules/webrtc/webrtc_multiplayer_peer.cpp | 2 +- modules/websocket/wsl_peer.cpp | 2 +- modules/webxr/webxr_interface_js.cpp | 2 +- platform/linuxbsd/x11/display_server_x11.cpp | 2 +- platform/web/audio_driver_web.cpp | 2 +- platform/windows/display_server_windows.cpp | 2 +- scene/2d/animated_sprite_2d.cpp | 2 +- scene/2d/cpu_particles_2d.cpp | 2 +- scene/2d/light_occluder_2d.cpp | 4 +- scene/2d/line_2d.cpp | 2 +- scene/2d/navigation/navigation_agent_2d.cpp | 8 ++-- scene/2d/physics/character_body_2d.cpp | 2 +- scene/2d/physics/collision_object_2d.cpp | 2 +- scene/2d/polygon_2d.cpp | 4 +- scene/3d/cpu_particles_3d.cpp | 2 +- scene/3d/lightmap_gi.cpp | 10 ++--- scene/3d/mesh_instance_3d.cpp | 4 +- scene/3d/navigation/navigation_agent_3d.cpp | 8 ++-- scene/3d/navigation/navigation_region_3d.cpp | 4 +- scene/3d/occluder_instance_3d.cpp | 2 +- scene/3d/physics/character_body_3d.cpp | 2 +- scene/3d/physics/collision_object_3d.cpp | 2 +- scene/3d/physics/collision_polygon_3d.cpp | 4 +- scene/3d/sprite_3d.cpp | 2 +- scene/animation/animation_blend_space_2d.cpp | 2 +- scene/animation/animation_mixer.cpp | 2 +- .../animation_node_state_machine.cpp | 2 +- scene/debugger/scene_debugger.cpp | 4 +- scene/gui/code_edit.cpp | 20 ++++----- scene/gui/file_dialog.cpp | 2 +- scene/gui/range.cpp | 2 +- scene/gui/rich_text_label.cpp | 2 +- scene/gui/text_edit.cpp | 2 +- scene/main/multiplayer_peer.cpp | 2 +- scene/main/shader_globals_override.cpp | 2 +- scene/main/viewport.cpp | 4 +- scene/resources/2d/polygon_path_finder.cpp | 2 +- scene/resources/3d/importer_mesh.cpp | 4 +- scene/resources/3d/primitive_meshes.cpp | 2 +- scene/resources/animation.cpp | 10 ++--- scene/resources/curve.cpp | 22 +++++----- scene/resources/mesh.cpp | 14 +++--- scene/resources/navigation_mesh.cpp | 4 +- .../resources/portable_compressed_texture.cpp | 2 +- scene/resources/surface_tool.cpp | 4 +- .../visual_shader_particle_nodes.cpp | 12 ++--- scene/theme/theme_db.cpp | 2 +- .../rendering/renderer_rd/environment/gi.cpp | 8 ++-- .../renderer_rd/framebuffer_cache_rd.h | 4 +- .../renderer_rd/renderer_canvas_render_rd.cpp | 6 +-- servers/rendering/renderer_rd/shader_rd.cpp | 6 +-- .../storage_rd/material_storage.cpp | 2 +- .../storage_rd/texture_storage.cpp | 2 +- servers/rendering/renderer_scene_cull.cpp | 2 +- servers/rendering/rendering_device.cpp | 2 +- servers/rendering/shader_preprocessor.cpp | 2 +- servers/rendering_server.cpp | 2 +- servers/text_server.cpp | 4 +- servers/xr_server.cpp | 4 +- 147 files changed, 300 insertions(+), 300 deletions(-) diff --git a/core/debugger/local_debugger.cpp b/core/debugger/local_debugger.cpp index a5d807f66bec..47a6d15df41d 100644 --- a/core/debugger/local_debugger.cpp +++ b/core/debugger/local_debugger.cpp @@ -242,7 +242,7 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { } else if (line.begins_with("br") || line.begins_with("break")) { if (line.get_slice_count(" ") <= 1) { const HashMap> &breakpoints = script_debugger->get_breakpoints(); - if (breakpoints.size() == 0) { + if (breakpoints.is_empty()) { print_line("No Breakpoints."); continue; } diff --git a/core/debugger/remote_debugger_peer.cpp b/core/debugger/remote_debugger_peer.cpp index 1afb7fe09b4e..011e6722facd 100644 --- a/core/debugger/remote_debugger_peer.cpp +++ b/core/debugger/remote_debugger_peer.cpp @@ -96,7 +96,7 @@ void RemoteDebuggerPeerTCP::_write_out() { while (tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTED && tcp_client->wait(NetSocket::POLL_TYPE_OUT) == OK) { uint8_t *buf = out_buf.ptrw(); if (out_left <= 0) { - if (out_queue.size() == 0) { + if (out_queue.is_empty()) { break; // Nothing left to send } mutex.lock(); diff --git a/core/debugger/script_debugger.cpp b/core/debugger/script_debugger.cpp index 1533a85b32a1..e522d9bacb15 100644 --- a/core/debugger/script_debugger.cpp +++ b/core/debugger/script_debugger.cpp @@ -58,7 +58,7 @@ void ScriptDebugger::remove_breakpoint(int p_line, const StringName &p_source) { } breakpoints[p_line].erase(p_source); - if (breakpoints[p_line].size() == 0) { + if (breakpoints[p_line].is_empty()) { breakpoints.erase(p_line); } } diff --git a/core/doc_data.h b/core/doc_data.h index 5611911a0fe1..a6124b22fc22 100644 --- a/core/doc_data.h +++ b/core/doc_data.h @@ -114,7 +114,7 @@ class DocData { // Must be an operator or a constructor since there is no other overloading if (name.left(8) == "operator") { if (arguments.size() == p_method.arguments.size()) { - if (arguments.size() == 0) { + if (arguments.is_empty()) { return false; } return arguments[0].type < p_method.arguments[0].type; @@ -126,7 +126,7 @@ class DocData { // - 1. Default constructor: Foo() // - 2. Copy constructor: Foo(Foo) // - 3+. Other constructors Foo(Bar, ...) based on first argument's name - if (arguments.size() == 0 || p_method.arguments.size() == 0) { // 1. + if (arguments.is_empty() || p_method.arguments.is_empty()) { // 1. return arguments.size() < p_method.arguments.size(); } if (arguments[0].type == return_type || p_method.arguments[0].type == p_method.return_type) { // 2. diff --git a/core/io/image.cpp b/core/io/image.cpp index d20648686b15..d11b13bf3d2b 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -573,7 +573,7 @@ static bool _are_formats_compatible(Image::Format p_format0, Image::Format p_for void Image::convert(Format p_new_format) { ERR_FAIL_INDEX_MSG(p_new_format, FORMAT_MAX, vformat("The Image format specified (%d) is out of range. See Image's Format enum.", p_new_format)); - if (data.size() == 0 || p_new_format == format) { + if (data.is_empty() || p_new_format == format) { return; } @@ -2177,7 +2177,7 @@ void Image::clear_mipmaps() { } bool Image::is_empty() const { - return (data.size() == 0); + return (data.is_empty()); } Vector Image::get_data() const { @@ -3096,7 +3096,7 @@ void Image::_repeat_pixel_over_subsequent_memory(uint8_t *p_pixel, int p_pixel_s } void Image::fill(const Color &p_color) { - if (data.size() == 0) { + if (data.is_empty()) { return; } ERR_FAIL_COND_MSG(is_compressed(), "Cannot fill in compressed image formats."); @@ -3112,7 +3112,7 @@ void Image::fill(const Color &p_color) { } void Image::fill_rect(const Rect2i &p_rect, const Color &p_color) { - if (data.size() == 0) { + if (data.is_empty()) { return; } ERR_FAIL_COND_MSG(is_compressed(), "Cannot fill rect in compressed image formats."); @@ -3734,7 +3734,7 @@ void Image::normal_map_to_xy() { } Ref Image::rgbe_to_srgb() { - if (data.size() == 0) { + if (data.is_empty()) { return Ref(); } @@ -3856,7 +3856,7 @@ bool Image::detect_signed(bool p_include_mips) const { } void Image::srgb_to_linear() { - if (data.size() == 0) { + if (data.is_empty()) { return; } @@ -3887,7 +3887,7 @@ void Image::srgb_to_linear() { } void Image::linear_to_srgb() { - if (data.size() == 0) { + if (data.is_empty()) { return; } @@ -3918,7 +3918,7 @@ void Image::linear_to_srgb() { } void Image::premultiply_alpha() { - if (data.size() == 0) { + if (data.is_empty()) { return; } @@ -3940,7 +3940,7 @@ void Image::premultiply_alpha() { } void Image::fix_alpha_edges() { - if (data.size() == 0) { + if (data.is_empty()) { return; } diff --git a/core/math/bvh.h b/core/math/bvh.h index 88cae1dbc775..9a9dde176050 100644 --- a/core/math/bvh.h +++ b/core/math/bvh.h @@ -406,7 +406,7 @@ class BVH_Manager { } Vector convex_points = Geometry3D::compute_convex_mesh_points(&p_convex[0], p_convex.size()); - if (convex_points.size() == 0) { + if (convex_points.is_empty()) { return 0; } diff --git a/core/math/convex_hull.cpp b/core/math/convex_hull.cpp index 4052234fa31f..fbd367b97dcb 100644 --- a/core/math/convex_hull.cpp +++ b/core/math/convex_hull.cpp @@ -2237,7 +2237,7 @@ real_t ConvexHullComputer::compute(const Vector3 *p_coords, int32_t p_count, rea Error ConvexHullComputer::convex_hull(const Vector &p_points, Geometry3D::MeshData &r_mesh) { r_mesh = Geometry3D::MeshData(); // clear - if (p_points.size() == 0) { + if (p_points.is_empty()) { return FAILED; // matches QuickHull } diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h index 3c3eb6c962ff..bd8dbe439e1e 100644 --- a/core/math/geometry_3d.h +++ b/core/math/geometry_3d.h @@ -484,7 +484,7 @@ class Geometry3D { LOC_OUTSIDE = -1 }; - if (polygon.size() == 0) { + if (polygon.is_empty()) { return polygon; } diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index e6d7ee9d4e02..360b272e5fac 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -323,7 +323,7 @@ Error QuickHull::build(const Vector &p_points, Geometry3D::MeshData &r_ for (List::Element *&E : new_faces) { Face &f2 = E->get(); - if (f2.points_over.size() == 0) { + if (f2.points_over.is_empty()) { faces.move_to_front(E); } } diff --git a/core/object/message_queue.cpp b/core/object/message_queue.cpp index 4b0b1ce63d8b..673e60d68d24 100644 --- a/core/object/message_queue.cpp +++ b/core/object/message_queue.cpp @@ -226,7 +226,7 @@ void CallQueue::_call_function(const Callable &p_callable, const Variant *p_args Error CallQueue::flush() { LOCK_MUTEX; - if (pages.size() == 0) { + if (pages.is_empty()) { // Never allocated UNLOCK_MUTEX; return OK; // Do nothing. @@ -308,7 +308,7 @@ Error CallQueue::flush() { void CallQueue::clear() { LOCK_MUTEX; - if (pages.size() == 0) { + if (pages.is_empty()) { UNLOCK_MUTEX; return; // Nothing to clear. } diff --git a/core/object/object.cpp b/core/object/object.cpp index e801fc58d6ff..7c1840619068 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -1900,7 +1900,7 @@ Variant::Type Object::get_static_property_type(const StringName &p_property, boo } Variant::Type Object::get_static_property_type_indexed(const Vector &p_path, bool *r_valid) const { - if (p_path.size() == 0) { + if (p_path.is_empty()) { if (r_valid) { *r_valid = false; } diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index 40e0b1b42e5a..8a401bb86e98 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -513,7 +513,7 @@ class ScriptLanguageExtension : public ScriptLanguage { virtual void debug_get_stack_level_locals(int p_level, List *p_locals, List *p_values, int p_max_subitems = -1, int p_max_depth = -1) override { Dictionary ret; GDVIRTUAL_CALL(_debug_get_stack_level_locals, p_level, p_max_subitems, p_max_depth, ret); - if (ret.size() == 0) { + if (ret.is_empty()) { return; } if (p_locals != nullptr && ret.has("locals")) { @@ -533,7 +533,7 @@ class ScriptLanguageExtension : public ScriptLanguage { virtual void debug_get_stack_level_members(int p_level, List *p_members, List *p_values, int p_max_subitems = -1, int p_max_depth = -1) override { Dictionary ret; GDVIRTUAL_CALL(_debug_get_stack_level_members, p_level, p_max_subitems, p_max_depth, ret); - if (ret.size() == 0) { + if (ret.is_empty()) { return; } if (p_members != nullptr && ret.has("members")) { @@ -560,7 +560,7 @@ class ScriptLanguageExtension : public ScriptLanguage { virtual void debug_get_globals(List *p_globals, List *p_values, int p_max_subitems = -1, int p_max_depth = -1) override { Dictionary ret; GDVIRTUAL_CALL(_debug_get_globals, p_max_subitems, p_max_depth, ret); - if (ret.size() == 0) { + if (ret.is_empty()) { return; } if (p_globals != nullptr && ret.has("globals")) { diff --git a/core/object/worker_thread_pool.cpp b/core/object/worker_thread_pool.cpp index 14a7a6936a1e..84ef71c815a4 100644 --- a/core/object/worker_thread_pool.cpp +++ b/core/object/worker_thread_pool.cpp @@ -221,7 +221,7 @@ void WorkerThreadPool::_post_tasks(Task **p_tasks, uint32_t p_count, bool p_high // Fall back to processing on the calling thread if there are no worker threads. // Separated into its own variable to make it easier to extend this logic // in custom builds. - bool process_on_calling_thread = threads.size() == 0; + bool process_on_calling_thread = threads.is_empty(); if (process_on_calling_thread) { p_lock.temp_unlock(); for (uint32_t i = 0; i < p_count; i++) { @@ -789,7 +789,7 @@ void WorkerThreadPool::init(int p_thread_count, float p_low_priority_task_ratio) } void WorkerThreadPool::exit_languages_threads() { - if (threads.size() == 0) { + if (threads.is_empty()) { return; } @@ -809,7 +809,7 @@ void WorkerThreadPool::exit_languages_threads() { } void WorkerThreadPool::finish() { - if (threads.size() == 0) { + if (threads.is_empty()) { return; } diff --git a/core/string/node_path.cpp b/core/string/node_path.cpp index 3ab8eb860de1..3ff121036273 100644 --- a/core/string/node_path.cpp +++ b/core/string/node_path.cpp @@ -350,7 +350,7 @@ void NodePath::simplify() { data->path.remove_at(i - 1); data->path.remove_at(i - 1); i -= 2; - if (data->path.size() == 0) { + if (data->path.is_empty()) { data->path.push_back("."); break; } @@ -366,7 +366,7 @@ NodePath NodePath::simplified() const { } NodePath::NodePath(const Vector &p_path, bool p_absolute) { - if (p_path.size() == 0 && !p_absolute) { + if (p_path.is_empty() && !p_absolute) { return; } @@ -378,7 +378,7 @@ NodePath::NodePath(const Vector &p_path, bool p_absolute) { } NodePath::NodePath(const Vector &p_path, const Vector &p_subpath, bool p_absolute) { - if (p_path.size() == 0 && p_subpath.size() == 0 && !p_absolute) { + if (p_path.is_empty() && p_subpath.is_empty() && !p_absolute) { return; } diff --git a/core/string/optimized_translation.cpp b/core/string/optimized_translation.cpp index fb55f58c8b79..7481929e3809 100644 --- a/core/string/optimized_translation.cpp +++ b/core/string/optimized_translation.cpp @@ -110,7 +110,7 @@ void OptimizedTranslation::generate(const Ref &p_from) { const Vector> &b = buckets[i]; HashMap &t = table.write[i]; - if (b.size() == 0) { + if (b.is_empty()) { continue; } @@ -148,7 +148,7 @@ void OptimizedTranslation::generate(const Ref &p_from) { for (int i = 0; i < size; i++) { const HashMap &t = table[i]; - if (t.size() == 0) { + if (t.is_empty()) { htw[i] = 0xFFFFFFFF; //nothing continue; } diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index fd07163d7344..854d32af9676 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -3298,7 +3298,7 @@ int String::findmk(const Vector &p_keys, int p_from, int *r_key) const { if (p_from < 0) { return -1; } - if (p_keys.size() == 0) { + if (p_keys.is_empty()) { return -1; } diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 1f203e94e6c4..8e13c89da6c4 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -345,7 +345,7 @@ Variant Array::pick_random() const { } int Array::find(const Variant &p_value, int p_from) const { - if (_p->array.size() == 0) { + if (_p->array.is_empty()) { return -1; } Variant value = p_value; @@ -396,7 +396,7 @@ int Array::find_custom(const Callable &p_callable, int p_from) const { } int Array::rfind(const Variant &p_value, int p_from) const { - if (_p->array.size() == 0) { + if (_p->array.is_empty()) { return -1; } Variant value = p_value; @@ -421,7 +421,7 @@ int Array::rfind(const Variant &p_value, int p_from) const { } int Array::rfind_custom(const Callable &p_callable, int p_from) const { - if (_p->array.size() == 0) { + if (_p->array.is_empty()) { return -1; } @@ -458,7 +458,7 @@ int Array::rfind_custom(const Callable &p_callable, int p_from) const { int Array::count(const Variant &p_value) const { Variant value = p_value; ERR_FAIL_COND_V(!_p->typed.validate(value, "count"), 0); - if (_p->array.size() == 0) { + if (_p->array.is_empty()) { return 0; } diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 25f35e0c1da4..c6a7b0d45841 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -984,34 +984,34 @@ bool Variant::is_zero() const { // Arrays. case PACKED_BYTE_ARRAY: { - return PackedArrayRef::get_array(_data.packed_array).size() == 0; + return PackedArrayRef::get_array(_data.packed_array).is_empty(); } case PACKED_INT32_ARRAY: { - return PackedArrayRef::get_array(_data.packed_array).size() == 0; + return PackedArrayRef::get_array(_data.packed_array).is_empty(); } case PACKED_INT64_ARRAY: { - return PackedArrayRef::get_array(_data.packed_array).size() == 0; + return PackedArrayRef::get_array(_data.packed_array).is_empty(); } case PACKED_FLOAT32_ARRAY: { - return PackedArrayRef::get_array(_data.packed_array).size() == 0; + return PackedArrayRef::get_array(_data.packed_array).is_empty(); } case PACKED_FLOAT64_ARRAY: { - return PackedArrayRef::get_array(_data.packed_array).size() == 0; + return PackedArrayRef::get_array(_data.packed_array).is_empty(); } case PACKED_STRING_ARRAY: { - return PackedArrayRef::get_array(_data.packed_array).size() == 0; + return PackedArrayRef::get_array(_data.packed_array).is_empty(); } case PACKED_VECTOR2_ARRAY: { - return PackedArrayRef::get_array(_data.packed_array).size() == 0; + return PackedArrayRef::get_array(_data.packed_array).is_empty(); } case PACKED_VECTOR3_ARRAY: { - return PackedArrayRef::get_array(_data.packed_array).size() == 0; + return PackedArrayRef::get_array(_data.packed_array).is_empty(); } case PACKED_COLOR_ARRAY: { - return PackedArrayRef::get_array(_data.packed_array).size() == 0; + return PackedArrayRef::get_array(_data.packed_array).is_empty(); } case PACKED_VECTOR4_ARRAY: { - return PackedArrayRef::get_array(_data.packed_array).size() == 0; + return PackedArrayRef::get_array(_data.packed_array).is_empty(); } default: { } diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index d6c9c26f332e..216a1bdfdf8f 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -1572,7 +1572,7 @@ void RasterizerCanvasGLES3::_add_to_batch(uint32_t &r_index, bool &r_batch_broke } void RasterizerCanvasGLES3::_new_batch(bool &r_batch_broken) { - if (state.canvas_instance_batches.size() == 0) { + if (state.canvas_instance_batches.is_empty()) { Batch new_batch; new_batch.instance_buffer_index = state.current_instance_buffer_index; state.canvas_instance_batches.push_back(new_batch); diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 634007b50a52..9d9a2cfb467d 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -3218,11 +3218,11 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL; spec_constants |= SceneShaderGLES3::DISABLE_LIGHTMAP; } else { - if (inst->omni_light_gl_cache.size() == 0) { + if (inst->omni_light_gl_cache.is_empty()) { spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_OMNI; } - if (inst->spot_light_gl_cache.size() == 0) { + if (inst->spot_light_gl_cache.is_empty()) { spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_SPOT; } @@ -3230,7 +3230,7 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL; } - if (inst->reflection_probe_rid_cache.size() == 0) { + if (inst->reflection_probe_rid_cache.is_empty()) { // We don't have any probes. spec_constants |= SceneShaderGLES3::DISABLE_REFLECTION_PROBE; } else if (inst->reflection_probe_rid_cache.size() > 1) { diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp index 50d89897c9c9..d7070d52f4aa 100644 --- a/drivers/gles3/shader_gles3.cpp +++ b/drivers/gles3/shader_gles3.cpp @@ -690,7 +690,7 @@ void ShaderGLES3::_save_to_cache(Version *p_version) { void ShaderGLES3::_clear_version(Version *p_version) { // Variants not compiled yet, just return - if (p_version->variants.size() == 0) { + if (p_version->variants.is_empty()) { return; } diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h index a6c874ed0220..bfa2ebb45310 100644 --- a/drivers/gles3/shader_gles3.h +++ b/drivers/gles3/shader_gles3.h @@ -188,7 +188,7 @@ class ShaderGLES3 { Version *version = version_owner.get_or_null(p_version); ERR_FAIL_NULL_V(version, false); - if (version->variants.size() == 0) { + if (version->variants.is_empty()) { _initialize_version(version); //may lack initialization } diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index eaf92a34f6a4..240ea7179195 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -2042,7 +2042,7 @@ void AnimationBezierTrackEdit::_menu_selected(int p_index) { } void AnimationBezierTrackEdit::duplicate_selected_keys(real_t p_ofs, bool p_ofs_valid) { - if (selection.size() == 0) { + if (selection.is_empty()) { return; } diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 9573d3c6a985..a2b24ffab34a 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -6623,7 +6623,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { } } break; case EDIT_PASTE_TRACKS: { - if (track_clipboard.size() == 0) { + if (track_clipboard.is_empty()) { EditorNode::get_singleton()->show_warning(TTR("Clipboard is empty!")); break; } diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index 0c60d16a46af..940753b5717f 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -371,7 +371,7 @@ void ScriptEditorDebugger::_msg_debug_exit(uint64_t p_thread_id, const Array &p_ threads_debugged.erase(p_thread_id); if (p_thread_id == debugging_thread_id) { _clear_execution(); - if (threads_debugged.size() == 0) { + if (threads_debugged.is_empty()) { debugging_thread_id = Thread::UNASSIGNED_ID; } else { // Find next thread to debug. @@ -1667,7 +1667,7 @@ void ScriptEditorDebugger::_error_selected() { } Array meta = selected->get_metadata(0); - if (meta.size() == 0) { + if (meta.is_empty()) { return; } diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index ca730a550429..082b61972b26 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -613,7 +613,7 @@ void DependencyRemoveDialog::ok_pressed() { ProjectSettings::get_singleton()->save(); } - if (dirs_to_delete.size() == 0) { + if (dirs_to_delete.is_empty()) { // If we only deleted files we should only need to tell the file system about the files we touched. for (int i = 0; i < files_to_delete.size(); ++i) { EditorFileSystem::get_singleton()->update_file(files_to_delete[i]); diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp index 34387d748970..f466606b0335 100644 --- a/editor/doc_tools.cpp +++ b/editor/doc_tools.cpp @@ -628,7 +628,7 @@ void DocTools::generate(BitField p_flags) { // Don't skip parametric setters and getters, i.e. method which require // one or more parameters to define what property should be set or retrieved. // E.g. CPUParticles3D::set_param(Parameter param, float value). - if (E.arguments.size() == 0 /* getter */ || (E.arguments.size() == 1 && E.return_val.type == Variant::NIL /* setter */)) { + if (E.arguments.is_empty() /* getter */ || (E.arguments.size() == 1 && E.return_val.type == Variant::NIL /* setter */)) { continue; } } diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index 1b0f449c9e82..f1430c54836c 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -621,7 +621,7 @@ Variant EditorAutoloadSettings::get_drag_data_fw(const Point2 &p_point, Control next = tree->get_next_selected(next); } - if (autoloads.size() == 0 || autoloads.size() == autoload_cache.size()) { + if (autoloads.is_empty() || autoloads.size() == autoload_cache.size()) { return Variant(); } diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 0e6303f13f74..be5081db402c 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -802,7 +802,7 @@ Vector EditorFileSystem::_get_import_dest_paths(const String &p_path) { } bool EditorFileSystem::_scan_import_support(const Vector &reimports) { - if (import_support_queries.size() == 0) { + if (import_support_queries.is_empty()) { return false; } HashMap import_support_test; @@ -818,7 +818,7 @@ bool EditorFileSystem::_scan_import_support(const Vector &reimports) { } } - if (import_support_test.size() == 0) { + if (import_support_test.is_empty()) { return false; //well nothing to do } @@ -1858,7 +1858,7 @@ bool EditorFileSystem::_find_file(const String &p_file, EditorFileSystemDirector Vector path = f.split("/"); - if (path.size() == 0) { + if (path.is_empty()) { return false; } String file = path[path.size() - 1]; @@ -1991,7 +1991,7 @@ EditorFileSystemDirectory *EditorFileSystem::get_filesystem_path(const String &p Vector path = f.split("/"); - if (path.size() == 0) { + if (path.is_empty()) { return nullptr; } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 52f3e980220c..05765e98ae7d 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -3816,7 +3816,7 @@ void EditorNode::_update_addon_config() { enabled_addons.push_back(E.key); } - if (enabled_addons.size() == 0) { + if (enabled_addons.is_empty()) { ProjectSettings::get_singleton()->set("editor_plugins/enabled", Variant()); } else { enabled_addons.sort(); @@ -6342,7 +6342,7 @@ void EditorNode::preload_reimporting_with_path_in_edited_scenes(const List filesPaths = drag_data["files"]; - if (filesPaths.size() == 0) { + if (filesPaths.is_empty()) { return; } @@ -589,7 +589,7 @@ bool EditorPropertyPath::_can_drop_data_fw(const Point2 &p_point, const Variant return false; } const Vector filesPaths = drag_data["files"]; - if (filesPaths.size() == 0) { + if (filesPaths.is_empty()) { return false; } diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index b090510bde0c..35a96983a3cd 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -262,7 +262,7 @@ const Dictionary EditorResourcePreview::get_preview_metadata(const String &p_pat void EditorResourcePreview::_iterate() { preview_mutex.lock(); - if (queue.size() == 0) { + if (queue.is_empty()) { preview_mutex.unlock(); return; } diff --git a/editor/export/editor_export_platform.cpp b/editor/export/editor_export_platform.cpp index ffe08e9fb69a..8673a80a2c56 100644 --- a/editor/export/editor_export_platform.cpp +++ b/editor/export/editor_export_platform.cpp @@ -1572,7 +1572,7 @@ Error EditorExportPlatform::export_project_files(const Ref & Vector array; if (GDExtension::get_extension_list_config_file() == forced_export[i]) { array = _filter_extension_list_config_file(forced_export[i], paths); - if (array.size() == 0) { + if (array.is_empty()) { continue; } } else { diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 8a950d5bdc09..c8806fa511df 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -3840,7 +3840,7 @@ void FileSystemDock::_update_import_dock() { imports.push_back(fpath); } - if (imports.size() == 0) { + if (imports.is_empty()) { ImportDock::get_singleton()->clear(); } else if (imports.size() == 1) { ImportDock::get_singleton()->set_edit_path(imports[0]); diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp index cc3f3f2259d7..fb9c16871843 100644 --- a/editor/find_in_files.cpp +++ b/editor/find_in_files.cpp @@ -117,7 +117,7 @@ void FindInFiles::start() { emit_signal(SceneStringName(finished)); return; } - if (_extension_filter.size() == 0) { + if (_extension_filter.is_empty()) { print_verbose("Nothing to search, filter matches no files"); emit_signal(SceneStringName(finished)); return; @@ -183,7 +183,7 @@ void FindInFiles::_iterate() { pop_back(_folders_stack); _current_dir = _current_dir.get_base_dir(); - if (_folders_stack.size() == 0) { + if (_folders_stack.is_empty()) { // All folders scanned. _initial_files_count = _files_to_scan.size(); } diff --git a/editor/gui/editor_file_dialog.cpp b/editor/gui/editor_file_dialog.cpp index e4437334289e..f7db59d50a54 100644 --- a/editor/gui/editor_file_dialog.cpp +++ b/editor/gui/editor_file_dialog.cpp @@ -770,7 +770,7 @@ void EditorFileDialog::_items_clear_selection(const Vector2 &p_pos, MouseButton void EditorFileDialog::_push_history() { local_history.resize(local_history_pos + 1); String new_path = dir_access->get_current_dir(); - if (local_history.size() == 0 || new_path != local_history[local_history_pos]) { + if (local_history.is_empty() || new_path != local_history[local_history_pos]) { local_history.push_back(new_path); local_history_pos++; dir_prev->set_disabled(local_history_pos == 0); @@ -940,7 +940,7 @@ bool EditorFileDialog::_is_open_should_be_disabled() { } Vector items = item_list->get_selected_items(); - if (items.size() == 0) { + if (items.is_empty()) { return mode != FILE_MODE_OPEN_DIR; // In "Open folder" mode, having nothing selected picks the current folder. } diff --git a/editor/gui/scene_tree_editor.cpp b/editor/gui/scene_tree_editor.cpp index f790502bfb0a..21591e3126ae 100644 --- a/editor/gui/scene_tree_editor.cpp +++ b/editor/gui/scene_tree_editor.cpp @@ -447,7 +447,7 @@ void SceneTreeEditor::_update_node(Node *p_node, TreeItem *p_item, bool p_part_o _set_item_custom_color(p_item, accent); } } else if (p_part_of_subscene) { - if (valid_types.size() == 0) { + if (valid_types.is_empty()) { _set_item_custom_color(p_item, get_theme_color(SNAME("warning_color"), EditorStringName(Editor))); } } else if (marked.has(p_node)) { @@ -1865,7 +1865,7 @@ bool SceneTreeEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_d if (String(d["type"]) == "files") { Vector files = d["files"]; - if (files.size() == 0) { + if (files.is_empty()) { return false; // TODO Weird? } diff --git a/editor/import/3d/editor_import_collada.cpp b/editor/import/3d/editor_import_collada.cpp index 844c3faa6fb6..27e1df77a834 100644 --- a/editor/import/3d/editor_import_collada.cpp +++ b/editor/import/3d/editor_import_collada.cpp @@ -706,7 +706,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref &p } } - if (weights.size() == 0 || total == 0) { //if nothing, add a weight to bone 0 + if (weights.is_empty() || total == 0) { //if nothing, add a weight to bone 0 //no weights assigned Collada::Vertex::Weight w; w.bone_idx = 0; @@ -1278,7 +1278,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres mesh_unique_names.insert(name); mesh->set_name(name); - Error err = _create_mesh_surfaces(morphs.size() == 0, mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, morph, morphs, p_use_compression, use_mesh_builtin_materials); + Error err = _create_mesh_surfaces(morphs.is_empty(), mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, morph, morphs, p_use_compression, use_mesh_builtin_materials); ERR_FAIL_COND_V_MSG(err, err, "Cannot create mesh surface."); mesh_cache[meshid] = mesh; diff --git a/editor/import/3d/resource_importer_obj.cpp b/editor/import/3d/resource_importer_obj.cpp index 1ed69837eb1f..9e82b8b28e65 100644 --- a/editor/import/3d/resource_importer_obj.cpp +++ b/editor/import/3d/resource_importer_obj.cpp @@ -402,7 +402,7 @@ static Error _parse_obj(const String &p_path, List> &r_meshes, //groups are too annoying if (surf_tool->get_vertex_array().size()) { //another group going on, commit it - if (normals.size() == 0) { + if (normals.is_empty()) { surf_tool->generate_normals(); } diff --git a/editor/plugins/bone_map_editor_plugin.cpp b/editor/plugins/bone_map_editor_plugin.cpp index 44da346da9e2..01b149d24fbe 100644 --- a/editor/plugins/bone_map_editor_plugin.cpp +++ b/editor/plugins/bone_map_editor_plugin.cpp @@ -665,7 +665,7 @@ void BoneMapper::auto_mapping_process(Ref &p_bone_map) { search_path.push_back(bone_idx); bone_idx = skeleton->get_bone_parent(bone_idx); } - if (search_path.size() == 0) { + if (search_path.is_empty()) { bone_idx = -1; } else if (search_path.size() == 1) { bone_idx = search_path[0]; // It is only one bone which can be root. @@ -1329,7 +1329,7 @@ void BoneMapper::auto_mapping_process(Ref &p_bone_map) { bone_idx = skeleton->get_bone_parent(bone_idx); } search_path.reverse(); - if (search_path.size() == 0) { + if (search_path.is_empty()) { p_bone_map->_set_skeleton_bone_name("Spine", skeleton->get_bone_name(chest_or_upper_chest)); // Maybe chibi model...? } else if (search_path.size() == 1) { p_bone_map->_set_skeleton_bone_name("Spine", skeleton->get_bone_name(search_path[0])); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 3267b14653e6..ca8c314f46a3 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -6273,7 +6273,7 @@ void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p if (d.has("type") && String(d["type"]) == "files") { selected_files = d["files"]; } - if (selected_files.size() == 0) { + if (selected_files.is_empty()) { return; } diff --git a/editor/plugins/control_editor_plugin.cpp b/editor/plugins/control_editor_plugin.cpp index 55d2ba196fc3..e5fdbca33dc6 100644 --- a/editor/plugins/control_editor_plugin.cpp +++ b/editor/plugins/control_editor_plugin.cpp @@ -330,7 +330,7 @@ void EditorPropertySizeFlags::update_property() { void EditorPropertySizeFlags::setup(const Vector &p_options, bool p_vertical) { vertical = p_vertical; - if (p_options.size() == 0) { + if (p_options.is_empty()) { flag_presets->clear(); flag_presets->add_item(TTR("Container Default")); flag_presets->set_disabled(true); diff --git a/editor/plugins/gizmos/lightmap_gi_gizmo_plugin.cpp b/editor/plugins/gizmos/lightmap_gi_gizmo_plugin.cpp index 20a876bb8f65..732554519d01 100644 --- a/editor/plugins/gizmos/lightmap_gi_gizmo_plugin.cpp +++ b/editor/plugins/gizmos/lightmap_gi_gizmo_plugin.cpp @@ -88,7 +88,7 @@ void LightmapGIGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { HashSet lines_found; Vector points = data->get_capture_points(); - if (points.size() == 0) { + if (points.is_empty()) { return; } Vector sh = data->get_capture_sh(); diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp index 6cd44eb3db81..66179b31a4a8 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp @@ -394,7 +394,7 @@ void MeshInstance3DEditor::_create_uv_lines(int p_layer) { Array a = mesh->surface_get_arrays(i); Vector uv = a[p_layer == 0 ? Mesh::ARRAY_TEX_UV : Mesh::ARRAY_TEX_UV2]; - if (uv.size() == 0) { + if (uv.is_empty()) { err_dialog->set_text(vformat(TTR("Mesh has no UV in layer %d."), p_layer + 1)); err_dialog->popup_centered(); return; @@ -440,7 +440,7 @@ void MeshInstance3DEditor::_create_uv_lines(int p_layer) { } void MeshInstance3DEditor::_debug_uv_draw() { - if (uv_lines.size() == 0) { + if (uv_lines.is_empty()) { return; } diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp index 97ace286a22c..afee61ef4091 100644 --- a/editor/plugins/multimesh_editor_plugin.cpp +++ b/editor/plugins/multimesh_editor_plugin.cpp @@ -120,7 +120,7 @@ void MultiMeshEditor::_populate() { Vector geometry = ss_instance->get_mesh()->get_faces(); - if (geometry.size() == 0) { + if (geometry.is_empty()) { err_dialog->set_text(TTR("Surface source is invalid (no faces).")); err_dialog->popup_centered(); return; diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp index 35181cda1116..156cbbd2a61c 100644 --- a/editor/plugins/particles_editor_plugin.cpp +++ b/editor/plugins/particles_editor_plugin.cpp @@ -656,7 +656,7 @@ void Particles3DEditorPlugin::_node_selected(const NodePath &p_path) { } geometry = mi->get_mesh()->get_faces(); - if (geometry.size() == 0) { + if (geometry.is_empty()) { EditorNode::get_singleton()->show_warning(vformat(TTR("\"%s\" doesn't contain face geometry."), sel->get_name())); return; } diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index 4ecbab1549d9..dbfded66bc65 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -182,7 +182,7 @@ void Polygon2DEditor::_sync_bones() { } } - if (weights.size() == 0) { //create them + if (weights.is_empty()) { //create them weights.resize(wc); float *w = weights.ptrw(); for (int j = 0; j < wc; j++) { @@ -311,7 +311,7 @@ void Polygon2DEditor::_edit_menu_option(int p_option) { switch (p_option) { case MENU_POLYGON_TO_UV: { Vector points = node->get_polygon(); - if (points.size() == 0) { + if (points.is_empty()) { break; } Vector uvs = node->get_uv(); @@ -323,7 +323,7 @@ void Polygon2DEditor::_edit_menu_option(int p_option) { case MENU_UV_TO_POLYGON: { Vector points = node->get_polygon(); Vector uvs = node->get_uv(); - if (uvs.size() == 0) { + if (uvs.is_empty()) { break; } @@ -334,7 +334,7 @@ void Polygon2DEditor::_edit_menu_option(int p_option) { } break; case MENU_UV_CLEAR: { Vector uvs = node->get_uv(); - if (uvs.size() == 0) { + if (uvs.is_empty()) { break; } undo_redo->create_action(TTR("Create UV Map")); diff --git a/editor/plugins/polygon_3d_editor_plugin.cpp b/editor/plugins/polygon_3d_editor_plugin.cpp index bce060db9cf2..49fca7f7ea7e 100644 --- a/editor/plugins/polygon_3d_editor_plugin.cpp +++ b/editor/plugins/polygon_3d_editor_plugin.cpp @@ -462,7 +462,7 @@ void Polygon3DEditor::_polygon_draw() { imesh->surface_end(); - if (poly.size() == 0) { + if (poly.is_empty()) { return; } diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index d12db740ac87..01ff2aa905a0 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -3206,7 +3206,7 @@ bool ScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data if (String(d["type"]) == "nodes") { Array nodes = d["nodes"]; - if (nodes.size() == 0) { + if (nodes.is_empty()) { return false; } Node *node = get_node((nodes[0])); @@ -3224,7 +3224,7 @@ bool ScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data if (String(d["type"]) == "files") { Vector files = d["files"]; - if (files.size() == 0) { + if (files.is_empty()) { return false; //weird } @@ -3282,7 +3282,7 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co if (String(d["type"]) == "nodes") { Array nodes = d["nodes"]; - if (nodes.size() == 0) { + if (nodes.is_empty()) { return; } Node *node = get_node(nodes[0]); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index f0f476b7f027..0fdba5894dee 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -760,7 +760,7 @@ void ScriptTextEditor::_update_bookmark_list() { bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV); PackedInt32Array bookmark_list = code_editor->get_text_editor()->get_bookmarked_lines(); - if (bookmark_list.size() == 0) { + if (bookmark_list.is_empty()) { return; } @@ -915,7 +915,7 @@ void ScriptTextEditor::_update_breakpoint_list() { breakpoints_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_breakpoint"), DEBUG_GOTO_PREV_BREAKPOINT); PackedInt32Array breakpoint_list = code_editor->get_text_editor()->get_breakpointed_lines(); - if (breakpoint_list.size() == 0) { + if (breakpoint_list.is_empty()) { return; } diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 467ba72f7ada..2549a674d6e0 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -646,7 +646,7 @@ bool ShaderEditorPlugin::can_drop_data_fw(const Point2 &p_point, const Variant & if (String(d["type"]) == "files") { Vector files = d["files"]; - if (files.size() == 0) { + if (files.is_empty()) { return false; } diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp index 45769c8c565e..41ad9b55a3d3 100644 --- a/editor/plugins/shader_file_editor_plugin.cpp +++ b/editor/plugins/shader_file_editor_plugin.cpp @@ -166,7 +166,7 @@ void ShaderFileEditor::_update_options() { } } - if (version_list.size() == 0) { + if (version_list.is_empty()) { for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { stages[i]->set_disabled(true); } diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 13adc83095a9..1ed85b856452 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -131,7 +131,7 @@ void SpriteFramesEditor::_sheet_preview_draw() { } _draw_shadowed_line(split_sheet_preview, draw_offset + Vector2(0, draw_size.y), Vector2(draw_size.x, 0), Vector2(0, 1), line_color, shadow_color); - if (frames_selected.size() == 0) { + if (frames_selected.is_empty()) { split_sheet_dialog->get_ok_button()->set_disabled(true); split_sheet_dialog->set_ok_button_text(TTR("No Frames Selected")); return; @@ -1699,7 +1699,7 @@ bool SpriteFramesEditor::can_drop_data_fw(const Point2 &p_point, const Variant & if (String(d["type"]) == "files") { Vector files = d["files"]; - if (files.size() == 0) { + if (files.is_empty()) { return false; } diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 5ba1b201e5b6..41af1517d47b 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -216,7 +216,7 @@ void TextEditor::_update_bookmark_list() { bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV); PackedInt32Array bookmark_list = code_editor->get_text_editor()->get_bookmarked_lines(); - if (bookmark_list.size() == 0) { + if (bookmark_list.is_empty()) { return; } diff --git a/editor/plugins/text_shader_editor.cpp b/editor/plugins/text_shader_editor.cpp index 91058a894a3c..c10393efbd1b 100644 --- a/editor/plugins/text_shader_editor.cpp +++ b/editor/plugins/text_shader_editor.cpp @@ -1062,7 +1062,7 @@ void TextShaderEditor::_update_bookmark_list() { bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV); PackedInt32Array bookmark_list = code_editor->get_text_editor()->get_bookmarked_lines(); - if (bookmark_list.size() == 0) { + if (bookmark_list.is_empty()) { return; } diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 9afe95f5315a..f2e092390d50 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -136,7 +136,7 @@ void ThemeItemImportTree::_update_items_tree() { filtered_names.push_back(F); } - if (filtered_names.size() == 0) { + if (filtered_names.is_empty()) { continue; } @@ -734,7 +734,7 @@ void ThemeItemImportTree::_deselect_all_data_type_pressed(int p_data_type) { } void ThemeItemImportTree::_import_selected() { - if (selected_items.size() == 0) { + if (selected_items.is_empty()) { EditorNode::get_singleton()->show_accept(TTR("Nothing was selected for the import."), TTR("OK")); return; } diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp index 7cbc134e9f1e..5a28e6176522 100644 --- a/editor/plugins/tiles/tile_data_editors.cpp +++ b/editor/plugins/tiles/tile_data_editors.cpp @@ -836,7 +836,7 @@ void GenericTilePolygonEditor::remove_polygon(int p_index) { ERR_FAIL_INDEX(p_index, (int)polygons.size()); polygons.remove_at(p_index); - if (polygons.size() == 0) { + if (polygons.is_empty()) { button_create->set_pressed(true); } base_control->queue_redraw(); diff --git a/editor/plugins/tiles/tile_set_editor.cpp b/editor/plugins/tiles/tile_set_editor.cpp index a559e993770f..bcef4508cb34 100644 --- a/editor/plugins/tiles/tile_set_editor.cpp +++ b/editor/plugins/tiles/tile_set_editor.cpp @@ -80,7 +80,7 @@ bool TileSetEditor::_can_drop_data_fw(const Point2 &p_point, const Variant &p_da if (String(d["type"]) == "files") { Vector files = d["files"]; - if (files.size() == 0) { + if (files.is_empty()) { return false; } diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp index 11854e2a7315..71a3640c1610 100644 --- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp @@ -483,7 +483,7 @@ bool TileSetScenesCollectionSourceEditor::_can_drop_data_fw(const Point2 &p_poin if (String(d["type"]) == "files") { Vector files = d["files"]; - if (files.size() == 0) { + if (files.is_empty()) { return false; } diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp index f86504499b8b..e3b482955408 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.cpp +++ b/editor/plugins/tiles/tiles_editor_plugin.cpp @@ -74,7 +74,7 @@ void TilesEditorUtils::_thread() { pattern_preview_sem.wait(); pattern_preview_mutex.lock(); - if (pattern_preview_queue.size() == 0) { + if (pattern_preview_queue.is_empty()) { pattern_preview_mutex.unlock(); } else { QueueItem item = pattern_preview_queue.front()->get(); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index fabd62a6f847..2e8ab8962c3b 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -7979,7 +7979,7 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref &p_par } Vector properties = p_node->get_editable_properties(); - if (properties.size() == 0) { + if (properties.is_empty()) { return nullptr; } @@ -7996,7 +7996,7 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref &p_par } } - if (pinfo.size() == 0) { + if (pinfo.is_empty()) { return nullptr; } diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp index 8f3cb1d3e2a3..ad9276474fb8 100644 --- a/editor/project_converter_3_to_4.cpp +++ b/editor/project_converter_3_to_4.cpp @@ -2226,7 +2226,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai int end = get_end_parenthesis(line.substr(start)) + 1; if (end > -1) { Vector parts = parse_arguments(line.substr(start, end)); - if (parts.size() == 0) { + if (parts.is_empty()) { line = line.substr(0, start) + "DisplayServer.get_display_safe_area()" + line.substr(end + start); } } diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 7e01c586c52a..848ce62de22d 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -673,7 +673,7 @@ void ProjectManager::_new_project() { void ProjectManager::_rename_project() { const Vector &selected_list = project_list->get_selected_projects(); - if (selected_list.size() == 0) { + if (selected_list.is_empty()) { return; } @@ -688,7 +688,7 @@ void ProjectManager::_rename_project() { void ProjectManager::_erase_project() { const HashSet &selected_list = project_list->get_selected_project_keys(); - if (selected_list.size() == 0) { + if (selected_list.is_empty()) { return; } diff --git a/editor/project_manager/project_list.cpp b/editor/project_manager/project_list.cpp index 5d86f2feb1e2..839bf5852481 100644 --- a/editor/project_manager/project_list.cpp +++ b/editor/project_manager/project_list.cpp @@ -1046,7 +1046,7 @@ void ProjectList::select_first_visible_project() { Vector ProjectList::get_selected_projects() const { Vector items; - if (_selected_project_paths.size() == 0) { + if (_selected_project_paths.is_empty()) { return items; } items.resize(_selected_project_paths.size()); @@ -1067,7 +1067,7 @@ const HashSet &ProjectList::get_selected_project_keys() const { } int ProjectList::get_single_selected_index() const { - if (_selected_project_paths.size() == 0) { + if (_selected_project_paths.is_empty()) { // Default selection return 0; } @@ -1088,7 +1088,7 @@ int ProjectList::get_single_selected_index() const { } void ProjectList::erase_selected_projects(bool p_delete_project_contents) { - if (_selected_project_paths.size() == 0) { + if (_selected_project_paths.is_empty()) { return; } diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 718820783ac0..651f43497339 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -659,7 +659,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } List selection = editor_selection->get_top_selected_node_list(); - if (selection.size() == 0) { + if (selection.is_empty()) { break; } @@ -887,7 +887,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } List selection = editor_selection->get_top_selected_node_list(); - if (selection.size() == 0) { + if (selection.is_empty()) { break; } @@ -2333,7 +2333,7 @@ void SceneTreeDock::_node_reparent(NodePath p_path, bool p_keep_global_xform) { void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, Vector p_nodes, bool p_keep_global_xform) { ERR_FAIL_NULL(p_new_parent); - if (p_nodes.size() == 0) { + if (p_nodes.is_empty()) { return; // Nothing to reparent. } @@ -3748,7 +3748,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { List selection = editor_selection->get_top_selected_node_list(); List full_selection = editor_selection->get_full_selected_node_list(); // Above method only returns nodes with common parent. - if (selection.size() == 0) { + if (selection.is_empty()) { return; } diff --git a/main/main.cpp b/main/main.cpp index 13c4bd098648..facbd78cab75 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2106,7 +2106,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->add_logger(memnew(RotatedFileLogger(base_path, max_files))); } - if (main_args.size() == 0 && String(GLOBAL_GET("application/run/main_scene")) == "") { + if (main_args.is_empty() && String(GLOBAL_GET("application/run/main_scene")) == "") { #ifdef TOOLS_ENABLED if (!editor && !project_manager) { #endif diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 4cfc69c6ee68..a7d820a16ecb 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -1135,13 +1135,13 @@ CSGBrush *CSGMesh3D::_build_brush() { Array arrays = mesh->surface_get_arrays(i); - if (arrays.size() == 0) { + if (arrays.is_empty()) { _make_dirty(); ERR_FAIL_COND_V(arrays.is_empty(), memnew(CSGBrush)); } Vector avertices = arrays[Mesh::ARRAY_VERTEX]; - if (avertices.size() == 0) { + if (avertices.is_empty()) { continue; } @@ -1257,7 +1257,7 @@ CSGBrush *CSGMesh3D::_build_brush() { } } - if (vertices.size() == 0) { + if (vertices.is_empty()) { return memnew(CSGBrush); } diff --git a/modules/csg/editor/csg_gizmos.cpp b/modules/csg/editor/csg_gizmos.cpp index 9ec73a253c06..59ccd4293e84 100644 --- a/modules/csg/editor/csg_gizmos.cpp +++ b/modules/csg/editor/csg_gizmos.cpp @@ -379,7 +379,7 @@ void CSGShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector faces = cs->get_brush_faces(); - if (faces.size() == 0) { + if (faces.is_empty()) { return; } diff --git a/modules/fbx/fbx_document.cpp b/modules/fbx/fbx_document.cpp index d6e6b16f4b12..a9ee9b3c0eac 100644 --- a/modules/fbx/fbx_document.cpp +++ b/modules/fbx/fbx_document.cpp @@ -1080,7 +1080,7 @@ Error FBXDocument::_parse_images(Ref p_state, const String &p_base_pat } // Fallback to loading as byte array. data = FileAccess::get_file_as_bytes(path); - if (data.size() == 0) { + if (data.is_empty()) { WARN_PRINT(vformat("FBX: Image index '%d' couldn't be loaded from path: %s because there was no data to load. Skipping it.", texture_i, path)); p_state->images.push_back(Ref()); // Placeholder to keep count. p_state->source_images.push_back(Ref()); diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 325d3a8e0895..714e22c9d9e5 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -2846,7 +2846,7 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b while (subclass) { if (subclass->extends_used) { if (!subclass->extends_path.is_empty()) { - if (subclass->extends.size() == 0) { + if (subclass->extends.is_empty()) { get_global_class_name(subclass->extends_path, r_base_type); subclass = nullptr; break; diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 19f6def62ba7..14b4f96c8dfc 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -741,7 +741,7 @@ Error GLTFDocument::_encode_buffer_glb(Ref p_state, const String &p_p if (file.is_null()) { return err; } - if (buffer_data.size() == 0) { + if (buffer_data.is_empty()) { return OK; } file->create(FileAccess::ACCESS_RESOURCES); @@ -773,7 +773,7 @@ Error GLTFDocument::_encode_buffer_bins(Ref p_state, const String &p_ if (file.is_null()) { return err; } - if (buffer_data.size() == 0) { + if (buffer_data.is_empty()) { return OK; } file->create(FileAccess::ACCESS_RESOURCES); @@ -1647,7 +1647,7 @@ Vector GLTFDocument::_decode_accessor(Ref p_state, const GLTF } GLTFAccessorIndex GLTFDocument::_encode_accessor_as_ints(Ref p_state, const Vector p_attribs, const bool p_for_vertex, const bool p_for_vertex_indices) { - if (p_attribs.size() == 0) { + if (p_attribs.is_empty()) { return -1; } const int element_count = 1; @@ -1712,7 +1712,7 @@ Vector GLTFDocument::_decode_accessor_as_ints(Ref p_state, const const Vector attribs = _decode_accessor(p_state, p_accessor, p_for_vertex); Vector ret; - if (attribs.size() == 0) { + if (attribs.is_empty()) { return ret; } @@ -1737,7 +1737,7 @@ Vector GLTFDocument::_decode_accessor_as_floats(Ref p_state, c const Vector attribs = _decode_accessor(p_state, p_accessor, p_for_vertex); Vector ret; - if (attribs.size() == 0) { + if (attribs.is_empty()) { return ret; } @@ -1768,7 +1768,7 @@ void GLTFDocument::_round_min_max_components(Vector &r_type_min, Vector< } GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec2(Ref p_state, const Vector p_attribs, const bool p_for_vertex) { - if (p_attribs.size() == 0) { + if (p_attribs.is_empty()) { return -1; } const int element_count = 2; @@ -1818,7 +1818,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec2(Ref p_state, } GLTFAccessorIndex GLTFDocument::_encode_accessor_as_color(Ref p_state, const Vector p_attribs, const bool p_for_vertex) { - if (p_attribs.size() == 0) { + if (p_attribs.is_empty()) { return -1; } @@ -1884,7 +1884,7 @@ void GLTFDocument::_calc_accessor_min_max(int p_i, const int p_element_count, Ve } GLTFAccessorIndex GLTFDocument::_encode_accessor_as_weights(Ref p_state, const Vector p_attribs, const bool p_for_vertex) { - if (p_attribs.size() == 0) { + if (p_attribs.is_empty()) { return -1; } @@ -1938,7 +1938,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_weights(Ref p_sta } GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref p_state, const Vector p_attribs, const bool p_for_vertex) { - if (p_attribs.size() == 0) { + if (p_attribs.is_empty()) { return -1; } @@ -1989,7 +1989,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref p_stat } GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quaternions(Ref p_state, const Vector p_attribs, const bool p_for_vertex) { - if (p_attribs.size() == 0) { + if (p_attribs.is_empty()) { return -1; } const int element_count = 4; @@ -2045,7 +2045,7 @@ Vector GLTFDocument::_decode_accessor_as_vec2(Ref p_state, c const Vector attribs = _decode_accessor(p_state, p_accessor, p_for_vertex); Vector ret; - if (attribs.size() == 0) { + if (attribs.is_empty()) { return ret; } @@ -2068,7 +2068,7 @@ Vector GLTFDocument::_decode_accessor_as_vec2(Ref p_state, c } GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref p_state, const Vector p_attribs, const bool p_for_vertex) { - if (p_attribs.size() == 0) { + if (p_attribs.is_empty()) { return -1; } const int element_count = 1; @@ -2117,7 +2117,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref p_stat } GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref p_state, const Vector p_attribs, const bool p_for_vertex) { - if (p_attribs.size() == 0) { + if (p_attribs.is_empty()) { return -1; } const int element_count = 3; @@ -2167,7 +2167,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref p_state, } GLTFAccessorIndex GLTFDocument::_encode_sparse_accessor_as_vec3(Ref p_state, const Vector p_attribs, const Vector p_reference_attribs, const float p_reference_multiplier, const bool p_for_vertex, const GLTFAccessorIndex p_reference_accessor) { - if (p_attribs.size() == 0) { + if (p_attribs.is_empty()) { return -1; } @@ -2276,7 +2276,7 @@ GLTFAccessorIndex GLTFDocument::_encode_sparse_accessor_as_vec3(Ref p } GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref p_state, const Vector p_attribs, const bool p_for_vertex) { - if (p_attribs.size() == 0) { + if (p_attribs.is_empty()) { return -1; } const int element_count = 16; @@ -2351,7 +2351,7 @@ Vector GLTFDocument::_decode_accessor_as_vec3(Ref p_state, c const Vector attribs = _decode_accessor(p_state, p_accessor, p_for_vertex); Vector ret; - if (attribs.size() == 0) { + if (attribs.is_empty()) { return ret; } @@ -2377,7 +2377,7 @@ Vector GLTFDocument::_decode_accessor_as_color(Ref p_state, co const Vector attribs = _decode_accessor(p_state, p_accessor, p_for_vertex); Vector ret; - if (attribs.size() == 0) { + if (attribs.is_empty()) { return ret; } @@ -2409,7 +2409,7 @@ Vector GLTFDocument::_decode_accessor_as_quaternion(Ref p const Vector attribs = _decode_accessor(p_state, p_accessor, p_for_vertex); Vector ret; - if (attribs.size() == 0) { + if (attribs.is_empty()) { return ret; } @@ -2428,7 +2428,7 @@ Vector GLTFDocument::_decode_accessor_as_xform2d(Ref p_s const Vector attribs = _decode_accessor(p_state, p_accessor, p_for_vertex); Vector ret; - if (attribs.size() == 0) { + if (attribs.is_empty()) { return ret; } @@ -2445,7 +2445,7 @@ Vector GLTFDocument::_decode_accessor_as_basis(Ref p_state, co const Vector attribs = _decode_accessor(p_state, p_accessor, p_for_vertex); Vector ret; - if (attribs.size() == 0) { + if (attribs.is_empty()) { return ret; } @@ -2463,7 +2463,7 @@ Vector GLTFDocument::_decode_accessor_as_xform(Ref p_sta const Vector attribs = _decode_accessor(p_state, p_accessor, p_for_vertex); Vector ret; - if (attribs.size() == 0) { + if (attribs.is_empty()) { return ret; } @@ -4148,7 +4148,7 @@ Error GLTFDocument::_parse_images(Ref p_state, const String &p_base_p // Fallback to loading as byte array. This enables us to support the // spec's requirement that we honor mimetype regardless of file URI. data = FileAccess::get_file_as_bytes(resource_uri); - if (data.size() == 0) { + if (data.is_empty()) { WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded as a buffer of MIME type '%s' from URI: %s because there was no data to load. Skipping it.", i, mime_type, resource_uri)); p_state->images.push_back(Ref()); // Placeholder to keep count. p_state->source_images.push_back(Ref()); diff --git a/modules/gltf/skin_tool.cpp b/modules/gltf/skin_tool.cpp index 1522c0e324d5..6d2da147d3d4 100644 --- a/modules/gltf/skin_tool.cpp +++ b/modules/gltf/skin_tool.cpp @@ -520,7 +520,7 @@ Error SkinTool::_determine_skeleton_roots( skeleton->roots = roots; - if (roots.size() == 0) { + if (roots.is_empty()) { return FAILED; } else if (roots.size() == 1) { return OK; diff --git a/modules/godot_physics_2d/godot_body_2d.cpp b/modules/godot_physics_2d/godot_body_2d.cpp index 35d021e3cfda..d68e3938fd95 100644 --- a/modules/godot_physics_2d/godot_body_2d.cpp +++ b/modules/godot_physics_2d/godot_body_2d.cpp @@ -626,7 +626,7 @@ void GodotBody2D::integrate_velocities(real_t p_step) { if (mode == PhysicsServer2D::BODY_MODE_KINEMATIC) { _set_transform(new_transform, false); _set_inv_transform(new_transform.affine_inverse()); - if (contacts.size() == 0 && linear_velocity == Vector2() && angular_velocity == 0) { + if (contacts.is_empty() && linear_velocity == Vector2() && angular_velocity == 0) { set_active(false); //stopped moving, deactivate } return; diff --git a/modules/godot_physics_2d/godot_shape_2d.cpp b/modules/godot_physics_2d/godot_shape_2d.cpp index e691f0a7e419..df32692da9d0 100644 --- a/modules/godot_physics_2d/godot_shape_2d.cpp +++ b/modules/godot_physics_2d/godot_shape_2d.cpp @@ -665,7 +665,7 @@ bool GodotConcavePolygonShape2D::contains_point(const Vector2 &p_point) const { } bool GodotConcavePolygonShape2D::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { - if (segments.size() == 0 || points.size() == 0) { + if (segments.is_empty() || points.is_empty()) { return false; } @@ -919,7 +919,7 @@ void GodotConcavePolygonShape2D::cull(const Rect2 &p_local_aabb, QueryCallback p stack[i]=0; */ - if (segments.size() == 0 || points.size() == 0 || bvh.size() == 0) { + if (segments.is_empty() || points.is_empty() || bvh.is_empty()) { return; } diff --git a/modules/godot_physics_3d/godot_body_3d.cpp b/modules/godot_physics_3d/godot_body_3d.cpp index 1edc01aeb4ce..397eb0d544bd 100644 --- a/modules/godot_physics_3d/godot_body_3d.cpp +++ b/modules/godot_physics_3d/godot_body_3d.cpp @@ -701,7 +701,7 @@ void GodotBody3D::integrate_velocities(real_t p_step) { if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { _set_transform(new_transform, false); _set_inv_transform(new_transform.affine_inverse()); - if (contacts.size() == 0 && linear_velocity == Vector3() && angular_velocity == Vector3()) { + if (contacts.is_empty() && linear_velocity == Vector3() && angular_velocity == Vector3()) { set_active(false); //stopped moving, deactivate } diff --git a/modules/godot_physics_3d/godot_shape_3d.cpp b/modules/godot_physics_3d/godot_shape_3d.cpp index f7f2c405a825..c5bbff8d68f0 100644 --- a/modules/godot_physics_3d/godot_shape_3d.cpp +++ b/modules/godot_physics_3d/godot_shape_3d.cpp @@ -838,7 +838,7 @@ void GodotConvexPolygonShape3D::project_range(const Vector3 &p_normal, const Tra Vector3 GodotConvexPolygonShape3D::get_support(const Vector3 &p_normal) const { // Skip if there are no vertices in the mesh - if (mesh.vertices.size() == 0) { + if (mesh.vertices.is_empty()) { return Vector3(); } @@ -1369,7 +1369,7 @@ void GodotConcavePolygonShape3D::_cull_segment(int p_idx, _SegmentCullParams *p_ } bool GodotConcavePolygonShape3D::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, int &r_face_index, bool p_hit_back_faces) const { - if (faces.size() == 0) { + if (faces.is_empty()) { return false; } @@ -1449,7 +1449,7 @@ bool GodotConcavePolygonShape3D::_cull(int p_idx, _CullParams *p_params) const { void GodotConcavePolygonShape3D::cull(const AABB &p_local_aabb, QueryCallback p_callback, void *p_userdata, bool p_invert_backface_collision) const { // make matrix local to concave - if (faces.size() == 0) { + if (faces.is_empty()) { return; } diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index d3d9adb24ff1..ff52a67dbc7c 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -605,7 +605,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { } g.multimesh_instances.clear(); - if (g.cells.size() == 0) { + if (g.cells.is_empty()) { //octant no longer needed _octant_clean_up(p_key); return true; @@ -637,7 +637,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { xform.basis = _ortho_bases[c.rot]; xform.set_origin(cellpos * cell_size + ofs); xform.basis.scale(Vector3(cell_scale, cell_scale, cell_scale)); - if (baked_meshes.size() == 0) { + if (baked_meshes.is_empty()) { if (mesh_library->get_item_mesh(c.item).is_valid()) { if (!multimesh_items.has(c.item)) { multimesh_items[c.item] = List>(); @@ -716,7 +716,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { #endif // defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED) //update multimeshes, only if not baked - if (baked_meshes.size() == 0) { + if (baked_meshes.is_empty()) { for (const KeyValue>> &E : multimesh_items) { Octant::MultimeshInstance mmi; @@ -1642,7 +1642,7 @@ void GridMap::_update_octant_navigation_debug_edge_connections_mesh(const Octant } } - if (vertex_array.size() == 0) { + if (vertex_array.is_empty()) { return; } diff --git a/modules/interactive_music/editor/audio_stream_interactive_editor_plugin.cpp b/modules/interactive_music/editor/audio_stream_interactive_editor_plugin.cpp index a29646e4a3c0..71a2fcd2f96f 100644 --- a/modules/interactive_music/editor/audio_stream_interactive_editor_plugin.cpp +++ b/modules/interactive_music/editor/audio_stream_interactive_editor_plugin.cpp @@ -115,7 +115,7 @@ void AudioStreamInteractiveTransitionEditor::_update_selection() { filler_clip->set_disabled(selected.is_empty()); hold_previous->set_disabled(selected.is_empty()); - if (selected.size() == 0) { + if (selected.is_empty()) { return; } diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp index 1e96efd8b957..17b64a626bc2 100644 --- a/modules/lightmapper_rd/lightmapper_rd.cpp +++ b/modules/lightmapper_rd/lightmapper_rd.cpp @@ -645,19 +645,19 @@ void LightmapperRD::_create_acceleration_structures(RenderingDevice *rd, Size2i r_cluster_aabbs_buffer = rd->storage_buffer_create(cab.size(), cab); Vector lb = lights.to_byte_array(); - if (lb.size() == 0) { + if (lb.is_empty()) { lb.resize(sizeof(Light)); //even if no lights, the buffer must exist } lights_buffer = rd->storage_buffer_create(lb.size(), lb); Vector sb = seam_buffer_vec.to_byte_array(); - if (sb.size() == 0) { + if (sb.is_empty()) { sb.resize(sizeof(Vector2i) * 2); //even if no seams, the buffer must exist } seams_buffer = rd->storage_buffer_create(sb.size(), sb); Vector pb = p_probe_positions.to_byte_array(); - if (pb.size() == 0) { + if (pb.is_empty()) { pb.resize(sizeof(Probe)); } probe_positions_buffer = rd->storage_buffer_create(pb.size(), pb); diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 8abd2126f1b7..6ac1e5a4d6b7 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -650,7 +650,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { for (SelfList *elem = script_list.first(); elem; elem = elem->next()) { // Do not reload scripts with only non-collectible instances to avoid disrupting event subscriptions and such. - bool is_reloadable = elem->self()->instances.size() == 0; + bool is_reloadable = elem->self()->instances.is_empty(); for (Object *obj : elem->self()->instances) { ERR_CONTINUE(!obj->get_script_instance()); CSharpInstance *csi = static_cast(obj->get_script_instance()); diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index e64840783b58..cf446dae5650 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -3200,7 +3200,7 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf // Generate signal { - bool is_parameterless = p_isignal.arguments.size() == 0; + bool is_parameterless = p_isignal.arguments.is_empty(); // Delegate name is [SignalName]EventHandler String delegate_name = is_parameterless ? "Action" : p_isignal.proxy_name + "EventHandler"; diff --git a/modules/multiplayer/multiplayer_synchronizer.cpp b/modules/multiplayer/multiplayer_synchronizer.cpp index c6ee33e4b043..ced4719a7367 100644 --- a/modules/multiplayer/multiplayer_synchronizer.cpp +++ b/modules/multiplayer/multiplayer_synchronizer.cpp @@ -376,7 +376,7 @@ Error MultiplayerSynchronizer::_watch_changes(uint64_t p_usec) { if (props.size() != watchers.size()) { watchers.resize(props.size()); } - if (props.size() == 0) { + if (props.is_empty()) { return OK; } Node *node = get_root_node(); diff --git a/modules/navigation_2d/2d/nav_mesh_generator_2d.cpp b/modules/navigation_2d/2d/nav_mesh_generator_2d.cpp index a0e938c3903a..3a47cdc1577f 100644 --- a/modules/navigation_2d/2d/nav_mesh_generator_2d.cpp +++ b/modules/navigation_2d/2d/nav_mesh_generator_2d.cpp @@ -71,7 +71,7 @@ NavMeshGenerator2D::~NavMeshGenerator2D() { } void NavMeshGenerator2D::sync() { - if (generator_tasks.size() == 0) { + if (generator_tasks.is_empty()) { return; } diff --git a/modules/navigation_3d/3d/nav_mesh_generator_3d.cpp b/modules/navigation_3d/3d/nav_mesh_generator_3d.cpp index e9f74f2209a0..703eb011dbaf 100644 --- a/modules/navigation_3d/3d/nav_mesh_generator_3d.cpp +++ b/modules/navigation_3d/3d/nav_mesh_generator_3d.cpp @@ -70,7 +70,7 @@ NavMeshGenerator3D::~NavMeshGenerator3D() { } void NavMeshGenerator3D::sync() { - if (generator_tasks.size() == 0) { + if (generator_tasks.is_empty()) { return; } diff --git a/modules/noise/noise.cpp b/modules/noise/noise.cpp index 9b9fd640f453..12e9aca3ea96 100644 --- a/modules/noise/noise.cpp +++ b/modules/noise/noise.cpp @@ -54,7 +54,7 @@ Vector> Noise::_get_seamless_image(int p_width, int p_height, int p_d Ref 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> images = _get_seamless_image(p_width, p_height, 1, p_invert, p_in_3d_space, p_blend_skirt, p_normalize); - if (images.size() == 0) { + if (images.is_empty()) { return Ref(); } return images[0]; diff --git a/modules/openxr/action_map/openxr_action_set.cpp b/modules/openxr/action_map/openxr_action_set.cpp index 08e46b65cedc..23470bdec32b 100644 --- a/modules/openxr/action_map/openxr_action_set.cpp +++ b/modules/openxr/action_map/openxr_action_set.cpp @@ -84,7 +84,7 @@ int OpenXRActionSet::get_action_count() const { void OpenXRActionSet::clear_actions() { // Actions held within our action set should be released and destroyed but just in case they are still used some where else - if (actions.size() == 0) { + if (actions.is_empty()) { return; } diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp index 4b08e1ffbe44..544763f642e0 100644 --- a/modules/regex/regex.cpp +++ b/modules/regex/regex.cpp @@ -69,7 +69,7 @@ String RegExMatch::get_subject() const { } int RegExMatch::get_group_count() const { - if (data.size() == 0) { + if (data.is_empty()) { return 0; } return data.size() - 1; diff --git a/modules/tinyexr/image_saver_tinyexr.cpp b/modules/tinyexr/image_saver_tinyexr.cpp index 9cd19155cdd0..969297d1e74b 100644 --- a/modules/tinyexr/image_saver_tinyexr.cpp +++ b/modules/tinyexr/image_saver_tinyexr.cpp @@ -285,7 +285,7 @@ Vector save_exr_buffer(const Ref &p_img, bool p_grayscale) { Error save_exr(const String &p_path, const Ref &p_img, bool p_grayscale) { const Vector buffer = save_exr_buffer(p_img, p_grayscale); - if (buffer.size() == 0) { + if (buffer.is_empty()) { print_error(String("Saving EXR failed.")); return ERR_FILE_CANT_WRITE; } else { diff --git a/modules/webrtc/webrtc_multiplayer_peer.cpp b/modules/webrtc/webrtc_multiplayer_peer.cpp index eb4632e7d9df..5506882ba087 100644 --- a/modules/webrtc/webrtc_multiplayer_peer.cpp +++ b/modules/webrtc/webrtc_multiplayer_peer.cpp @@ -64,7 +64,7 @@ bool WebRTCMultiplayerPeer::is_server() const { } void WebRTCMultiplayerPeer::poll() { - if (peer_map.size() == 0) { + if (peer_map.is_empty()) { return; } diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp index 9cabf14b9c97..805cd5d7ccfd 100644 --- a/modules/websocket/wsl_peer.cpp +++ b/modules/websocket/wsl_peer.cpp @@ -451,7 +451,7 @@ bool WSLPeer::_verify_server_response() { WSL_CHECK_NC("sec-websocket-accept", _compute_key_response(session_key)); #undef WSL_CHECK_NC #undef WSL_CHECK - if (supported_protocols.size() == 0) { + if (supported_protocols.is_empty()) { // We didn't request a custom protocol ERR_FAIL_COND_V_MSG(headers.has("sec-websocket-protocol"), false, "Received unrequested sub-protocol -> " + headers["sec-websocket-protocol"]); } else { diff --git a/modules/webxr/webxr_interface_js.cpp b/modules/webxr/webxr_interface_js.cpp index f45135a61188..2c92ba9d6d50 100644 --- a/modules/webxr/webxr_interface_js.cpp +++ b/modules/webxr/webxr_interface_js.cpp @@ -294,7 +294,7 @@ bool WebXRInterfaceJS::initialize() { return false; } - if (requested_reference_space_types.size() == 0) { + if (requested_reference_space_types.is_empty()) { return false; } diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index edc6f8488098..a7efff303589 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -2092,7 +2092,7 @@ void DisplayServerX11::_update_window_mouse_passthrough(WindowID p_window) { Region region = XCreateRegion(); XShapeCombineRegion(x11_display, windows[p_window].x11_window, ShapeInput, 0, 0, region, ShapeSet); XDestroyRegion(region); - } else if (region_path.size() == 0) { + } else if (region_path.is_empty()) { XShapeCombineMask(x11_display, windows[p_window].x11_window, ShapeInput, 0, 0, None, ShapeSet); } else { XPoint *points = (XPoint *)memalloc(sizeof(XPoint) * region_path.size()); diff --git a/platform/web/audio_driver_web.cpp b/platform/web/audio_driver_web.cpp index f3d5b5cd1a16..ab1c85900033 100644 --- a/platform/web/audio_driver_web.cpp +++ b/platform/web/audio_driver_web.cpp @@ -95,7 +95,7 @@ void AudioDriverWeb::_audio_driver_process(int p_from, int p_samples) { } void AudioDriverWeb::_audio_driver_capture(int p_from, int p_samples) { - if (get_input_buffer().size() == 0) { + if (get_input_buffer().is_empty()) { return; // Input capture stopped. } const int max_samples = memarr_len(input_rb); diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 79de8c4b135e..956a4a2f3d11 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -420,7 +420,7 @@ class FileDialogEventHandler : public IFileDialogEvents, public IFileDialogContr int gid = ctl_id++; int cid = ctl_id++; - if (p_options.size() == 0) { + if (p_options.is_empty()) { // Add check box. p_pfdc->StartVisualGroup(gid, L""); p_pfdc->AddCheckButton(cid, (LPCWSTR)p_name.utf16().get_data(), p_default); diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp index 09ca2b3ccfb8..e9a8c11b2a51 100644 --- a/scene/2d/animated_sprite_2d.cpp +++ b/scene/2d/animated_sprite_2d.cpp @@ -301,7 +301,7 @@ void AnimatedSprite2D::set_sprite_frames(const Ref &p_frames) { List al; frames->get_animation_list(&al); - if (al.size() == 0) { + if (al.is_empty()) { set_animation(StringName()); autoplay = String(); } else { diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 049b49d4225f..9aae3a11316a 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -675,7 +675,7 @@ static real_t rand_from_seed(uint32_t &seed) { } void CPUParticles2D::_update_internal() { - if (particles.size() == 0 || !is_visible_in_tree()) { + if (particles.is_empty() || !is_visible_in_tree()) { _set_do_redraw(false); return; } diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index 63b95f8bf4fb..a0ee730e437d 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -51,7 +51,7 @@ Rect2 OccluderPolygon2D::_edit_get_rect() const { } rect_cache_dirty = false; } else { - if (polygon.size() == 0) { + if (polygon.is_empty()) { item_rect = Rect2(); } else { Vector2 d = Vector2(LINE_GRAB_WIDTH, LINE_GRAB_WIDTH); @@ -270,7 +270,7 @@ PackedStringArray LightOccluder2D::get_configuration_warnings() const { warnings.push_back(RTR("An occluder polygon must be set (or drawn) for this occluder to take effect.")); } - if (occluder_polygon.is_valid() && occluder_polygon->get_polygon().size() == 0) { + if (occluder_polygon.is_valid() && occluder_polygon->get_polygon().is_empty()) { warnings.push_back(RTR("The occluder polygon for this occluder is empty. Please draw a polygon.")); } diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index 90fdaa94f19d..917a3b61cf59 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -38,7 +38,7 @@ Line2D::Line2D() { #ifdef DEBUG_ENABLED Rect2 Line2D::_edit_get_rect() const { - if (_points.size() == 0) { + if (_points.is_empty()) { return Rect2(0, 0, 0, 0); } Vector2 min = _points[0]; diff --git a/scene/2d/navigation/navigation_agent_2d.cpp b/scene/2d/navigation/navigation_agent_2d.cpp index d288bbc97726..91d6bcba74dd 100644 --- a/scene/2d/navigation/navigation_agent_2d.cpp +++ b/scene/2d/navigation/navigation_agent_2d.cpp @@ -594,7 +594,7 @@ Vector2 NavigationAgent2D::get_next_path_position() { _update_navigation(); const Vector &navigation_path = navigation_result->get_path(); - if (navigation_path.size() == 0) { + if (navigation_path.is_empty()) { ERR_FAIL_NULL_V_MSG(agent_parent, Vector2(), "The agent has no parent."); return agent_parent->get_global_position(); } else { @@ -632,7 +632,7 @@ Vector2 NavigationAgent2D::get_final_position() { Vector2 NavigationAgent2D::_get_final_position() const { const Vector &navigation_path = navigation_result->get_path(); - if (navigation_path.size() == 0) { + if (navigation_path.is_empty()) { return Vector2(); } return navigation_path[navigation_path.size() - 1]; @@ -685,7 +685,7 @@ void NavigationAgent2D::_update_navigation() { if (NavigationServer2D::get_singleton()->agent_is_map_changed(agent)) { reload_path = true; - } else if (navigation_result->get_path().size() == 0) { + } else if (navigation_result->get_path().is_empty()) { reload_path = true; } else { // Check if too far from the navigation path @@ -724,7 +724,7 @@ void NavigationAgent2D::_update_navigation() { emit_signal(SNAME("path_changed")); } - if (navigation_result->get_path().size() == 0) { + if (navigation_result->get_path().is_empty()) { return; } diff --git a/scene/2d/physics/character_body_2d.cpp b/scene/2d/physics/character_body_2d.cpp index d8bed2f23e91..9028a3846ef1 100644 --- a/scene/2d/physics/character_body_2d.cpp +++ b/scene/2d/physics/character_body_2d.cpp @@ -509,7 +509,7 @@ Ref CharacterBody2D::_get_slide_collision(int p_bounce) { } Ref CharacterBody2D::_get_last_slide_collision() { - if (motion_results.size() == 0) { + if (motion_results.is_empty()) { return Ref(); } return _get_slide_collision(motion_results.size() - 1); diff --git a/scene/2d/physics/collision_object_2d.cpp b/scene/2d/physics/collision_object_2d.cpp index 57ab4f9e2ad2..c95c84f0d9f5 100644 --- a/scene/2d/physics/collision_object_2d.cpp +++ b/scene/2d/physics/collision_object_2d.cpp @@ -295,7 +295,7 @@ uint32_t CollisionObject2D::create_shape_owner(Object *p_owner) { ShapeData sd; uint32_t id; - if (shapes.size() == 0) { + if (shapes.is_empty()) { id = 0; } else { id = shapes.back()->key() + 1; diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index beb86b4e463c..57e0c818d31d 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -157,7 +157,7 @@ void Polygon2D::_notification(int p_what) { Vector weights; int len = polygon.size(); - if ((invert || polygons.size() == 0) && internal_vertices > 0) { + if ((invert || polygons.is_empty()) && internal_vertices > 0) { //if no polygons are around, internal vertices must not be drawn, else let them be len -= internal_vertices; } @@ -327,7 +327,7 @@ void Polygon2D::_notification(int p_what) { Vector index_array; - if (invert || polygons.size() == 0) { + if (invert || polygons.is_empty()) { index_array = Geometry2D::triangulate_polygon(points); } else { //draw individual polygons diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index 8f20c754e26c..107bb7de85c5 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -647,7 +647,7 @@ static real_t rand_from_seed(uint32_t &seed) { } void CPUParticles3D::_update_internal() { - if (particles.size() == 0 || !is_visible_in_tree()) { + if (particles.is_empty() || !is_visible_in_tree()) { _set_redraw(false); return; } diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp index 686dc6038bab..baa3b97e60ac 100644 --- a/scene/3d/lightmap_gi.cpp +++ b/scene/3d/lightmap_gi.cpp @@ -698,7 +698,7 @@ int32_t LightmapGI::_compute_bsp_tree(const Vector &p_points, const Loc BSPNode node; node.plane = best_plane; - if (indices_under.size() == 0) { + if (indices_under.is_empty()) { //nothing to do here node.under = BSPNode::EMPTY_LEAF; } else if (indices_under.size() == 1) { @@ -707,7 +707,7 @@ int32_t LightmapGI::_compute_bsp_tree(const Vector &p_points, const Loc node.under = _compute_bsp_tree(p_points, p_planes, planes_tested, p_simplices, indices_under, bsp_nodes); } - if (indices_over.size() == 0) { + if (indices_over.is_empty()) { //nothing to do here node.over = BSPNode::EMPTY_LEAF; } else if (indices_over.size() == 1) { @@ -916,7 +916,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa Vector meshes_found; _find_meshes_and_lights(p_from_node ? p_from_node : get_parent(), meshes_found, lights_found, probes_found); - if (meshes_found.size() == 0) { + if (meshes_found.is_empty()) { return BAKE_ERROR_NO_MESHES; } // create mesh data for insert @@ -1023,8 +1023,8 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa const Vector3 *nr = nullptr; Vector index = a[Mesh::ARRAY_INDEX]; - ERR_CONTINUE(uv.size() == 0); - ERR_CONTINUE(normals.size() == 0); + ERR_CONTINUE(uv.is_empty()); + ERR_CONTINUE(normals.is_empty()); uvr = uv.ptr(); nr = normals.ptr(); diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index 20dd5f5ecc51..8e68e8fca779 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -437,11 +437,11 @@ MeshInstance3D *MeshInstance3D::create_debug_tangents_node() { Vector verts = arrays[Mesh::ARRAY_VERTEX]; Vector norms = arrays[Mesh::ARRAY_NORMAL]; - if (norms.size() == 0) { + if (norms.is_empty()) { continue; } Vector tangents = arrays[Mesh::ARRAY_TANGENT]; - if (tangents.size() == 0) { + if (tangents.is_empty()) { continue; } diff --git a/scene/3d/navigation/navigation_agent_3d.cpp b/scene/3d/navigation/navigation_agent_3d.cpp index ffb35f05c4da..b90c9e47016b 100644 --- a/scene/3d/navigation/navigation_agent_3d.cpp +++ b/scene/3d/navigation/navigation_agent_3d.cpp @@ -658,7 +658,7 @@ Vector3 NavigationAgent3D::get_next_path_position() { _update_navigation(); const Vector &navigation_path = navigation_result->get_path(); - if (navigation_path.size() == 0) { + if (navigation_path.is_empty()) { ERR_FAIL_NULL_V_MSG(agent_parent, Vector3(), "The agent has no parent."); return agent_parent->get_global_position(); } else { @@ -696,7 +696,7 @@ Vector3 NavigationAgent3D::get_final_position() { Vector3 NavigationAgent3D::_get_final_position() const { const Vector &navigation_path = navigation_result->get_path(); - if (navigation_path.size() == 0) { + if (navigation_path.is_empty()) { return Vector3(); } return navigation_path[navigation_path.size() - 1] - Vector3(0, path_height_offset, 0); @@ -751,7 +751,7 @@ void NavigationAgent3D::_update_navigation() { if (NavigationServer3D::get_singleton()->agent_is_map_changed(agent)) { reload_path = true; - } else if (navigation_result->get_path().size() == 0) { + } else if (navigation_result->get_path().is_empty()) { reload_path = true; } else { // Check if too far from the navigation path @@ -792,7 +792,7 @@ void NavigationAgent3D::_update_navigation() { emit_signal(SNAME("path_changed")); } - if (navigation_result->get_path().size() == 0) { + if (navigation_result->get_path().is_empty()) { return; } diff --git a/scene/3d/navigation/navigation_region_3d.cpp b/scene/3d/navigation/navigation_region_3d.cpp index bd336c41f804..405f4361fd72 100644 --- a/scene/3d/navigation/navigation_region_3d.cpp +++ b/scene/3d/navigation/navigation_region_3d.cpp @@ -504,7 +504,7 @@ void NavigationRegion3D::_update_debug_mesh() { debug_mesh->clear_surfaces(); Vector vertices = navigation_mesh->get_vertices(); - if (vertices.size() == 0) { + if (vertices.is_empty()) { return; } @@ -720,7 +720,7 @@ void NavigationRegion3D::_update_debug_edge_connections_mesh() { vertex_array_ptrw[vertex_array_index++] = right_end_pos; } - if (vertex_array.size() == 0) { + if (vertex_array.is_empty()) { return; } diff --git a/scene/3d/occluder_instance_3d.cpp b/scene/3d/occluder_instance_3d.cpp index 6d88323c76d2..a67805452d88 100644 --- a/scene/3d/occluder_instance_3d.cpp +++ b/scene/3d/occluder_instance_3d.cpp @@ -521,7 +521,7 @@ void OccluderInstance3D::_bake_surface(const Transform3D &p_transform, Array p_s PackedVector3Array vertices = p_surface_arrays[Mesh::ARRAY_VERTEX]; PackedInt32Array indices = p_surface_arrays[Mesh::ARRAY_INDEX]; - if (vertices.size() == 0 || indices.size() == 0) { + if (vertices.is_empty() || indices.is_empty()) { return; } diff --git a/scene/3d/physics/character_body_3d.cpp b/scene/3d/physics/character_body_3d.cpp index 6b3c97630a67..146450ba6cbf 100644 --- a/scene/3d/physics/character_body_3d.cpp +++ b/scene/3d/physics/character_body_3d.cpp @@ -717,7 +717,7 @@ Ref CharacterBody3D::_get_slide_collision(int p_bounce) { } Ref CharacterBody3D::_get_last_slide_collision() { - if (motion_results.size() == 0) { + if (motion_results.is_empty()) { return Ref(); } return _get_slide_collision(motion_results.size() - 1); diff --git a/scene/3d/physics/collision_object_3d.cpp b/scene/3d/physics/collision_object_3d.cpp index 653cbd1e5bd4..f181c44134e7 100644 --- a/scene/3d/physics/collision_object_3d.cpp +++ b/scene/3d/physics/collision_object_3d.cpp @@ -519,7 +519,7 @@ uint32_t CollisionObject3D::create_shape_owner(Object *p_owner) { ShapeData sd; uint32_t id; - if (shapes.size() == 0) { + if (shapes.is_empty()) { id = 0; } else { id = shapes.back()->key() + 1; diff --git a/scene/3d/physics/collision_polygon_3d.cpp b/scene/3d/physics/collision_polygon_3d.cpp index 51945452ab01..10281b0818f9 100644 --- a/scene/3d/physics/collision_polygon_3d.cpp +++ b/scene/3d/physics/collision_polygon_3d.cpp @@ -41,12 +41,12 @@ void CollisionPolygon3D::_build_polygon() { collision_object->shape_owner_clear_shapes(owner_id); - if (polygon.size() == 0) { + if (polygon.is_empty()) { return; } Vector> decomp = Geometry2D::decompose_polygon_in_convex(polygon); - if (decomp.size() == 0) { + if (decomp.is_empty()) { return; } diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index fb62b46e8637..4f2f24118ab8 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -1186,7 +1186,7 @@ void AnimatedSprite3D::set_sprite_frames(const Ref &p_frames) { List al; frames->get_animation_list(&al); - if (al.size() == 0) { + if (al.is_empty()) { set_animation(StringName()); autoplay = String(); } else { diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp index 682334cc8fc7..ae936a7774f8 100644 --- a/scene/animation/animation_blend_space_2d.cpp +++ b/scene/animation/animation_blend_space_2d.cpp @@ -367,7 +367,7 @@ void AnimationNodeBlendSpace2D::_update_triangles() { Vector2 AnimationNodeBlendSpace2D::get_closest_point(const Vector2 &p_point) { _update_triangles(); - if (triangles.size() == 0) { + if (triangles.is_empty()) { return Vector2(); } diff --git a/scene/animation/animation_mixer.cpp b/scene/animation/animation_mixer.cpp index 27b3bbccb10b..bcb867edf9f4 100644 --- a/scene/animation/animation_mixer.cpp +++ b/scene/animation/animation_mixer.cpp @@ -1998,7 +1998,7 @@ void AnimationMixer::_blend_apply() { for (uint32_t erase_idx = 0; erase_idx < erase_streams.size(); erase_idx++) { map.erase(erase_streams[erase_idx]); } - if (map.size() == 0) { + if (map.is_empty()) { erase_maps.push_back(L.key); } } diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 1c4d489d6873..5573b7bb851a 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -563,7 +563,7 @@ bool AnimationNodeStateMachinePlayback::_make_travel_path(AnimationTree *p_tree, // Begin astar. while (!found_route) { - if (open_list.size() == 0) { + if (open_list.is_empty()) { break; // No path found. } diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index 2de6fe24bf95..6cb97ea4ed71 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -475,7 +475,7 @@ void SceneDebugger::remove_from_cache(const String &p_filename, Node *p_node) { HashMap>::Iterator E = edit_cache.find(p_filename); if (E) { E->value.erase(p_node); - if (E->value.size() == 0) { + if (E->value.is_empty()) { edit_cache.remove(E); } } @@ -1178,7 +1178,7 @@ void LiveEditor::_restore_node_func(ObjectID p_id, const NodePath &p_at, int p_a EN->value.remove(FN); - if (EN->value.size() == 0) { + if (EN->value.is_empty()) { live_edit_remove_list.remove(EN); } diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index 37552f7597d5..9722b5e2eefa 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -963,7 +963,7 @@ void CodeEdit::indent_lines() { for (Point2i line_range : line_ranges) { for (int i = line_range.x; i <= line_range.y; i++) { const String line_text = get_line(i); - if (line_text.size() == 0) { + if (line_text.is_empty()) { // Ignore empty lines. continue; } @@ -1599,7 +1599,7 @@ bool CodeEdit::can_fold_line(int p_line) const { return false; } - if (p_line + 1 >= get_line_count() || get_line(p_line).strip_edges().size() == 0) { + if (p_line + 1 >= get_line_count() || get_line(p_line).strip_edges().is_empty()) { return false; } @@ -1658,7 +1658,7 @@ bool CodeEdit::can_fold_line(int p_line) const { /* Otherwise check indent levels. */ int start_indent = get_indent_level(p_line); for (int i = p_line + 1; i < get_line_count(); i++) { - if (is_in_string(i) != -1 || is_in_comment(i) != -1 || get_line(i).strip_edges().size() == 0) { + if (is_in_string(i) != -1 || is_in_comment(i) != -1 || get_line(i).strip_edges().is_empty()) { continue; } return (get_indent_level(i) > start_indent); @@ -1711,7 +1711,7 @@ void CodeEdit::fold_line(int p_line) { } else { int start_indent = get_indent_level(p_line); for (int i = p_line + 1; i <= line_count; i++) { - if (get_line(i).strip_edges().size() == 0) { + if (get_line(i).strip_edges().is_empty()) { continue; } if (get_indent_level(i) > start_indent) { @@ -1958,7 +1958,7 @@ String CodeEdit::get_delimiter_end_key(int p_delimiter_idx) const { } Point2 CodeEdit::get_delimiter_start_position(int p_line, int p_column) const { - if (delimiters.size() == 0) { + if (delimiters.is_empty()) { return Point2(-1, -1); } ERR_FAIL_INDEX_V(p_line, get_line_count(), Point2(-1, -1)); @@ -2009,7 +2009,7 @@ Point2 CodeEdit::get_delimiter_start_position(int p_line, int p_column) const { } Point2 CodeEdit::get_delimiter_end_position(int p_line, int p_column) const { - if (delimiters.size() == 0) { + if (delimiters.is_empty()) { return Point2(-1, -1); } ERR_FAIL_INDEX_V(p_line, get_line_count(), Point2(-1, -1)); @@ -3060,7 +3060,7 @@ void CodeEdit::_update_code_region_tags() { /* Delimiters */ void CodeEdit::_update_delimiter_cache(int p_from_line, int p_to_line) { - if (delimiters.size() == 0) { + if (delimiters.is_empty()) { return; } @@ -3210,7 +3210,7 @@ void CodeEdit::_update_delimiter_cache(int p_from_line, int p_to_line) { } int CodeEdit::_is_in_delimiter(int p_line, int p_column, DelimiterType p_type) const { - if (delimiters.size() == 0 || p_line >= delimiter_cache.size()) { + if (delimiters.is_empty() || p_line >= delimiter_cache.size()) { return -1; } ERR_FAIL_INDEX_V(p_line, get_line_count(), 0); @@ -3424,7 +3424,7 @@ void CodeEdit::_filter_code_completion_candidates_impl() { GDVIRTUAL_CALL(_filter_code_completion_candidates, completion_options_sources, completion_options); /* No options to complete, cancel. */ - if (completion_options.size() == 0) { + if (completion_options.is_empty()) { cancel_code_completion(); return; } @@ -3656,7 +3656,7 @@ void CodeEdit::_filter_code_completion_candidates_impl() { } /* No options to complete, cancel. */ - if (code_completion_options_new.size() == 0) { + if (code_completion_options_new.is_empty()) { cancel_code_completion(); return; } diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index ac3fb1ed6d6d..c6e4497a3814 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -486,7 +486,7 @@ void FileDialog::_post_popup() { void FileDialog::_push_history() { local_history.resize(local_history_pos + 1); String new_path = dir_access->get_current_dir(); - if (local_history.size() == 0 || new_path != local_history[local_history_pos]) { + if (local_history.is_empty() || new_path != local_history[local_history_pos]) { local_history.push_back(new_path); local_history_pos++; dir_prev->set_disabled(local_history_pos == 0); diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp index d7b1a4933d02..d7c8d19b6fcf 100644 --- a/scene/gui/range.cpp +++ b/scene/gui/range.cpp @@ -279,7 +279,7 @@ void Range::_ref_shared(Shared *p_shared) { void Range::_unref_shared() { if (shared) { shared->owners.erase(this); - if (shared->owners.size() == 0) { + if (shared->owners.is_empty()) { memdelete(shared); shared = nullptr; } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 7c82c8d27235..d6d77d22584b 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -5819,7 +5819,7 @@ bool RichTextLabel::_search_line(ItemFrame *p_frame, int p_line, const String &p bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p_search_previous) { ERR_FAIL_COND_V(!selection.enabled, false); - if (p_string.size() == 0) { + if (p_string.is_empty()) { selection.active = false; return false; } diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index f6f700de2a6a..abb4a2f21583 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -4596,7 +4596,7 @@ Rect2i TextEdit::get_rect_at_line_column(int p_line, int p_column) const { return Rect2i(); } - if (line_drawing_cache.size() == 0 || !line_drawing_cache.has(p_line)) { + if (line_drawing_cache.is_empty() || !line_drawing_cache.has(p_line)) { // Line is not in the cache, which means it's outside of the viewing area. return Rect2i(-1, -1, 0, 0); } diff --git a/scene/main/multiplayer_peer.cpp b/scene/main/multiplayer_peer.cpp index 8c9eeea0278c..4d4a12150cfc 100644 --- a/scene/main/multiplayer_peer.cpp +++ b/scene/main/multiplayer_peer.cpp @@ -137,7 +137,7 @@ Error MultiplayerPeerExtension::get_packet(const uint8_t **r_buffer, int &r_buff return FAILED; } - if (script_buffer.size() == 0) { + if (script_buffer.is_empty()) { return Error::ERR_UNAVAILABLE; } diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp index 4007cd58e94c..1836a9a3c0aa 100644 --- a/scene/main/shader_globals_override.cpp +++ b/scene/main/shader_globals_override.cpp @@ -228,7 +228,7 @@ void ShaderGlobalsOverride::_activate() { ERR_FAIL_NULL(get_tree()); List nodes; get_tree()->get_nodes_in_group(SceneStringName(shader_overrides_group_active), &nodes); - if (nodes.size() == 0) { + if (nodes.is_empty()) { //good we are the only override, enable all active = true; add_to_group(SceneStringName(shader_overrides_group_active)); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 31fd1cb08926..ce21690a0a83 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -294,7 +294,7 @@ void Viewport::_sub_window_register(Window *p_window) { ERR_FAIL_COND(gui.sub_windows[i].window == p_window); } - if (gui.sub_windows.size() == 0) { + if (gui.sub_windows.is_empty()) { subwindow_canvas = RS::get_singleton()->canvas_create(); RS::get_singleton()->viewport_attach_canvas(viewport, subwindow_canvas); RS::get_singleton()->viewport_set_canvas_stacking(viewport, subwindow_canvas, SUBWINDOW_CANVAS_LAYER, 0); @@ -465,7 +465,7 @@ void Viewport::_sub_window_remove(Window *p_window) { RS::get_singleton()->free(sw.canvas_item); gui.sub_windows.remove_at(index); - if (gui.sub_windows.size() == 0) { + if (gui.sub_windows.is_empty()) { RS::get_singleton()->free(subwindow_canvas); subwindow_canvas = RID(); } diff --git a/scene/resources/2d/polygon_path_finder.cpp b/scene/resources/2d/polygon_path_finder.cpp index 31cd54058bee..e3da45f266a3 100644 --- a/scene/resources/2d/polygon_path_finder.cpp +++ b/scene/resources/2d/polygon_path_finder.cpp @@ -295,7 +295,7 @@ Vector PolygonPathFinder::find_path(const Vector2 &p_from, const Vector bool found_route = false; while (true) { - if (open_list.size() == 0) { + if (open_list.is_empty()) { print_verbose("Open list empty."); break; } diff --git a/scene/resources/3d/importer_mesh.cpp b/scene/resources/3d/importer_mesh.cpp index db19122258ab..5a83446b8b7b 100644 --- a/scene/resources/3d/importer_mesh.cpp +++ b/scene/resources/3d/importer_mesh.cpp @@ -874,7 +874,7 @@ Ref ImporterMesh::create_convex_shape(bool p_clean, bool p Ref ImporterMesh::create_trimesh_shape() const { Vector faces = get_faces(); - if (faces.size() == 0) { + if (faces.is_empty()) { return Ref(); } @@ -896,7 +896,7 @@ Ref ImporterMesh::create_trimesh_shape() const { Ref ImporterMesh::create_navigation_mesh() { Vector faces = get_faces(); - if (faces.size() == 0) { + if (faces.is_empty()) { return Ref(); } diff --git a/scene/resources/3d/primitive_meshes.cpp b/scene/resources/3d/primitive_meshes.cpp index 422c3a7a74ed..3dac3afc4798 100644 --- a/scene/resources/3d/primitive_meshes.cpp +++ b/scene/resources/3d/primitive_meshes.cpp @@ -103,7 +103,7 @@ void PrimitiveMesh::_update() const { Vector uv = arr[RS::ARRAY_TEX_UV]; Vector uv2 = arr[RS::ARRAY_TEX_UV2]; - if (uv.size() > 0 && uv2.size() == 0) { + if (uv.size() > 0 && uv2.is_empty()) { Vector2 uv2_scale = get_uv2_scale(); uv2.resize(uv.size()); diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 5c5febd7b544..688ef1a61242 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -4335,7 +4335,7 @@ void Animation::_value_track_optimize(int p_idx, real_t p_allowed_velocity_err, ERR_FAIL_INDEX(p_idx, tracks.size()); ERR_FAIL_COND(tracks[p_idx]->type != TYPE_VALUE); ValueTrack *vt = static_cast(tracks[p_idx]); - if (vt->values.size() == 0) { + if (vt->values.is_empty()) { return; } Variant::Type type = vt->values[0].value.get_type(); @@ -4582,7 +4582,7 @@ struct AnimationCompressionDataState { } uint32_t get_temp_packet_size() const { - if (temp_packets.size() == 0) { + if (temp_packets.is_empty()) { return 0; } else if (temp_packets.size() == 1) { return components == 1 ? 4 : 8; // 1 component packet is 16 bits and 16 bits unused. 3 component packets is 48 bits and 16 bits unused @@ -4624,7 +4624,7 @@ struct AnimationCompressionDataState { } void commit_temp_packets() { - if (temp_packets.size() == 0) { + if (temp_packets.is_empty()) { return; // Nothing to do. } //#define DEBUG_PACKET_PUSH @@ -4890,7 +4890,7 @@ void Animation::compress(uint32_t p_page_size, uint32_t p_fps, float p_split_tol track_bounds.push_back(bounds); } - if (tracks_to_compress.size() == 0) { + if (tracks_to_compress.is_empty()) { return; //nothing to compress } @@ -5045,7 +5045,7 @@ void Animation::compress(uint32_t p_page_size, uint32_t p_fps, float p_split_tol uint32_t total_page_size = 0; for (uint32_t i = 0; i < data_tracks.size(); i++) { - if (data_tracks[i].temp_packets.size() == 0 || (data_tracks[i].temp_packets[data_tracks[i].temp_packets.size() - 1].frame) < finalizer_local_frame) { + if (data_tracks[i].temp_packets.is_empty() || (data_tracks[i].temp_packets[data_tracks[i].temp_packets.size() - 1].frame) < finalizer_local_frame) { // Add finalizer frame if it makes sense Vector3i values = _compress_key(tracks_to_compress[i], track_bounds[i], -1, page_end_frame * frame_len); diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index ca9b247f2719..f0917d446913 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -65,7 +65,7 @@ int Curve::_add_point(Vector2 p_position, real_t p_left_tangent, real_t p_right_ int ret = -1; - if (_points.size() == 0) { + if (_points.is_empty()) { _points.push_back(Point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode)); ret = 0; @@ -377,7 +377,7 @@ void Curve::set_max_domain(real_t p_max) { } real_t Curve::sample(real_t p_offset) const { - if (_points.size() == 0) { + if (_points.is_empty()) { return 0; } if (_points.size() == 1) { @@ -539,8 +539,8 @@ real_t Curve::sample_baked(real_t p_offset) const { } // Special cases if the cache is too small. - if (_baked_cache.size() == 0) { - if (_points.size() == 0) { + if (_baked_cache.is_empty()) { + if (_points.is_empty()) { return 0; } return _points[0].position.y; @@ -569,7 +569,7 @@ real_t Curve::sample_baked(real_t p_offset) const { } void Curve::ensure_default_setup(real_t p_min, real_t p_max) { - if (_points.size() == 0 && _min_value == 0 && _max_value == 1) { + if (_points.is_empty() && _min_value == 0 && _max_value == 1) { add_point(Vector2(0, 1)); add_point(Vector2(1, 1)); set_min_value(p_min); @@ -910,7 +910,7 @@ void Curve2D::_bake() const { baked_max_ofs = 0; baked_cache_dirty = false; - if (points.size() == 0) { + if (points.is_empty()) { baked_point_cache.clear(); baked_dist_cache.clear(); baked_forward_vector_cache.clear(); @@ -1259,7 +1259,7 @@ void Curve2D::_set_data(const Dictionary &p_data) { PackedVector2Array Curve2D::tessellate(int p_max_stages, real_t p_tolerance) const { PackedVector2Array tess; - if (points.size() == 0) { + if (points.is_empty()) { return tess; } @@ -1309,7 +1309,7 @@ PackedVector2Array Curve2D::tessellate_even_length(int p_max_stages, real_t p_le PackedVector2Array tess; Vector> midpoints = _tessellate_even_length(p_max_stages, p_length); - if (midpoints.size() == 0) { + if (midpoints.is_empty()) { return tess; } @@ -1659,7 +1659,7 @@ void Curve3D::_bake() const { baked_max_ofs = 0; baked_cache_dirty = false; - if (points.size() == 0) { + if (points.is_empty()) { #ifdef TOOLS_ENABLED points_in_cache.clear(); #endif @@ -2293,7 +2293,7 @@ void Curve3D::_set_data(const Dictionary &p_data) { PackedVector3Array Curve3D::tessellate(int p_max_stages, real_t p_tolerance) const { PackedVector3Array tess; - if (points.size() == 0) { + if (points.is_empty()) { return tess; } Vector> midpoints; @@ -2356,7 +2356,7 @@ PackedVector3Array Curve3D::tessellate_even_length(int p_max_stages, real_t p_le PackedVector3Array tess; Vector> midpoints = _tessellate_even_length(p_max_stages, p_length); - if (midpoints.size() == 0) { + if (midpoints.is_empty()) { return tess; } diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index daa310212655..5c5ec5d98359 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -565,7 +565,7 @@ Ref Mesh::create_convex_shape(bool p_clean, bool p_simplif Ref Mesh::create_trimesh_shape() const { Vector faces = get_faces(); - if (faces.size() == 0) { + if (faces.is_empty()) { return Ref(); } @@ -617,7 +617,7 @@ Ref Mesh::create_outline(float p_margin) const { if (j == ARRAY_VERTEX) { vcount = src.size(); } - if (dst.size() == 0 || src.size() == 0) { + if (dst.is_empty() || src.is_empty()) { arrays[j] = Variant(); continue; } @@ -629,7 +629,7 @@ Ref Mesh::create_outline(float p_margin) const { case ARRAY_WEIGHTS: { Vector dst = arrays[j]; Vector src = a[j]; - if (dst.size() == 0 || src.size() == 0) { + if (dst.is_empty() || src.is_empty()) { arrays[j] = Variant(); continue; } @@ -640,7 +640,7 @@ Ref Mesh::create_outline(float p_margin) const { case ARRAY_COLOR: { Vector dst = arrays[j]; Vector src = a[j]; - if (dst.size() == 0 || src.size() == 0) { + if (dst.is_empty() || src.is_empty()) { arrays[j] = Variant(); continue; } @@ -652,7 +652,7 @@ Ref Mesh::create_outline(float p_margin) const { case ARRAY_TEX_UV2: { Vector dst = arrays[j]; Vector src = a[j]; - if (dst.size() == 0 || src.size() == 0) { + if (dst.is_empty() || src.is_empty()) { arrays[j] = Variant(); continue; } @@ -663,7 +663,7 @@ Ref Mesh::create_outline(float p_margin) const { case ARRAY_INDEX: { Vector dst = arrays[j]; Vector src = a[j]; - if (dst.size() == 0 || src.size() == 0) { + if (dst.is_empty() || src.is_empty()) { arrays[j] = Variant(); continue; } @@ -2032,7 +2032,7 @@ AABB ArrayMesh::get_custom_aabb() const { } void ArrayMesh::regen_normal_maps() { - if (surfaces.size() == 0) { + if (surfaces.is_empty()) { return; } Vector> surfs; diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp index 034d4d69966f..43be579f8918 100644 --- a/scene/resources/navigation_mesh.cpp +++ b/scene/resources/navigation_mesh.cpp @@ -51,7 +51,7 @@ void NavigationMesh::create_from_mesh(const Ref &p_mesh) { Vector varr = arr[Mesh::ARRAY_VERTEX]; Vector iarr = arr[Mesh::ARRAY_INDEX]; - if (varr.size() == 0 || iarr.size() == 0) { + if (varr.is_empty() || iarr.is_empty()) { WARN_PRINT("A mesh surface was skipped when creating a NavigationMesh due to an empty vertex or index array."); continue; } @@ -398,7 +398,7 @@ Ref NavigationMesh::get_debug_mesh() { debug_mesh->clear_surfaces(); } - if (vertices.size() == 0) { + if (vertices.is_empty()) { return debug_mesh; } diff --git a/scene/resources/portable_compressed_texture.cpp b/scene/resources/portable_compressed_texture.cpp index 99317af5a113..3a7d0991f4bd 100644 --- a/scene/resources/portable_compressed_texture.cpp +++ b/scene/resources/portable_compressed_texture.cpp @@ -35,7 +35,7 @@ #include "scene/resources/bit_map.h" void PortableCompressedTexture2D::_set_data(const Vector &p_data) { - if (p_data.size() == 0) { + if (p_data.is_empty()) { return; //nothing to do } diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 3e12342973a2..226ff0cce081 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -772,7 +772,7 @@ void SurfaceTool::index() { } void SurfaceTool::deindex() { - if (index_array.size() == 0) { + if (index_array.is_empty()) { return; //nothing to deindex } @@ -1020,7 +1020,7 @@ void SurfaceTool::create_from_blend_shape(const Ref &p_existing, int p_sur void SurfaceTool::append_from(const Ref &p_existing, int p_surface, const Transform3D &p_xform) { ERR_FAIL_COND_MSG(p_existing.is_null(), "First argument in SurfaceTool::append_from() must be a valid object of type Mesh"); - if (vertex_array.size() == 0) { + if (vertex_array.is_empty()) { primitive = p_existing->surface_get_primitive_type(p_surface); format = 0; } diff --git a/scene/resources/visual_shader_particle_nodes.cpp b/scene/resources/visual_shader_particle_nodes.cpp index cce340fd74eb..64c87885ef0a 100644 --- a/scene/resources/visual_shader_particle_nodes.cpp +++ b/scene/resources/visual_shader_particle_nodes.cpp @@ -461,7 +461,7 @@ void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector Ref image; image.instantiate(); - if (p_array.size() == 0) { + if (p_array.is_empty()) { image->initialize_data(1, 1, false, Image::Format::FORMAT_RGBF); } else { image->initialize_data(p_array.size(), 1, false, Image::Format::FORMAT_RGBF); @@ -471,7 +471,7 @@ void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector Vector2 v = p_array[i]; image->set_pixel(i, 0, Color(v.x, v.y, 0)); } - if (r_texture->get_width() != p_array.size() || p_array.size() == 0) { + if (r_texture->get_width() != p_array.size() || p_array.is_empty()) { r_texture->set_image(image); } else { r_texture->update(image); @@ -482,7 +482,7 @@ void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector Ref image; image.instantiate(); - if (p_array.size() == 0) { + if (p_array.is_empty()) { image->initialize_data(1, 1, false, Image::Format::FORMAT_RGBF); } else { image->initialize_data(p_array.size(), 1, false, Image::Format::FORMAT_RGBF); @@ -492,7 +492,7 @@ void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector Vector3 v = p_array[i]; image->set_pixel(i, 0, Color(v.x, v.y, v.z)); } - if (r_texture->get_width() != p_array.size() || p_array.size() == 0) { + if (r_texture->get_width() != p_array.size() || p_array.is_empty()) { r_texture->set_image(image); } else { r_texture->update(image); @@ -503,7 +503,7 @@ void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector &p Ref image; image.instantiate(); - if (p_array.size() == 0) { + if (p_array.is_empty()) { image->initialize_data(1, 1, false, Image::Format::FORMAT_RGBA8); } else { image->initialize_data(p_array.size(), 1, false, Image::Format::FORMAT_RGBA8); @@ -512,7 +512,7 @@ void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector &p for (int i = 0; i < p_array.size(); i++) { image->set_pixel(i, 0, p_array[i]); } - if (r_texture->get_width() != p_array.size() || p_array.size() == 0) { + if (r_texture->get_width() != p_array.size() || p_array.is_empty()) { r_texture->set_image(image); } else { r_texture->update(image); diff --git a/scene/theme/theme_db.cpp b/scene/theme/theme_db.cpp index c33c31558f92..b768aef0d1f9 100644 --- a/scene/theme/theme_db.cpp +++ b/scene/theme/theme_db.cpp @@ -500,7 +500,7 @@ const Vector> ThemeContext::get_themes() const { Ref ThemeContext::get_fallback_theme() const { // We expect all contexts to be valid and non-empty, but just in case... - if (themes.size() == 0) { + if (themes.is_empty()) { return ThemeDB::get_singleton()->get_default_theme(); } diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp index 574b217494ba..757c69b1af5b 100644 --- a/servers/rendering/renderer_rd/environment/gi.cpp +++ b/servers/rendering/renderer_rd/environment/gi.cpp @@ -2676,13 +2676,13 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vectortexture_create(dtf, RD::TextureView()); RD::get_singleton()->set_resource_name(dmap.texture, "VoxelGI Instance DMap Texture"); - if (dynamic_maps.size() == 0) { + if (dynamic_maps.is_empty()) { // Render depth for first one. // Use 16-bit depth when supported to improve performance. dtf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D16_UNORM, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_X8_D24_UNORM_PACK32; @@ -2698,7 +2698,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vectortexture_create(dtf, RD::TextureView()); RD::get_singleton()->set_resource_name(dmap.depth, "VoxelGI Instance DMap Depth"); - if (dynamic_maps.size() == 0) { + if (dynamic_maps.is_empty()) { dtf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; dmap.albedo = RD::get_singleton()->texture_create(dtf, RD::TextureView()); @@ -3279,7 +3279,7 @@ void GI::VoxelGIInstance::free_resources() { void GI::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - if (mipmaps.size() == 0) { + if (mipmaps.is_empty()) { return; } diff --git a/servers/rendering/renderer_rd/framebuffer_cache_rd.h b/servers/rendering/renderer_rd/framebuffer_cache_rd.h index 87b637de27ac..df0fa6ae9fc3 100644 --- a/servers/rendering/renderer_rd/framebuffer_cache_rd.h +++ b/servers/rendering/renderer_rd/framebuffer_cache_rd.h @@ -207,7 +207,7 @@ class FramebufferCacheRD : public Object { const Cache *c = hash_table[table_idx]; while (c) { - if (c->hash == h && c->passes.size() == 0 && c->textures.size() == sizeof...(Args) && c->views == 1 && _compare_args(0, c->textures, args...)) { + if (c->hash == h && c->passes.is_empty() && c->textures.size() == sizeof...(Args) && c->views == 1 && _compare_args(0, c->textures, args...)) { return c->cache; } c = c->next; @@ -235,7 +235,7 @@ class FramebufferCacheRD : public Object { const Cache *c = hash_table[table_idx]; while (c) { - if (c->hash == h && c->passes.size() == 0 && c->textures.size() == sizeof...(Args) && c->views == p_views && _compare_args(0, c->textures, args...)) { + if (c->hash == h && c->passes.is_empty() && c->textures.size() == sizeof...(Args) && c->views == p_views && _compare_args(0, c->textures, args...)) { return c->cache; } c = c->next; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 185e69ddcdbf..d93e35f4191b 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1299,7 +1299,7 @@ void RendererCanvasRenderRD::occluder_polygon_set_shape(RID p_occluder, const Ve } } - if ((oc->line_point_count != lines.size() || lines.size() == 0) && oc->vertex_array.is_valid()) { + if ((oc->line_point_count != lines.size() || lines.is_empty()) && oc->vertex_array.is_valid()) { RD::get_singleton()->free(oc->vertex_array); RD::get_singleton()->free(oc->vertex_buffer); RD::get_singleton()->free(oc->index_array); @@ -1404,7 +1404,7 @@ void RendererCanvasRenderRD::occluder_polygon_set_shape(RID p_occluder, const Ve } } - if (((oc->sdf_index_count != sdf_indices.size() && oc->sdf_point_count != p_points.size()) || p_points.size() == 0) && oc->sdf_vertex_array.is_valid()) { + if (((oc->sdf_index_count != sdf_indices.size() && oc->sdf_point_count != p_points.size()) || p_points.is_empty()) && oc->sdf_vertex_array.is_valid()) { RD::get_singleton()->free(oc->sdf_vertex_array); RD::get_singleton()->free(oc->sdf_vertex_buffer); RD::get_singleton()->free(oc->sdf_index_array); @@ -3200,7 +3200,7 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, CanvasSha } RendererCanvasRenderRD::Batch *RendererCanvasRenderRD::_new_batch(bool &r_batch_broken) { - if (state.canvas_instance_batches.size() == 0) { + if (state.canvas_instance_batches.is_empty()) { Batch new_batch; new_batch.instance_buffer_index = state.current_instance_buffer_index; state.canvas_instance_batches.push_back(new_batch); diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp index 8044e79f728b..a8a9566f7e40 100644 --- a/servers/rendering/renderer_rd/shader_rd.cpp +++ b/servers/rendering/renderer_rd/shader_rd.cpp @@ -282,7 +282,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, CompileData p_data) { current_source = builder.as_string(); RD::ShaderStageSPIRVData stage; stage.spirv = RD::get_singleton()->shader_compile_spirv_from_source(RD::SHADER_STAGE_VERTEX, current_source, RD::SHADER_LANGUAGE_GLSL, &error); - if (stage.spirv.size() == 0) { + if (stage.spirv.is_empty()) { build_ok = false; } else { stage.shader_stage = RD::SHADER_STAGE_VERTEX; @@ -300,7 +300,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, CompileData p_data) { current_source = builder.as_string(); RD::ShaderStageSPIRVData stage; stage.spirv = RD::get_singleton()->shader_compile_spirv_from_source(RD::SHADER_STAGE_FRAGMENT, current_source, RD::SHADER_LANGUAGE_GLSL, &error); - if (stage.spirv.size() == 0) { + if (stage.spirv.is_empty()) { build_ok = false; } else { stage.shader_stage = RD::SHADER_STAGE_FRAGMENT; @@ -319,7 +319,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, CompileData p_data) { RD::ShaderStageSPIRVData stage; stage.spirv = RD::get_singleton()->shader_compile_spirv_from_source(RD::SHADER_STAGE_COMPUTE, current_source, RD::SHADER_LANGUAGE_GLSL, &error); - if (stage.spirv.size() == 0) { + if (stage.spirv.is_empty()) { build_ok = false; } else { stage.shader_stage = RD::SHADER_STAGE_COMPUTE; diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp index 4d8eae82d17f..1e4d49815416 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp @@ -1137,7 +1137,7 @@ bool MaterialStorage::MaterialData::update_parameters_uniform_set(const HashMap< update_textures(p_parameters, p_default_texture_params, p_texture_uniforms, texture_cache.ptrw(), p_use_linear_color, p_3d_material); } - if (p_ubo_size == 0 && (p_texture_uniforms.size() == 0)) { + if (p_ubo_size == 0 && (p_texture_uniforms.is_empty())) { // This material does not require an uniform set, so don't create it. return false; } diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index 4fc3f995ed78..aae3d7de4620 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -3717,7 +3717,7 @@ RID TextureStorage::render_target_get_rd_texture_slice(RID p_render_target, uint return rt->color; } else { ERR_FAIL_UNSIGNED_INDEX_V(p_layer, rt->view_count, RID()); - if (rt->color_slices.size() == 0) { + if (rt->color_slices.is_empty()) { for (uint32_t v = 0; v < rt->view_count; v++) { RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->color, v, 0); rt->color_slices.push_back(slice); diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index c5a442da6bac..b9c6c0863a37 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -2121,7 +2121,7 @@ void RendererSceneCull::_update_instance_aabb(Instance *p_instance) const { } void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance) const { - bool first_set = p_instance->lightmap_sh.size() == 0; + bool first_set = p_instance->lightmap_sh.is_empty(); p_instance->lightmap_sh.resize(9); //using SH p_instance->lightmap_target_sh.resize(9); //using SH Color *instance_sh = p_instance->lightmap_target_sh.ptrw(); diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 1d52eae79238..458252c2f614 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -6922,7 +6922,7 @@ void RenderingDevice::_save_pipeline_cache(void *p_data) { Vector cache_blob = self->driver->pipeline_cache_serialize(); self->_thread_safe_.unlock(); - if (cache_blob.size() == 0) { + if (cache_blob.is_empty()) { return; } print_verbose(vformat("Updated PSO cache (%.1f MiB)", cache_blob.size() / (1024.0f * 1024.0f))); diff --git a/servers/rendering/shader_preprocessor.cpp b/servers/rendering/shader_preprocessor.cpp index b27f3b2878cb..24866bdb4ac5 100644 --- a/servers/rendering/shader_preprocessor.cpp +++ b/servers/rendering/shader_preprocessor.cpp @@ -133,7 +133,7 @@ void ShaderPreprocessor::Tokenizer::skip_whitespace() { bool ShaderPreprocessor::Tokenizer::consume_empty_line() { // Read until newline and return true if the content was all whitespace/empty. - return tokens_to_string(advance('\n')).strip_edges().size() == 0; + return tokens_to_string(advance('\n')).strip_edges().is_empty(); } String ShaderPreprocessor::Tokenizer::get_identifier(bool *r_is_cursor, bool p_started) { diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index b6daf0f986bf..a3b3884aa974 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -924,7 +924,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint64_t p_format, uint // Create AABBs for each detected bone. int total_bones = max_bone + 1; - bool first = r_bone_aabb.size() == 0; + bool first = r_bone_aabb.is_empty(); r_bone_aabb.resize(total_bones); diff --git a/servers/text_server.cpp b/servers/text_server.cpp index 8302bd89ebe3..a87cc44c05bc 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -965,7 +965,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped } if (l_size > 0) { - if (lines.size() == 0 || (lines[lines.size() - 1] < range.y && prev_safe_break < l_size)) { + if (lines.is_empty() || (lines[lines.size() - 1] < range.y && prev_safe_break < l_size)) { if (p_break_flags.has_flag(BREAK_TRIM_START_EDGE_SPACES)) { int start_pos = (prev_safe_break < l_size) ? prev_safe_break : l_size - 1; if (last_end <= l_gl[start_pos].start) { @@ -1152,7 +1152,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do } if (l_size > 0) { - if (lines.size() == 0 || (lines[lines.size() - 1] < range.y && prev_safe_break < l_size)) { + if (lines.is_empty() || (lines[lines.size() - 1] < range.y && prev_safe_break < l_size)) { if (p_break_flags.has_flag(BREAK_TRIM_START_EDGE_SPACES)) { int start_pos = (prev_safe_break < l_size) ? prev_safe_break : l_size - 1; if (last_end <= l_gl[start_pos].start) { diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp index cd28ee8bce09..2b741164a40c 100644 --- a/servers/xr_server.cpp +++ b/servers/xr_server.cpp @@ -389,7 +389,7 @@ PackedStringArray XRServer::get_suggested_tracker_names() const { } } - if (arr.size() == 0) { + if (arr.is_empty()) { // no suggestions from our tracker? include our defaults arr.push_back(String("head")); arr.push_back(String("left_hand")); @@ -412,7 +412,7 @@ PackedStringArray XRServer::get_suggested_pose_names(const StringName &p_tracker } } - if (arr.size() == 0) { + if (arr.is_empty()) { // no suggestions from our tracker? include our defaults arr.push_back(String("default")); From 6312a095001233085206d4cecd3af829e00a1527 Mon Sep 17 00:00:00 2001 From: Yufeng Ying Date: Thu, 20 Mar 2025 10:16:05 +0800 Subject: [PATCH 028/111] size() <= 0 and size() < 1. --- core/debugger/remote_debugger.cpp | 4 ++-- core/os/keyboard.cpp | 2 +- editor/code_editor.cpp | 4 ++-- editor/plugins/canvas_item_editor_plugin.cpp | 2 +- editor/plugins/script_text_editor.cpp | 4 ++-- .../tiles/tile_set_scenes_collection_source_editor.cpp | 2 +- modules/gdscript/gdscript_analyzer.cpp | 2 +- modules/mono/editor/bindings_generator.cpp | 4 ++-- scene/gui/item_list.cpp | 2 +- scene/gui/rich_text_label.cpp | 2 +- .../2d/skeleton/skeleton_modification_2d_physicalbones.cpp | 2 +- scene/resources/3d/primitive_meshes.cpp | 2 +- 12 files changed, 16 insertions(+), 16 deletions(-) diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp index cd9cd084005d..d14ea59a96fc 100644 --- a/core/debugger/remote_debugger.cpp +++ b/core/debugger/remote_debugger.cpp @@ -533,7 +533,7 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { ERR_FAIL_COND(data.is_empty()); script_debugger->set_skip_breakpoints(data[0]); } else if (command == "set_ignore_error_breaks") { - ERR_FAIL_COND(data.size() < 1); + ERR_FAIL_COND(data.is_empty()); script_debugger->set_ignore_error_breaks(data[0]); } else if (command == "evaluate") { String expression_str = data[0]; @@ -675,7 +675,7 @@ Error RemoteDebugger::_core_capture(const String &p_cmd, const Array &p_data, bo ERR_FAIL_COND_V(p_data.is_empty(), ERR_INVALID_DATA); script_debugger->set_skip_breakpoints(p_data[0]); } else if (p_cmd == "set_ignore_error_breaks") { - ERR_FAIL_COND_V(p_data.size() < 1, ERR_INVALID_DATA); + ERR_FAIL_COND_V(p_data.is_empty(), ERR_INVALID_DATA); script_debugger->set_ignore_error_breaks(p_data[0]); } else if (p_cmd == "break") { script_debugger->debug(script_debugger->get_break_language()); diff --git a/core/os/keyboard.cpp b/core/os/keyboard.cpp index 307e15bed0d4..902d1af7a539 100644 --- a/core/os/keyboard.cpp +++ b/core/os/keyboard.cpp @@ -410,7 +410,7 @@ String keycode_get_string(Key p_code) { Key find_keycode(const String &p_codestr) { Key keycode = Key::NONE; Vector code_parts = p_codestr.split("+"); - if (code_parts.size() < 1) { + if (code_parts.is_empty()) { return keycode; } diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index f979fd2a1406..f9e397e05fa1 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -1730,7 +1730,7 @@ void CodeTextEditor::toggle_bookmark() { void CodeTextEditor::goto_next_bookmark() { PackedInt32Array bmarks = text_editor->get_bookmarked_lines(); - if (bmarks.size() <= 0) { + if (bmarks.is_empty()) { return; } @@ -1746,7 +1746,7 @@ void CodeTextEditor::goto_next_bookmark() { void CodeTextEditor::goto_prev_bookmark() { PackedInt32Array bmarks = text_editor->get_bookmarked_lines(); - if (bmarks.size() <= 0) { + if (bmarks.is_empty()) { return; } diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index ca8c314f46a3..e23d52280d67 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -6063,7 +6063,7 @@ bool CanvasItemEditorViewport::_create_instance(Node *p_parent, const String &p_ } void CanvasItemEditorViewport::_perform_drop_data() { - ERR_FAIL_COND(selected_files.size() <= 0); + ERR_FAIL_COND(selected_files.is_empty()); _remove_preview(); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 0fdba5894dee..72466f915a04 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -1696,7 +1696,7 @@ void ScriptTextEditor::_edit_option(int p_op) { } break; case DEBUG_GOTO_NEXT_BREAKPOINT: { PackedInt32Array bpoints = tx->get_breakpointed_lines(); - if (bpoints.size() <= 0) { + if (bpoints.is_empty()) { return; } @@ -1711,7 +1711,7 @@ void ScriptTextEditor::_edit_option(int p_op) { } break; case DEBUG_GOTO_PREV_BREAKPOINT: { PackedInt32Array bpoints = tx->get_breakpointed_lines(); - if (bpoints.size() <= 0) { + if (bpoints.is_empty()) { return; } diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp index 71a3640c1610..a48ebbc08ba4 100644 --- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp @@ -302,7 +302,7 @@ void TileSetScenesCollectionSourceEditor::_update_tile_inspector() { void TileSetScenesCollectionSourceEditor::_update_action_buttons() { Vector selected_indices = scene_tiles_list->get_selected_items(); - scene_tile_delete_button->set_disabled(selected_indices.size() <= 0 || read_only); + scene_tile_delete_button->set_disabled(selected_indices.is_empty() || read_only); } void TileSetScenesCollectionSourceEditor::_update_scenes_list() { diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index bc55603a1941..9de697b32c3c 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -2157,7 +2157,7 @@ void GDScriptAnalyzer::resolve_for(GDScriptParser::ForNode *p_for) { GDScriptParser::IdentifierNode *callee = static_cast(call->callee); if (callee->name == "range") { list_resolved = true; - if (call->arguments.size() < 1) { + if (call->arguments.is_empty()) { push_error(R"*(Invalid call for "range()" function. Expected at least 1 argument, none given.)*", call->callee); } else if (call->arguments.size() > 3) { push_error(vformat(R"*(Invalid call for "range()" function. Expected at most 3 arguments, %d given.)*", call->arguments.size()), call->callee); diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index cf446dae5650..907337ed606f 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -249,7 +249,7 @@ String BindingsGenerator::bbcode_to_text(const String &p_bbcode, const TypeInter const Vector link_target_parts = link_target.split("."); - if (link_target_parts.size() <= 0 || link_target_parts.size() > 2) { + if (link_target_parts.is_empty() || link_target_parts.size() > 2) { ERR_PRINT("Invalid reference format: '" + tag + "'."); output.append(tag); @@ -561,7 +561,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf const Vector link_target_parts = link_target.split("."); - if (link_target_parts.size() <= 0 || link_target_parts.size() > 2) { + if (link_target_parts.is_empty() || link_target_parts.size() > 2) { ERR_PRINT("Invalid reference format: '" + tag + "'."); xml_output.append(""); diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index fe66819b091c..b40746562c5a 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -429,7 +429,7 @@ void ItemList::deselect(int p_idx) { } void ItemList::deselect_all() { - if (items.size() < 1) { + if (items.is_empty()) { return; } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index d6d77d22584b..6f3c5961e13f 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -5532,7 +5532,7 @@ void RichTextLabel::append_text(const String &p_bbcode) { } else { Vector &expr = split_tag_block; - if (expr.size() < 1) { + if (expr.is_empty()) { add_text("["); pos = brk_pos + 1; } else { diff --git a/scene/resources/2d/skeleton/skeleton_modification_2d_physicalbones.cpp b/scene/resources/2d/skeleton/skeleton_modification_2d_physicalbones.cpp index 292654fe4af9..0dcba66c5e61 100644 --- a/scene/resources/2d/skeleton/skeleton_modification_2d_physicalbones.cpp +++ b/scene/resources/2d/skeleton/skeleton_modification_2d_physicalbones.cpp @@ -238,7 +238,7 @@ void SkeletonModification2DPhysicalBones::_update_simulation_state() { } _simulation_state_dirty = false; - if (_simulation_state_dirty_names.size() <= 0) { + if (_simulation_state_dirty_names.is_empty()) { for (int i = 0; i < physical_bone_chain.size(); i++) { PhysicalBone2D *physical_bone = Object::cast_to(stack->skeleton->get_node(physical_bone_chain[i].physical_bone_node)); if (!physical_bone) { diff --git a/scene/resources/3d/primitive_meshes.cpp b/scene/resources/3d/primitive_meshes.cpp index 3dac3afc4798..bd2b03198814 100644 --- a/scene/resources/3d/primitive_meshes.cpp +++ b/scene/resources/3d/primitive_meshes.cpp @@ -2972,7 +2972,7 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph PackedInt32Array contours = d["contours"]; bool orientation = d["orientation"]; - if (points.size() < 3 || contours.size() < 1) { + if (points.size() < 3 || contours.is_empty()) { return; // No full contours, only glyph control points (or nothing), ignore. } From a44f8a7a84982d6497d43e48a401eda99819b91e Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Mon, 31 Mar 2025 22:32:59 +0200 Subject: [PATCH 029/111] Prepare NavigationServer for process() and physics_process() split Prepares the NavigationServer API for a split of its functionality between frame process() and stepped physics_process(). --- main/main.cpp | 11 ++- .../2d/godot_navigation_server_2d.cpp | 18 ++++- .../2d/godot_navigation_server_2d.h | 4 +- modules/navigation_2d/nav_map_2d.cpp | 6 +- modules/navigation_2d/nav_map_2d.h | 5 +- .../3d/godot_navigation_server_3d.cpp | 18 ++++- .../3d/godot_navigation_server_3d.h | 4 +- modules/navigation_3d/nav_map_3d.cpp | 8 +- modules/navigation_3d/nav_map_3d.h | 5 +- servers/navigation_server_2d.h | 3 +- servers/navigation_server_2d_dummy.h | 4 +- servers/navigation_server_3d.h | 3 +- servers/navigation_server_3d_dummy.h | 3 +- tests/servers/test_navigation_server_2d.h | 68 ++++++++--------- tests/servers/test_navigation_server_3d.h | 74 +++++++++---------- 15 files changed, 131 insertions(+), 103 deletions(-) diff --git a/main/main.cpp b/main/main.cpp index facbd78cab75..c74f508054d2 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -4648,10 +4648,10 @@ bool Main::iteration() { uint64_t navigation_begin = OS::get_singleton()->get_ticks_usec(); #ifndef NAVIGATION_2D_DISABLED - NavigationServer2D::get_singleton()->process(physics_step * time_scale); + NavigationServer2D::get_singleton()->physics_process(physics_step * time_scale); #endif // NAVIGATION_2D_DISABLED #ifndef NAVIGATION_3D_DISABLED - NavigationServer3D::get_singleton()->process(physics_step * time_scale); + NavigationServer3D::get_singleton()->physics_process(physics_step * time_scale); #endif // NAVIGATION_3D_DISABLED navigation_process_ticks = MAX(navigation_process_ticks, OS::get_singleton()->get_ticks_usec() - navigation_begin); // keep the largest one for reference @@ -4691,6 +4691,13 @@ bool Main::iteration() { } message_queue->flush(); +#ifndef NAVIGATION_2D_DISABLED + NavigationServer2D::get_singleton()->process(process_step * time_scale); +#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED + NavigationServer3D::get_singleton()->process(process_step * time_scale); +#endif // NAVIGATION_3D_DISABLED + RenderingServer::get_singleton()->sync(); //sync if still drawing from previous frames. const bool has_pending_resources_for_processing = RD::get_singleton() && RD::get_singleton()->has_pending_resources_for_processing(); diff --git a/modules/navigation_2d/2d/godot_navigation_server_2d.cpp b/modules/navigation_2d/2d/godot_navigation_server_2d.cpp index 432541c6db97..a3caf0a889b4 100644 --- a/modules/navigation_2d/2d/godot_navigation_server_2d.cpp +++ b/modules/navigation_2d/2d/godot_navigation_server_2d.cpp @@ -1138,8 +1138,6 @@ Vector GodotNavigationServer2D::obstacle_get_vertices(RID p_obstacle) c } void GodotNavigationServer2D::flush_queries() { - // In c++ we can't be sure that this is performed in the main thread - // even with mutable functions. MutexLock lock(commands_mutex); MutexLock lock2(operations_mutex); @@ -1259,7 +1257,21 @@ void GodotNavigationServer2D::internal_free_obstacle(RID p_object) { } } -void GodotNavigationServer2D::process(real_t p_delta_time) { +void GodotNavigationServer2D::process(double p_delta_time) { + // Called for each main loop iteration AFTER node and user script process() and BEFORE RenderingServer sync. + // Will run reliably every rendered frame independent of the physics tick rate. + // Use for things that (only) need to update once per main loop iteration and rendered frame or is visible to the user. + // E.g. (final) sync of objects for this main loop iteration, updating rendered debug visuals, updating debug statistics, ... +} + +void GodotNavigationServer2D::physics_process(double p_delta_time) { + // Called for each physics process step AFTER node and user script physics_process() and BEFORE PhysicsServer sync. + // Will NOT run reliably every rendered frame. If there is no physics step this function will not run. + // Use for physics or step depending calculations and updates where the result affects the next step calculation. + // E.g. anything physics sync related, avoidance simulations, physics space state queries, ... + // If physics process needs to play catchup this function will be called multiple times per frame so it should not hold + // costly updates that are not important outside the stepped calculations to avoid causing a physics performance death spiral. + flush_queries(); if (!active) { diff --git a/modules/navigation_2d/2d/godot_navigation_server_2d.h b/modules/navigation_2d/2d/godot_navigation_server_2d.h index 5188dd5959cb..8398d3cdae5a 100644 --- a/modules/navigation_2d/2d/godot_navigation_server_2d.h +++ b/modules/navigation_2d/2d/godot_navigation_server_2d.h @@ -320,7 +320,9 @@ class GodotNavigationServer2D : public NavigationServer2D { virtual void set_active(bool p_active) override; void flush_queries(); - virtual void process(real_t p_delta_time) override; + + virtual void process(double p_delta_time) override; + virtual void physics_process(double p_delta_time) override; virtual void init() override; virtual void sync() override; virtual void finish() override; diff --git a/modules/navigation_2d/nav_map_2d.cpp b/modules/navigation_2d/nav_map_2d.cpp index d417b2f911e3..9673f4861a0b 100644 --- a/modules/navigation_2d/nav_map_2d.cpp +++ b/modules/navigation_2d/nav_map_2d.cpp @@ -532,10 +532,8 @@ void NavMap2D::compute_single_avoidance_step(uint32_t p_index, NavAgent2D **p_ag (*(p_agent + p_index))->update(); } -void NavMap2D::step(real_t p_deltatime) { - deltatime = p_deltatime; - - rvo_simulation.setTimeStep(float(deltatime)); +void NavMap2D::step(double p_delta_time) { + rvo_simulation.setTimeStep(float(p_delta_time)); if (active_avoidance_agents.size() > 0) { if (use_threads && avoidance_use_multiple_threads) { diff --git a/modules/navigation_2d/nav_map_2d.h b/modules/navigation_2d/nav_map_2d.h index 584c24ae0509..1c1abb4ded1c 100644 --- a/modules/navigation_2d/nav_map_2d.h +++ b/modules/navigation_2d/nav_map_2d.h @@ -91,9 +91,6 @@ class NavMap2D : public NavRid2D { /// Are rvo obstacles modified? bool obstacles_dirty = true; - /// Physics delta time. - real_t deltatime = 0.0; - /// Change the id each time the map is updated. uint32_t iteration_id = 0; @@ -203,7 +200,7 @@ class NavMap2D : public NavRid2D { Vector2 get_random_point(uint32_t p_navigation_layers, bool p_uniformly) const; void sync(); - void step(real_t p_deltatime); + void step(double p_delta_time); void dispatch_callbacks(); // Performance Monitor diff --git a/modules/navigation_3d/3d/godot_navigation_server_3d.cpp b/modules/navigation_3d/3d/godot_navigation_server_3d.cpp index 3a946e3911c3..4fd569e72673 100644 --- a/modules/navigation_3d/3d/godot_navigation_server_3d.cpp +++ b/modules/navigation_3d/3d/godot_navigation_server_3d.cpp @@ -1306,8 +1306,6 @@ void GodotNavigationServer3D::set_active(bool p_active) { } void GodotNavigationServer3D::flush_queries() { - // In c++ we can't be sure that this is performed in the main thread - // even with mutable functions. MutexLock lock(commands_mutex); MutexLock lock2(operations_mutex); @@ -1340,7 +1338,21 @@ void GodotNavigationServer3D::sync() { } } -void GodotNavigationServer3D::process(real_t p_delta_time) { +void GodotNavigationServer3D::process(double p_delta_time) { + // Called for each main loop iteration AFTER node and user script process() and BEFORE RenderingServer sync. + // Will run reliably every rendered frame independent of the physics tick rate. + // Use for things that (only) need to update once per main loop iteration and rendered frame or is visible to the user. + // E.g. (final) sync of objects for this main loop iteration, updating rendered debug visuals, updating debug statistics, ... +} + +void GodotNavigationServer3D::physics_process(double p_delta_time) { + // Called for each physics process step AFTER node and user script physics_process() and BEFORE PhysicsServer sync. + // Will NOT run reliably every rendered frame. If there is no physics step this function will not run. + // Use for physics or step depending calculations and updates where the result affects the next step calculation. + // E.g. anything physics sync related, avoidance simulations, physics space state queries, ... + // If physics process needs to play catchup this function will be called multiple times per frame so it should not hold + // costly updates that are not important outside the stepped calculations to avoid causing a physics performance death spiral. + flush_queries(); if (!active) { diff --git a/modules/navigation_3d/3d/godot_navigation_server_3d.h b/modules/navigation_3d/3d/godot_navigation_server_3d.h index eef36ede3d87..35b905365d54 100644 --- a/modules/navigation_3d/3d/godot_navigation_server_3d.h +++ b/modules/navigation_3d/3d/godot_navigation_server_3d.h @@ -280,7 +280,9 @@ class GodotNavigationServer3D : public NavigationServer3D { virtual void set_active(bool p_active) override; void flush_queries(); - virtual void process(real_t p_delta_time) override; + + virtual void process(double p_delta_time) override; + virtual void physics_process(double p_delta_time) override; virtual void init() override; virtual void sync() override; virtual void finish() override; diff --git a/modules/navigation_3d/nav_map_3d.cpp b/modules/navigation_3d/nav_map_3d.cpp index 743932381770..0ccbab230079 100644 --- a/modules/navigation_3d/nav_map_3d.cpp +++ b/modules/navigation_3d/nav_map_3d.cpp @@ -614,11 +614,9 @@ void NavMap3D::compute_single_avoidance_step_3d(uint32_t index, NavAgent3D **age (*(agent + index))->update(); } -void NavMap3D::step(real_t p_deltatime) { - deltatime = p_deltatime; - - rvo_simulation_2d.setTimeStep(float(deltatime)); - rvo_simulation_3d.setTimeStep(float(deltatime)); +void NavMap3D::step(double p_delta_time) { + rvo_simulation_2d.setTimeStep(float(p_delta_time)); + rvo_simulation_3d.setTimeStep(float(p_delta_time)); if (active_2d_avoidance_agents.size() > 0) { if (use_threads && avoidance_use_multiple_threads) { diff --git a/modules/navigation_3d/nav_map_3d.h b/modules/navigation_3d/nav_map_3d.h index 958b86ac1705..691f9a42cec0 100644 --- a/modules/navigation_3d/nav_map_3d.h +++ b/modules/navigation_3d/nav_map_3d.h @@ -99,9 +99,6 @@ class NavMap3D : public NavRid3D { /// Are rvo obstacles modified? bool obstacles_dirty = true; - /// Physics delta time - real_t deltatime = 0.0; - /// Change the id each time the map is updated. uint32_t iteration_id = 0; @@ -221,7 +218,7 @@ class NavMap3D : public NavRid3D { Vector3 get_random_point(uint32_t p_navigation_layers, bool p_uniformly) const; void sync(); - void step(real_t p_deltatime); + void step(double p_delta_time); void dispatch_callbacks(); // Performance Monitor diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h index c76c9c72b82d..25796249be9a 100644 --- a/servers/navigation_server_2d.h +++ b/servers/navigation_server_2d.h @@ -308,7 +308,8 @@ class NavigationServer2D : public Object { /// The result of this process is needed by the physics server, /// so this must be called in the main thread. /// Note: This function is not thread safe. - virtual void process(real_t delta_time) = 0; + virtual void process(double p_delta_time) = 0; + virtual void physics_process(double p_delta_time) = 0; virtual void init() = 0; virtual void sync() = 0; virtual void finish() = 0; diff --git a/servers/navigation_server_2d_dummy.h b/servers/navigation_server_2d_dummy.h index b19c272093fc..f5401008ad28 100644 --- a/servers/navigation_server_2d_dummy.h +++ b/servers/navigation_server_2d_dummy.h @@ -163,8 +163,8 @@ class NavigationServer2DDummy : public NavigationServer2D { void query_path(const Ref &p_query_parameters, Ref p_query_result, const Callable &p_callback = Callable()) override {} void set_active(bool p_active) override {} - - void process(real_t delta_time) override {} + void process(double p_delta_time) override {} + void physics_process(double p_delta_time) override {} void init() override {} void sync() override {} void finish() override {} diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index a8686825841f..07fc9c0fe7dc 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -346,7 +346,8 @@ class NavigationServer3D : public Object { /// The result of this process is needed by the physics server, /// so this must be called in the main thread. /// Note: This function is not thread safe. - virtual void process(real_t delta_time) = 0; + virtual void process(double p_delta_time) = 0; + virtual void physics_process(double p_delta_time) = 0; virtual void init() = 0; virtual void sync() = 0; virtual void finish() = 0; diff --git a/servers/navigation_server_3d_dummy.h b/servers/navigation_server_3d_dummy.h index 0dc88b792266..43097f0105b6 100644 --- a/servers/navigation_server_3d_dummy.h +++ b/servers/navigation_server_3d_dummy.h @@ -196,7 +196,8 @@ class NavigationServer3DDummy : public NavigationServer3D { void free(RID p_object) override {} void set_active(bool p_active) override {} - void process(real_t delta_time) override {} + void process(double p_delta_time) override {} + void physics_process(double p_delta_time) override {} void init() override {} void sync() override {} void finish() override {} diff --git a/tests/servers/test_navigation_server_2d.h b/tests/servers/test_navigation_server_2d.h index fcd668719e8f..e3e99690465f 100644 --- a/tests/servers/test_navigation_server_2d.h +++ b/tests/servers/test_navigation_server_2d.h @@ -120,7 +120,7 @@ TEST_SUITE("[Navigation2D]") { SUBCASE("Setters/getters should work") { bool initial_avoidance_enabled = navigation_server->agent_get_avoidance_enabled(agent); navigation_server->agent_set_avoidance_enabled(agent, !initial_avoidance_enabled); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->agent_get_avoidance_enabled(agent), !initial_avoidance_enabled); // TODO: Add remaining setters/getters once the missing getters are added. @@ -131,11 +131,11 @@ TEST_SUITE("[Navigation2D]") { CHECK(map.is_valid()); navigation_server->map_set_active(map, true); navigation_server->agent_set_map(agent, map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->get_process_info(NavigationServer2D::INFO_AGENT_COUNT), 1); navigation_server->agent_set_map(agent, RID()); navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->get_process_info(NavigationServer2D::INFO_AGENT_COUNT), 0); } @@ -184,7 +184,7 @@ TEST_SUITE("[Navigation2D]") { navigation_server->map_set_link_connection_radius(map, 0.77); bool initial_use_edge_connections = navigation_server->map_get_use_edge_connections(map); navigation_server->map_set_use_edge_connections(map, !initial_use_edge_connections); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_cell_size(map), doctest::Approx(0.55)); CHECK_EQ(navigation_server->map_get_edge_connection_margin(map), doctest::Approx(0.66)); @@ -194,11 +194,11 @@ TEST_SUITE("[Navigation2D]") { SUBCASE("'ProcessInfo' should report map iff active") { navigation_server->map_set_active(map, true); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK(navigation_server->map_is_active(map)); CHECK_EQ(navigation_server->get_process_info(NavigationServer2D::INFO_ACTIVE_MAPS), 1); navigation_server->map_set_active(map, false); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->get_process_info(NavigationServer2D::INFO_ACTIVE_MAPS), 0); } @@ -206,10 +206,10 @@ TEST_SUITE("[Navigation2D]") { RID agent = navigation_server->agent_create(); CHECK(agent.is_valid()); navigation_server->agent_set_map(agent, map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_agents(map).size(), 1); navigation_server->free(agent); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_agents(map).size(), 0); } @@ -217,10 +217,10 @@ TEST_SUITE("[Navigation2D]") { RID link = navigation_server->link_create(); CHECK(link.is_valid()); navigation_server->link_set_map(link, map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_links(map).size(), 1); navigation_server->free(link); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_links(map).size(), 0); } @@ -228,10 +228,10 @@ TEST_SUITE("[Navigation2D]") { RID obstacle = navigation_server->obstacle_create(); CHECK(obstacle.is_valid()); navigation_server->obstacle_set_map(obstacle, map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_obstacles(map).size(), 1); navigation_server->free(obstacle); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_obstacles(map).size(), 0); } @@ -239,16 +239,16 @@ TEST_SUITE("[Navigation2D]") { RID region = navigation_server->region_create(); CHECK(region.is_valid()); navigation_server->region_set_map(region, map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_regions(map).size(), 1); navigation_server->free(region); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_regions(map).size(), 0); } SUBCASE("Queries against empty map should return empty or invalid values") { navigation_server->map_set_active(map, true); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. ERR_PRINT_OFF; CHECK_EQ(navigation_server->map_get_closest_point(map, Vector2(7, 7)), Vector2()); @@ -271,11 +271,11 @@ TEST_SUITE("[Navigation2D]") { ERR_PRINT_ON; navigation_server->map_set_active(map, false); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. } navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to actually remove map. + navigation_server->physics_process(0.0); // Give server some cycles to actually remove map. CHECK_EQ(navigation_server->get_maps().size(), 0); } @@ -298,7 +298,7 @@ TEST_SUITE("[Navigation2D]") { navigation_server->link_set_owner_id(link, ObjectID((int64_t)7)); navigation_server->link_set_start_position(link, Vector2(8, 8)); navigation_server->link_set_travel_cost(link, 0.66); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->link_is_bidirectional(link), !initial_bidirectional); CHECK_EQ(navigation_server->link_get_end_position(link), Vector2(7, 7)); @@ -314,11 +314,11 @@ TEST_SUITE("[Navigation2D]") { CHECK(map.is_valid()); navigation_server->map_set_active(map, true); navigation_server->link_set_map(link, map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->get_process_info(NavigationServer2D::INFO_LINK_COUNT), 1); navigation_server->link_set_map(link, RID()); navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->get_process_info(NavigationServer2D::INFO_LINK_COUNT), 0); } @@ -353,7 +353,7 @@ TEST_SUITE("[Navigation2D]") { navigation_server->region_set_owner_id(region, ObjectID((int64_t)7)); navigation_server->region_set_travel_cost(region, 0.66); navigation_server->region_set_use_edge_connections(region, !initial_use_edge_connections); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->region_get_enter_cost(region), doctest::Approx(0.55)); CHECK_EQ(navigation_server->region_get_navigation_layers(region), 5); @@ -367,11 +367,11 @@ TEST_SUITE("[Navigation2D]") { CHECK(map.is_valid()); navigation_server->map_set_active(map, true); navigation_server->region_set_map(region, map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->get_process_info(NavigationServer2D::INFO_REGION_COUNT), 1); navigation_server->region_set_map(region, RID()); navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->get_process_info(NavigationServer2D::INFO_REGION_COUNT), 0); } @@ -400,7 +400,7 @@ TEST_SUITE("[Navigation2D]") { CallableMock agent_avoidance_callback_mock; navigation_server->agent_set_avoidance_callback(agent, callable_mp(&agent_avoidance_callback_mock, &CallableMock::function1)); CHECK_EQ(agent_avoidance_callback_mock.function1_calls, 0); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(agent_avoidance_callback_mock.function1_calls, 1); CHECK_NE(agent_avoidance_callback_mock.function1_latest_arg0, Vector3(0, 0, 0)); @@ -436,7 +436,7 @@ TEST_SUITE("[Navigation2D]") { CHECK_EQ(agent_1_avoidance_callback_mock.function1_calls, 0); CHECK_EQ(agent_2_avoidance_callback_mock.function1_calls, 0); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(agent_1_avoidance_callback_mock.function1_calls, 1); CHECK_EQ(agent_2_avoidance_callback_mock.function1_calls, 1); Vector3 agent_1_safe_velocity = agent_1_avoidance_callback_mock.function1_latest_arg0; @@ -474,7 +474,7 @@ TEST_SUITE("[Navigation2D]") { navigation_server->obstacle_set_radius(obstacle_1, 1); CHECK_EQ(agent_1_avoidance_callback_mock.function1_calls, 0); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(agent_1_avoidance_callback_mock.function1_calls, 1); Vector3 agent_1_safe_velocity = agent_1_avoidance_callback_mock.function1_latest_arg0; CHECK_MESSAGE(agent_1_safe_velocity.x > 0, "Agent 1 should move a bit along desired velocity (+X)."); @@ -483,7 +483,7 @@ TEST_SUITE("[Navigation2D]") { navigation_server->free(obstacle_1); navigation_server->free(agent_1); navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. } TEST_CASE("[NavigationServer2D] Server should make agents avoid static obstacles when avoidance enabled") { @@ -525,7 +525,7 @@ TEST_SUITE("[Navigation2D]") { CHECK_EQ(agent_1_avoidance_callback_mock.function1_calls, 0); CHECK_EQ(agent_2_avoidance_callback_mock.function1_calls, 0); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(agent_1_avoidance_callback_mock.function1_calls, 1); CHECK_EQ(agent_2_avoidance_callback_mock.function1_calls, 1); Vector3 agent_1_safe_velocity = agent_1_avoidance_callback_mock.function1_latest_arg0; @@ -539,7 +539,7 @@ TEST_SUITE("[Navigation2D]") { navigation_server->free(agent_2); navigation_server->free(agent_1); navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. } TEST_CASE("[NavigationServer2D][SceneTree] Server should be able to parse geometry") { @@ -614,7 +614,7 @@ TEST_SUITE("[Navigation2D]") { navigation_server->map_set_use_async_iterations(map, false); navigation_server->region_set_map(region, map); navigation_server->region_set_navigation_polygon(region, navigation_polygon); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_polygon->get_polygon_count(), 0); CHECK_EQ(navigation_polygon->get_vertices().size(), 0); @@ -633,7 +633,7 @@ TEST_SUITE("[Navigation2D]") { SUBCASE("Map should emit signal and take newly baked navigation mesh into account") { SIGNAL_WATCH(navigation_server, "map_changed"); SIGNAL_CHECK_FALSE("map_changed"); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. SIGNAL_CHECK("map_changed", build_array(build_array(map))); SIGNAL_UNWATCH(navigation_server, "map_changed"); CHECK_NE(navigation_server->map_get_closest_point(map, Vector2(0, 0)), Vector2(0, 0)); @@ -641,7 +641,7 @@ TEST_SUITE("[Navigation2D]") { navigation_server->free(region); navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. memdelete(polygon); memdelete(node_2d); @@ -671,7 +671,7 @@ TEST_SUITE("[Navigation2D]") { navigation_server->map_set_use_async_iterations(map, false); navigation_server->region_set_map(region, map); navigation_server->region_set_navigation_polygon(region, navigation_polygon); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. SUBCASE("Simple queries should return non-default values") { CHECK_NE(navigation_server->map_get_closest_point(map, Vector2(0.0, 0.0)), Vector2(0, 0)); @@ -746,7 +746,7 @@ TEST_SUITE("[Navigation2D]") { navigation_server->free(region); navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. } TEST_CASE("[NavigationServer2D] Server should simplify path properly") { diff --git a/tests/servers/test_navigation_server_3d.h b/tests/servers/test_navigation_server_3d.h index cf6ee1fe7c7d..463929f6295c 100644 --- a/tests/servers/test_navigation_server_3d.h +++ b/tests/servers/test_navigation_server_3d.h @@ -91,7 +91,7 @@ TEST_SUITE("[Navigation3D]") { SUBCASE("Setters/getters should work") { bool initial_use_3d_avoidance = navigation_server->agent_get_use_3d_avoidance(agent); navigation_server->agent_set_use_3d_avoidance(agent, !initial_use_3d_avoidance); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->agent_get_use_3d_avoidance(agent), !initial_use_3d_avoidance); // TODO: Add remaining setters/getters once the missing getters are added. @@ -102,11 +102,11 @@ TEST_SUITE("[Navigation3D]") { CHECK(map.is_valid()); navigation_server->map_set_active(map, true); navigation_server->agent_set_map(agent, map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->get_process_info(NavigationServer3D::INFO_AGENT_COUNT), 1); navigation_server->agent_set_map(agent, RID()); navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->get_process_info(NavigationServer3D::INFO_AGENT_COUNT), 0); } @@ -157,7 +157,7 @@ TEST_SUITE("[Navigation3D]") { navigation_server->map_set_up(map, Vector3(1, 0, 0)); bool initial_use_edge_connections = navigation_server->map_get_use_edge_connections(map); navigation_server->map_set_use_edge_connections(map, !initial_use_edge_connections); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_cell_size(map), doctest::Approx(0.55)); CHECK_EQ(navigation_server->map_get_edge_connection_margin(map), doctest::Approx(0.66)); @@ -168,11 +168,11 @@ TEST_SUITE("[Navigation3D]") { SUBCASE("'ProcessInfo' should report map iff active") { navigation_server->map_set_active(map, true); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK(navigation_server->map_is_active(map)); CHECK_EQ(navigation_server->get_process_info(NavigationServer3D::INFO_ACTIVE_MAPS), 1); navigation_server->map_set_active(map, false); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->get_process_info(NavigationServer3D::INFO_ACTIVE_MAPS), 0); } @@ -180,10 +180,10 @@ TEST_SUITE("[Navigation3D]") { RID agent = navigation_server->agent_create(); CHECK(agent.is_valid()); navigation_server->agent_set_map(agent, map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_agents(map).size(), 1); navigation_server->free(agent); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_agents(map).size(), 0); } @@ -191,10 +191,10 @@ TEST_SUITE("[Navigation3D]") { RID link = navigation_server->link_create(); CHECK(link.is_valid()); navigation_server->link_set_map(link, map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_links(map).size(), 1); navigation_server->free(link); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_links(map).size(), 0); } @@ -202,10 +202,10 @@ TEST_SUITE("[Navigation3D]") { RID obstacle = navigation_server->obstacle_create(); CHECK(obstacle.is_valid()); navigation_server->obstacle_set_map(obstacle, map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_obstacles(map).size(), 1); navigation_server->free(obstacle); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_obstacles(map).size(), 0); } @@ -213,16 +213,16 @@ TEST_SUITE("[Navigation3D]") { RID region = navigation_server->region_create(); CHECK(region.is_valid()); navigation_server->region_set_map(region, map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_regions(map).size(), 1); navigation_server->free(region); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->map_get_regions(map).size(), 0); } SUBCASE("Queries against empty map should return empty or invalid values") { navigation_server->map_set_active(map, true); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. ERR_PRINT_OFF; CHECK_EQ(navigation_server->map_get_closest_point(map, Vector3(7, 7, 7)), Vector3()); @@ -246,11 +246,11 @@ TEST_SUITE("[Navigation3D]") { ERR_PRINT_ON; navigation_server->map_set_active(map, false); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. } navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to actually remove map. + navigation_server->physics_process(0.0); // Give server some cycles to actually remove map. CHECK_EQ(navigation_server->get_maps().size(), 0); } @@ -273,7 +273,7 @@ TEST_SUITE("[Navigation3D]") { navigation_server->link_set_owner_id(link, ObjectID((int64_t)7)); navigation_server->link_set_start_position(link, Vector3(8, 8, 8)); navigation_server->link_set_travel_cost(link, 0.66); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->link_is_bidirectional(link), !initial_bidirectional); CHECK_EQ(navigation_server->link_get_end_position(link), Vector3(7, 7, 7)); @@ -289,11 +289,11 @@ TEST_SUITE("[Navigation3D]") { CHECK(map.is_valid()); navigation_server->map_set_active(map, true); navigation_server->link_set_map(link, map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->get_process_info(NavigationServer3D::INFO_LINK_COUNT), 1); navigation_server->link_set_map(link, RID()); navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->get_process_info(NavigationServer3D::INFO_LINK_COUNT), 0); } @@ -328,7 +328,7 @@ TEST_SUITE("[Navigation3D]") { navigation_server->region_set_owner_id(region, ObjectID((int64_t)7)); navigation_server->region_set_travel_cost(region, 0.66); navigation_server->region_set_use_edge_connections(region, !initial_use_edge_connections); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->region_get_enter_cost(region), doctest::Approx(0.55)); CHECK_EQ(navigation_server->region_get_navigation_layers(region), 5); @@ -342,11 +342,11 @@ TEST_SUITE("[Navigation3D]") { CHECK(map.is_valid()); navigation_server->map_set_active(map, true); navigation_server->region_set_map(region, map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->get_process_info(NavigationServer3D::INFO_REGION_COUNT), 1); navigation_server->region_set_map(region, RID()); navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_server->get_process_info(NavigationServer3D::INFO_REGION_COUNT), 0); } @@ -375,7 +375,7 @@ TEST_SUITE("[Navigation3D]") { CallableMock agent_avoidance_callback_mock; navigation_server->agent_set_avoidance_callback(agent, callable_mp(&agent_avoidance_callback_mock, &CallableMock::function1)); CHECK_EQ(agent_avoidance_callback_mock.function1_calls, 0); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(agent_avoidance_callback_mock.function1_calls, 1); CHECK_NE(agent_avoidance_callback_mock.function1_latest_arg0, Vector3(0, 0, 0)); @@ -411,7 +411,7 @@ TEST_SUITE("[Navigation3D]") { CHECK_EQ(agent_1_avoidance_callback_mock.function1_calls, 0); CHECK_EQ(agent_2_avoidance_callback_mock.function1_calls, 0); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(agent_1_avoidance_callback_mock.function1_calls, 1); CHECK_EQ(agent_2_avoidance_callback_mock.function1_calls, 1); Vector3 agent_1_safe_velocity = agent_1_avoidance_callback_mock.function1_latest_arg0; @@ -449,7 +449,7 @@ TEST_SUITE("[Navigation3D]") { navigation_server->obstacle_set_radius(obstacle_1, 1); CHECK_EQ(agent_1_avoidance_callback_mock.function1_calls, 0); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(agent_1_avoidance_callback_mock.function1_calls, 1); Vector3 agent_1_safe_velocity = agent_1_avoidance_callback_mock.function1_latest_arg0; CHECK_MESSAGE(agent_1_safe_velocity.x > 0, "Agent 1 should move a bit along desired velocity (+X)."); @@ -458,7 +458,7 @@ TEST_SUITE("[Navigation3D]") { navigation_server->free(obstacle_1); navigation_server->free(agent_1); navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. } TEST_CASE("[NavigationServer3D] Server should make agents avoid static obstacles when avoidance enabled") { @@ -508,7 +508,7 @@ TEST_SUITE("[Navigation3D]") { CHECK_EQ(agent_1_avoidance_callback_mock.function1_calls, 0); CHECK_EQ(agent_2_avoidance_callback_mock.function1_calls, 0); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(agent_1_avoidance_callback_mock.function1_calls, 1); CHECK_EQ(agent_2_avoidance_callback_mock.function1_calls, 1); Vector3 agent_1_safe_velocity = agent_1_avoidance_callback_mock.function1_latest_arg0; @@ -522,7 +522,7 @@ TEST_SUITE("[Navigation3D]") { navigation_server->free(agent_2); navigation_server->free(agent_1); navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. } #ifndef DISABLE_DEPRECATED @@ -548,7 +548,7 @@ TEST_SUITE("[Navigation3D]") { navigation_server->map_set_active(map, true); navigation_server->region_set_map(region, map); navigation_server->region_set_navigation_mesh(region, navigation_mesh); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_mesh->get_polygon_count(), 0); CHECK_EQ(navigation_mesh->get_vertices().size(), 0); @@ -564,7 +564,7 @@ TEST_SUITE("[Navigation3D]") { SUBCASE("Map should emit signal and take newly baked navigation mesh into account") { SIGNAL_WATCH(navigation_server, "map_changed"); SIGNAL_CHECK_FALSE("map_changed"); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. SIGNAL_CHECK("map_changed", build_array(build_array(map))); SIGNAL_UNWATCH(navigation_server, "map_changed"); CHECK_NE(navigation_server->map_get_closest_point(map, Vector3(0, 0, 0)), Vector3(0, 0, 0)); @@ -572,7 +572,7 @@ TEST_SUITE("[Navigation3D]") { navigation_server->free(region); navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. memdelete(mesh_instance); memdelete(node_3d); } @@ -644,7 +644,7 @@ TEST_SUITE("[Navigation3D]") { navigation_server->map_set_active(map, true); navigation_server->region_set_map(region, map); navigation_server->region_set_navigation_mesh(region, navigation_mesh); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. CHECK_EQ(navigation_mesh->get_polygon_count(), 0); CHECK_EQ(navigation_mesh->get_vertices().size(), 0); @@ -660,7 +660,7 @@ TEST_SUITE("[Navigation3D]") { SUBCASE("Map should emit signal and take newly baked navigation mesh into account") { SIGNAL_WATCH(navigation_server, "map_changed"); SIGNAL_CHECK_FALSE("map_changed"); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. SIGNAL_CHECK("map_changed", build_array(build_array(map))); SIGNAL_UNWATCH(navigation_server, "map_changed"); CHECK_NE(navigation_server->map_get_closest_point(map, Vector3(0, 0, 0)), Vector3(0, 0, 0)); @@ -668,7 +668,7 @@ TEST_SUITE("[Navigation3D]") { navigation_server->free(region); navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. memdelete(mesh_instance); memdelete(node_3d); } @@ -693,7 +693,7 @@ TEST_SUITE("[Navigation3D]") { navigation_server->map_set_use_async_iterations(map, false); navigation_server->region_set_map(region, map); navigation_server->region_set_navigation_mesh(region, navigation_mesh); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. SUBCASE("Simple queries should return non-default values") { CHECK_NE(navigation_server->map_get_closest_point(map, Vector3(0, 0, 0)), Vector3(0, 0, 0)); @@ -807,7 +807,7 @@ TEST_SUITE("[Navigation3D]") { navigation_server->free(region); navigation_server->free(map); - navigation_server->process(0.0); // Give server some cycles to commit. + navigation_server->physics_process(0.0); // Give server some cycles to commit. } // FIXME: The race condition mentioned below is actually a problem and fails on CI (GH-90613). From f1038fdd3bce614dbc70f6adc9895f936f8f7783 Mon Sep 17 00:00:00 2001 From: Thaddeus Crews Date: Tue, 1 Apr 2025 13:57:43 -0500 Subject: [PATCH 030/111] SCons: Add `CPPEXTPATH` for external includes --- SConstruct | 25 ++++++++++- core/SCsub | 16 +++---- core/crypto/SCsub | 2 +- drivers/backtrace/SCsub | 2 +- drivers/d3d12/SCsub | 14 +++---- drivers/d3d12/d3d12ma.cpp | 33 +-------------- .../d3d12/rendering_context_driver_d3d12.cpp | 22 +--------- .../d3d12/rendering_context_driver_d3d12.h | 24 +---------- .../d3d12/rendering_device_driver_d3d12.cpp | 39 ++--------------- drivers/d3d12/rendering_device_driver_d3d12.h | 26 +----------- drivers/gl_context/SCsub | 7 +--- drivers/metal/SCsub | 2 +- drivers/png/SCsub | 4 +- drivers/vulkan/SCsub | 4 +- modules/astcenc/SCsub | 2 +- modules/basis_universal/SCsub | 12 ++---- modules/csg/SCsub | 2 +- modules/cvtt/SCsub | 2 +- modules/enet/SCsub | 2 +- modules/etcpak/SCsub | 2 +- modules/fbx/SCsub | 2 +- modules/freetype/SCsub | 6 +-- modules/glslang/SCsub | 6 +-- modules/jolt_physics/SCsub | 2 +- modules/jpg/SCsub | 2 +- modules/ktx/SCsub | 12 +++--- modules/mbedtls/SCsub | 2 +- modules/minimp3/SCsub | 6 +-- modules/msdfgen/SCsub | 2 +- modules/navigation_2d/SCsub | 2 +- modules/navigation_3d/SCsub | 6 +-- modules/noise/SCsub | 2 +- modules/ogg/SCsub | 2 +- modules/openxr/SCsub | 4 +- modules/raycast/SCsub | 2 +- modules/regex/SCsub | 2 +- modules/svg/SCsub | 10 ++--- modules/text_server_adv/SCsub | 42 +++++++++---------- modules/text_server_adv/text_server_adv.cpp | 8 +--- modules/text_server_adv/text_server_adv.h | 9 ---- modules/text_server_fb/SCsub | 10 ++--- modules/text_server_fb/text_server_fb.cpp | 6 --- modules/theora/SCsub | 6 +-- modules/tinyexr/SCsub | 2 +- modules/upnp/SCsub | 4 +- modules/vhacd/SCsub | 2 +- modules/vorbis/SCsub | 4 +- modules/webp/SCsub | 2 +- modules/websocket/SCsub | 2 +- modules/xatlas_unwrap/SCsub | 2 +- platform/ios/detect.py | 2 +- platform/linuxbsd/detect.py | 8 ++-- platform/macos/detect.py | 4 +- platform/windows/detect.py | 4 +- servers/rendering/renderer_rd/effects/SCsub | 2 +- 55 files changed, 141 insertions(+), 290 deletions(-) diff --git a/SConstruct b/SConstruct index 0f337a6e3140..87d08bfd0b3e 100644 --- a/SConstruct +++ b/SConstruct @@ -15,6 +15,7 @@ from types import ModuleType from SCons import __version__ as scons_raw_version from SCons.Builder import ListEmitter +from SCons.Util import CLVar # Explicitly resolve the helper modules, this is done to avoid clash with # modules of the same name that might be randomly added (e.g. someone adding @@ -445,10 +446,19 @@ for tool in custom_tools: env.Tool(tool) -# add default include paths - +# Add default include paths. env.Prepend(CPPPATH=["#"]) +# Allow marking includes as external/system to avoid raising warnings. +env["_CCCOMCOM"] += " $_CPPEXTINCFLAGS" +env["CPPEXTPATH"] = CLVar("") +if env.scons_version < (4, 2): + env["_CPPEXTINCFLAGS"] = "${_concat(EXTINCPREFIX, CPPEXTPATH, EXTINCSUFFIX, __env__, RDirs, TARGET, SOURCE)}" +else: + env["_CPPEXTINCFLAGS"] = ( + "${_concat(EXTINCPREFIX, CPPEXTPATH, EXTINCSUFFIX, __env__, RDirs, TARGET, SOURCE, affect_signature=False)}" + ) + # configure ENV for platform env.platform_exporters = platform_exporters env.platform_apis = platform_apis @@ -912,6 +922,17 @@ else: # GCC, Clang if env["werror"]: env.Append(CCFLAGS=["-Werror"]) +# Configure external includes. +if env.msvc: + if cc_version_major < 16 or (cc_version_major == 16 and cc_version_minor < 10): + env.AppendUnique(CCFLAGS=["/experimental:external"]) + env.AppendUnique(CCFLAGS=["/external:W0"]) + env["EXTINCPREFIX"] = "/external:I" + env["EXTINCSUFFIX"] = "" +else: + env["EXTINCPREFIX"] = "-isystem " + env["EXTINCSUFFIX"] = "" + if hasattr(detect, "get_program_suffix"): suffix = "." + detect.get_program_suffix() else: diff --git a/core/SCsub b/core/SCsub index 778ae5ea7c30..a252a07404e3 100644 --- a/core/SCsub +++ b/core/SCsub @@ -51,8 +51,8 @@ if env["brotli"] and env["builtin_brotli"]: ] thirdparty_brotli_sources = [thirdparty_brotli_dir + file for file in thirdparty_brotli_sources] - env_thirdparty.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"]) - env.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"]) + env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_brotli_dir + "include"]) + env.Prepend(CPPEXTPATH=[thirdparty_brotli_dir + "include"]) if env.get("use_ubsan") or env.get("use_asan") or env.get("use_tsan") or env.get("use_lsan") or env.get("use_msan"): env_thirdparty.Append(CPPDEFINES=["BROTLI_BUILD_PORTABLE"]) @@ -69,8 +69,8 @@ if env["builtin_clipper2"]: ] thirdparty_clipper_sources = [thirdparty_clipper_dir + file for file in thirdparty_clipper_sources] - env_thirdparty.Prepend(CPPPATH=[thirdparty_clipper_dir + "include"]) - env.Prepend(CPPPATH=[thirdparty_clipper_dir + "include"]) + env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_clipper_dir + "include"]) + env.Prepend(CPPEXTPATH=[thirdparty_clipper_dir + "include"]) env_thirdparty.Append(CPPDEFINES=["CLIPPER2_ENABLED"]) env.Append(CPPDEFINES=["CLIPPER2_ENABLED"]) @@ -94,9 +94,9 @@ if env["builtin_zlib"]: ] thirdparty_zlib_sources = [thirdparty_zlib_dir + file for file in thirdparty_zlib_sources] - env_thirdparty.Prepend(CPPPATH=[thirdparty_zlib_dir]) + env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_zlib_dir]) # Needs to be available in main env too - env.Prepend(CPPPATH=[thirdparty_zlib_dir]) + env.Prepend(CPPEXTPATH=[thirdparty_zlib_dir]) if env.dev_build: env_thirdparty.Append(CPPDEFINES=["ZLIB_DEBUG"]) # Affects headers so it should also be defined for Godot code @@ -148,9 +148,9 @@ if env["builtin_zstd"]: thirdparty_zstd_sources.append("decompress/huf_decompress_amd64.S") thirdparty_zstd_sources = [thirdparty_zstd_dir + file for file in thirdparty_zstd_sources] - env_thirdparty.Prepend(CPPPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"]) + env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"]) env_thirdparty.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"]) - env.Prepend(CPPPATH=thirdparty_zstd_dir) + env.Prepend(CPPEXTPATH=thirdparty_zstd_dir) # Also needed in main env includes will trigger warnings env.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"]) diff --git a/core/crypto/SCsub b/core/crypto/SCsub index 3cea6bfb4711..d33d119fa3ee 100644 --- a/core/crypto/SCsub +++ b/core/crypto/SCsub @@ -13,7 +13,7 @@ if is_builtin or not has_module: # Use our headers for builtin or if the module is not going to be compiled. # We decided not to depend on system mbedtls just for these few files that can # be easily extracted. - env_crypto.Prepend(CPPPATH=["#thirdparty/mbedtls/include"]) + env_crypto.Prepend(CPPEXTPATH=["#thirdparty/mbedtls/include"]) # MbedTLS core functions (for CryptoCore). # If the mbedtls module is compiled we don't need to add the .c files with our diff --git a/drivers/backtrace/SCsub b/drivers/backtrace/SCsub index cc2cf0a6d8da..0d52f951dab6 100644 --- a/drivers/backtrace/SCsub +++ b/drivers/backtrace/SCsub @@ -26,7 +26,7 @@ thirdparty_sources = [ ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_backtrace.Prepend(CPPPATH=[thirdparty_dir]) +env_backtrace.Prepend(CPPEXTPATH=[thirdparty_dir]) env_thirdparty = env_backtrace.Clone() env_thirdparty.disable_warnings() diff --git a/drivers/d3d12/SCsub b/drivers/d3d12/SCsub index beeb13398e37..de9a16a16870 100644 --- a/drivers/d3d12/SCsub +++ b/drivers/d3d12/SCsub @@ -15,15 +15,15 @@ thirdparty_obj = [] # DirectX Headers (must take precedence over Windows SDK's). -env.Prepend(CPPPATH=["#thirdparty/directx_headers/include/directx"]) -env_d3d12_rdd.Prepend(CPPPATH=["#thirdparty/directx_headers/include/directx"]) -env_d3d12_rdd.Prepend(CPPPATH=["#thirdparty/directx_headers/include/dxguids"]) +env.Prepend(CPPEXTPATH=["#thirdparty/directx_headers/include/directx"]) +env_d3d12_rdd.Prepend(CPPEXTPATH=["#thirdparty/directx_headers/include/directx"]) +env_d3d12_rdd.Prepend(CPPEXTPATH=["#thirdparty/directx_headers/include/dxguids"]) # Direct3D 12 Memory Allocator. -env.Append(CPPPATH=["#thirdparty/d3d12ma"]) -env_d3d12_rdd.Append(CPPPATH=["#thirdparty/d3d12ma"]) +env.Append(CPPEXTPATH=["#thirdparty/d3d12ma"]) +env_d3d12_rdd.Append(CPPEXTPATH=["#thirdparty/d3d12ma"]) # Agility SDK. @@ -38,7 +38,7 @@ if env["agility_sdk_path"] != "" and os.path.exists(env["agility_sdk_path"]): if env["use_pix"]: env_d3d12_rdd.Append(CPPDEFINES=["PIX_ENABLED"]) - env_d3d12_rdd.Append(CPPPATH=[env["pix_path"] + "/Include"]) + env_d3d12_rdd.Append(CPPEXTPATH=[env["pix_path"] + "/Include"]) # Mesa (SPIR-V to DXIL functionality). @@ -147,7 +147,7 @@ else: env.Append(CCFLAGS=["-Wno-unknown-pragmas"]) # This is needed since rendering_device_d3d12.cpp needs to include some Mesa internals. -env_d3d12_rdd.Prepend(CPPPATH=mesa_private_inc_paths) +env_d3d12_rdd.Prepend(CPPEXTPATH=mesa_private_inc_paths) # For the same reason as above, the defines must be the same as in the 3rd-party code itself. env_d3d12_rdd.Append(CPPDEFINES=extra_defines) diff --git a/drivers/d3d12/d3d12ma.cpp b/drivers/d3d12/d3d12ma.cpp index fdec19f92aa3..27f67d66e8dd 100644 --- a/drivers/d3d12/d3d12ma.cpp +++ b/drivers/d3d12/d3d12ma.cpp @@ -30,35 +30,4 @@ #include "rendering_context_driver_d3d12.h" -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wshadow" -#pragma GCC diagnostic ignored "-Wswitch" -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#pragma GCC diagnostic ignored "-Wduplicated-branches" -#pragma GCC diagnostic ignored "-Wunused-variable" -#pragma GCC diagnostic ignored "-Wsign-compare" -#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" -#pragma GCC diagnostic ignored "-Wunused-function" -#pragma GCC diagnostic ignored "-Wnonnull-compare" -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#elif defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wstring-plus-int" -#pragma clang diagnostic ignored "-Wswitch" -#pragma clang diagnostic ignored "-Wmissing-field-initializers" -#pragma clang diagnostic ignored "-Wtautological-undefined-compare" -#pragma clang diagnostic ignored "-Wunused-variable" -#pragma clang diagnostic ignored "-Wunused-but-set-variable" -#pragma clang diagnostic ignored "-Wunused-function" -#pragma clang diagnostic ignored "-Wunused-private-field" -#pragma clang diagnostic ignored "-Wimplicit-fallthrough" -#endif - -#if defined(_MSC_VER) -#pragma warning(disable : 4189 4505) -#endif - -#include "thirdparty/d3d12ma/D3D12MemAlloc.cpp" +#include diff --git a/drivers/d3d12/rendering_context_driver_d3d12.cpp b/drivers/d3d12/rendering_context_driver_d3d12.cpp index 7081d1730f32..3d1adc0d5547 100644 --- a/drivers/d3d12/rendering_context_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_context_driver_d3d12.cpp @@ -37,27 +37,7 @@ #include "core/version.h" #include "servers/rendering/rendering_device.h" -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wshadow" -#pragma GCC diagnostic ignored "-Wswitch" -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#elif defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wstring-plus-int" -#pragma clang diagnostic ignored "-Wswitch" -#pragma clang diagnostic ignored "-Wmissing-field-initializers" -#endif - -#include "dxcapi.h" - -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#elif defined(__clang__) -#pragma clang diagnostic pop -#endif +#include #if !defined(_MSC_VER) #include diff --git a/drivers/d3d12/rendering_context_driver_d3d12.h b/drivers/d3d12/rendering_context_driver_d3d12.h index 7c09a086dd68..234517d9ec7c 100644 --- a/drivers/d3d12/rendering_context_driver_d3d12.h +++ b/drivers/d3d12/rendering_context_driver_d3d12.h @@ -37,22 +37,6 @@ #include "servers/display_server.h" #include "servers/rendering/rendering_context_driver.h" -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wshadow" -#pragma GCC diagnostic ignored "-Wswitch" -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" -#elif defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wstring-plus-int" -#pragma clang diagnostic ignored "-Wswitch" -#pragma clang diagnostic ignored "-Wmissing-field-initializers" -#pragma clang diagnostic ignored "-Wimplicit-fallthrough" -#endif - #if defined(AS) #undef AS #endif @@ -71,17 +55,11 @@ #include #endif -#include "d3dx12.h" +#include #include #include -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#elif defined(__clang__) -#pragma clang diagnostic pop -#endif - using Microsoft::WRL::ComPtr; #define ARRAY_SIZE(a) std::size(a) diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp index 9bfb9bc55d88..8081f1ca864d 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp @@ -39,44 +39,13 @@ #include "dxil_hash.h" #include "rendering_context_driver_d3d12.h" -// No point in fighting warnings in Mesa. -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable : 4200) // "nonstandard extension used: zero-sized array in struct/union". -#pragma warning(disable : 4806) // "'&': unsafe operation: no value of type 'bool' promoted to type 'uint32_t' can equal the given constant". -#endif - -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wshadow" -#pragma GCC diagnostic ignored "-Wswitch" -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#elif defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wstring-plus-int" -#pragma clang diagnostic ignored "-Wswitch" -#pragma clang diagnostic ignored "-Wmissing-field-initializers" -#endif - -#include "nir_spirv.h" -#include "nir_to_dxil.h" -#include "spirv_to_dxil.h" +#include +#include +#include extern "C" { -#include "dxil_spirv_nir.h" +#include } -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#elif defined(__clang__) -#pragma clang diagnostic pop -#endif - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - #if !defined(_MSC_VER) #include diff --git a/drivers/d3d12/rendering_device_driver_d3d12.h b/drivers/d3d12/rendering_device_driver_d3d12.h index 2d279ffab02b..bc5ccc012350 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.h +++ b/drivers/d3d12/rendering_device_driver_d3d12.h @@ -40,26 +40,10 @@ #define __REQUIRED_RPCNDR_H_VERSION__ 475 #endif -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wshadow" -#pragma GCC diagnostic ignored "-Wswitch" -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" -#elif defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wstring-plus-int" -#pragma clang diagnostic ignored "-Wswitch" -#pragma clang diagnostic ignored "-Wmissing-field-initializers" -#pragma clang diagnostic ignored "-Wimplicit-fallthrough" -#endif - -#include "d3dx12.h" +#include #include #define D3D12MA_D3D12_HEADERS_ALREADY_INCLUDED -#include "D3D12MemAlloc.h" +#include #include @@ -68,12 +52,6 @@ #undef MemoryBarrier #endif -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#elif defined(__clang__) -#pragma clang diagnostic pop -#endif - using Microsoft::WRL::ComPtr; #define D3D12_BITCODE_OFFSETS_NUM_STAGES 3 diff --git a/drivers/gl_context/SCsub b/drivers/gl_context/SCsub index a2ba425990de..92b32d36be14 100644 --- a/drivers/gl_context/SCsub +++ b/drivers/gl_context/SCsub @@ -13,12 +13,7 @@ if env["platform"] in ["macos", "windows", "linuxbsd"]: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - # Treat glad headers as system headers to avoid raising warnings. Not supported on MSVC. - if not env.msvc: - env.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path]) - else: - env.Prepend(CPPPATH=[thirdparty_dir]) - + env.Prepend(CPPEXTPATH=[thirdparty_dir]) env.Append(CPPDEFINES=["GLAD_ENABLED"]) env.Append(CPPDEFINES=["EGL_ENABLED"]) diff --git a/drivers/metal/SCsub b/drivers/metal/SCsub index f597580763e4..ced6dfbbfdcf 100644 --- a/drivers/metal/SCsub +++ b/drivers/metal/SCsub @@ -22,7 +22,7 @@ thirdparty_sources = [ ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_metal.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "/include"]) +env_metal.Prepend(CPPEXTPATH=[thirdparty_dir, thirdparty_dir + "/include"]) # Must enable exceptions for SPIRV-Cross; otherwise, it will abort the process on errors. if "-fno-exceptions" in env_metal["CXXFLAGS"]: diff --git a/drivers/png/SCsub b/drivers/png/SCsub index 4d9e61dec6b7..9d3b3effb8d0 100644 --- a/drivers/png/SCsub +++ b/drivers/png/SCsub @@ -30,9 +30,9 @@ if env["builtin_libpng"]: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_png.Prepend(CPPPATH=[thirdparty_dir]) + env_png.Prepend(CPPEXTPATH=[thirdparty_dir]) # Needed for drivers includes and in platform/web. - env.Prepend(CPPPATH=[thirdparty_dir]) + env.Prepend(CPPEXTPATH=[thirdparty_dir]) env_thirdparty = env_png.Clone() env_thirdparty.disable_warnings() diff --git a/drivers/vulkan/SCsub b/drivers/vulkan/SCsub index 6ea7cc9a3b92..6751e63821a0 100644 --- a/drivers/vulkan/SCsub +++ b/drivers/vulkan/SCsub @@ -8,11 +8,11 @@ thirdparty_dir = "#thirdparty/vulkan" thirdparty_volk_dir = "#thirdparty/volk" # Use bundled Vulkan headers -env.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "/include"]) +env.Prepend(CPPEXTPATH=[thirdparty_dir, thirdparty_dir + "/include"]) if env["use_volk"]: env.AppendUnique(CPPDEFINES=["USE_VOLK"]) - env.Prepend(CPPPATH=[thirdparty_volk_dir]) + env.Prepend(CPPEXTPATH=[thirdparty_volk_dir]) if env["platform"] == "android": env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_ANDROID_KHR"]) diff --git a/modules/astcenc/SCsub b/modules/astcenc/SCsub index bb8bc8d86778..12c660faa896 100644 --- a/modules/astcenc/SCsub +++ b/modules/astcenc/SCsub @@ -37,7 +37,7 @@ thirdparty_sources = [ ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_astcenc.Prepend(CPPPATH=[thirdparty_dir]) +env_astcenc.Prepend(CPPEXTPATH=[thirdparty_dir]) env_thirdparty = env_astcenc.Clone() env_thirdparty.disable_warnings() diff --git a/modules/basis_universal/SCsub b/modules/basis_universal/SCsub index b8cce67f897b..f58554bb52b6 100644 --- a/modules/basis_universal/SCsub +++ b/modules/basis_universal/SCsub @@ -42,18 +42,14 @@ if basisu_encoder: transcoder_sources = [thirdparty_dir + "transcoder/basisu_transcoder.cpp"] -# Treat Basis headers as system headers to avoid raising warnings. Not supported on MSVC. -if not env.msvc: - env_basisu.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path]) -else: - env_basisu.Prepend(CPPPATH=[thirdparty_dir]) +env_basisu.Prepend(CPPEXTPATH=[thirdparty_dir]) if basisu_encoder: - env_basisu.Prepend(CPPPATH=["#thirdparty/jpeg-compressor"]) - env_basisu.Prepend(CPPPATH=["#thirdparty/tinyexr"]) + env_basisu.Prepend(CPPEXTPATH=["#thirdparty/jpeg-compressor"]) + env_basisu.Prepend(CPPEXTPATH=["#thirdparty/tinyexr"]) if env["builtin_zstd"]: - env_basisu.Prepend(CPPPATH=["#thirdparty/zstd"]) + env_basisu.Prepend(CPPEXTPATH=["#thirdparty/zstd"]) env_thirdparty = env_basisu.Clone() env_thirdparty.disable_warnings() diff --git a/modules/csg/SCsub b/modules/csg/SCsub index 5b880f155e7a..32bc240a8283 100644 --- a/modules/csg/SCsub +++ b/modules/csg/SCsub @@ -31,7 +31,7 @@ thirdparty_sources = [ ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_csg.Prepend(CPPPATH=[thirdparty_dir + "include"]) +env_csg.Prepend(CPPEXTPATH=[thirdparty_dir + "include"]) env_thirdparty = env_csg.Clone() env_thirdparty.disable_warnings() env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources) diff --git a/modules/cvtt/SCsub b/modules/cvtt/SCsub index 44e56ab6a770..8b58dcd9c484 100644 --- a/modules/cvtt/SCsub +++ b/modules/cvtt/SCsub @@ -26,7 +26,7 @@ thirdparty_sources = [ thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_cvtt.Prepend(CPPPATH=[thirdparty_dir]) +env_cvtt.Prepend(CPPEXTPATH=[thirdparty_dir]) env_thirdparty = env_cvtt.Clone() env_thirdparty.disable_warnings() diff --git a/modules/enet/SCsub b/modules/enet/SCsub index af64f2be82a0..1855281dd319 100644 --- a/modules/enet/SCsub +++ b/modules/enet/SCsub @@ -24,7 +24,7 @@ if env["builtin_enet"]: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_enet.Prepend(CPPPATH=[thirdparty_dir]) + env_enet.Prepend(CPPEXTPATH=[thirdparty_dir]) env_enet.Append(CPPDEFINES=["GODOT_ENET"]) env_thirdparty = env_enet.Clone() diff --git a/modules/etcpak/SCsub b/modules/etcpak/SCsub index e6ecb2bc83f8..0d8d7c4c3ad4 100644 --- a/modules/etcpak/SCsub +++ b/modules/etcpak/SCsub @@ -20,7 +20,7 @@ thirdparty_sources = [ ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_etcpak.Prepend(CPPPATH=[thirdparty_dir]) +env_etcpak.Prepend(CPPEXTPATH=[thirdparty_dir]) env_thirdparty = env_etcpak.Clone() env_thirdparty.disable_warnings() diff --git a/modules/fbx/SCsub b/modules/fbx/SCsub index 6f9fbba0b468..05a15c3be293 100644 --- a/modules/fbx/SCsub +++ b/modules/fbx/SCsub @@ -13,7 +13,7 @@ thirdparty_obj = [] thirdparty_dir = "#thirdparty/ufbx/" thirdparty_sources = [thirdparty_dir + "ufbx.c"] -env_fbx.Prepend(CPPPATH=[thirdparty_dir]) +env_fbx.Prepend(CPPEXTPATH=[thirdparty_dir]) env_thirdparty = env_fbx.Clone() env_thirdparty.disable_warnings() diff --git a/modules/freetype/SCsub b/modules/freetype/SCsub index dc46513a3faa..0a52ef46c55c 100644 --- a/modules/freetype/SCsub +++ b/modules/freetype/SCsub @@ -62,15 +62,15 @@ if env["builtin_freetype"]: if env["brotli"]: env_freetype.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"]) - env_freetype.Prepend(CPPPATH=[thirdparty_dir + "/include"]) + env_freetype.Prepend(CPPEXTPATH=[thirdparty_dir + "/include"]) # Also needed in main env for scene/ - env.Prepend(CPPPATH=[thirdparty_dir + "/include"]) + env.Prepend(CPPEXTPATH=[thirdparty_dir + "/include"]) env_freetype.Append(CPPDEFINES=["FT2_BUILD_LIBRARY", "FT_CONFIG_OPTION_USE_PNG", "FT_CONFIG_OPTION_SYSTEM_ZLIB"]) # Also requires libpng headers if env["builtin_libpng"]: - env_freetype.Prepend(CPPPATH=["#thirdparty/libpng"]) + env_freetype.Prepend(CPPEXTPATH=["#thirdparty/libpng"]) sfnt = thirdparty_dir + "src/sfnt/sfnt.c" # Must be done after all CPPDEFINES are being set so we can copy them. diff --git a/modules/glslang/SCsub b/modules/glslang/SCsub index b6e3da2316c4..4b1f0177ae35 100644 --- a/modules/glslang/SCsub +++ b/modules/glslang/SCsub @@ -62,13 +62,9 @@ if env["builtin_glslang"]: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - # Treat glslang headers as system headers to avoid raising warnings. Not supported on MSVC. # Include `#thirdparty` to workaround mismatch between location of `SPIRV` in library source # and in installed public headers. - if not env.msvc: - env_glslang.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path, "-isystem", Dir("#thirdparty").path]) - else: - env_glslang.Prepend(CPPPATH=[thirdparty_dir, "#thirdparty"]) + env_glslang.Prepend(CPPEXTPATH=[thirdparty_dir, "#thirdparty"]) env_glslang.Append(CPPDEFINES=["ENABLE_OPT=0"]) diff --git a/modules/jolt_physics/SCsub b/modules/jolt_physics/SCsub index d4b02ec41dec..cd84c0ef0bde 100644 --- a/modules/jolt_physics/SCsub +++ b/modules/jolt_physics/SCsub @@ -144,7 +144,7 @@ thirdparty_sources = [ thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_jolt.Prepend(CPPPATH=[thirdparty_dir]) +env_jolt.Prepend(CPPEXTPATH=[thirdparty_dir]) if env.dev_build: env_jolt.Append(CPPDEFINES=["JPH_ENABLE_ASSERTS"]) diff --git a/modules/jpg/SCsub b/modules/jpg/SCsub index 2d948d335540..fbc69a86fd76 100644 --- a/modules/jpg/SCsub +++ b/modules/jpg/SCsub @@ -18,7 +18,7 @@ thirdparty_sources = [ ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_jpg.Prepend(CPPPATH=[thirdparty_dir]) +env_jpg.Prepend(CPPEXTPATH=[thirdparty_dir]) env_thirdparty = env_jpg.Clone() env_thirdparty.disable_warnings() diff --git a/modules/ktx/SCsub b/modules/ktx/SCsub index f4c394d7345e..df994bf38e8f 100644 --- a/modules/ktx/SCsub +++ b/modules/ktx/SCsub @@ -33,18 +33,18 @@ thirdparty_sources = [ ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_ktx.Prepend(CPPPATH=[thirdparty_dir + "include"]) -env_ktx.Prepend(CPPPATH=[thirdparty_dir + "utils"]) -env_ktx.Prepend(CPPPATH=[thirdparty_dir + "lib"]) -env_ktx.Prepend(CPPPATH=[thirdparty_dir + "other_include"]) +env_ktx.Prepend(CPPEXTPATH=[thirdparty_dir + "include"]) +env_ktx.Prepend(CPPEXTPATH=[thirdparty_dir + "utils"]) +env_ktx.Prepend(CPPEXTPATH=[thirdparty_dir + "lib"]) +env_ktx.Prepend(CPPEXTPATH=[thirdparty_dir + "other_include"]) -env_ktx.Prepend(CPPPATH=["#thirdparty/basis_universal"]) +env_ktx.Prepend(CPPEXTPATH=["#thirdparty/basis_universal"]) if env.editor_build: # We already build miniz in the basis_universal module (editor only). env_ktx.Append(CPPDEFINES=["MINIZ_HEADER_FILE_ONLY"]) if env["vulkan"]: - env_ktx.Prepend(CPPPATH=["#thirdparty/vulkan/include"]) + env_ktx.Prepend(CPPEXTPATH=["#thirdparty/vulkan/include"]) else: # Falls back on bundled `vkformat_enum.h`. env_ktx.Append(CPPDEFINES=["LIBKTX"]) diff --git a/modules/mbedtls/SCsub b/modules/mbedtls/SCsub index 6183fa594437..1db5375163bc 100644 --- a/modules/mbedtls/SCsub +++ b/modules/mbedtls/SCsub @@ -120,7 +120,7 @@ if env["builtin_mbedtls"]: thirdparty_dir = "#thirdparty/mbedtls/library/" thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_mbed_tls.Prepend(CPPPATH=["#thirdparty/mbedtls/include/"]) + env_mbed_tls.Prepend(CPPEXTPATH=["#thirdparty/mbedtls/include/"]) config_path = "thirdparty/mbedtls/include/godot_module_mbedtls_config.h" config_path = f"<{config_path}>" if env_mbed_tls["ninja"] and env_mbed_tls.msvc else f'\\"{config_path}\\"' env_mbed_tls.Append(CPPDEFINES=[("MBEDTLS_CONFIG_FILE", config_path)]) diff --git a/modules/minimp3/SCsub b/modules/minimp3/SCsub index e9491bb72ff2..888f5e535693 100644 --- a/modules/minimp3/SCsub +++ b/modules/minimp3/SCsub @@ -8,11 +8,7 @@ env_minimp3 = env_modules.Clone() thirdparty_dir = "#thirdparty/minimp3/" -# Treat minimp3 headers as system headers to avoid raising warnings. Not supported on MSVC. -if not env.msvc: - env_minimp3.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path]) -else: - env_minimp3.Prepend(CPPPATH=[thirdparty_dir]) +env_minimp3.Prepend(CPPEXTPATH=[thirdparty_dir]) if not env["minimp3_extra_formats"]: env_minimp3.Append(CPPDEFINES=["MINIMP3_ONLY_MP3"]) diff --git a/modules/msdfgen/SCsub b/modules/msdfgen/SCsub index 55c1394e302f..391b99e12f55 100644 --- a/modules/msdfgen/SCsub +++ b/modules/msdfgen/SCsub @@ -42,7 +42,7 @@ if env["builtin_msdfgen"]: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] env_msdfgen.Append(CPPDEFINES=[("MSDFGEN_PUBLIC", "")]) - env_msdfgen.Prepend(CPPPATH=["#thirdparty/freetype/include", "#thirdparty/msdfgen", "#thirdparty/nanosvg"]) + env_msdfgen.Prepend(CPPEXTPATH=["#thirdparty/freetype/include", "#thirdparty/msdfgen", "#thirdparty/nanosvg"]) lib = env_msdfgen.add_library("msdfgen_builtin", thirdparty_sources) thirdparty_obj += lib diff --git a/modules/navigation_2d/SCsub b/modules/navigation_2d/SCsub index e3192f9e39ee..3babb118bbd4 100644 --- a/modules/navigation_2d/SCsub +++ b/modules/navigation_2d/SCsub @@ -21,7 +21,7 @@ if env["builtin_rvo2_2d"]: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_navigation_2d.Prepend(CPPPATH=[thirdparty_dir]) + env_navigation_2d.Prepend(CPPEXTPATH=[thirdparty_dir]) env_thirdparty = env_navigation_2d.Clone() env_thirdparty.disable_warnings() diff --git a/modules/navigation_3d/SCsub b/modules/navigation_3d/SCsub index 657b71439860..d20a8294a0e4 100644 --- a/modules/navigation_3d/SCsub +++ b/modules/navigation_3d/SCsub @@ -29,7 +29,7 @@ if env["builtin_recastnavigation"]: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_navigation_3d.Prepend(CPPPATH=[thirdparty_dir + "Include"]) + env_navigation_3d.Prepend(CPPEXTPATH=[thirdparty_dir + "Include"]) env_thirdparty = env_navigation_3d.Clone() env_thirdparty.disable_warnings() @@ -46,7 +46,7 @@ if env["builtin_rvo2_2d"]: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_navigation_3d.Prepend(CPPPATH=[thirdparty_dir]) + env_navigation_3d.Prepend(CPPEXTPATH=[thirdparty_dir]) # Don't build rvo_2d if 2D navigation is enabled. if not navigation_2d_enabled: @@ -64,7 +64,7 @@ if env["builtin_rvo2_3d"]: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_navigation_3d.Prepend(CPPPATH=[thirdparty_dir]) + env_navigation_3d.Prepend(CPPEXTPATH=[thirdparty_dir]) env_thirdparty = env_navigation_3d.Clone() env_thirdparty.disable_warnings() diff --git a/modules/noise/SCsub b/modules/noise/SCsub index de994e60a80b..1ef2d955c97a 100644 --- a/modules/noise/SCsub +++ b/modules/noise/SCsub @@ -7,7 +7,7 @@ Import("env_modules") env_noise = env_modules.Clone() thirdparty_dir = "#thirdparty/noise/" -env_noise.Prepend(CPPPATH=[thirdparty_dir]) +env_noise.Prepend(CPPEXTPATH=[thirdparty_dir]) # Godot source files diff --git a/modules/ogg/SCsub b/modules/ogg/SCsub index fabd4f936ac6..21298a6ab8f3 100644 --- a/modules/ogg/SCsub +++ b/modules/ogg/SCsub @@ -18,7 +18,7 @@ if env["builtin_libogg"]: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_ogg.Prepend(CPPPATH=[thirdparty_dir]) + env_ogg.Prepend(CPPEXTPATH=[thirdparty_dir]) env_thirdparty = env_ogg.Clone() env_thirdparty.disable_warnings() diff --git a/modules/openxr/SCsub b/modules/openxr/SCsub index edfe0bbfad6f..b83ad582d736 100644 --- a/modules/openxr/SCsub +++ b/modules/openxr/SCsub @@ -49,7 +49,7 @@ if env["builtin_openxr"]: thirdparty_dir = "#thirdparty/openxr" env_openxr.Prepend( - CPPPATH=[ + CPPEXTPATH=[ thirdparty_dir, thirdparty_dir + "/include", thirdparty_dir + "/src", @@ -65,7 +65,7 @@ if env["builtin_openxr"]: if env["disable_exceptions"]: env_thirdparty.AppendUnique(CPPDEFINES=["XRLOADER_DISABLE_EXCEPTION_HANDLING", ("JSON_USE_EXCEPTION", 0)]) - env_thirdparty.Append(CPPPATH=[thirdparty_dir + "/src/loader"]) + env_thirdparty.Append(CPPEXTPATH=[thirdparty_dir + "/src/loader"]) # add in external jsoncpp dependency thirdparty_jsoncpp_dir = thirdparty_dir + "/src/external/jsoncpp/src/lib_json/" diff --git a/modules/raycast/SCsub b/modules/raycast/SCsub index b2e86382b28a..46e1c3292af3 100644 --- a/modules/raycast/SCsub +++ b/modules/raycast/SCsub @@ -62,7 +62,7 @@ if env["builtin_embree"]: thirdparty_sources = [thirdparty_dir + file for file in embree_src] - env_raycast.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "include"]) + env_raycast.Prepend(CPPEXTPATH=[thirdparty_dir, thirdparty_dir + "include"]) env_raycast.Append(CPPDEFINES=["EMBREE_TARGET_SSE2", "EMBREE_LOWEST_ISA", "TASKING_INTERNAL"]) env_raycast.AppendUnique(CPPDEFINES=["NDEBUG"]) # No assert() even in debug builds. diff --git a/modules/regex/SCsub b/modules/regex/SCsub index 49aa0a9fc829..979995ef5135 100644 --- a/modules/regex/SCsub +++ b/modules/regex/SCsub @@ -53,7 +53,7 @@ if env["builtin_pcre2"]: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_regex.Prepend(CPPPATH=[thirdparty_dir]) + env_regex.Prepend(CPPEXTPATH=[thirdparty_dir]) env_regex.Append(CPPDEFINES=thirdparty_flags) def pcre2_builtin(width): diff --git a/modules/svg/SCsub b/modules/svg/SCsub index 696e1649489d..aa7f6a2263b2 100644 --- a/modules/svg/SCsub +++ b/modules/svg/SCsub @@ -65,7 +65,7 @@ if env["module_webp_enabled"]: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_svg.Prepend(CPPPATH=[thirdparty_dir + "inc"]) +env_svg.Prepend(CPPEXTPATH=[thirdparty_dir + "inc"]) # Enable ThorVG static object linking. env_svg.Append(CPPDEFINES=["TVG_STATIC"]) @@ -75,7 +75,7 @@ env_svg.Append(CPPDEFINES=["THORVG_FILE_IO_SUPPORT"]) env_thirdparty = env_svg.Clone() env_thirdparty.disable_warnings() env_thirdparty.Prepend( - CPPPATH=[ + CPPEXTPATH=[ thirdparty_dir + "src/common", thirdparty_dir + "src/loaders/svg", thirdparty_dir + "src/renderer", @@ -86,11 +86,11 @@ env_thirdparty.Prepend( ] ) if env["builtin_libpng"]: - env_thirdparty.Prepend(CPPPATH=["#thirdparty/libpng"]) + env_thirdparty.Prepend(CPPEXTPATH=["#thirdparty/libpng"]) if env["module_webp_enabled"]: - env_thirdparty.Prepend(CPPPATH=[thirdparty_dir + "src/loaders/external_webp"]) + env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_dir + "src/loaders/external_webp"]) if env["builtin_libwebp"]: - env_thirdparty.Prepend(CPPPATH=["#thirdparty/libwebp/src"]) + env_thirdparty.Prepend(CPPEXTPATH=["#thirdparty/libwebp/src"]) env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources) env.modules_sources += thirdparty_obj diff --git a/modules/text_server_adv/SCsub b/modules/text_server_adv/SCsub index 5bb753e92033..71e1c6141415 100644 --- a/modules/text_server_adv/SCsub +++ b/modules/text_server_adv/SCsub @@ -35,7 +35,7 @@ msdfgen_enabled = "msdfgen" in env.module_list if "svg" in env.module_list: env_text_server_adv.Prepend( - CPPPATH=[ + CPPEXTPATH=[ "#thirdparty/thorvg/inc", "#thirdparty/thorvg/src/common", "#thirdparty/thorvg/src/renderer", @@ -135,11 +135,11 @@ if env["builtin_harfbuzz"]: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_harfbuzz.Prepend(CPPPATH=["#thirdparty/harfbuzz/src"]) + env_harfbuzz.Prepend(CPPEXTPATH=["#thirdparty/harfbuzz/src"]) env_harfbuzz.Append(CCFLAGS=["-DHAVE_ICU"]) if env["builtin_icu4c"]: - env_harfbuzz.Prepend(CPPPATH=["#thirdparty/icu4c/common/", "#thirdparty/icu4c/i18n/"]) + env_harfbuzz.Prepend(CPPEXTPATH=["#thirdparty/icu4c/common/", "#thirdparty/icu4c/i18n/"]) env_harfbuzz.Append( CCFLAGS=[ "-DU_STATIC_IMPLEMENTATION", @@ -162,15 +162,15 @@ if env["builtin_harfbuzz"]: ] ) if env["builtin_freetype"]: - env_harfbuzz.Prepend(CPPPATH=["#thirdparty/freetype/include"]) + env_harfbuzz.Prepend(CPPEXTPATH=["#thirdparty/freetype/include"]) if env["builtin_graphite"] and env["graphite"]: - env_harfbuzz.Prepend(CPPPATH=["#thirdparty/graphite/include"]) + env_harfbuzz.Prepend(CPPEXTPATH=["#thirdparty/graphite/include"]) env_harfbuzz.Append(CCFLAGS=["-DGRAPHITE2_STATIC"]) if env["platform"] in ["android", "linuxbsd", "web"]: env_harfbuzz.Append(CCFLAGS=["-DHAVE_PTHREAD"]) - env_text_server_adv.Prepend(CPPPATH=["#thirdparty/harfbuzz/src"]) + env_text_server_adv.Prepend(CPPEXTPATH=["#thirdparty/harfbuzz/src"]) lib = env_harfbuzz.add_library("harfbuzz_builtin", thirdparty_sources) thirdparty_obj += lib @@ -233,7 +233,7 @@ if env["builtin_graphite"] and freetype_enabled and env["graphite"]: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_graphite.Prepend(CPPPATH=["#thirdparty/graphite/src", "#thirdparty/graphite/include"]) + env_graphite.Prepend(CPPEXTPATH=["#thirdparty/graphite/src", "#thirdparty/graphite/include"]) env_graphite.Append( CCFLAGS=[ "-DGRAPHITE2_STATIC", @@ -473,15 +473,10 @@ if env["builtin_icu4c"]: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - if env.editor_build: - env_icu.CommandNoCache( - "#thirdparty/icu4c/icudata.gen.h", "#thirdparty/icu4c/icudt_godot.dat", env.Run(make_icu_data) - ) - env_text_server_adv.Prepend(CPPPATH=["#thirdparty/icu4c/"]) - else: + if not env.editor_build: thirdparty_sources += ["icu_data/icudata_stub.cpp"] - env_icu.Prepend(CPPPATH=["#thirdparty/icu4c/common/", "#thirdparty/icu4c/i18n/"]) + env_icu.Prepend(CPPEXTPATH=["#thirdparty/icu4c/common/", "#thirdparty/icu4c/i18n/"]) env_icu.Append( CXXFLAGS=[ "-DU_STATIC_IMPLEMENTATION", @@ -510,11 +505,18 @@ if env["builtin_icu4c"]: if env.editor_build: env_text_server_adv.Append(CXXFLAGS=["-DICU_STATIC_DATA"]) - env_text_server_adv.Prepend(CPPPATH=["#thirdparty/icu4c/common/", "#thirdparty/icu4c/i18n/"]) + env_text_server_adv.Prepend(CPPEXTPATH=["#thirdparty/icu4c/common/", "#thirdparty/icu4c/i18n/"]) lib = env_icu.add_library("icu_builtin", thirdparty_sources) thirdparty_obj += lib + if env.editor_build: + icudata = env_icu.CommandNoCache( + "#thirdparty/icu4c/icudata.gen.h", "#thirdparty/icu4c/icudt_godot.dat", env.Run(make_icu_data) + ) + env_text_server_adv.Prepend(CPPEXTPATH=["#thirdparty/icu4c/"]) + env_icu.Depends(lib, icudata) + # Needs to be appended to arrive after libscene in the linker call, # but we don't want it to arrive *after* system libs, so manual hack # LIBS contains first SCons Library objects ("SCons.Node.FS.File object") @@ -534,19 +536,15 @@ if env["builtin_icu4c"]: module_obj = [] if env["builtin_msdfgen"] and msdfgen_enabled: - # Treat msdfgen headers as system headers to avoid raising warnings. Not supported on MSVC. env_text_server_adv.Append(CPPDEFINES=[("MSDFGEN_PUBLIC", "")]) - if not env.msvc: - env_text_server_adv.Append(CPPFLAGS=["-isystem", Dir("#thirdparty/msdfgen").path]) - else: - env_text_server_adv.Prepend(CPPPATH=["#thirdparty/msdfgen"]) + env_text_server_adv.Prepend(CPPEXTPATH=["#thirdparty/msdfgen"]) if env["builtin_freetype"] and freetype_enabled: env_text_server_adv.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"]) - env_text_server_adv.Prepend(CPPPATH=["#thirdparty/freetype/include"]) + env_text_server_adv.Prepend(CPPEXTPATH=["#thirdparty/freetype/include"]) if env["builtin_graphite"] and freetype_enabled and env["graphite"]: - env_text_server_adv.Prepend(CPPPATH=["#thirdparty/graphite/include"]) + env_text_server_adv.Prepend(CPPEXTPATH=["#thirdparty/graphite/include"]) env_text_server_adv.add_source_files(module_obj, "*.cpp") env.modules_sources += module_obj diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 8a06293fcdfa..e229af0418f2 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -60,23 +60,17 @@ using namespace godot; // Built-in ICU data. #ifdef ICU_STATIC_DATA -#include "icudata.gen.h" +#include #endif // Thirdparty headers. #ifdef MODULE_MSDFGEN_ENABLED -#ifdef _MSC_VER -#pragma warning(disable : 4458) -#endif #include #include #include #include #include -#ifdef _MSC_VER -#pragma warning(default : 4458) -#endif #endif #ifdef MODULE_SVG_ENABLED diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index a7c1e40d5502..2c2b52bc34d2 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -94,11 +94,6 @@ using namespace godot; // Thirdparty headers. -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wshadow" -#endif - #include #include #include @@ -112,10 +107,6 @@ using namespace godot; #include #include -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif - #ifdef MODULE_FREETYPE_ENABLED #include #include FT_FREETYPE_H diff --git a/modules/text_server_fb/SCsub b/modules/text_server_fb/SCsub index b56df192c256..50c6abf5b489 100644 --- a/modules/text_server_fb/SCsub +++ b/modules/text_server_fb/SCsub @@ -11,21 +11,17 @@ env_text_server_fb = env_modules.Clone() if "svg" in env.module_list: env_text_server_fb.Prepend( - CPPPATH=["#thirdparty/thorvg/inc", "#thirdparty/thorvg/src/common", "#thirdparty/thorvg/src/renderer"] + CPPEXTPATH=["#thirdparty/thorvg/inc", "#thirdparty/thorvg/src/common", "#thirdparty/thorvg/src/renderer"] ) # Enable ThorVG static object linking. env_text_server_fb.Append(CPPDEFINES=["TVG_STATIC"]) if env["builtin_msdfgen"] and msdfgen_enabled: - # Treat msdfgen headers as system headers to avoid raising warnings. Not supported on MSVC. env_text_server_fb.Append(CPPDEFINES=[("MSDFGEN_PUBLIC", "")]) - if not env.msvc: - env_text_server_fb.Append(CPPFLAGS=["-isystem", Dir("#thirdparty/msdfgen").path]) - else: - env_text_server_fb.Prepend(CPPPATH=["#thirdparty/msdfgen"]) + env_text_server_fb.Prepend(CPPEXTPATH=["#thirdparty/msdfgen"]) if env["builtin_freetype"] and freetype_enabled: env_text_server_fb.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"]) - env_text_server_fb.Prepend(CPPPATH=["#thirdparty/freetype/include"]) + env_text_server_fb.Prepend(CPPEXTPATH=["#thirdparty/freetype/include"]) env_text_server_fb.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 0f6d877af4ae..7e31ae17c8c6 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -61,17 +61,11 @@ using namespace godot; // Thirdparty headers. #ifdef MODULE_MSDFGEN_ENABLED -#ifdef _MSC_VER -#pragma warning(disable : 4458) -#endif #include #include #include #include #include -#ifdef _MSC_VER -#pragma warning(default : 4458) -#endif #endif #ifdef MODULE_FREETYPE_ENABLED diff --git a/modules/theora/SCsub b/modules/theora/SCsub index be557c1c24c9..c601435800fb 100644 --- a/modules/theora/SCsub +++ b/modules/theora/SCsub @@ -79,13 +79,13 @@ if env["builtin_libtheora"]: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_theora.Prepend(CPPPATH=[thirdparty_dir]) + env_theora.Prepend(CPPEXTPATH=[thirdparty_dir]) # also requires libogg and libvorbis if env["builtin_libogg"]: - env_theora.Prepend(CPPPATH=["#thirdparty/libogg"]) + env_theora.Prepend(CPPEXTPATH=["#thirdparty/libogg"]) if env["builtin_libvorbis"]: - env_theora.Prepend(CPPPATH=["#thirdparty/libvorbis"]) + env_theora.Prepend(CPPEXTPATH=["#thirdparty/libvorbis"]) env_thirdparty = env_theora.Clone() env_thirdparty.disable_warnings() diff --git a/modules/tinyexr/SCsub b/modules/tinyexr/SCsub index 434e99bf84de..0f22e36cabe8 100644 --- a/modules/tinyexr/SCsub +++ b/modules/tinyexr/SCsub @@ -17,7 +17,7 @@ thirdparty_sources = [ ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_tinyexr.Prepend(CPPPATH=[thirdparty_dir]) +env_tinyexr.Prepend(CPPEXTPATH=[thirdparty_dir]) # Enable threaded loading with C++11. env_tinyexr.Append(CPPDEFINES=["TINYEXR_USE_THREAD"]) diff --git a/modules/upnp/SCsub b/modules/upnp/SCsub index 98a13dbf6efb..44e007a19bda 100644 --- a/modules/upnp/SCsub +++ b/modules/upnp/SCsub @@ -29,13 +29,13 @@ if env["builtin_miniupnpc"] and env["platform"] != "web": ] thirdparty_sources = [thirdparty_dir + "src/" + file for file in thirdparty_sources] - env_upnp.Prepend(CPPPATH=[thirdparty_dir + "include"]) + env_upnp.Prepend(CPPEXTPATH=[thirdparty_dir + "include"]) env_upnp.Append(CPPDEFINES=["MINIUPNP_STATICLIB"]) if env["platform"] != "windows": env_upnp.Append(CPPDEFINES=["MINIUPNPC_SET_SOCKET_TIMEOUT"]) env_thirdparty = env_upnp.Clone() - env_thirdparty.Prepend(CPPPATH=[thirdparty_dir + "include/miniupnpc"]) + env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_dir + "include/miniupnpc"]) env_thirdparty.disable_warnings() env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources) env.modules_sources += thirdparty_obj diff --git a/modules/vhacd/SCsub b/modules/vhacd/SCsub index 926cc5b16f41..1703b96bbf0e 100644 --- a/modules/vhacd/SCsub +++ b/modules/vhacd/SCsub @@ -27,7 +27,7 @@ thirdparty_sources = [ thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_vhacd.Prepend(CPPPATH=[thirdparty_dir + "inc"]) +env_vhacd.Prepend(CPPEXTPATH=[thirdparty_dir + "inc"]) env_thirdparty = env_vhacd.Clone() env_thirdparty.disable_warnings() diff --git a/modules/vorbis/SCsub b/modules/vorbis/SCsub index f063d97fee75..82830e3b2a60 100644 --- a/modules/vorbis/SCsub +++ b/modules/vorbis/SCsub @@ -42,11 +42,11 @@ if env["builtin_libvorbis"]: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_vorbis.Prepend(CPPPATH=[thirdparty_dir]) + env_vorbis.Prepend(CPPEXTPATH=[thirdparty_dir]) # also requires libogg if env["builtin_libogg"]: - env_vorbis.Prepend(CPPPATH=["#thirdparty/libogg"]) + env_vorbis.Prepend(CPPEXTPATH=["#thirdparty/libogg"]) env_thirdparty = env_vorbis.Clone() env_thirdparty.disable_warnings() diff --git a/modules/webp/SCsub b/modules/webp/SCsub index a939e2f90e78..bcc5bba250d8 100644 --- a/modules/webp/SCsub +++ b/modules/webp/SCsub @@ -139,7 +139,7 @@ if env["builtin_libwebp"]: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_webp.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "src/"]) + env_webp.Prepend(CPPEXTPATH=[thirdparty_dir, thirdparty_dir + "src/"]) env_thirdparty = env_webp.Clone() env_thirdparty.disable_warnings() diff --git a/modules/websocket/SCsub b/modules/websocket/SCsub index acaa0d3cebea..bbc39f07cded 100644 --- a/modules/websocket/SCsub +++ b/modules/websocket/SCsub @@ -23,7 +23,7 @@ elif env["builtin_wslay"]: ] thirdparty_sources = [thirdparty_dir + s for s in thirdparty_sources] - env_ws.Prepend(CPPPATH=[thirdparty_dir]) + env_ws.Prepend(CPPEXTPATH=[thirdparty_dir]) env_ws.Append(CPPDEFINES=["HAVE_CONFIG_H"]) if env["platform"] == "windows": diff --git a/modules/xatlas_unwrap/SCsub b/modules/xatlas_unwrap/SCsub index ae82a53bd916..47885452625c 100644 --- a/modules/xatlas_unwrap/SCsub +++ b/modules/xatlas_unwrap/SCsub @@ -17,7 +17,7 @@ if env["builtin_xatlas"]: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_xatlas_unwrap.Prepend(CPPPATH=[thirdparty_dir]) + env_xatlas_unwrap.Prepend(CPPEXTPATH=[thirdparty_dir]) env_thirdparty = env_xatlas_unwrap.Clone() env_thirdparty.disable_warnings() diff --git a/platform/ios/detect.py b/platform/ios/detect.py index 6b5b9f50ceec..16ee4385650d 100644 --- a/platform/ios/detect.py +++ b/platform/ios/detect.py @@ -164,7 +164,7 @@ def configure(env: "SConsEnvironment"): "$IOS_SDK_PATH/System/Library/Frameworks/QuartzCore.framework/Headers", ] ) - env.Prepend(CPPPATH=["#thirdparty/spirv-cross"]) + env.Prepend(CPPEXTPATH=["#thirdparty/spirv-cross"]) if env["vulkan"] and env["ios_simulator"]: print_warning("iOS simulator does not support the Vulkan rendering driver") diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index b5e80f4a4dbc..75c6e8ab4371 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -293,7 +293,7 @@ def configure(env: "SConsEnvironment"): if not env["builtin_recastnavigation"]: # No pkgconfig file so far, hardcode default paths. - env.Prepend(CPPPATH=["/usr/include/recastnavigation"]) + env.Prepend(CPPEXTPATH=["/usr/include/recastnavigation"]) env.Append(LIBS=["Recast"]) if not env["builtin_embree"] and env["arch"] in ["x86_64", "arm64"]: @@ -394,7 +394,7 @@ def configure(env: "SConsEnvironment"): env.Prepend(CPPPATH=["#platform/linuxbsd"]) if env["use_sowrap"]: - env.Prepend(CPPPATH=["#thirdparty/linuxbsd_headers"]) + env.Prepend(CPPEXTPATH=["#thirdparty/linuxbsd_headers"]) env.Append( CPPDEFINES=[ @@ -456,9 +456,9 @@ def configure(env: "SConsEnvironment"): sys.exit(255) env.ParseConfig("pkg-config wayland-egl --cflags --libs") else: - env.Prepend(CPPPATH=["#thirdparty/linuxbsd_headers/wayland/"]) + env.Prepend(CPPEXTPATH=["#thirdparty/linuxbsd_headers/wayland/"]) if env["libdecor"]: - env.Prepend(CPPPATH=["#thirdparty/linuxbsd_headers/libdecor-0/"]) + env.Prepend(CPPEXTPATH=["#thirdparty/linuxbsd_headers/libdecor-0/"]) if env["libdecor"]: env.Append(CPPDEFINES=["LIBDECOR_ENABLED"]) diff --git a/platform/macos/detect.py b/platform/macos/detect.py index 227738877d05..f165dc8d9d53 100644 --- a/platform/macos/detect.py +++ b/platform/macos/detect.py @@ -231,7 +231,7 @@ def configure(env: "SConsEnvironment"): env.Append(LINKFLAGS=["-lANGLE.macos." + env["arch"]]) env.Append(LINKFLAGS=["-lEGL.macos." + env["arch"]]) env.Append(LINKFLAGS=["-lGLES.macos." + env["arch"]]) - env.Prepend(CPPPATH=["#thirdparty/angle/include"]) + env.Prepend(CPPEXTPATH=["#thirdparty/angle/include"]) env.Append(LINKFLAGS=["-rpath", "@executable_path/../Frameworks", "-rpath", "@executable_path"]) @@ -246,7 +246,7 @@ def configure(env: "SConsEnvironment"): extra_frameworks.add("Metal") extra_frameworks.add("MetalKit") extra_frameworks.add("MetalFX") - env.Prepend(CPPPATH=["#thirdparty/spirv-cross"]) + env.Prepend(CPPEXTPATH=["#thirdparty/spirv-cross"]) if env["vulkan"]: env.AppendUnique(CPPDEFINES=["VULKAN_ENABLED", "RD_ENABLED"]) diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 789909b22351..a1af39e42903 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -461,7 +461,7 @@ def spawn_capture(sh, escape, cmd, args, env): "libGLES.windows." + env["arch"] + prebuilt_lib_extra_suffix, ] LIBS += ["dxgi", "d3d9", "d3d11"] - env.Prepend(CPPPATH=["#thirdparty/angle/include"]) + env.Prepend(CPPEXTPATH=["#thirdparty/angle/include"]) if env["target"] in ["editor", "template_debug"]: LIBS += ["psapi", "dbghelp"] @@ -808,7 +808,7 @@ def configure_mingw(env: "SConsEnvironment"): ] ) env.Append(LIBS=["dxgi", "d3d9", "d3d11"]) - env.Prepend(CPPPATH=["#thirdparty/angle/include"]) + env.Prepend(CPPEXTPATH=["#thirdparty/angle/include"]) env.Append(CPPDEFINES=["MINGW_ENABLED", ("MINGW_HAS_SECURE_API", 1)]) diff --git a/servers/rendering/renderer_rd/effects/SCsub b/servers/rendering/renderer_rd/effects/SCsub index 25edf51835ed..c60099512ec0 100644 --- a/servers/rendering/renderer_rd/effects/SCsub +++ b/servers/rendering/renderer_rd/effects/SCsub @@ -13,7 +13,7 @@ thirdparty_dir = "#thirdparty/amd-fsr2/" thirdparty_sources = ["ffx_assert.cpp", "ffx_fsr2.cpp"] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_effects.Prepend(CPPPATH=[thirdparty_dir]) +env_effects.Prepend(CPPEXTPATH=[thirdparty_dir]) # This flag doesn't actually control anything GCC specific in FSR2. It determines # if symbols should be exported, which is not required for Godot. From 574a5f0e6d15e428cd9fbc4f137731eba9c531d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Thu, 3 Apr 2025 11:29:59 +0200 Subject: [PATCH 031/111] CryptoCore: Use size_t for buffer sizes to fix encoding/sums of 2.0+ GiB files. Fixes #104949. --- core/crypto/crypto_core.cpp | 14 +++++++------- core/crypto/crypto_core.h | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/core/crypto/crypto_core.cpp b/core/crypto/crypto_core.cpp index 13852d517794..9d2c346e3ae1 100644 --- a/core/crypto/crypto_core.cpp +++ b/core/crypto/crypto_core.cpp @@ -214,8 +214,8 @@ Error CryptoCore::AESContext::decrypt_cfb(size_t p_length, uint8_t p_iv[16], con } // CryptoCore -String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) { - int b64len = p_src_len / 3 * 4 + 4 + 1; +String CryptoCore::b64_encode_str(const uint8_t *p_src, size_t p_src_len) { + size_t b64len = p_src_len / 3 * 4 + 4 + 1; Vector b64buff; b64buff.resize(b64len); uint8_t *w64 = b64buff.ptrw(); @@ -225,27 +225,27 @@ String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) { return ret ? String() : (const char *)&w64[0]; } -Error CryptoCore::b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) { +Error CryptoCore::b64_encode(uint8_t *r_dst, size_t p_dst_len, size_t *r_len, const uint8_t *p_src, size_t p_src_len) { int ret = mbedtls_base64_encode(r_dst, p_dst_len, r_len, p_src, p_src_len); return ret ? FAILED : OK; } -Error CryptoCore::b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) { +Error CryptoCore::b64_decode(uint8_t *r_dst, size_t p_dst_len, size_t *r_len, const uint8_t *p_src, size_t p_src_len) { int ret = mbedtls_base64_decode(r_dst, p_dst_len, r_len, p_src, p_src_len); return ret ? FAILED : OK; } -Error CryptoCore::md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]) { +Error CryptoCore::md5(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[16]) { int ret = mbedtls_md5_ret(p_src, p_src_len, r_hash); return ret ? FAILED : OK; } -Error CryptoCore::sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]) { +Error CryptoCore::sha1(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[20]) { int ret = mbedtls_sha1_ret(p_src, p_src_len, r_hash); return ret ? FAILED : OK; } -Error CryptoCore::sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]) { +Error CryptoCore::sha256(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[32]) { int ret = mbedtls_sha256_ret(p_src, p_src_len, r_hash, 0); return ret ? FAILED : OK; } diff --git a/core/crypto/crypto_core.h b/core/crypto/crypto_core.h index 75455eb9ddad..8ef50fbcf7db 100644 --- a/core/crypto/crypto_core.h +++ b/core/crypto/crypto_core.h @@ -106,11 +106,11 @@ class CryptoCore { Error decrypt_cfb(size_t p_length, uint8_t p_iv[16], const uint8_t *p_src, uint8_t *r_dst); }; - static String b64_encode_str(const uint8_t *p_src, int p_src_len); - static Error b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len); - static Error b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len); + static String b64_encode_str(const uint8_t *p_src, size_t p_src_len); + static Error b64_encode(uint8_t *r_dst, size_t p_dst_len, size_t *r_len, const uint8_t *p_src, size_t p_src_len); + static Error b64_decode(uint8_t *r_dst, size_t p_dst_len, size_t *r_len, const uint8_t *p_src, size_t p_src_len); - static Error md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]); - static Error sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]); - static Error sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]); + static Error md5(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[16]); + static Error sha1(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[20]); + static Error sha256(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[32]); }; From 807c3a33c09afb42ce8981edeebd0cc08b9a021a Mon Sep 17 00:00:00 2001 From: LuoZhihao Date: Thu, 3 Apr 2025 18:32:04 +0800 Subject: [PATCH 032/111] Display PortableCompressedTexture's format in inspector preview --- editor/plugins/texture_editor_plugin.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp index fcda832c9111..e7b9b1394928 100644 --- a/editor/plugins/texture_editor_plugin.cpp +++ b/editor/plugins/texture_editor_plugin.cpp @@ -124,6 +124,11 @@ static Image::Format get_texture_2d_format(const Ref &p_texture) { return compressed_texture->get_format(); } + const Ref portable_compressed_texture = p_texture; + if (portable_compressed_texture.is_valid()) { + return portable_compressed_texture->get_format(); + } + // AtlasTexture? // Unknown From d47347a0364bdb29fe23ec28d0701f0b074dac30 Mon Sep 17 00:00:00 2001 From: "Silc Lizard (Tokage) Renew" <61938263+TokageItLab@users.noreply.github.com> Date: Sat, 15 Mar 2025 17:17:57 +0900 Subject: [PATCH 033/111] Add is_inside_tree() check to SpringBoneSimulator3D --- scene/3d/spring_bone_simulator_3d.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scene/3d/spring_bone_simulator_3d.cpp b/scene/3d/spring_bone_simulator_3d.cpp index 54ae2807f32b..1350d54c6e1f 100644 --- a/scene/3d/spring_bone_simulator_3d.cpp +++ b/scene/3d/spring_bone_simulator_3d.cpp @@ -1371,6 +1371,9 @@ void SpringBoneSimulator3D::_find_collisions() { } void SpringBoneSimulator3D::_process_collisions() { + if (!is_inside_tree()) { + return; + } for (const ObjectID &oid : collisions) { Object *t_obj = ObjectDB::get_instance(oid); if (!t_obj) { @@ -1494,6 +1497,10 @@ void SpringBoneSimulator3D::_set_active(bool p_active) { } void SpringBoneSimulator3D::_process_modification() { + if (!is_inside_tree()) { + return; + } + Skeleton3D *skeleton = get_skeleton(); if (!skeleton) { return; @@ -1515,6 +1522,9 @@ void SpringBoneSimulator3D::_process_modification() { } void SpringBoneSimulator3D::reset() { + if (!is_inside_tree()) { + return; + } Skeleton3D *skeleton = get_skeleton(); if (!skeleton) { return; From 099bd4a5ce1a2037f4accac0a29582607b8f474e Mon Sep 17 00:00:00 2001 From: Ricardo Subtil Date: Wed, 2 Apr 2025 19:20:13 +0100 Subject: [PATCH 034/111] Fix invalid DAP responses when content had non-ASCII content --- .../debug_adapter/debug_adapter_protocol.cpp | 19 ++++++++----------- .../debug_adapter/debug_adapter_protocol.h | 2 +- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp index 35d841849c93..49249d856043 100644 --- a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp +++ b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp @@ -116,12 +116,12 @@ Error DAPeer::send_data() { if (!data.has("seq")) { data["seq"] = ++seq; } - String formatted_data = format_output(data); + const Vector &formatted_data = format_output(data); int data_sent = 0; - while (data_sent < formatted_data.length()) { + while (data_sent < formatted_data.size()) { int curr_sent = 0; - Error err = connection->put_partial_data((const uint8_t *)formatted_data.utf8().get_data(), formatted_data.size() - data_sent - 1, curr_sent); + Error err = connection->put_partial_data(formatted_data.ptr() + data_sent, formatted_data.size() - data_sent, curr_sent); if (err != OK) { return err; } @@ -132,15 +132,12 @@ Error DAPeer::send_data() { return OK; } -String DAPeer::format_output(const Dictionary &p_params) const { - String response = Variant(p_params).to_json_string(); - String header = "Content-Length: "; - CharString charstr = response.utf8(); - size_t len = charstr.length(); - header += itos(len); - header += "\r\n\r\n"; +Vector DAPeer::format_output(const Dictionary &p_params) const { + const Vector &content = Variant(p_params).to_json_string().to_utf8_buffer(); + Vector response = vformat("Content-Length: %d\r\n\r\n", content.size()).to_utf8_buffer(); - return header + response; + response.append_array(content); + return response; } Error DebugAdapterProtocol::on_client_connected() { diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.h b/editor/debugger/debug_adapter/debug_adapter_protocol.h index 23d1bdb1544b..9cd5741b19f9 100644 --- a/editor/debugger/debug_adapter/debug_adapter_protocol.h +++ b/editor/debugger/debug_adapter/debug_adapter_protocol.h @@ -67,7 +67,7 @@ struct DAPeer : RefCounted { Error handle_data(); Error send_data(); - String format_output(const Dictionary &p_params) const; + Vector format_output(const Dictionary &p_params) const; }; class DebugAdapterProtocol : public Object { From 9904ecf9611c69b7bd1abe0461bc6e60eb2482e1 Mon Sep 17 00:00:00 2001 From: Daylily-Zeleen Date: Wed, 2 Apr 2025 14:48:26 +0800 Subject: [PATCH 035/111] Allow instantiate unexposed EditorPlugin form GDExtension. --- core/object/class_db.cpp | 20 +++++++++++++++----- core/object/class_db.h | 6 ++++-- editor/editor_node.cpp | 2 +- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index 943e340dfca6..c09303eaddf6 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -533,19 +533,21 @@ StringName ClassDB::get_compatibility_class(const StringName &p_class) { return StringName(); } -Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require_real_class, bool p_notify_postinitialize) { +Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require_real_class, bool p_notify_postinitialize, bool p_exposed_only) { ClassInfo *ti; { Locker::Lock lock(Locker::STATE_READ); ti = classes.getptr(p_class); - if (!_can_instantiate(ti)) { + if (!_can_instantiate(ti, p_exposed_only)) { if (compat_classes.has(p_class)) { ti = classes.getptr(compat_classes[p_class]); } } ERR_FAIL_NULL_V_MSG(ti, nullptr, vformat("Cannot get class '%s'.", String(p_class))); ERR_FAIL_COND_V_MSG(ti->disabled, nullptr, vformat("Class '%s' is disabled.", String(p_class))); - ERR_FAIL_COND_V_MSG(!ti->exposed, nullptr, vformat("Class '%s' isn't exposed.", String(p_class))); + if (p_exposed_only) { + ERR_FAIL_COND_V_MSG(!ti->exposed, nullptr, vformat("Class '%s' isn't exposed.", String(p_class))); + } ERR_FAIL_NULL_V_MSG(ti->creation_func, nullptr, vformat("Class '%s' or its base class cannot be instantiated.", String(p_class))); } @@ -597,12 +599,16 @@ Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require } } -bool ClassDB::_can_instantiate(ClassInfo *p_class_info) { +bool ClassDB::_can_instantiate(ClassInfo *p_class_info, bool p_exposed_only) { if (!p_class_info) { return false; } - if (p_class_info->disabled || !p_class_info->exposed || !p_class_info->creation_func) { + if (p_exposed_only && !p_class_info->exposed) { + return false; + } + + if (p_class_info->disabled || !p_class_info->creation_func) { return false; } @@ -2337,6 +2343,10 @@ uint64_t ClassDB::get_native_struct_size(const StringName &p_name) { return native_structs[p_name].struct_size; } +Object *ClassDB::_instantiate_allow_unexposed(const StringName &p_class) { + return _instantiate_internal(p_class, false, true, false); +} + void ClassDB::cleanup_defaults() { default_values.clear(); default_values_cached.clear(); diff --git a/core/object/class_db.h b/core/object/class_db.h index ffd5c53c2c62..1ce62226eff1 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -216,9 +216,9 @@ class ClassDB { static MethodBind *_bind_vararg_method(MethodBind *p_bind, const StringName &p_name, const Vector &p_default_args, bool p_compatibility); static void _bind_method_custom(const StringName &p_class, MethodBind *p_method, bool p_compatibility); - static Object *_instantiate_internal(const StringName &p_class, bool p_require_real_class = false, bool p_notify_postinitialize = true); + static Object *_instantiate_internal(const StringName &p_class, bool p_require_real_class = false, bool p_notify_postinitialize = true, bool p_exposed_only = true); - static bool _can_instantiate(ClassInfo *p_class_info); + static bool _can_instantiate(ClassInfo *p_class_info, bool p_exposed_only = true); public: // DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!! @@ -520,6 +520,8 @@ class ClassDB { static void get_native_struct_list(List *r_names); static String get_native_struct_code(const StringName &p_name); static uint64_t get_native_struct_size(const StringName &p_name); // Used for asserting + + static Object *_instantiate_allow_unexposed(const StringName &p_class); // Used to create unexposed classes from GDExtension, typically for unexposed EditorPlugin. }; #define BIND_ENUM_CONSTANT(m_constant) \ diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 05765e98ae7d..6e2789f559a0 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -3786,7 +3786,7 @@ void EditorNode::add_extension_editor_plugin(const StringName &p_class_name) { ERR_FAIL_COND_MSG(!ClassDB::is_parent_class(p_class_name, SNAME("EditorPlugin")), vformat("Class is not an editor plugin: %s", p_class_name)); ERR_FAIL_COND_MSG(singleton->editor_data.has_extension_editor_plugin(p_class_name), vformat("Editor plugin already added for class: %s", p_class_name)); - EditorPlugin *plugin = Object::cast_to(ClassDB::instantiate(p_class_name)); + EditorPlugin *plugin = Object::cast_to(ClassDB::_instantiate_allow_unexposed(p_class_name)); singleton->editor_data.add_extension_editor_plugin(p_class_name, plugin); add_editor_plugin(plugin); } From dce1871d366d3c92e1779e58c9ca74dea5478e3a Mon Sep 17 00:00:00 2001 From: kobewi Date: Wed, 2 Apr 2025 20:47:06 +0200 Subject: [PATCH 036/111] Fix Edit option for sub-resources --- editor/editor_inspector.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 5611d00814f3..228daedab76e 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -3002,7 +3002,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, EditorIn ep->connect("property_pinned", callable_mp(this, &EditorInspector::_property_pinned)); ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected)); ep->connect("multiple_properties_changed", callable_mp(this, &EditorInspector::_multiple_properties_changed)); - ep->connect("resource_selected", callable_mp(this, &EditorInspector::_resource_selected), CONNECT_DEFERRED); + ep->connect("resource_selected", callable_mp(get_root_inspector(), &EditorInspector::_resource_selected), CONNECT_DEFERRED); ep->connect("object_id_selected", callable_mp(this, &EditorInspector::_object_id_selected), CONNECT_DEFERRED); if (F.properties.size()) { @@ -3844,7 +3844,7 @@ void EditorInspector::update_tree() { ep->connect("property_pinned", callable_mp(this, &EditorInspector::_property_pinned)); ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected)); ep->connect("multiple_properties_changed", callable_mp(this, &EditorInspector::_multiple_properties_changed)); - ep->connect("resource_selected", callable_mp(this, &EditorInspector::_resource_selected), CONNECT_DEFERRED); + ep->connect("resource_selected", callable_mp(get_root_inspector(), &EditorInspector::_resource_selected), CONNECT_DEFERRED); ep->connect("object_id_selected", callable_mp(this, &EditorInspector::_object_id_selected), CONNECT_DEFERRED); if (use_doc_hints) { From 114d3dd130a224cdc20b16105068cfad0c640609 Mon Sep 17 00:00:00 2001 From: Micky Date: Sun, 24 Nov 2024 17:00:17 +0100 Subject: [PATCH 037/111] Mention DUPLICATE_SIGNALS only affects CONNECT_PERSIST signals --- doc/classes/Node.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index fd0a2594c293..1e27ed486027 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -1319,7 +1319,7 @@ Disables physics interpolation for this node and for children set to [constant PHYSICS_INTERPOLATION_MODE_INHERIT]. - Duplicate the node's signal connections. + Duplicate the node's signal connections that are connected with the [constant Object.CONNECT_PERSIST] flag. Duplicate the node's groups. From a6f2868567e4bee8238c55ce7b99a7fb93cc8d80 Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Sun, 16 Mar 2025 17:46:22 +0100 Subject: [PATCH 038/111] Emit changed signal after baking navigation mesh Emits changed signal after baking navigation mesh. --- .../2d/nav_mesh_generator_2d.cpp | 5 ++ .../3d/nav_mesh_generator_3d.cpp | 5 ++ scene/2d/navigation/navigation_region_2d.cpp | 43 +++++++------- scene/2d/navigation/navigation_region_2d.h | 2 +- scene/3d/navigation/navigation_region_3d.cpp | 58 +++++++++---------- scene/3d/navigation/navigation_region_3d.h | 2 +- 6 files changed, 59 insertions(+), 56 deletions(-) diff --git a/modules/navigation_2d/2d/nav_mesh_generator_2d.cpp b/modules/navigation_2d/2d/nav_mesh_generator_2d.cpp index 3a47cdc1577f..191a2ee4c57c 100644 --- a/modules/navigation_2d/2d/nav_mesh_generator_2d.cpp +++ b/modules/navigation_2d/2d/nav_mesh_generator_2d.cpp @@ -93,6 +93,7 @@ void NavMeshGenerator2D::sync() { if (generator_task->callback.is_valid()) { generator_emit_callback(generator_task->callback); } + generator_task->navigation_mesh->emit_changed(); memdelete(generator_task); } } @@ -150,6 +151,7 @@ void NavMeshGenerator2D::bake_from_source_geometry_data(Ref p if (p_callback.is_valid()) { generator_emit_callback(p_callback); } + p_navigation_mesh->emit_changed(); return; } @@ -169,6 +171,8 @@ void NavMeshGenerator2D::bake_from_source_geometry_data(Ref p if (p_callback.is_valid()) { generator_emit_callback(p_callback); } + + p_navigation_mesh->emit_changed(); } void NavMeshGenerator2D::bake_from_source_geometry_data_async(Ref p_navigation_mesh, Ref p_source_geometry_data, const Callable &p_callback) { @@ -180,6 +184,7 @@ void NavMeshGenerator2D::bake_from_source_geometry_data_async(Refemit_changed(); return; } diff --git a/modules/navigation_3d/3d/nav_mesh_generator_3d.cpp b/modules/navigation_3d/3d/nav_mesh_generator_3d.cpp index 703eb011dbaf..b489adf5b6e8 100644 --- a/modules/navigation_3d/3d/nav_mesh_generator_3d.cpp +++ b/modules/navigation_3d/3d/nav_mesh_generator_3d.cpp @@ -92,6 +92,7 @@ void NavMeshGenerator3D::sync() { if (generator_task->callback.is_valid()) { generator_emit_callback(generator_task->callback); } + generator_task->navigation_mesh->emit_changed(); memdelete(generator_task); } } @@ -149,6 +150,7 @@ void NavMeshGenerator3D::bake_from_source_geometry_data(Ref p_na if (p_callback.is_valid()) { generator_emit_callback(p_callback); } + p_navigation_mesh->emit_changed(); return; } @@ -168,6 +170,8 @@ void NavMeshGenerator3D::bake_from_source_geometry_data(Ref p_na if (p_callback.is_valid()) { generator_emit_callback(p_callback); } + + p_navigation_mesh->emit_changed(); } void NavMeshGenerator3D::bake_from_source_geometry_data_async(Ref p_navigation_mesh, Ref p_source_geometry_data, const Callable &p_callback) { @@ -179,6 +183,7 @@ void NavMeshGenerator3D::bake_from_source_geometry_data_async(Refemit_changed(); return; } diff --git a/scene/2d/navigation/navigation_region_2d.cpp b/scene/2d/navigation/navigation_region_2d.cpp index e5a310cec241..f107fee0647b 100644 --- a/scene/2d/navigation/navigation_region_2d.cpp +++ b/scene/2d/navigation/navigation_region_2d.cpp @@ -198,27 +198,12 @@ void NavigationRegion2D::set_navigation_polygon(const Ref &p_ } navigation_polygon = p_navigation_polygon; -#ifdef DEBUG_ENABLED - debug_mesh_dirty = true; -#endif // DEBUG_ENABLED - - _update_bounds(); - - NavigationServer2D::get_singleton()->region_set_navigation_polygon(region, p_navigation_polygon); if (navigation_polygon.is_valid()) { navigation_polygon->connect_changed(callable_mp(this, &NavigationRegion2D::_navigation_polygon_changed)); } -#ifdef DEBUG_ENABLED - if (navigation_polygon.is_null()) { - _set_debug_visible(false); - } -#endif // DEBUG_ENABLED - _navigation_polygon_changed(); - - update_configuration_warnings(); } Ref NavigationRegion2D::get_navigation_polygon() const { @@ -254,19 +239,18 @@ void NavigationRegion2D::bake_navigation_polygon(bool p_on_thread) { NavigationServer2D::get_singleton()->parse_source_geometry_data(navigation_polygon, source_geometry_data, this); if (p_on_thread) { - NavigationServer2D::get_singleton()->bake_from_source_geometry_data_async(navigation_polygon, source_geometry_data, callable_mp(this, &NavigationRegion2D::_bake_finished).bind(navigation_polygon)); + NavigationServer2D::get_singleton()->bake_from_source_geometry_data_async(navigation_polygon, source_geometry_data, callable_mp(this, &NavigationRegion2D::_bake_finished)); } else { - NavigationServer2D::get_singleton()->bake_from_source_geometry_data(navigation_polygon, source_geometry_data, callable_mp(this, &NavigationRegion2D::_bake_finished).bind(navigation_polygon)); + NavigationServer2D::get_singleton()->bake_from_source_geometry_data(navigation_polygon, source_geometry_data, callable_mp(this, &NavigationRegion2D::_bake_finished)); } } -void NavigationRegion2D::_bake_finished(Ref p_navigation_polygon) { +void NavigationRegion2D::_bake_finished() { if (!Thread::is_main_thread()) { - callable_mp(this, &NavigationRegion2D::_bake_finished).call_deferred(p_navigation_polygon); + callable_mp(this, &NavigationRegion2D::_bake_finished).call_deferred(); return; } - set_navigation_polygon(p_navigation_polygon); emit_signal(SNAME("bake_finished")); } @@ -275,12 +259,25 @@ bool NavigationRegion2D::is_baking() const { } void NavigationRegion2D::_navigation_polygon_changed() { + _update_bounds(); + + NavigationServer2D::get_singleton()->region_set_navigation_polygon(region, navigation_polygon); + +#ifdef DEBUG_ENABLED + debug_mesh_dirty = true; + + if (navigation_polygon.is_null()) { + _set_debug_visible(false); + } + if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint())) { queue_redraw(); } - if (navigation_polygon.is_valid()) { - NavigationServer2D::get_singleton()->region_set_navigation_polygon(region, navigation_polygon); - } +#endif // DEBUG_ENABLED + + emit_signal(SNAME("navigation_polygon_changed")); + + update_configuration_warnings(); } #ifdef DEBUG_ENABLED diff --git a/scene/2d/navigation/navigation_region_2d.h b/scene/2d/navigation/navigation_region_2d.h index 2a18e3730710..011267153fbe 100644 --- a/scene/2d/navigation/navigation_region_2d.h +++ b/scene/2d/navigation/navigation_region_2d.h @@ -111,7 +111,7 @@ class NavigationRegion2D : public Node2D { PackedStringArray get_configuration_warnings() const override; void bake_navigation_polygon(bool p_on_thread); - void _bake_finished(Ref p_navigation_polygon); + void _bake_finished(); bool is_baking() const; Rect2 get_bounds() const { return bounds; } diff --git a/scene/3d/navigation/navigation_region_3d.cpp b/scene/3d/navigation/navigation_region_3d.cpp index 405f4361fd72..94d897211477 100644 --- a/scene/3d/navigation/navigation_region_3d.cpp +++ b/scene/3d/navigation/navigation_region_3d.cpp @@ -194,30 +194,7 @@ void NavigationRegion3D::set_navigation_mesh(const Ref &p_naviga navigation_mesh->connect_changed(callable_mp(this, &NavigationRegion3D::_navigation_mesh_changed)); } - _update_bounds(); - - NavigationServer3D::get_singleton()->region_set_navigation_mesh(region, p_navigation_mesh); - -#ifdef DEBUG_ENABLED - if (is_inside_tree() && NavigationServer3D::get_singleton()->get_debug_navigation_enabled()) { - if (navigation_mesh.is_valid()) { - _update_debug_mesh(); - _update_debug_edge_connections_mesh(); - } else { - if (debug_instance.is_valid()) { - RS::get_singleton()->instance_set_visible(debug_instance, false); - } - if (debug_edge_connections_instance.is_valid()) { - RS::get_singleton()->instance_set_visible(debug_edge_connections_instance, false); - } - } - } -#endif // DEBUG_ENABLED - - emit_signal(SNAME("navigation_mesh_changed")); - - update_gizmos(); - update_configuration_warnings(); + _navigation_mesh_changed(); } Ref NavigationRegion3D::get_navigation_mesh() const { @@ -253,19 +230,18 @@ void NavigationRegion3D::bake_navigation_mesh(bool p_on_thread) { NavigationServer3D::get_singleton()->parse_source_geometry_data(navigation_mesh, source_geometry_data, this); if (p_on_thread) { - NavigationServer3D::get_singleton()->bake_from_source_geometry_data_async(navigation_mesh, source_geometry_data, callable_mp(this, &NavigationRegion3D::_bake_finished).bind(navigation_mesh)); + NavigationServer3D::get_singleton()->bake_from_source_geometry_data_async(navigation_mesh, source_geometry_data, callable_mp(this, &NavigationRegion3D::_bake_finished)); } else { - NavigationServer3D::get_singleton()->bake_from_source_geometry_data(navigation_mesh, source_geometry_data, callable_mp(this, &NavigationRegion3D::_bake_finished).bind(navigation_mesh)); + NavigationServer3D::get_singleton()->bake_from_source_geometry_data(navigation_mesh, source_geometry_data, callable_mp(this, &NavigationRegion3D::_bake_finished)); } } -void NavigationRegion3D::_bake_finished(Ref p_navigation_mesh) { +void NavigationRegion3D::_bake_finished() { if (!Thread::is_main_thread()) { - callable_mp(this, &NavigationRegion3D::_bake_finished).call_deferred(p_navigation_mesh); + callable_mp(this, &NavigationRegion3D::_bake_finished).call_deferred(); return; } - set_navigation_mesh(p_navigation_mesh); emit_signal(SNAME("bake_finished")); } @@ -350,12 +326,32 @@ bool NavigationRegion3D::_get(const StringName &p_name, Variant &r_ret) const { #endif // DISABLE_DEPRECATED void NavigationRegion3D::_navigation_mesh_changed() { - update_gizmos(); - update_configuration_warnings(); + _update_bounds(); + + NavigationServer3D::get_singleton()->region_set_navigation_mesh(region, navigation_mesh); #ifdef DEBUG_ENABLED + if (is_inside_tree() && NavigationServer3D::get_singleton()->get_debug_navigation_enabled()) { + if (navigation_mesh.is_valid()) { + _update_debug_mesh(); + _update_debug_edge_connections_mesh(); + } else { + if (debug_instance.is_valid()) { + RS::get_singleton()->instance_set_visible(debug_instance, false); + } + if (debug_edge_connections_instance.is_valid()) { + RS::get_singleton()->instance_set_visible(debug_edge_connections_instance, false); + } + } + } + _update_debug_edge_connections_mesh(); #endif // DEBUG_ENABLED + + emit_signal(SNAME("navigation_mesh_changed")); + + update_gizmos(); + update_configuration_warnings(); } #ifdef DEBUG_ENABLED diff --git a/scene/3d/navigation/navigation_region_3d.h b/scene/3d/navigation/navigation_region_3d.h index 95b9673a0842..c6a5629b2558 100644 --- a/scene/3d/navigation/navigation_region_3d.h +++ b/scene/3d/navigation/navigation_region_3d.h @@ -106,7 +106,7 @@ class NavigationRegion3D : public Node3D { /// Bakes the navigation mesh; once done, automatically /// sets the new navigation mesh and emits a signal void bake_navigation_mesh(bool p_on_thread); - void _bake_finished(Ref p_navigation_mesh); + void _bake_finished(); bool is_baking() const; PackedStringArray get_configuration_warnings() const override; From bacfaf964f4fccca9e9d006cf7048e2107bbb37a Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Wed, 2 Apr 2025 03:15:02 -0700 Subject: [PATCH 039/111] Organize ifdefs for disabling navigation, physics, and XR --- SConstruct | 2 +- main/main.cpp | 15 +++--- platform/android/java_godot_lib_jni.cpp | 4 +- scene/main/canvas_item.cpp | 1 + scene/resources/packed_scene.cpp | 7 +-- scene/resources/world_2d.cpp | 52 ++++++++----------- scene/resources/world_2d.h | 4 +- servers/register_server_types.cpp | 25 +++++---- servers/rendering/renderer_compositor.cpp | 3 ++ servers/rendering/renderer_rd/effects/vrs.cpp | 4 +- 10 files changed, 59 insertions(+), 58 deletions(-) diff --git a/SConstruct b/SConstruct index 87d08bfd0b3e..a869f59b3815 100644 --- a/SConstruct +++ b/SConstruct @@ -977,8 +977,8 @@ if env.editor_build: if env["disable_3d"]: env.Append(CPPDEFINES=["_3D_DISABLED"]) - env["disable_physics_3d"] = True env["disable_navigation_3d"] = True + env["disable_physics_3d"] = True env["disable_xr"] = True if env["disable_advanced_gui"]: env.Append(CPPDEFINES=["ADVANCED_GUI_DISABLED"]) diff --git a/main/main.cpp b/main/main.cpp index c74f508054d2..6121d893e3f3 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -82,23 +82,26 @@ #include "servers/navigation_server_2d.h" #include "servers/navigation_server_2d_dummy.h" #endif // NAVIGATION_2D_DISABLED + #ifndef PHYSICS_2D_DISABLED #include "servers/physics_server_2d.h" #include "servers/physics_server_2d_dummy.h" #endif // PHYSICS_2D_DISABLED // 3D -#ifndef PHYSICS_3D_DISABLED -#include "servers/physics_server_3d.h" -#include "servers/physics_server_3d_dummy.h" -#endif // PHYSICS_3D_DISABLED #ifndef NAVIGATION_3D_DISABLED #include "servers/navigation_server_3d.h" #include "servers/navigation_server_3d_dummy.h" #endif // NAVIGATION_3D_DISABLED -#ifndef _3D_DISABLED + +#ifndef PHYSICS_3D_DISABLED +#include "servers/physics_server_3d.h" +#include "servers/physics_server_3d_dummy.h" +#endif // PHYSICS_3D_DISABLED + +#ifndef XR_DISABLED #include "servers/xr_server.h" -#endif // _3D_DISABLED +#endif // XR_DISABLED #ifdef TESTS_ENABLED #include "tests/test_main.h" diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index 378c0bc081f9..196dfd88f462 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -51,9 +51,9 @@ #include "main/main.h" #include "servers/rendering_server.h" -#ifndef _3D_DISABLED +#ifndef XR_DISABLED #include "servers/xr_server.h" -#endif // _3D_DISABLED +#endif // XR_DISABLED #ifdef TOOLS_ENABLED #include "editor/editor_settings.h" diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 6f7c1e68d8ea..6baaac1d3f89 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -1687,6 +1687,7 @@ void CanvasItem::set_clip_children_mode(ClipChildrenMode p_clip_mode) { RS::get_singleton()->canvas_item_set_canvas_group_mode(get_canvas_item(), RS::CanvasGroupMode(clip_children_mode)); } + CanvasItem::ClipChildrenMode CanvasItem::get_clip_children_mode() const { ERR_READ_THREAD_GUARD_V(CLIP_CHILDREN_DISABLED); return clip_children_mode; diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 0e2ab59b7a37..2604a3f53ddb 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -35,14 +35,15 @@ #include "core/io/resource_loader.h" #include "core/templates/local_vector.h" #include "scene/2d/node_2d.h" -#ifndef _3D_DISABLED -#include "scene/3d/node_3d.h" -#endif // _3D_DISABLED #include "scene/gui/control.h" #include "scene/main/instance_placeholder.h" #include "scene/main/missing_node.h" #include "scene/property_utils.h" +#ifndef _3D_DISABLED +#include "scene/3d/node_3d.h" +#endif // _3D_DISABLED + #define PACKED_SCENE_VERSION 3 #ifdef TOOLS_ENABLED diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index 9fb3418760cf..1f2586646bed 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -42,20 +42,6 @@ RID World2D::get_canvas() const { return canvas; } -#ifndef PHYSICS_2D_DISABLED -RID World2D::get_space() const { - if (space.is_null()) { - space = PhysicsServer2D::get_singleton()->space_create(); - PhysicsServer2D::get_singleton()->space_set_active(space, true); - PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY, GLOBAL_GET("physics/2d/default_gravity")); - PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_GET("physics/2d/default_gravity_vector")); - PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_LINEAR_DAMP, GLOBAL_GET("physics/2d/default_linear_damp")); - PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_GET("physics/2d/default_angular_damp")); - } - return space; -} -#endif // PHYSICS_2D_DISABLED - #ifndef NAVIGATION_2D_DISABLED RID World2D::get_navigation_map() const { if (navigation_map.is_null()) { @@ -71,6 +57,18 @@ RID World2D::get_navigation_map() const { #endif // NAVIGATION_2D_DISABLED #ifndef PHYSICS_2D_DISABLED +RID World2D::get_space() const { + if (space.is_null()) { + space = PhysicsServer2D::get_singleton()->space_create(); + PhysicsServer2D::get_singleton()->space_set_active(space, true); + PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY, GLOBAL_GET("physics/2d/default_gravity")); + PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_GET("physics/2d/default_gravity_vector")); + PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_LINEAR_DAMP, GLOBAL_GET("physics/2d/default_linear_damp")); + PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_GET("physics/2d/default_angular_damp")); + } + return space; +} + PhysicsDirectSpaceState2D *World2D::get_direct_space_state() { return PhysicsServer2D::get_singleton()->space_get_direct_state(get_space()); } @@ -78,19 +76,16 @@ PhysicsDirectSpaceState2D *World2D::get_direct_space_state() { void World2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_canvas"), &World2D::get_canvas); + ADD_PROPERTY(PropertyInfo(Variant::RID, "canvas", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "", "get_canvas"); + #ifndef NAVIGATION_2D_DISABLED ClassDB::bind_method(D_METHOD("get_navigation_map"), &World2D::get_navigation_map); + ADD_PROPERTY(PropertyInfo(Variant::RID, "navigation_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "", "get_navigation_map"); #endif // NAVIGATION_2D_DISABLED + #ifndef PHYSICS_2D_DISABLED ClassDB::bind_method(D_METHOD("get_space"), &World2D::get_space); ClassDB::bind_method(D_METHOD("get_direct_space_state"), &World2D::get_direct_space_state); -#endif // PHYSICS_2D_DISABLED - - ADD_PROPERTY(PropertyInfo(Variant::RID, "canvas", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "", "get_canvas"); -#ifndef NAVIGATION_2D_DISABLED - ADD_PROPERTY(PropertyInfo(Variant::RID, "navigation_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "", "get_navigation_map"); -#endif // NAVIGATION_2D_DISABLED -#ifndef PHYSICS_2D_DISABLED ADD_PROPERTY(PropertyInfo(Variant::RID, "space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "", "get_space"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState2D", PROPERTY_USAGE_NONE), "", "get_direct_space_state"); #endif // PHYSICS_2D_DISABLED @@ -110,22 +105,19 @@ World2D::World2D() { World2D::~World2D() { ERR_FAIL_NULL(RenderingServer::get_singleton()); -#ifndef PHYSICS_2D_DISABLED - ERR_FAIL_NULL(PhysicsServer2D::get_singleton()); -#endif // PHYSICS_2D_DISABLED + RenderingServer::get_singleton()->free(canvas); + #ifndef NAVIGATION_2D_DISABLED ERR_FAIL_NULL(NavigationServer2D::get_singleton()); + if (navigation_map.is_valid()) { + NavigationServer2D::get_singleton()->free(navigation_map); + } #endif // NAVIGATION_2D_DISABLED - RenderingServer::get_singleton()->free(canvas); #ifndef PHYSICS_2D_DISABLED + ERR_FAIL_NULL(PhysicsServer2D::get_singleton()); if (space.is_valid()) { PhysicsServer2D::get_singleton()->free(space); } #endif // PHYSICS_2D_DISABLED -#ifndef NAVIGATION_2D_DISABLED - if (navigation_map.is_valid()) { - NavigationServer2D::get_singleton()->free(navigation_map); - } -#endif // NAVIGATION_2D_DISABLED } diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h index 007e1ffaff5d..fd93c884a2e6 100644 --- a/scene/resources/world_2d.h +++ b/scene/resources/world_2d.h @@ -44,10 +44,12 @@ class World2D : public Resource { GDCLASS(World2D, Resource); RID canvas; - mutable RID space; #ifndef NAVIGATION_2D_DISABLED mutable RID navigation_map; #endif // NAVIGATION_2D_DISABLED +#ifndef PHYSICS_2D_DISABLED + mutable RID space; +#endif // PHYSICS_2D_DISABLED HashSet viewports; diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index b99dc72ba6e0..62ae5418d1e1 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -258,6 +258,12 @@ void register_server_types() { ServersDebugger::initialize(); +#ifndef NAVIGATION_2D_DISABLED + GDREGISTER_ABSTRACT_CLASS(NavigationServer2D); + GDREGISTER_CLASS(NavigationPathQueryParameters2D); + GDREGISTER_CLASS(NavigationPathQueryResult2D); +#endif // NAVIGATION_2D_DISABLED + #ifndef PHYSICS_2D_DISABLED // Physics 2D GDREGISTER_CLASS(PhysicsServer2DManager); @@ -286,11 +292,11 @@ void register_server_types() { PhysicsServer2DManager::get_singleton()->register_server("Dummy", callable_mp_static(_create_dummy_physics_server_2d)); #endif // PHYSICS_2D_DISABLED -#ifndef NAVIGATION_2D_DISABLED - GDREGISTER_ABSTRACT_CLASS(NavigationServer2D); - GDREGISTER_CLASS(NavigationPathQueryParameters2D); - GDREGISTER_CLASS(NavigationPathQueryResult2D); -#endif // NAVIGATION_2D_DISABLED +#ifndef NAVIGATION_3D_DISABLED + GDREGISTER_ABSTRACT_CLASS(NavigationServer3D); + GDREGISTER_CLASS(NavigationPathQueryParameters3D); + GDREGISTER_CLASS(NavigationPathQueryResult3D); +#endif // NAVIGATION_3D_DISABLED #ifndef PHYSICS_3D_DISABLED // Physics 3D @@ -336,12 +342,6 @@ void register_server_types() { GDREGISTER_ABSTRACT_CLASS(XRTracker); #endif // XR_DISABLED -#ifndef NAVIGATION_3D_DISABLED - GDREGISTER_ABSTRACT_CLASS(NavigationServer3D); - GDREGISTER_CLASS(NavigationPathQueryParameters3D); - GDREGISTER_CLASS(NavigationPathQueryResult3D); -#endif // NAVIGATION_3D_DISABLED - writer_mjpeg = memnew(MovieWriterMJPEG); MovieWriter::add_writer(writer_mjpeg); @@ -369,14 +369,13 @@ void register_server_singletons() { Engine::get_singleton()->add_singleton(Engine::Singleton("CameraServer", CameraServer::get_singleton(), "CameraServer")); Engine::get_singleton()->add_singleton(Engine::Singleton("DisplayServer", DisplayServer::get_singleton(), "DisplayServer")); Engine::get_singleton()->add_singleton(Engine::Singleton("NativeMenu", NativeMenu::get_singleton(), "NativeMenu")); + Engine::get_singleton()->add_singleton(Engine::Singleton("RenderingServer", RenderingServer::get_singleton(), "RenderingServer")); #ifndef NAVIGATION_2D_DISABLED Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer2D", NavigationServer2D::get_singleton(), "NavigationServer2D")); #endif // NAVIGATION_2D_DISABLED #ifndef NAVIGATION_3D_DISABLED Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer3D", NavigationServer3D::get_singleton(), "NavigationServer3D")); #endif // NAVIGATION_3D_DISABLED - Engine::get_singleton()->add_singleton(Engine::Singleton("RenderingServer", RenderingServer::get_singleton(), "RenderingServer")); - #ifndef PHYSICS_2D_DISABLED Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer2D", PhysicsServer2D::get_singleton(), "PhysicsServer2D")); #endif // PHYSICS_2D_DISABLED diff --git a/servers/rendering/renderer_compositor.cpp b/servers/rendering/renderer_compositor.cpp index b6c9c04ede2e..b99220097785 100644 --- a/servers/rendering/renderer_compositor.cpp +++ b/servers/rendering/renderer_compositor.cpp @@ -31,7 +31,10 @@ #include "renderer_compositor.h" #include "core/config/project_settings.h" + +#ifndef XR_DISABLED #include "servers/xr_server.h" +#endif // XR_DISABLED RendererCompositor *RendererCompositor::singleton = nullptr; diff --git a/servers/rendering/renderer_rd/effects/vrs.cpp b/servers/rendering/renderer_rd/effects/vrs.cpp index 4730b5db0456..142eebabea90 100644 --- a/servers/rendering/renderer_rd/effects/vrs.cpp +++ b/servers/rendering/renderer_rd/effects/vrs.cpp @@ -33,9 +33,9 @@ #include "../storage_rd/texture_storage.h" #include "../uniform_set_cache_rd.h" -#ifndef _3D_DISABLED +#ifndef XR_DISABLED #include "servers/xr_server.h" -#endif // _3D_DISABLED +#endif // XR_DISABLED using namespace RendererRD; From c6284b3186cdb0d7fceae8c82c0bc660f08169af Mon Sep 17 00:00:00 2001 From: Lukas Tenbrink Date: Wed, 2 Apr 2025 13:50:47 +0200 Subject: [PATCH 040/111] Removed unused `get_valid_parents_static` functions from `GDCLASS`. --- core/object/object.cpp | 6 ------ core/object/object.h | 9 --------- 2 files changed, 15 deletions(-) diff --git a/core/object/object.cpp b/core/object/object.cpp index 7c1840619068..c45157863990 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -258,12 +258,6 @@ void Object::_postinitialize() { notification(NOTIFICATION_POSTINITIALIZE); } -void Object::get_valid_parents_static(List *p_parents) { -} - -void Object::_get_valid_parents_static(List *p_parents) { -} - void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid) { #ifdef TOOLS_ENABLED diff --git a/core/object/object.h b/core/object/object.h index 9550b6243bfc..4275f4ca16e4 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -441,13 +441,6 @@ public: return true; \ } \ return (p_class == (#m_class)) ? true : m_inherits::is_class(p_class); \ - } \ - static void get_valid_parents_static(List *p_parents) { \ - if (m_class::_get_valid_parents_static != m_inherits::_get_valid_parents_static) { \ - m_class::_get_valid_parents_static(p_parents); \ - } \ - \ - m_inherits::get_valid_parents_static(p_parents); \ } \ \ protected: \ @@ -749,8 +742,6 @@ class Object { _FORCE_INLINE_ void (Object::*_get_notification() const)(int) { return &Object::_notification; } - static void get_valid_parents_static(List *p_parents); - static void _get_valid_parents_static(List *p_parents); Variant _call_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); Variant _call_deferred_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); From 1c6e0d362c2b9796a3e859e7c91402dae6da571b Mon Sep 17 00:00:00 2001 From: arkology <43543909+arkology@users.noreply.github.com> Date: Thu, 3 Apr 2025 05:51:30 +0000 Subject: [PATCH 041/111] Fix `BitMapEditor` crash when bitmap is empty --- editor/plugins/bit_map_editor_plugin.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/editor/plugins/bit_map_editor_plugin.cpp b/editor/plugins/bit_map_editor_plugin.cpp index cb4d8d49112e..7d5724efb788 100644 --- a/editor/plugins/bit_map_editor_plugin.cpp +++ b/editor/plugins/bit_map_editor_plugin.cpp @@ -41,7 +41,11 @@ void BitMapEditor::setup(const Ref &p_bitmap) { Ref bitmap_texture = ImageTexture::create_from_image(p_bitmap->convert_to_image()); texture_rect->set_texture(bitmap_texture); - centering_container->set_ratio(bitmap_texture->get_size().aspect()); + if (bitmap_texture.is_valid()) { + centering_container->set_custom_minimum_size(Size2(0, 250) * EDSCALE); + centering_container->set_ratio(bitmap_texture->get_size().aspect()); + outline_overlay->connect(SceneStringName(draw), callable_mp(this, &BitMapEditor::_draw_outline)); + } size_label->set_text(vformat(U"%s×%s", p_bitmap->get_size().width, p_bitmap->get_size().height)); } @@ -70,7 +74,6 @@ BitMapEditor::BitMapEditor() { add_child(margin_container); centering_container = memnew(AspectRatioContainer); - centering_container->set_custom_minimum_size(Size2(0, 250) * EDSCALE); margin_container->add_child(centering_container); texture_rect = memnew(TextureRect); @@ -79,7 +82,6 @@ BitMapEditor::BitMapEditor() { centering_container->add_child(texture_rect); outline_overlay = memnew(Control); - outline_overlay->connect(SceneStringName(draw), callable_mp(this, &BitMapEditor::_draw_outline)); centering_container->add_child(outline_overlay); size_label = memnew(Label); From 8af7805ce44c894fe8afcebc53d6c1ed406af8ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Thu, 3 Apr 2025 11:09:37 +0300 Subject: [PATCH 042/111] Make `swap_cancel_ok` setting 3-state instead of boolean. --- doc/classes/EditorSettings.xml | 2 +- doc/classes/ProjectSettings.xml | 7 +++++-- editor/project_manager.cpp | 6 +++++- editor/project_manager/quick_settings_dialog.cpp | 6 +++++- scene/register_scene_types.cpp | 8 ++++---- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index 2879b6e09b98..cb910eb84677 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -805,7 +805,7 @@ How to position the Cancel and OK buttons in the editor's [AcceptDialog]s. Different platforms have different standard behaviors for this, which can be overridden using this setting. This is useful if you use Godot both on Windows and macOS/Linux and your Godot muscle memory is stronger than your OS specific one. - - [b]Auto[/b] follows the platform convention: Cancel first on macOS and Linux, OK first on Windows. + - [b]Auto[/b] follows the platform convention: OK first on Windows, KDE, and LXQt, Cancel first on macOS and other Linux desktop environments. - [b]Cancel First[/b] forces the ordering Cancel/OK. - [b]OK First[/b] forces the ordering OK/Cancel. diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 05d8d617bc7e..d66c83a7effd 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -1135,8 +1135,11 @@ If [code]true[/code], snaps [Control] node vertices to the nearest pixel to ensure they remain crisp even when the camera moves or zooms. - - If [code]true[/code], swaps [b]Cancel[/b] and [b]OK[/b] buttons in dialogs on Windows to follow interface conventions. [method DisplayServer.get_swap_cancel_ok] can be used to query whether buttons are swapped at run-time. + + How to position the Cancel and OK buttons in the project's [AcceptDialog]s. Different platforms have different standard behaviors for this, which can be overridden using this setting. + - [b]Auto[/b] ([code]0[/code]) follows the platform convention: OK first on Windows, KDE, and LXQt, Cancel first on macOS and other Linux desktop environments. [method DisplayServer.get_swap_cancel_ok] can be used to query whether buttons are swapped at run-time. + - [b]Cancel First[/b] ([code]1[/code]) forces the ordering Cancel/OK. + - [b]OK First[/b] ([code]2[/code]) forces the ordering OK/Cancel. [b]Note:[/b] This doesn't affect native dialogs such as the ones spawned by [method DisplayServer.dialog_show]. diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 848ce62de22d..16c3721060fd 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -1630,7 +1630,11 @@ ProjectManager::ProjectManager() { ask_update_settings = memnew(ConfirmationDialog); ask_update_settings->set_autowrap(true); ask_update_settings->get_ok_button()->connect(SceneStringName(pressed), callable_mp(this, &ProjectManager::_open_selected_projects_with_migration)); - full_convert_button = ask_update_settings->add_button(TTR("Convert Full Project"), !GLOBAL_GET("gui/common/swap_cancel_ok")); + int ed_swap_cancel_ok = EDITOR_GET("interface/editor/accept_dialog_cancel_ok_buttons"); + if (ed_swap_cancel_ok == 0) { + ed_swap_cancel_ok = DisplayServer::get_singleton()->get_swap_cancel_ok() ? 2 : 1; + } + full_convert_button = ask_update_settings->add_button(TTR("Convert Full Project"), ed_swap_cancel_ok != 2); full_convert_button->connect(SceneStringName(pressed), callable_mp(this, &ProjectManager::_full_convert_button_pressed)); add_child(ask_update_settings); diff --git a/editor/project_manager/quick_settings_dialog.cpp b/editor/project_manager/quick_settings_dialog.cpp index a805f6c75e60..923c72287a13 100644 --- a/editor/project_manager/quick_settings_dialog.cpp +++ b/editor/project_manager/quick_settings_dialog.cpp @@ -192,7 +192,11 @@ void QuickSettingsDialog::_set_setting_value(const String &p_setting, const Vari restart_required_label->show(); if (!restart_required_button) { - restart_required_button = add_button(TTR("Restart Now"), !GLOBAL_GET("gui/common/swap_cancel_ok")); + int ed_swap_cancel_ok = EDITOR_GET("interface/editor/accept_dialog_cancel_ok_buttons"); + if (ed_swap_cancel_ok == 0) { + ed_swap_cancel_ok = DisplayServer::get_singleton()->get_swap_cancel_ok() ? 2 : 1; + } + restart_required_button = add_button(TTR("Restart Now"), ed_swap_cancel_ok != 2); restart_required_button->connect(SceneStringName(pressed), callable_mp(this, &QuickSettingsDialog::_request_restart)); } } diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 006f9a45a8ab..eaa809b1eb8b 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -521,11 +521,11 @@ void register_scene_types() { OS::get_singleton()->yield(); // may take time to init - bool swap_cancel_ok = false; - if (DisplayServer::get_singleton()) { - swap_cancel_ok = GLOBAL_DEF_NOVAL("gui/common/swap_cancel_ok", bool(DisplayServer::get_singleton()->get_swap_cancel_ok())); + int swap_cancel_ok = GLOBAL_DEF(PropertyInfo(Variant::INT, "gui/common/swap_cancel_ok", PROPERTY_HINT_ENUM, "Auto,Cancel First,OK First"), 0); + if (DisplayServer::get_singleton() && swap_cancel_ok == 0) { + swap_cancel_ok = DisplayServer::get_singleton()->get_swap_cancel_ok() ? 2 : 1; } - AcceptDialog::set_swap_cancel_ok(swap_cancel_ok); + AcceptDialog::set_swap_cancel_ok(swap_cancel_ok == 2); #endif int root_dir = GLOBAL_GET("internationalization/rendering/root_node_layout_direction"); From 9c574c6373cc77c3ca375de70ba081c00e7f10d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Thu, 3 Apr 2025 12:15:27 +0300 Subject: [PATCH 043/111] Detect KDE/LXQt and swap OK/Cancel buttons to Windows style. --- platform/linuxbsd/wayland/display_server_wayland.cpp | 8 ++++++++ platform/linuxbsd/wayland/display_server_wayland.h | 3 +++ platform/linuxbsd/x11/display_server_x11.cpp | 10 +++++++++- platform/linuxbsd/x11/display_server_x11.h | 3 +++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index 1fe5df1d7709..1d1d9ee33f0d 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -1142,6 +1142,10 @@ void DisplayServerWayland::cursor_set_custom_image(const Ref &p_cursor } } +bool DisplayServerWayland::get_swap_cancel_ok() { + return swap_cancel_ok; +} + int DisplayServerWayland::keyboard_get_layout_count() const { MutexLock mutex_lock(wayland_thread.mutex); @@ -1450,6 +1454,10 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win r_error = ERR_UNAVAILABLE; context = p_context; + String current_desk = OS::get_singleton()->get_environment("XDG_CURRENT_DESKTOP").to_lower(); + String session_desk = OS::get_singleton()->get_environment("XDG_SESSION_DESKTOP").to_lower(); + swap_cancel_ok = (current_desk.contains("kde") || session_desk.contains("kde") || current_desk.contains("lxqt") || session_desk.contains("lxqt")); + Error thread_err = wayland_thread.init(); if (thread_err != OK) { diff --git a/platform/linuxbsd/wayland/display_server_wayland.h b/platform/linuxbsd/wayland/display_server_wayland.h index c5f7e0548d24..0fa4b9d6a612 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.h +++ b/platform/linuxbsd/wayland/display_server_wayland.h @@ -123,6 +123,7 @@ class DisplayServerWayland : public DisplayServer { WaylandThread wayland_thread; Context context; + bool swap_cancel_ok = false; String ime_text; Vector2i ime_selection; @@ -295,6 +296,8 @@ class DisplayServerWayland : public DisplayServer { virtual CursorShape cursor_get_shape() const override; virtual void cursor_set_custom_image(const Ref &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) override; + virtual bool get_swap_cancel_ok() override; + virtual int keyboard_get_layout_count() const override; virtual int keyboard_get_current_layout() const override; virtual void keyboard_set_current_layout(int p_index) override; diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index a7efff303589..5f2850c83c52 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -3395,6 +3395,10 @@ void DisplayServerX11::cursor_set_custom_image(const Ref &p_cursor, Cu } } +bool DisplayServerX11::get_swap_cancel_ok() { + return swap_cancel_ok; +} + int DisplayServerX11::keyboard_get_layout_count() const { int _group_count = 0; XkbDescRec *kbd = XkbAllocKeyboard(); @@ -6515,8 +6519,12 @@ static ::XIMStyle _get_best_xim_style(const ::XIMStyle &p_style_a, const ::XIMSt DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error) { KeyMappingX11::initialize(); + String current_desk = OS::get_singleton()->get_environment("XDG_CURRENT_DESKTOP").to_lower(); + String session_desk = OS::get_singleton()->get_environment("XDG_SESSION_DESKTOP").to_lower(); + swap_cancel_ok = (current_desk.contains("kde") || session_desk.contains("kde") || current_desk.contains("lxqt") || session_desk.contains("lxqt")); + xwayland = OS::get_singleton()->get_environment("XDG_SESSION_TYPE").to_lower() == "wayland"; - kde5_embed_workaround = OS::get_singleton()->get_environment("XDG_CURRENT_DESKTOP").to_lower() == "kde" && OS::get_singleton()->get_environment("KDE_SESSION_VERSION") == "5"; + kde5_embed_workaround = current_desk == "kde" && OS::get_singleton()->get_environment("KDE_SESSION_VERSION") == "5"; native_menu = memnew(NativeMenu); context = p_context; diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h index fe9322ae5659..25bf3111dc29 100644 --- a/platform/linuxbsd/x11/display_server_x11.h +++ b/platform/linuxbsd/x11/display_server_x11.h @@ -359,6 +359,7 @@ class DisplayServerX11 : public DisplayServer { void _update_context(WindowData &wd); Context context = CONTEXT_ENGINE; + bool swap_cancel_ok = false; WindowID _get_focused_window_or_popup() const; bool _window_focus_check(); @@ -550,6 +551,8 @@ class DisplayServerX11 : public DisplayServer { virtual CursorShape cursor_get_shape() const override; virtual void cursor_set_custom_image(const Ref &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) override; + virtual bool get_swap_cancel_ok() override; + virtual int keyboard_get_layout_count() const override; virtual int keyboard_get_current_layout() const override; virtual void keyboard_set_current_layout(int p_index) override; From a5a07ace0289c02d2c93f89a2ecdcd49b544e54e Mon Sep 17 00:00:00 2001 From: LuoZhihao Date: Fri, 4 Apr 2025 03:34:11 +0800 Subject: [PATCH 044/111] PortableCompressedTexture: Fix create compressed format from image --- scene/resources/portable_compressed_texture.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scene/resources/portable_compressed_texture.cpp b/scene/resources/portable_compressed_texture.cpp index 3a7d0991f4bd..694517aefbd8 100644 --- a/scene/resources/portable_compressed_texture.cpp +++ b/scene/resources/portable_compressed_texture.cpp @@ -171,6 +171,7 @@ void PortableCompressedTexture2D::create_from_image(const Ref &p_image, C } } break; case COMPRESSION_MODE_BASIS_UNIVERSAL: { + ERR_FAIL_COND(p_image->is_compressed()); encode_uint16(DATA_FORMAT_BASIS_UNIVERSAL, buffer.ptrw() + 2); Image::UsedChannels uc = p_image->detect_used_channels(p_normal_map ? Image::COMPRESS_SOURCE_NORMAL : Image::COMPRESS_SOURCE_GENERIC); Vector budata = Image::basis_universal_packer(p_image, uc); @@ -180,6 +181,7 @@ void PortableCompressedTexture2D::create_from_image(const Ref &p_image, C case COMPRESSION_MODE_S3TC: case COMPRESSION_MODE_ETC2: case COMPRESSION_MODE_BPTC: { + ERR_FAIL_COND(p_image->is_compressed()); encode_uint16(DATA_FORMAT_IMAGE, buffer.ptrw() + 2); Ref copy = p_image->duplicate(); switch (p_compression_mode) { @@ -195,7 +197,7 @@ void PortableCompressedTexture2D::create_from_image(const Ref &p_image, C default: { }; } - + encode_uint32(copy->get_format(), buffer.ptrw() + 4); buffer.append_array(copy->get_data()); } break; From a612347f335795396fd01afb3e6478b852b217cd Mon Sep 17 00:00:00 2001 From: BrotherShort <129957860+BrotherShort@users.noreply.github.com> Date: Sun, 30 Mar 2025 04:11:24 +0800 Subject: [PATCH 045/111] fix TextEdit VScroll max tolerance newline Co-Authored-By: Kit Bishop --- scene/gui/text_edit.cpp | 7 +++---- tests/scene/test_text_edit.h | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index abb4a2f21583..47b0befa29d6 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -852,7 +852,7 @@ void TextEdit::_notification(int p_what) { } int first_vis_line = get_first_visible_line() - 1; - int draw_amount = visible_rows + (smooth_scroll_enabled ? 1 : 0); + int draw_amount = visible_rows + 1; draw_amount += draw_placeholder ? placeholder_wrapped_rows.size() - 1 : get_line_wrap_count(first_vis_line + 1); // Draw minimap. @@ -4639,7 +4639,7 @@ int TextEdit::get_minimap_line_at_pos(const Point2i &p_pos) const { int minimap_visible_lines = get_minimap_visible_lines(); int visible_rows = get_visible_line_count() + 1; int first_vis_line = get_first_visible_line() - 1; - int draw_amount = visible_rows + (smooth_scroll_enabled ? 1 : 0); + int draw_amount = visible_rows + 1; draw_amount += get_line_wrap_count(first_vis_line + 1); int minimap_line_height = (minimap_char_size.y + minimap_line_spacing); @@ -8053,7 +8053,7 @@ void TextEdit::_update_scrollbars() { int visible_rows = get_visible_line_count(); int total_rows = draw_placeholder ? placeholder_wrapped_rows.size() : get_total_visible_line_count(); - if (scroll_past_end_of_file_enabled && !fit_content_height) { + if ((scroll_past_end_of_file_enabled && !fit_content_height) || visible_rows == 0) { total_rows += visible_rows - 1; } @@ -8076,7 +8076,6 @@ void TextEdit::_update_scrollbars() { v_scroll->set_max(total_rows + _get_visible_lines_offset()); v_scroll->set_page(visible_rows + _get_visible_lines_offset()); set_v_scroll(get_v_scroll()); - } else { first_visible_line = 0; first_visible_line_wrap_ofs = 0; diff --git a/tests/scene/test_text_edit.h b/tests/scene/test_text_edit.h index 8a10c0b6ee59..19db4f19e17e 100644 --- a/tests/scene/test_text_edit.h +++ b/tests/scene/test_text_edit.h @@ -7920,6 +7920,20 @@ TEST_CASE("[SceneTree][TextEdit] viewport") { memdelete(text_edit); } +TEST_CASE("[SceneTree][TextEdit] small height value") { + TextEdit *text_edit = memnew(TextEdit); + SceneTree::get_singleton()->get_root()->add_child(text_edit); + + text_edit->set_size(Size2(800, 32)); + text_edit->set_text("0\n1\n2"); + MessageQueue::get_singleton()->flush(); + + text_edit->set_v_scroll(100); + CHECK(text_edit->get_v_scroll() < 3); + + memdelete(text_edit); +} + TEST_CASE("[SceneTree][TextEdit] setter getters") { TextEdit *text_edit = memnew(TextEdit); SceneTree::get_singleton()->get_root()->add_child(text_edit); From 89807082d8ceb507a44e2bc4c1dbbd86f42b9cfa Mon Sep 17 00:00:00 2001 From: Anish Mishra Date: Thu, 3 Apr 2025 18:05:30 +0530 Subject: [PATCH 046/111] Android Editor: Auto create `nomedia` file to hide project files in media apps --- editor/editor_file_system.cpp | 13 +++++++++++++ editor/project_manager/project_dialog.cpp | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index be5081db402c..8dec50d5aa30 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -1068,6 +1068,19 @@ void EditorFileSystem::scan() { // to be loaded to continue the scan and reimportations. if (first_scan) { _first_scan_filesystem(); +#ifdef ANDROID_ENABLED + const String nomedia_file_path = ProjectSettings::get_singleton()->get_resource_path().path_join(".nomedia"); + if (!FileAccess::exists(nomedia_file_path)) { + // Create a .nomedia file to hide assets from media apps on Android. + Ref f = FileAccess::open(nomedia_file_path, FileAccess::WRITE); + if (f.is_null()) { + // .nomedia isn't so critical. + ERR_PRINT("Couldn't create .nomedia in project path."); + } else { + f->close(); + } + } +#endif } _update_extensions(); diff --git a/editor/project_manager/project_dialog.cpp b/editor/project_manager/project_dialog.cpp index cf0ffcfa71e5..a2aca198035f 100644 --- a/editor/project_manager/project_dialog.cpp +++ b/editor/project_manager/project_dialog.cpp @@ -725,6 +725,17 @@ void ProjectDialog::ok_pressed() { hide(); if (mode == MODE_NEW || mode == MODE_IMPORT || mode == MODE_INSTALL) { +#ifdef ANDROID_ENABLED + // Create a .nomedia file to hide assets from media apps on Android. + const String nomedia_file_path = path.path_join(".nomedia"); + Ref f2 = FileAccess::open(nomedia_file_path, FileAccess::WRITE); + if (f2.is_null()) { + // .nomedia isn't so critical. + ERR_PRINT("Couldn't create .nomedia in project path."); + } else { + f2->close(); + } +#endif emit_signal(SNAME("project_created"), path, edit_check_box->is_pressed()); } else if (mode == MODE_RENAME) { emit_signal(SNAME("projects_updated")); From 0c53fe5e60256871d100f2e44568a32681de2ce6 Mon Sep 17 00:00:00 2001 From: kobewi Date: Thu, 3 Apr 2025 15:31:36 +0200 Subject: [PATCH 047/111] Cleanup QuickOpenDialog history and fix UID errors --- editor/gui/editor_quick_open_dialog.cpp | 31 ++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/editor/gui/editor_quick_open_dialog.cpp b/editor/gui/editor_quick_open_dialog.cpp index 71b92045b28c..e95e15176faf 100644 --- a/editor/gui/editor_quick_open_dialog.cpp +++ b/editor/gui/editor_quick_open_dialog.cpp @@ -343,18 +343,31 @@ void QuickOpenResultContainer::init(const Vector &p_base_types) { // Load history when opening for the first time. file_type_icons.insert(SNAME("__default_icon"), get_editor_theme_icon(SNAME("Object"))); + bool history_modified = false; List history_keys; history_file->get_section_keys("selected_history", &history_keys); for (const String &type : history_keys) { const StringName type_name = type; const PackedStringArray paths = history_file->get_value("selected_history", type); + PackedStringArray cleaned_paths; + cleaned_paths.resize(paths.size()); + Vector loaded_candidates; loaded_candidates.resize(paths.size()); { QuickOpenResultCandidate *candidates_write = loaded_candidates.ptrw(); + String *cleanup_write = cleaned_paths.ptrw(); int i = 0; - for (const String &path : paths) { + for (String path : paths) { + if (path.begins_with("uid://")) { + ResourceUID::ID id = ResourceUID::get_singleton()->text_to_id(path); + if (!ResourceUID::get_singleton()->has_id(id)) { + continue; + } + path = ResourceUID::get_singleton()->get_id_path(id); + } + if (!ResourceLoader::exists(path)) { continue; } @@ -363,13 +376,29 @@ void QuickOpenResultContainer::init(const Vector &p_base_types) { QuickOpenResultCandidate candidate; _setup_candidate(candidate, path); candidates_write[i] = candidate; + cleanup_write[i] = path; i++; } loaded_candidates.resize(i); + cleaned_paths.resize(i); selected_history.insert(type, loaded_candidates); + + if (i < paths.size()) { + // Some paths removed, need to update history. + if (i == 0) { + history_file->erase_section_key("selected_history", type); + } else { + history_file->set_value("selected_history", type, cleaned_paths); + } + history_modified = true; + } } } + if (history_modified) { + history_file->save(_get_cache_file_path()); + } } + _create_initial_results(); } From 585cc1693ce1121fcfcf6a1ae218d67c908c7119 Mon Sep 17 00:00:00 2001 From: Lukas Tenbrink Date: Thu, 3 Apr 2025 17:18:28 +0200 Subject: [PATCH 048/111] Remove unused `get_inheritance_list_static` from `GDCLASS`. --- core/object/object.h | 6 ------ tests/core/object/test_object.h | 9 --------- 2 files changed, 15 deletions(-) diff --git a/core/object/object.h b/core/object/object.h index 4275f4ca16e4..a57a3b71c688 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -432,10 +432,6 @@ public: static _FORCE_INLINE_ String get_parent_class_static() { \ return m_inherits::get_class_static(); \ } \ - static void get_inheritance_list_static(List *p_inheritance_list) { \ - m_inherits::get_inheritance_list_static(p_inheritance_list); \ - p_inheritance_list->push_back(String(#m_class)); \ - } \ virtual bool is_class(const String &p_class) const override { \ if (_get_extension() && _get_extension()->is_class(p_class)) { \ return true; \ @@ -817,8 +813,6 @@ class Object { }; /* TYPE API */ - static void get_inheritance_list_static(List *p_inheritance_list) { p_inheritance_list->push_back("Object"); } - static String get_class_static() { return "Object"; } static String get_parent_class_static() { return String(); } diff --git a/tests/core/object/test_object.h b/tests/core/object/test_object.h index 03119efcc288..0ca0b17fd2aa 100644 --- a/tests/core/object/test_object.h +++ b/tests/core/object/test_object.h @@ -143,15 +143,6 @@ TEST_CASE("[Object] Core getters") { CHECK_MESSAGE( object.get_save_class() == "Object", "The returned save class should match the expected value."); - - List inheritance_list; - object.get_inheritance_list_static(&inheritance_list); - CHECK_MESSAGE( - inheritance_list.size() == 1, - "The inheritance list should consist of Object only"); - CHECK_MESSAGE( - inheritance_list.front()->get() == "Object", - "The inheritance list should consist of Object only"); } TEST_CASE("[Object] Metadata") { From 03d9260255e20a5a20d3a0b5746826355b0a76f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Thu, 3 Apr 2025 18:47:23 +0300 Subject: [PATCH 049/111] [macOS] Fix native menu submenu items have wrong action and accelerators set. --- platform/macos/godot_menu_item.h | 1 + platform/macos/godot_menu_item.mm | 1 + platform/macos/native_menu_macos.mm | 30 +++++++++++++++++++++++------ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/platform/macos/godot_menu_item.h b/platform/macos/godot_menu_item.h index ed63e78ec865..95cc91f31149 100644 --- a/platform/macos/godot_menu_item.h +++ b/platform/macos/godot_menu_item.h @@ -50,6 +50,7 @@ enum GlobalMenuCheckType { Callable key_callback; Callable hover_callback; Variant meta; + Key accel; GlobalMenuCheckType checkable_type; bool checked; int max_states; diff --git a/platform/macos/godot_menu_item.mm b/platform/macos/godot_menu_item.mm index 687b4e85a99e..494956762718 100644 --- a/platform/macos/godot_menu_item.mm +++ b/platform/macos/godot_menu_item.mm @@ -41,6 +41,7 @@ - (id)init { self->checked = false; self->max_states = 0; self->state = 0; + self->accel = Key::NONE; return self; } diff --git a/platform/macos/native_menu_macos.mm b/platform/macos/native_menu_macos.mm index bd3ccf25f5c8..33bfb210ffd1 100644 --- a/platform/macos/native_menu_macos.mm +++ b/platform/macos/native_menu_macos.mm @@ -415,6 +415,7 @@ obj->callback = p_callback; obj->key_callback = p_key_callback; obj->meta = p_tag; + obj->accel = p_accel; [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)]; [menu_item setRepresentedObject:obj]; } @@ -433,6 +434,7 @@ obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_CHECK_BOX; + obj->accel = p_accel; [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)]; [menu_item setRepresentedObject:obj]; } @@ -450,6 +452,7 @@ obj->callback = p_callback; obj->key_callback = p_key_callback; obj->meta = p_tag; + obj->accel = p_accel; DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (ds && p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) { obj->img = p_icon->get_image(); @@ -479,6 +482,7 @@ obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_CHECK_BOX; + obj->accel = p_accel; DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (ds && p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) { obj->img = p_icon->get_image(); @@ -508,6 +512,7 @@ obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_RADIO_BUTTON; + obj->accel = p_accel; [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)]; [menu_item setRepresentedObject:obj]; } @@ -526,6 +531,7 @@ obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_RADIO_BUTTON; + obj->accel = p_accel; DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (ds && p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) { obj->img = p_icon->get_image(); @@ -556,6 +562,7 @@ obj->meta = p_tag; obj->max_states = p_max_states; obj->state = p_default_state; + obj->accel = p_accel; [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)]; [menu_item setRepresentedObject:obj]; } @@ -1096,6 +1103,8 @@ NSMenuItem *menu_item = [md->menu itemAtIndex:p_idx]; if (menu_item) { [md->menu setSubmenu:md_sub->menu forItem:menu_item]; + [menu_item setAction:nil]; + [menu_item setKeyEquivalent:@""]; } } else { int item_start = _get_system_menu_start(md->menu); @@ -1108,7 +1117,11 @@ ERR_PRINT("Can't remove open menu!"); return; } + GodotMenuItem *obj = [menu_item representedObject]; + String keycode = KeyMappingMacOS::keycode_get_native_string(obj->accel & KeyModifierMask::CODE_MASK); [md->menu setSubmenu:nil forItem:menu_item]; + [menu_item setAction:@selector(globalMenuCallback:)]; + [menu_item setKeyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]]; } } } @@ -1124,12 +1137,17 @@ ERR_FAIL_COND(p_idx >= item_start + item_count); NSMenuItem *menu_item = [md->menu itemAtIndex:p_idx]; if (menu_item) { - if (p_keycode == Key::NONE) { - [menu_item setKeyEquivalent:@""]; - } else { - [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_keycode)]; - String keycode = KeyMappingMacOS::keycode_get_native_string(p_keycode & KeyModifierMask::CODE_MASK); - [menu_item setKeyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]]; + GodotMenuItem *obj = [menu_item representedObject]; + obj->accel = p_keycode; + NSMenu *sub_menu = [menu_item submenu]; + if (!sub_menu) { + if (p_keycode == Key::NONE) { + [menu_item setKeyEquivalent:@""]; + } else { + [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_keycode)]; + String keycode = KeyMappingMacOS::keycode_get_native_string(p_keycode & KeyModifierMask::CODE_MASK); + [menu_item setKeyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]]; + } } } } From e1629f3d4f27369fffe284b813bf2f802bb7a819 Mon Sep 17 00:00:00 2001 From: LuoZhihao Date: Fri, 4 Apr 2025 00:22:18 +0800 Subject: [PATCH 050/111] Fix compiling with `disable_xr=yes` --- main/main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main/main.cpp b/main/main.cpp index 6121d893e3f3..0cea51cacf99 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -184,9 +184,9 @@ static PhysicsServer2D *physics_server_2d = nullptr; static PhysicsServer3DManager *physics_server_3d_manager = nullptr; static PhysicsServer3D *physics_server_3d = nullptr; #endif // PHYSICS_3D_DISABLED -#ifndef _3D_DISABLED +#ifndef XR_DISABLED static XRServer *xr_server = nullptr; -#endif // _3D_DISABLED +#endif // XR_DISABLED // We error out if setup2() doesn't turn this true static bool _start_success = false; @@ -4919,11 +4919,11 @@ void Main::cleanup(bool p_force) { EngineDebugger::deinitialize(); -#ifndef _3D_DISABLED +#ifndef XR_DISABLED if (xr_server) { memdelete(xr_server); } -#endif // _3D_DISABLED +#endif // XR_DISABLED if (audio_server) { audio_server->finish(); From f7dea2a2308816b5cc40ab1180bbd0fdae3a684d Mon Sep 17 00:00:00 2001 From: Thaddeus Crews Date: Mon, 31 Mar 2025 10:56:33 -0500 Subject: [PATCH 051/111] Core: Integrate warning suppression macro helpers --- core/io/packet_peer_udp.cpp | 26 +++++------ core/math/geometry_2d.h | 11 +---- core/object/method_bind.h | 11 ++--- core/object/script_language_extension.h | 10 +---- core/os/safe_binary_mutex.h | 9 +--- core/os/thread.h | 9 +--- core/templates/cowdata.h | 10 +---- core/templates/lru.h | 27 +++--------- core/typedefs.h | 43 +++++++++++++++++++ core/variant/binder_common.h | 9 +--- .../d3d12/rendering_device_driver_d3d12.cpp | 9 +--- drivers/metal/pixel_formats.h | 7 +-- drivers/metal/pixel_formats.mm | 15 +++---- drivers/unix/net_socket_unix.cpp | 9 +--- drivers/wasapi/audio_driver_wasapi.cpp | 10 +---- platform/ios/display_server_ios.mm | 5 +-- platform/ios/godot_view.mm | 5 +-- platform/macos/gl_manager_macos_legacy.h | 5 +-- platform/macos/gl_manager_macos_legacy.mm | 5 +-- platform/macos/godot_content_view.h | 5 +-- platform/windows/display_server_windows.cpp | 10 +---- platform/windows/drop_target_windows.h | 10 +---- platform/windows/os_windows.cpp | 9 +--- servers/display_server.cpp | 10 ++--- .../rendering/renderer_rd/effects/metal_fx.mm | 20 ++++----- 25 files changed, 119 insertions(+), 180 deletions(-) diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp index 3463c41ae7ff..91e9934fdcef 100644 --- a/core/io/packet_peer_udp.cpp +++ b/core/io/packet_peer_udp.cpp @@ -105,18 +105,16 @@ Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { return ERR_UNAVAILABLE; } -/* Bogus GCC warning here: - * In member function 'int RingBuffer::read(T*, int, bool) [with T = unsigned char]', - * inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:112:9, - * inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:99:7: - * Error: ./core/ring_buffer.h:68:46: error: writing 1 byte into a region of size 0 [-Werror=stringop-overflow=] - * 68 | p_buf[dst++] = read[pos + i]; - * | ~~~~~~~~~~~~~^~~~~~~ - */ -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic warning "-Wstringop-overflow=0" -#endif + /* Bogus GCC warning here: + * In member function 'int RingBuffer::read(T*, int, bool) [with T = unsigned char]', + * inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:112:9, + * inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:99:7: + * Error: ./core/ring_buffer.h:68:46: error: writing 1 byte into a region of size 0 [-Werror=stringop-overflow=] + * 68 | p_buf[dst++] = read[pos + i]; + * | ~~~~~~~~~~~~~^~~~~~~ + */ + GODOT_GCC_WARNING_PUSH + GODOT_GCC_PRAGMA(GCC diagnostic warning "-Wstringop-overflow=0") // Can't "ignore" this for some reason. uint32_t size = 0; uint8_t ipv6[16] = {}; @@ -129,9 +127,7 @@ Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { *r_buffer = packet_buffer; r_buffer_size = size; -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif + GODOT_GCC_WARNING_POP return OK; } diff --git a/core/math/geometry_2d.h b/core/math/geometry_2d.h index 3619ce27ccf6..fa5b0f061bda 100644 --- a/core/math/geometry_2d.h +++ b/core/math/geometry_2d.h @@ -167,11 +167,7 @@ class Geometry2D { return p_segment_a + n * d; // Inside. } -// Disable False Positives in MSVC compiler; we correctly check for 0 here to prevent a division by 0. -// See: https://github.com/godotengine/godot/pull/44274 -#ifdef _MSC_VER -#pragma warning(disable : 4723) -#endif + GODOT_MSVC_WARNING_PUSH_AND_IGNORE(4723) // Potential divide by 0. False positive (see: GH-44274). static bool line_intersects_line(const Vector2 &p_from_a, const Vector2 &p_dir_a, const Vector2 &p_from_b, const Vector2 &p_dir_b, Vector2 &r_result) { // See http://paulbourke.net/geometry/pointlineplane/ @@ -187,10 +183,7 @@ class Geometry2D { return true; } -// Re-enable division by 0 warning -#ifdef _MSC_VER -#pragma warning(default : 4723) -#endif + GODOT_MSVC_WARNING_POP static bool segment_intersects_segment(const Vector2 &p_from_a, const Vector2 &p_to_a, const Vector2 &p_from_b, const Vector2 &p_to_b, Vector2 *r_result) { Vector2 B = p_to_a - p_from_a; diff --git a/core/object/method_bind.h b/core/object/method_bind.h index 4edc5e823aa6..72a7d53885ec 100644 --- a/core/object/method_bind.h +++ b/core/object/method_bind.h @@ -257,11 +257,8 @@ class MethodBindVarArgTR : public MethodBindVarArgBase, friend class MethodBindVarArgBase, T, R, true>; public: -#if defined(SANITIZERS_ENABLED) && defined(__GNUC__) && !defined(__clang__) - // Workaround GH-66343 raised only with UBSAN, seems to be a false positive. -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif + GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Wmaybe-uninitialized") // Workaround GH-66343 raised only with UBSAN, seems to be a false positive. + virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override { #ifdef TOOLS_ENABLED ERR_FAIL_COND_V_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == MethodBind::get_instance_class(), Variant(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name())); @@ -269,9 +266,7 @@ class MethodBindVarArgTR : public MethodBindVarArgBase, return (static_cast(p_object)->*MethodBindVarArgBase, T, R, true>::method)(p_args, p_arg_count, r_error); } -#if defined(SANITIZERS_ENABLED) && defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif + GODOT_GCC_WARNING_POP MethodBindVarArgTR( R (T::*p_method)(const Variant **, int, Callable::CallError &), diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index 8a401bb86e98..a8e47eef4425 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -711,11 +711,7 @@ class ScriptInstanceExtension : public ScriptInstance { GDExtensionScriptInstanceDataPtr instance = nullptr; -// There should not be warnings on explicit casts. -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wignored-qualifiers" -#endif + GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Wignored-qualifiers") // There should not be warnings on explicit casts. virtual bool set(const StringName &p_name, const Variant &p_value) override { if (native_info->set_func) { @@ -963,7 +959,5 @@ class ScriptInstanceExtension : public ScriptInstance { #endif // DISABLE_DEPRECATED } -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif + GODOT_GCC_WARNING_POP }; diff --git a/core/os/safe_binary_mutex.h b/core/os/safe_binary_mutex.h index 11b03e6fee20..c353ca536ed2 100644 --- a/core/os/safe_binary_mutex.h +++ b/core/os/safe_binary_mutex.h @@ -36,10 +36,7 @@ #ifdef THREADS_ENABLED -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wundefined-var-template" -#endif +GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wundefined-var-template") // A very special kind of mutex, used in scenarios where these // requirements hold at the same time: @@ -119,9 +116,7 @@ class MutexLock> { // TODO: Implement a `try_temp_relock` if needed (will also need a dummy method below). }; -#ifdef __clang__ -#pragma clang diagnostic pop -#endif +GODOT_CLANG_WARNING_POP #else // No threads. diff --git a/core/os/thread.h b/core/os/thread.h index f684e98df773..f5c9a20e59e6 100644 --- a/core/os/thread.h +++ b/core/os/thread.h @@ -92,14 +92,9 @@ class Thread { }; #if defined(__cpp_lib_hardware_interference_size) && !defined(ANDROID_ENABLED) // This would be OK with NDK >= 26. -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Winterference-size" -#endif + GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Winterference-size") static constexpr size_t CACHE_LINE_BYTES = std::hardware_destructive_interference_size; -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif + GODOT_GCC_WARNING_POP #else // At a negligible memory cost, we use a conservatively high value. static constexpr size_t CACHE_LINE_BYTES = 128; diff --git a/core/templates/cowdata.h b/core/templates/cowdata.h index 0d517adad076..f4a7211be719 100644 --- a/core/templates/cowdata.h +++ b/core/templates/cowdata.h @@ -49,11 +49,7 @@ class VMap; static_assert(std::is_trivially_destructible_v>); -// Silence a false positive warning (see GH-52119). -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wplacement-new" -#endif +GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Wplacement-new") // Silence a false positive warning (see GH-52119). template class CowData { @@ -460,9 +456,7 @@ CowData::CowData(std::initializer_list p_init) { } } -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif +GODOT_GCC_WARNING_POP // Zero-constructing CowData initializes _ptr to nullptr (and thus empty). template diff --git a/core/templates/lru.h b/core/templates/lru.h index 1348c224d152..df15d4b63f05 100644 --- a/core/templates/lru.h +++ b/core/templates/lru.h @@ -33,18 +33,6 @@ #include "hash_map.h" #include "list.h" -#if defined(__GNUC__) && !defined(__clang__) -#define ADDRESS_DIAGNOSTIC_WARNING_DISABLE \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Waddress\""); - -#define ADDRESS_DIAGNOSTIC_POP \ - _Pragma("GCC diagnostic pop"); -#else -#define ADDRESS_DIAGNOSTIC_WARNING_DISABLE -#define ADDRESS_DIAGNOSTIC_POP -#endif - template , void (*BeforeEvict)(TKey &, TData &) = nullptr> class LRUCache { public: @@ -72,11 +60,11 @@ class LRUCache { Element n = _list.push_front(Pair(p_key, p_value)); if (e) { - ADDRESS_DIAGNOSTIC_WARNING_DISABLE; + GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Waddress") if constexpr (BeforeEvict != nullptr) { BeforeEvict((*e)->get().key, (*e)->get().data); } - ADDRESS_DIAGNOSTIC_POP; + GODOT_GCC_WARNING_POP _list.erase(*e); _map.erase(p_key); } @@ -84,11 +72,11 @@ class LRUCache { while (_map.size() > capacity) { Element d = _list.back(); - ADDRESS_DIAGNOSTIC_WARNING_DISABLE + GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Waddress") if constexpr (BeforeEvict != nullptr) { BeforeEvict(d->get().key, d->get().data); } - ADDRESS_DIAGNOSTIC_POP + GODOT_GCC_WARNING_POP _map.erase(d->get().key); _list.pop_back(); } @@ -141,11 +129,11 @@ class LRUCache { capacity = p_capacity; while (_map.size() > capacity) { Element d = _list.back(); - ADDRESS_DIAGNOSTIC_WARNING_DISABLE; + GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Waddress") if constexpr (BeforeEvict != nullptr) { BeforeEvict(d->get().key, d->get().data); } - ADDRESS_DIAGNOSTIC_POP; + GODOT_GCC_WARNING_POP _map.erase(d->get().key); _list.pop_back(); } @@ -160,6 +148,3 @@ class LRUCache { capacity = p_capacity; } }; - -#undef ADDRESS_DIAGNOSTIC_WARNING_DISABLE -#undef ADDRESS_DIAGNOSTIC_POP diff --git a/core/typedefs.h b/core/typedefs.h index 863f66d59934..104b2da179ef 100644 --- a/core/typedefs.h +++ b/core/typedefs.h @@ -344,3 +344,46 @@ struct is_zero_constructible : is_zero_constructible {}; template inline constexpr bool is_zero_constructible_v = is_zero_constructible::value; + +// Warning suppression helper macros. +#if defined(__clang__) +#define GODOT_CLANG_PRAGMA(m_content) _Pragma(#m_content) +#define GODOT_CLANG_WARNING_PUSH GODOT_CLANG_PRAGMA(clang diagnostic push) +#define GODOT_CLANG_WARNING_IGNORE(m_warning) GODOT_CLANG_PRAGMA(clang diagnostic ignored m_warning) +#define GODOT_CLANG_WARNING_POP GODOT_CLANG_PRAGMA(clang diagnostic pop) +#define GODOT_CLANG_WARNING_PUSH_AND_IGNORE(m_warning) GODOT_CLANG_WARNING_PUSH GODOT_CLANG_WARNING_IGNORE(m_warning) +#else +#define GODOT_CLANG_PRAGMA(m_content) +#define GODOT_CLANG_WARNING_PUSH +#define GODOT_CLANG_WARNING_IGNORE(m_warning) +#define GODOT_CLANG_WARNING_POP +#define GODOT_CLANG_WARNING_PUSH_AND_IGNORE(m_warning) +#endif + +#if defined(__GNUC__) && !defined(__clang__) +#define GODOT_GCC_PRAGMA(m_content) _Pragma(#m_content) +#define GODOT_GCC_WARNING_PUSH GODOT_GCC_PRAGMA(GCC diagnostic push) +#define GODOT_GCC_WARNING_IGNORE(m_warning) GODOT_GCC_PRAGMA(GCC diagnostic ignored m_warning) +#define GODOT_GCC_WARNING_POP GODOT_GCC_PRAGMA(GCC diagnostic pop) +#define GODOT_GCC_WARNING_PUSH_AND_IGNORE(m_warning) GODOT_GCC_WARNING_PUSH GODOT_GCC_WARNING_IGNORE(m_warning) +#else +#define GODOT_GCC_PRAGMA(m_content) +#define GODOT_GCC_WARNING_PUSH +#define GODOT_GCC_WARNING_IGNORE(m_warning) +#define GODOT_GCC_WARNING_POP +#define GODOT_GCC_WARNING_PUSH_AND_IGNORE(m_warning) +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +#define GODOT_MSVC_PRAGMA(m_command) __pragma(m_command) +#define GODOT_MSVC_WARNING_PUSH GODOT_MSVC_PRAGMA(warning(push)) +#define GODOT_MSVC_WARNING_IGNORE(m_warning) GODOT_MSVC_PRAGMA(warning(disable : m_warning)) +#define GODOT_MSVC_WARNING_POP GODOT_MSVC_PRAGMA(warning(pop)) +#define GODOT_MSVC_WARNING_PUSH_AND_IGNORE(m_warning) GODOT_MSVC_WARNING_PUSH GODOT_MSVC_WARNING_IGNORE(m_warning) +#else +#define GODOT_MSVC_PRAGMA(m_command) +#define GODOT_MSVC_WARNING_PUSH +#define GODOT_MSVC_WARNING_IGNORE(m_warning) +#define GODOT_MSVC_WARNING_POP +#define GODOT_MSVC_WARNING_PUSH_AND_IGNORE(m_warning) +#endif diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h index e8dc74f8ee04..1d1a0e8f5e2f 100644 --- a/core/variant/binder_common.h +++ b/core/variant/binder_common.h @@ -689,10 +689,7 @@ void call_with_validated_object_instance_args_static_retc(T *base, R (*p_method) // GCC raises "parameter 'p_args' set but not used" when P = {}, // it's not clever enough to treat other P values as making this branch valid. -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-but-set-parameter" -#endif +GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Wunused-but-set-parameter") template void call_get_argument_type_helper(int p_arg, int &index, Variant::Type &type) { @@ -1033,6 +1030,4 @@ void call_with_variant_args_static_dv(void (*p_method)(P...), const Variant **p_ call_with_variant_args_static(p_method, args, r_error, BuildIndexSequence{}); } -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif +GODOT_GCC_WARNING_POP diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp index 8081f1ca864d..a52430965a18 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp @@ -1336,14 +1336,9 @@ RDD::TextureID RenderingDeviceDriverD3D12::texture_create(const TextureFormat &p } tex_info->states_ptr = &tex_info->owner_info.states; tex_info->format = p_format.format; -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif + GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Wstrict-aliasing") tex_info->desc = *(CD3DX12_RESOURCE_DESC *)&resource_desc; -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif + GODOT_GCC_WARNING_POP tex_info->base_layer = 0; tex_info->layers = resource_desc.ArraySize(); tex_info->base_mip = 0; diff --git a/drivers/metal/pixel_formats.h b/drivers/metal/pixel_formats.h index ee021323ed3f..2db9be255771 100644 --- a/drivers/metal/pixel_formats.h +++ b/drivers/metal/pixel_formats.h @@ -50,8 +50,9 @@ /* permissions and limitations under the License. */ /**************************************************************************/ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#include "core/typedefs.h" + +GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wdeprecated-declarations") #import "inflection_map.h" #import "metal_device_properties.h" @@ -407,4 +408,4 @@ class API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) PixelFormats { TightLocalVector _mtl_vertex_format_descs; }; -#pragma clang diagnostic pop +GODOT_CLANG_WARNING_POP diff --git a/drivers/metal/pixel_formats.mm b/drivers/metal/pixel_formats.mm index c784faa8397b..86924c6530ac 100644 --- a/drivers/metal/pixel_formats.mm +++ b/drivers/metal/pixel_formats.mm @@ -450,8 +450,7 @@ void clear(T *p_val, size_t p_count = 1) { addDataFormatDesc(X8_D24_UNORM_PACK32, Invalid, Depth24Unorm_Stencil8, Invalid, Invalid, 1, 1, 4, DepthStencil); -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" + GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wunguarded-availability") addDataFormatDesc(BC1_RGB_UNORM_BLOCK, BC1_RGBA, Invalid, Invalid, Invalid, 4, 4, 8, Compressed); addDataFormatDesc(BC1_RGB_SRGB_BLOCK, BC1_RGBA_sRGB, Invalid, Invalid, Invalid, 4, 4, 8, Compressed); @@ -476,7 +475,7 @@ void clear(T *p_val, size_t p_count = 1) { addDataFormatDesc(BC7_UNORM_BLOCK, BC7_RGBAUnorm, Invalid, Invalid, Invalid, 4, 4, 16, Compressed); addDataFormatDesc(BC7_SRGB_BLOCK, BC7_RGBAUnorm_sRGB, Invalid, Invalid, Invalid, 4, 4, 16, Compressed); -#pragma clang diagnostic pop + GODOT_CLANG_WARNING_POP addDataFormatDesc(ETC2_R8G8B8_UNORM_BLOCK, ETC2_RGB8, Invalid, Invalid, Invalid, 4, 4, 8, Compressed); addDataFormatDesc(ETC2_R8G8B8_SRGB_BLOCK, ETC2_RGB8_sRGB, Invalid, Invalid, Invalid, 4, 4, 8, Compressed); @@ -729,8 +728,7 @@ void clear(T *p_val, size_t p_count = 1) { addMTLPixelFormatDescSRGB(ASTC_12x12_sRGB, ASTC_12x12, RF, ASTC_12x12_LDR); addMTLPixelFormatDesc(ASTC_12x12_HDR, ASTC_12x12, RF); -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" + GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wunguarded-availability") addMTLPixelFormatDesc(BC1_RGBA, BC1_RGBA, RF); addMTLPixelFormatDescSRGB(BC1_RGBA_sRGB, BC1_RGBA, RF, BC1_RGBA); @@ -747,7 +745,7 @@ void clear(T *p_val, size_t p_count = 1) { addMTLPixelFormatDesc(BC7_RGBAUnorm, BC7_RGBA, RF); addMTLPixelFormatDescSRGB(BC7_RGBAUnorm_sRGB, BC7_RGBA, RF, BC7_RGBAUnorm); -#pragma clang diagnostic pop + GODOT_CLANG_WARNING_POP // YUV pixel formats addMTLPixelFormatDesc(GBGR422, None, RF); @@ -968,8 +966,7 @@ void clear(T *p_val, size_t p_count = 1) { setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_12x10_HDR, None); setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_12x12_HDR, None); -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" + GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wunguarded-availability") bool noBC = !p_feat.supportsBCTextureCompression; setMTLPixFmtCapsIf(noBC, BC1_RGBA, None); @@ -987,7 +984,7 @@ void clear(T *p_val, size_t p_count = 1) { setMTLPixFmtCapsIf(noBC, BC7_RGBAUnorm, None); setMTLPixFmtCapsIf(noBC, BC7_RGBAUnorm_sRGB, None); -#pragma clang diagnostic pop + GODOT_CLANG_WARNING_POP setMTLPixFmtCapsIf(iosOnly2, BGRA10_XR, None); setMTLPixFmtCapsIf(iosOnly2, BGRA10_XR_sRGB, None); diff --git a/drivers/unix/net_socket_unix.cpp b/drivers/unix/net_socket_unix.cpp index 3eaf1b2885ad..06a1d42b254d 100644 --- a/drivers/unix/net_socket_unix.cpp +++ b/drivers/unix/net_socket_unix.cpp @@ -135,10 +135,7 @@ NetSocketUnix::~NetSocketUnix() { // Silence a warning reported in GH-27594. // EAGAIN and EWOULDBLOCK have the same value on most platforms, but it's not guaranteed. -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wlogical-op" -#endif +GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Wlogical-op") NetSocketUnix::NetError NetSocketUnix::_get_socket_error() const { if (errno == EISCONN) { @@ -163,9 +160,7 @@ NetSocketUnix::NetError NetSocketUnix::_get_socket_error() const { return ERR_NET_OTHER; } -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif +GODOT_GCC_WARNING_POP bool NetSocketUnix::_can_use_ip(const IPAddress &p_ip, const bool p_for_bind) const { if (p_for_bind && !(p_ip.is_valid() || p_ip.is_wildcard())) { diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index ac2104a31a76..bbccc6f28fd5 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -126,11 +126,7 @@ static bool default_input_device_changed = false; static int output_reinit_countdown = 0; static int input_reinit_countdown = 0; -// Silence warning due to a COM API weirdness (GH-35194). -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#endif +GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Wnon-virtual-dtor") // Silence warning due to a COM API weirdness (GH-35194). class CMMNotificationClient : public IMMNotificationClient { LONG _cRef = 1; @@ -196,9 +192,7 @@ class CMMNotificationClient : public IMMNotificationClient { } }; -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif +GODOT_GCC_WARNING_POP static CMMNotificationClient notif_client; diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm index 4a5a05d0eced..7c75fa0faa52 100644 --- a/platform/ios/display_server_ios.mm +++ b/platform/ios/display_server_ios.mm @@ -76,11 +76,10 @@ RenderingContextDriverVulkanIOS::WindowPlatformData vulkan; #endif #ifdef METAL_ENABLED -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" + GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wunguarded-availability") // Eliminate "RenderingContextDriverMetal is only available on iOS 14.0 or newer". RenderingContextDriverMetal::WindowPlatformData metal; -#pragma clang diagnostic pop + GODOT_CLANG_WARNING_POP #endif } wpd; diff --git a/platform/ios/godot_view.mm b/platform/ios/godot_view.mm index 552c4c262cf5..817835ee510c 100644 --- a/platform/ios/godot_view.mm +++ b/platform/ios/godot_view.mm @@ -82,10 +82,9 @@ @implementation GodotView layer = [GodotMetalLayer layer]; #endif } else if ([driverName isEqualToString:@"opengl3"]) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" // OpenGL is deprecated in iOS 12.0 + GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wdeprecated-declarations") // OpenGL is deprecated in iOS 12.0. layer = [GodotOpenGLLayer layer]; -#pragma clang diagnostic pop + GODOT_CLANG_WARNING_POP } else { return nil; } diff --git a/platform/macos/gl_manager_macos_legacy.h b/platform/macos/gl_manager_macos_legacy.h index 7188e052664a..0f19901da797 100644 --- a/platform/macos/gl_manager_macos_legacy.h +++ b/platform/macos/gl_manager_macos_legacy.h @@ -40,8 +40,7 @@ #import #import -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" // OpenGL is deprecated in macOS 10.14 +GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wdeprecated-declarations") // OpenGL is deprecated in macOS 10.14. typedef CGLError (*CGLEnablePtr)(CGLContextObj ctx, CGLContextEnable pname); typedef CGLError (*CGLSetParameterPtr)(CGLContextObj ctx, CGLContextParameter pname, const GLint *params); @@ -89,6 +88,6 @@ class GLManagerLegacy_MacOS { ~GLManagerLegacy_MacOS(); }; -#pragma clang diagnostic push +GODOT_CLANG_WARNING_PUSH #endif // MACOS_ENABLED && GLES3_ENABLED diff --git a/platform/macos/gl_manager_macos_legacy.mm b/platform/macos/gl_manager_macos_legacy.mm index 7dee5780cdd6..3f73d6596ecf 100644 --- a/platform/macos/gl_manager_macos_legacy.mm +++ b/platform/macos/gl_manager_macos_legacy.mm @@ -36,8 +36,7 @@ #include #include -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" // OpenGL is deprecated in macOS 10.14 +GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wdeprecated-declarations") // OpenGL is deprecated in macOS 10.14. Error GLManagerLegacy_MacOS::create_context(GLWindow &win) { NSOpenGLPixelFormatAttribute attributes[] = { @@ -204,6 +203,6 @@ release_current(); } -#pragma clang diagnostic pop +GODOT_CLANG_WARNING_POP #endif // MACOS_ENABLED && GLES3_ENABLED diff --git a/platform/macos/godot_content_view.h b/platform/macos/godot_content_view.h index 25d3a9e08e8e..98ca51fb1e22 100644 --- a/platform/macos/godot_content_view.h +++ b/platform/macos/godot_content_view.h @@ -54,8 +54,7 @@ @end -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" // OpenGL is deprecated in macOS 10.14 +GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wdeprecated-declarations") // OpenGL is deprecated in macOS 10.14. @interface GodotContentView : RootView { DisplayServer::WindowID window_id; @@ -78,4 +77,4 @@ @end -#pragma clang diagnostic pop +GODOT_CLANG_WARNING_POP diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 956a4a2f3d11..5d3fe5aa1136 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -322,11 +322,7 @@ Error DisplayServerWindows::file_dialog_with_options_show(const String &p_title, return _file_dialog_with_options_show(p_title, p_current_directory, p_root, p_filename, p_show_hidden, p_mode, p_filters, p_options, p_callback, true, p_window_id); } -// Silence warning due to a COM API weirdness. -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#endif +GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Wnon-virtual-dtor") // Silence warning due to a COM API weirdness. class FileDialogEventHandler : public IFileDialogEvents, public IFileDialogControlEvents { LONG ref_count = 1; @@ -445,9 +441,7 @@ class FileDialogEventHandler : public IFileDialogEvents, public IFileDialogContr virtual ~FileDialogEventHandler() {} }; -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif +GODOT_GCC_WARNING_POP LRESULT CALLBACK WndProcFileDialog(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { DisplayServerWindows *ds_win = static_cast(DisplayServer::get_singleton()); diff --git a/platform/windows/drop_target_windows.h b/platform/windows/drop_target_windows.h index 4964ee8501cd..4ab8698c59fa 100644 --- a/platform/windows/drop_target_windows.h +++ b/platform/windows/drop_target_windows.h @@ -34,11 +34,7 @@ #include -// Silence warning due to a COM API weirdness. -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#endif +GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Wnon-virtual-dtor") // Silence warning due to a COM API weirdness. // https://learn.microsoft.com/en-us/windows/win32/api/ole2/nf-ole2-dodragdrop#remarks class DropTargetWindows : public IDropTarget { @@ -69,6 +65,4 @@ class DropTargetWindows : public IDropTarget { HRESULT STDMETHODCALLTYPE Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) override; }; -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif +GODOT_GCC_WARNING_POP diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index fe2600d34595..a52ebfc974a3 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -1654,10 +1654,7 @@ Vector OS_Windows::get_system_fonts() const { return ret; } -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#endif +GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Wnon-virtual-dtor") // Silence warning due to a COM API weirdness. class FallbackTextAnalysisSource : public IDWriteTextAnalysisSource { LONG _cRef = 1; @@ -1741,9 +1738,7 @@ class FallbackTextAnalysisSource : public IDWriteTextAnalysisSource { virtual ~FallbackTextAnalysisSource() {} }; -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif +GODOT_GCC_WARNING_POP String OS_Windows::_get_default_fontname(const String &p_font_name) const { String font_name = p_font_name; diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 4992fa2c6c10..a8ae645d8940 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -1370,11 +1370,10 @@ bool DisplayServer::is_rendering_device_supported() { #endif #ifdef METAL_ENABLED if (rcd == nullptr) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" + GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wunguarded-availability") // Eliminate "RenderingContextDriverMetal is only available on iOS 14.0 or newer". rcd = memnew(RenderingContextDriverMetal); -#pragma clang diagnostic pop + GODOT_CLANG_WARNING_POP } #endif @@ -1453,11 +1452,10 @@ bool DisplayServer::can_create_rendering_device() { #endif #ifdef METAL_ENABLED if (rcd == nullptr) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" + GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wunguarded-availability") // Eliminate "RenderingContextDriverMetal is only available on iOS 14.0 or newer". rcd = memnew(RenderingContextDriverMetal); -#pragma clang diagnostic pop + GODOT_CLANG_WARNING_POP } #endif diff --git a/servers/rendering/renderer_rd/effects/metal_fx.mm b/servers/rendering/renderer_rd/effects/metal_fx.mm index e2273d446395..c3c81937229e 100644 --- a/servers/rendering/renderer_rd/effects/metal_fx.mm +++ b/servers/rendering/renderer_rd/effects/metal_fx.mm @@ -51,8 +51,7 @@ } void MFXSpatialEffect::callback(RDD *p_driver, RDD::CommandBufferID p_command_buffer, CallbackArgs *p_userdata) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" + GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wunguarded-availability") MDCommandBuffer *obj = (MDCommandBuffer *)(p_command_buffer.id); obj->end(); @@ -73,7 +72,7 @@ CallbackArgs::free(&p_userdata); -#pragma clang diagnostic pop + GODOT_CLANG_WARNING_POP } void MFXSpatialEffect::ensure_context(Ref p_render_buffers) { @@ -99,8 +98,7 @@ MFXSpatialContext *MFXSpatialEffect::create_context(CreateParams p_params) const { DEV_ASSERT(RD::get_singleton()->has_feature(RD::SUPPORTS_METALFX_SPATIAL)); -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" + GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wunguarded-availability") RenderingDeviceDriverMetal *rdd = (RenderingDeviceDriverMetal *)RD::get_singleton()->get_device_driver(); PixelFormats &pf = rdd->get_pixel_formats(); @@ -120,7 +118,7 @@ MFXSpatialContext *context = memnew(MFXSpatialContext); context->scaler = scaler; -#pragma clang diagnostic pop + GODOT_CLANG_WARNING_POP return context; } @@ -135,8 +133,7 @@ MFXTemporalContext *MFXTemporalEffect::create_context(CreateParams p_params) const { DEV_ASSERT(RD::get_singleton()->has_feature(RD::SUPPORTS_METALFX_TEMPORAL)); -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" + GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wunguarded-availability") RenderingDeviceDriverMetal *rdd = (RenderingDeviceDriverMetal *)RD::get_singleton()->get_device_driver(); PixelFormats &pf = rdd->get_pixel_formats(); @@ -164,7 +161,7 @@ scaler.motionVectorScaleY = p_params.motion_vector_scale.y; scaler.depthReversed = true; // Godot uses reverse Z per https://github.com/godotengine/godot/pull/88328 -#pragma clang diagnostic pop + GODOT_CLANG_WARNING_POP return context; } @@ -189,8 +186,7 @@ } void MFXTemporalEffect::callback(RDD *p_driver, RDD::CommandBufferID p_command_buffer, CallbackArgs *p_userdata) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" + GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wunguarded-availability") MDCommandBuffer *obj = (MDCommandBuffer *)(p_command_buffer.id); obj->end(); @@ -221,5 +217,5 @@ CallbackArgs::free(&p_userdata); -#pragma clang diagnostic pop + GODOT_CLANG_WARNING_POP } From 26bb395baaabf872c9b14eb33c213905dff18b4f Mon Sep 17 00:00:00 2001 From: "Silc Lizard (Tokage) Renew" <61938263+TokageItLab@users.noreply.github.com> Date: Thu, 6 Mar 2025 02:45:24 +0900 Subject: [PATCH 052/111] Add p_delta argument to _process_modification() and expose advance() --- doc/classes/Skeleton3D.xml | 11 ++++++ doc/classes/SkeletonModifier3D.xml | 11 +++++- scene/3d/look_at_modifier_3d.cpp | 10 ++---- scene/3d/look_at_modifier_3d.h | 2 +- .../3d/physics/physical_bone_simulator_3d.cpp | 2 +- scene/3d/physics/physical_bone_simulator_3d.h | 2 +- scene/3d/retarget_modifier_3d.cpp | 2 +- scene/3d/retarget_modifier_3d.h | 2 +- scene/3d/skeleton_3d.cpp | 34 ++++++++++++++----- scene/3d/skeleton_3d.h | 4 +++ scene/3d/skeleton_ik_3d.cpp | 4 +-- scene/3d/skeleton_ik_3d.h | 2 +- scene/3d/skeleton_modifier_3d.cpp | 18 +++++++--- scene/3d/skeleton_modifier_3d.h | 8 +++-- scene/3d/spring_bone_simulator_3d.cpp | 5 ++- scene/3d/spring_bone_simulator_3d.h | 2 +- scene/3d/xr/xr_body_modifier_3d.cpp | 2 +- scene/3d/xr/xr_body_modifier_3d.h | 2 +- scene/3d/xr/xr_hand_modifier_3d.cpp | 2 +- scene/3d/xr/xr_hand_modifier_3d.h | 2 +- 20 files changed, 87 insertions(+), 40 deletions(-) diff --git a/doc/classes/Skeleton3D.xml b/doc/classes/Skeleton3D.xml index aa751de5f24a..9a6fdc33f73c 100644 --- a/doc/classes/Skeleton3D.xml +++ b/doc/classes/Skeleton3D.xml @@ -20,6 +20,14 @@ [b]Note:[/b] Bone names should be unique, non empty, and cannot include the [code]:[/code] and [code]/[/code] characters. + + + + + Manually advance the child [SkeletonModifier3D]s by the specified time (in seconds). + [b]Note:[/b] The [param delta] is temporarily accumulated in the [Skeleton3D], and the deferred process uses the accumulated value to process the modification. + + @@ -420,5 +428,8 @@ Set a flag to process modification during process frames (see [constant Node.NOTIFICATION_INTERNAL_PROCESS]). + + Do not process modification. Use [method advance] to process the modification manually. + diff --git a/doc/classes/SkeletonModifier3D.xml b/doc/classes/SkeletonModifier3D.xml index 7e9814b16f8f..be75365105be 100644 --- a/doc/classes/SkeletonModifier3D.xml +++ b/doc/classes/SkeletonModifier3D.xml @@ -12,13 +12,22 @@ https://godotengine.org/article/design-of-the-skeleton-modifier-3d/ - + Override this virtual method to implement a custom skeleton modifier. You should do things like get the [Skeleton3D]'s current pose and apply the pose here. [method _process_modification] must not apply [member influence] to bone poses because the [Skeleton3D] automatically applies influence to all bone poses set by the modifier. + + + + + Override this virtual method to implement a custom skeleton modifier. You should do things like get the [Skeleton3D]'s current pose and apply the pose here. + [method _process_modification_with_delta] must not apply [member influence] to bone poses because the [Skeleton3D] automatically applies influence to all bone poses set by the modifier. + [param delta] is passed from parent [Skeleton3D]. See also [method Skeleton3D.advance]. + + diff --git a/scene/3d/look_at_modifier_3d.cpp b/scene/3d/look_at_modifier_3d.cpp index 1046cb67061c..c355abfbb75e 100644 --- a/scene/3d/look_at_modifier_3d.cpp +++ b/scene/3d/look_at_modifier_3d.cpp @@ -487,7 +487,7 @@ void LookAtModifier3D::_bind_methods() { BIND_ENUM_CONSTANT(ORIGIN_FROM_EXTERNAL_NODE); } -void LookAtModifier3D::_process_modification() { +void LookAtModifier3D::_process_modification(double p_delta) { if (!is_inside_tree()) { return; } @@ -570,13 +570,7 @@ void LookAtModifier3D::_process_modification() { // Do time-based interpolation. if (remaining > 0) { - double delta = 0.0; - if (skeleton->get_modifier_callback_mode_process() == Skeleton3D::MODIFIER_CALLBACK_MODE_PROCESS_IDLE) { - delta = get_process_delta_time(); - } else { - delta = get_physics_process_delta_time(); - } - remaining = MAX(0, remaining - time_step * delta); + remaining = MAX(0, remaining - time_step * p_delta); if (is_flippable) { // Interpolate through the rest same as AnimationTree blending for preventing to penetrate the bone into the body. Quaternion rest = skeleton->get_bone_rest(bone).basis.get_rotation_quaternion(); diff --git a/scene/3d/look_at_modifier_3d.h b/scene/3d/look_at_modifier_3d.h index 7a06d5a886a6..b8800636ee26 100644 --- a/scene/3d/look_at_modifier_3d.h +++ b/scene/3d/look_at_modifier_3d.h @@ -107,7 +107,7 @@ class LookAtModifier3D : public SkeletonModifier3D { static void _bind_methods(); - virtual void _process_modification() override; + virtual void _process_modification(double p_delta) override; public: void set_bone_name(const String &p_bone_name); diff --git a/scene/3d/physics/physical_bone_simulator_3d.cpp b/scene/3d/physics/physical_bone_simulator_3d.cpp index 491a3073732d..fe3cfecb463f 100644 --- a/scene/3d/physics/physical_bone_simulator_3d.cpp +++ b/scene/3d/physics/physical_bone_simulator_3d.cpp @@ -364,7 +364,7 @@ void PhysicalBoneSimulator3D::set_bone_global_pose(int p_bone, const Transform3D bones.write[p_bone].global_pose = p_pose; } -void PhysicalBoneSimulator3D::_process_modification() { +void PhysicalBoneSimulator3D::_process_modification(double p_delta) { Skeleton3D *skeleton = get_skeleton(); if (!skeleton) { return; diff --git a/scene/3d/physics/physical_bone_simulator_3d.h b/scene/3d/physics/physical_bone_simulator_3d.h index cbeea22e2ee2..f18024b34d7d 100644 --- a/scene/3d/physics/physical_bone_simulator_3d.h +++ b/scene/3d/physics/physical_bone_simulator_3d.h @@ -72,7 +72,7 @@ class PhysicalBoneSimulator3D : public SkeletonModifier3D { void _pose_updated(); void _bone_pose_updated(Skeleton3D *skeleton, int p_bone_id); - virtual void _process_modification() override; + virtual void _process_modification(double p_delta) override; virtual void _skeleton_changed(Skeleton3D *p_old, Skeleton3D *p_new) override; diff --git a/scene/3d/retarget_modifier_3d.cpp b/scene/3d/retarget_modifier_3d.cpp index 6530eb00bde3..925e5134139f 100644 --- a/scene/3d/retarget_modifier_3d.cpp +++ b/scene/3d/retarget_modifier_3d.cpp @@ -370,7 +370,7 @@ void RetargetModifier3D::_retarget_pose() { } } -void RetargetModifier3D::_process_modification() { +void RetargetModifier3D::_process_modification(double p_delta) { if (use_global_pose) { _retarget_global_pose(); } else { diff --git a/scene/3d/retarget_modifier_3d.h b/scene/3d/retarget_modifier_3d.h index a8f2ebb9735b..f1e4c3e31a75 100644 --- a/scene/3d/retarget_modifier_3d.h +++ b/scene/3d/retarget_modifier_3d.h @@ -96,7 +96,7 @@ class RetargetModifier3D : public SkeletonModifier3D { virtual void remove_child_notify(Node *p_child) override; virtual void _set_active(bool p_active) override; - virtual void _process_modification() override; + virtual void _process_modification(double p_delta) override; public: virtual PackedStringArray get_configuration_warnings() const override; diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 52dcd0ed50d4..0ca3e1678e03 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -357,7 +357,9 @@ void Skeleton3D::_notification(int p_what) { // Store dirty flags for global bone poses. bone_global_pose_dirty_backup = bone_global_pose_dirty; - _process_modifiers(); + if (update_flags & UPDATE_FLAG_MODIFIER) { + _process_modifiers(); + } } // Abort if pose is not changed. @@ -438,16 +440,23 @@ void Skeleton3D::_notification(int p_what) { updating = false; update_flags = UPDATE_FLAG_NONE; } break; - case NOTIFICATION_INTERNAL_PROCESS: + case NOTIFICATION_INTERNAL_PROCESS: { + advance(get_process_delta_time()); + } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { - _find_modifiers(); - if (!modifiers.is_empty()) { - _update_deferred(UPDATE_FLAG_MODIFIER); - } + advance(get_physics_process_delta_time()); } break; } } +void Skeleton3D::advance(double p_delta) { + _find_modifiers(); + if (!modifiers.is_empty()) { + update_delta += p_delta; // Accumulate delta for manual advance as it needs to process in deferred update. + _update_deferred(UPDATE_FLAG_MODIFIER); + } +} + void Skeleton3D::set_modifier_callback_mode_process(Skeleton3D::ModifierCallbackModeProcess p_mode) { if (modifier_callback_mode_process == p_mode) { return; @@ -467,6 +476,9 @@ void Skeleton3D::_process_changed() { } else if (modifier_callback_mode_process == MODIFIER_CALLBACK_MODE_PROCESS_PHYSICS) { set_process_internal(false); set_physics_process_internal(true); + } else { + set_process_internal(false); + set_physics_process_internal(false); } } @@ -1194,7 +1206,7 @@ void Skeleton3D::_process_modifiers() { for (int i = 0; i < get_bone_count(); i++) { old_poses.push_back(get_bone_pose(i)); } - mod->process_modification(); + mod->process_modification(update_delta); LocalVector new_poses; for (int i = 0; i < get_bone_count(); i++) { new_poses.push_back(get_bone_pose(i)); @@ -1206,10 +1218,11 @@ void Skeleton3D::_process_modifiers() { set_bone_pose(i, old_poses[i].interpolate_with(new_poses[i], influence)); } } else { - mod->process_modification(); + mod->process_modification(update_delta); } force_update_all_dirty_bones(); } + update_delta = 0; // Reset accumulated delta. } void Skeleton3D::add_child_notify(Node *p_child) { @@ -1297,11 +1310,13 @@ void Skeleton3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_modifier_callback_mode_process", "mode"), &Skeleton3D::set_modifier_callback_mode_process); ClassDB::bind_method(D_METHOD("get_modifier_callback_mode_process"), &Skeleton3D::get_modifier_callback_mode_process); + ClassDB::bind_method(D_METHOD("advance", "delta"), &Skeleton3D::advance); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "motion_scale", PROPERTY_HINT_RANGE, "0.001,10,0.001,or_greater"), "set_motion_scale", "get_motion_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_rest_only"), "set_show_rest_only", "is_show_rest_only"); ADD_GROUP("Modifier", "modifier_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "modifier_callback_mode_process", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_modifier_callback_mode_process", "get_modifier_callback_mode_process"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "modifier_callback_mode_process", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_modifier_callback_mode_process", "get_modifier_callback_mode_process"); ADD_SIGNAL(MethodInfo("rest_updated")); ADD_SIGNAL(MethodInfo("pose_updated")); @@ -1313,6 +1328,7 @@ void Skeleton3D::_bind_methods() { BIND_CONSTANT(NOTIFICATION_UPDATE_SKELETON); BIND_ENUM_CONSTANT(MODIFIER_CALLBACK_MODE_PROCESS_PHYSICS); BIND_ENUM_CONSTANT(MODIFIER_CALLBACK_MODE_PROCESS_IDLE); + BIND_ENUM_CONSTANT(MODIFIER_CALLBACK_MODE_PROCESS_MANUAL); #ifndef DISABLE_DEPRECATED ClassDB::bind_method(D_METHOD("clear_bones_global_pose_override"), &Skeleton3D::clear_bones_global_pose_override); diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index c8e7c3ca7aec..6e630437e1b6 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -79,6 +79,7 @@ class Skeleton3D : public Node3D { enum ModifierCallbackModeProcess { MODIFIER_CALLBACK_MODE_PROCESS_PHYSICS, MODIFIER_CALLBACK_MODE_PROCESS_IDLE, + MODIFIER_CALLBACK_MODE_PROCESS_MANUAL, }; private: @@ -93,6 +94,7 @@ class Skeleton3D : public Node3D { void _update_deferred(UpdateFlag p_update_flag = UPDATE_FLAG_POSE); uint8_t update_flags = UPDATE_FLAG_NONE; bool updating = false; // Is updating now? + double update_delta = 0.0; struct Bone { String name; @@ -294,6 +296,8 @@ class Skeleton3D : public Node3D { void set_modifier_callback_mode_process(ModifierCallbackModeProcess p_mode); ModifierCallbackModeProcess get_modifier_callback_mode_process() const; + void advance(double p_delta); + #ifndef DISABLE_DEPRECATED Transform3D get_bone_global_pose_no_override(int p_bone) const; void clear_bones_global_pose_override(); diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp index 2476e7d5cd40..3c3c3990e041 100644 --- a/scene/3d/skeleton_ik_3d.cpp +++ b/scene/3d/skeleton_ik_3d.cpp @@ -366,7 +366,7 @@ void SkeletonIK3D::_bind_methods() { #endif } -void SkeletonIK3D::_process_modification() { +void SkeletonIK3D::_process_modification(double p_delta) { if (!internal_active) { return; } @@ -485,7 +485,7 @@ bool SkeletonIK3D::is_running() { void SkeletonIK3D::start(bool p_one_time) { if (p_one_time) { internal_active = true; - SkeletonModifier3D::process_modification(); + SkeletonModifier3D::process_modification(0); internal_active = false; } else { internal_active = true; diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h index 0dc3ce62f977..3bad4de98093 100644 --- a/scene/3d/skeleton_ik_3d.h +++ b/scene/3d/skeleton_ik_3d.h @@ -144,7 +144,7 @@ class SkeletonIK3D : public SkeletonModifier3D { static void _bind_methods(); virtual void _notification(int p_what); - virtual void _process_modification() override; + virtual void _process_modification(double p_delta) override; public: SkeletonIK3D(); diff --git a/scene/3d/skeleton_modifier_3d.cpp b/scene/3d/skeleton_modifier_3d.cpp index 48ee0e53d4ce..ccbc65066c11 100644 --- a/scene/3d/skeleton_modifier_3d.cpp +++ b/scene/3d/skeleton_modifier_3d.cpp @@ -113,16 +113,23 @@ real_t SkeletonModifier3D::get_influence() const { return influence; } -void SkeletonModifier3D::process_modification() { +void SkeletonModifier3D::process_modification(double p_delta) { if (!active) { return; } - _process_modification(); + _process_modification(p_delta); emit_signal(SNAME("modification_processed")); } -void SkeletonModifier3D::_process_modification() { - GDVIRTUAL_CALL(_process_modification); +void SkeletonModifier3D::_process_modification(double p_delta) { + if (GDVIRTUAL_CALL(_process_modification_with_delta, p_delta)) { + return; + } +#ifndef DISABLE_DEPRECATED + if (GDVIRTUAL_CALL(_process_modification)) { + return; + } +#endif // DISABLE_DEPRECATED } void SkeletonModifier3D::_notification(int p_what) { @@ -151,7 +158,10 @@ void SkeletonModifier3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "influence", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_influence", "get_influence"); ADD_SIGNAL(MethodInfo("modification_processed")); + GDVIRTUAL_BIND(_process_modification_with_delta, "delta"); +#ifndef DISABLE_DEPRECATED GDVIRTUAL_BIND(_process_modification); +#endif BIND_ENUM_CONSTANT(BONE_AXIS_PLUS_X); BIND_ENUM_CONSTANT(BONE_AXIS_MINUS_X); diff --git a/scene/3d/skeleton_modifier_3d.h b/scene/3d/skeleton_modifier_3d.h index c82cbb212f5d..7710539c11ee 100644 --- a/scene/3d/skeleton_modifier_3d.h +++ b/scene/3d/skeleton_modifier_3d.h @@ -68,8 +68,12 @@ class SkeletonModifier3D : public Node3D { virtual void _set_active(bool p_active); - virtual void _process_modification(); + virtual void _process_modification(double p_delta); + // TODO: In Godot 5, should obsolete old GDVIRTUAL0(_process_modification); and replace it with _process_modification_with_delta as GDVIRTUAL1(_process_modification, double). + GDVIRTUAL1(_process_modification_with_delta, double); +#ifndef DISABLE_DEPRECATED GDVIRTUAL0(_process_modification); +#endif public: virtual PackedStringArray get_configuration_warnings() const override; @@ -83,7 +87,7 @@ class SkeletonModifier3D : public Node3D { Skeleton3D *get_skeleton() const; - void process_modification(); + void process_modification(double p_delta); // Utility APIs. static Vector3 get_vector_from_bone_axis(BoneAxis p_axis); diff --git a/scene/3d/spring_bone_simulator_3d.cpp b/scene/3d/spring_bone_simulator_3d.cpp index 1350d54c6e1f..cf2e672289e4 100644 --- a/scene/3d/spring_bone_simulator_3d.cpp +++ b/scene/3d/spring_bone_simulator_3d.cpp @@ -1496,7 +1496,7 @@ void SpringBoneSimulator3D::_set_active(bool p_active) { } } -void SpringBoneSimulator3D::_process_modification() { +void SpringBoneSimulator3D::_process_modification(double p_delta) { if (!is_inside_tree()) { return; } @@ -1514,10 +1514,9 @@ void SpringBoneSimulator3D::_process_modification() { } #endif //TOOLS_ENABLED - double delta = skeleton->get_modifier_callback_mode_process() == Skeleton3D::MODIFIER_CALLBACK_MODE_PROCESS_IDLE ? skeleton->get_process_delta_time() : skeleton->get_physics_process_delta_time(); for (int i = 0; i < settings.size(); i++) { _init_joints(skeleton, settings[i]); - _process_joints(delta, skeleton, settings[i]->joints, get_valid_collision_instance_ids(i), settings[i]->cached_center, settings[i]->cached_inverted_center, settings[i]->cached_inverted_center.basis.get_rotation_quaternion()); + _process_joints(p_delta, skeleton, settings[i]->joints, get_valid_collision_instance_ids(i), settings[i]->cached_center, settings[i]->cached_inverted_center, settings[i]->cached_inverted_center.basis.get_rotation_quaternion()); } } diff --git a/scene/3d/spring_bone_simulator_3d.h b/scene/3d/spring_bone_simulator_3d.h index e01ab1deee75..d2398b080ac6 100644 --- a/scene/3d/spring_bone_simulator_3d.h +++ b/scene/3d/spring_bone_simulator_3d.h @@ -153,7 +153,7 @@ class SpringBoneSimulator3D : public SkeletonModifier3D { static void _bind_methods(); virtual void _set_active(bool p_active) override; - virtual void _process_modification() override; + virtual void _process_modification(double p_delta) override; void _init_joints(Skeleton3D *p_skeleton, SpringBone3DSetting *p_setting); void _process_joints(double p_delta, Skeleton3D *p_skeleton, Vector &p_joints, const LocalVector &p_collisions, const Transform3D &p_center_transform, const Transform3D &p_inverted_center_transform, const Quaternion &p_inverted_center_rotation); diff --git a/scene/3d/xr/xr_body_modifier_3d.cpp b/scene/3d/xr/xr_body_modifier_3d.cpp index 9cdf732de65d..80f00d8bdc4f 100644 --- a/scene/3d/xr/xr_body_modifier_3d.cpp +++ b/scene/3d/xr/xr_body_modifier_3d.cpp @@ -238,7 +238,7 @@ void XRBodyModifier3D::_get_joint_data() { } } -void XRBodyModifier3D::_process_modification() { +void XRBodyModifier3D::_process_modification(double p_delta) { Skeleton3D *skeleton = get_skeleton(); if (!skeleton) { return; diff --git a/scene/3d/xr/xr_body_modifier_3d.h b/scene/3d/xr/xr_body_modifier_3d.h index 6fde212d6a7a..123daf894021 100644 --- a/scene/3d/xr/xr_body_modifier_3d.h +++ b/scene/3d/xr/xr_body_modifier_3d.h @@ -71,7 +71,7 @@ class XRBodyModifier3D : public SkeletonModifier3D { static void _bind_methods(); virtual void _skeleton_changed(Skeleton3D *p_old, Skeleton3D *p_new) override; - virtual void _process_modification() override; + virtual void _process_modification(double p_delta) override; private: struct JointData { diff --git a/scene/3d/xr/xr_hand_modifier_3d.cpp b/scene/3d/xr/xr_hand_modifier_3d.cpp index 7a44f1ad3b53..872e169fa14f 100644 --- a/scene/3d/xr/xr_hand_modifier_3d.cpp +++ b/scene/3d/xr/xr_hand_modifier_3d.cpp @@ -183,7 +183,7 @@ void XRHandModifier3D::_get_joint_data() { } } -void XRHandModifier3D::_process_modification() { +void XRHandModifier3D::_process_modification(double p_delta) { Skeleton3D *skeleton = get_skeleton(); if (!skeleton) { return; diff --git a/scene/3d/xr/xr_hand_modifier_3d.h b/scene/3d/xr/xr_hand_modifier_3d.h index 5d70c1f5bcf1..e30756187243 100644 --- a/scene/3d/xr/xr_hand_modifier_3d.h +++ b/scene/3d/xr/xr_hand_modifier_3d.h @@ -62,7 +62,7 @@ class XRHandModifier3D : public SkeletonModifier3D { static void _bind_methods(); virtual void _skeleton_changed(Skeleton3D *p_old, Skeleton3D *p_new) override; - virtual void _process_modification() override; + virtual void _process_modification(double p_delta) override; private: struct JointData { From 0b233910288619ed1f286102229de86029a5c5e1 Mon Sep 17 00:00:00 2001 From: Tom Date: Wed, 26 Mar 2025 19:01:56 +0000 Subject: [PATCH 053/111] Add missing initializer_list constructor for TypedDictionary --- core/object/ref_counted.h | 4 ++++ core/variant/typed_dictionary.h | 7 +++++++ tests/core/variant/test_dictionary.h | 24 ++++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/core/object/ref_counted.h b/core/object/ref_counted.h index 10d5e761614c..09b0f6a02798 100644 --- a/core/object/ref_counted.h +++ b/core/object/ref_counted.h @@ -85,6 +85,10 @@ class Ref { //virtual RefCounted * get_reference() const { return reference; } public: + static _FORCE_INLINE_ String get_class_static() { + return T::get_class_static(); + } + _FORCE_INLINE_ bool operator==(const T *p_ptr) const { return reference == p_ptr; } diff --git a/core/variant/typed_dictionary.h b/core/variant/typed_dictionary.h index 7670eb6adcf0..b0df0d3aaa8e 100644 --- a/core/variant/typed_dictionary.h +++ b/core/variant/typed_dictionary.h @@ -189,6 +189,13 @@ struct GetTypeInfo &> { _FORCE_INLINE_ TypedDictionary() { \ set_typed(m_variant_type, StringName(), Variant(), Variant::OBJECT, T::get_class_static(), Variant()); \ } \ + _FORCE_INLINE_ TypedDictionary(std::initializer_list> p_init) : \ + Dictionary() { \ + set_typed(m_variant_type, StringName(), Variant(), Variant::OBJECT, std::remove_pointer::type::get_class_static(), Variant()); \ + for (const KeyValue &E : p_init) { \ + operator[](E.key) = E.value; \ + } \ + } \ }; \ template \ struct GetTypeInfo> { \ diff --git a/tests/core/variant/test_dictionary.h b/tests/core/variant/test_dictionary.h index fd3341209a6d..cef6a8ef7495 100644 --- a/tests/core/variant/test_dictionary.h +++ b/tests/core/variant/test_dictionary.h @@ -606,4 +606,28 @@ TEST_CASE("[Dictionary] Iteration") { a2.clear(); } +TEST_CASE("[Dictionary] Object value init") { + Object *a = memnew(Object); + Object *b = memnew(Object); + TypedDictionary tdict = { + { 0.0, a }, + { 5.0, b }, + }; + CHECK_EQ(tdict[0.0], Variant(a)); + CHECK_EQ(tdict[5.0], Variant(b)); + memdelete(a); + memdelete(b); +} + +TEST_CASE("[Dictionary] RefCounted value init") { + Ref a = memnew(RefCounted); + Ref b = memnew(RefCounted); + TypedDictionary> tdict = { + { 0.0, a }, + { 5.0, b }, + }; + CHECK_EQ(tdict[0.0], Variant(a)); + CHECK_EQ(tdict[5.0], Variant(b)); +} + } // namespace TestDictionary From 51238186ed44b338c687c042ec991e7d913df469 Mon Sep 17 00:00:00 2001 From: HolonProduction Date: Tue, 1 Apr 2025 20:19:49 +0200 Subject: [PATCH 054/111] JSONRPC: Require manual method registration --- doc/classes/JSONRPC.xml | 9 ++-- .../4.4-stable.expected | 7 +++ .../gdscript_language_protocol.cpp | 43 +++++++++++++++++-- .../language_server/gdscript_text_document.h | 16 +++---- .../language_server/gdscript_workspace.cpp | 4 +- .../language_server/gdscript_workspace.h | 2 +- modules/jsonrpc/jsonrpc.compat.inc | 41 ++++++++++++++++++ modules/jsonrpc/jsonrpc.cpp | 21 ++++----- modules/jsonrpc/jsonrpc.h | 9 +++- modules/jsonrpc/tests/test_jsonrpc.cpp | 4 -- modules/jsonrpc/tests/test_jsonrpc.h | 11 ++--- 11 files changed, 124 insertions(+), 43 deletions(-) create mode 100644 modules/jsonrpc/jsonrpc.compat.inc diff --git a/doc/classes/JSONRPC.xml b/doc/classes/JSONRPC.xml index e5ee93cb9316..b9975d406bf4 100644 --- a/doc/classes/JSONRPC.xml +++ b/doc/classes/JSONRPC.xml @@ -69,11 +69,14 @@ - + - - + + + Registers a callback for the given method name. + - [param name] The name that clients can use to access the callback. + - [param callback] The callback which will handle the specific method. diff --git a/misc/extension_api_validation/4.4-stable.expected b/misc/extension_api_validation/4.4-stable.expected index 7ea8fc10789f..a7b4de861847 100644 --- a/misc/extension_api_validation/4.4-stable.expected +++ b/misc/extension_api_validation/4.4-stable.expected @@ -24,3 +24,10 @@ Validate extension JSON: Error: Field 'classes/OpenXRAPIExtension/methods/regist Validate extension JSON: Error: Field 'classes/OpenXRAPIExtension/methods/unregister_projection_views_extension/arguments/0': type changed value in new API, from "OpenXRExtensionWrapperExtension" to "OpenXRExtensionWrapper". Switched from `OpenXRExtensionWrapperExtension` to parent `OpenXRExtensionWrapper`. Compatibility methods registered. + + +GH-104890 +--------- +Validate extension JSON: API was removed: classes/JSONRPC/methods/set_scope + +Replaced `set_scope` with `set_method`. Compatibility method registered for binary compatibility. Manual upgrade required by users to retain functionality. diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp index c69e99f25918..ef7c08594614 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.cpp +++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp @@ -334,13 +334,50 @@ bool GDScriptLanguageProtocol::is_goto_native_symbols_enabled() const { return bool(_EDITOR_GET("network/language_server/show_native_symbols_in_editor")); } +// clang-format off +#define SET_DOCUMENT_METHOD(m_method) set_method(_STR(textDocument/m_method), callable_mp(text_document.ptr(), &GDScriptTextDocument::m_method)) +#define SET_COMPLETION_METHOD(m_method) set_method(_STR(completionItem/m_method), callable_mp(text_document.ptr(), &GDScriptTextDocument::m_method)) +#define SET_WORKSPACE_METHOD(m_method) set_method(_STR(workspace/m_method), callable_mp(workspace.ptr(), &GDScriptWorkspace::m_method)) +// clang-format on + GDScriptLanguageProtocol::GDScriptLanguageProtocol() { server.instantiate(); singleton = this; workspace.instantiate(); text_document.instantiate(); - set_scope("textDocument", text_document.ptr()); - set_scope("completionItem", text_document.ptr()); - set_scope("workspace", workspace.ptr()); + + SET_DOCUMENT_METHOD(didOpen); + SET_DOCUMENT_METHOD(didClose); + SET_DOCUMENT_METHOD(didChange); + SET_DOCUMENT_METHOD(willSaveWaitUntil); + SET_DOCUMENT_METHOD(didSave); + + SET_DOCUMENT_METHOD(documentSymbol); + SET_DOCUMENT_METHOD(completion); + SET_DOCUMENT_METHOD(rename); + SET_DOCUMENT_METHOD(prepareRename); + SET_DOCUMENT_METHOD(references); + SET_DOCUMENT_METHOD(foldingRange); + SET_DOCUMENT_METHOD(codeLens); + SET_DOCUMENT_METHOD(documentLink); + SET_DOCUMENT_METHOD(colorPresentation); + SET_DOCUMENT_METHOD(hover); + SET_DOCUMENT_METHOD(definition); + SET_DOCUMENT_METHOD(declaration); + SET_DOCUMENT_METHOD(signatureHelp); + + SET_DOCUMENT_METHOD(nativeSymbol); // Custom method. + + SET_COMPLETION_METHOD(resolve); + + SET_WORKSPACE_METHOD(didDeleteFiles); + + set_method("initialize", callable_mp(this, &GDScriptLanguageProtocol::initialize)); + set_method("initialized", callable_mp(this, &GDScriptLanguageProtocol::initialized)); + workspace->root = ProjectSettings::get_singleton()->get_resource_path(); } + +#undef SET_DOCUMENT_METHOD +#undef SET_COMPLETION_METHOD +#undef SET_WORKSPACE_METHOD diff --git a/modules/gdscript/language_server/gdscript_text_document.h b/modules/gdscript/language_server/gdscript_text_document.h index 3160715acedc..5e3ef82140fd 100644 --- a/modules/gdscript/language_server/gdscript_text_document.h +++ b/modules/gdscript/language_server/gdscript_text_document.h @@ -44,6 +44,14 @@ class GDScriptTextDocument : public RefCounted { Ref file_checker; + Array native_member_completions; + +private: + Array find_symbols(const LSP::TextDocumentPositionParams &p_location, List &r_list); + LSP::TextDocumentItem load_document_item(const Variant &p_param); + void notify_client_show_symbol(const LSP::DocumentSymbol *symbol); + +public: void didOpen(const Variant &p_param); void didClose(const Variant &p_param); void didChange(const Variant &p_param); @@ -54,14 +62,6 @@ class GDScriptTextDocument : public RefCounted { void sync_script_content(const String &p_path, const String &p_content); void show_native_symbol_in_editor(const String &p_symbol_id); - Array native_member_completions; - -private: - Array find_symbols(const LSP::TextDocumentPositionParams &p_location, List &r_list); - LSP::TextDocumentItem load_document_item(const Variant &p_param); - void notify_client_show_symbol(const LSP::DocumentSymbol *symbol); - -public: Variant nativeSymbol(const Dictionary &p_params); Array documentSymbol(const Dictionary &p_params); Array completion(const Dictionary &p_params); diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index b2e52b742569..6806c8016112 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -45,7 +45,7 @@ void GDScriptWorkspace::_bind_methods() { ClassDB::bind_method(D_METHOD("apply_new_signal"), &GDScriptWorkspace::apply_new_signal); - ClassDB::bind_method(D_METHOD("didDeleteFiles"), &GDScriptWorkspace::did_delete_files); + ClassDB::bind_method(D_METHOD("didDeleteFiles"), &GDScriptWorkspace::didDeleteFiles); ClassDB::bind_method(D_METHOD("parse_script", "path", "content"), &GDScriptWorkspace::parse_script); ClassDB::bind_method(D_METHOD("parse_local_script", "path"), &GDScriptWorkspace::parse_local_script); ClassDB::bind_method(D_METHOD("get_file_path", "uri"), &GDScriptWorkspace::get_file_path); @@ -106,7 +106,7 @@ void GDScriptWorkspace::apply_new_signal(Object *obj, String function, PackedStr GDScriptLanguageProtocol::get_singleton()->request_client("workspace/applyEdit", params.to_json()); } -void GDScriptWorkspace::did_delete_files(const Dictionary &p_params) { +void GDScriptWorkspace::didDeleteFiles(const Dictionary &p_params) { Array files = p_params["files"]; for (int i = 0; i < files.size(); ++i) { Dictionary file = files[i]; diff --git a/modules/gdscript/language_server/gdscript_workspace.h b/modules/gdscript/language_server/gdscript_workspace.h index d19901af06de..cd527f04ceab 100644 --- a/modules/gdscript/language_server/gdscript_workspace.h +++ b/modules/gdscript/language_server/gdscript_workspace.h @@ -90,7 +90,7 @@ class GDScriptWorkspace : public RefCounted { void resolve_document_links(const String &p_uri, List &r_list); Dictionary generate_script_api(const String &p_path); Error resolve_signature(const LSP::TextDocumentPositionParams &p_doc_pos, LSP::SignatureHelp &r_signature); - void did_delete_files(const Dictionary &p_params); + void didDeleteFiles(const Dictionary &p_params); Dictionary rename(const LSP::TextDocumentPositionParams &p_doc_pos, const String &new_name); bool can_rename(const LSP::TextDocumentPositionParams &p_doc_pos, LSP::DocumentSymbol &r_symbol, LSP::Range &r_range); Vector find_usages_in_file(const LSP::DocumentSymbol &p_symbol, const String &p_file_path); diff --git a/modules/jsonrpc/jsonrpc.compat.inc b/modules/jsonrpc/jsonrpc.compat.inc new file mode 100644 index 000000000000..ad56dc61c0bf --- /dev/null +++ b/modules/jsonrpc/jsonrpc.compat.inc @@ -0,0 +1,41 @@ +/**************************************************************************/ +/* jsonrpc.compat.inc */ +/**************************************************************************/ +/* 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 DISABLE_DEPRECATED + +void JSONRPC::_set_scope_bind_compat_104890(const String &p_scope, Object *p_obj) { + ERR_PRINT("JSONRPC::set_scope is not supported anymore. Upgrade to JSONRPC::set_method."); +} + +void JSONRPC::_bind_compatibility_methods() { + ClassDB::bind_compatibility_method(D_METHOD("set_scope", "scope", "target"), &JSONRPC::_set_scope_bind_compat_104890); +} + +#endif diff --git a/modules/jsonrpc/jsonrpc.cpp b/modules/jsonrpc/jsonrpc.cpp index 0f03e49fc8b7..6c4259d6fd27 100644 --- a/modules/jsonrpc/jsonrpc.cpp +++ b/modules/jsonrpc/jsonrpc.cpp @@ -29,6 +29,7 @@ /**************************************************************************/ #include "jsonrpc.h" +#include "jsonrpc.compat.inc" #include "core/io/json.h" @@ -39,7 +40,7 @@ JSONRPC::~JSONRPC() { } void JSONRPC::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_scope", "scope", "target"), &JSONRPC::set_scope); + ClassDB::bind_method(D_METHOD("set_method", "name", "callback"), &JSONRPC::set_method); ClassDB::bind_method(D_METHOD("process_action", "action", "recurse"), &JSONRPC::process_action, DEFVAL(false)); ClassDB::bind_method(D_METHOD("process_string", "action"), &JSONRPC::process_string); @@ -113,12 +114,6 @@ Variant JSONRPC::process_action(const Variant &p_action, bool p_process_arr_elem } } - Object *object = this; - if (method_scopes.has(method.get_base_dir())) { - object = method_scopes[method.get_base_dir()]; - method = method.get_file(); - } - Variant id; if (dict.has("id")) { id = dict["id"]; @@ -129,13 +124,13 @@ Variant JSONRPC::process_action(const Variant &p_action, bool p_process_arr_elem } } - if (object == nullptr || !object->has_method(method)) { - ret = make_response_error(JSONRPC::METHOD_NOT_FOUND, "Method not found: " + method, id); - } else { - Variant call_ret = object->callv(method, args); + if (methods.has(method)) { + Variant call_ret = methods[method].callv(args); if (id.get_type() != Variant::NIL) { ret = make_response(call_ret, id); } + } else { + ret = make_response_error(JSONRPC::METHOD_NOT_FOUND, "Method not found: " + method, id); } } else if (p_action.get_type() == Variant::ARRAY && p_process_arr_elements) { Array arr = p_action; @@ -175,6 +170,6 @@ String JSONRPC::process_string(const String &p_input) { return ret.to_json_string(); } -void JSONRPC::set_scope(const String &p_scope, Object *p_obj) { - method_scopes[p_scope] = p_obj; +void JSONRPC::set_method(const String &p_name, const Callable &p_callback) { + methods[p_name] = p_callback; } diff --git a/modules/jsonrpc/jsonrpc.h b/modules/jsonrpc/jsonrpc.h index 774bc9e0bec7..254bb3fcac80 100644 --- a/modules/jsonrpc/jsonrpc.h +++ b/modules/jsonrpc/jsonrpc.h @@ -36,11 +36,16 @@ class JSONRPC : public Object { GDCLASS(JSONRPC, Object) - HashMap method_scopes; + HashMap methods; protected: static void _bind_methods(); +#ifndef DISABLE_DEPRECATED + void _set_scope_bind_compat_104890(const String &p_scope, Object *p_obj); + static void _bind_compatibility_methods(); +#endif + public: JSONRPC(); ~JSONRPC(); @@ -61,7 +66,7 @@ class JSONRPC : public Object { Variant process_action(const Variant &p_action, bool p_process_arr_elements = false); String process_string(const String &p_input); - void set_scope(const String &p_scope, Object *p_obj); + void set_method(const String &p_name, const Callable &p_callback); }; VARIANT_ENUM_CAST(JSONRPC::ErrorCode); diff --git a/modules/jsonrpc/tests/test_jsonrpc.cpp b/modules/jsonrpc/tests/test_jsonrpc.cpp index 8500ff6da92b..c1028892c332 100644 --- a/modules/jsonrpc/tests/test_jsonrpc.cpp +++ b/modules/jsonrpc/tests/test_jsonrpc.cpp @@ -57,10 +57,6 @@ String TestClassJSONRPC::something(const String &p_in) { return p_in + ", please"; } -void TestClassJSONRPC::_bind_methods() { - ClassDB::bind_method(D_METHOD("something", "in"), &TestClassJSONRPC::something); -} - void test_process_action(const Variant &p_in, const Variant &p_expected, bool p_process_array_elements) { TestClassJSONRPC json_rpc = TestClassJSONRPC(); const Variant &observed = json_rpc.process_action(p_in, p_process_array_elements); diff --git a/modules/jsonrpc/tests/test_jsonrpc.h b/modules/jsonrpc/tests/test_jsonrpc.h index ef0404cc43eb..08303193125e 100644 --- a/modules/jsonrpc/tests/test_jsonrpc.h +++ b/modules/jsonrpc/tests/test_jsonrpc.h @@ -60,20 +60,17 @@ TEST_CASE("[JSONRPC] process_string invalid") { } class TestClassJSONRPC : public JSONRPC { - GDCLASS(TestClassJSONRPC, JSONRPC) - public: - String something(const String &p_in); + TestClassJSONRPC() { + set_method("something", callable_mp(this, &TestClassJSONRPC::something)); + } -protected: - static void _bind_methods(); + String something(const String &p_in); }; void test_process_action(const Variant &p_in, const Variant &p_expected, bool p_process_array_elements = false); TEST_CASE("[JSONRPC] process_action Dictionary") { - ClassDB::register_class(); - Dictionary in_dict = Dictionary(); in_dict["method"] = "something"; in_dict["id"] = "ID"; From 5dfaf5804b3aab414d8cb20e57b7bc44ccd2b273 Mon Sep 17 00:00:00 2001 From: Mikael Hermansson Date: Fri, 21 Mar 2025 17:17:55 +0100 Subject: [PATCH 055/111] Jolt: Update to 5.3.0 --- modules/jolt_physics/SCsub | 5 - .../shapes/jolt_height_map_shape_3d.cpp | 2 +- .../jolt_physics_direct_space_state_3d.cpp | 6 +- thirdparty/README.md | 2 +- thirdparty/jolt_physics/Jolt/Core/Array.h | 117 ++++++- thirdparty/jolt_physics/Jolt/Core/Color.h | 2 +- thirdparty/jolt_physics/Jolt/Core/Core.h | 22 +- .../jolt_physics/Jolt/Core/FPException.h | 26 +- thirdparty/jolt_physics/Jolt/Core/HashTable.h | 70 ++-- .../jolt_physics/Jolt/Core/Profiler.cpp | 327 +++++++++++++++++- .../Jolt/Core/STLLocalAllocator.h | 3 +- .../jolt_physics/Jolt/Core/Semaphore.cpp | 64 +++- thirdparty/jolt_physics/Jolt/Core/Semaphore.h | 55 ++- thirdparty/jolt_physics/Jolt/Core/StreamIn.h | 3 +- .../jolt_physics/Jolt/Core/TempAllocator.h | 14 +- thirdparty/jolt_physics/Jolt/Geometry/AABox.h | 5 +- .../Jolt/Geometry/EPAPenetrationDepth.h | 6 +- .../Jolt/Geometry/GJKClosestPoint.h | 1 - .../jolt_physics/Jolt/Geometry/OrientedBox.h | 2 +- .../jolt_physics/Jolt/Geometry/RayAABox.h | 2 +- .../jolt_physics/Jolt/Geometry/RayTriangle.h | 6 +- thirdparty/jolt_physics/Jolt/Jolt.natvis | 2 +- thirdparty/jolt_physics/Jolt/Math/DVec3.h | 3 + thirdparty/jolt_physics/Jolt/Math/DVec3.inl | 7 +- .../Jolt/Math/EigenValueSymmetric.h | 2 +- thirdparty/jolt_physics/Jolt/Math/HalfFloat.h | 4 + thirdparty/jolt_physics/Jolt/Math/Math.h | 3 + thirdparty/jolt_physics/Jolt/Math/Vec3.h | 3 + thirdparty/jolt_physics/Jolt/Math/Vec3.inl | 7 +- thirdparty/jolt_physics/Jolt/Math/Vec4.h | 3 + thirdparty/jolt_physics/Jolt/Math/Vec4.inl | 15 +- .../jolt_physics/Jolt/Physics/Body/Body.cpp | 6 +- .../jolt_physics/Jolt/Physics/Body/Body.h | 25 +- .../jolt_physics/Jolt/Physics/Body/BodyID.h | 9 +- .../Jolt/Physics/Body/BodyInterface.cpp | 64 ++-- .../Jolt/Physics/Body/BodyInterface.h | 7 + .../Jolt/Physics/Body/BodyManager.cpp | 10 +- .../Jolt/Physics/Body/MotionProperties.inl | 4 +- .../Jolt/Physics/Character/Character.cpp | 18 +- .../Jolt/Physics/Character/Character.h | 4 + .../Jolt/Physics/Character/CharacterID.h | 98 ++++++ .../Physics/Character/CharacterVirtual.cpp | 257 +++++++++++--- .../Jolt/Physics/Character/CharacterVirtual.h | 163 +++++++-- .../BroadPhase/BroadPhaseQuadTree.cpp | 26 +- .../Physics/Collision/BroadPhase/QuadTree.cpp | 110 +++--- .../Physics/Collision/BroadPhase/QuadTree.h | 5 +- .../Collision/CollideConvexVsTriangles.cpp | 15 +- .../Collision/CollideShapeVsShapePerLeaf.h | 93 +++++ .../Physics/Collision/CollisionCollector.h | 6 +- .../Collision/CollisionCollectorImpl.h | 85 +++++ .../Jolt/Physics/Collision/CollisionGroup.cpp | 2 + .../Jolt/Physics/Collision/CollisionGroup.h | 3 + .../Collision/InternalEdgeRemovingCollector.h | 11 + .../Collision/ManifoldBetweenTwoFaces.cpp | 39 ++- .../Collision/ManifoldBetweenTwoFaces.h | 4 +- .../Physics/Collision/NarrowPhaseQuery.cpp | 103 ++---- .../Physics/Collision/Shape/CompoundShape.cpp | 7 +- .../Physics/Collision/Shape/CompoundShape.h | 8 +- .../Physics/Collision/Shape/ConvexHullShape.h | 2 +- .../Physics/Collision/Shape/ConvexShape.cpp | 31 +- .../Physics/Collision/Shape/CylinderShape.cpp | 24 +- .../Collision/Shape/HeightFieldShape.cpp | 230 ++++++------ .../Collision/Shape/HeightFieldShape.h | 8 +- .../Physics/Collision/Shape/MeshShape.cpp | 40 ++- .../Jolt/Physics/Collision/Shape/MeshShape.h | 11 + .../Collision/Shape/MutableCompoundShape.cpp | 34 +- .../Collision/Shape/MutableCompoundShape.h | 9 +- .../Jolt/Physics/Collision/Shape/PlaneShape.h | 6 +- .../Physics/Collision/Shape/ScaleHelpers.h | 2 +- .../Jolt/Physics/Collision/Shape/Shape.cpp | 2 +- .../Physics/Collision/Shape/SphereShape.cpp | 2 +- .../Collision/Shape/StaticCompoundShape.cpp | 2 +- .../Collision/Shape/TaperedCapsuleShape.cpp | 2 +- .../Collision/Shape/TaperedCylinderShape.cpp | 44 ++- .../Physics/Collision/Shape/TriangleShape.cpp | 5 +- .../Constraints/ContactConstraintManager.cpp | 21 +- .../Constraints/ContactConstraintManager.h | 8 + .../Physics/Constraints/HingeConstraint.cpp | 2 +- .../Jolt/Physics/PhysicsScene.cpp | 2 +- .../Jolt/Physics/PhysicsSettings.h | 4 +- .../Jolt/Physics/PhysicsSystem.cpp | 67 ++-- .../jolt_physics/Jolt/Physics/PhysicsSystem.h | 34 ++ .../SoftBody/SoftBodyMotionProperties.cpp | 32 +- .../SoftBody/SoftBodyMotionProperties.h | 3 +- .../Jolt/Physics/SoftBody/SoftBodyShape.cpp | 3 + .../SoftBody/SoftBodySharedSettings.cpp | 147 ++++++++ .../Physics/SoftBody/SoftBodySharedSettings.h | 6 + .../Jolt/Physics/Vehicle/VehicleAntiRollBar.h | 2 + .../Vehicle/VehicleCollisionTester.cpp | 4 +- .../Physics/Vehicle/VehicleConstraint.cpp | 37 +- .../Jolt/Physics/Vehicle/VehicleConstraint.h | 8 +- .../Jolt/Physics/Vehicle/VehicleController.h | 2 +- .../jolt_physics/Jolt/RegisterTypes.cpp | 8 + .../Jolt/Renderer/DebugRenderer.cpp | 2 +- .../Jolt/Renderer/DebugRenderer.h | 2 +- .../Jolt/TriangleGrouper/TriangleGrouper.h | 27 -- .../TriangleGrouperClosestCentroid.cpp | 95 ----- .../TriangleGrouperClosestCentroid.h | 21 -- .../TriangleGrouper/TriangleGrouperMorton.cpp | 49 --- .../TriangleGrouper/TriangleGrouperMorton.h | 20 -- .../TriangleSplitter/TriangleSplitter.cpp | 30 +- .../TriangleSplitterBinning.cpp | 13 +- .../TriangleSplitterFixedLeafSize.cpp | 170 --------- .../TriangleSplitterFixedLeafSize.h | 55 --- .../TriangleSplitterLongestAxis.cpp | 31 -- .../TriangleSplitterLongestAxis.h | 28 -- .../TriangleSplitter/TriangleSplitterMean.cpp | 11 +- .../TriangleSplitterMorton.cpp | 63 ---- .../TriangleSplitter/TriangleSplitterMorton.h | 32 -- 109 files changed, 2230 insertions(+), 1234 deletions(-) create mode 100644 thirdparty/jolt_physics/Jolt/Physics/Character/CharacterID.h create mode 100644 thirdparty/jolt_physics/Jolt/Physics/Collision/CollideShapeVsShapePerLeaf.h delete mode 100644 thirdparty/jolt_physics/Jolt/TriangleGrouper/TriangleGrouper.h delete mode 100644 thirdparty/jolt_physics/Jolt/TriangleGrouper/TriangleGrouperClosestCentroid.cpp delete mode 100644 thirdparty/jolt_physics/Jolt/TriangleGrouper/TriangleGrouperClosestCentroid.h delete mode 100644 thirdparty/jolt_physics/Jolt/TriangleGrouper/TriangleGrouperMorton.cpp delete mode 100644 thirdparty/jolt_physics/Jolt/TriangleGrouper/TriangleGrouperMorton.h delete mode 100644 thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterFixedLeafSize.cpp delete mode 100644 thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterFixedLeafSize.h delete mode 100644 thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterLongestAxis.cpp delete mode 100644 thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterLongestAxis.h delete mode 100644 thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterMorton.cpp delete mode 100644 thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterMorton.h diff --git a/modules/jolt_physics/SCsub b/modules/jolt_physics/SCsub index cd84c0ef0bde..08500d8fc1af 100644 --- a/modules/jolt_physics/SCsub +++ b/modules/jolt_physics/SCsub @@ -132,14 +132,9 @@ thirdparty_sources = [ "Jolt/Skeleton/Skeleton.cpp", "Jolt/Skeleton/SkeletonMapper.cpp", "Jolt/Skeleton/SkeletonPose.cpp", - "Jolt/TriangleGrouper/TriangleGrouperClosestCentroid.cpp", - "Jolt/TriangleGrouper/TriangleGrouperMorton.cpp", "Jolt/TriangleSplitter/TriangleSplitter.cpp", "Jolt/TriangleSplitter/TriangleSplitterBinning.cpp", - "Jolt/TriangleSplitter/TriangleSplitterFixedLeafSize.cpp", - "Jolt/TriangleSplitter/TriangleSplitterLongestAxis.cpp", "Jolt/TriangleSplitter/TriangleSplitterMean.cpp", - "Jolt/TriangleSplitter/TriangleSplitterMorton.cpp", ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] diff --git a/modules/jolt_physics/shapes/jolt_height_map_shape_3d.cpp b/modules/jolt_physics/shapes/jolt_height_map_shape_3d.cpp index edacc6d057d9..2855ec88e08b 100644 --- a/modules/jolt_physics/shapes/jolt_height_map_shape_3d.cpp +++ b/modules/jolt_physics/shapes/jolt_height_map_shape_3d.cpp @@ -103,7 +103,7 @@ JPH::ShapeRefC JoltHeightMapShape3D::_build_height_field() const { } } - JPH::HeightFieldShapeSettings shape_settings(heights_rev.ptr(), JPH::Vec3(offset_x, 0, offset_y), JPH::Vec3::sReplicate(1.0f), (JPH::uint32)width); + JPH::HeightFieldShapeSettings shape_settings(heights_rev.ptr(), JPH::Vec3(offset_x, 0, offset_y), JPH::Vec3::sOne(), (JPH::uint32)width); shape_settings.mBitsPerSample = shape_settings.CalculateBitsPerSampleForError(0.0f); shape_settings.mActiveEdgeCosThresholdAngle = JoltProjectSettings::active_edge_threshold_cos; diff --git a/modules/jolt_physics/spaces/jolt_physics_direct_space_state_3d.cpp b/modules/jolt_physics/spaces/jolt_physics_direct_space_state_3d.cpp index 02fcbbc7e6a7..d78f08c8c1b6 100644 --- a/modules/jolt_physics/spaces/jolt_physics_direct_space_state_3d.cpp +++ b/modules/jolt_physics/spaces/jolt_physics_direct_space_state_3d.cpp @@ -190,7 +190,7 @@ bool JoltPhysicsDirectSpaceState3D::_body_motion_recover(const JoltBody3D &p_bod for (int i = 0; i < JoltProjectSettings::motion_query_recovery_iterations; ++i) { collector.reset(); - _collide_shape_kinematics(jolt_shape, JPH::Vec3::sReplicate(1.0f), to_jolt_r(transform_com), settings, to_jolt_r(base_offset), collector, motion_filter, motion_filter, motion_filter, motion_filter); + _collide_shape_kinematics(jolt_shape, JPH::Vec3::sOne(), to_jolt_r(transform_com), settings, to_jolt_r(base_offset), collector, motion_filter, motion_filter, motion_filter, motion_filter); if (!collector.had_hit()) { break; @@ -320,7 +320,7 @@ bool JoltPhysicsDirectSpaceState3D::_body_motion_collide(const JoltBody3D &p_bod const JoltMotionFilter3D motion_filter(p_body, p_excluded_bodies, p_excluded_objects); JoltQueryCollectorClosestMulti collector(p_max_collisions); - _collide_shape_kinematics(jolt_shape, JPH::Vec3::sReplicate(1.0f), to_jolt_r(transform_com), settings, to_jolt_r(base_offset), collector, motion_filter, motion_filter, motion_filter, motion_filter); + _collide_shape_kinematics(jolt_shape, JPH::Vec3::sOne(), to_jolt_r(transform_com), settings, to_jolt_r(base_offset), collector, motion_filter, motion_filter, motion_filter, motion_filter); if (!collector.had_hit() || p_result == nullptr) { return collector.had_hit(); @@ -418,7 +418,7 @@ void JoltPhysicsDirectSpaceState3D::_generate_manifold(const JPH::CollideShapeRe const JPH::PhysicsSettings &physics_settings = physics_system.GetPhysicsSettings(); const JPH::Vec3 penetration_axis = p_hit.mPenetrationAxis.Normalized(); - JPH::ManifoldBetweenTwoFaces(p_hit.mContactPointOn1, p_hit.mContactPointOn2, penetration_axis, physics_settings.mManifoldToleranceSq, p_hit.mShape1Face, p_hit.mShape2Face, r_contact_points1, r_contact_points2 JPH_IF_DEBUG_RENDERER(, p_center_of_mass)); + JPH::ManifoldBetweenTwoFaces(p_hit.mContactPointOn1, p_hit.mContactPointOn2, penetration_axis, physics_settings.mManifoldTolerance, p_hit.mShape1Face, p_hit.mShape2Face, r_contact_points1, r_contact_points2 JPH_IF_DEBUG_RENDERER(, p_center_of_mass)); if (r_contact_points1.size() > 4) { JPH::PruneContactPoints(penetration_axis, r_contact_points1, r_contact_points2 JPH_IF_DEBUG_RENDERER(, p_center_of_mass)); diff --git a/thirdparty/README.md b/thirdparty/README.md index de195192242f..9591ea294ab3 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -448,7 +448,7 @@ Files generated from upstream source: ## jolt_physics - Upstream: https://github.com/jrouwe/JoltPhysics -- Version: 5.2.1 (f094082aa2bbfcbebc725dbe8b8f65c7d5152886, 2024) +- Version: 5.3.0 (0373ec0dd762e4bc2f6acdb08371ee84fa23c6db, 2025) - License: MIT Files extracted from upstream source: diff --git a/thirdparty/jolt_physics/Jolt/Core/Array.h b/thirdparty/jolt_physics/Jolt/Core/Array.h index a273f4eb50ff..b8dbce595355 100644 --- a/thirdparty/jolt_physics/Jolt/Core/Array.h +++ b/thirdparty/jolt_physics/Jolt/Core/Array.h @@ -47,6 +47,83 @@ class [[nodiscard]] Array : private Allocator using const_iterator = const T *; using iterator = T *; + /// An iterator that traverses the array in reverse order + class rev_it + { + public: + /// Constructor + rev_it() = default; + explicit rev_it(T *inValue) : mValue(inValue) { } + + /// Copying + rev_it(const rev_it &) = default; + rev_it & operator = (const rev_it &) = default; + + /// Comparison + bool operator == (const rev_it &inRHS) const { return mValue == inRHS.mValue; } + bool operator != (const rev_it &inRHS) const { return mValue != inRHS.mValue; } + + /// Arithmetics + rev_it & operator ++ () { --mValue; return *this; } + rev_it operator ++ (int) { return rev_it(mValue--); } + rev_it & operator -- () { ++mValue; return *this; } + rev_it operator -- (int) { return rev_it(mValue++); } + + rev_it operator + (int inValue) { return rev_it(mValue - inValue); } + rev_it operator - (int inValue) { return rev_it(mValue + inValue); } + + rev_it & operator += (int inValue) { mValue -= inValue; return *this; } + rev_it & operator -= (int inValue) { mValue += inValue; return *this; } + + /// Access + T & operator * () const { return *mValue; } + T & operator -> () const { return *mValue; } + + private: + T * mValue; + }; + + /// A const iterator that traverses the array in reverse order + class crev_it + { + public: + /// Constructor + crev_it() = default; + explicit crev_it(const T *inValue) : mValue(inValue) { } + + /// Copying + crev_it(const crev_it &) = default; + explicit crev_it(const rev_it &inValue) : mValue(inValue.mValue) { } + crev_it & operator = (const crev_it &) = default; + crev_it & operator = (const rev_it &inRHS) { mValue = inRHS.mValue; return *this; } + + /// Comparison + bool operator == (const crev_it &inRHS) const { return mValue == inRHS.mValue; } + bool operator != (const crev_it &inRHS) const { return mValue != inRHS.mValue; } + + /// Arithmetics + crev_it & operator ++ () { --mValue; return *this; } + crev_it operator ++ (int) { return crev_it(mValue--); } + crev_it & operator -- () { ++mValue; return *this; } + crev_it operator -- (int) { return crev_it(mValue++); } + + crev_it operator + (int inValue) { return crev_it(mValue - inValue); } + crev_it operator - (int inValue) { return crev_it(mValue + inValue); } + + crev_it & operator += (int inValue) { mValue -= inValue; return *this; } + crev_it & operator -= (int inValue) { mValue += inValue; return *this; } + + /// Access + const T & operator * () const { return *mValue; } + const T & operator -> () const { return *mValue; } + + private: + const T * mValue; + }; + + using reverse_iterator = rev_it; + using const_reverse_iterator = crev_it; + private: /// Move elements from one location to another inline void move(pointer inDestination, pointer inSource, size_type inCount) @@ -388,7 +465,7 @@ class [[nodiscard]] Array : private Allocator } /// Remove one element from the array - void erase(const_iterator inIter) + iterator erase(const_iterator inIter) { size_type p = size_type(inIter - begin()); JPH_ASSERT(p < mSize); @@ -396,10 +473,11 @@ class [[nodiscard]] Array : private Allocator if (p + 1 < mSize) move(mElements + p, mElements + p + 1, mSize - p - 1); --mSize; + return const_cast(inIter); } /// Remove multiple element from the array - void erase(const_iterator inBegin, const_iterator inEnd) + iterator erase(const_iterator inBegin, const_iterator inEnd) { size_type p = size_type(inBegin - begin()); size_type n = size_type(inEnd - inBegin); @@ -408,6 +486,7 @@ class [[nodiscard]] Array : private Allocator if (p + n < mSize) move(mElements + p, mElements + p + n, mSize - p - n); mSize -= n; + return const_cast(inBegin); } /// Iterators @@ -421,14 +500,34 @@ class [[nodiscard]] Array : private Allocator return mElements + mSize; } + inline crev_it rbegin() const + { + return crev_it(mElements + mSize - 1); + } + + inline crev_it rend() const + { + return crev_it(mElements - 1); + } + inline const_iterator cbegin() const { - return mElements; + return begin(); } inline const_iterator cend() const { - return mElements + mSize; + return end(); + } + + inline crev_it crbegin() const + { + return rbegin(); + } + + inline crev_it crend() const + { + return rend(); } inline iterator begin() @@ -441,6 +540,16 @@ class [[nodiscard]] Array : private Allocator return mElements + mSize; } + inline rev_it rbegin() + { + return rev_it(mElements + mSize - 1); + } + + inline rev_it rend() + { + return rev_it(mElements - 1); + } + inline const T * data() const { return mElements; diff --git a/thirdparty/jolt_physics/Jolt/Core/Color.h b/thirdparty/jolt_physics/Jolt/Core/Color.h index d07390de1cb3..7706ca85b598 100644 --- a/thirdparty/jolt_physics/Jolt/Core/Color.h +++ b/thirdparty/jolt_physics/Jolt/Core/Color.h @@ -12,7 +12,7 @@ class Color; using ColorArg = Color; /// Class that holds an RGBA color with 8-bits per component -class [[nodiscard]] JPH_EXPORT_GCC_BUG_WORKAROUND Color +class JPH_EXPORT_GCC_BUG_WORKAROUND [[nodiscard]] Color { public: /// Constructors diff --git a/thirdparty/jolt_physics/Jolt/Core/Core.h b/thirdparty/jolt_physics/Jolt/Core/Core.h index 01b6afbf19f2..dfd2a04d2f4a 100644 --- a/thirdparty/jolt_physics/Jolt/Core/Core.h +++ b/thirdparty/jolt_physics/Jolt/Core/Core.h @@ -6,8 +6,8 @@ // Jolt library version #define JPH_VERSION_MAJOR 5 -#define JPH_VERSION_MINOR 2 -#define JPH_VERSION_PATCH 1 +#define JPH_VERSION_MINOR 3 +#define JPH_VERSION_PATCH 0 // Determine which features the library was compiled with #ifdef JPH_DOUBLE_PRECISION @@ -83,8 +83,8 @@ #define JPH_PLATFORM_ANDROID #elif defined(__linux__) #define JPH_PLATFORM_LINUX -#elif defined(__FreeBSD__) - #define JPH_PLATFORM_FREEBSD +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + #define JPH_PLATFORM_BSD #elif defined(__APPLE__) #include #if defined(TARGET_OS_IPHONE) && !TARGET_OS_IPHONE @@ -195,7 +195,11 @@ #elif defined(JPH_PLATFORM_WASM) // WebAssembly CPU architecture #define JPH_CPU_WASM - #define JPH_CPU_ADDRESS_BITS 32 + #if defined(__wasm64__) + #define JPH_CPU_ADDRESS_BITS 64 + #else + #define JPH_CPU_ADDRESS_BITS 32 + #endif #define JPH_VECTOR_ALIGNMENT 16 #define JPH_DVECTOR_ALIGNMENT 32 #ifdef __wasm_simd128__ @@ -360,6 +364,7 @@ JPH_MSVC_SUPPRESS_WARNING(4514) /* 'X' : unreferenced inline function has been removed */ \ JPH_MSVC_SUPPRESS_WARNING(4710) /* 'X' : function not inlined */ \ JPH_MSVC_SUPPRESS_WARNING(4711) /* function 'X' selected for automatic inline expansion */ \ + JPH_MSVC_SUPPRESS_WARNING(4714) /* function 'X' marked as __forceinline not inlined */ \ JPH_MSVC_SUPPRESS_WARNING(4820) /* 'X': 'Y' bytes padding added after data member 'Z' */ \ JPH_MSVC_SUPPRESS_WARNING(4100) /* 'X' : unreferenced formal parameter */ \ JPH_MSVC_SUPPRESS_WARNING(4626) /* 'X' : assignment operator was implicitly defined as deleted because a base class assignment operator is inaccessible or deleted */ \ @@ -388,9 +393,9 @@ // Configuration for a popular game console. // This file is not distributed because it would violate an NDA. // Creating one should only be a couple of minutes of work if you have the documentation for the platform - // (you only need to define JPH_BREAKPOINT, JPH_PLATFORM_BLUE_GET_TICKS, JPH_PLATFORM_BLUE_MUTEX*, JPH_PLATFORM_BLUE_RWLOCK* and include the right header). + // (you only need to define JPH_BREAKPOINT, JPH_PLATFORM_BLUE_GET_TICKS, JPH_PLATFORM_BLUE_MUTEX*, JPH_PLATFORM_BLUE_RWLOCK*, JPH_PLATFORM_BLUE_SEMAPHORE* and include the right header). #include -#elif defined(JPH_PLATFORM_LINUX) || defined(JPH_PLATFORM_ANDROID) || defined(JPH_PLATFORM_MACOS) || defined(JPH_PLATFORM_IOS) || defined(JPH_PLATFORM_FREEBSD) +#elif defined(JPH_PLATFORM_LINUX) || defined(JPH_PLATFORM_ANDROID) || defined(JPH_PLATFORM_MACOS) || defined(JPH_PLATFORM_IOS) || defined(JPH_PLATFORM_BSD) #if defined(JPH_CPU_X86) #define JPH_BREAKPOINT __asm volatile ("int $0x3") #elif defined(JPH_CPU_ARM) || defined(JPH_CPU_RISCV) || defined(JPH_CPU_E2K) || defined(JPH_CPU_PPC) || defined(JPH_CPU_LOONGARCH) @@ -426,7 +431,8 @@ JPH_MSVC_SUPPRESS_WARNING(4514) \ JPH_MSVC_SUPPRESS_WARNING(5262) \ JPH_MSVC_SUPPRESS_WARNING(5264) \ - JPH_MSVC_SUPPRESS_WARNING(4738) + JPH_MSVC_SUPPRESS_WARNING(4738) \ + JPH_MSVC_SUPPRESS_WARNING(5045) #define JPH_SUPPRESS_WARNINGS_STD_END \ JPH_SUPPRESS_WARNING_POP diff --git a/thirdparty/jolt_physics/Jolt/Core/FPException.h b/thirdparty/jolt_physics/Jolt/Core/FPException.h index ef757802424e..9e22f5422e2c 100644 --- a/thirdparty/jolt_physics/Jolt/Core/FPException.h +++ b/thirdparty/jolt_physics/Jolt/Core/FPException.h @@ -16,11 +16,12 @@ JPH_NAMESPACE_BEGIN class FPExceptionsEnable { }; class FPExceptionDisableInvalid { }; class FPExceptionDisableDivByZero { }; +class FPExceptionDisableOverflow { }; #elif defined(JPH_USE_SSE) -/// Enable floating point divide by zero exception and exceptions on invalid numbers -class FPExceptionsEnable : public FPControlWord<0, _MM_MASK_DIV_ZERO | _MM_MASK_INVALID> { }; +/// Enable floating point divide by zero exception, overflow exceptions and exceptions on invalid numbers +class FPExceptionsEnable : public FPControlWord<0, _MM_MASK_DIV_ZERO | _MM_MASK_INVALID | _MM_MASK_OVERFLOW> { }; /// Disable invalid floating point value exceptions class FPExceptionDisableInvalid : public FPControlWord<_MM_MASK_INVALID, _MM_MASK_INVALID> { }; @@ -28,10 +29,13 @@ class FPExceptionDisableInvalid : public FPControlWord<_MM_MASK_INVALID, _MM_MAS /// Disable division by zero floating point exceptions class FPExceptionDisableDivByZero : public FPControlWord<_MM_MASK_DIV_ZERO, _MM_MASK_DIV_ZERO> { }; +/// Disable floating point overflow exceptions +class FPExceptionDisableOverflow : public FPControlWord<_MM_MASK_OVERFLOW, _MM_MASK_OVERFLOW> { }; + #elif defined(JPH_CPU_ARM) && defined(JPH_COMPILER_MSVC) -/// Enable floating point divide by zero exception and exceptions on invalid numbers -class FPExceptionsEnable : public FPControlWord<0, _EM_INVALID | _EM_ZERODIVIDE> { }; +/// Enable floating point divide by zero exception, overflow exceptions and exceptions on invalid numbers +class FPExceptionsEnable : public FPControlWord<0, _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW> { }; /// Disable invalid floating point value exceptions class FPExceptionDisableInvalid : public FPControlWord<_EM_INVALID, _EM_INVALID> { }; @@ -39,6 +43,9 @@ class FPExceptionDisableInvalid : public FPControlWord<_EM_INVALID, _EM_INVALID> /// Disable division by zero floating point exceptions class FPExceptionDisableDivByZero : public FPControlWord<_EM_ZERODIVIDE, _EM_ZERODIVIDE> { }; +/// Disable floating point overflow exceptions +class FPExceptionDisableOverflow : public FPControlWord<_EM_OVERFLOW, _EM_OVERFLOW> { }; + #elif defined(JPH_CPU_ARM) /// Invalid operation exception bit @@ -47,8 +54,11 @@ static constexpr uint64 FP_IOE = 1 << 8; /// Enable divide by zero exception bit static constexpr uint64 FP_DZE = 1 << 9; -/// Enable floating point divide by zero exception and exceptions on invalid numbers -class FPExceptionsEnable : public FPControlWord { }; +/// Enable floating point overflow bit +static constexpr uint64 FP_OFE = 1 << 10; + +/// Enable floating point divide by zero exception, overflow exceptions and exceptions on invalid numbers +class FPExceptionsEnable : public FPControlWord { }; /// Disable invalid floating point value exceptions class FPExceptionDisableInvalid : public FPControlWord<0, FP_IOE> { }; @@ -56,6 +66,9 @@ class FPExceptionDisableInvalid : public FPControlWord<0, FP_IOE> { }; /// Disable division by zero floating point exceptions class FPExceptionDisableDivByZero : public FPControlWord<0, FP_DZE> { }; +/// Disable floating point overflow exceptions +class FPExceptionDisableOverflow : public FPControlWord<0, FP_OFE> { }; + #elif defined(JPH_CPU_RISCV) #error "RISC-V only implements manually checking if exceptions occurred by reading the fcsr register. It doesn't generate exceptions. JPH_FLOATING_POINT_EXCEPTIONS_ENABLED must be disabled." @@ -76,6 +89,7 @@ class FPExceptionDisableDivByZero : public FPControlWord<0, FP_DZE> { }; class FPExceptionsEnable { }; class FPExceptionDisableInvalid { }; class FPExceptionDisableDivByZero { }; +class FPExceptionDisableOverflow { }; #endif diff --git a/thirdparty/jolt_physics/Jolt/Core/HashTable.h b/thirdparty/jolt_physics/Jolt/Core/HashTable.h index 9b69f9d08401..d2d766fe0f21 100644 --- a/thirdparty/jolt_physics/Jolt/Core/HashTable.h +++ b/thirdparty/jolt_physics/Jolt/Core/HashTable.h @@ -26,10 +26,10 @@ class HashTable class IteratorBase { public: - /// Properties + /// Properties using difference_type = typename Table::difference_type; - using value_type = typename Table::value_type; - using iterator_category = std::forward_iterator_tag; + using value_type = typename Table::value_type; + using iterator_category = std::forward_iterator_tag; /// Copy constructor IteratorBase(const IteratorBase &inRHS) = default; @@ -179,17 +179,9 @@ class HashTable mSize = inRHS.mSize; } - /// Grow the table to the next power of 2 - void GrowTable() + /// Grow the table to a new size + void GrowTable(size_type inNewMaxSize) { - // Calculate new size - size_type new_max_size = max(mMaxSize << 1, 16); - if (new_max_size < mMaxSize) - { - JPH_ASSERT(false, "Overflow in hash table size, can't grow!"); - return; - } - // Move the old table to a temporary structure size_type old_max_size = mMaxSize; KeyValue *old_data = mData; @@ -201,7 +193,7 @@ class HashTable mLoadLeft = 0; // Allocate new table - AllocateTable(new_max_size); + AllocateTable(inNewMaxSize); // Reset all control bytes memset(mControl, cBucketEmpty, mMaxSize + 15); @@ -252,7 +244,16 @@ class HashTable if (num_deleted * cMaxDeletedElementsDenominator > mMaxSize * cMaxDeletedElementsNumerator) rehash(0); else - GrowTable(); + { + // Grow by a power of 2 + size_type new_max_size = max(mMaxSize << 1, 16); + if (new_max_size < mMaxSize) + { + JPH_ASSERT(false, "Overflow in hash table size, can't grow!"); + return false; + } + GrowTable(new_max_size); + } } // Split hash into index and control value @@ -363,9 +364,9 @@ class HashTable using Base = IteratorBase; public: - /// Properties - using reference = typename Base::value_type &; - using pointer = typename Base::value_type *; + /// Properties + using reference = typename Base::value_type &; + using pointer = typename Base::value_type *; /// Constructors explicit iterator(HashTable *inTable) : Base(inTable) { } @@ -400,9 +401,9 @@ class HashTable using Base = IteratorBase; public: - /// Properties - using reference = const typename Base::value_type &; - using pointer = const typename Base::value_type *; + /// Properties + using reference = const typename Base::value_type &; + using pointer = const typename Base::value_type *; /// Constructors explicit const_iterator(const HashTable *inTable) : Base(inTable) { } @@ -489,11 +490,7 @@ class HashTable if (max_size <= mMaxSize) return; - // Allocate buffers - AllocateTable(max_size); - - // Reset all control bytes - memset(mControl, cBucketEmpty, mMaxSize + 15); + GrowTable(max_size); } /// Destroy the entire hash table @@ -523,6 +520,27 @@ class HashTable } } + /// Destroy the entire hash table but keeps the memory allocated + void ClearAndKeepMemory() + { + // Destruct elements + if constexpr (!std::is_trivially_destructible()) + if (!empty()) + for (size_type i = 0; i < mMaxSize; ++i) + if (mControl[i] & cBucketUsed) + mData[i].~KeyValue(); + mSize = 0; + + // If there are elements that are not marked cBucketEmpty, we reset them + size_type max_load = sGetMaxLoad(mMaxSize); + if (mLoadLeft != max_load) + { + // Reset all control bytes + memset(mControl, cBucketEmpty, mMaxSize + 15); + mLoadLeft = max_load; + } + } + /// Iterator to first element iterator begin() { diff --git a/thirdparty/jolt_physics/Jolt/Core/Profiler.cpp b/thirdparty/jolt_physics/Jolt/Core/Profiler.cpp index 39152b10b4d7..6536607d5af7 100644 --- a/thirdparty/jolt_physics/Jolt/Core/Profiler.cpp +++ b/thirdparty/jolt_physics/Jolt/Core/Profiler.cpp @@ -222,8 +222,331 @@ void Profiler::DumpChart(const char *inTag, const Threads &inThreads, const KeyT Profile Chart - - + +