Skip to content

Commit

Permalink
Deduplicate closestPointOnPoly
Browse files Browse the repository at this point in the history
  • Loading branch information
jakobbotsch committed Mar 16, 2019
1 parent 3a619d7 commit a0e6605
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 81 deletions.
2 changes: 2 additions & 0 deletions Detour/Include/DetourNavMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,8 @@ class dtNavMesh
unsigned int m_tileBits; ///< Number of tile bits in the tile ID.
unsigned int m_polyBits; ///< Number of poly bits in the tile ID.
#endif

friend class dtNavMeshQuery;
};

/// Allocates a navigation mesh object using the Detour allocator.
Expand Down
2 changes: 0 additions & 2 deletions Detour/Include/DetourNavMeshQuery.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,6 @@ class dtQueryFilter

};



/// Provides information about raycast hit
/// filled by dtNavMeshQuery::raycast
/// @ingroup detour
Expand Down
84 changes: 5 additions & 79 deletions Detour/Source/DetourNavMeshQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,88 +514,14 @@ dtStatus dtNavMeshQuery::findRandomPointAroundCircle(dtPolyRef startRef, const f
dtStatus dtNavMeshQuery::closestPointOnPoly(dtPolyRef ref, const float* pos, float* closest, bool* posOverPoly) const
{
dtAssert(m_nav);
const dtMeshTile* tile = 0;
const dtPoly* poly = 0;
if (dtStatusFailed(m_nav->getTileAndPolyByRef(ref, &tile, &poly)))
return DT_FAILURE | DT_INVALID_PARAM;
if (!tile)
return DT_FAILURE | DT_INVALID_PARAM;

if (!pos || !dtVisfinite(pos) || !closest)
return DT_FAILURE | DT_INVALID_PARAM;

// Off-mesh connections don't have detail polygons.
if (poly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION)
{
const float* v0 = &tile->verts[poly->verts[0]*3];
const float* v1 = &tile->verts[poly->verts[1]*3];
const float d0 = dtVdist(pos, v0);
const float d1 = dtVdist(pos, v1);
const float u = d0 / (d0+d1);
dtVlerp(closest, v0, v1, u);
if (posOverPoly)
*posOverPoly = false;
return DT_SUCCESS;
}

const unsigned int ip = (unsigned int)(poly - tile->polys);
const dtPolyDetail* pd = &tile->detailMeshes[ip];

// Clamp point to be inside the polygon.
float verts[DT_VERTS_PER_POLYGON*3];
float edged[DT_VERTS_PER_POLYGON];
float edget[DT_VERTS_PER_POLYGON];
const int nv = poly->vertCount;
for (int i = 0; i < nv; ++i)
dtVcopy(&verts[i*3], &tile->verts[poly->verts[i]*3]);

dtVcopy(closest, pos);
if (!dtDistancePtPolyEdgesSqr(pos, verts, nv, edged, edget))
if (!m_nav->isValidPolyRef(ref) ||
!pos || !dtVisfinite(pos) ||
!closest)
{
// Point is outside the polygon, dtClamp to nearest edge.
float dmin = edged[0];
int imin = 0;
for (int i = 1; i < nv; ++i)
{
if (edged[i] < dmin)
{
dmin = edged[i];
imin = i;
}
}
const float* va = &verts[imin*3];
const float* vb = &verts[((imin+1)%nv)*3];
dtVlerp(closest, va, vb, edget[imin]);

if (posOverPoly)
*posOverPoly = false;
}
else
{
if (posOverPoly)
*posOverPoly = true;
return DT_FAILURE | DT_INVALID_PARAM;
}

// Find height at the location.
for (int j = 0; j < pd->triCount; ++j)
{
const unsigned char* t = &tile->detailTris[(pd->triBase+j)*4];
const float* v[3];
for (int k = 0; k < 3; ++k)
{
if (t[k] < poly->vertCount)
v[k] = &tile->verts[poly->verts[t[k]]*3];
else
v[k] = &tile->detailVerts[(pd->vertBase+(t[k]-poly->vertCount))*3];
}
float h;
if (dtClosestHeightPointTriangle(closest, v[0], v[1], v[2], h))
{
closest[1] = h;
break;
}
}

m_nav->closestPointOnPoly(ref, pos, closest, posOverPoly);
return DT_SUCCESS;
}

Expand Down

0 comments on commit a0e6605

Please sign in to comment.