remove FindNearestPolyResult 1st

This commit is contained in:
ikpil 2023-06-11 13:28:05 +09:00
parent 34e04f010e
commit 64315ca56e
11 changed files with 116 additions and 108 deletions

View File

@ -245,10 +245,13 @@ namespace DotRecast.Detour.Crowd
UpdateAgentParameters(ag, option); UpdateAgentParameters(ag, option);
// Find nearest position on navmesh and place the agent there. // Find nearest position on navmesh and place the agent there.
Result<FindNearestPolyResult> nearestPoly = _navQuery.FindNearestPoly(pos, _ext, _filters[ag.option.queryFilterType]); var status = _navQuery.FindNearestPoly(pos, _ext, _filters[ag.option.queryFilterType], out var refs, out var nearest, out var _);
if (status.Failed())
{
nearest = pos;
refs = 0;
}
var nearest = nearestPoly.Succeeded() ? nearestPoly.result.GetNearestPos() : pos;
long refs = nearestPoly.Succeeded() ? nearestPoly.result.GetNearestRef() : 0L;
ag.corridor.Reset(refs, nearest); ag.corridor.Reset(refs, nearest);
ag.boundary.Reset(); ag.boundary.Reset();
ag.partial = false; ag.partial = false;
@ -462,13 +465,8 @@ namespace DotRecast.Detour.Crowd
{ {
// Current location is not valid, try to reposition. // Current location is not valid, try to reposition.
// TODO: this can snap agents, how to handle that? // TODO: this can snap agents, how to handle that?
Result<FindNearestPolyResult> nearestPoly = _navQuery.FindNearestPoly(ag.npos, _ext, _navQuery.FindNearestPoly(ag.npos, _ext, _filters[ag.option.queryFilterType], out agentRef, out var nearest, out var _);
_filters[ag.option.queryFilterType]); agentPos = nearest;
agentRef = nearestPoly.Succeeded() ? nearestPoly.result.GetNearestRef() : 0L;
if (nearestPoly.Succeeded())
{
agentPos = nearestPoly.result.GetNearestPos();
}
if (agentRef == 0) if (agentRef == 0)
{ {
@ -507,14 +505,8 @@ namespace DotRecast.Detour.Crowd
if (!_navQuery.IsValidPolyRef(ag.targetRef, _filters[ag.option.queryFilterType])) if (!_navQuery.IsValidPolyRef(ag.targetRef, _filters[ag.option.queryFilterType]))
{ {
// Current target is not valid, try to reposition. // Current target is not valid, try to reposition.
Result<FindNearestPolyResult> fnp = _navQuery.FindNearestPoly(ag.targetPos, _ext, _navQuery.FindNearestPoly(ag.targetPos, _ext, _filters[ag.option.queryFilterType], out ag.targetRef, out var nearest, out var _);
_filters[ag.option.queryFilterType]); ag.targetPos = nearest;
ag.targetRef = fnp.Succeeded() ? fnp.result.GetNearestRef() : 0L;
if (fnp.Succeeded())
{
ag.targetPos = fnp.result.GetNearestPos();
}
replan = true; replan = true;
} }

View File

@ -6,30 +6,30 @@ namespace DotRecast.Detour
{ {
public class DtFindNearestPolyQuery : IDtPolyQuery public class DtFindNearestPolyQuery : IDtPolyQuery
{ {
private readonly DtNavMeshQuery query; private readonly DtNavMeshQuery _query;
private readonly RcVec3f center; private readonly RcVec3f _center;
private long nearestRef; private long _nearestRef;
private RcVec3f nearestPt; private RcVec3f _nearestPt;
private bool overPoly; private bool _overPoly;
private float nearestDistanceSqr; private float _nearestDistanceSqr;
public DtFindNearestPolyQuery(DtNavMeshQuery query, RcVec3f center) public DtFindNearestPolyQuery(DtNavMeshQuery query, RcVec3f center)
{ {
this.query = query; this._query = query;
this.center = center; this._center = center;
nearestDistanceSqr = float.MaxValue; _nearestDistanceSqr = float.MaxValue;
nearestPt = center; _nearestPt = center;
} }
public void Process(DtMeshTile tile, DtPoly poly, long refs) public void Process(DtMeshTile tile, DtPoly poly, long refs)
{ {
// Find nearest polygon amongst the nearby polygons. // Find nearest polygon amongst the nearby polygons.
query.ClosestPointOnPoly(refs, center, out var closestPtPoly, out var posOverPoly); _query.ClosestPointOnPoly(refs, _center, out var closestPtPoly, out var posOverPoly);
// If a point is directly over a polygon and closer than // If a point is directly over a polygon and closer than
// climb height, favor that instead of straight line nearest point. // climb height, favor that instead of straight line nearest point.
float d = 0; float d = 0;
RcVec3f diff = center.Subtract(closestPtPoly); RcVec3f diff = _center.Subtract(closestPtPoly);
if (posOverPoly) if (posOverPoly)
{ {
d = Math.Abs(diff.y) - tile.data.header.walkableClimb; d = Math.Abs(diff.y) - tile.data.header.walkableClimb;
@ -40,18 +40,28 @@ namespace DotRecast.Detour
d = RcVec3f.LenSqr(diff); d = RcVec3f.LenSqr(diff);
} }
if (d < nearestDistanceSqr) if (d < _nearestDistanceSqr)
{ {
nearestPt = closestPtPoly; _nearestPt = closestPtPoly;
nearestDistanceSqr = d; _nearestDistanceSqr = d;
nearestRef = refs; _nearestRef = refs;
overPoly = posOverPoly; _overPoly = posOverPoly;
} }
} }
public FindNearestPolyResult Result() public long NearestRef()
{ {
return new FindNearestPolyResult(nearestRef, nearestPt, overPoly); return _nearestRef;
}
public RcVec3f NearestPt()
{
return _nearestPt;
}
public bool OverPoly()
{
return _overPoly;
} }
} }
} }

View File

@ -559,29 +559,36 @@ namespace DotRecast.Detour
return null != height ? Results.Success(height.Value) : Results.InvalidParam<float>(); return null != height ? Results.Success(height.Value) : Results.InvalidParam<float>();
} }
/** /// Finds the polygon nearest to the specified center point.
* Finds the polygon nearest to the specified center point. If center and nearestPt point to an equal position, /// [opt] means the specified parameter can be a null pointer, in that case the output parameter will not be set.
* isOverPoly will be true; however there's also a special case of climb height inside the polygon ///
* /// @param[in] center The center of the search box. [(x, y, z)]
* @param center /// @param[in] halfExtents The search distance along each axis. [(x, y, z)]
* The center of the search box. [(x, y, z)] /// @param[in] filter The polygon filter to apply to the query.
* @param halfExtents /// @param[out] nearestRef The reference id of the nearest polygon. Will be set to 0 if no polygon is found.
* The search distance along each axis. [(x, y, z)] /// @param[out] nearestPt The nearest point on the polygon. Unchanged if no polygon is found. [opt] [(x, y, z)]
* @param filter /// @param[out] isOverPoly Set to true if the point's X/Z coordinate lies inside the polygon, false otherwise. Unchanged if no polygon is found. [opt]
* The polygon filter to apply to the query. /// @returns The status flags for the query.
* @return FindNearestPolyResult containing nearestRef, nearestPt and overPoly public DtStatus FindNearestPoly(RcVec3f center, RcVec3f halfExtents, IDtQueryFilter filter,
*/ out long nearestRef, out RcVec3f nearestPt, out bool isOverPoly)
public Result<FindNearestPolyResult> FindNearestPoly(RcVec3f center, RcVec3f halfExtents, IDtQueryFilter filter)
{ {
nearestRef = 0;
nearestPt = center;
isOverPoly = false;
// 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.Failed()) if (status.Failed())
{ {
return Results.Of<FindNearestPolyResult>(status, ""); return status;
} }
return Results.Success(query.Result()); nearestRef = query.NearestRef();
nearestPt = query.NearestPt();
isOverPoly = query.OverPoly();
return DtStatus.DT_SUCCSESS;
} }
// FIXME: (PP) duplicate? // FIXME: (PP) duplicate?

View File

@ -279,10 +279,10 @@ public class CrowdProfilingTool
private void MoveMob(DtNavMeshQuery navquery, IDtQueryFilter filter, DtCrowdAgent ag, CrowdAgentData crowAgentData) private void MoveMob(DtNavMeshQuery navquery, IDtQueryFilter filter, DtCrowdAgent ag, CrowdAgentData crowAgentData)
{ {
// Move somewhere // Move somewhere
Result<FindNearestPolyResult> nearestPoly = navquery.FindNearestPoly(ag.npos, crowd.GetQueryExtents(), filter); var status = navquery.FindNearestPoly(ag.npos, crowd.GetQueryExtents(), filter, out var nearestRef, out var nearest, out var _);
if (nearestPoly.Succeeded()) if (status.Succeeded())
{ {
var status = navquery.FindRandomPointAroundCircle(nearestPoly.result.GetNearestRef(), crowAgentData.home, zoneRadius * 2f, filter, rnd, status = navquery.FindRandomPointAroundCircle(nearestRef, crowAgentData.home, zoneRadius * 2f, filter, rnd,
out var randomRef, out var randomPt); out var randomRef, out var randomPt);
if (status.Succeeded()) if (status.Succeeded())
{ {
@ -294,10 +294,10 @@ public class CrowdProfilingTool
private void MoveVillager(DtNavMeshQuery navquery, IDtQueryFilter filter, DtCrowdAgent ag, CrowdAgentData crowAgentData) private void MoveVillager(DtNavMeshQuery navquery, IDtQueryFilter filter, DtCrowdAgent ag, CrowdAgentData crowAgentData)
{ {
// Move somewhere close // Move somewhere close
Result<FindNearestPolyResult> nearestPoly = navquery.FindNearestPoly(ag.npos, crowd.GetQueryExtents(), filter); var status = navquery.FindNearestPoly(ag.npos, crowd.GetQueryExtents(), filter, out var nearestRef, out var nearest, out var _);
if (nearestPoly.Succeeded()) if (status.Succeeded())
{ {
var status = navquery.FindRandomPointAroundCircle(nearestPoly.result.GetNearestRef(), crowAgentData.home, zoneRadius * 0.2f, filter, rnd, status = navquery.FindRandomPointAroundCircle(nearestRef, crowAgentData.home, zoneRadius * 0.2f, filter, rnd,
out var randomRef, out var randomPt); out var randomRef, out var randomPt);
if (status.Succeeded()) if (status.Succeeded())
{ {

View File

@ -158,8 +158,7 @@ public class CrowdTool : ITool
{ {
IDtQueryFilter filter = new DtQueryDefaultFilter(); IDtQueryFilter filter = new DtQueryDefaultFilter();
RcVec3f halfExtents = crowd.GetQueryExtents(); RcVec3f halfExtents = crowd.GetQueryExtents();
Result<FindNearestPolyResult> result = navquery.FindNearestPoly(p, halfExtents, filter); navquery.FindNearestPoly(p, halfExtents, filter, out var refs, out var nearest, out var _);
long refs = result.result.GetNearestRef();
if (refs != 0) if (refs != 0)
{ {
Result<int> flags = nav.GetPolyFlags(refs); Result<int> flags = nav.GetPolyFlags(refs);
@ -288,9 +287,7 @@ public class CrowdTool : ITool
} }
else else
{ {
Result<FindNearestPolyResult> result = navquery.FindNearestPoly(p, halfExtents, filter); navquery.FindNearestPoly(p, halfExtents, filter, out m_targetRef, out m_targetPos, out var _);
m_targetRef = result.result.GetNearestRef();
m_targetPos = result.result.GetNearestPos();
if (m_agentDebug.agent != null) if (m_agentDebug.agent != null)
{ {
crowd.RequestMoveTarget(m_agentDebug.agent, m_targetRef, m_targetPos); crowd.RequestMoveTarget(m_agentDebug.agent, m_targetRef, m_targetPos);
@ -801,7 +798,5 @@ public class CrowdTool : ITool
public void HandleClickRay(RcVec3f start, RcVec3f direction, bool shift) public void HandleClickRay(RcVec3f start, RcVec3f direction, bool shift)
{ {
} }
} }

View File

@ -168,7 +168,7 @@ public class TestNavmeshTool : ITool
DtNavMeshQuery m_navQuery = m_sample.GetNavMeshQuery(); DtNavMeshQuery m_navQuery = m_sample.GetNavMeshQuery();
if (m_sposSet) if (m_sposSet)
{ {
m_startRef = m_navQuery.FindNearestPoly(m_spos, m_polyPickExt, m_filter).result?.GetNearestRef() ?? 0; m_navQuery.FindNearestPoly(m_spos, m_polyPickExt, m_filter, out m_startRef, out var _, out var _);
} }
else else
{ {
@ -177,7 +177,7 @@ public class TestNavmeshTool : ITool
if (m_eposSet) if (m_eposSet)
{ {
m_endRef = m_navQuery.FindNearestPoly(m_epos, m_polyPickExt, m_filter).result?.GetNearestRef() ?? 0; m_navQuery.FindNearestPoly(m_epos, m_polyPickExt, m_filter, out m_endRef, out var _, out var _);
} }
else else
{ {

View File

@ -143,10 +143,10 @@ public class AbstractCrowdTest
} }
else else
{ {
Result<FindNearestPolyResult> nearest = query.FindNearestPoly(pos, ext, filter); query.FindNearestPoly(pos, ext, filter, out var refs, out var nearest, out var _);
foreach (DtCrowdAgent ag in crowd.GetActiveAgents()) foreach (DtCrowdAgent ag in crowd.GetActiveAgents())
{ {
crowd.RequestMoveTarget(ag, nearest.result.GetNearestRef(), nearest.result.GetNearestPos()); crowd.RequestMoveTarget(ag, refs, nearest);
} }
} }
} }

View File

@ -34,30 +34,35 @@ public class DynamicNavMeshTest
Task<bool> future = mesh.Build(Task.Factory); Task<bool> future = mesh.Build(Task.Factory);
// wait for build to complete // wait for build to complete
bool _ = future.Result; bool _ = future.Result;
// create new query // create new query
DtNavMeshQuery query = new DtNavMeshQuery(mesh.NavMesh()); DtNavMeshQuery query = new DtNavMeshQuery(mesh.NavMesh());
IDtQueryFilter filter = new DtQueryDefaultFilter(); IDtQueryFilter filter = new DtQueryDefaultFilter();
// find path // find path
FindNearestPolyResult start = query.FindNearestPoly(START_POS, EXTENT, filter).result; query.FindNearestPoly(START_POS, EXTENT, filter, out var startRef, out var startPt, out var _);
FindNearestPolyResult end = query.FindNearestPoly(END_POS, EXTENT, filter).result; query.FindNearestPoly(END_POS, EXTENT, filter, out var endRef, out var endPt, out var _);
List<long> path = query.FindPath(start.GetNearestRef(), end.GetNearestRef(), start.GetNearestPos(),
end.GetNearestPos(), filter, DtNavMeshQuery.DT_FINDPATH_ANY_ANGLE, float.MaxValue).result; List<long> path = query.FindPath(startRef, endRef, startPt, endPt, filter, DtNavMeshQuery.DT_FINDPATH_ANY_ANGLE, float.MaxValue).result;
// check path length without any obstacles // check path length without any obstacles
Assert.That(path.Count, Is.EqualTo(16)); Assert.That(path.Count, Is.EqualTo(16));
// place obstacle // place obstacle
ICollider colldier = new SphereCollider(SPHERE_POS, 20, SampleAreaModifications.SAMPLE_POLYAREA_TYPE_GROUND, 0.1f); ICollider colldier = new SphereCollider(SPHERE_POS, 20, SampleAreaModifications.SAMPLE_POLYAREA_TYPE_GROUND, 0.1f);
long colliderId = mesh.AddCollider(colldier); long colliderId = mesh.AddCollider(colldier);
// update navmesh asynchronously // update navmesh asynchronously
future = mesh.Update(Task.Factory); future = mesh.Update(Task.Factory);
// wait for update to complete // wait for update to complete
_ = future.Result; _ = future.Result;
// create new query // create new query
query = new DtNavMeshQuery(mesh.NavMesh()); query = new DtNavMeshQuery(mesh.NavMesh());
// find path again // find path again
start = query.FindNearestPoly(START_POS, EXTENT, filter).result; query.FindNearestPoly(START_POS, EXTENT, filter, out startRef, out startPt, out var _);
end = query.FindNearestPoly(END_POS, EXTENT, filter).result; query.FindNearestPoly(END_POS, EXTENT, filter, out endRef, out endPt, out var _);
path = query.FindPath(start.GetNearestRef(), end.GetNearestRef(), start.GetNearestPos(), end.GetNearestPos(), filter, path = query.FindPath(startRef, endRef, startPt, endPt, filter, DtNavMeshQuery.DT_FINDPATH_ANY_ANGLE, float.MaxValue).result;
DtNavMeshQuery.DT_FINDPATH_ANY_ANGLE, float.MaxValue).result;
// check path length with obstacles // check path length with obstacles
Assert.That(path.Count, Is.EqualTo(19)); Assert.That(path.Count, Is.EqualTo(19));
// remove obstacle // remove obstacle
@ -68,11 +73,12 @@ public class DynamicNavMeshTest
_ = future.Result; _ = future.Result;
// create new query // create new query
query = new DtNavMeshQuery(mesh.NavMesh()); query = new DtNavMeshQuery(mesh.NavMesh());
// find path one more time // find path one more time
start = query.FindNearestPoly(START_POS, EXTENT, filter).result; query.FindNearestPoly(START_POS, EXTENT, filter, out startRef, out startPt, out var _);
end = query.FindNearestPoly(END_POS, EXTENT, filter).result; query.FindNearestPoly(END_POS, EXTENT, filter, out endRef, out endPt, out var _);
path = query.FindPath(start.GetNearestRef(), end.GetNearestRef(), start.GetNearestPos(), end.GetNearestPos(), filter, path = query.FindPath(startRef, endRef, startPt, endPt, filter, DtNavMeshQuery.DT_FINDPATH_ANY_ANGLE, float.MaxValue).result;
DtNavMeshQuery.DT_FINDPATH_ANY_ANGLE, float.MaxValue).result;
// path length should be back to the initial value // path length should be back to the initial value
Assert.That(path.Count, Is.EqualTo(16)); Assert.That(path.Count, Is.EqualTo(16));
} }

View File

@ -66,15 +66,15 @@ public class UnityAStarPathfindingImporterTest
DtMeshData data = tile.data; DtMeshData data = tile.data;
DtBVNode[] bvNodes = data.bvTree; DtBVNode[] bvNodes = data.bvTree;
data.bvTree = null; // set BV-Tree empty to get 'clear' search poly without BV data.bvTree = null; // set BV-Tree empty to get 'clear' search poly without BV
FindNearestPolyResult clearResult = GetNearestPolys(mesh, position)[0]; // check poly to exists var clearResult = GetNearestPolys(mesh, position)[0]; // check poly to exists
// restore BV-Tree and try search again // restore BV-Tree and try search again
// important aspect in that test: BV result must equals result without BV // important aspect in that test: BV result must equals result without BV
// if poly not found or found other poly - tile bounds is wrong! // if poly not found or found other poly - tile bounds is wrong!
data.bvTree = bvNodes; data.bvTree = bvNodes;
FindNearestPolyResult bvResult = GetNearestPolys(mesh, position)[0]; var bvResult = GetNearestPolys(mesh, position)[0];
Assert.That(bvResult.GetNearestRef(), Is.EqualTo(clearResult.GetNearestRef())); Assert.That(bvResult.refs, Is.EqualTo(clearResult.refs));
} }
private DtNavMesh LoadNavMesh(string filename) private DtNavMesh LoadNavMesh(string filename)
@ -95,24 +95,25 @@ public class UnityAStarPathfindingImporterTest
DtNavMeshQuery query = new DtNavMeshQuery(mesh); DtNavMeshQuery query = new DtNavMeshQuery(mesh);
IDtQueryFilter filter = new DtQueryDefaultFilter(); IDtQueryFilter filter = new DtQueryDefaultFilter();
FindNearestPolyResult[] polys = GetNearestPolys(mesh, startPos, endPos); var polys = GetNearestPolys(mesh, startPos, endPos);
return query.FindPath(polys[0].GetNearestRef(), polys[1].GetNearestRef(), startPos, endPos, filter); return query.FindPath(polys[0].refs, polys[1].refs, startPos, endPos, filter);
} }
private FindNearestPolyResult[] GetNearestPolys(DtNavMesh mesh, params RcVec3f[] positions) private DtPolyPoint[] GetNearestPolys(DtNavMesh mesh, params RcVec3f[] positions)
{ {
DtNavMeshQuery query = new DtNavMeshQuery(mesh); DtNavMeshQuery query = new DtNavMeshQuery(mesh);
IDtQueryFilter filter = new DtQueryDefaultFilter(); IDtQueryFilter filter = new DtQueryDefaultFilter();
RcVec3f extents = RcVec3f.Of(0.1f, 0.1f, 0.1f); RcVec3f extents = RcVec3f.Of(0.1f, 0.1f, 0.1f);
FindNearestPolyResult[] results = new FindNearestPolyResult[positions.Length]; var results = new DtPolyPoint[positions.Length];
for (int i = 0; i < results.Length; i++) for (int i = 0; i < results.Length; i++)
{ {
RcVec3f position = positions[i]; RcVec3f position = positions[i];
Result<FindNearestPolyResult> result = query.FindNearestPoly(position, extents, filter); var status = query.FindNearestPoly(position, extents, filter, out var nearestRef, out var nearest, out var _);
Assert.That(result.Succeeded(), Is.True); Assert.That(status.Succeeded(), Is.True);
Assert.That(result.result.GetNearestPos(), Is.Not.EqualTo(RcVec3f.Zero), "Nearest start position is null!"); Assert.That(nearest, Is.Not.EqualTo(RcVec3f.Zero), "Nearest start position is null!");
results[i] = result.result;
results[i] = new DtPolyPoint(nearestRef, nearest);
} }
return results; return results;

View File

@ -42,12 +42,12 @@ public class FindNearestPolyTest : AbstractDetourTest
for (int i = 0; i < startRefs.Length; i++) for (int i = 0; i < startRefs.Length; i++)
{ {
RcVec3f startPos = startPoss[i]; RcVec3f startPos = startPoss[i];
Result<FindNearestPolyResult> poly = query.FindNearestPoly(startPos, extents, filter); var status = query.FindNearestPoly(startPos, extents, filter, out var nearestRef, out var nearest, out var _);
Assert.That(poly.Succeeded(), Is.True); Assert.That(status.Succeeded(), Is.True);
Assert.That(poly.result.GetNearestRef(), Is.EqualTo(POLY_REFS[i])); Assert.That(nearestRef, Is.EqualTo(POLY_REFS[i]));
for (int v = 0; v < POLY_POS[i].Length; v++) for (int v = 0; v < POLY_POS[i].Length; v++)
{ {
Assert.That(poly.result.GetNearestPos()[v], Is.EqualTo(POLY_POS[i][v]).Within(0.001f)); Assert.That(nearest[v], Is.EqualTo(POLY_POS[i][v]).Within(0.001f));
} }
} }
} }
@ -61,12 +61,12 @@ public class FindNearestPolyTest : AbstractDetourTest
for (int i = 0; i < startRefs.Length; i++) for (int i = 0; i < startRefs.Length; i++)
{ {
RcVec3f startPos = startPoss[i]; RcVec3f startPos = startPoss[i];
Result<FindNearestPolyResult> poly = query.FindNearestPoly(startPos, extents, filter); var status = query.FindNearestPoly(startPos, extents, filter, out var nearestRef, out var nearest, out var _);
Assert.That(poly.Succeeded(), Is.True); Assert.That(status.Succeeded(), Is.True);
Assert.That(poly.result.GetNearestRef(), Is.EqualTo(0L)); Assert.That(nearestRef, Is.EqualTo(0L));
for (int v = 0; v < POLY_POS[i].Length; v++) for (int v = 0; v < POLY_POS[i].Length; v++)
{ {
Assert.That(poly.result.GetNearestPos()[v], Is.EqualTo(startPos[v]).Within(0.001f)); Assert.That(nearest[v], Is.EqualTo(startPos[v]).Within(0.001f));
} }
} }
} }

View File

@ -49,12 +49,9 @@ public class TileCacheFindPathTest : AbstractTileCacheTest
{ {
IDtQueryFilter filter = new DtQueryDefaultFilter(); IDtQueryFilter filter = new DtQueryDefaultFilter();
RcVec3f extents = RcVec3f.Of(2f, 4f, 2f); RcVec3f extents = RcVec3f.Of(2f, 4f, 2f);
Result<FindNearestPolyResult> findPolyStart = query.FindNearestPoly(start, extents, filter); query.FindNearestPoly(start, extents, filter, out var startRef, out var startPos, out var _);
Result<FindNearestPolyResult> findPolyEnd = query.FindNearestPoly(end, extents, filter); query.FindNearestPoly(end, extents, filter, out var endRef, out var endPos, out var _);
long startRef = findPolyStart.result.GetNearestRef();
long endRef = findPolyEnd.result.GetNearestRef();
RcVec3f startPos = findPolyStart.result.GetNearestPos();
RcVec3f endPos = findPolyEnd.result.GetNearestPos();
Result<List<long>> path = query.FindPath(startRef, endRef, startPos, endPos, filter); Result<List<long>> path = query.FindPath(startRef, endRef, startPos, endPos, filter);
int maxStraightPath = 256; int maxStraightPath = 256;
int options = 0; int options = 0;