The library used signed 32bit integers and single precission floating points to represent build times, but on long build times this will overflow. Added a dedicated time type while promoting it to double precission and adjusting all use cases throughout the library.
Go over each neighboring tile starting with the tile facing the edge normal, and then its oposite, and perform the same alternation on the next tiles. This link pattern gives the best and most consistent results by trying to link all sides equally. In order to guarantee maximum coverage, the link count multiplication has been increased from 8 to 32 per detail mesh bound as this new approach is creating an incredible amount of new links. Some of the links will end up not being used, but these will be removed during the prune stage.
- Portal kink point is now always offset twice the walkable radius to account ledge spans and center of hull to ledge, any extra is put on top with the default being 4.f to account for irregularities.
- Make sure we have enough clearance over the kink point and lower start point of the portal so that the NPC does not clip into overhead obstacles when performing an animation.
- Make sure we don't link a portal from underneath geometry by performing a raycast from the edge's mid point, and 2 additional ones if the link's span is larger than 100.f in world units.
This allows for getting the direct side of a side by doing side-1, side+1, etc.. A useful case would be to get tiles at sides facing the normal of an edge on our own tile and doing anything with these tiles.
If there's no movement on the x-y plane between sp and sq, there will be no magnitude, and thus also no discriminant. The code however will continue as it only checks if discriminant < 0. Due to this, the code will no longer take the origin and radius of the cylinder into account and that will cause any ray that extends above or below the cylinder to be a hit, regardless of where it was emitted from in the world. If we have no magnitude, we should always check if the start point resides inside the cylinder area on the x-y plane and determine from there whether to perform a vertical intersection test.
Shift portal mins and maxs together to try and align the portals. The system is dynamic and will take portal span into consideration. Also slightly changed the API to implement an optimization by switching the directional vector of the edges to their normals as we only need the normals in traverseLinkInLOS, this avoids having to recalculate them.
Draw inner and outer poly boundaries, and only draw detail meshes if this was specified by the user. Most of the time we don't want to draw detail as this has a huge performance cost.
This was increased in commit 0a4817a707035e49e757dcd16d132ac5a5a9a46c to address an issue where the AI gets stuck in corners, but the issue also happened on other traverse types (abeit much more rare). After investigating the problem again, the issue was caused by connecting adjacent polygons with traverse portals (which causes an infinite recursion during pathfinding if the first link of that polygon happens to reference the one from which the traversal is taking place). This issue has been patched in commit 582ecec0381b4071f2f7fd1920eeb27c8c8539c7, therefore, we should restore this to its default value again.
The static pathing data is either not built, or has to be rebuilt at this stage. If we have do happen to have dead polygons that we can use for traverse portals then we should leverage them to get as much coverage as possible.
Connecting adjacent polygons with traverse links will cause pathfinding to run into itself infinitely if either of the 2 poly's first link references the polygon from which the traverse link originates from. The behavior in-game is that the AI become stuck in the area with error code FAIL_NO_ROUTE_BLOCKED. Implemented the method 'dtNavMesh::arePolysAdjacent' to make sure we never connect adjacent polygons on our own or neighboring tile with a traverse link.
Use a cell size of 15 instead for navmeshes used for titans and goliaths (_large and _extra_large). This value results in identical values with Titanfall 2 regarding bounding volume quantization factors.
The traversability of off-mesh links is not dictated by the walkable climb in this engine; an off-mesh connection can be higher from the ground due to ziplines.
Currently, trigger only gets used for hazard or door area's, and we don't want NPC's to traverse through these. The collision detection system needs a small overhaul to take actual polygon flags or contents into account which will allow for a much more detailed filtering. This will be done once we use more areas than just hazard or door.
Some of them were incorrectly assigned and also missed a few traverse types dedicated to of-mesh connections. These new values now correspond exactly to the values the game uses. The only one that couldn't be confirmed is GOLIATH, but it should be the same as TITAN. This will fix cases where a polygon island is marked as unreachable for an NPC hull that could traverse a link connecting its current island to the goal one.
Convex volume hmin and hmax are mapped to world coordinates, thus we need to treat them as such. Also fixed a bug where deselecting a shape, and selecting another one, and then resetting the other ones causes it to be reset to the data of the previously selected shape as the index thereof was never reset on deselect.
These new parameters give the best results so far when generating the navmesh over both vphysics and BVH4 collision geometry. Also removed a todo comment that has been addressed.
Type 1 can cause the AI to become stuck when a link is established within a hole that is too short. Testing revealed that any link beyond this length, wether its on a hole or gap, does not cause the AI to become stuck. Updated default.
The mesh data from the game's BVH4 tree does not appear to have a fixed triangle winding order, making it nearly impossible to generate correct navmeshes while using the decoded BVH4 data. Fixing the sign enables us to generate the navmesh over the game's collision data properly rather than using the render mesh. This change does not appear to have a negative effect on the generated NavMesh.
These changes seem to yield better results for the larger maps. The improvements are minimal however. This change is probably more noticable on tile cache.
In recastnavigation/recastnavigation@15ebb8bd25 the change was made to use detail polygons, but it appears that after this change, the bounding volume gets build under the polygons, especially if the polygons's Z are equal on all vertices. Flooring the mins and ceiling the maxs appears to yield correct behavior in all scenarios by making sure the bounding volume always encases its respective polygon.