-
-
Notifications
You must be signed in to change notification settings - Fork 21.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Navigation2D.get_simple_path doesn't return shortest path #62115
Comments
CC @smix8 |
From limited testing the root cause seem to be that the 2D navpoly creates NavigationMesh resources with wrong geometry as I cannot recreate this pathing issue in 3D which uses the same pathing algo and navmesh as 2D. |
Actually I do can create the issue in 3D but only with GridMap cells which are the equivalent of 2D tilemaps. |
in 3D it also still generates unoptimal paths, like in 3.4 |
I think that's the exact reason why it's called like that in the first place though. Otherwise it would be called Indeed seems like that's the case, from the message of the first commit involving navigation (in which
I guess it was never improved properly? 🙂 So if the pathfinding algorithm would be changed to actually always return the shortest path then the method to obtain such path should actually be called |
@Flavelius @kleonc |
@smix8 I'm familiar with how it currently works. I was referring only to the name of |
I extracted the navmesh to not have to supply my whole project with the MRP, it was already 'corrupted' in the source project (as every other navmesh i bake in 3.5 in the same way). Interestingly they don't cause any problems apart from sometimes generating unoptimal paths (not always though, so it's the same behaviour as in 3.4). |
@Flavelius This is your navmesh in my custom debug view, it is a complet polygon mess as you can see by the red line connections formed. |
Isn't the navmesh generated by the navserver? This navmesh atleast was generated in godot 3.5 RC4. |
Godot parses the source geometry from the scene nodes. If the meshes on the scene nodes are already corrupted this is what the recast library that bakes the navmesh gets to work with. |
The source meshes are not corrupted (it's actually just a single height field as mesh) and in 3.4 the navmeshes are (/seem to be) neither, which just leads me to believe it's the generation algorithm. But it may also be that this is just an error that already existed in 3.4 and is just logged in 3.5. Not sure what to report as issue then. |
Could you send me a project that includes the source geometry so I can take a closer look what is going on with the baking steps. |
NavProblem.zip |
Totally unrelated to the issue I suggest not saving binary mesh data in a text format (.tres). With such complex meshes like in the test project parsing and saving the text file takes ages for something that takes a split second as a binary file (.res) and the Godot Editor has a high chance of even crashing when tab in/out of the editor window. The source of your problems again is the imported mesh and collision shape. The geometry parsing expects proper triangulated mesh data for both terrain source mesh or convex collision shape and both fail at this. When you draw debug lines for each face in the meshes you immediatly see that you used quads or n-gons faces in e.g. Blender and those do not work for building navmesh. Since the data for the collision shape is only stored as an array as long as the array sizes is possible for triangles Godot would not notice that the data is corrupted but it will parse the array as if it would be triangles so starting with the 4th value everything shifts in the wrong place. |
@smix8 Could Godot somehow detect n-gons and warn user? |
@Zireael07 |
I meant on import ofc ;) |
Good to know, this is not something i was aware of (nor is it mentioned in the docs) though that it only works (well) with triangles but fails silently with quads/ngons (and quads are usually not something to be called corrupt). It's also not something one would intuitively expect as being wrong as even the generation settings allow setting the limit for polygon points for the resulting navmesh. This should be noted in the docs somewhere as it seems to be an important, mostly unknown, caveat. Edit: but the more i think about it the more it seems reasonable to me to expect the generation algorithm to properly work with quads, as it would be quite an unrealistic expectation for every user supplied mesh to be fully triangulated as any in the scene can potentially contribute to the navmesh. I used Blenders navmesh generator in the past and it worked just fine in that regard, unfortunately it seems to have been deprecated with BGE. |
I just re-checked my terrain mesh in blender (with select by trait->polygon sides) and interestingly it doesn't even contain n-gons, nor quads. It's actually fully triangulated. The collision shape in godot also confirms this, visually (and works without problems too). Maybe there's a bug in your visualization tool or something deeper in godot itself? |
@Flavelius EDIT Solved the debug (not the navmesh) problem, was actually good-old copy&paste error with a varible that caused it, my apology. The problem for both 2D and 3D issues here seem to be that the path funnel post-processing has nothing to work with as A* finds such a narrow passage that the path takes unnatural turns. Since improving / solving this will require to considerably change the algorithm (e.g. search additional neighbors / line of sight checks) which makes the processing far more expensive this is something that needs to be added as a new pathfinding option instead of changing the current pathfinding. The current pathfinding has technically no bug but it is just insufficient for these cases. Grids suffer the most from this but also navmesh areas with a lot of small elevation changes like in the 3D test project. The issue in a user project is an easy fix when physics is involved as we can do just a raycast to check for line of sight but on the NavigationServer it will be a little more work. |
Thanks for being so engaged in fixing this. But for the errors, i still believe this is not a good way to work with the underlying problem. The navmesh itself can be triangulated as much as it needs to be, but it should be generatable from any kinds of polygonal source meshes (like in other game engines and tools). It is kind of detrimental to a fluent workflow to force triangulation for any mesh that can potentially contribute to the navmesh (many meshes are typically used visually and for that quads are easier to work with in for example blender, and often times even preferred for loops). As for the unoptimal a* search; i used the 'A* pathfinding project' for unity for a long time. it also has a funnel modifier for simplifying paths but it works alot better, not sure what it does differently to godot though (https://arongranberg.com/astar/docs/funnelmodifier.html). But if it's the the same underlying algorithm, in my understanding this could only point to an unoptimally/wrongly generated navmesh. |
@Flavelius Funnel is not funnel. The A* in Godot returns a raw grid cell path. This results in the funnel getting stuck on every single grid corner as soon as the path goes diagonal. This is less a problem in 3D with large flat areas cause the polygons span from real geometry obstacle corners to corners. Grids create artifical corners in the middle of nowhere so the path look ugly without a lot of pre-processing or post-processing or making the entire pathfinding algo more costly. |
@smix8 i have to say now i'm even more confused. When you said earlier that the source of my problems was that I was using quads or ngons what did you mean there (when Godot and gltf don't even use those)? Also if they don't exist in Godot what would an error message accomplish then? If this get's too much off topic here, I'm also on the Godot discord with the same username. |
The error msg is for the import stage, e.g. when users import 3D assets from Blender / Maya into Godot as other formats supported by Godot like Collada can import those. Discussed this on devchat and this is the only stage where this can be detected to give a warning. |
Ok, so technically this is not related to the navmesh problem but only to indicate/hint at incomplete fbx & collada importer functionality, if i now understand correctly. Then these warnings do make sense, yes. |
Godot version
6ecdef8
System information
Windows 10, GLES3, NVidia GeForce GTX 760 2GiB
Issue description
This issue continues the story started in #28235
Godot uses A* algorithm to calculate the shortest path between two points through navigation mesh of polygons.
To compute the traveling cost to next polygon:
In some revisions it uses sum of lengths of rectangular perpendiculars from enter point of polygon to common side with the next polygon.
In last revision it uses more complex way, where costs calculated earlier have some correction.
But no one way cannot calculate right traveling cost between polygons because polygons are not points. They have minimum and maximum distance between their points but not have a single cost as a number.
To calculate the shortest path we can use points instead polygons because they have no area and distances between them are constant numbers at one moment of time.
One of these methods is described here. Main idea to use navmesh vertices as A* nodes and create connections between mutually visible vertices. I used this method when I wrote my pathfinding library. It can be improved by creating connections only between those vertices that have both sides pointing in the same side from the line of the connecting segment.
This method have pros and cons:
Pros: Very fast if navmesh is static and if space is indexed by 2D-array of squares with lots of cross-visibility data
Cons: Greater algorithmic complexity of baking map changes on the fly and space reindexing
Algorithm in action (the picture is a link to YouTube):
I don't think my way is the best. But if it helps, I can share the source code of the library. It is rather messy and contains only a naive implementation.
This issue may be related to the following: #60277 and #19011
Steps to reproduce
Navigation2D
node under root nodeTileMap
node underNavigation2D
nodeLine2D
node under root node to visualize found pathTileSet
inTileMap
node with one or two tiles with square navigation polygon in one of themResult:
Minimal reproduction project
TestNavigationFix.zip
The text was updated successfully, but these errors were encountered: