2

Sidenote: I'm not sure if this question belongs on the game development stack exchange site - but, I feel it belongs here since, while the context is a game, the algorithm itself that I'm looking to implement is fairly application agnostic. Furthermore, I'm not looking for a high level technique, as I feel that I have already established one, but instead I'm seeking more specific help to a certain problem. Anyhow, to the question:

Hey everyone!

I'm working on a multiplayer game that requires that the server can perform pathfinding for server-controlled entities. The server is a straight-up C# application, and the client uses the Unity game engine. Using Unity on the server is not an option. Furthermore, I would like to avoid native libraries completely.

I've already examined Detour for pathfinding, and though they do have C# ports, I'd rather have my own implementation of the actual pathfinding bit; as the process straightforward enough and I'd like it to be tailored to my needs so that it plays well with the existing components on the server.

Unity comes with built-in support for Recast/Detour. This is good, since I can use Recast in Unity to generate the navigation mesh; then consume it on the server using my own pathfinding. The problem is that I cannot seem to find a proper way to generate a graph based off of the mesh created by Unity/Recast.

What I need to do is create a graph, in memory, where each node is a triangle in the mesh, and each edge of the graph connects two triangles that are adjacent to eachother.

The only data I'm able to extract from Unity's API are the vertices and triangle indices of the generated mesh, so I'll need to re-construct my own graph. My first implementation simply created a node per triangle, and if that triangle shared two other points with another triangle, to create a link between them - forming the edges of my graph.

While this works great for the majority of the mesh, it falls short because it seems that Unity is spitting out meshes that can have connections (edges) between areas (polygons) even if they don't share two vertices. Here is an example of Unity overlaying its generated navmesh onto my level geometry (Unity does merge triangles into convex polygons, while my code does not - however, the problem still exists in either case)

Unity Navmesh

In this example, my generated graph needs to connect the polygons separated by the white line (which I can't find any documentation that explains why it's rendered as white in Unity) but is unable to do so since they only share a single vertex.

I'm wondering if there is an efficient algorithm for detecting these cases. What I'm thinking of doing is having it so that polygons are considered connected:

if (sharedVertexCount == 2)
    connectPolygons()
else if (sharedVertexCount == 1)
    Vector3[] parallelLine = findParallelLineSharedByBothPolygons()
    if (parallelLine != null)
        Vector3 otherPoint = getUnsharedPointInLine(parallelLine)
        if (isPointInLine(parallelLine, otherPoint))
            connectPolygons()

I think this should work, but I'm not finding a way to do this efficiently. Also, I'm having a bit of trouble with the "isPointInLine" implementation as apparently my math skills are rustier than I thought.

Either way, there has to be a simpler solution; yet I've found nothing online that points me in that direction... which is why I'm asking you fine folks if there's anything I can do to efficiently turn the generated navmesh into a graph of connected polygons. Either help with my implementation of isPointInLine or pointing me in the direction of a more sensible algorithm would be appreciated beyond words.

LittlePip
  • 266
  • 3
  • 7

2 Answers2

1

When it comes to pathfinding, most methods suggest a premade data-structure dedicated for the navigation which is easier to work with (unless your graphic data-structure is simple enough - which here it isn't).

I'm suggesting you few solutions:

  • Voxel based navigation system: implementing a voxel system with 3D array of booleans (can/'t pass), and applying and A Star or D Star algorithm on it.

  • Know path vectors which are known to the AI that it can pass through there.

  • A merge of the two systems (Main paths use known path vectors while the meshes sign a voxel it's intersecting with false. - This is probably the solution you are looking for.

Tamir Vered
  • 10,187
  • 5
  • 45
  • 57
  • Well, I could certainly ditch Unity's use of Recast and write my own automatic navmesh generator; but with the triangles exported out from Unity's navmesh I'm infuriatingly close to having a working implementing using it as the input to my pathfinding system. Basically you're suggesting that this approach isn't worth the trouble? – LittlePip Feb 08 '14 at 12:02
  • This method is hermetic, for most applications (games, etc...) you don't need an hermetic solution, you need a working simple maintainable solution. And i'm software infrastructure designer, I love hermetic solutions lol... – Tamir Vered Feb 08 '14 at 12:10
  • D\* is obsolete, if you really need it you should be using D\*-Lite instead. However, even D\*-Lite is pretty rare for games, because it's much more complicated than A\*. See [here](http://cstheory.stackexchange.com/questions/11855) for more information. – BlueRaja - Danny Pflughoeft Feb 08 '14 at 16:43
0

Visibility graph based path planning algorithms can solve your problem:

The clue is to extract a graph from an existing polygon map in which nodes are connected when they are directly reachable from each other. The resulting so called visibility graph (cf. https://en.wikipedia.org/wiki/Visibility_graph), can then be used for navigation with regular shortest path algorithms (https://en.wikipedia.org/wiki/Shortest_path_problem).

There are quite a few existing algorithms to extract a visibility graph for path planning in an efficient manner. Here are a few related links:

A thesis describing the general procedure and a few tweaks in chapter 4.4

Please note that there is open source software available implementing this.

jannikmi
  • 23
  • 4