Bake navigation mesh with two forms, but same point values? Is this an bug?

Godot Version

4.2.1

Question

Hello, community!

First, sorry my english and the fact that new users can only add one media to the post…

ALL prints can be see here, please

I’m working on navigation/procedurally generated mesh, and to me this is strange behavior:

In the code below, I created a var named bounding_outline_1 with the same points that exist in var bounding_outline_2, but in a different insertion order, the results obtained during execution are different…

Points in differrent order:

Executions results:

A) Parabounding_outline_1 I had two triangles for navigation

B) Parabounding_outline_2 I had a square

Is this a bug?

Is there a rule for the correct order of adding points?

Code:

func teste05():
var new_navigation_mesh = NavigationPolygon.new()

var bounding_outline_1 = PackedVector2Array([Vector2(0, 0), Vector2(320, 0), Vector2(0, 320), Vector2(320, 320)])
var bounding_outline_2 =  PackedVector2Array([Vector2(0, 0), Vector2(0, 320), Vector2(320, 320), Vector2(320, 0)])
new_navigation_mesh.add_outline(bounding_outline_1)
#new_navigation_mesh.add_outline(bounding_outline_2)
NavigationServer2D.bake_from_source_geometry_data(new_navigation_mesh, NavigationMeshSourceGeometryData2D.new());
$".".navigation_polygon = new_navigation_mesh

Code print:

Execution results mesh result:

A) With line 146 commented

B) with line 145 commented

It is an outline, not a polygon.

An outline can not self-intersect / cross its own edges. That is an invalid outline.

That said, it might still bake as long as it not too complex because the polygon clipping will try to fix it in the outline merge process. Try means there is a chance to break, when things are nested polygon hole calculations gets involved and that has a chance to flip polygons. Eg. what should be a “hole” will turn into a navmesh surface and what should be navmesh surface will turn into a “hole”.

Depends on what you plan to do with the outlines later. but if you are already baking directly with the NavigationServer API you might as well add your traversable and obstruction outlines directly to the NavigationMeshSourceGeometryData2D object that you create.

If you add outlines to the NavigationPolygon those are the outlines the Editor creates and shows. They stay forever with the resource until you delete them, while the source geometry data will free itself after the baking.

You can also find the updated navigation mesh documention here Using navigation meshes — Godot Engine (latest) documentation in English.

1 Like

Please, if possible explain for me de correct process.
I am tryng to procedurally create an navmesh 2d for an tilemap filled proceduraly.
That is, in my tilemap i had some river tiles, rocks, etc.
I’m trying to bake a navmesh with squares of 32x32 for ech tile of type grass and not generate that square (32x32) for river, rocks, etc.

In summary:
Trying make a nav mesh joining squares of 32x32 pixels that represent only de tiles of type grass.

I did something similar recently. Maybe this helps you?

1 Like

Thanks

Thanks

Either I didn’t understand a concept, or maybe there was something wrong with the code, but I tried several times and the result seems unpredictable.

First of all the code doesn’t work without adding indexes. For me, the indices should not be mandatory, however, just adding the points (without indices) the code does not work.

Now, if you run the code below, different results will appear depending on the commented/uncommented line

Code:

func teste07() -> void:
	var new_2d_region_rid: RID = NavigationServer2D.region_create()

	var default_2d_map_rid: RID = get_world_2d().get_navigation_map()
	NavigationServer2D.region_set_map(new_2d_region_rid, default_2d_map_rid)

	var new_navigation_mesh: NavigationPolygon = NavigationPolygon.new()

	# Add vertices for a convex polygon.
	new_navigation_mesh.vertices = PackedVector2Array([
		Vector2(0.0, 0.0),
		Vector2(1000.0, 0.0),
		Vector2(1000.0, 1000.0),
		Vector2(0.0, 1000.0)
	])
	
	var actual_vertices = new_navigation_mesh.get_vertices()
	var new_points:= PackedVector2Array([
		Vector2(1001.0, 1001.0),
		Vector2(2000.0, 1001.0),
		Vector2(2000.0, 2000.0),
		Vector2(1001.0, 2000.0)
	])
	actual_vertices.append_array(new_points)
	new_navigation_mesh.vertices = actual_vertices

	# Add indices for the polygon.
	new_navigation_mesh.add_polygon(
		PackedInt32Array([0, 1, 2, 3])
		#PackedInt32Array([0, 5, 6, 7])
		#PackedInt32Array([0,1,2,3,4,5,6,7])
	)

	NavigationServer2D.region_set_navigation_polygon(new_2d_region_rid, new_navigation_mesh)
	
	var nav_region: NavigationRegion2D = $"."
	nav_region.navigation_polygon.clear()
	nav_region.navigation_polygon = new_navigation_mesh

Code print:


Results of execution:

A) if line 256 and 257 are commented - OK, an small square

B) if line 255 and 257 are commented - ???

C) if line 255 and 256 are commented (all index for all squares points) - Where is de full square?

Must I be getting this all wrong?

Well, it seems like I started to understand and get the concept right.
I need to create and add polygons one by one and not all at once.
In my tests it was also necessary to collide the region, that is, it cannot be tiled perfectly. If a square ends at 100, the next one has to start at 100 and not 101.

Code working:

func teste08() -> void:
	var new_2d_region_rid: RID = NavigationServer2D.region_create()

	var default_2d_map_rid: RID = get_world_2d().get_navigation_map()
	NavigationServer2D.region_set_map(new_2d_region_rid, default_2d_map_rid)

	var new_navigation_mesh: NavigationPolygon = NavigationPolygon.new()

	# Add vertices for a convex polygon.
	new_navigation_mesh.vertices = PackedVector2Array([
		Vector2(0.0, 0.0),
		Vector2(100.0, 0.0),
		Vector2(100.0, 100.0),
		Vector2(0.0, 100.0)
	])
	
	var actual_vertices = new_navigation_mesh.get_vertices()
	var new_points:= PackedVector2Array([
		Vector2(100.0, 0.0),
		Vector2(200.0, 0.0),
		Vector2(200.0, 100.0),
		Vector2(100.0, 100)
	])
	actual_vertices.append_array(new_points)
	new_navigation_mesh.vertices = actual_vertices

	# Add indices for the polygon.
	new_navigation_mesh.add_polygon(
		PackedInt32Array([0, 1, 2, 3]),
	)
	
	new_navigation_mesh.add_polygon(
		PackedInt32Array([4, 5, 6, 7]),
	)

	NavigationServer2D.region_set_navigation_polygon(new_2d_region_rid, new_navigation_mesh)
	
	var nav_region: NavigationRegion2D = $"."
	nav_region.navigation_polygon.clear()
	nav_region.navigation_polygon = new_navigation_mesh

Pay attention to adding polygons so that they are one by one

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.