diff --git a/src/DotRecast.Detour.Crowd/DtPathCorridor.cs b/src/DotRecast.Detour.Crowd/DtPathCorridor.cs index 9b5982e..493d9d1 100644 --- a/src/DotRecast.Detour.Crowd/DtPathCorridor.cs +++ b/src/DotRecast.Detour.Crowd/DtPathCorridor.cs @@ -364,7 +364,7 @@ namespace DotRecast.Detour.Crowd return false; } - public bool MoveOverOffmeshConnection(long offMeshConRef, long[] refs, ref RcVec3f start, ref RcVec3f end, DtNavMeshQuery navquery) + public bool MoveOverOffmeshConnection(long offMeshConRef, long[] refs, ref RcVec3f startPos, ref RcVec3f endPos, DtNavMeshQuery navquery) { // Advance the path up to and over the off-mesh connection. long prevRef = 0, polyRef = m_path[0]; @@ -388,12 +388,10 @@ namespace DotRecast.Detour.Crowd refs[1] = polyRef; DtNavMesh nav = navquery.GetAttachedNavMesh(); - var startEnd = nav.GetOffMeshConnectionPolyEndPoints(refs[0], refs[1]); + var startEnd = nav.GetOffMeshConnectionPolyEndPoints(refs[0], refs[1], ref startPos, ref endPos); if (startEnd.Succeeded()) { - m_pos = startEnd.result.Item2; - start = startEnd.result.Item1; - end = startEnd.result.Item2; + m_pos = endPos; return true; } diff --git a/src/DotRecast.Detour/DtNavMesh.cs b/src/DotRecast.Detour/DtNavMesh.cs index dd34e76..bd46b92 100644 --- a/src/DotRecast.Detour/DtNavMesh.cs +++ b/src/DotRecast.Detour/DtNavMesh.cs @@ -1497,39 +1497,43 @@ namespace DotRecast.Detour return (int)(n & mask); } + /// Gets the endpoints for an off-mesh connection, ordered by "direction of travel". + /// @param[in] prevRef The reference of the polygon before the connection. + /// @param[in] polyRef The reference of the off-mesh connection polygon. + /// @param[out] startPos The start position of the off-mesh connection. [(x, y, z)] + /// @param[out] endPos The end position of the off-mesh connection. [(x, y, z)] + /// @return The status flags for the operation. + /// /// @par /// - /// Off-mesh connections are stored in the navigation mesh as special - /// 2-vertex - /// polygons with a single edge. At least one of the vertices is expected to - /// be - /// inside a normal polygon. So an off-mesh connection is "entered" from a - /// normal polygon at one of its endpoints. This is the polygon identified - /// by + /// Off-mesh connections are stored in the navigation mesh as special 2-vertex + /// polygons with a single edge. At least one of the vertices is expected to be + /// inside a normal polygon. So an off-mesh connection is "entered" from a + /// normal polygon at one of its endpoints. This is the polygon identified by /// the prevRef parameter. - public Result> GetOffMeshConnectionPolyEndPoints(long prevRef, long polyRef) + public DtStatus GetOffMeshConnectionPolyEndPoints(long prevRef, long polyRef, ref RcVec3f startPos, ref RcVec3f endPos) { if (polyRef == 0) { - return Results.InvalidParam>("polyRef = 0"); + return DtStatus.DT_FAILURE; } // Get current polygon DecodePolyId(polyRef, out var salt, out var it, out var ip); if (it >= m_maxTiles) { - return Results.InvalidParam>("Invalid tile ID > max tiles"); + return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM; } if (m_tiles[it].salt != salt || m_tiles[it].data.header == null) { - return Results.InvalidParam>("Invalid salt or missing tile header"); + return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM; } DtMeshTile tile = m_tiles[it]; if (ip >= tile.data.header.polyCount) { - return Results.InvalidParam>("Invalid poly ID > poly count"); + return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM; } DtPoly poly = tile.data.polys[ip]; @@ -1537,7 +1541,7 @@ namespace DotRecast.Detour // Make sure that the current poly is indeed off-mesh link. if (poly.GetPolyType() != DtPoly.DT_POLYTYPE_OFFMESH_CONNECTION) { - return Results.InvalidParam>("Invalid poly type"); + return DtStatus.DT_FAILURE; } // Figure out which way to hand out the vertices. @@ -1558,11 +1562,10 @@ namespace DotRecast.Detour } } - RcVec3f startPos = new RcVec3f(); - RcVec3f endPos = new RcVec3f(); - startPos.Set(tile.data.verts, poly.verts[idx0] * 3); - endPos.Set(tile.data.verts, poly.verts[idx1] * 3); - return Results.Success(Tuple.Create(startPos, endPos)); + startPos = RcVec3f.Of(tile.data.verts, poly.verts[idx0] * 3); + endPos = RcVec3f.Of(tile.data.verts, poly.verts[idx1] * 3); + + return DtStatus.DT_SUCCSESS; } public int GetMaxVertsPerPoly() diff --git a/src/DotRecast.Recast.Demo/Tools/TestNavmeshTool.cs b/src/DotRecast.Recast.Demo/Tools/TestNavmeshTool.cs index 65fb506..b407ebc 100644 --- a/src/DotRecast.Recast.Demo/Tools/TestNavmeshTool.cs +++ b/src/DotRecast.Recast.Demo/Tools/TestNavmeshTool.cs @@ -275,6 +275,9 @@ public class TestNavmeshTool : IRcTool else if (offMeshConnection && PathUtils.InRange(iterPos, steerTarget.steerPos, SLOP, 1.0f)) { // Reached off-mesh connection. + RcVec3f startPos = RcVec3f.Zero; + RcVec3f endPos = RcVec3f.Zero; + // Advance the path up to and over the off-mesh connection. long prevRef = 0; long polyRef = polys[0]; @@ -289,11 +292,9 @@ public class TestNavmeshTool : IRcTool polys = polys.GetRange(npos, polys.Count - npos); // Handle the connection. - var offMeshCon = m_navMesh.GetOffMeshConnectionPolyEndPoints(prevRef, polyRef); - if (offMeshCon.Succeeded()) + var status2 = m_navMesh.GetOffMeshConnectionPolyEndPoints(prevRef, polyRef, ref startPos, ref endPos); + if (status2.Succeeded()) { - var startPos = offMeshCon.result.Item1; - var endPos = offMeshCon.result.Item2; if (m_smoothPath.Count < MAX_SMOOTH) { m_smoothPath.Add(startPos);