diff --git a/src/DotRecast.Detour.Crowd/DtCrowd.cs b/src/DotRecast.Detour.Crowd/DtCrowd.cs index 2bf80af..fd4c621 100644 --- a/src/DotRecast.Detour.Crowd/DtCrowd.cs +++ b/src/DotRecast.Detour.Crowd/DtCrowd.cs @@ -615,8 +615,7 @@ namespace DotRecast.Detour.Crowd { // Partial path, constrain target position inside the // last polygon. - Result cr = _navQuery.ClosestPointOnPoly(reqPath[reqPath.Count - 1], - ag.targetPos); + Result cr = _navQuery.ClosestPointOnPoly(reqPath[reqPath.Count - 1], ag.targetPos); if (cr.Succeeded()) { reqPos = cr.result.GetClosest(); diff --git a/src/DotRecast.Detour/DtNavMesh.cs b/src/DotRecast.Detour/DtNavMesh.cs index 5ce239f..92342d8 100644 --- a/src/DotRecast.Detour/DtNavMesh.cs +++ b/src/DotRecast.Detour/DtNavMesh.cs @@ -243,10 +243,11 @@ namespace DotRecast.Detour /// reference is valid. This function is faster than #getTileAndPolyByRef, /// but /// it does not validate the reference. - public Tuple GetTileAndPolyByRefUnsafe(long refs) + public void GetTileAndPolyByRefUnsafe(long refs, out DtMeshTile tile, out DtPoly poly) { DecodePolyId(refs, out var salt, out var it, out var ip); - return Tuple.Create(m_tiles[it], m_tiles[it].data.polys[ip]); + tile = m_tiles[it]; + poly = m_tiles[it].data.polys[ip]; } public bool IsValidPolyRef(long refs) @@ -1302,9 +1303,7 @@ namespace DotRecast.Detour public ClosestPointOnPolyResult ClosestPointOnPoly(long refs, RcVec3f pos) { - Tuple tileAndPoly = GetTileAndPolyByRefUnsafe(refs); - DtMeshTile tile = tileAndPoly.Item1; - DtPoly poly = tileAndPoly.Item2; + GetTileAndPolyByRefUnsafe(refs, out var tile, out var poly); RcVec3f closest = new RcVec3f(); closest = pos; float? h = GetPolyHeight(tile, poly, pos); diff --git a/src/DotRecast.Detour/DtNavMeshQuery.cs b/src/DotRecast.Detour/DtNavMeshQuery.cs index 501ce2c..64e63d5 100644 --- a/src/DotRecast.Detour/DtNavMeshQuery.cs +++ b/src/DotRecast.Detour/DtNavMeshQuery.cs @@ -232,9 +232,7 @@ namespace DotRecast.Detour return Results.InvalidParam(); } - Tuple tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(startRef); - DtMeshTile startTile = tileAndPoly.Item1; - DtPoly startPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(startRef, out var startTile, out var startPoly); if (!filter.PassFilter(startRef, startTile, startPoly)) { return Results.InvalidParam("Invalid start ref"); @@ -267,9 +265,7 @@ namespace DotRecast.Detour // Get poly and tile. // The API input has been cheked already, skip checking internal data. long bestRef = bestNode.id; - Tuple bestTilePoly = m_nav.GetTileAndPolyByRefUnsafe(bestRef); - DtMeshTile bestTile = bestTilePoly.Item1; - DtPoly bestPoly = bestTilePoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(bestRef, out var bestTile, out var bestPoly); // Place random locations on on ground. if (bestPoly.GetPolyType() == DtPoly.DT_POLYTYPE_GROUND) @@ -324,9 +320,7 @@ namespace DotRecast.Detour } // Expand to neighbour - Tuple neighbourTilePoly = m_nav.GetTileAndPolyByRefUnsafe(neighbourRef); - DtMeshTile neighbourTile = neighbourTilePoly.Item1; - DtPoly neighbourPoly = neighbourTilePoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(neighbourRef, out var neighbourTile, out var neighbourPoly); // Do not advance if the polygon is excluded by the filter. if (!filter.PassFilter(neighbourRef, neighbourTile, neighbourPoly)) @@ -818,9 +812,7 @@ namespace DotRecast.Detour // Get current poly and tile. // The API input has been cheked already, skip checking internal data. long bestRef = bestNode.id; - Tuple tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(bestRef); - DtMeshTile bestTile = tileAndPoly.Item1; - DtPoly bestPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(bestRef, out var bestTile, out var bestPoly); // Get parent poly and tile. long parentRef = 0, grandpaRef = 0; @@ -839,9 +831,7 @@ namespace DotRecast.Detour if (parentRef != 0) { - tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(parentRef); - parentTile = tileAndPoly.Item1; - parentPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(parentRef, out parentTile, out parentPoly); } // decide whether to test raycast to previous nodes @@ -867,9 +857,7 @@ namespace DotRecast.Detour // Get neighbour poly and tile. // The API input has been cheked already, skip checking internal data. - tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(neighbourRef); - DtMeshTile neighbourTile = tileAndPoly.Item1; - DtPoly neighbourPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(neighbourRef, out var neighbourTile, out var neighbourPoly); if (!filter.PassFilter(neighbourRef, neighbourTile, neighbourPoly)) { @@ -1195,9 +1183,7 @@ namespace DotRecast.Detour // Get neighbour poly and tile. // The API input has been cheked already, skip checking internal // data. - Tuple tileAndPolyUns = m_nav.GetTileAndPolyByRefUnsafe(neighbourRef); - DtMeshTile neighbourTile = tileAndPolyUns.Item1; - DtPoly neighbourPoly = tileAndPolyUns.Item2; + m_nav.GetTileAndPolyByRefUnsafe(neighbourRef, out var neighbourTile, out var neighbourPoly); if (!m_query.filter.PassFilter(neighbourRef, neighbourTile, neighbourPoly)) { @@ -1540,7 +1526,7 @@ namespace DotRecast.Detour { List straightPath = new List(); if (!RcVec3f.IsFinite(startPos) || !RcVec3f.IsFinite(endPos) - || null == path || 0 == path.Count || path[0] == 0 || maxStraightPath <= 0) + || null == path || 0 == path.Count || path[0] == 0 || maxStraightPath <= 0) { return Results.InvalidParam>(); } @@ -1833,9 +1819,7 @@ namespace DotRecast.Detour // Get poly and tile. // The API input has been cheked already, skip checking internal data. long curRef = curNode.id; - Tuple tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(curRef); - DtMeshTile curTile = tileAndPoly.Item1; - DtPoly curPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(curRef, out var curTile, out var curPoly); // Collect vertices. int nverts = curPoly.vertCount; @@ -1870,9 +1854,7 @@ namespace DotRecast.Detour { if (link.refs != 0) { - tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(link.refs); - DtMeshTile neiTile = tileAndPoly.Item1; - DtPoly neiPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(link.refs, out var neiTile, out var neiPoly); if (filter.PassFilter(link.refs, neiTile, neiPoly)) { if (nneis < MAX_NEIS) @@ -2206,16 +2188,12 @@ namespace DotRecast.Detour // The API input has been checked already, skip checking internal data. long curRef = startRef; - Tuple tileAndPolyUns = m_nav.GetTileAndPolyByRefUnsafe(curRef); - tile = tileAndPolyUns.Item1; - poly = tileAndPolyUns.Item2; + m_nav.GetTileAndPolyByRefUnsafe(curRef, out tile, out poly); nextTile = prevTile = tile; nextPoly = prevPoly = poly; if (prevRef != 0) { - tileAndPolyUns = m_nav.GetTileAndPolyByRefUnsafe(prevRef); - prevTile = tileAndPolyUns.Item1; - prevPoly = tileAndPolyUns.Item2; + m_nav.GetTileAndPolyByRefUnsafe(prevRef, out prevTile, out prevPoly); } while (curRef != 0) @@ -2277,9 +2255,8 @@ namespace DotRecast.Detour } // Get pointer to the next polygon. - tileAndPolyUns = m_nav.GetTileAndPolyByRefUnsafe(link.refs); - nextTile = tileAndPolyUns.Item1; - nextPoly = tileAndPolyUns.Item2; + m_nav.GetTileAndPolyByRefUnsafe(link.refs, out nextTile, out nextPoly); + // Skip off-mesh connections. if (nextPoly.GetPolyType() == DtPoly.DT_POLYTYPE_OFFMESH_CONNECTION) { @@ -2486,9 +2463,7 @@ namespace DotRecast.Detour // Get poly and tile. // The API input has been cheked already, skip checking internal data. long bestRef = bestNode.id; - Tuple tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(bestRef); - DtMeshTile bestTile = tileAndPoly.Item1; - DtPoly bestPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(bestRef, out var bestTile, out var bestPoly); // Get parent poly and tile. long parentRef = 0; @@ -2501,9 +2476,7 @@ namespace DotRecast.Detour if (parentRef != 0) { - tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(parentRef); - parentTile = tileAndPoly.Item1; - parentPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(parentRef, out parentTile, out parentPoly); } resultRef.Add(bestRef); @@ -2521,9 +2494,7 @@ namespace DotRecast.Detour } // Expand to neighbour - tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(neighbourRef); - DtMeshTile neighbourTile = tileAndPoly.Item1; - DtPoly neighbourPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(neighbourRef, out var neighbourTile, out var neighbourPoly); // Do not advance if the polygon is excluded by the filter. if (!filter.PassFilter(neighbourRef, neighbourTile, neighbourPoly)) @@ -2673,9 +2644,7 @@ namespace DotRecast.Detour // Get poly and tile. // The API input has been cheked already, skip checking internal data. long bestRef = bestNode.id; - Tuple tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(bestRef); - DtMeshTile bestTile = tileAndPoly.Item1; - DtPoly bestPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(bestRef, out var bestTile, out var bestPoly); // Get parent poly and tile. long parentRef = 0; @@ -2688,9 +2657,7 @@ namespace DotRecast.Detour if (parentRef != 0) { - tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(parentRef); - parentTile = tileAndPoly.Item1; - parentPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(parentRef, out parentTile, out parentPoly); } resultRef.Add(bestRef); @@ -2708,9 +2675,7 @@ namespace DotRecast.Detour } // Expand to neighbour - tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(neighbourRef); - DtMeshTile neighbourTile = tileAndPoly.Item1; - DtPoly neighbourPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(neighbourRef, out var neighbourTile, out var neighbourPoly); // Do not advance if the polygon is excluded by the filter. if (!filter.PassFilter(neighbourRef, neighbourTile, neighbourPoly)) @@ -2856,9 +2821,7 @@ namespace DotRecast.Detour // Get poly and tile. // The API input has been cheked already, skip checking internal data. long curRef = curNode.id; - Tuple tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(curRef); - DtMeshTile curTile = tileAndPoly.Item1; - DtPoly curPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(curRef, out var curTile, out var curPoly); for (int i = curTile.polyLinks[curPoly.index]; i != DtNavMesh.DT_NULL_LINK; i = curTile.links[i].next) { @@ -2878,9 +2841,7 @@ namespace DotRecast.Detour } // Expand to neighbour - tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(neighbourRef); - DtMeshTile neighbourTile = tileAndPoly.Item1; - DtPoly neighbourPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(neighbourRef, out var neighbourTile, out var neighbourPoly); // Skip off-mesh connections. if (neighbourPoly.GetPolyType() == DtPoly.DT_POLYTYPE_OFFMESH_CONNECTION) @@ -2948,9 +2909,7 @@ namespace DotRecast.Detour } // Potentially overlapping. - tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(pastRef); - DtMeshTile pastTile = tileAndPoly.Item1; - DtPoly pastPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(pastRef, out var pastTile, out var pastPoly); // Get vertices and test overlap int npb = pastPoly.vertCount; @@ -3053,9 +3012,7 @@ namespace DotRecast.Detour { if (link.refs != 0) { - Tuple tileAndPolyUnsafe = m_nav.GetTileAndPolyByRefUnsafe(link.refs); - DtMeshTile neiTile = tileAndPolyUnsafe.Item1; - DtPoly neiPoly = tileAndPolyUnsafe.Item2; + m_nav.GetTileAndPolyByRefUnsafe(link.refs, out var neiTile, out var neiPoly); if (filter.PassFilter(link.refs, neiTile, neiPoly)) { InsertInterval(ints, link.bmin, link.bmax, link.refs); @@ -3191,9 +3148,7 @@ namespace DotRecast.Detour // Get poly and tile. // The API input has been cheked already, skip checking internal data. long bestRef = bestNode.id; - Tuple tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(bestRef); - DtMeshTile bestTile = tileAndPoly.Item1; - DtPoly bestPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(bestRef, out var bestTile, out var bestPoly); // Get parent poly and tile. long parentRef = 0; @@ -3217,9 +3172,7 @@ namespace DotRecast.Detour { if (link.refs != 0) { - Tuple linkTileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(link.refs); - DtMeshTile neiTile = linkTileAndPoly.Item1; - DtPoly neiPoly = linkTileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(link.refs, out var neiTile, out var neiPoly); if (filter.PassFilter(link.refs, neiTile, neiPoly)) { solid = false; @@ -3280,9 +3233,7 @@ namespace DotRecast.Detour } // Expand to neighbour. - Tuple neighbourTileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(neighbourRef); - DtMeshTile neighbourTile = neighbourTileAndPoly.Item1; - DtPoly neighbourPoly = neighbourTileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(neighbourRef, out var neighbourTile, out var neighbourPoly); // Skip off-mesh connections. if (neighbourPoly.GetPolyType() == DtPoly.DT_POLYTYPE_OFFMESH_CONNECTION) diff --git a/src/DotRecast.Detour/LegacyNavMeshQuery.cs b/src/DotRecast.Detour/LegacyNavMeshQuery.cs index d5ae4b4..8bc6528 100644 --- a/src/DotRecast.Detour/LegacyNavMeshQuery.cs +++ b/src/DotRecast.Detour/LegacyNavMeshQuery.cs @@ -89,9 +89,7 @@ namespace DotRecast.Detour // Get current poly and tile. // The API input has been cheked already, skip checking internal data. long bestRef = bestNode.id; - Tuple tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(bestRef); - DtMeshTile bestTile = tileAndPoly.Item1; - DtPoly bestPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(bestRef, out var bestTile, out var bestPoly); // Get parent poly and tile. long parentRef = 0; @@ -104,9 +102,7 @@ namespace DotRecast.Detour if (parentRef != 0) { - tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(parentRef); - parentTile = tileAndPoly.Item1; - parentPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(parentRef, out parentTile, out parentPoly); } for (int i = bestTile.polyLinks[bestPoly.index]; i != DtNavMesh.DT_NULL_LINK; i = bestTile.links[i].next) @@ -121,10 +117,7 @@ namespace DotRecast.Detour // Get neighbour poly and tile. // The API input has been cheked already, skip checking internal data. - tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(neighbourRef); - DtMeshTile neighbourTile = tileAndPoly.Item1; - DtPoly neighbourPoly = tileAndPoly.Item2; - + m_nav.GetTileAndPolyByRefUnsafe(neighbourRef, out var neighbourTile, out var neighbourPoly); if (!filter.PassFilter(neighbourRef, neighbourTile, neighbourPoly)) { continue; @@ -337,10 +330,7 @@ namespace DotRecast.Detour // Get neighbour poly and tile. // The API input has been cheked already, skip checking internal // data. - Tuple tileAndPolyUns = m_nav.GetTileAndPolyByRefUnsafe(neighbourRef); - DtMeshTile neighbourTile = tileAndPolyUns.Item1; - DtPoly neighbourPoly = tileAndPolyUns.Item2; - + m_nav.GetTileAndPolyByRefUnsafe(neighbourRef, out var neighbourTile, out var neighbourPoly); if (!m_query.filter.PassFilter(neighbourRef, neighbourTile, neighbourPoly)) { continue; @@ -680,9 +670,7 @@ namespace DotRecast.Detour // Get poly and tile. // The API input has been cheked already, skip checking internal data. long bestRef = bestNode.id; - Tuple tileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(bestRef); - DtMeshTile bestTile = tileAndPoly.Item1; - DtPoly bestPoly = tileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(bestRef, out var bestTile, out var bestPoly); // Get parent poly and tile. long parentRef = 0; @@ -706,9 +694,7 @@ namespace DotRecast.Detour { if (link.refs != 0) { - Tuple linkTileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(link.refs); - DtMeshTile neiTile = linkTileAndPoly.Item1; - DtPoly neiPoly = linkTileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(link.refs, out var neiTile, out var neiPoly); if (filter.PassFilter(link.refs, neiTile, neiPoly)) { solid = false; @@ -738,7 +724,7 @@ namespace DotRecast.Detour // Calc distance to the edge. int vj = bestPoly.verts[j] * 3; int vi = bestPoly.verts[i] * 3; - var distSqr = DetourCommon.DistancePtSegSqr2D(centerPos, bestTile.data.verts, vj, vi, out var tseg); + var distSqr = DetourCommon.DistancePtSegSqr2D(centerPos, bestTile.data.verts, vj, vi, out var tseg); // Edge is too far, skip. if (distSqr > radiusSqr) { @@ -768,9 +754,7 @@ namespace DotRecast.Detour } // Expand to neighbour. - Tuple neighbourTileAndPoly = m_nav.GetTileAndPolyByRefUnsafe(neighbourRef); - DtMeshTile neighbourTile = neighbourTileAndPoly.Item1; - DtPoly neighbourPoly = neighbourTileAndPoly.Item2; + m_nav.GetTileAndPolyByRefUnsafe(neighbourRef, out var neighbourTile, out var neighbourPoly); // Skip off-mesh connections. if (neighbourPoly.GetPolyType() == DtPoly.DT_POLYTYPE_OFFMESH_CONNECTION) diff --git a/src/DotRecast.Recast.Demo/Tools/TestNavmeshTool.cs b/src/DotRecast.Recast.Demo/Tools/TestNavmeshTool.cs index 862a771..f998801 100644 --- a/src/DotRecast.Recast.Demo/Tools/TestNavmeshTool.cs +++ b/src/DotRecast.Recast.Demo/Tools/TestNavmeshTool.cs @@ -334,8 +334,7 @@ public class TestNavmeshTool : ITool var epos = RcVec3f.Of(m_epos.x, m_epos.y, m_epos.z); if (m_polys[m_polys.Count - 1] != m_endRef) { - Result result = m_navQuery - .ClosestPointOnPoly(m_polys[m_polys.Count - 1], m_epos); + Result result = m_navQuery.ClosestPointOnPoly(m_polys[m_polys.Count - 1], m_epos); if (result.Succeeded()) { epos = result.result.GetClosest(); @@ -995,8 +994,7 @@ public class TestNavmeshTool : ITool epos = m_epos; if (m_polys[m_polys.Count - 1] != m_endRef) { - Result result = m_navQuery - .ClosestPointOnPoly(m_polys[m_polys.Count - 1], m_epos); + Result result = m_navQuery.ClosestPointOnPoly(m_polys[m_polys.Count - 1], m_epos); if (result.Succeeded()) { epos = result.result.GetClosest();