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)
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.