godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
88.96k stars 20.18k forks source link

NavigationRegion3D with multiple floor levels bakes polygons with wrong height #95029

Open rlcevg opened 1 month ago

rlcevg commented 1 month ago

Tested versions

System information

Linux - Godot v4.3.rc1.official.e343dbbcc - Vulkan (Forward+)

Issue description

With specific geometry, like map with bridges or multiple connected height levels (floors), NavigationRegion3D may create polygons using height from wrong level. nav_bake_3d Current example bugs with sample_partition_type Monotone or Layers

Steps to reproduce

  1. Open MRP
  2. Select NavigationRegion3D node
  3. Click Clear NavigationMesh
  4. Click Bake NavigationMesh

Minimal reproduction project (MRP)

nav-bake-3d.zip

rlcevg commented 1 month ago

Additional info: Using Monotone or Layers sample_partition_type as suggested in Optimizing Navigation Performance. MRP is a simplified version of "dungeon" generated using SimpleDungeons addon. Hence can't pre-bake and tweak navigation mesh for my use-case.

Assuming the issue is in thirdparty module recastnavigation.

Unless i misunderstood and provided illegal params for NavigationMesh...

smix8 commented 1 month ago

There is a practical limit that depends on your geometry how much detail you can discard for performance before you run into a lot of problems.

At the end of the day ReCast spans a giant voxel grid over your geometry and if you remove or lower nearly every setting that stands for detail you get low or no quality.

If you dont use Watershed you have no distance field so verticality is already at the lower detail end. That alone might be compensated with a better cell resolution or lower error margins but pair everything together like in this project and it can not work. Dial at least 1 or 2 of those parameters to something more reasonable and the issue will disappear.

rlcevg commented 1 month ago

Having ground tiles 10x10 i tried cell_size=0.25, cell_height=0.1, sample_partition_type=Layers (Monotone had no issue) and issue persists (not in MRP): nav_bake_05_01 Thought cell_size=1.0, cell_height=0.5 was good enough for 10.0x10.0x10.0 room-tile.

EDIT: maybe i have to add advanced MRP, as case on the picture is very persistent; though only for sample_partition_type=Layers but down to cell_size=0.1, cell_height=0.1, edge_max_error=1.0, sample_distance=1.0, sample_max_error=1.0

rlcevg commented 1 month ago

1) workaround for sample_partition_type=Monotone: region_merge_size=0 or depending on geometry and current cell_size - small enough region_merge_size to avoid creation of loops in horizontal plane that go from low floor to higher one. Region-merging is simple in monotone: only by spanCount and don't care about verticality, except no overlaps: mergeAndFilterRegions

2) sample_partition_type=Watershed: Noticed issues with watershed only on relatively big maps (110x160x110m with tile 10x10x10m). With cell_size ~= cell_height (and respective value for agent_max_climb) issues went away. Otherwise it may fail to create polygons even on flat ground at random spots (level with 8+ vertical floors).

3) sample_partition_type=Layers: remain broken with any values (0.1..1.0) for cell_size, cell_height, region_merge_size. Will try with the official fix fix:rcBuildLayerRegions missing areaType - not related. EDIT: Layers doesn't use region_merge_size

I wonder if the issue is lack of ability to pass areaID with geometry (it is only RC_WALKABLE_AREA now). It would allow to assign special areaID for stair-tiles; Layers doesn't merge voxel-span regions with different areaType, and it would allow to build navigation mesh in one call. Another "more manual work" option is to create navigation region with stairs left out of "navigation group" and then manually connect stairs with floors, but too much scripting for what internal recast's areaType already supposed to do.