forked from mirror/DotRecast
67 lines
1.8 KiB
C#
67 lines
1.8 KiB
C#
using System;
|
|
using DotRecast.Core;
|
|
using DotRecast.Detour.QueryResults;
|
|
|
|
namespace DotRecast.Detour
|
|
{
|
|
public class DtFindNearestPolyQuery : IDtPolyQuery
|
|
{
|
|
private readonly DtNavMeshQuery _query;
|
|
private readonly RcVec3f _center;
|
|
private long _nearestRef;
|
|
private RcVec3f _nearestPt;
|
|
private bool _overPoly;
|
|
private float _nearestDistanceSqr;
|
|
|
|
public DtFindNearestPolyQuery(DtNavMeshQuery query, RcVec3f center)
|
|
{
|
|
this._query = query;
|
|
this._center = center;
|
|
_nearestDistanceSqr = float.MaxValue;
|
|
_nearestPt = center;
|
|
}
|
|
|
|
public void Process(DtMeshTile tile, DtPoly poly, long refs)
|
|
{
|
|
// Find nearest polygon amongst the nearby polygons.
|
|
_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.
|
|
float d = 0;
|
|
RcVec3f diff = _center.Subtract(closestPtPoly);
|
|
if (posOverPoly)
|
|
{
|
|
d = Math.Abs(diff.y) - tile.data.header.walkableClimb;
|
|
d = d > 0 ? d * d : 0;
|
|
}
|
|
else
|
|
{
|
|
d = RcVec3f.LenSqr(diff);
|
|
}
|
|
|
|
if (d < _nearestDistanceSqr)
|
|
{
|
|
_nearestPt = closestPtPoly;
|
|
_nearestDistanceSqr = d;
|
|
_nearestRef = refs;
|
|
_overPoly = posOverPoly;
|
|
}
|
|
}
|
|
|
|
public long NearestRef()
|
|
{
|
|
return _nearestRef;
|
|
}
|
|
|
|
public RcVec3f NearestPt()
|
|
{
|
|
return _nearestPt;
|
|
}
|
|
|
|
public bool OverPoly()
|
|
{
|
|
return _overPoly;
|
|
}
|
|
}
|
|
} |