diff --git a/src/DotRecast.Detour.Crowd/DtCrowd.cs b/src/DotRecast.Detour.Crowd/DtCrowd.cs index 64ac1a4..6bb0b3d 100644 --- a/src/DotRecast.Detour.Crowd/DtCrowd.cs +++ b/src/DotRecast.Detour.Crowd/DtCrowd.cs @@ -615,12 +615,8 @@ namespace DotRecast.Detour.Crowd { // Partial path, constrain target position inside the // last polygon. - Result cr = _navQuery.ClosestPointOnPoly(reqPath[reqPath.Count - 1], ag.targetPos); - if (cr.Succeeded()) - { - reqPos = cr.result.GetClosest(); - } - else + var cr = _navQuery.ClosestPointOnPoly(reqPath[reqPath.Count - 1], ag.targetPos, out reqPos, out var _); + if (cr.IsFailed()) { reqPath = new List(); } @@ -783,10 +779,10 @@ namespace DotRecast.Detour.Crowd { // Partial path, constrain target position inside // the last polygon. - Result cr = _navQuery.ClosestPointOnPoly(res[res.Count - 1], targetPos); - if (cr.Succeeded()) + var cr = _navQuery.ClosestPointOnPoly(res[res.Count - 1], targetPos, out var nearest, out var _); + if (cr.IsSuccess()) { - targetPos = cr.result.GetClosest(); + targetPos = nearest; } else { diff --git a/src/DotRecast.Detour/DtFindNearestPolyQuery.cs b/src/DotRecast.Detour/DtFindNearestPolyQuery.cs index 5a0a899..14c6f2f 100644 --- a/src/DotRecast.Detour/DtFindNearestPolyQuery.cs +++ b/src/DotRecast.Detour/DtFindNearestPolyQuery.cs @@ -24,9 +24,7 @@ namespace DotRecast.Detour public void Process(DtMeshTile tile, DtPoly poly, long refs) { // Find nearest polygon amongst the nearby polygons. - Result closest = query.ClosestPointOnPoly(refs, center); - bool posOverPoly = closest.result.IsPosOverPoly(); - var closestPtPoly = closest.result.GetClosest(); + query.ClosestPointOnPoly(refs, center, out var closestPtPoly, out var posOverPoly); // If a point is directly over a polygon and closer than // climb height, favor that instead of straight line nearest point. diff --git a/src/DotRecast.Detour/DtNavMesh.cs b/src/DotRecast.Detour/DtNavMesh.cs index c3d65a7..4c8761b 100644 --- a/src/DotRecast.Detour/DtNavMesh.cs +++ b/src/DotRecast.Detour/DtNavMesh.cs @@ -1301,18 +1301,21 @@ namespace DotRecast.Detour return closest.y; } - public ClosestPointOnPolyResult ClosestPointOnPoly(long refs, RcVec3f pos) + public void ClosestPointOnPoly(long refs, RcVec3f pos, out RcVec3f closest, out bool posOverPoly) { GetTileAndPolyByRefUnsafe(refs, out var tile, out var poly); - RcVec3f closest = new RcVec3f(); closest = pos; + float? h = GetPolyHeight(tile, poly, pos); if (null != h) { closest.y = h.Value; - return new ClosestPointOnPolyResult(true, closest); + posOverPoly = true; + return; } + posOverPoly = false; + // Off-mesh connections don't have detail polygons. if (poly.GetPolyType() == DtPoly.DT_POLYTYPE_OFFMESH_CONNECTION) { @@ -1320,12 +1323,13 @@ namespace DotRecast.Detour var v0 = new RcVec3f { x = tile.data.verts[i], y = tile.data.verts[i + 1], z = tile.data.verts[i + 2] }; i = poly.verts[1] * 3; var v1 = new RcVec3f { x = tile.data.verts[i], y = tile.data.verts[i + 1], z = tile.data.verts[i + 2] }; - var distSqr = DetourCommon.DistancePtSegSqr2D(pos, v0, v1, out var t); - return new ClosestPointOnPolyResult(false, RcVec3f.Lerp(v0, v1, t)); + DetourCommon.DistancePtSegSqr2D(pos, v0, v1, out var t); + closest = RcVec3f.Lerp(v0, v1, t); + return; } // Outside poly that is not an offmesh connection. - return new ClosestPointOnPolyResult(false, ClosestPointOnDetailEdges(tile, poly, pos, true)); + closest = ClosestPointOnDetailEdges(tile, poly, pos, true); } FindNearestPolyResult FindNearestPolyInTile(DtMeshTile tile, RcVec3f center, RcVec3f extents) @@ -1345,9 +1349,7 @@ namespace DotRecast.Detour { long refs = polys[i]; float d; - ClosestPointOnPolyResult cpp = ClosestPointOnPoly(refs, center); - bool posOverPoly = cpp.IsPosOverPoly(); - RcVec3f closestPtPoly = cpp.GetClosest(); + ClosestPointOnPoly(refs, center, out var closestPtPoly, out var posOverPoly); // If a point is directly over a polygon and closer than // climb height, favor that instead of straight line nearest point. diff --git a/src/DotRecast.Detour/DtNavMeshQuery.cs b/src/DotRecast.Detour/DtNavMeshQuery.cs index 581ca4a..862a719 100644 --- a/src/DotRecast.Detour/DtNavMeshQuery.cs +++ b/src/DotRecast.Detour/DtNavMeshQuery.cs @@ -175,8 +175,8 @@ namespace DotRecast.Detour float t = frand.Next(); var pt = DetourCommon.RandomPointInConvexPoly(verts, poly.vertCount, areas, s, t); - ClosestPointOnPolyResult closest = ClosestPointOnPoly(polyRef, pt).result; - return Results.Success(new FindRandomPointResult(polyRef, closest.GetClosest())); + ClosestPointOnPoly(polyRef, pt, out var closest, out var _); + return Results.Success(new FindRandomPointResult(polyRef, closest)); } /** @@ -395,8 +395,8 @@ namespace DotRecast.Detour float[] areas = new float[randomPolyVerts.Length / 3]; RcVec3f pt = DetourCommon.RandomPointInConvexPoly(randomPolyVerts, randomPolyVerts.Length / 3, areas, s, t); - ClosestPointOnPolyResult closest = ClosestPointOnPoly(randomPolyRef, pt).result; - return Results.Success(new FindRandomPointResult(randomPolyRef, closest.GetClosest())); + ClosestPointOnPoly(randomPolyRef, pt, out var closest, out var _); + return Results.Success(new FindRandomPointResult(randomPolyRef, closest)); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -414,14 +414,18 @@ namespace DotRecast.Detour /// @param[out] closest /// @param[out] posOverPoly /// @returns The status flags for the query. - public Result ClosestPointOnPoly(long refs, RcVec3f pos) + public DtStatus ClosestPointOnPoly(long refs, RcVec3f pos, out RcVec3f closest, out bool posOverPoly) { + closest = RcVec3f.Zero; + posOverPoly = false; + if (!m_nav.IsValidPolyRef(refs) || !RcVec3f.IsFinite(pos)) { - return Results.InvalidParam(); + return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM; } - return Results.Success(m_nav.ClosestPointOnPoly(refs, pos)); + m_nav.ClosestPointOnPoly(refs, pos, out closest, out posOverPoly); + return DtStatus.DT_SUCCSESS; } /// @par @@ -1005,20 +1009,17 @@ namespace DotRecast.Detour * query options (see: #FindPathOptions) * @return */ - public DtStatus InitSlicedFindPath(long startRef, long endRef, RcVec3f startPos, RcVec3f endPos, IDtQueryFilter filter, - int options) + public DtStatus InitSlicedFindPath(long startRef, long endRef, RcVec3f startPos, RcVec3f endPos, IDtQueryFilter filter, int options) { return InitSlicedFindPath(startRef, endRef, startPos, endPos, filter, options, new DefaultQueryHeuristic(), -1.0f); } - public DtStatus InitSlicedFindPath(long startRef, long endRef, RcVec3f startPos, RcVec3f endPos, IDtQueryFilter filter, - int options, float raycastLimit) + public DtStatus InitSlicedFindPath(long startRef, long endRef, RcVec3f startPos, RcVec3f endPos, IDtQueryFilter filter, int options, float raycastLimit) { return InitSlicedFindPath(startRef, endRef, startPos, endPos, filter, options, new DefaultQueryHeuristic(), raycastLimit); } - public DtStatus InitSlicedFindPath(long startRef, long endRef, RcVec3f startPos, RcVec3f endPos, IDtQueryFilter filter, - int options, IQueryHeuristic heuristic, float raycastLimit) + public DtStatus InitSlicedFindPath(long startRef, long endRef, RcVec3f startPos, RcVec3f endPos, IDtQueryFilter filter, int options, IQueryHeuristic heuristic, float raycastLimit) { // Init path state. m_query = new DtQueryData(); diff --git a/src/DotRecast.Detour/QueryResults/ClosestPointOnPolyResult.cs b/src/DotRecast.Detour/QueryResults/ClosestPointOnPolyResult.cs deleted file mode 100644 index 415e092..0000000 --- a/src/DotRecast.Detour/QueryResults/ClosestPointOnPolyResult.cs +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright (c) 2009-2010 Mikko Mononen memon@inside.org -recast4j copyright (c) 2015-2019 Piotr Piastucki piotr@jtilia.org -DotRecast Copyright (c) 2023 Choi Ikpil ikpil@naver.com - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. -*/ - -using DotRecast.Core; - -namespace DotRecast.Detour.QueryResults -{ - public class ClosestPointOnPolyResult - { - private readonly bool posOverPoly; - private readonly RcVec3f closest; - - public ClosestPointOnPolyResult(bool posOverPoly, RcVec3f closest) - { - this.posOverPoly = posOverPoly; - this.closest = closest; - } - - /** Returns true if the position is over the polygon. */ - public bool IsPosOverPoly() - { - return posOverPoly; - } - - /** Returns the closest point on the polygon. [(x, y, z)] */ - public RcVec3f GetClosest() - { - return closest; - } - } -} \ No newline at end of file diff --git a/src/DotRecast.Detour/QueryResults/Result.cs b/src/DotRecast.Detour/QueryResults/Result.cs index 598724b..ba326ec 100644 --- a/src/DotRecast.Detour/QueryResults/Result.cs +++ b/src/DotRecast.Detour/QueryResults/Result.cs @@ -37,11 +37,6 @@ namespace DotRecast.Detour.QueryResults return new Result(default, DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM, null); } - public static Result Failure(string message) - { - return new Result(default, DtStatus.DT_FAILURE, message); - } - public static Result InvalidParam(string message) { return new Result(default, DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM, message); @@ -52,11 +47,6 @@ namespace DotRecast.Detour.QueryResults return new Result(result, DtStatus.DT_FAILURE, null); } - public static Result Partial(T result) - { - return new Result(default, DtStatus.DT_PARTIAL_RESULT, null); - } - public static Result Of(DtStatus status, string message) { return new Result(default, status, message); diff --git a/src/DotRecast.Recast.Demo/Tools/TestNavmeshTool.cs b/src/DotRecast.Recast.Demo/Tools/TestNavmeshTool.cs index ffd3a43..407ef41 100644 --- a/src/DotRecast.Recast.Demo/Tools/TestNavmeshTool.cs +++ b/src/DotRecast.Recast.Demo/Tools/TestNavmeshTool.cs @@ -195,8 +195,8 @@ public class TestNavmeshTool : ITool { List polys = new(m_polys); // Iterate over the path to find smooth path on the detail mesh surface. - RcVec3f iterPos = m_navQuery.ClosestPointOnPoly(m_startRef, m_spos).result.GetClosest(); - RcVec3f targetPos = m_navQuery.ClosestPointOnPoly(polys[polys.Count - 1], m_epos).result.GetClosest(); + m_navQuery.ClosestPointOnPoly(m_startRef, m_spos, out var iterPos, out var _); + m_navQuery.ClosestPointOnPoly(polys[polys.Count - 1], m_epos, out var targetPos, out var _); float STEP_SIZE = 0.5f; float SLOP = 0.01f; @@ -334,10 +334,10 @@ 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); - if (result.Succeeded()) + var result = m_navQuery.ClosestPointOnPoly(m_polys[m_polys.Count - 1], m_epos, out var closest, out var _); + if (result.IsSuccess()) { - epos = result.result.GetClosest(); + epos = closest; } } @@ -994,10 +994,10 @@ 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); - if (result.Succeeded()) + var result = m_navQuery.ClosestPointOnPoly(m_polys[m_polys.Count - 1], m_epos, out var closest, out var _); + if (result.IsSuccess()) { - epos = result.result.GetClosest(); + epos = closest; } }