remove FindRandomPointResult 1st

This commit is contained in:
ikpil 2023-06-10 21:57:39 +09:00
parent fc1f64bcc9
commit 6271dc71d9
16 changed files with 136 additions and 122 deletions

View File

@ -616,7 +616,7 @@ namespace DotRecast.Detour.Crowd
// Partial path, constrain target position inside the // Partial path, constrain target position inside the
// last polygon. // last polygon.
var cr = _navQuery.ClosestPointOnPoly(reqPath[reqPath.Count - 1], ag.targetPos, out reqPos, out var _); var cr = _navQuery.ClosestPointOnPoly(reqPath[reqPath.Count - 1], ag.targetPos, out reqPos, out var _);
if (cr.IsFailed()) if (cr.Failed())
{ {
reqPath = new List<long>(); reqPath = new List<long>();
} }
@ -694,7 +694,7 @@ namespace DotRecast.Detour.Crowd
// _telemetry.RecordPathWaitTime(ag.targetReplanTime); // _telemetry.RecordPathWaitTime(ag.targetReplanTime);
// Poll path queue. // Poll path queue.
DtStatus status = ag.targetPathQueryResult.status; DtStatus status = ag.targetPathQueryResult.status;
if (status.IsFailed()) if (status.Failed())
{ {
// Path find failed, retry if the target location is still // Path find failed, retry if the target location is still
// valid. // valid.
@ -710,7 +710,7 @@ namespace DotRecast.Detour.Crowd
ag.targetReplanTime = 0; ag.targetReplanTime = 0;
} }
else if (status.IsSuccess()) else if (status.Succeeded())
{ {
List<long> path = ag.corridor.GetPath(); List<long> path = ag.corridor.GetPath();
if (0 == path.Count) if (0 == path.Count)
@ -723,7 +723,7 @@ namespace DotRecast.Detour.Crowd
bool valid = true; bool valid = true;
List<long> res = ag.targetPathQueryResult.path; List<long> res = ag.targetPathQueryResult.path;
if (status.IsFailed() || 0 == res.Count) if (status.Failed() || 0 == res.Count)
{ {
valid = false; valid = false;
} }
@ -780,7 +780,7 @@ namespace DotRecast.Detour.Crowd
// Partial path, constrain target position inside // Partial path, constrain target position inside
// the last polygon. // the last polygon.
var cr = _navQuery.ClosestPointOnPoly(res[res.Count - 1], targetPos, out var nearest, out var _); var cr = _navQuery.ClosestPointOnPoly(res[res.Count - 1], targetPos, out var nearest, out var _);
if (cr.IsSuccess()) if (cr.Succeeded())
{ {
targetPos = nearest; targetPos = nearest;
} }

View File

@ -56,21 +56,21 @@ namespace DotRecast.Detour.Crowd
} }
// Handle query in progress. // Handle query in progress.
if (q.result.status.IsInProgress()) if (q.result.status.InProgress())
{ {
Result<int> res = q.navQuery.UpdateSlicedFindPath(iterCount); Result<int> res = q.navQuery.UpdateSlicedFindPath(iterCount);
q.result.status = res.status; q.result.status = res.status;
iterCount -= res.result; iterCount -= res.result;
} }
if (q.result.status.IsSuccess()) if (q.result.status.Succeeded())
{ {
Result<List<long>> path = q.navQuery.FinalizeSlicedFindPath(); Result<List<long>> path = q.navQuery.FinalizeSlicedFindPath();
q.result.status = path.status; q.result.status = path.status;
q.result.path = path.result; q.result.path = path.result;
} }
if (!(q.result.status.IsFailed() || q.result.status.IsSuccess())) if (!(q.result.status.Failed() || q.result.status.Succeeded()))
{ {
queue.AddFirst(q); queue.AddFirst(q);
} }

View File

@ -72,24 +72,24 @@ namespace DotRecast.Detour
m_openList = new DtNodeQueue(); m_openList = new DtNodeQueue();
} }
/** /// Returns random location on navmesh.
* Returns random location on navmesh. Polygons are chosen weighted by area. The search runs in linear related to /// Polygons are chosen weighted by area. The search runs in linear related to number of polygon.
* number of polygon. /// @param[in] filter The polygon filter to apply to the query.
* /// @param[in] frand Function returning a random number [0..1).
* @param filter /// @param[out] randomRef The reference id of the random location.
* The polygon filter to apply to the query. /// @param[out] randomPt The random location.
* @param frand /// @returns The status flags for the query.
* Function returning a random number [0..1). public DtStatus FindRandomPoint(IDtQueryFilter filter, FRand frand, out long randomRef, out RcVec3f randomPt)
* @return Random location
*/
public Result<FindRandomPointResult> FindRandomPoint(IDtQueryFilter filter, FRand frand)
{ {
// Randomly pick one tile. Assume that all tiles cover roughly the same area. randomRef = 0;
randomPt = RcVec3f.Zero;
if (null == filter || null == frand) if (null == filter || null == frand)
{ {
return Results.InvalidParam<FindRandomPointResult>(); return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
} }
// Randomly pick one tile. Assume that all tiles cover roughly the same area.
DtMeshTile tile = null; DtMeshTile tile = null;
float tsum = 0.0f; float tsum = 0.0f;
for (int i = 0; i < m_nav.GetMaxTiles(); i++) for (int i = 0; i < m_nav.GetMaxTiles(); i++)
@ -112,7 +112,7 @@ namespace DotRecast.Detour
if (tile == null) if (tile == null)
{ {
return Results.InvalidParam<FindRandomPointResult>("Tile not found"); return DtStatus.DT_FAILURE;
} }
// Randomly pick one polygon weighted by polygon area. // Randomly pick one polygon weighted by polygon area.
@ -159,7 +159,7 @@ namespace DotRecast.Detour
if (poly == null) if (poly == null)
{ {
return Results.InvalidParam<FindRandomPointResult>("Poly not found"); return DtStatus.DT_FAILURE;
} }
// Randomly pick point on polygon. // Randomly pick point on polygon.
@ -176,7 +176,11 @@ namespace DotRecast.Detour
var pt = DetourCommon.RandomPointInConvexPoly(verts, poly.vertCount, areas, s, t); var pt = DetourCommon.RandomPointInConvexPoly(verts, poly.vertCount, areas, s, t);
ClosestPointOnPoly(polyRef, pt, out var closest, out var _); ClosestPointOnPoly(polyRef, pt, out var closest, out var _);
return Results.Success(new FindRandomPointResult(polyRef, closest));
randomRef = polyRef;
randomPt = closest;
return DtStatus.DT_SUCCSESS;
} }
/** /**
@ -198,7 +202,7 @@ namespace DotRecast.Detour
public Result<FindRandomPointResult> FindRandomPointAroundCircle(long startRef, RcVec3f centerPos, float maxRadius, public Result<FindRandomPointResult> FindRandomPointAroundCircle(long startRef, RcVec3f centerPos, float maxRadius,
IDtQueryFilter filter, FRand frand) IDtQueryFilter filter, FRand frand)
{ {
return FindRandomPointAroundCircle(startRef, centerPos, maxRadius, filter, frand, IPolygonByCircleConstraint.Noop()); return FindRandomPointAroundCircle(startRef, centerPos, maxRadius, filter, frand, NoOpPolygonByCircleConstraint.Noop);
} }
/** /**
@ -219,7 +223,7 @@ namespace DotRecast.Detour
public Result<FindRandomPointResult> FindRandomPointWithinCircle(long startRef, RcVec3f centerPos, float maxRadius, public Result<FindRandomPointResult> FindRandomPointWithinCircle(long startRef, RcVec3f centerPos, float maxRadius,
IDtQueryFilter filter, FRand frand) IDtQueryFilter filter, FRand frand)
{ {
return FindRandomPointAroundCircle(startRef, centerPos, maxRadius, filter, frand, IPolygonByCircleConstraint.Strict()); return FindRandomPointAroundCircle(startRef, centerPos, maxRadius, filter, frand, StrictPolygonByCircleConstraint.Strict);
} }
public Result<FindRandomPointResult> FindRandomPointAroundCircle(long startRef, RcVec3f centerPos, float maxRadius, public Result<FindRandomPointResult> FindRandomPointAroundCircle(long startRef, RcVec3f centerPos, float maxRadius,
@ -416,9 +420,9 @@ namespace DotRecast.Detour
/// @returns The status flags for the query. /// @returns The status flags for the query.
public DtStatus ClosestPointOnPoly(long refs, RcVec3f pos, out RcVec3f closest, out bool posOverPoly) public DtStatus ClosestPointOnPoly(long refs, RcVec3f pos, out RcVec3f closest, out bool posOverPoly)
{ {
closest = RcVec3f.Zero; closest = pos;
posOverPoly = false; posOverPoly = false;
if (!m_nav.IsValidPolyRef(refs) || !RcVec3f.IsFinite(pos)) if (!m_nav.IsValidPolyRef(refs) || !RcVec3f.IsFinite(pos))
{ {
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM; return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
@ -562,7 +566,7 @@ namespace DotRecast.Detour
// Get nearby polygons from proximity grid. // Get nearby polygons from proximity grid.
DtFindNearestPolyQuery query = new DtFindNearestPolyQuery(this, center); DtFindNearestPolyQuery query = new DtFindNearestPolyQuery(this, center);
DtStatus status = QueryPolygons(center, halfExtents, filter, query); DtStatus status = QueryPolygons(center, halfExtents, filter, query);
if (status.IsFailed()) if (status.Failed())
{ {
return Results.Of<FindNearestPolyResult>(status, ""); return Results.Of<FindNearestPolyResult>(status, "");
} }
@ -1083,7 +1087,7 @@ namespace DotRecast.Detour
*/ */
public virtual Result<int> UpdateSlicedFindPath(int maxIter) public virtual Result<int> UpdateSlicedFindPath(int maxIter)
{ {
if (!m_query.status.IsInProgress()) if (!m_query.status.InProgress())
{ {
return Results.Of(m_query.status, 0); return Results.Of(m_query.status, 0);
} }
@ -1322,7 +1326,7 @@ namespace DotRecast.Detour
public virtual Result<List<long>> FinalizeSlicedFindPath() public virtual Result<List<long>> FinalizeSlicedFindPath()
{ {
List<long> path = new List<long>(64); List<long> path = new List<long>(64);
if (m_query.status.IsFailed()) if (m_query.status.Failed())
{ {
// Reset query. // Reset query.
m_query = new DtQueryData(); m_query = new DtQueryData();
@ -1367,7 +1371,7 @@ namespace DotRecast.Detour
return Results.Failure(path); return Results.Failure(path);
} }
if (m_query.status.IsFailed()) if (m_query.status.Failed())
{ {
// Reset query. // Reset query.
m_query = new DtQueryData(); m_query = new DtQueryData();
@ -1487,7 +1491,7 @@ namespace DotRecast.Detour
{ {
var pt = RcVec3f.Lerp(left, right, t); var pt = RcVec3f.Lerp(left, right, t);
stat = AppendVertex(pt, 0, path[i + 1], straightPath, maxStraightPath); stat = AppendVertex(pt, 0, path[i + 1], straightPath, maxStraightPath);
if (!stat.IsInProgress()) if (!stat.InProgress())
{ {
return stat; return stat;
} }
@ -1549,7 +1553,7 @@ namespace DotRecast.Detour
var closestEndPos = closestEndPosRes.result; var closestEndPos = closestEndPosRes.result;
// Add start point. // Add start point.
DtStatus stat = AppendVertex(closestStartPos, DT_STRAIGHTPATH_START, path[0], straightPath, maxStraightPath); DtStatus stat = AppendVertex(closestStartPos, DT_STRAIGHTPATH_START, path[0], straightPath, maxStraightPath);
if (!stat.IsInProgress()) if (!stat.InProgress())
{ {
return Results.Success(straightPath); return Results.Success(straightPath);
} }
@ -1639,7 +1643,7 @@ namespace DotRecast.Detour
{ {
stat = AppendPortals(apexIndex, leftIndex, portalLeft, path, straightPath, maxStraightPath, stat = AppendPortals(apexIndex, leftIndex, portalLeft, path, straightPath, maxStraightPath,
options); options);
if (!stat.IsInProgress()) if (!stat.InProgress())
{ {
return Results.Success(straightPath); return Results.Success(straightPath);
} }
@ -1662,7 +1666,7 @@ namespace DotRecast.Detour
// Append or update vertex // Append or update vertex
stat = AppendVertex(portalApex, flags, refs, straightPath, maxStraightPath); stat = AppendVertex(portalApex, flags, refs, straightPath, maxStraightPath);
if (!stat.IsInProgress()) if (!stat.InProgress())
{ {
return Results.Success(straightPath); return Results.Success(straightPath);
} }
@ -1696,7 +1700,7 @@ namespace DotRecast.Detour
{ {
stat = AppendPortals(apexIndex, rightIndex, portalRight, path, straightPath, stat = AppendPortals(apexIndex, rightIndex, portalRight, path, straightPath,
maxStraightPath, options); maxStraightPath, options);
if (!stat.IsInProgress()) if (!stat.InProgress())
{ {
return Results.Success(straightPath); return Results.Success(straightPath);
} }
@ -1719,7 +1723,7 @@ namespace DotRecast.Detour
// Append or update vertex // Append or update vertex
stat = AppendVertex(portalApex, flags, refs, straightPath, maxStraightPath); stat = AppendVertex(portalApex, flags, refs, straightPath, maxStraightPath);
if (!stat.IsInProgress()) if (!stat.InProgress())
{ {
return Results.Success(straightPath); return Results.Success(straightPath);
} }
@ -1742,7 +1746,7 @@ namespace DotRecast.Detour
{ {
stat = AppendPortals(apexIndex, path.Count - 1, closestEndPos, path, straightPath, maxStraightPath, stat = AppendPortals(apexIndex, path.Count - 1, closestEndPos, path, straightPath, maxStraightPath,
options); options);
if (!stat.IsInProgress()) if (!stat.InProgress())
{ {
return Results.Success(straightPath); return Results.Success(straightPath);
} }

View File

@ -56,19 +56,19 @@ namespace DotRecast.Detour
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsSuccess() public bool Succeeded()
{ {
return 0 != (Value & (DT_SUCCSESS.Value | DT_PARTIAL_RESULT.Value)); return 0 != (Value & (DT_SUCCSESS.Value | DT_PARTIAL_RESULT.Value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsFailed() public bool Failed()
{ {
return 0 != (Value & (DT_FAILURE.Value | DT_INVALID_PARAM.Value)); return 0 != (Value & (DT_FAILURE.Value | DT_INVALID_PARAM.Value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsInProgress() public bool InProgress()
{ {
return 0 != (Value & DT_IN_PROGRESS.Value); return 0 != (Value & DT_IN_PROGRESS.Value);
} }

View File

@ -24,15 +24,5 @@ namespace DotRecast.Detour
public interface IPolygonByCircleConstraint public interface IPolygonByCircleConstraint
{ {
float[] Aply(float[] polyVerts, RcVec3f circleCenter, float radius); float[] Aply(float[] polyVerts, RcVec3f circleCenter, float radius);
public static IPolygonByCircleConstraint Noop()
{
return new NoOpPolygonByCircleConstraint();
}
public static IPolygonByCircleConstraint Strict()
{
return new StrictPolygonByCircleConstraint();
}
} }
} }

View File

@ -230,7 +230,7 @@ namespace DotRecast.Detour
*/ */
public override Result<int> UpdateSlicedFindPath(int maxIter) public override Result<int> UpdateSlicedFindPath(int maxIter)
{ {
if (!m_query.status.IsInProgress()) if (!m_query.status.InProgress())
{ {
return Results.Of(m_query.status, 0); return Results.Of(m_query.status, 0);
} }
@ -467,7 +467,7 @@ namespace DotRecast.Detour
public override Result<List<long>> FinalizeSlicedFindPath() public override Result<List<long>> FinalizeSlicedFindPath()
{ {
List<long> path = new List<long>(64); List<long> path = new List<long>(64);
if (m_query.status.IsFailed()) if (m_query.status.Failed())
{ {
// Reset query. // Reset query.
m_query = new DtQueryData(); m_query = new DtQueryData();
@ -553,7 +553,7 @@ namespace DotRecast.Detour
return Results.Failure(path); return Results.Failure(path);
} }
if (m_query.status.IsFailed()) if (m_query.status.Failed())
{ {
// Reset query. // Reset query.
m_query = new DtQueryData(); m_query = new DtQueryData();

View File

@ -4,6 +4,12 @@ namespace DotRecast.Detour
{ {
public class NoOpPolygonByCircleConstraint : IPolygonByCircleConstraint public class NoOpPolygonByCircleConstraint : IPolygonByCircleConstraint
{ {
public static readonly NoOpPolygonByCircleConstraint Noop = new NoOpPolygonByCircleConstraint();
private NoOpPolygonByCircleConstraint()
{
}
public float[] Aply(float[] polyVerts, RcVec3f circleCenter, float radius) public float[] Aply(float[] polyVerts, RcVec3f circleCenter, float radius)
{ {
return polyVerts; return polyVerts;

View File

@ -22,7 +22,7 @@ using DotRecast.Core;
namespace DotRecast.Detour.QueryResults namespace DotRecast.Detour.QueryResults
{ {
//TODO: (PP) Add comments //TODO: (PP) Add comments
public class FindRandomPointResult public class FindRandomPointResult
{ {
private readonly long randomRef; private readonly long randomRef;

View File

@ -74,12 +74,12 @@ namespace DotRecast.Detour.QueryResults
public bool Failed() public bool Failed()
{ {
return status.IsFailed(); return status.Failed();
} }
public bool Succeeded() public bool Succeeded()
{ {
return status.IsSuccess(); return status.Succeeded();
} }
} }
} }

View File

@ -9,7 +9,27 @@ namespace DotRecast.Detour
public class StrictPolygonByCircleConstraint : IPolygonByCircleConstraint public class StrictPolygonByCircleConstraint : IPolygonByCircleConstraint
{ {
private const int CIRCLE_SEGMENTS = 12; private const int CIRCLE_SEGMENTS = 12;
private static float[] unitCircle; private static readonly float[] UnitCircle = MakeUnitCircle();
public static readonly IPolygonByCircleConstraint Strict = new StrictPolygonByCircleConstraint();
private StrictPolygonByCircleConstraint()
{
}
private static float[] MakeUnitCircle()
{
var temp = new float[CIRCLE_SEGMENTS * 3];
for (int i = 0; i < CIRCLE_SEGMENTS; i++)
{
double a = i * Math.PI * 2 / CIRCLE_SEGMENTS;
temp[3 * i] = (float)Math.Cos(a);
temp[3 * i + 1] = 0;
temp[3 * i + 2] = (float)-Math.Sin(a);
}
return temp;
}
public float[] Aply(float[] verts, RcVec3f center, float radius) public float[] Aply(float[] verts, RcVec3f center, float radius)
{ {
@ -41,26 +61,15 @@ namespace DotRecast.Detour
return intersection; return intersection;
} }
private float[] Circle(RcVec3f center, float radius) private float[] Circle(RcVec3f center, float radius)
{ {
if (unitCircle == null)
{
unitCircle = new float[CIRCLE_SEGMENTS * 3];
for (int i = 0; i < CIRCLE_SEGMENTS; i++)
{
double a = i * Math.PI * 2 / CIRCLE_SEGMENTS;
unitCircle[3 * i] = (float)Math.Cos(a);
unitCircle[3 * i + 1] = 0;
unitCircle[3 * i + 2] = (float)-Math.Sin(a);
}
}
float[] circle = new float[12 * 3]; float[] circle = new float[12 * 3];
for (int i = 0; i < CIRCLE_SEGMENTS * 3; i += 3) for (int i = 0; i < CIRCLE_SEGMENTS * 3; i += 3)
{ {
circle[i] = unitCircle[i] * radius + center.x; circle[i] = UnitCircle[i] * radius + center.x;
circle[i + 1] = center.y; circle[i + 1] = center.y;
circle[i + 2] = unitCircle[i + 2] * radius + center.z; circle[i + 2] = UnitCircle[i + 2] * radius + center.z;
} }
return circle; return circle;

View File

@ -147,10 +147,10 @@ public class CrowdProfilingTool
private RcVec3f? GetMobPosition(DtNavMeshQuery navquery, IDtQueryFilter filter) private RcVec3f? GetMobPosition(DtNavMeshQuery navquery, IDtQueryFilter filter)
{ {
Result<FindRandomPointResult> result = navquery.FindRandomPoint(filter, rnd); var status = navquery.FindRandomPoint(filter, rnd, out var randomRef, out var randomPt);
if (result.Succeeded()) if (status.Succeeded())
{ {
return result.result.GetRandomPt(); return randomPt;
} }
return null; return null;
@ -182,13 +182,13 @@ public class CrowdProfilingTool
float zoneSeparation = zoneRadius * zoneRadius * 16; float zoneSeparation = zoneRadius * zoneRadius * 16;
for (int k = 0; k < 100; k++) for (int k = 0; k < 100; k++)
{ {
Result<FindRandomPointResult> result = navquery.FindRandomPoint(filter, rnd); var status = navquery.FindRandomPoint(filter, rnd, out var randomRef, out var randomPt);
if (result.Succeeded()) if (status.Succeeded())
{ {
bool valid = true; bool valid = true;
foreach (FindRandomPointResult zone in zones) foreach (var zone in zones)
{ {
if (RcVec3f.DistSqr(zone.GetRandomPt(), result.result.GetRandomPt()) < zoneSeparation) if (RcVec3f.DistSqr(zone.GetRandomPt(), randomPt) < zoneSeparation)
{ {
valid = false; valid = false;
break; break;
@ -197,7 +197,7 @@ public class CrowdProfilingTool
if (valid) if (valid)
{ {
zones.Add(result.result); zones.Add(new FindRandomPointResult(randomRef, randomPt));
break; break;
} }
} }

View File

@ -335,7 +335,7 @@ public class TestNavmeshTool : ITool
if (m_polys[m_polys.Count - 1] != m_endRef) if (m_polys[m_polys.Count - 1] != m_endRef)
{ {
var result = m_navQuery.ClosestPointOnPoly(m_polys[m_polys.Count - 1], m_epos, out var closest, out var _); var result = m_navQuery.ClosestPointOnPoly(m_polys[m_polys.Count - 1], m_epos, out var closest, out var _);
if (result.IsSuccess()) if (result.Succeeded())
{ {
epos = closest; epos = closest;
} }
@ -489,8 +489,9 @@ public class TestNavmeshTool : ITool
float dz = m_epos.z - m_spos.z; float dz = m_epos.z - m_spos.z;
float dist = (float)Math.Sqrt(dx * dx + dz * dz); float dist = (float)Math.Sqrt(dx * dx + dz * dz);
IPolygonByCircleConstraint constraint = constrainByCircle IPolygonByCircleConstraint constraint = constrainByCircle
? IPolygonByCircleConstraint.Strict() ? StrictPolygonByCircleConstraint.Strict
: IPolygonByCircleConstraint.Noop(); : NoOpPolygonByCircleConstraint.Noop;
for (int i = 0; i < 200; i++) for (int i = 0; i < 200; i++)
{ {
Result<FindRandomPointResult> result = m_navQuery.FindRandomPointAroundCircle(m_startRef, m_spos, dist, Result<FindRandomPointResult> result = m_navQuery.FindRandomPointAroundCircle(m_startRef, m_spos, dist,
@ -978,12 +979,12 @@ public class TestNavmeshTool : ITool
if (m_toolMode == TestNavmeshToolMode.PATHFIND_SLICED) if (m_toolMode == TestNavmeshToolMode.PATHFIND_SLICED)
{ {
DtNavMeshQuery m_navQuery = m_sample.GetNavMeshQuery(); DtNavMeshQuery m_navQuery = m_sample.GetNavMeshQuery();
if (m_pathFindStatus.IsInProgress()) if (m_pathFindStatus.InProgress())
{ {
m_pathFindStatus = m_navQuery.UpdateSlicedFindPath(1).status; m_pathFindStatus = m_navQuery.UpdateSlicedFindPath(1).status;
} }
if (m_pathFindStatus.IsSuccess()) if (m_pathFindStatus.Succeeded())
{ {
m_polys = m_navQuery.FinalizeSlicedFindPath().result; m_polys = m_navQuery.FinalizeSlicedFindPath().result;
m_straightPath = null; m_straightPath = null;
@ -995,7 +996,7 @@ public class TestNavmeshTool : ITool
if (m_polys[m_polys.Count - 1] != m_endRef) if (m_polys[m_polys.Count - 1] != m_endRef)
{ {
var result = m_navQuery.ClosestPointOnPoly(m_polys[m_polys.Count - 1], m_epos, out var closest, out var _); var result = m_navQuery.ClosestPointOnPoly(m_polys[m_polys.Count - 1], m_epos, out var closest, out var _);
if (result.IsSuccess()) if (result.Succeeded())
{ {
epos = closest; epos = closest;
} }

View File

@ -49,7 +49,7 @@ public class UnityAStarPathfindingImporterTest
RcVec3f startPos = RcVec3f.Of(22.93f, -2.37f, -5.11f); RcVec3f startPos = RcVec3f.Of(22.93f, -2.37f, -5.11f);
RcVec3f endPos = RcVec3f.Of(16.81f, -2.37f, 25.52f); RcVec3f endPos = RcVec3f.Of(16.81f, -2.37f, 25.52f);
Result<List<long>> path = FindPath(mesh, startPos, endPos); Result<List<long>> path = FindPath(mesh, startPos, endPos);
Assert.That(path.status.IsSuccess(), Is.True); Assert.That(path.status.Succeeded(), Is.True);
Assert.That(path.result.Count, Is.EqualTo(15)); Assert.That(path.result.Count, Is.EqualTo(15));
SaveMesh(mesh, "v4_1_16"); SaveMesh(mesh, "v4_1_16");
} }

View File

@ -160,7 +160,7 @@ public class FindPathTest : AbstractDetourTest
var endPos = endPoss[i]; var endPos = endPoss[i];
query.InitSlicedFindPath(startRef, endRef, startPos, endPos, filter, DtNavMeshQuery.DT_FINDPATH_ANY_ANGLE); query.InitSlicedFindPath(startRef, endRef, startPos, endPos, filter, DtNavMeshQuery.DT_FINDPATH_ANY_ANGLE);
DtStatus status = DtStatus.DT_IN_PROGRESS; DtStatus status = DtStatus.DT_IN_PROGRESS;
while (status.IsInProgress()) while (status.InProgress())
{ {
Result<int> res = query.UpdateSlicedFindPath(10); Result<int> res = query.UpdateSlicedFindPath(10);
status = res.status; status = res.status;

View File

@ -24,14 +24,14 @@ namespace DotRecast.Detour.Test;
[Parallelizable] [Parallelizable]
public class PolygonByCircleConstraintTest public class PolygonByCircleConstraintTest
{ {
private readonly IPolygonByCircleConstraint constraint = new StrictPolygonByCircleConstraint(); private readonly IPolygonByCircleConstraint _constraint = StrictPolygonByCircleConstraint.Strict;
[Test] [Test]
public void ShouldHandlePolygonFullyInsideCircle() public void ShouldHandlePolygonFullyInsideCircle()
{ {
float[] polygon = { -2, 0, 2, 2, 0, 2, 2, 0, -2, -2, 0, -2 }; float[] polygon = { -2, 0, 2, 2, 0, 2, 2, 0, -2, -2, 0, -2 };
RcVec3f center = RcVec3f.Of(1, 0, 1); RcVec3f center = RcVec3f.Of(1, 0, 1);
float[] constrained = constraint.Aply(polygon, center, 6); float[] constrained = _constraint.Aply(polygon, center, 6);
Assert.That(constrained, Is.EqualTo(polygon)); Assert.That(constrained, Is.EqualTo(polygon));
} }
@ -43,7 +43,7 @@ public class PolygonByCircleConstraintTest
float[] polygon = { -2, 0, 2, 2, 0, 2, 2, 0, -2, -2, 0, -2 }; float[] polygon = { -2, 0, 2, 2, 0, 2, 2, 0, -2, -2, 0, -2 };
RcVec3f center = RcVec3f.Of(2, 0, 0); RcVec3f center = RcVec3f.Of(2, 0, 0);
float[] constrained = constraint.Aply(polygon, center, 3); float[] constrained = _constraint.Aply(polygon, center, 3);
Assert.That(constrained.Length, Is.EqualTo(expectedSize)); Assert.That(constrained.Length, Is.EqualTo(expectedSize));
Assert.That(constrained, Is.SupersetOf(new[] { 2f, 0f, 2f, 2f, 0f, -2f })); Assert.That(constrained, Is.SupersetOf(new[] { 2f, 0f, 2f, 2f, 0f, -2f }));
} }
@ -54,7 +54,7 @@ public class PolygonByCircleConstraintTest
int expectedSize = 12 * 3; int expectedSize = 12 * 3;
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 }; float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
RcVec3f center = RcVec3f.Of(-1, 0, -1); RcVec3f center = RcVec3f.Of(-1, 0, -1);
float[] constrained = constraint.Aply(polygon, center, 2); float[] constrained = _constraint.Aply(polygon, center, 2);
Assert.That(constrained.Length, Is.EqualTo(expectedSize)); Assert.That(constrained.Length, Is.EqualTo(expectedSize));
@ -72,7 +72,7 @@ public class PolygonByCircleConstraintTest
int expectedSize = 9 * 3; int expectedSize = 9 * 3;
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 }; float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
RcVec3f center = RcVec3f.Of(-2, 0, -1); RcVec3f center = RcVec3f.Of(-2, 0, -1);
float[] constrained = constraint.Aply(polygon, center, 3); float[] constrained = _constraint.Aply(polygon, center, 3);
Assert.That(constrained.Length, Is.EqualTo(expectedSize)); Assert.That(constrained.Length, Is.EqualTo(expectedSize));
Assert.That(constrained, Is.SupersetOf(new[] { -2f, 0f, -4f, -4f, 0f, 0f, -3.4641016f, 0.0f, 1.6076951f, -2.0f, 0.0f, 2.0f })); Assert.That(constrained, Is.SupersetOf(new[] { -2f, 0f, -4f, -4f, 0f, 0f, -3.4641016f, 0.0f, 1.6076951f, -2.0f, 0.0f, 2.0f }));
@ -84,7 +84,7 @@ public class PolygonByCircleConstraintTest
int expectedSize = 7 * 3; int expectedSize = 7 * 3;
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 }; float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
RcVec3f center = RcVec3f.Of(4, 0, 0); RcVec3f center = RcVec3f.Of(4, 0, 0);
float[] constrained = constraint.Aply(polygon, center, 4); float[] constrained = _constraint.Aply(polygon, center, 4);
Assert.That(constrained.Length, Is.EqualTo(expectedSize)); Assert.That(constrained.Length, Is.EqualTo(expectedSize));
Assert.That(constrained, Is.SupersetOf(new[] { 1.5358982f, 0f, 3f, 2f, 0f, 3f, 3f, 0f, -3f })); Assert.That(constrained, Is.SupersetOf(new[] { 1.5358982f, 0f, 3f, 2f, 0f, 3f, 3f, 0f, -3f }));

View File

@ -35,9 +35,9 @@ public class RandomPointTest : AbstractDetourTest
IDtQueryFilter filter = new DtQueryDefaultFilter(); IDtQueryFilter filter = new DtQueryDefaultFilter();
for (int i = 0; i < 1000; i++) for (int i = 0; i < 1000; i++)
{ {
Result<FindRandomPointResult> point = query.FindRandomPoint(filter, f); var status = query.FindRandomPoint(filter, f, out var randomRef, out var randomPt);
Assert.That(point.Succeeded(), Is.True); Assert.That(status.Succeeded(), Is.True);
Tuple<DtMeshTile, DtPoly> tileAndPoly = navmesh.GetTileAndPolyByRef(point.result.GetRandomRef()).result; Tuple<DtMeshTile, DtPoly> tileAndPoly = navmesh.GetTileAndPolyByRef(randomRef).result;
float[] bmin = new float[2]; float[] bmin = new float[2];
float[] bmax = new float[2]; float[] bmax = new float[2];
for (int j = 0; j < tileAndPoly.Item2.vertCount; j++) for (int j = 0; j < tileAndPoly.Item2.vertCount; j++)
@ -49,10 +49,10 @@ public class RandomPointTest : AbstractDetourTest
bmax[1] = j == 0 ? tileAndPoly.Item1.data.verts[v + 2] : Math.Max(bmax[1], tileAndPoly.Item1.data.verts[v + 2]); bmax[1] = j == 0 ? tileAndPoly.Item1.data.verts[v + 2] : Math.Max(bmax[1], tileAndPoly.Item1.data.verts[v + 2]);
} }
Assert.That(point.result.GetRandomPt().x >= bmin[0], Is.True); Assert.That(randomPt.x >= bmin[0], Is.True);
Assert.That(point.result.GetRandomPt().x <= bmax[0], Is.True); Assert.That(randomPt.x <= bmax[0], Is.True);
Assert.That(point.result.GetRandomPt().z >= bmin[1], Is.True); Assert.That(randomPt.z >= bmin[1], Is.True);
Assert.That(point.result.GetRandomPt().z <= bmax[1], Is.True); Assert.That(randomPt.z <= bmax[1], Is.True);
} }
} }
@ -61,14 +61,15 @@ public class RandomPointTest : AbstractDetourTest
{ {
FRand f = new FRand(1); FRand f = new FRand(1);
IDtQueryFilter filter = new DtQueryDefaultFilter(); IDtQueryFilter filter = new DtQueryDefaultFilter();
FindRandomPointResult point = query.FindRandomPoint(filter, f).result; query.FindRandomPoint(filter, f, out var randomRef, out var randomPt);
for (int i = 0; i < 1000; i++) for (int i = 0; i < 1000; i++)
{ {
Result<FindRandomPointResult> result = query.FindRandomPointAroundCircle(point.GetRandomRef(), point.GetRandomPt(), Result<FindRandomPointResult> result = query.FindRandomPointAroundCircle(randomRef, randomPt, 5f, filter, f);
5f, filter, f);
Assert.That(result.Failed(), Is.False); Assert.That(result.Failed(), Is.False);
point = result.result;
Tuple<DtMeshTile, DtPoly> tileAndPoly = navmesh.GetTileAndPolyByRef(point.GetRandomRef()).result; randomRef = result.result.GetRandomRef();
randomPt = result.result.GetRandomPt();
Tuple<DtMeshTile, DtPoly> tileAndPoly = navmesh.GetTileAndPolyByRef(randomRef).result;
float[] bmin = new float[2]; float[] bmin = new float[2];
float[] bmax = new float[2]; float[] bmax = new float[2];
for (int j = 0; j < tileAndPoly.Item2.vertCount; j++) for (int j = 0; j < tileAndPoly.Item2.vertCount; j++)
@ -80,10 +81,10 @@ public class RandomPointTest : AbstractDetourTest
bmax[1] = j == 0 ? tileAndPoly.Item1.data.verts[v + 2] : Math.Max(bmax[1], tileAndPoly.Item1.data.verts[v + 2]); bmax[1] = j == 0 ? tileAndPoly.Item1.data.verts[v + 2] : Math.Max(bmax[1], tileAndPoly.Item1.data.verts[v + 2]);
} }
Assert.That(point.GetRandomPt().x >= bmin[0], Is.True); Assert.That(randomPt.x >= bmin[0], Is.True);
Assert.That(point.GetRandomPt().x <= bmax[0], Is.True); Assert.That(randomPt.x <= bmax[0], Is.True);
Assert.That(point.GetRandomPt().z >= bmin[1], Is.True); Assert.That(randomPt.z >= bmin[1], Is.True);
Assert.That(point.GetRandomPt().z <= bmax[1], Is.True); Assert.That(randomPt.z <= bmax[1], Is.True);
} }
} }
@ -92,16 +93,18 @@ public class RandomPointTest : AbstractDetourTest
{ {
FRand f = new FRand(1); FRand f = new FRand(1);
IDtQueryFilter filter = new DtQueryDefaultFilter(); IDtQueryFilter filter = new DtQueryDefaultFilter();
FindRandomPointResult point = query.FindRandomPoint(filter, f).result; query.FindRandomPoint(filter, f, out var randomRef, out var randomPt);
float radius = 5f; float radius = 5f;
for (int i = 0; i < 1000; i++) for (int i = 0; i < 1000; i++)
{ {
Result<FindRandomPointResult> result = query.FindRandomPointWithinCircle(point.GetRandomRef(), point.GetRandomPt(), Result<FindRandomPointResult> result = query.FindRandomPointWithinCircle(randomRef, randomPt, radius, filter, f);
radius, filter, f);
Assert.That(result.Failed(), Is.False); Assert.That(result.Failed(), Is.False);
float distance = RcVec3f.Dist2D(point.GetRandomPt(), result.result.GetRandomPt());
float distance = RcVec3f.Dist2D(randomPt, result.result.GetRandomPt());
Assert.That(distance <= radius, Is.True); Assert.That(distance <= radius, Is.True);
point = result.result;
randomRef = result.result.GetRandomRef();
randomPt = result.result.GetRandomPt();
} }
} }
@ -110,33 +113,34 @@ public class RandomPointTest : AbstractDetourTest
{ {
FRand f = new FRand(1); FRand f = new FRand(1);
IDtQueryFilter filter = new DtQueryDefaultFilter(); IDtQueryFilter filter = new DtQueryDefaultFilter();
FindRandomPointResult point = query.FindRandomPoint(filter, f).result; query.FindRandomPoint(filter, f, out var randomRef, out var randomPt);
float radius = 5f; float radius = 5f;
// jvm warmup // jvm warmup
for (int i = 0; i < 1000; i++) for (int i = 0; i < 1000; i++)
{ {
query.FindRandomPointAroundCircle(point.GetRandomRef(), point.GetRandomPt(), radius, filter, f); query.FindRandomPointAroundCircle(randomRef, randomPt, radius, filter, f);
} }
for (int i = 0; i < 1000; i++) for (int i = 0; i < 1000; i++)
{ {
query.FindRandomPointWithinCircle(point.GetRandomRef(), point.GetRandomPt(), radius, filter, f); query.FindRandomPointWithinCircle(randomRef, randomPt, radius, filter, f);
} }
long t1 = RcFrequency.Ticks; long t1 = RcFrequency.Ticks;
for (int i = 0; i < 10000; i++) for (int i = 0; i < 10000; i++)
{ {
query.FindRandomPointAroundCircle(point.GetRandomRef(), point.GetRandomPt(), radius, filter, f); query.FindRandomPointAroundCircle(randomRef, randomPt, radius, filter, f);
} }
long t2 = RcFrequency.Ticks; long t2 = RcFrequency.Ticks;
for (int i = 0; i < 10000; i++) for (int i = 0; i < 10000; i++)
{ {
query.FindRandomPointWithinCircle(point.GetRandomRef(), point.GetRandomPt(), radius, filter, f); query.FindRandomPointWithinCircle(randomRef, randomPt, radius, filter, f);
} }
long t3 = RcFrequency.Ticks; long t3 = RcFrequency.Ticks;
Console.WriteLine("Random point around circle: " + (t2 - t1) / TimeSpan.TicksPerMillisecond + "ms"); Console.WriteLine("Random point around circle: " + (t2 - t1) / TimeSpan.TicksPerMillisecond + "ms");
Console.WriteLine("Random point within circle: " + (t3 - t2) / TimeSpan.TicksPerMillisecond + "ms"); Console.WriteLine("Random point within circle: " + (t3 - t2) / TimeSpan.TicksPerMillisecond + "ms");
} }
} }