Skip to content

Commit 1f7630f

Browse files
committed
Merge pull request #110841 from smix8/raster_casual
Make navmesh rasterization errors more lenient
2 parents e49e73e + 19df15f commit 1f7630f

File tree

12 files changed

+75
-16
lines changed

12 files changed

+75
-16
lines changed

core/config/project_settings.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,6 +1733,14 @@ ProjectSettings::ProjectSettings() {
17331733
GLOBAL_DEF("navigation/baking/thread_model/baking_use_multiple_threads", true);
17341734
GLOBAL_DEF("navigation/baking/thread_model/baking_use_high_priority_threads", true);
17351735
#endif // !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED)
1736+
#ifndef NAVIGATION_2D_DISABLED
1737+
GLOBAL_DEF("navigation/2d/warnings/navmesh_edge_merge_errors", true);
1738+
GLOBAL_DEF("navigation/2d/warnings/navmesh_cell_size_mismatch", true);
1739+
#endif // NAVIGATION_2D_DISABLED
1740+
#ifndef NAVIGATION_3D_DISABLED
1741+
GLOBAL_DEF("navigation/3d/warnings/navmesh_edge_merge_errors", true);
1742+
GLOBAL_DEF("navigation/3d/warnings/navmesh_cell_size_mismatch", true);
1743+
#endif // NAVIGATION_3D_DISABLED
17361744

17371745
ProjectSettings::get_singleton()->add_hidden_prefix("input/");
17381746
}

doc/classes/ProjectSettings.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2314,6 +2314,12 @@
23142314
<member name="navigation/2d/use_edge_connections" type="bool" setter="" getter="" default="true">
23152315
If enabled 2D navigation regions will use edge connections to connect with other navigation regions within proximity of the navigation map edge connection margin. This setting only affects World2D default navigation maps.
23162316
</member>
2317+
<member name="navigation/2d/warnings/navmesh_cell_size_mismatch" type="bool" setter="" getter="" default="true">
2318+
If [code]true[/code], the navigation system will print warnings when a navigation mesh with a small cell size is used on a navigation map with a larger size as this commonly causes rasterization errors.
2319+
</member>
2320+
<member name="navigation/2d/warnings/navmesh_edge_merge_errors" type="bool" setter="" getter="" default="true">
2321+
If [code]true[/code], the navigation system will print warnings about navigation mesh edge merge errors occurring in navigation regions or maps.
2322+
</member>
23172323
<member name="navigation/3d/default_cell_height" type="float" setter="" getter="" default="0.25">
23182324
Default cell height for 3D navigation maps. See [method NavigationServer3D.map_set_cell_height].
23192325
</member>
@@ -2335,6 +2341,12 @@
23352341
<member name="navigation/3d/use_edge_connections" type="bool" setter="" getter="" default="true">
23362342
If enabled 3D navigation regions will use edge connections to connect with other navigation regions within proximity of the navigation map edge connection margin. This setting only affects World3D default navigation maps.
23372343
</member>
2344+
<member name="navigation/3d/warnings/navmesh_cell_size_mismatch" type="bool" setter="" getter="" default="true">
2345+
If [code]true[/code], the navigation system will print warnings when a navigation mesh with a small cell size (or in 3D height) is used on a navigation map with a larger size as this commonly causes rasterization errors.
2346+
</member>
2347+
<member name="navigation/3d/warnings/navmesh_edge_merge_errors" type="bool" setter="" getter="" default="true">
2348+
If [code]true[/code], the navigation system will print warnings about navigation mesh edge merge errors occurring in navigation regions or maps.
2349+
</member>
23382350
<member name="navigation/avoidance/thread_model/avoidance_use_high_priority_threads" type="bool" setter="" getter="" default="true">
23392351
If enabled and avoidance calculations use multiple threads the threads run with high priority.
23402352
</member>

modules/navigation_2d/2d/nav_map_builder_2d.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
#include "nav_map_iteration_2d.h"
3838
#include "nav_region_iteration_2d.h"
3939

40+
#include "core/config/project_settings.h"
41+
4042
using namespace Nav2D;
4143

4244
PointKey NavMapBuilder2D::get_point_key(const Vector2 &p_pos, const Vector2 &p_cell_size) {
@@ -110,6 +112,7 @@ void NavMapBuilder2D::_build_step_find_edge_connection_pairs(NavMapIterationBuil
110112
connection_pairs_map.clear();
111113
connection_pairs_map.reserve(polygon_count);
112114
int free_edges_count = 0; // How many ConnectionPairs have only one Connection.
115+
int edge_merge_error_count = 0;
113116

114117
for (const Ref<NavRegionIteration2D> &region : map_iteration->region_iterations) {
115118
for (const ConnectableEdge &connectable_edge : region->get_external_edges()) {
@@ -138,11 +141,15 @@ void NavMapBuilder2D::_build_step_find_edge_connection_pairs(NavMapIterationBuil
138141

139142
} else {
140143
// The edge is already connected with another edge, skip.
141-
ERR_PRINT_ONCE("Navigation map synchronization error. Attempted to merge a navigation mesh polygon edge with another already-merged edge. This is usually caused by crossing edges, overlapping polygons, or a mismatch of the NavigationMesh / NavigationPolygon baked 'cell_size' and navigation map 'cell_size'. If you're certain none of above is the case, change 'navigation/2d/merge_rasterizer_cell_scale' to 0.001.");
144+
edge_merge_error_count++;
142145
}
143146
}
144147
}
145148

149+
if (edge_merge_error_count > 0 && GLOBAL_GET_CACHED(bool, "navigation/2d/warnings/navmesh_edge_merge_errors")) {
150+
WARN_PRINT("Navigation map synchronization had " + itos(edge_merge_error_count) + " edge error(s).\nMore than 2 edges tried to occupy the same map rasterization space.\nThis causes a logical error in the navigation mesh geometry and is commonly caused by overlap or too densely placed edges.\nConsider baking with a higher 'cell_size', greater geometry margin, and less detailed bake objects to cause fewer edges.\nConsider lowering the 'navigation/2d/merge_rasterizer_cell_scale' in the project settings.\nThis warning can be toggled under 'navigation/2d/warnings/navmesh_edge_merge_errors' in the project settings.");
151+
}
152+
146153
r_build.free_edge_count = free_edges_count;
147154
}
148155

modules/navigation_2d/2d/nav_region_builder_2d.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
#include "../triangle2.h"
3636
#include "nav_region_iteration_2d.h"
3737

38+
#include "core/config/project_settings.h"
39+
3840
using namespace Nav2D;
3941

4042
void NavRegionBuilder2D::build_iteration(NavRegionIterationBuild2D &r_build) {
@@ -179,6 +181,7 @@ void NavRegionBuilder2D::_build_step_find_edge_connection_pairs(NavRegionIterati
179181
region_iteration->external_edges.clear();
180182

181183
int free_edges_count = 0;
184+
int edge_merge_error_count = 0;
182185

183186
for (Polygon &poly : region_iteration->navmesh_polygons) {
184187
for (uint32_t p = 0; p < poly.vertices.size(); p++) {
@@ -208,11 +211,15 @@ void NavRegionBuilder2D::_build_step_find_edge_connection_pairs(NavRegionIterati
208211

209212
} else {
210213
// The edge is already connected with another edge, skip.
211-
ERR_FAIL_COND_MSG(pair.size >= 2, "Navigation region synchronization error. More than 2 edges tried to occupy the same map rasterization space. This is a logical error in the navigation mesh caused by overlap or too densely placed edges.");
214+
edge_merge_error_count++;
212215
}
213216
}
214217
}
215218

219+
if (edge_merge_error_count > 0 && GLOBAL_GET_CACHED(bool, "navigation/2d/warnings/navmesh_edge_merge_errors")) {
220+
WARN_PRINT("Navigation region synchronization had " + itos(edge_merge_error_count) + " edge error(s).\nMore than 2 edges tried to occupy the same map rasterization space.\nThis causes a logical error in the navigation mesh geometry and is commonly caused by overlap or too densely placed edges.\nConsider baking with a higher 'cell_size', greater geometry margin, and less detailed bake objects to cause fewer edges.\nConsider lowering the 'navigation/2d/merge_rasterizer_cell_scale' in the project settings.\nThis warning can be toggled under 'navigation/2d/warnings/navmesh_edge_merge_errors' in the project settings.");
221+
}
222+
216223
performance_data.pm_edge_free_count = free_edges_count;
217224
}
218225

modules/navigation_2d/nav_map_2d.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ void NavMap2D::set_merge_rasterizer_cell_scale(float p_value) {
8080
if (merge_rasterizer_cell_scale == p_value) {
8181
return;
8282
}
83-
merge_rasterizer_cell_scale = MAX(p_value, NavigationDefaults2D::NAV_MESH_CELL_SIZE_MIN);
83+
merge_rasterizer_cell_scale = MAX(MIN(p_value, 0.1), NavigationDefaults2D::NAV_MESH_CELL_SIZE_MIN);
8484
_update_merge_rasterizer_cell_dimensions();
8585
map_settings_dirty = true;
8686
}

modules/navigation_2d/nav_map_2d.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class NavMap2D : public NavRid2D {
5656
Vector2 merge_rasterizer_cell_size = Vector2(cell_size, cell_size);
5757

5858
// This value is used to control sensitivity of internal rasterizer.
59-
float merge_rasterizer_cell_scale = 1.0;
59+
float merge_rasterizer_cell_scale = 0.1;
6060

6161
bool use_edge_connections = true;
6262
/// This value is used to detect the near edges to connect.

modules/navigation_2d/nav_region_2d.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,13 @@ void NavRegion2D::set_transform(Transform2D p_transform) {
9494

9595
void NavRegion2D::set_navigation_mesh(Ref<NavigationPolygon> p_navigation_mesh) {
9696
#ifdef DEBUG_ENABLED
97-
if (map && p_navigation_mesh.is_valid() && !Math::is_equal_approx(double(map->get_cell_size()), double(p_navigation_mesh->get_cell_size()))) {
98-
ERR_PRINT_ONCE(vformat("Attempted to update a navigation region with a navigation mesh that uses a `cell_size` of %s while assigned to a navigation map set to a `cell_size` of %s. The cell size for navigation maps can be changed by using the NavigationServer map_set_cell_size() function. The cell size for default navigation maps can also be changed in the ProjectSettings.", double(p_navigation_mesh->get_cell_size()), double(map->get_cell_size())));
97+
if (map && p_navigation_mesh.is_valid() && GLOBAL_GET_CACHED(bool, "navigation/2d/warnings/navmesh_cell_size_mismatch")) {
98+
const double map_cell_size = double(map->get_cell_size());
99+
const double navmesh_cell_size = double(p_navigation_mesh->get_cell_size());
100+
101+
if (map_cell_size > navmesh_cell_size) {
102+
WARN_PRINT(vformat("A navigation mesh that uses a `cell_size` of %s was assigned to a navigation map set to a larger `cell_size` of %s.\nThis mismatch in cell size can cause rasterization errors with navigation mesh edges on the navigation map.\nThe cell size for navigation maps can be changed by using the NavigationServer map_set_cell_size() function.\nThe cell size for default navigation maps can also be changed in the project settings.\nThis warning can be toggled under 'navigation/2d/warnings/navmesh_cell_size_mismatch' in the project settings.", navmesh_cell_size, map_cell_size));
103+
}
99104
}
100105
#endif // DEBUG_ENABLED
101106

modules/navigation_3d/3d/nav_map_builder_3d.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
#include "nav_map_iteration_3d.h"
3737
#include "nav_region_iteration_3d.h"
3838

39+
#include "core/config/project_settings.h"
40+
3941
using namespace Nav3D;
4042

4143
PointKey NavMapBuilder3D::get_point_key(const Vector3 &p_pos, const Vector3 &p_cell_size) {
@@ -111,6 +113,7 @@ void NavMapBuilder3D::_build_step_find_edge_connection_pairs(NavMapIterationBuil
111113
connection_pairs_map.clear();
112114
connection_pairs_map.reserve(polygon_count);
113115
int free_edges_count = 0; // How many ConnectionPairs have only one Connection.
116+
int edge_merge_error_count = 0;
114117

115118
for (const Ref<NavRegionIteration3D> &region : map_iteration->region_iterations) {
116119
for (const ConnectableEdge &connectable_edge : region->get_external_edges()) {
@@ -139,11 +142,15 @@ void NavMapBuilder3D::_build_step_find_edge_connection_pairs(NavMapIterationBuil
139142

140143
} else {
141144
// The edge is already connected with another edge, skip.
142-
ERR_PRINT_ONCE("Navigation map synchronization error. Attempted to merge a navigation mesh polygon edge with another already-merged edge. This is usually caused by crossing edges, overlapping polygons, or a mismatch of the NavigationMesh / NavigationPolygon baked 'cell_size' and navigation map 'cell_size'. If you're certain none of above is the case, change 'navigation/3d/merge_rasterizer_cell_scale' to 0.001.");
145+
edge_merge_error_count++;
143146
}
144147
}
145148
}
146149

150+
if (edge_merge_error_count > 0 && GLOBAL_GET_CACHED(bool, "navigation/3d/warnings/navmesh_edge_merge_errors")) {
151+
WARN_PRINT("Navigation map synchronization had " + itos(edge_merge_error_count) + " edge error(s).\nMore than 2 edges tried to occupy the same map rasterization space.\nThis causes a logical error in the navigation mesh geometry and is commonly caused by overlap or too densely placed edges.\nConsider baking with a higher 'cell_size', greater geometry margin, and less detailed bake objects to cause fewer edges.\nConsider lowering the 'navigation/3d/merge_rasterizer_cell_scale' in the project settings.\nThis warning can be toggled under 'navigation/3d/warnings/navmesh_edge_merge_errors' in the project settings.");
152+
}
153+
147154
r_build.free_edge_count = free_edges_count;
148155
}
149156

modules/navigation_3d/3d/nav_region_builder_3d.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#include "../nav_region_3d.h"
3535
#include "nav_region_iteration_3d.h"
3636

37+
#include "core/config/project_settings.h"
38+
3739
using namespace Nav3D;
3840

3941
void NavRegionBuilder3D::build_iteration(NavRegionIterationBuild3D &r_build) {
@@ -180,6 +182,7 @@ void NavRegionBuilder3D::_build_step_find_edge_connection_pairs(NavRegionIterati
180182
region_iteration->external_edges.clear();
181183

182184
int free_edges_count = 0;
185+
int edge_merge_error_count = 0;
183186

184187
for (Polygon &poly : region_iteration->navmesh_polygons) {
185188
for (uint32_t p = 0; p < poly.vertices.size(); p++) {
@@ -209,11 +212,15 @@ void NavRegionBuilder3D::_build_step_find_edge_connection_pairs(NavRegionIterati
209212

210213
} else {
211214
// The edge is already connected with another edge, skip.
212-
ERR_FAIL_COND_MSG(pair.size >= 2, "Navigation region synchronization error. More than 2 edges tried to occupy the same map rasterization space. This is a logical error in the navigation mesh caused by overlap or too densely placed edges.");
215+
edge_merge_error_count++;
213216
}
214217
}
215218
}
216219

220+
if (edge_merge_error_count > 0 && GLOBAL_GET_CACHED(bool, "navigation/3d/warnings/navmesh_edge_merge_errors")) {
221+
WARN_PRINT("Navigation region synchronization had " + itos(edge_merge_error_count) + " edge error(s).\nMore than 2 edges tried to occupy the same map rasterization space.\nThis causes a logical error in the navigation mesh geometry and is commonly caused by overlap or too densely placed edges.\nConsider baking with a higher 'cell_size', greater geometry margin, and less detailed bake objects to cause fewer edges.\nConsider lowering the 'navigation/3d/merge_rasterizer_cell_scale' in the project settings.\nThis warning can be toggled under 'navigation/3d/warnings/navmesh_edge_merge_errors' in the project settings.");
222+
}
223+
217224
performance_data.pm_edge_free_count = free_edges_count;
218225
}
219226

modules/navigation_3d/nav_map_3d.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ void NavMap3D::set_merge_rasterizer_cell_scale(float p_value) {
9797
if (merge_rasterizer_cell_scale == p_value) {
9898
return;
9999
}
100-
merge_rasterizer_cell_scale = MAX(p_value, NavigationDefaults3D::NAV_MESH_CELL_SIZE_MIN);
100+
merge_rasterizer_cell_scale = MAX(MIN(p_value, 0.1), NavigationDefaults3D::NAV_MESH_CELL_SIZE_MIN);
101101
_update_merge_rasterizer_cell_dimensions();
102102
map_settings_dirty = true;
103103
}

0 commit comments

Comments
 (0)