summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--SConstruct148
-rw-r--r--doc/classes/@GlobalScope.xml1
-rw-r--r--doc/classes/Control.xml2
-rw-r--r--doc/classes/NavigationAgent2D.xml7
-rw-r--r--doc/classes/NavigationAgent3D.xml7
-rw-r--r--doc/classes/NavigationPathQueryParameters2D.xml7
-rw-r--r--doc/classes/NavigationPathQueryParameters3D.xml7
-rw-r--r--doc/classes/NavigationServer2D.xml9
-rw-r--r--doc/classes/NavigationServer3D.xml9
-rw-r--r--editor/filesystem_dock.cpp5
-rw-r--r--editor/filesystem_dock.h1
-rw-r--r--editor/import/3d/editor_import_collada.cpp11
-rw-r--r--editor/import/3d/resource_importer_obj.cpp15
-rw-r--r--editor/import/3d/scene_import_settings.cpp22
-rw-r--r--editor/import/3d/scene_import_settings.h4
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp4
-rw-r--r--editor/plugins/animation_player_editor_plugin.h2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp2
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp7
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp4
-rw-r--r--editor/scene_tree_dock.cpp29
-rw-r--r--methods.py4
-rw-r--r--modules/fbx/fbx_document.cpp14
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp2
-rw-r--r--modules/gdscript/gdscript_parser.cpp34
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/cast_enum_to_int.gd9
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/cast_enum_to_int.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/match_array.gd33
-rw-r--r--modules/gdscript/tests/scripts/parser/features/match_array.out6
-rw-r--r--modules/gdscript/tests/scripts/parser/features/match_dictionary.gd21
-rw-r--r--modules/gdscript/tests/scripts/parser/features/match_dictionary.out3
-rw-r--r--modules/gltf/gltf_document.cpp12
-rw-r--r--modules/navigation/2d/godot_navigation_server_2d.cpp4
-rw-r--r--modules/navigation/2d/godot_navigation_server_2d.h2
-rw-r--r--modules/navigation/2d/nav_mesh_generator_2d.cpp2
-rw-r--r--modules/navigation/3d/godot_navigation_server_3d.cpp129
-rw-r--r--modules/navigation/3d/godot_navigation_server_3d.h7
-rw-r--r--modules/navigation/3d/nav_mesh_generator_3d.cpp2
-rw-r--r--modules/navigation/editor/navigation_mesh_editor_plugin.cpp2
-rw-r--r--platform/android/doc_classes/EditorExportPlatformAndroid.xml30
-rw-r--r--platform/ios/os_ios.mm8
-rw-r--r--platform/windows/detect.py34
-rw-r--r--scene/2d/navigation_agent_2d.cpp26
-rw-r--r--scene/2d/navigation_agent_2d.h8
-rw-r--r--scene/3d/navigation_agent_3d.cpp26
-rw-r--r--scene/3d/navigation_agent_3d.h8
-rw-r--r--servers/navigation/navigation_path_query_parameters_2d.cpp24
-rw-r--r--servers/navigation/navigation_path_query_parameters_2d.h6
-rw-r--r--servers/navigation/navigation_path_query_parameters_3d.cpp24
-rw-r--r--servers/navigation/navigation_path_query_parameters_3d.h6
-rw-r--r--servers/navigation/navigation_utilities.h2
-rw-r--r--servers/navigation_server_2d.cpp2
-rw-r--r--servers/navigation_server_2d.h2
-rw-r--r--servers/navigation_server_2d_dummy.h2
-rw-r--r--servers/navigation_server_3d.cpp2
-rw-r--r--servers/navigation_server_3d.h2
-rw-r--r--servers/navigation_server_3d_dummy.h2
-rw-r--r--thirdparty/README.md2
-rw-r--r--thirdparty/mbedtls/include/psa/crypto.h14
-rw-r--r--thirdparty/mbedtls/include/psa/crypto_extra.h4
-rw-r--r--thirdparty/mbedtls/patches/msvc-redeclaration-bug.diff98
62 files changed, 781 insertions, 144 deletions
diff --git a/SConstruct b/SConstruct
index 2cce05a20b..7452d755a8 100644
--- a/SConstruct
+++ b/SConstruct
@@ -180,6 +180,7 @@ opts.Add(
)
opts.Add(BoolVariable("debug_symbols", "Build with debugging symbols", False))
opts.Add(BoolVariable("separate_debug_symbols", "Extract debugging symbols to a separate file", False))
+opts.Add(BoolVariable("debug_paths_relative", "Make file paths in debug symbols relative (if supported)", True))
opts.Add(EnumVariable("lto", "Link-time optimization (production builds)", "none", ("none", "auto", "thin", "full")))
opts.Add(BoolVariable("production", "Set defaults to build Godot for use in production", False))
opts.Add(BoolVariable("threads", "Enable threading support", True))
@@ -583,73 +584,6 @@ print(f'Building for platform "{selected_platform}", architecture "{env["arch"]}
if env.dev_build:
print("NOTE: Developer build, with debug optimization level and debug symbols (unless overridden).")
-# Set optimize and debug_symbols flags.
-# "custom" means do nothing and let users set their own optimization flags.
-# Needs to happen after configure to have `env.msvc` defined.
-if env.msvc:
- if env["debug_symbols"]:
- env.Append(CCFLAGS=["/Zi", "/FS"])
- env.Append(LINKFLAGS=["/DEBUG:FULL"])
- else:
- env.Append(LINKFLAGS=["/DEBUG:NONE"])
-
- if env["optimize"] == "speed":
- env.Append(CCFLAGS=["/O2"])
- env.Append(LINKFLAGS=["/OPT:REF"])
- elif env["optimize"] == "speed_trace":
- env.Append(CCFLAGS=["/O2"])
- env.Append(LINKFLAGS=["/OPT:REF", "/OPT:NOICF"])
- elif env["optimize"] == "size":
- env.Append(CCFLAGS=["/O1"])
- env.Append(LINKFLAGS=["/OPT:REF"])
- elif env["optimize"] == "debug" or env["optimize"] == "none":
- env.Append(CCFLAGS=["/Od"])
-else:
- if env["debug_symbols"]:
- # Adding dwarf-4 explicitly makes stacktraces work with clang builds,
- # otherwise addr2line doesn't understand them
- env.Append(CCFLAGS=["-gdwarf-4"])
- if env.dev_build:
- env.Append(CCFLAGS=["-g3"])
- else:
- env.Append(CCFLAGS=["-g2"])
- else:
- if methods.using_clang(env) and not methods.is_vanilla_clang(env):
- # Apple Clang, its linker doesn't like -s.
- env.Append(LINKFLAGS=["-Wl,-S", "-Wl,-x", "-Wl,-dead_strip"])
- else:
- env.Append(LINKFLAGS=["-s"])
-
- if env["optimize"] == "speed":
- env.Append(CCFLAGS=["-O3"])
- # `-O2` is friendlier to debuggers than `-O3`, leading to better crash backtraces.
- elif env["optimize"] == "speed_trace":
- env.Append(CCFLAGS=["-O2"])
- elif env["optimize"] == "size":
- env.Append(CCFLAGS=["-Os"])
- elif env["optimize"] == "debug":
- env.Append(CCFLAGS=["-Og"])
- elif env["optimize"] == "none":
- env.Append(CCFLAGS=["-O0"])
-
-# Needs to happen after configure to handle "auto".
-if env["lto"] != "none":
- print("Using LTO: " + env["lto"])
-
-# Set our C and C++ standard requirements.
-# C++17 is required as we need guaranteed copy elision as per GH-36436.
-# Prepending to make it possible to override.
-# This needs to come after `configure`, otherwise we don't have env.msvc.
-if not env.msvc:
- # Specifying GNU extensions support explicitly, which are supported by
- # both GCC and Clang. Both currently default to gnu11 and gnu++14.
- env.Prepend(CFLAGS=["-std=gnu11"])
- env.Prepend(CXXFLAGS=["-std=gnu++17"])
-else:
- # MSVC doesn't have clear C standard support, /std only covers C++.
- # We apply it to CCFLAGS (both C and C++ code) in case it impacts C features.
- env.Prepend(CCFLAGS=["/std:c++17"])
-
# Enforce our minimal compiler version requirements
cc_version = methods.get_compiler_version(env) or {
"major": None,
@@ -695,6 +629,9 @@ if methods.using_gcc(env):
"to switch to posix threads."
)
Exit(255)
+ if env["debug_paths_relative"] and cc_version_major < 8:
+ print("GCC < 8 doesn't support -ffile-prefix-map, disabling `debug_paths_relative` option.")
+ env["debug_paths_relative"] = False
elif methods.using_clang(env):
if cc_version_major == -1:
print(
@@ -717,12 +654,89 @@ elif methods.using_clang(env):
"support C++17. Supported versions are Apple Clang 10 and later."
)
Exit(255)
+ if env["debug_paths_relative"] and not vanilla and cc_version_major < 12:
+ print("Apple Clang < 12 doesn't support -ffile-prefix-map, disabling `debug_paths_relative` option.")
+ env["debug_paths_relative"] = False
elif cc_version_major < 6:
print(
"Detected Clang version older than 6, which does not fully support "
"C++17. Supported versions are Clang 6 and later."
)
Exit(255)
+ if env["debug_paths_relative"] and cc_version_major < 10:
+ print("Clang < 10 doesn't support -ffile-prefix-map, disabling `debug_paths_relative` option.")
+ env["debug_paths_relative"] = False
+
+# Set optimize and debug_symbols flags.
+# "custom" means do nothing and let users set their own optimization flags.
+# Needs to happen after configure to have `env.msvc` defined.
+if env.msvc:
+ if env["debug_symbols"]:
+ env.Append(CCFLAGS=["/Zi", "/FS"])
+ env.Append(LINKFLAGS=["/DEBUG:FULL"])
+ else:
+ env.Append(LINKFLAGS=["/DEBUG:NONE"])
+
+ if env["optimize"] == "speed":
+ env.Append(CCFLAGS=["/O2"])
+ env.Append(LINKFLAGS=["/OPT:REF"])
+ elif env["optimize"] == "speed_trace":
+ env.Append(CCFLAGS=["/O2"])
+ env.Append(LINKFLAGS=["/OPT:REF", "/OPT:NOICF"])
+ elif env["optimize"] == "size":
+ env.Append(CCFLAGS=["/O1"])
+ env.Append(LINKFLAGS=["/OPT:REF"])
+ elif env["optimize"] == "debug" or env["optimize"] == "none":
+ env.Append(CCFLAGS=["/Od"])
+else:
+ if env["debug_symbols"]:
+ # Adding dwarf-4 explicitly makes stacktraces work with clang builds,
+ # otherwise addr2line doesn't understand them
+ env.Append(CCFLAGS=["-gdwarf-4"])
+ if env.dev_build:
+ env.Append(CCFLAGS=["-g3"])
+ else:
+ env.Append(CCFLAGS=["-g2"])
+ if env["debug_paths_relative"]:
+ # Remap absolute paths to relative paths for debug symbols.
+ project_path = Dir("#").abspath
+ env.Append(CCFLAGS=[f"-ffile-prefix-map={project_path}=."])
+ else:
+ if methods.using_clang(env) and not methods.is_vanilla_clang(env):
+ # Apple Clang, its linker doesn't like -s.
+ env.Append(LINKFLAGS=["-Wl,-S", "-Wl,-x", "-Wl,-dead_strip"])
+ else:
+ env.Append(LINKFLAGS=["-s"])
+
+ if env["optimize"] == "speed":
+ env.Append(CCFLAGS=["-O3"])
+ # `-O2` is friendlier to debuggers than `-O3`, leading to better crash backtraces.
+ elif env["optimize"] == "speed_trace":
+ env.Append(CCFLAGS=["-O2"])
+ elif env["optimize"] == "size":
+ env.Append(CCFLAGS=["-Os"])
+ elif env["optimize"] == "debug":
+ env.Append(CCFLAGS=["-Og"])
+ elif env["optimize"] == "none":
+ env.Append(CCFLAGS=["-O0"])
+
+# Needs to happen after configure to handle "auto".
+if env["lto"] != "none":
+ print("Using LTO: " + env["lto"])
+
+# Set our C and C++ standard requirements.
+# C++17 is required as we need guaranteed copy elision as per GH-36436.
+# Prepending to make it possible to override.
+# This needs to come after `configure`, otherwise we don't have env.msvc.
+if not env.msvc:
+ # Specifying GNU extensions support explicitly, which are supported by
+ # both GCC and Clang. Both currently default to gnu11 and gnu++14.
+ env.Prepend(CFLAGS=["-std=gnu11"])
+ env.Prepend(CXXFLAGS=["-std=gnu++17"])
+else:
+ # MSVC doesn't have clear C standard support, /std only covers C++.
+ # We apply it to CCFLAGS (both C and C++ code) in case it impacts C features.
+ env.Prepend(CCFLAGS=["/std:c++17"])
# Disable exception handling. Godot doesn't use exceptions anywhere, and this
# saves around 20% of binary size and very significant build time (GH-80513).
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 6d8517927c..0307684588 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -901,6 +901,7 @@
<method name="printraw" qualifiers="vararg">
<description>
Prints one or more arguments to strings in the best way possible to the OS terminal. Unlike [method print], no newline is automatically added at the end.
+ [b]Note:[/b] The OS terminal is [i]not[/i] the same as the editor's Output dock. The output sent to the OS terminal can be seen when running Godot from a terminal. On Windows, this requires using the [code]console.exe[/code] executable.
[codeblocks]
[gdscript]
printraw("A")
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index cc32964e87..09bc4b3412 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -944,7 +944,7 @@
Enables whether rendering of [CanvasItem] based children should be clipped to this control's rectangle. If [code]true[/code], parts of a child which would be visibly outside of this control's rectangle will not be rendered and won't receive input.
</member>
<member name="custom_minimum_size" type="Vector2" setter="set_custom_minimum_size" getter="get_custom_minimum_size" default="Vector2(0, 0)">
- The minimum size of the node's bounding rectangle. If you set it to a value greater than (0, 0), the node's bounding rectangle will always have at least this size, even if its content is smaller. If it's set to (0, 0), the node sizes automatically to fit its content, be it a texture or child nodes.
+ The minimum size of the node's bounding rectangle. If you set it to a value greater than [code](0, 0)[/code], the node's bounding rectangle will always have at least this size. Note that [Control] nodes have their internal minimum size returned by [method get_minimum_size]. It depends on the control's contents, like text, textures, or style boxes. The actual minimum size is the maximum value of this property and the internal minimum size (see [method get_combined_minimum_size]).
</member>
<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" enum="Control.FocusMode" default="0">
The focus access mode for the control (None, Click or All). Only one Control can be focused at the same time, and it will receive keyboard, gamepad, and mouse signals.
diff --git a/doc/classes/NavigationAgent2D.xml b/doc/classes/NavigationAgent2D.xml
index 132ece53b0..6f0561e66e 100644
--- a/doc/classes/NavigationAgent2D.xml
+++ b/doc/classes/NavigationAgent2D.xml
@@ -198,6 +198,13 @@
The radius of the avoidance agent. This is the "body" of the avoidance agent and not the avoidance maneuver starting radius (which is controlled by [member neighbor_distance]).
Does not affect normal pathfinding. To change an actor's pathfinding radius bake [NavigationMesh] resources with a different [member NavigationMesh.agent_radius] property and use different navigation maps for each actor size.
</member>
+ <member name="simplify_epsilon" type="float" setter="set_simplify_epsilon" getter="get_simplify_epsilon" default="0.0">
+ The path simplification amount in worlds units.
+ </member>
+ <member name="simplify_path" type="bool" setter="set_simplify_path" getter="get_simplify_path" default="false">
+ If [code]true[/code] a simplified version of the path will be returned with less critical path points removed. The simplification amount is controlled by [member simplify_epsilon]. The simplification uses a variant of Ramer-Douglas-Peucker algorithm for curve point decimation.
+ Path simplification can be helpful to mitigate various path following issues that can arise with certain agent types and script behaviors. E.g. "steering" agents or avoidance in "open fields".
+ </member>
<member name="target_desired_distance" type="float" setter="set_target_desired_distance" getter="get_target_desired_distance" default="10.0">
The distance threshold before the target is considered to be reached. On reaching the target, [signal target_reached] is emitted and navigation ends (see [method is_navigation_finished] and [signal navigation_finished]).
You can make navigation end early by setting this property to a value greater than [member path_desired_distance] (navigation will end before reaching the last waypoint).
diff --git a/doc/classes/NavigationAgent3D.xml b/doc/classes/NavigationAgent3D.xml
index dd75cedf61..64ee35a84b 100644
--- a/doc/classes/NavigationAgent3D.xml
+++ b/doc/classes/NavigationAgent3D.xml
@@ -204,6 +204,13 @@
The radius of the avoidance agent. This is the "body" of the avoidance agent and not the avoidance maneuver starting radius (which is controlled by [member neighbor_distance]).
Does not affect normal pathfinding. To change an actor's pathfinding radius bake [NavigationMesh] resources with a different [member NavigationMesh.agent_radius] property and use different navigation maps for each actor size.
</member>
+ <member name="simplify_epsilon" type="float" setter="set_simplify_epsilon" getter="get_simplify_epsilon" default="0.0">
+ The path simplification amount in worlds units.
+ </member>
+ <member name="simplify_path" type="bool" setter="set_simplify_path" getter="get_simplify_path" default="false">
+ If [code]true[/code] a simplified version of the path will be returned with less critical path points removed. The simplification amount is controlled by [member simplify_epsilon]. The simplification uses a variant of Ramer-Douglas-Peucker algorithm for curve point decimation.
+ Path simplification can be helpful to mitigate various path following issues that can arise with certain agent types and script behaviors. E.g. "steering" agents or avoidance in "open fields".
+ </member>
<member name="target_desired_distance" type="float" setter="set_target_desired_distance" getter="get_target_desired_distance" default="1.0">
The distance threshold before the target is considered to be reached. On reaching the target, [signal target_reached] is emitted and navigation ends (see [method is_navigation_finished] and [signal navigation_finished]).
You can make navigation end early by setting this property to a value greater than [member path_desired_distance] (navigation will end before reaching the last waypoint).
diff --git a/doc/classes/NavigationPathQueryParameters2D.xml b/doc/classes/NavigationPathQueryParameters2D.xml
index 7d9ecf61b0..ce0a00bc83 100644
--- a/doc/classes/NavigationPathQueryParameters2D.xml
+++ b/doc/classes/NavigationPathQueryParameters2D.xml
@@ -25,6 +25,13 @@
<member name="pathfinding_algorithm" type="int" setter="set_pathfinding_algorithm" getter="get_pathfinding_algorithm" enum="NavigationPathQueryParameters2D.PathfindingAlgorithm" default="0">
The pathfinding algorithm used in the path query.
</member>
+ <member name="simplify_epsilon" type="float" setter="set_simplify_epsilon" getter="get_simplify_epsilon" default="0.0">
+ The path simplification amount in worlds units.
+ </member>
+ <member name="simplify_path" type="bool" setter="set_simplify_path" getter="get_simplify_path" default="false">
+ If [code]true[/code] a simplified version of the path will be returned with less critical path points removed. The simplification amount is controlled by [member simplify_epsilon]. The simplification uses a variant of Ramer-Douglas-Peucker algorithm for curve point decimation.
+ Path simplification can be helpful to mitigate various path following issues that can arise with certain agent types and script behaviors. E.g. "steering" agents or avoidance in "open fields".
+ </member>
<member name="start_position" type="Vector2" setter="set_start_position" getter="get_start_position" default="Vector2(0, 0)">
The pathfinding start position in global coordinates.
</member>
diff --git a/doc/classes/NavigationPathQueryParameters3D.xml b/doc/classes/NavigationPathQueryParameters3D.xml
index 862f8a8347..fcd913f73b 100644
--- a/doc/classes/NavigationPathQueryParameters3D.xml
+++ b/doc/classes/NavigationPathQueryParameters3D.xml
@@ -25,6 +25,13 @@
<member name="pathfinding_algorithm" type="int" setter="set_pathfinding_algorithm" getter="get_pathfinding_algorithm" enum="NavigationPathQueryParameters3D.PathfindingAlgorithm" default="0">
The pathfinding algorithm used in the path query.
</member>
+ <member name="simplify_epsilon" type="float" setter="set_simplify_epsilon" getter="get_simplify_epsilon" default="0.0">
+ The path simplification amount in worlds units.
+ </member>
+ <member name="simplify_path" type="bool" setter="set_simplify_path" getter="get_simplify_path" default="false">
+ If [code]true[/code] a simplified version of the path will be returned with less critical path points removed. The simplification amount is controlled by [member simplify_epsilon]. The simplification uses a variant of Ramer-Douglas-Peucker algorithm for curve point decimation.
+ Path simplification can be helpful to mitigate various path following issues that can arise with certain agent types and script behaviors. E.g. "steering" agents or avoidance in "open fields".
+ </member>
<member name="start_position" type="Vector3" setter="set_start_position" getter="get_start_position" default="Vector3(0, 0, 0)">
The pathfinding start position in global coordinates.
</member>
diff --git a/doc/classes/NavigationServer2D.xml b/doc/classes/NavigationServer2D.xml
index baef7dc02d..a6f6abccbd 100644
--- a/doc/classes/NavigationServer2D.xml
+++ b/doc/classes/NavigationServer2D.xml
@@ -947,6 +947,15 @@
If [code]true[/code] enables debug mode on the NavigationServer.
</description>
</method>
+ <method name="simplify_path">
+ <return type="PackedVector2Array" />
+ <param index="0" name="path" type="PackedVector2Array" />
+ <param index="1" name="epsilon" type="float" />
+ <description>
+ Returns a simplified version of [param path] with less critical path points removed. The simplification amount is in worlds units and controlled by [param epsilon]. The simplification uses a variant of Ramer-Douglas-Peucker algorithm for curve point decimation.
+ Path simplification can be helpful to mitigate various path following issues that can arise with certain agent types and script behaviors. E.g. "steering" agents or avoidance in "open fields".
+ </description>
+ </method>
</methods>
<signals>
<signal name="map_changed">
diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml
index 6be9d5165f..6fcf033544 100644
--- a/doc/classes/NavigationServer3D.xml
+++ b/doc/classes/NavigationServer3D.xml
@@ -1094,6 +1094,15 @@
If [code]true[/code] enables debug mode on the NavigationServer.
</description>
</method>
+ <method name="simplify_path">
+ <return type="PackedVector3Array" />
+ <param index="0" name="path" type="PackedVector3Array" />
+ <param index="1" name="epsilon" type="float" />
+ <description>
+ Returns a simplified version of [param path] with less critical path points removed. The simplification amount is in worlds units and controlled by [param epsilon]. The simplification uses a variant of Ramer-Douglas-Peucker algorithm for curve point decimation.
+ Path simplification can be helpful to mitigate various path following issues that can arise with certain agent types and script behaviors. E.g. "steering" agents or avoidance in "open fields".
+ </description>
+ </method>
</methods>
<signals>
<signal name="avoidance_debug_changed">
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 3b6ce8d396..2ed547a970 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -3693,6 +3693,10 @@ void FileSystemDock::_feature_profile_changed() {
_update_display_mode(true);
}
+void FileSystemDock::_project_settings_changed() {
+ assigned_folder_colors = ProjectSettings::get_singleton()->get_setting("file_customization/folder_colors");
+}
+
void FileSystemDock::set_file_sort(FileSortOption p_file_sort) {
for (int i = 0; i != FILE_SORT_MAX; i++) {
tree_button_sort->get_popup()->set_item_checked(i, (i == (int)p_file_sort));
@@ -4122,6 +4126,7 @@ FileSystemDock::FileSystemDock() {
old_display_mode = DISPLAY_MODE_TREE_ONLY;
file_list_display_mode = FILE_LIST_DISPLAY_THUMBNAILS;
+ ProjectSettings::get_singleton()->connect("settings_changed", callable_mp(this, &FileSystemDock::_project_settings_changed));
add_resource_tooltip_plugin(memnew(EditorTextureTooltipPlugin));
}
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index c9fe3a8baf..8830f31d2d 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -362,6 +362,7 @@ private:
bool _is_file_type_disabled_by_feature_profile(const StringName &p_class);
void _feature_profile_changed();
+ void _project_settings_changed();
static Vector<String> _remove_self_included_paths(Vector<String> selected_strings);
void _change_bottom_dock_placement();
diff --git a/editor/import/3d/editor_import_collada.cpp b/editor/import/3d/editor_import_collada.cpp
index 58aa6a462d..4b91b1431a 100644
--- a/editor/import/3d/editor_import_collada.cpp
+++ b/editor/import/3d/editor_import_collada.cpp
@@ -996,7 +996,16 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p
surftool->generate_tangents();
}
- if (p_mesh->get_blend_shape_count() != 0 || p_skin_controller) {
+ // Disable compression if all z equals 0 (the mesh is 2D).
+ bool is_mesh_2d = true;
+ for (int k = 0; k < vertex_array.size(); k++) {
+ if (!Math::is_zero_approx(vertex_array[k].vertex.z)) {
+ is_mesh_2d = false;
+ break;
+ }
+ };
+
+ if (p_mesh->get_blend_shape_count() != 0 || p_skin_controller || is_mesh_2d) {
// Can't compress if attributes missing or if using vertex weights.
mesh_flags &= ~RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES;
}
diff --git a/editor/import/3d/resource_importer_obj.cpp b/editor/import/3d/resource_importer_obj.cpp
index 62643eaa25..242b483b51 100644
--- a/editor/import/3d/resource_importer_obj.cpp
+++ b/editor/import/3d/resource_importer_obj.cpp
@@ -384,7 +384,22 @@ static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes,
if (p_disable_compression) {
mesh_flags = 0;
+ } else {
+ bool is_mesh_2d = true;
+
+ // Disable compression if all z equals 0 (the mesh is 2D).
+ for (int i = 0; i < vertices.size(); i++) {
+ if (!Math::is_zero_approx(vertices[i].z)) {
+ is_mesh_2d = false;
+ break;
+ }
+ }
+
+ if (is_mesh_2d) {
+ mesh_flags = 0;
+ }
}
+
//groups are too annoying
if (surf_tool->get_vertex_array().size()) {
//another group going on, commit it
diff --git a/editor/import/3d/scene_import_settings.cpp b/editor/import/3d/scene_import_settings.cpp
index 67b13e3328..620ebce44b 100644
--- a/editor/import/3d/scene_import_settings.cpp
+++ b/editor/import/3d/scene_import_settings.cpp
@@ -1653,6 +1653,28 @@ SceneImportSettingsDialog::SceneImportSettingsDialog() {
camera->set_attributes(camera_attributes);
}
+ // Use a grayscale gradient sky to avoid skewing the preview towards a specific color,
+ // but still allow shaded areas to be easily distinguished (using the ambient and reflected light).
+ // This also helps the user orient themselves in the preview, since the bottom of the sky is black
+ // and the top of the sky is white.
+ procedural_sky_material.instantiate();
+ procedural_sky_material->set_sky_top_color(Color(1, 1, 1));
+ procedural_sky_material->set_sky_horizon_color(Color(0.5, 0.5, 0.5));
+ procedural_sky_material->set_ground_horizon_color(Color(0.5, 0.5, 0.5));
+ procedural_sky_material->set_ground_bottom_color(Color(0, 0, 0));
+ procedural_sky_material->set_sky_curve(2.0);
+ procedural_sky_material->set_ground_curve(0.5);
+ // Hide the sun from the sky.
+ procedural_sky_material->set_sun_angle_max(0.0);
+ sky.instantiate();
+ sky->set_material(procedural_sky_material);
+ environment.instantiate();
+ environment->set_background(Environment::BG_SKY);
+ environment->set_sky(sky);
+ // A custom FOV must be specified, as an orthogonal camera is used for the preview.
+ environment->set_sky_custom_fov(50.0);
+ camera->set_environment(environment);
+
light = memnew(DirectionalLight3D);
light->set_transform(Transform3D().looking_at(Vector3(-1, -2, -0.6), Vector3(0, 1, 0)));
base_viewport->add_child(light);
diff --git a/editor/import/3d/scene_import_settings.h b/editor/import/3d/scene_import_settings.h
index f4954c41db..17d6616fc0 100644
--- a/editor/import/3d/scene_import_settings.h
+++ b/editor/import/3d/scene_import_settings.h
@@ -47,6 +47,7 @@
#include "scene/gui/tab_container.h"
#include "scene/gui/tree.h"
#include "scene/resources/3d/primitive_meshes.h"
+#include "scene/resources/3d/sky_material.h"
class EditorFileDialog;
class EditorInspector;
@@ -78,6 +79,9 @@ class SceneImportSettingsDialog : public ConfirmationDialog {
Camera3D *camera = nullptr;
Ref<CameraAttributesPractical> camera_attributes;
+ Ref<Environment> environment;
+ Ref<Sky> sky;
+ Ref<ProceduralSkyMaterial> procedural_sky_material;
bool first_aabb = false;
AABB contents_aabb;
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index bfac9c8cf9..43928b9c17 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -2041,10 +2041,10 @@ AnimationPlayerEditor::AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plug
vb->add_child(name_hb);
name_dialog->register_text_enter(name);
- error_dialog = memnew(ConfirmationDialog);
+ error_dialog = memnew(AcceptDialog);
error_dialog->set_ok_button_text(TTR("Close"));
error_dialog->set_title(TTR("Error!"));
- add_child(error_dialog);
+ name_dialog->add_child(error_dialog);
name_dialog->connect(SNAME("confirmed"), callable_mp(this, &AnimationPlayerEditor::_animation_name_edited));
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index c780023c6d..a1175e2a0f 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -128,7 +128,7 @@ class AnimationPlayerEditor : public VBoxContainer {
} blend_editor;
ConfirmationDialog *name_dialog = nullptr;
- ConfirmationDialog *error_dialog = nullptr;
+ AcceptDialog *error_dialog = nullptr;
int name_dialog_op = TOOL_NEW_ANIM;
bool updating = false;
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 41e5eee486..8d24e90cce 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -5944,7 +5944,7 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian
}
Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
- if (_cyclical_dependency_exists(edited_scene->get_scene_file_path(), instantiated_scene)) {
+ if (edited_scene && !edited_scene->get_scene_file_path().is_empty() && _cyclical_dependency_exists(edited_scene->get_scene_file_path(), instantiated_scene)) {
memdelete(instantiated_scene);
can_instantiate = false;
is_cyclical_dep = true;
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index 085e8cddbe..7e98950f32 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -979,10 +979,11 @@ Ref<StandardMaterial3D> EditorNode3DGizmoPlugin::get_material(const String &p_na
Ref<StandardMaterial3D> mat = materials[p_name][index];
- if (current_state == ON_TOP && p_gizmo->is_selected()) {
+ bool on_top_mat = mat->get_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST);
+
+ if (!on_top_mat && current_state == ON_TOP && p_gizmo->is_selected()) {
+ mat = mat->duplicate();
mat->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true);
- } else {
- mat->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, false);
}
return mat;
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 88250ea3c3..aea3ea9700 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -4507,7 +4507,7 @@ bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant
continue;
}
Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
- if (_cyclical_dependency_exists(edited_scene->get_scene_file_path(), instantiated_scene)) {
+ if (edited_scene && !edited_scene->get_scene_file_path().is_empty() && _cyclical_dependency_exists(edited_scene->get_scene_file_path(), instantiated_scene)) {
memdelete(instantiated_scene);
can_instantiate = false;
is_cyclical_dep = true;
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index 3055e178ba..fc361ab264 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -2334,7 +2334,9 @@ void SpriteFramesEditorPlugin::make_visible(bool p_visible) {
EditorNode::get_bottom_panel()->make_item_visible(frames_editor);
} else {
button->hide();
- frames_editor->edit(Ref<SpriteFrames>());
+ if (frames_editor->is_visible_in_tree()) {
+ EditorNode::get_bottom_panel()->hide_bottom_panel();
+ }
}
}
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 757b9e72ea..0b489cbb36 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -2079,17 +2079,19 @@ bool SceneTreeDock::_validate_no_foreign() {
return false;
}
- // When edited_scene inherits from another one the root Node will be the parent Scene,
- // we don't want to consider that Node a foreign one otherwise we would not be able to
- // delete it.
- if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene == E) {
- continue;
- }
+ if (edited_scene->get_scene_inherited_state().is_valid()) {
+ // When edited_scene inherits from another one the root Node will be the parent Scene,
+ // we don't want to consider that Node a foreign one otherwise we would not be able to
+ // delete it.
+ if (edited_scene == E && current_option != TOOL_REPLACE) {
+ continue;
+ }
- if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(E)) >= 0) {
- accept->set_text(TTR("Can't operate on nodes the current scene inherits from!"));
- accept->popup_centered();
- return false;
+ if (edited_scene == E || edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(E)) >= 0) {
+ accept->set_text(TTR("Can't operate on nodes the current scene inherits from!"));
+ accept->popup_centered();
+ return false;
+ }
}
}
@@ -3443,6 +3445,13 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
can_replace = false;
break;
}
+
+ if (edited_scene->get_scene_inherited_state().is_valid()) {
+ if (E == edited_scene || edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(E)) >= 0) {
+ can_replace = false;
+ break;
+ }
+ }
}
if (can_replace) {
diff --git a/methods.py b/methods.py
index dd01469b86..4d1f4c1cda 100644
--- a/methods.py
+++ b/methods.py
@@ -1621,8 +1621,8 @@ def generate_vs_project(env, original_args, project_name="godot"):
sln_template = sln_template.replace("%%NAME%%", project_name)
sln_template = sln_template.replace("%%UUID%%", proj_uuid)
sln_template = sln_template.replace("%%SLNUUID%%", sln_uuid)
- sln_template = sln_template.replace("%%SECTION1%%", "\n ".join(section1))
- sln_template = sln_template.replace("%%SECTION2%%", "\n ".join(section2))
+ sln_template = sln_template.replace("%%SECTION1%%", "\n\t\t".join(section1))
+ sln_template = sln_template.replace("%%SECTION2%%", "\n\t\t".join(section2))
with open(f"{project_name}.sln", "w", encoding="utf-8", newline="\r\n") as f:
f.write(sln_template)
diff --git a/modules/fbx/fbx_document.cpp b/modules/fbx/fbx_document.cpp
index 1dbe4c535a..63766247ee 100644
--- a/modules/fbx/fbx_document.cpp
+++ b/modules/fbx/fbx_document.cpp
@@ -1080,7 +1080,7 @@ Error FBXDocument::_parse_materials(Ref<FBXState> p_state) {
if (fbx_material->pbr.base_color.has_value) {
Color albedo = _material_color(fbx_material->pbr.base_color, fbx_material->pbr.base_factor);
- material->set_albedo(albedo);
+ material->set_albedo(albedo.linear_to_srgb());
}
if (fbx_material->features.double_sided.enabled) {
@@ -1178,7 +1178,11 @@ Error FBXDocument::_parse_materials(Ref<FBXState> p_state) {
}
// Combined textures and factors are very unreliable in FBX
- material->set_albedo(Color(1, 1, 1));
+ Color albedo_factor = Color(1, 1, 1);
+ if (fbx_material->pbr.base_factor.has_value) {
+ albedo_factor *= (float)fbx_material->pbr.base_factor.value_real;
+ }
+ material->set_albedo(albedo_factor.linear_to_srgb());
// TODO: Does not support rotation, could be inverted?
material->set_uv1_offset(_as_vec3(base_texture->uv_transform.translation));
@@ -1232,11 +1236,11 @@ Error FBXDocument::_parse_materials(Ref<FBXState> p_state) {
if (fbx_material->pbr.emission_color.has_value) {
material->set_feature(BaseMaterial3D::FEATURE_EMISSION, true);
- material->set_emission(_material_color(fbx_material->pbr.emission_color));
+ material->set_emission(_material_color(fbx_material->pbr.emission_color).linear_to_srgb());
material->set_emission_energy_multiplier(float(fbx_material->pbr.emission_factor.value_real));
}
- const ufbx_texture *emission_texture = _get_file_texture(fbx_material->pbr.ambient_occlusion.texture);
+ const ufbx_texture *emission_texture = _get_file_texture(fbx_material->pbr.emission_color.texture);
if (emission_texture) {
material->set_texture(BaseMaterial3D::TEXTURE_EMISSION, _get_texture(p_state, GLTFTextureIndex(emission_texture->file_index), TEXTURE_TYPE_GENERIC));
material->set_feature(BaseMaterial3D::FEATURE_EMISSION, true);
@@ -1266,7 +1270,7 @@ Error FBXDocument::_parse_cameras(Ref<FBXState> p_state) {
camera->set_fov(Math::deg_to_rad(real_t(fbx_camera->field_of_view_deg.y)));
} else {
camera->set_perspective(false);
- camera->set_size_mag(real_t(fbx_camera->orthographic_size.y));
+ camera->set_size_mag(real_t(fbx_camera->orthographic_size.y * 0.5f));
}
if (fbx_camera->near_plane != 0.0f) {
camera->set_depth_near(fbx_camera->near_plane);
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index a30a87f3a1..b198338ff0 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -3469,6 +3469,8 @@ void GDScriptAnalyzer::reduce_cast(GDScriptParser::CastNode *p_cast) {
if (op_type.builtin_type == Variant::INT && cast_type.kind == GDScriptParser::DataType::ENUM) {
mark_node_unsafe(p_cast);
valid = true;
+ } else if (op_type.kind == GDScriptParser::DataType::ENUM && cast_type.builtin_type == Variant::INT) {
+ valid = true;
} else if (op_type.kind == GDScriptParser::DataType::BUILTIN && cast_type.kind == GDScriptParser::DataType::BUILTIN) {
valid = Variant::can_convert(op_type.builtin_type, cast_type.builtin_type);
} else if (op_type.kind != GDScriptParser::DataType::BUILTIN && cast_type.kind != GDScriptParser::DataType::BUILTIN) {
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 173bff575a..bb5d6770c6 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -2270,28 +2270,31 @@ GDScriptParser::PatternNode *GDScriptParser::parse_match_pattern(PatternNode *p_
break;
case GDScriptTokenizer::Token::BRACKET_OPEN: {
// Array.
+ push_multiline(true);
advance();
pattern->pattern_type = PatternNode::PT_ARRAY;
-
- if (!check(GDScriptTokenizer::Token::BRACKET_CLOSE)) {
- do {
- PatternNode *sub_pattern = parse_match_pattern(p_root_pattern != nullptr ? p_root_pattern : pattern);
- if (sub_pattern == nullptr) {
- continue;
- }
- if (pattern->rest_used) {
- push_error(R"(The ".." pattern must be the last element in the pattern array.)");
- } else if (sub_pattern->pattern_type == PatternNode::PT_REST) {
- pattern->rest_used = true;
- }
- pattern->array.push_back(sub_pattern);
- } while (match(GDScriptTokenizer::Token::COMMA));
- }
+ do {
+ if (is_at_end() || check(GDScriptTokenizer::Token::BRACKET_CLOSE)) {
+ break;
+ }
+ PatternNode *sub_pattern = parse_match_pattern(p_root_pattern != nullptr ? p_root_pattern : pattern);
+ if (sub_pattern == nullptr) {
+ continue;
+ }
+ if (pattern->rest_used) {
+ push_error(R"(The ".." pattern must be the last element in the pattern array.)");
+ } else if (sub_pattern->pattern_type == PatternNode::PT_REST) {
+ pattern->rest_used = true;
+ }
+ pattern->array.push_back(sub_pattern);
+ } while (match(GDScriptTokenizer::Token::COMMA));
consume(GDScriptTokenizer::Token::BRACKET_CLOSE, R"(Expected "]" to close the array pattern.)");
+ pop_multiline();
break;
}
case GDScriptTokenizer::Token::BRACE_OPEN: {
// Dictionary.
+ push_multiline(true);
advance();
pattern->pattern_type = PatternNode::PT_DICTIONARY;
do {
@@ -2334,6 +2337,7 @@ GDScriptParser::PatternNode *GDScriptParser::parse_match_pattern(PatternNode *p_
}
} while (match(GDScriptTokenizer::Token::COMMA));
consume(GDScriptTokenizer::Token::BRACE_CLOSE, R"(Expected "}" to close the dictionary pattern.)");
+ pop_multiline();
break;
}
default: {
diff --git a/modules/gdscript/tests/scripts/analyzer/features/cast_enum_to_int.gd b/modules/gdscript/tests/scripts/analyzer/features/cast_enum_to_int.gd
new file mode 100644
index 0000000000..77ef9e2073
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/cast_enum_to_int.gd
@@ -0,0 +1,9 @@
+# GH-85882
+
+enum Foo { A, B, C }
+
+func test():
+ var a := Foo.A
+ var b := a as int + 1
+ print(b)
+
diff --git a/modules/gdscript/tests/scripts/analyzer/features/cast_enum_to_int.out b/modules/gdscript/tests/scripts/analyzer/features/cast_enum_to_int.out
new file mode 100644
index 0000000000..a7f1357bb2
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/cast_enum_to_int.out
@@ -0,0 +1,2 @@
+GDTEST_OK
+1
diff --git a/modules/gdscript/tests/scripts/parser/features/match_array.gd b/modules/gdscript/tests/scripts/parser/features/match_array.gd
new file mode 100644
index 0000000000..9103092cb4
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/match_array.gd
@@ -0,0 +1,33 @@
+func foo(x):
+ match x:
+ ["value1"]:
+ print('["value1"]')
+ ["value1", "value2"]:
+ print('["value1", "value2"]')
+
+func bar(x):
+ match x:
+ [
+ "value1"
+ ]:
+ print('multiline ["value1"]')
+ [
+ "value1",
+ "value2",
+ ]:
+ print('multiline ["value1", "value2",]')
+ [
+ "value1",
+ [
+ "value2",
+ ..,
+ ],
+ ]:
+ print('multiline ["value1", ["value2", ..,],]')
+
+func test():
+ foo(["value1"])
+ foo(["value1", "value2"])
+ bar(["value1"])
+ bar(["value1", "value2"])
+ bar(["value1", ["value2", "value3"]])
diff --git a/modules/gdscript/tests/scripts/parser/features/match_array.out b/modules/gdscript/tests/scripts/parser/features/match_array.out
new file mode 100644
index 0000000000..d0111f07b1
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/match_array.out
@@ -0,0 +1,6 @@
+GDTEST_OK
+["value1"]
+["value1", "value2"]
+multiline ["value1"]
+multiline ["value1", "value2",]
+multiline ["value1", ["value2", ..,],]
diff --git a/modules/gdscript/tests/scripts/parser/features/match_dictionary.gd b/modules/gdscript/tests/scripts/parser/features/match_dictionary.gd
index 75857fb8ff..7685622e5a 100644
--- a/modules/gdscript/tests/scripts/parser/features/match_dictionary.gd
+++ b/modules/gdscript/tests/scripts/parser/features/match_dictionary.gd
@@ -26,6 +26,24 @@ func bar(x):
_:
print("wildcard")
+func baz(x):
+ match x:
+ {
+ "key1": "value1"
+ }:
+ print('multiline {"key1": "value1"}')
+ {
+ "key2": "value2",
+ }:
+ print('multiline {"key2": "value2",}')
+ {
+ "key3": {
+ "key1",
+ ..,
+ },
+ }:
+ print('multiline {"key3": {"key1", ..,},}')
+
func test():
foo({"key1": "value1", "key2": "value2"})
foo({"key1": "value1", "key2": ""})
@@ -41,3 +59,6 @@ func test():
bar({1: "1"})
bar({2: "2"})
bar({3: "3"})
+ baz({"key1": "value1"})
+ baz({"key2": "value2"})
+ baz({"key3": {"key1": "value1", "key2": "value2"}})
diff --git a/modules/gdscript/tests/scripts/parser/features/match_dictionary.out b/modules/gdscript/tests/scripts/parser/features/match_dictionary.out
index 4dee886927..f9adcbd331 100644
--- a/modules/gdscript/tests/scripts/parser/features/match_dictionary.out
+++ b/modules/gdscript/tests/scripts/parser/features/match_dictionary.out
@@ -13,3 +13,6 @@ wildcard
1
2
wildcard
+multiline {"key1": "value1"}
+multiline {"key2": "value2",}
+multiline {"key3": {"key1", ..,},}
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 2b3a00a224..f8c35ab6d1 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -3059,7 +3059,17 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) {
array[Mesh::ARRAY_TANGENT] = tangents;
}
- if (p_state->force_disable_compression || !a.has("POSITION") || !a.has("NORMAL") || p.has("targets") || (a.has("JOINTS_0") || a.has("JOINTS_1"))) {
+ // Disable compression if all z equals 0 (the mesh is 2D).
+ const Vector<Vector3> &vertices = array[Mesh::ARRAY_VERTEX];
+ bool is_mesh_2d = true;
+ for (int k = 0; k < vertices.size(); k++) {
+ if (!Math::is_zero_approx(vertices[k].z)) {
+ is_mesh_2d = false;
+ break;
+ }
+ }
+
+ if (p_state->force_disable_compression || is_mesh_2d || !a.has("POSITION") || !a.has("NORMAL") || p.has("targets") || (a.has("JOINTS_0") || a.has("JOINTS_1"))) {
flags &= ~RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES;
}
diff --git a/modules/navigation/2d/godot_navigation_server_2d.cpp b/modules/navigation/2d/godot_navigation_server_2d.cpp
index 28bcd16310..5eefbe4228 100644
--- a/modules/navigation/2d/godot_navigation_server_2d.cpp
+++ b/modules/navigation/2d/godot_navigation_server_2d.cpp
@@ -229,6 +229,10 @@ bool GodotNavigationServer2D::is_baking_navigation_polygon(Ref<NavigationPolygon
#endif
}
+Vector<Vector2> GodotNavigationServer2D::simplify_path(const Vector<Vector2> &p_path, real_t p_epsilon) {
+ return vector_v3_to_v2(NavigationServer3D::get_singleton()->simplify_path(vector_v2_to_v3(p_path), p_epsilon));
+}
+
GodotNavigationServer2D::GodotNavigationServer2D() {}
GodotNavigationServer2D::~GodotNavigationServer2D() {}
diff --git a/modules/navigation/2d/godot_navigation_server_2d.h b/modules/navigation/2d/godot_navigation_server_2d.h
index a148887a65..ba375afd33 100644
--- a/modules/navigation/2d/godot_navigation_server_2d.h
+++ b/modules/navigation/2d/godot_navigation_server_2d.h
@@ -252,6 +252,8 @@ public:
virtual void bake_from_source_geometry_data(const Ref<NavigationPolygon> &p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData2D> &p_source_geometry_data, const Callable &p_callback = Callable()) override;
virtual void bake_from_source_geometry_data_async(const Ref<NavigationPolygon> &p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData2D> &p_source_geometry_data, const Callable &p_callback = Callable()) override;
virtual bool is_baking_navigation_polygon(Ref<NavigationPolygon> p_navigation_polygon) const override;
+
+ virtual Vector<Vector2> simplify_path(const Vector<Vector2> &p_path, real_t p_epsilon) override;
};
#endif // GODOT_NAVIGATION_SERVER_2D_H
diff --git a/modules/navigation/2d/nav_mesh_generator_2d.cpp b/modules/navigation/2d/nav_mesh_generator_2d.cpp
index 0738a102eb..d8f1170f6a 100644
--- a/modules/navigation/2d/nav_mesh_generator_2d.cpp
+++ b/modules/navigation/2d/nav_mesh_generator_2d.cpp
@@ -72,7 +72,7 @@ NavMeshGenerator2D::NavMeshGenerator2D() {
// Using threads might cause problems on certain exports or with the Editor on certain devices.
// This is the main switch to turn threaded navmesh baking off should the need arise.
- use_threads = baking_use_multiple_threads && !Engine::get_singleton()->is_editor_hint();
+ use_threads = baking_use_multiple_threads;
}
NavMeshGenerator2D::~NavMeshGenerator2D() {
diff --git a/modules/navigation/3d/godot_navigation_server_3d.cpp b/modules/navigation/3d/godot_navigation_server_3d.cpp
index 15de33f58f..301b4aa8f3 100644
--- a/modules/navigation/3d/godot_navigation_server_3d.cpp
+++ b/modules/navigation/3d/godot_navigation_server_3d.cpp
@@ -1381,11 +1381,140 @@ PathQueryResult GodotNavigationServer3D::_query_path(const PathQueryParameters &
// add path postprocessing
+ if (r_query_result.path.size() > 2 && p_parameters.simplify_path) {
+ const LocalVector<uint32_t> &simplified_path_indices = get_simplified_path_indices(r_query_result.path, p_parameters.simplify_epsilon);
+
+ uint32_t indices_count = simplified_path_indices.size();
+
+ {
+ Vector3 *w = r_query_result.path.ptrw();
+ const Vector3 *r = r_query_result.path.ptr();
+ for (uint32_t i = 0; i < indices_count; i++) {
+ w[i] = r[simplified_path_indices[i]];
+ }
+ r_query_result.path.resize(indices_count);
+ }
+
+ if (p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_TYPES)) {
+ int32_t *w = r_query_result.path_types.ptrw();
+ const int32_t *r = r_query_result.path_types.ptr();
+ for (uint32_t i = 0; i < indices_count; i++) {
+ w[i] = r[simplified_path_indices[i]];
+ }
+ r_query_result.path_types.resize(indices_count);
+ }
+
+ if (p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_RIDS)) {
+ TypedArray<RID> simplified_path_rids;
+ simplified_path_rids.resize(indices_count);
+ for (uint32_t i = 0; i < indices_count; i++) {
+ simplified_path_rids[i] = r_query_result.path_rids[i];
+ }
+ r_query_result.path_rids = simplified_path_rids;
+ }
+
+ if (p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_OWNERS)) {
+ int64_t *w = r_query_result.path_owner_ids.ptrw();
+ const int64_t *r = r_query_result.path_owner_ids.ptr();
+ for (uint32_t i = 0; i < indices_count; i++) {
+ w[i] = r[simplified_path_indices[i]];
+ }
+ r_query_result.path_owner_ids.resize(indices_count);
+ }
+ }
+
// add path stats
return r_query_result;
}
+Vector<Vector3> GodotNavigationServer3D::simplify_path(const Vector<Vector3> &p_path, real_t p_epsilon) {
+ if (p_path.size() <= 2) {
+ return p_path;
+ }
+
+ p_epsilon = MAX(0.0, p_epsilon);
+
+ LocalVector<uint32_t> simplified_path_indices = get_simplified_path_indices(p_path, p_epsilon);
+
+ uint32_t indices_count = simplified_path_indices.size();
+
+ Vector<Vector3> simplified_path;
+ simplified_path.resize(indices_count);
+
+ Vector3 *w = simplified_path.ptrw();
+ const Vector3 *r = p_path.ptr();
+ for (uint32_t i = 0; i < indices_count; i++) {
+ w[i] = r[simplified_path_indices[i]];
+ }
+
+ return simplified_path;
+}
+
+LocalVector<uint32_t> GodotNavigationServer3D::get_simplified_path_indices(const Vector<Vector3> &p_path, real_t p_epsilon) {
+ p_epsilon = MAX(0.0, p_epsilon);
+ real_t squared_epsilon = p_epsilon * p_epsilon;
+
+ LocalVector<bool> valid_points;
+ valid_points.resize(p_path.size());
+ for (uint32_t i = 0; i < valid_points.size(); i++) {
+ valid_points[i] = false;
+ }
+
+ simplify_path_segment(0, p_path.size() - 1, p_path, squared_epsilon, valid_points);
+
+ int valid_point_index = 0;
+
+ for (bool valid : valid_points) {
+ if (valid) {
+ valid_point_index += 1;
+ }
+ }
+
+ LocalVector<uint32_t> simplified_path_indices;
+ simplified_path_indices.resize(valid_point_index);
+ valid_point_index = 0;
+
+ for (uint32_t i = 0; i < valid_points.size(); i++) {
+ if (valid_points[i]) {
+ simplified_path_indices[valid_point_index] = i;
+ valid_point_index += 1;
+ }
+ }
+
+ return simplified_path_indices;
+}
+
+void GodotNavigationServer3D::simplify_path_segment(int p_start_inx, int p_end_inx, const Vector<Vector3> &p_points, real_t p_epsilon, LocalVector<bool> &r_valid_points) {
+ r_valid_points[p_start_inx] = true;
+ r_valid_points[p_end_inx] = true;
+
+ const Vector3 &start_point = p_points[p_start_inx];
+ const Vector3 &end_point = p_points[p_end_inx];
+
+ Vector3 path_segment[2] = { start_point, end_point };
+
+ real_t point_max_distance = 0.0;
+ int point_max_index = 0;
+
+ 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);
+ real_t distance_squared = closest_point.distance_squared_to(checked_point);
+
+ if (distance_squared > point_max_distance) {
+ point_max_index = i;
+ point_max_distance = distance_squared;
+ }
+ }
+
+ if (point_max_distance > p_epsilon) {
+ simplify_path_segment(p_start_inx, point_max_index, p_points, p_epsilon, r_valid_points);
+ simplify_path_segment(point_max_index, p_end_inx, p_points, p_epsilon, r_valid_points);
+ }
+}
+
int GodotNavigationServer3D::get_process_info(ProcessInfo p_info) const {
switch (p_info) {
case INFO_ACTIVE_MAPS: {
diff --git a/modules/navigation/3d/godot_navigation_server_3d.h b/modules/navigation/3d/godot_navigation_server_3d.h
index f7d991d47a..89839ff459 100644
--- a/modules/navigation/3d/godot_navigation_server_3d.h
+++ b/modules/navigation/3d/godot_navigation_server_3d.h
@@ -264,6 +264,13 @@ public:
virtual void bake_from_source_geometry_data_async(const Ref<NavigationMesh> &p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData3D> &p_source_geometry_data, const Callable &p_callback = Callable()) override;
virtual bool is_baking_navigation_mesh(Ref<NavigationMesh> p_navigation_mesh) const override;
+ virtual Vector<Vector3> simplify_path(const Vector<Vector3> &p_path, real_t p_epsilon) override;
+
+private:
+ static void simplify_path_segment(int p_start_inx, int p_end_inx, const Vector<Vector3> &p_points, real_t p_epsilon, LocalVector<bool> &r_valid_points);
+ static LocalVector<uint32_t> get_simplified_path_indices(const Vector<Vector3> &p_path, real_t p_epsilon);
+
+public:
COMMAND_1(free, RID, p_object);
virtual void set_active(bool p_active) override;
diff --git a/modules/navigation/3d/nav_mesh_generator_3d.cpp b/modules/navigation/3d/nav_mesh_generator_3d.cpp
index 8b43eba080..11f4359146 100644
--- a/modules/navigation/3d/nav_mesh_generator_3d.cpp
+++ b/modules/navigation/3d/nav_mesh_generator_3d.cpp
@@ -85,7 +85,7 @@ NavMeshGenerator3D::NavMeshGenerator3D() {
// Using threads might cause problems on certain exports or with the Editor on certain devices.
// This is the main switch to turn threaded navmesh baking off should the need arise.
- use_threads = baking_use_multiple_threads && !Engine::get_singleton()->is_editor_hint();
+ use_threads = baking_use_multiple_threads;
}
NavMeshGenerator3D::~NavMeshGenerator3D() {
diff --git a/modules/navigation/editor/navigation_mesh_editor_plugin.cpp b/modules/navigation/editor/navigation_mesh_editor_plugin.cpp
index 18d66c7b69..352203f5aa 100644
--- a/modules/navigation/editor/navigation_mesh_editor_plugin.cpp
+++ b/modules/navigation/editor/navigation_mesh_editor_plugin.cpp
@@ -99,7 +99,7 @@ void NavigationMeshEditor::_bake_pressed() {
}
}
- node->bake_navigation_mesh(false);
+ node->bake_navigation_mesh(true);
node->update_gizmos();
}
diff --git a/platform/android/doc_classes/EditorExportPlatformAndroid.xml b/platform/android/doc_classes/EditorExportPlatformAndroid.xml
index 341d14a3b1..020e432155 100644
--- a/platform/android/doc_classes/EditorExportPlatformAndroid.xml
+++ b/platform/android/doc_classes/EditorExportPlatformAndroid.xml
@@ -15,11 +15,11 @@
Array of random bytes that the licensing Policy uses to create an [url=https://developer.android.com/google/play/licensing/adding-licensing#impl-Obfuscator]Obfuscator[/url].
</member>
<member name="apk_expansion/enable" type="bool" setter="" getter="">
- If [code]true[/code], project resources are stored in the separate APK expansion file, instead APK.
- [b]Note:[/b] APK expansion should be enabled to use PCK encryption.
+ If [code]true[/code], project resources are stored in the separate APK expansion file, instead of the APK.
+ [b]Note:[/b] APK expansion should be enabled to use PCK encryption. See [url=https://developer.android.com/google/play/expansion-files]APK Expansion Files[/url]
</member>
<member name="apk_expansion/public_key" type="String" setter="" getter="">
- Base64 encoded RSA public key for your publisher account, available from the profile page on the "Play Console".
+ Base64 encoded RSA public key for your publisher account, available from the profile page on the "Google Play Console".
</member>
<member name="architectures/arm64-v8a" type="bool" setter="" getter="">
If [code]true[/code], [code]arm64[/code] binaries are included into exported project.
@@ -34,7 +34,7 @@
If [code]true[/code], [code]x86_64[/code] binaries are included into exported project.
</member>
<member name="command_line/extra_args" type="String" setter="" getter="">
- A list of additional command line arguments, exported project will receive when started.
+ A list of additional command line arguments, separated by space, which the exported project will receive when started.
</member>
<member name="custom_template/debug" type="String" setter="" getter="">
Path to an APK file to use as a custom export template for debug exports. If left empty, default template is used.
@@ -52,16 +52,16 @@
[b]Note:[/b] Although your binary may be smaller, your application may load slower because the native libraries are not loaded directly from the binary at runtime.
</member>
<member name="gradle_build/export_format" type="int" setter="" getter="">
- Export format for Gradle build.
+ Application export format (*.apk or *.aab).
</member>
<member name="gradle_build/gradle_build_directory" type="String" setter="" getter="">
Path to the Gradle build directory. If left empty, then [code]res://android[/code] will be used.
</member>
<member name="gradle_build/min_sdk" type="String" setter="" getter="">
- Minimal Android SDK version for Gradle build.
+ Minimum Android API level required for the application to run (used during Gradle build). See [url=https://developer.android.com/guide/topics/manifest/uses-sdk-element#uses]android:minSdkVersion[/url].
</member>
<member name="gradle_build/target_sdk" type="String" setter="" getter="">
- Target Android SDK version for Gradle build.
+ The Android API level on which the application is designed to run (used during Gradle build). See [url=https://developer.android.com/guide/topics/manifest/uses-sdk-element#uses]android:targetSdkVersion[/url].
</member>
<member name="gradle_build/use_gradle_build" type="bool" setter="" getter="">
If [code]true[/code], Gradle build is used instead of pre-built APK.
@@ -97,25 +97,25 @@
Can be overridden with the environment variable [code]GODOT_ANDROID_KEYSTORE_RELEASE_USER[/code].
</member>
<member name="launcher_icons/adaptive_background_432x432" type="String" setter="" getter="">
- Background layer of the application adaptive icon file.
+ Background layer of the application adaptive icon file. See [url=https://developer.android.com/develop/ui/views/launch/icon_design_adaptive#design-adaptive-icons]Design adaptive icons[/url].
</member>
<member name="launcher_icons/adaptive_foreground_432x432" type="String" setter="" getter="">
- Foreground layer of the application adaptive icon file.
+ Foreground layer of the application adaptive icon file. See [url=https://developer.android.com/develop/ui/views/launch/icon_design_adaptive#design-adaptive-icons]Design adaptive icons[/url].
</member>
<member name="launcher_icons/main_192x192" type="String" setter="" getter="">
Application icon file. If left empty, it will fallback to [member ProjectSettings.application/config/icon].
</member>
<member name="package/app_category" type="int" setter="" getter="">
- Application category for the Play Store.
+ Application category for the Google Play Store. Only define this if your application fits one of the categories well. See [url=https://developer.android.com/guide/topics/manifest/application-element#appCategory]android:appCategory[/url].
</member>
<member name="package/exclude_from_recents" type="bool" setter="" getter="">
- If [code]true[/code], task initiated by main activity will be excluded from the list of recently used applications.
+ If [code]true[/code], task initiated by main activity will be excluded from the list of recently used applications. See [url=https://developer.android.com/guide/topics/manifest/activity-element#exclude]android:excludeFromRecents[/url].
</member>
<member name="package/name" type="String" setter="" getter="">
Name of the application.
</member>
<member name="package/retain_data_on_uninstall" type="bool" setter="" getter="">
- If [code]true[/code], when the user uninstalls an app, a prompt to keep the app's data will be shown.
+ If [code]true[/code], when the user uninstalls an app, a prompt to keep the app's data will be shown. See [url=https://developer.android.com/guide/topics/manifest/application-element#fragileuserdata]android:hasFragileUserData[/url].
</member>
<member name="package/show_as_launcher_app" type="bool" setter="" getter="">
If [code]true[/code], the user will be able to set this app as the system launcher in Android preferences.
@@ -378,10 +378,10 @@
Allows applications to perform I/O operations over NFC. See [url=https://developer.android.com/reference/android/Manifest.permission#NFC]NFC[/url].
</member>
<member name="permissions/persistent_activity" type="bool" setter="" getter="" deprecated="Deprecated in API level 15.">
- Allow an application to make its activities persistent.
+ Allows an application to make its activities persistent.
</member>
- <member name="permissions/post_notifications" type="bool" setter="" getter="" deprecated="">
- Allow an application to post notifications. Added in API level 33. See [url=https://developer.android.com/develop/ui/views/notifications/notification-permission]Notification runtime permission[/url].
+ <member name="permissions/post_notifications" type="bool" setter="" getter="">
+ Allows an application to post notifications. Added in API level 33. See [url=https://developer.android.com/develop/ui/views/notifications/notification-permission]Notification runtime permission[/url].
</member>
<member name="permissions/process_outgoing_calls" type="bool" setter="" getter="" deprecated="Deprecated in API level 29.">
Allows an application to see the number being dialed during an outgoing call with the option to redirect the call to a different number or abort the call altogether. See [url=https://developer.android.com/reference/android/Manifest.permission#PROCESS_OUTGOING_CALLS]PROCESS_OUTGOING_CALLS[/url].
diff --git a/platform/ios/os_ios.mm b/platform/ios/os_ios.mm
index c989dc6221..bcf21bc802 100644
--- a/platform/ios/os_ios.mm
+++ b/platform/ios/os_ios.mm
@@ -149,10 +149,6 @@ void OS_IOS::deinitialize_modules() {
void OS_IOS::set_main_loop(MainLoop *p_main_loop) {
main_loop = p_main_loop;
-
- if (main_loop) {
- main_loop->initialize();
- }
}
MainLoop *OS_IOS::get_main_loop() const {
@@ -181,7 +177,9 @@ bool OS_IOS::iterate() {
}
void OS_IOS::start() {
- Main::start();
+ if (Main::start() == EXIT_SUCCESS) {
+ main_loop->initialize();
+ }
if (joypad_ios) {
joypad_ios->start_processing();
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 196beb423f..9aa32a7b2d 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -202,9 +202,7 @@ def get_opts():
BoolVariable("use_asan", "Use address sanitizer (ASAN)", False),
BoolVariable("debug_crt", "Compile with MSVC's debug CRT (/MDd)", False),
BoolVariable("incremental_link", "Use MSVC incremental linking. May increase or decrease build times.", False),
- BoolVariable(
- "silence_msvc", "Silence MSVC's stdout to decrease output log bloat. May hide error messages.", False
- ),
+ BoolVariable("silence_msvc", "Silence MSVC's cl/link stdout bloat, redirecting any errors to stderr.", True),
("angle_libs", "Path to the ANGLE static libraries", ""),
# Direct3D 12 support.
(
@@ -398,16 +396,32 @@ def configure_msvc(env: "SConsEnvironment", vcvars_msvc_config):
env["MAXLINELENGTH"] = 8192 # Windows Vista and beyond, so always applicable.
if env["silence_msvc"]:
- env.Prepend(CCFLAGS=[">", "NUL"])
- env.Prepend(LINKFLAGS=[">", "NUL"])
+ from tempfile import mkstemp
+
+ old_spawn = env["SPAWN"]
+
+ def spawn_capture(sh, escape, cmd, args, env):
+ # We only care about cl/link, process everything else as normal.
+ if args[0] not in ["cl", "link"]:
+ return old_spawn(sh, escape, cmd, args, env)
- # "> NUL" fails if using a tempfile, circumvent by removing the argument altogether.
- old_esc_func = env["TEMPFILEARGESCFUNC"]
+ tmp_stdout, tmp_stdout_name = mkstemp()
+ os.close(tmp_stdout)
+ args.append(f">{tmp_stdout_name}")
+ ret = old_spawn(sh, escape, cmd, args, env)
+
+ try:
+ with open(tmp_stdout_name, "rt", encoding=sys.stdout.encoding) as tmp_stdout:
+ # First line is always bloat, subsequent lines are always errors. This filter sends
+ # either just the errors to stderr, or an empty string to effectively do nothing.
+ sys.stderr.write("".join(tmp_stdout.readlines()[1:]))
+ os.remove(tmp_stdout_name)
+ except OSError:
+ pass
- def trim_nul(arg):
- return "" if arg in [">", "NUL"] else old_esc_func(arg)
+ return ret
- env["TEMPFILEARGESCFUNC"] = trim_nul
+ env["SPAWN"] = spawn_capture
if env["debug_crt"]:
# Always use dynamic runtime, static debug CRT breaks thread_local.
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index fee774fe2e..5d14358120 100644
--- a/scene/2d/navigation_agent_2d.cpp
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -89,6 +89,12 @@ void NavigationAgent2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_target_position", "position"), &NavigationAgent2D::set_target_position);
ClassDB::bind_method(D_METHOD("get_target_position"), &NavigationAgent2D::get_target_position);
+ ClassDB::bind_method(D_METHOD("set_simplify_path", "enabled"), &NavigationAgent2D::set_simplify_path);
+ ClassDB::bind_method(D_METHOD("get_simplify_path"), &NavigationAgent2D::get_simplify_path);
+
+ ClassDB::bind_method(D_METHOD("set_simplify_epsilon", "epsilon"), &NavigationAgent2D::set_simplify_epsilon);
+ ClassDB::bind_method(D_METHOD("get_simplify_epsilon"), &NavigationAgent2D::get_simplify_epsilon);
+
ClassDB::bind_method(D_METHOD("get_next_path_position"), &NavigationAgent2D::get_next_path_position);
ClassDB::bind_method(D_METHOD("set_velocity_forced", "velocity"), &NavigationAgent2D::set_velocity_forced);
@@ -129,6 +135,8 @@ void NavigationAgent2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "pathfinding_algorithm", PROPERTY_HINT_ENUM, "AStar"), "set_pathfinding_algorithm", "get_pathfinding_algorithm");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_postprocessing", PROPERTY_HINT_ENUM, "Corridorfunnel,Edgecentered"), "set_path_postprocessing", "get_path_postprocessing");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_path_metadata_flags", "get_path_metadata_flags");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "simplify_path"), "set_simplify_path", "get_simplify_path");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "simplify_epsilon", PROPERTY_HINT_RANGE, "0.0,10.0,0.001,or_greater,suffix:px"), "set_simplify_epsilon", "get_simplify_epsilon");
ADD_GROUP("Avoidance", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
@@ -427,6 +435,24 @@ void NavigationAgent2D::set_path_postprocessing(const NavigationPathQueryParamet
navigation_query->set_path_postprocessing(path_postprocessing);
}
+void NavigationAgent2D::set_simplify_path(bool p_enabled) {
+ simplify_path = p_enabled;
+ navigation_query->set_simplify_path(simplify_path);
+}
+
+bool NavigationAgent2D::get_simplify_path() const {
+ return simplify_path;
+}
+
+void NavigationAgent2D::set_simplify_epsilon(real_t p_epsilon) {
+ simplify_epsilon = MAX(0.0, p_epsilon);
+ navigation_query->set_simplify_epsilon(simplify_epsilon);
+}
+
+real_t NavigationAgent2D::get_simplify_epsilon() const {
+ return simplify_epsilon;
+}
+
void NavigationAgent2D::set_path_metadata_flags(BitField<NavigationPathQueryParameters2D::PathMetadataFlags> p_path_metadata_flags) {
if (path_metadata_flags == p_path_metadata_flags) {
return;
diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h
index 0e46086a81..0acfc82162 100644
--- a/scene/2d/navigation_agent_2d.h
+++ b/scene/2d/navigation_agent_2d.h
@@ -63,6 +63,8 @@ class NavigationAgent2D : public Node {
real_t time_horizon_obstacles = 0.0;
real_t max_speed = 100.0;
real_t path_max_distance = 100.0;
+ bool simplify_path = false;
+ real_t simplify_epsilon = 0.0;
Vector2 target_position;
@@ -179,6 +181,12 @@ public:
void set_target_position(Vector2 p_position);
Vector2 get_target_position() const;
+ void set_simplify_path(bool p_enabled);
+ bool get_simplify_path() const;
+
+ void set_simplify_epsilon(real_t p_epsilon);
+ real_t get_simplify_epsilon() const;
+
Vector2 get_next_path_position();
Ref<NavigationPathQueryResult2D> get_current_navigation_result() const { return navigation_result; }
diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp
index eb52d4540e..43c41c1b5b 100644
--- a/scene/3d/navigation_agent_3d.cpp
+++ b/scene/3d/navigation_agent_3d.cpp
@@ -99,6 +99,12 @@ void NavigationAgent3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_target_position", "position"), &NavigationAgent3D::set_target_position);
ClassDB::bind_method(D_METHOD("get_target_position"), &NavigationAgent3D::get_target_position);
+ ClassDB::bind_method(D_METHOD("set_simplify_path", "enabled"), &NavigationAgent3D::set_simplify_path);
+ ClassDB::bind_method(D_METHOD("get_simplify_path"), &NavigationAgent3D::get_simplify_path);
+
+ ClassDB::bind_method(D_METHOD("set_simplify_epsilon", "epsilon"), &NavigationAgent3D::set_simplify_epsilon);
+ ClassDB::bind_method(D_METHOD("get_simplify_epsilon"), &NavigationAgent3D::get_simplify_epsilon);
+
ClassDB::bind_method(D_METHOD("get_next_path_position"), &NavigationAgent3D::get_next_path_position);
ClassDB::bind_method(D_METHOD("set_velocity_forced", "velocity"), &NavigationAgent3D::set_velocity_forced);
@@ -140,6 +146,8 @@ void NavigationAgent3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "pathfinding_algorithm", PROPERTY_HINT_ENUM, "AStar"), "set_pathfinding_algorithm", "get_pathfinding_algorithm");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_postprocessing", PROPERTY_HINT_ENUM, "Corridorfunnel,Edgecentered"), "set_path_postprocessing", "get_path_postprocessing");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_path_metadata_flags", "get_path_metadata_flags");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "simplify_path"), "set_simplify_path", "get_simplify_path");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "simplify_epsilon", PROPERTY_HINT_RANGE, "0.0,10.0,0.001,or_greater,suffix:m"), "set_simplify_epsilon", "get_simplify_epsilon");
ADD_GROUP("Avoidance", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
@@ -464,6 +472,24 @@ void NavigationAgent3D::set_path_postprocessing(const NavigationPathQueryParamet
navigation_query->set_path_postprocessing(path_postprocessing);
}
+void NavigationAgent3D::set_simplify_path(bool p_enabled) {
+ simplify_path = p_enabled;
+ navigation_query->set_simplify_path(simplify_path);
+}
+
+bool NavigationAgent3D::get_simplify_path() const {
+ return simplify_path;
+}
+
+void NavigationAgent3D::set_simplify_epsilon(real_t p_epsilon) {
+ simplify_epsilon = MAX(0.0, p_epsilon);
+ navigation_query->set_simplify_epsilon(simplify_epsilon);
+}
+
+real_t NavigationAgent3D::get_simplify_epsilon() const {
+ return simplify_epsilon;
+}
+
void NavigationAgent3D::set_path_metadata_flags(BitField<NavigationPathQueryParameters3D::PathMetadataFlags> p_path_metadata_flags) {
if (path_metadata_flags == p_path_metadata_flags) {
return;
diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h
index 4eaed83149..ade6afd445 100644
--- a/scene/3d/navigation_agent_3d.h
+++ b/scene/3d/navigation_agent_3d.h
@@ -66,6 +66,8 @@ class NavigationAgent3D : public Node {
real_t time_horizon_obstacles = 0.0;
real_t max_speed = 10.0;
real_t path_max_distance = 5.0;
+ bool simplify_path = false;
+ real_t simplify_epsilon = 0.0;
Vector3 target_position;
@@ -200,6 +202,12 @@ public:
void set_target_position(Vector3 p_position);
Vector3 get_target_position() const;
+ void set_simplify_path(bool p_enabled);
+ bool get_simplify_path() const;
+
+ void set_simplify_epsilon(real_t p_epsilon);
+ real_t get_simplify_epsilon() const;
+
Vector3 get_next_path_position();
Ref<NavigationPathQueryResult3D> get_current_navigation_result() const { return navigation_result; }
diff --git a/servers/navigation/navigation_path_query_parameters_2d.cpp b/servers/navigation/navigation_path_query_parameters_2d.cpp
index 78da87d677..6c1f88e349 100644
--- a/servers/navigation/navigation_path_query_parameters_2d.cpp
+++ b/servers/navigation/navigation_path_query_parameters_2d.cpp
@@ -119,6 +119,22 @@ BitField<NavigationPathQueryParameters2D::PathMetadataFlags> NavigationPathQuery
return (int64_t)parameters.metadata_flags;
}
+void NavigationPathQueryParameters2D::set_simplify_path(bool p_enabled) {
+ parameters.simplify_path = p_enabled;
+}
+
+bool NavigationPathQueryParameters2D::get_simplify_path() const {
+ return parameters.simplify_path;
+}
+
+void NavigationPathQueryParameters2D::set_simplify_epsilon(real_t p_epsilon) {
+ parameters.simplify_epsilon = MAX(0.0, p_epsilon);
+}
+
+real_t NavigationPathQueryParameters2D::get_simplify_epsilon() const {
+ return parameters.simplify_epsilon;
+}
+
void NavigationPathQueryParameters2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pathfinding_algorithm", "pathfinding_algorithm"), &NavigationPathQueryParameters2D::set_pathfinding_algorithm);
ClassDB::bind_method(D_METHOD("get_pathfinding_algorithm"), &NavigationPathQueryParameters2D::get_pathfinding_algorithm);
@@ -141,6 +157,12 @@ void NavigationPathQueryParameters2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_metadata_flags", "flags"), &NavigationPathQueryParameters2D::set_metadata_flags);
ClassDB::bind_method(D_METHOD("get_metadata_flags"), &NavigationPathQueryParameters2D::get_metadata_flags);
+ ClassDB::bind_method(D_METHOD("set_simplify_path", "enabled"), &NavigationPathQueryParameters2D::set_simplify_path);
+ ClassDB::bind_method(D_METHOD("get_simplify_path"), &NavigationPathQueryParameters2D::get_simplify_path);
+
+ ClassDB::bind_method(D_METHOD("set_simplify_epsilon", "epsilon"), &NavigationPathQueryParameters2D::set_simplify_epsilon);
+ ClassDB::bind_method(D_METHOD("get_simplify_epsilon"), &NavigationPathQueryParameters2D::get_simplify_epsilon);
+
ADD_PROPERTY(PropertyInfo(Variant::RID, "map"), "set_map", "get_map");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "start_position"), "set_start_position", "get_start_position");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "target_position"), "set_target_position", "get_target_position");
@@ -148,6 +170,8 @@ void NavigationPathQueryParameters2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "pathfinding_algorithm", PROPERTY_HINT_ENUM, "AStar"), "set_pathfinding_algorithm", "get_pathfinding_algorithm");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_postprocessing", PROPERTY_HINT_ENUM, "Corridorfunnel,Edgecentered"), "set_path_postprocessing", "get_path_postprocessing");
ADD_PROPERTY(PropertyInfo(Variant::INT, "metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_metadata_flags", "get_metadata_flags");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "simplify_path"), "set_simplify_path", "get_simplify_path");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "simplify_epsilon"), "set_simplify_epsilon", "get_simplify_epsilon");
BIND_ENUM_CONSTANT(PATHFINDING_ALGORITHM_ASTAR);
diff --git a/servers/navigation/navigation_path_query_parameters_2d.h b/servers/navigation/navigation_path_query_parameters_2d.h
index 48bb93aa7c..a1d5f2d109 100644
--- a/servers/navigation/navigation_path_query_parameters_2d.h
+++ b/servers/navigation/navigation_path_query_parameters_2d.h
@@ -82,6 +82,12 @@ public:
void set_metadata_flags(BitField<NavigationPathQueryParameters2D::PathMetadataFlags> p_flags);
BitField<NavigationPathQueryParameters2D::PathMetadataFlags> get_metadata_flags() const;
+
+ void set_simplify_path(bool p_enabled);
+ bool get_simplify_path() const;
+
+ void set_simplify_epsilon(real_t p_epsilon);
+ real_t get_simplify_epsilon() const;
};
VARIANT_ENUM_CAST(NavigationPathQueryParameters2D::PathfindingAlgorithm);
diff --git a/servers/navigation/navigation_path_query_parameters_3d.cpp b/servers/navigation/navigation_path_query_parameters_3d.cpp
index 52333edbc1..b0a5b0ad82 100644
--- a/servers/navigation/navigation_path_query_parameters_3d.cpp
+++ b/servers/navigation/navigation_path_query_parameters_3d.cpp
@@ -119,6 +119,22 @@ BitField<NavigationPathQueryParameters3D::PathMetadataFlags> NavigationPathQuery
return (int64_t)parameters.metadata_flags;
}
+void NavigationPathQueryParameters3D::set_simplify_path(bool p_enabled) {
+ parameters.simplify_path = p_enabled;
+}
+
+bool NavigationPathQueryParameters3D::get_simplify_path() const {
+ return parameters.simplify_path;
+}
+
+void NavigationPathQueryParameters3D::set_simplify_epsilon(real_t p_epsilon) {
+ parameters.simplify_epsilon = MAX(0.0, p_epsilon);
+}
+
+real_t NavigationPathQueryParameters3D::get_simplify_epsilon() const {
+ return parameters.simplify_epsilon;
+}
+
void NavigationPathQueryParameters3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pathfinding_algorithm", "pathfinding_algorithm"), &NavigationPathQueryParameters3D::set_pathfinding_algorithm);
ClassDB::bind_method(D_METHOD("get_pathfinding_algorithm"), &NavigationPathQueryParameters3D::get_pathfinding_algorithm);
@@ -141,6 +157,12 @@ void NavigationPathQueryParameters3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_metadata_flags", "flags"), &NavigationPathQueryParameters3D::set_metadata_flags);
ClassDB::bind_method(D_METHOD("get_metadata_flags"), &NavigationPathQueryParameters3D::get_metadata_flags);
+ ClassDB::bind_method(D_METHOD("set_simplify_path", "enabled"), &NavigationPathQueryParameters3D::set_simplify_path);
+ ClassDB::bind_method(D_METHOD("get_simplify_path"), &NavigationPathQueryParameters3D::get_simplify_path);
+
+ ClassDB::bind_method(D_METHOD("set_simplify_epsilon", "epsilon"), &NavigationPathQueryParameters3D::set_simplify_epsilon);
+ ClassDB::bind_method(D_METHOD("get_simplify_epsilon"), &NavigationPathQueryParameters3D::get_simplify_epsilon);
+
ADD_PROPERTY(PropertyInfo(Variant::RID, "map"), "set_map", "get_map");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "start_position"), "set_start_position", "get_start_position");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_position"), "set_target_position", "get_target_position");
@@ -148,6 +170,8 @@ void NavigationPathQueryParameters3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "pathfinding_algorithm", PROPERTY_HINT_ENUM, "AStar"), "set_pathfinding_algorithm", "get_pathfinding_algorithm");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_postprocessing", PROPERTY_HINT_ENUM, "Corridorfunnel,Edgecentered"), "set_path_postprocessing", "get_path_postprocessing");
ADD_PROPERTY(PropertyInfo(Variant::INT, "metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_metadata_flags", "get_metadata_flags");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "simplify_path"), "set_simplify_path", "get_simplify_path");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "simplify_epsilon"), "set_simplify_epsilon", "get_simplify_epsilon");
BIND_ENUM_CONSTANT(PATHFINDING_ALGORITHM_ASTAR);
diff --git a/servers/navigation/navigation_path_query_parameters_3d.h b/servers/navigation/navigation_path_query_parameters_3d.h
index b12c2d49d5..2eb85db787 100644
--- a/servers/navigation/navigation_path_query_parameters_3d.h
+++ b/servers/navigation/navigation_path_query_parameters_3d.h
@@ -82,6 +82,12 @@ public:
void set_metadata_flags(BitField<NavigationPathQueryParameters3D::PathMetadataFlags> p_flags);
BitField<NavigationPathQueryParameters3D::PathMetadataFlags> get_metadata_flags() const;
+
+ void set_simplify_path(bool p_enabled);
+ bool get_simplify_path() const;
+
+ void set_simplify_epsilon(real_t p_epsilon);
+ real_t get_simplify_epsilon() const;
};
VARIANT_ENUM_CAST(NavigationPathQueryParameters3D::PathfindingAlgorithm);
diff --git a/servers/navigation/navigation_utilities.h b/servers/navigation/navigation_utilities.h
index 04d0ab0d98..7ae22b1d3a 100644
--- a/servers/navigation/navigation_utilities.h
+++ b/servers/navigation/navigation_utilities.h
@@ -66,6 +66,8 @@ struct PathQueryParameters {
Vector3 target_position;
uint32_t navigation_layers = 1;
BitField<PathMetadataFlags> metadata_flags = PATH_INCLUDE_ALL;
+ bool simplify_path = false;
+ real_t simplify_epsilon = 0.0;
};
struct PathQueryResult {
diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp
index d87ac00e32..625ae8abde 100644
--- a/servers/navigation_server_2d.cpp
+++ b/servers/navigation_server_2d.cpp
@@ -165,6 +165,8 @@ void NavigationServer2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("bake_from_source_geometry_data_async", "navigation_polygon", "source_geometry_data", "callback"), &NavigationServer2D::bake_from_source_geometry_data_async, DEFVAL(Callable()));
ClassDB::bind_method(D_METHOD("is_baking_navigation_polygon", "navigation_polygon"), &NavigationServer2D::is_baking_navigation_polygon);
+ ClassDB::bind_method(D_METHOD("simplify_path", "path", "epsilon"), &NavigationServer2D::simplify_path);
+
ClassDB::bind_method(D_METHOD("free_rid", "rid"), &NavigationServer2D::free);
ClassDB::bind_method(D_METHOD("set_debug_enabled", "enabled"), &NavigationServer2D::set_debug_enabled);
diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h
index d7dc9d6526..876b09d549 100644
--- a/servers/navigation_server_2d.h
+++ b/servers/navigation_server_2d.h
@@ -306,6 +306,8 @@ public:
virtual void bake_from_source_geometry_data_async(const Ref<NavigationPolygon> &p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData2D> &p_source_geometry_data, const Callable &p_callback = Callable()) = 0;
virtual bool is_baking_navigation_polygon(Ref<NavigationPolygon> p_navigation_polygon) const = 0;
+ virtual Vector<Vector2> simplify_path(const Vector<Vector2> &p_path, real_t p_epsilon) = 0;
+
NavigationServer2D();
~NavigationServer2D() override;
diff --git a/servers/navigation_server_2d_dummy.h b/servers/navigation_server_2d_dummy.h
index 94c6dfd6a7..5d4cfbf91b 100644
--- a/servers/navigation_server_2d_dummy.h
+++ b/servers/navigation_server_2d_dummy.h
@@ -170,6 +170,8 @@ public:
void bake_from_source_geometry_data_async(const Ref<NavigationPolygon> &p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData2D> &p_source_geometry_data, const Callable &p_callback = Callable()) override {}
bool is_baking_navigation_polygon(Ref<NavigationPolygon> p_navigation_polygon) const override { return false; }
+ Vector<Vector2> simplify_path(const Vector<Vector2> &p_path, real_t p_epsilon) override { return Vector<Vector2>(); }
+
void set_debug_enabled(bool p_enabled) {}
bool get_debug_enabled() const { return false; }
};
diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp
index e460bcb9c6..7b54a24b59 100644
--- a/servers/navigation_server_3d.cpp
+++ b/servers/navigation_server_3d.cpp
@@ -186,6 +186,8 @@ void NavigationServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("bake_from_source_geometry_data_async", "navigation_mesh", "source_geometry_data", "callback"), &NavigationServer3D::bake_from_source_geometry_data_async, DEFVAL(Callable()));
ClassDB::bind_method(D_METHOD("is_baking_navigation_mesh", "navigation_mesh"), &NavigationServer3D::is_baking_navigation_mesh);
+ ClassDB::bind_method(D_METHOD("simplify_path", "path", "epsilon"), &NavigationServer3D::simplify_path);
+
ClassDB::bind_method(D_METHOD("free_rid", "rid"), &NavigationServer3D::free);
ClassDB::bind_method(D_METHOD("set_active", "active"), &NavigationServer3D::set_active);
diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h
index 975ffdee94..c23da78299 100644
--- a/servers/navigation_server_3d.h
+++ b/servers/navigation_server_3d.h
@@ -349,6 +349,8 @@ public:
virtual void bake_from_source_geometry_data_async(const Ref<NavigationMesh> &p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData3D> &p_source_geometry_data, const Callable &p_callback = Callable()) = 0;
virtual bool is_baking_navigation_mesh(Ref<NavigationMesh> p_navigation_mesh) const = 0;
+ virtual Vector<Vector3> simplify_path(const Vector<Vector3> &p_path, real_t p_epsilon) = 0;
+
NavigationServer3D();
~NavigationServer3D() override;
diff --git a/servers/navigation_server_3d_dummy.h b/servers/navigation_server_3d_dummy.h
index 9ba9b20d00..d98a0edb01 100644
--- a/servers/navigation_server_3d_dummy.h
+++ b/servers/navigation_server_3d_dummy.h
@@ -180,6 +180,8 @@ public:
void bake_from_source_geometry_data_async(const Ref<NavigationMesh> &p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData3D> &p_source_geometry_data, const Callable &p_callback = Callable()) override {}
bool is_baking_navigation_mesh(Ref<NavigationMesh> p_navigation_mesh) const override { return false; }
+ Vector<Vector3> simplify_path(const Vector<Vector3> &p_path, real_t p_epsilon) override { return Vector<Vector3>(); }
+
void free(RID p_object) override {}
void set_active(bool p_active) override {}
void process(real_t delta_time) override {}
diff --git a/thirdparty/README.md b/thirdparty/README.md
index dab3c9c04a..4c44a9b6f6 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -532,6 +532,8 @@ File extracted from upstream release tarball:
- The `LICENSE` file (edited to keep only the Apache 2.0 variant)
- Applied the patch `no-flexible-arrays.diff` to fix Windows build (see
upstream GH-9020)
+- Applied the patch `msvc-redeclaration-bug.diff` to fix a compilation error
+ with some MSVC versions
- Added 2 files `godot_core_mbedtls_platform.c` and `godot_core_mbedtls_config.h`
providing configuration for light bundling with core
- Added the file `godot_module_mbedtls_config.h` to customize the build
diff --git a/thirdparty/mbedtls/include/psa/crypto.h b/thirdparty/mbedtls/include/psa/crypto.h
index 92f9c824e9..390534edf5 100644
--- a/thirdparty/mbedtls/include/psa/crypto.h
+++ b/thirdparty/mbedtls/include/psa/crypto.h
@@ -107,7 +107,9 @@ psa_status_t psa_crypto_init(void);
/** Return an initial value for a key attributes structure.
*/
+#if !(defined(__cplusplus) && defined(_MSC_VER))
static psa_key_attributes_t psa_key_attributes_init(void);
+#endif
/** Declare a key as persistent and set its key identifier.
*
@@ -333,7 +335,9 @@ static void psa_set_key_bits(psa_key_attributes_t *attributes,
*
* \return The key type stored in the attribute structure.
*/
+#if !(defined(__cplusplus) && defined(_MSC_VER))
static psa_key_type_t psa_get_key_type(const psa_key_attributes_t *attributes);
+#endif
/** Retrieve the key size from key attributes.
*
@@ -936,7 +940,9 @@ typedef struct psa_hash_operation_s psa_hash_operation_t;
/** Return an initial value for a hash operation object.
*/
+#if !(defined(__cplusplus) && defined(_MSC_VER))
static psa_hash_operation_t psa_hash_operation_init(void);
+#endif
/** Set up a multipart hash operation.
*
@@ -1295,7 +1301,9 @@ typedef struct psa_mac_operation_s psa_mac_operation_t;
/** Return an initial value for a MAC operation object.
*/
+#if !(defined(__cplusplus) && defined(_MSC_VER))
static psa_mac_operation_t psa_mac_operation_init(void);
+#endif
/** Set up a multipart MAC calculation operation.
*
@@ -1708,7 +1716,9 @@ typedef struct psa_cipher_operation_s psa_cipher_operation_t;
/** Return an initial value for a cipher operation object.
*/
+#if !(defined(__cplusplus) && defined(_MSC_VER))
static psa_cipher_operation_t psa_cipher_operation_init(void);
+#endif
/** Set the key for a multipart symmetric encryption operation.
*
@@ -2226,7 +2236,9 @@ typedef struct psa_aead_operation_s psa_aead_operation_t;
/** Return an initial value for an AEAD operation object.
*/
+#if !(defined(__cplusplus) && defined(_MSC_VER))
static psa_aead_operation_t psa_aead_operation_init(void);
+#endif
/** Set the key for a multipart authenticated encryption operation.
*
@@ -3213,7 +3225,9 @@ typedef struct psa_key_derivation_s psa_key_derivation_operation_t;
/** Return an initial value for a key derivation operation object.
*/
+#if !(defined(__cplusplus) && defined(_MSC_VER))
static psa_key_derivation_operation_t psa_key_derivation_operation_init(void);
+#endif
/** Set up a key derivation operation.
*
diff --git a/thirdparty/mbedtls/include/psa/crypto_extra.h b/thirdparty/mbedtls/include/psa/crypto_extra.h
index 6ed1f6c43a..bd985e9b78 100644
--- a/thirdparty/mbedtls/include/psa/crypto_extra.h
+++ b/thirdparty/mbedtls/include/psa/crypto_extra.h
@@ -915,7 +915,9 @@ typedef struct psa_pake_cipher_suite_s psa_pake_cipher_suite_t;
/** Return an initial value for a PAKE cipher suite object.
*/
+#if !(defined(__cplusplus) && defined(_MSC_VER))
static psa_pake_cipher_suite_t psa_pake_cipher_suite_init(void);
+#endif
/** Retrieve the PAKE algorithm from a PAKE cipher suite.
*
@@ -1048,7 +1050,9 @@ typedef struct psa_jpake_computation_stage_s psa_jpake_computation_stage_t;
/** Return an initial value for a PAKE operation object.
*/
+#if !(defined(__cplusplus) && defined(_MSC_VER))
static psa_pake_operation_t psa_pake_operation_init(void);
+#endif
/** Get the length of the password in bytes from given inputs.
*
diff --git a/thirdparty/mbedtls/patches/msvc-redeclaration-bug.diff b/thirdparty/mbedtls/patches/msvc-redeclaration-bug.diff
new file mode 100644
index 0000000000..c5f1970223
--- /dev/null
+++ b/thirdparty/mbedtls/patches/msvc-redeclaration-bug.diff
@@ -0,0 +1,98 @@
+diff --git a/thirdparty/mbedtls/include/psa/crypto.h b/thirdparty/mbedtls/include/psa/crypto.h
+index 92f9c824e9..1cc2e7e729 100644
+--- a/thirdparty/mbedtls/include/psa/crypto.h
++++ b/thirdparty/mbedtls/include/psa/crypto.h
+@@ -107,7 +107,9 @@ psa_status_t psa_crypto_init(void);
+
+ /** Return an initial value for a key attributes structure.
+ */
++#if !(defined(__cplusplus) && defined(_MSC_VER))
+ static psa_key_attributes_t psa_key_attributes_init(void);
++#endif
+
+ /** Declare a key as persistent and set its key identifier.
+ *
+@@ -333,7 +335,9 @@ static void psa_set_key_bits(psa_key_attributes_t *attributes,
+ *
+ * \return The key type stored in the attribute structure.
+ */
++#if !(defined(__cplusplus) && defined(_MSC_VER))
+ static psa_key_type_t psa_get_key_type(const psa_key_attributes_t *attributes);
++#endif
+
+ /** Retrieve the key size from key attributes.
+ *
+@@ -936,7 +940,9 @@ typedef struct psa_hash_operation_s psa_hash_operation_t;
+
+ /** Return an initial value for a hash operation object.
+ */
++#if !(defined(__cplusplus) && defined(_MSC_VER))
+ static psa_hash_operation_t psa_hash_operation_init(void);
++#endif
+
+ /** Set up a multipart hash operation.
+ *
+@@ -1295,7 +1301,9 @@ typedef struct psa_mac_operation_s psa_mac_operation_t;
+
+ /** Return an initial value for a MAC operation object.
+ */
++#if !(defined(__cplusplus) && defined(_MSC_VER))
+ static psa_mac_operation_t psa_mac_operation_init(void);
++#endif
+
+ /** Set up a multipart MAC calculation operation.
+ *
+@@ -1708,7 +1716,9 @@ typedef struct psa_cipher_operation_s psa_cipher_operation_t;
+
+ /** Return an initial value for a cipher operation object.
+ */
++#if !(defined(__cplusplus) && defined(_MSC_VER))
+ static psa_cipher_operation_t psa_cipher_operation_init(void);
++#endif
+
+ /** Set the key for a multipart symmetric encryption operation.
+ *
+@@ -2226,7 +2236,9 @@ typedef struct psa_aead_operation_s psa_aead_operation_t;
+
+ /** Return an initial value for an AEAD operation object.
+ */
++#if !(defined(__cplusplus) && defined(_MSC_VER))
+ static psa_aead_operation_t psa_aead_operation_init(void);
++#endif
+
+ /** Set the key for a multipart authenticated encryption operation.
+ *
+@@ -3213,7 +3225,9 @@ typedef struct psa_key_derivation_s psa_key_derivation_operation_t;
+
+ /** Return an initial value for a key derivation operation object.
+ */
++#if !(defined(__cplusplus) && defined(_MSC_VER))
+ static psa_key_derivation_operation_t psa_key_derivation_operation_init(void);
++#endif
+
+ /** Set up a key derivation operation.
+ *
+diff --git a/thirdparty/mbedtls/include/psa/crypto_extra.h b/thirdparty/mbedtls/include/psa/crypto_extra.h
+index 6ed1f6c43a..2686b9d74d 100644
+--- a/thirdparty/mbedtls/include/psa/crypto_extra.h
++++ b/thirdparty/mbedtls/include/psa/crypto_extra.h
+@@ -915,7 +915,9 @@ typedef struct psa_pake_cipher_suite_s psa_pake_cipher_suite_t;
+
+ /** Return an initial value for a PAKE cipher suite object.
+ */
++#if !(defined(__cplusplus) && defined(_MSC_VER))
+ static psa_pake_cipher_suite_t psa_pake_cipher_suite_init(void);
++#endif
+
+ /** Retrieve the PAKE algorithm from a PAKE cipher suite.
+ *
+@@ -1048,7 +1050,9 @@ typedef struct psa_jpake_computation_stage_s psa_jpake_computation_stage_t;
+
+ /** Return an initial value for a PAKE operation object.
+ */
++#if !(defined(__cplusplus) && defined(_MSC_VER))
+ static psa_pake_operation_t psa_pake_operation_init(void);
++#endif
+
+ /** Get the length of the password in bytes from given inputs.
+ *