Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions core/config/project_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1733,6 +1733,14 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF("navigation/baking/thread_model/baking_use_multiple_threads", true);
GLOBAL_DEF("navigation/baking/thread_model/baking_use_high_priority_threads", true);
#endif // !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED)
#ifndef NAVIGATION_2D_DISABLED
GLOBAL_DEF("navigation/2d/warnings/navmesh_edge_merge_errors", true);
GLOBAL_DEF("navigation/2d/warnings/navmesh_cell_size_mismatch", true);
#endif // NAVIGATION_2D_DISABLED
#ifndef NAVIGATION_3D_DISABLED
GLOBAL_DEF("navigation/3d/warnings/navmesh_edge_merge_errors", true);
GLOBAL_DEF("navigation/3d/warnings/navmesh_cell_size_mismatch", true);
#endif // NAVIGATION_3D_DISABLED

ProjectSettings::get_singleton()->add_hidden_prefix("input/");
}
Expand Down
12 changes: 12 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2314,6 +2314,12 @@
<member name="navigation/2d/use_edge_connections" type="bool" setter="" getter="" default="true">
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.
</member>
<member name="navigation/2d/warnings/navmesh_cell_size_mismatch" type="bool" setter="" getter="" default="true">
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.
</member>
<member name="navigation/2d/warnings/navmesh_edge_merge_errors" type="bool" setter="" getter="" default="true">
If [code]true[/code], the navigation system will print warnings about navigation mesh edge merge errors occurring in navigation regions or maps.
</member>
<member name="navigation/3d/default_cell_height" type="float" setter="" getter="" default="0.25">
Default cell height for 3D navigation maps. See [method NavigationServer3D.map_set_cell_height].
</member>
Expand All @@ -2335,6 +2341,12 @@
<member name="navigation/3d/use_edge_connections" type="bool" setter="" getter="" default="true">
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.
</member>
<member name="navigation/3d/warnings/navmesh_cell_size_mismatch" type="bool" setter="" getter="" default="true">
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.
</member>
<member name="navigation/3d/warnings/navmesh_edge_merge_errors" type="bool" setter="" getter="" default="true">
If [code]true[/code], the navigation system will print warnings about navigation mesh edge merge errors occurring in navigation regions or maps.
</member>
<member name="navigation/avoidance/thread_model/avoidance_use_high_priority_threads" type="bool" setter="" getter="" default="true">
If enabled and avoidance calculations use multiple threads the threads run with high priority.
</member>
Expand Down
9 changes: 8 additions & 1 deletion modules/navigation_2d/2d/nav_map_builder_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
#include "nav_map_iteration_2d.h"
#include "nav_region_iteration_2d.h"

#include "core/config/project_settings.h"

using namespace Nav2D;

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

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

} else {
// The edge is already connected with another edge, skip.
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.");
edge_merge_error_count++;
}
}
}

if (edge_merge_error_count > 0 && GLOBAL_GET_CACHED(bool, "navigation/2d/warnings/navmesh_edge_merge_errors")) {
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.");
}

r_build.free_edge_count = free_edges_count;
}

Expand Down
9 changes: 8 additions & 1 deletion modules/navigation_2d/2d/nav_region_builder_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include "../triangle2.h"
#include "nav_region_iteration_2d.h"

#include "core/config/project_settings.h"

using namespace Nav2D;

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

int free_edges_count = 0;
int edge_merge_error_count = 0;

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

} else {
// The edge is already connected with another edge, skip.
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.");
edge_merge_error_count++;
}
}
}

if (edge_merge_error_count > 0 && GLOBAL_GET_CACHED(bool, "navigation/2d/warnings/navmesh_edge_merge_errors")) {
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.");
}

performance_data.pm_edge_free_count = free_edges_count;
}

Expand Down
2 changes: 1 addition & 1 deletion modules/navigation_2d/nav_map_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void NavMap2D::set_merge_rasterizer_cell_scale(float p_value) {
if (merge_rasterizer_cell_scale == p_value) {
return;
}
merge_rasterizer_cell_scale = MAX(p_value, NavigationDefaults2D::NAV_MESH_CELL_SIZE_MIN);
merge_rasterizer_cell_scale = MAX(MIN(p_value, 0.1), NavigationDefaults2D::NAV_MESH_CELL_SIZE_MIN);
_update_merge_rasterizer_cell_dimensions();
map_settings_dirty = true;
}
Expand Down
2 changes: 1 addition & 1 deletion modules/navigation_2d/nav_map_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class NavMap2D : public NavRid2D {
Vector2 merge_rasterizer_cell_size = Vector2(cell_size, cell_size);

// This value is used to control sensitivity of internal rasterizer.
float merge_rasterizer_cell_scale = 1.0;
float merge_rasterizer_cell_scale = 0.1;

bool use_edge_connections = true;
/// This value is used to detect the near edges to connect.
Expand Down
9 changes: 7 additions & 2 deletions modules/navigation_2d/nav_region_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,13 @@ void NavRegion2D::set_transform(Transform2D p_transform) {

void NavRegion2D::set_navigation_mesh(Ref<NavigationPolygon> p_navigation_mesh) {
#ifdef DEBUG_ENABLED
if (map && p_navigation_mesh.is_valid() && !Math::is_equal_approx(double(map->get_cell_size()), double(p_navigation_mesh->get_cell_size()))) {
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())));
if (map && p_navigation_mesh.is_valid() && GLOBAL_GET_CACHED(bool, "navigation/2d/warnings/navmesh_cell_size_mismatch")) {
const double map_cell_size = double(map->get_cell_size());
const double navmesh_cell_size = double(p_navigation_mesh->get_cell_size());

if (map_cell_size > navmesh_cell_size) {
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));
}
}
#endif // DEBUG_ENABLED

Expand Down
9 changes: 8 additions & 1 deletion modules/navigation_3d/3d/nav_map_builder_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#include "nav_map_iteration_3d.h"
#include "nav_region_iteration_3d.h"

#include "core/config/project_settings.h"

using namespace Nav3D;

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

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

} else {
// The edge is already connected with another edge, skip.
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.");
edge_merge_error_count++;
}
}
}

if (edge_merge_error_count > 0 && GLOBAL_GET_CACHED(bool, "navigation/3d/warnings/navmesh_edge_merge_errors")) {
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.");
}

r_build.free_edge_count = free_edges_count;
}

Expand Down
9 changes: 8 additions & 1 deletion modules/navigation_3d/3d/nav_region_builder_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#include "../nav_region_3d.h"
#include "nav_region_iteration_3d.h"

#include "core/config/project_settings.h"

using namespace Nav3D;

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

int free_edges_count = 0;
int edge_merge_error_count = 0;

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

} else {
// The edge is already connected with another edge, skip.
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.");
edge_merge_error_count++;
}
}
}

if (edge_merge_error_count > 0 && GLOBAL_GET_CACHED(bool, "navigation/3d/warnings/navmesh_edge_merge_errors")) {
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.");
}

performance_data.pm_edge_free_count = free_edges_count;
}

Expand Down
2 changes: 1 addition & 1 deletion modules/navigation_3d/nav_map_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ void NavMap3D::set_merge_rasterizer_cell_scale(float p_value) {
if (merge_rasterizer_cell_scale == p_value) {
return;
}
merge_rasterizer_cell_scale = MAX(p_value, NavigationDefaults3D::NAV_MESH_CELL_SIZE_MIN);
merge_rasterizer_cell_scale = MAX(MIN(p_value, 0.1), NavigationDefaults3D::NAV_MESH_CELL_SIZE_MIN);
_update_merge_rasterizer_cell_dimensions();
map_settings_dirty = true;
}
Expand Down
2 changes: 1 addition & 1 deletion modules/navigation_3d/nav_map_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class NavMap3D : public NavRid3D {
Vector3 merge_rasterizer_cell_size = Vector3(cell_size, cell_height, cell_size);

// This value is used to control sensitivity of internal rasterizer.
float merge_rasterizer_cell_scale = 1.0;
float merge_rasterizer_cell_scale = 0.1;

bool use_edge_connections = true;
/// This value is used to detect the near edges to connect.
Expand Down
18 changes: 12 additions & 6 deletions modules/navigation_3d/nav_region_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,18 @@ void NavRegion3D::set_transform(Transform3D p_transform) {

void NavRegion3D::set_navigation_mesh(Ref<NavigationMesh> p_navigation_mesh) {
#ifdef DEBUG_ENABLED
if (map && p_navigation_mesh.is_valid() && !Math::is_equal_approx(double(map->get_cell_size()), double(p_navigation_mesh->get_cell_size()))) {
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())));
}

if (map && p_navigation_mesh.is_valid() && !Math::is_equal_approx(double(map->get_cell_height()), double(p_navigation_mesh->get_cell_height()))) {
ERR_PRINT_ONCE(vformat("Attempted to update a navigation region with a navigation mesh that uses a `cell_height` of %s while assigned to a navigation map set to a `cell_height` of %s. The cell height for navigation maps can be changed by using the NavigationServer map_set_cell_height() function. The cell height for default navigation maps can also be changed in the ProjectSettings.", double(p_navigation_mesh->get_cell_height()), double(map->get_cell_height())));
if (map && p_navigation_mesh.is_valid() && GLOBAL_GET_CACHED(bool, "navigation/3d/warnings/navmesh_cell_size_mismatch")) {
const double map_cell_size = double(map->get_cell_size());
const double map_cell_height = double(map->get_cell_height());
const double navmesh_cell_size = double(p_navigation_mesh->get_cell_size());
const double navmesh_cell_height = double(p_navigation_mesh->get_cell_height());

if (map_cell_size > navmesh_cell_size) {
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/3d/warnings/navmesh_cell_size_mismatch' in the project settings.", navmesh_cell_size, map_cell_size));
}
if (map_cell_height > navmesh_cell_height) {
WARN_PRINT(vformat("A navigation mesh that uses a `cell_height` of %s was assigned to a navigation map set to a larger `cell_height` of %s.\nThis mismatch in cell height can cause rasterization errors with navigation mesh edges on the navigation map.\nThe cell height for navigation maps can be changed by using the NavigationServer map_set_cell_height() function.\nThe cell height for default navigation maps can also be changed in the project settings.\nThis warning can be toggled under 'navigation/3d/warnings/navmesh_cell_size_mismatch' in the project settings.", navmesh_cell_height, map_cell_height));
}
}
#endif // DEBUG_ENABLED

Expand Down
Loading