summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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/import/3d/editor_import_collada.cpp11
-rw-r--r--editor/import/3d/resource_importer_obj.cpp15
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp7
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp4
-rw-r--r--modules/gdscript/gdscript_parser.cpp34
-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--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
44 files changed, 578 insertions, 25 deletions
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/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/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/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/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/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/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.
+ *