Fixed pos-over-poly case for finding nearest polygon

This commit is contained in:
Mikko Mononen 2014-02-16 11:27:45 +02:00
parent 6702143bc1
commit 19e2d8dbe6
3 changed files with 17 additions and 15 deletions

View File

@ -711,13 +711,13 @@ dtPolyRef dtNavMesh::findNearestPolyInTile(const dtMeshTile* tile,
// Find nearest polygon amongst the nearby polygons. // Find nearest polygon amongst the nearby polygons.
dtPolyRef nearest = 0; dtPolyRef nearest = 0;
float nearestDistanceSqr = FLT_MAX; float nearestDistanceSqr = FLT_MAX;
bool nearestOverPoly = false;
for (int i = 0; i < polyCount; ++i) for (int i = 0; i < polyCount; ++i)
{ {
dtPolyRef ref = polys[i]; dtPolyRef ref = polys[i];
float closestPtPoly[3]; float closestPtPoly[3];
float diff[3]; float diff[3];
bool posOverPoly = false; bool posOverPoly = false;
float d = 0;
closestPointOnPoly(ref, center, closestPtPoly, &posOverPoly); closestPointOnPoly(ref, center, closestPtPoly, &posOverPoly);
// If a point is directly over a polygon and closer than // If a point is directly over a polygon and closer than
@ -725,18 +725,18 @@ dtPolyRef dtNavMesh::findNearestPolyInTile(const dtMeshTile* tile,
dtVsub(diff, center, closestPtPoly); dtVsub(diff, center, closestPtPoly);
if (posOverPoly) if (posOverPoly)
{ {
const dtMeshTile* tile = 0; d = dtAbs(diff[1]) - tile->header->walkableClimb;
if (dtAbs(diff[1]) > tile->header->walkableClimb) d = d > 0 ? d*d : 0;
posOverPoly = false; }
else
{
d = dtVlenSqr(diff);
} }
float d = dtVlenSqr(diff); if (d < nearestDistanceSqr)
if (d < nearestDistanceSqr || (!nearestOverPoly && posOverPoly))
{ {
dtVcopy(nearestPt, closestPtPoly); dtVcopy(nearestPt, closestPtPoly);
nearestDistanceSqr = d; nearestDistanceSqr = d;
nearestOverPoly = posOverPoly;
nearest = ref; nearest = ref;
} }
} }

View File

@ -723,13 +723,13 @@ dtStatus dtNavMeshQuery::findNearestPoly(const float* center, const float* exten
// Find nearest polygon amongst the nearby polygons. // Find nearest polygon amongst the nearby polygons.
dtPolyRef nearest = 0; dtPolyRef nearest = 0;
float nearestDistanceSqr = FLT_MAX; float nearestDistanceSqr = FLT_MAX;
bool nearestOverPoly = false;
for (int i = 0; i < polyCount; ++i) for (int i = 0; i < polyCount; ++i)
{ {
dtPolyRef ref = polys[i]; dtPolyRef ref = polys[i];
float closestPtPoly[3]; float closestPtPoly[3];
float diff[3]; float diff[3];
bool posOverPoly = false; bool posOverPoly = false;
float d = 0;
closestPointOnPoly(ref, center, closestPtPoly, &posOverPoly); closestPointOnPoly(ref, center, closestPtPoly, &posOverPoly);
// If a point is directly over a polygon and closer than // If a point is directly over a polygon and closer than
@ -740,18 +740,19 @@ dtStatus dtNavMeshQuery::findNearestPoly(const float* center, const float* exten
const dtMeshTile* tile = 0; const dtMeshTile* tile = 0;
const dtPoly* poly = 0; const dtPoly* poly = 0;
m_nav->getTileAndPolyByRefUnsafe(polys[i], &tile, &poly); m_nav->getTileAndPolyByRefUnsafe(polys[i], &tile, &poly);
if (dtAbs(diff[1]) > tile->header->walkableClimb) d = dtAbs(diff[1]) - tile->header->walkableClimb;
posOverPoly = false; d = d > 0 ? d*d : 0;
}
else
{
d = dtVlenSqr(diff);
} }
float d = dtVlenSqr(diff); if (d < nearestDistanceSqr)
if (d < nearestDistanceSqr || (!nearestOverPoly && posOverPoly))
{ {
if (nearestPt) if (nearestPt)
dtVcopy(nearestPt, closestPtPoly); dtVcopy(nearestPt, closestPtPoly);
nearestDistanceSqr = d; nearestDistanceSqr = d;
nearestOverPoly = posOverPoly;
nearest = ref; nearest = ref;
} }
} }

View File

@ -3,3 +3,4 @@ f nav_test.obj
rc 45.133884 -0.533207 -3.775568 47.078232 7.797605 14.293253 0xffef 0x0 rc 45.133884 -0.533207 -3.775568 47.078232 7.797605 14.293253 0xffef 0x0
rc 52.979847 -2.778793 -2.914886 50.628868 -2.350212 13.917850 0xffef 0x0 rc 52.979847 -2.778793 -2.914886 50.628868 -2.350212 13.917850 0xffef 0x0
rc 45.209217 2.024442 1.838851 46.888412 7.797606 15.772338 0xffef 0x0 rc 45.209217 2.024442 1.838851 46.888412 7.797606 15.772338 0xffef 0x0
rc 45.388317 -0.562073 -3.673226 46.651001 7.797606 15.513507 0xffef 0x0