Poly query API: expose distance and isOverPoly (#448)

* Add dtNavMeshQuery.findNearestPoly() overload with parameters: distance, isOverPoly

* dtNavMeshQuery::findNearestPoly(): improve documentation, avoid code duplication

* Make code C++98-compatible

* Remove distance parameter from dtNavMeshQuery::queryPolygons()
This commit is contained in:
Jan Haller 2021-01-23 13:25:41 +01:00 committed by GitHub
parent c32297c2f9
commit cf4f3e15a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 4 deletions

View File

@ -313,15 +313,31 @@ public:
///@{ ///@{
/// Finds the polygon nearest to the specified center point. /// Finds the polygon nearest to the specified center point.
/// [opt] means the specified parameter can be a null pointer, in that case the output parameter will not be set.
///
/// @param[in] center The center of the search box. [(x, y, z)] /// @param[in] center The center of the search box. [(x, y, z)]
/// @param[in] halfExtents The search distance along each axis. [(x, y, z)] /// @param[in] halfExtents The search distance along each axis. [(x, y, z)]
/// @param[in] filter The polygon filter to apply to the query. /// @param[in] filter The polygon filter to apply to the query.
/// @param[out] nearestRef The reference id of the nearest polygon. /// @param[out] nearestRef The reference id of the nearest polygon. Will be set to 0 if no polygon is found.
/// @param[out] nearestPt The nearest point on the polygon. [opt] [(x, y, z)] /// @param[out] nearestPt The nearest point on the polygon. Unchanged if no polygon is found. [opt] [(x, y, z)]
/// @returns The status flags for the query. /// @returns The status flags for the query.
dtStatus findNearestPoly(const float* center, const float* halfExtents, dtStatus findNearestPoly(const float* center, const float* halfExtents,
const dtQueryFilter* filter, const dtQueryFilter* filter,
dtPolyRef* nearestRef, float* nearestPt) const; dtPolyRef* nearestRef, float* nearestPt) const;
/// Finds the polygon nearest to the specified center point.
/// [opt] means the specified parameter can be a null pointer, in that case the output parameter will not be set.
///
/// @param[in] center The center of the search box. [(x, y, z)]
/// @param[in] halfExtents The search distance along each axis. [(x, y, z)]
/// @param[in] filter The polygon filter to apply to the query.
/// @param[out] nearestRef The reference id of the nearest polygon. Will be set to 0 if no polygon is found.
/// @param[out] nearestPt The nearest point on the polygon. Unchanged if no polygon is found. [opt] [(x, y, z)]
/// @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]
/// @returns The status flags for the query.
dtStatus findNearestPoly(const float* center, const float* halfExtents,
const dtQueryFilter* filter,
dtPolyRef* nearestRef, float* nearestPt, bool* isOverPoly) const;
/// Finds polygons that overlap the search box. /// Finds polygons that overlap the search box.
/// @param[in] center The center of the search box. [(x, y, z)] /// @param[in] center The center of the search box. [(x, y, z)]

View File

@ -630,15 +630,17 @@ class dtFindNearestPolyQuery : public dtPolyQuery
float m_nearestDistanceSqr; float m_nearestDistanceSqr;
dtPolyRef m_nearestRef; dtPolyRef m_nearestRef;
float m_nearestPoint[3]; float m_nearestPoint[3];
bool m_overPoly;
public: public:
dtFindNearestPolyQuery(const dtNavMeshQuery* query, const float* center) dtFindNearestPolyQuery(const dtNavMeshQuery* query, const float* center)
: m_query(query), m_center(center), m_nearestDistanceSqr(FLT_MAX), m_nearestRef(0), m_nearestPoint() : m_query(query), m_center(center), m_nearestDistanceSqr(FLT_MAX), m_nearestRef(0), m_nearestPoint(), m_overPoly(false)
{ {
} }
dtPolyRef nearestRef() const { return m_nearestRef; } dtPolyRef nearestRef() const { return m_nearestRef; }
const float* nearestPoint() const { return m_nearestPoint; } const float* nearestPoint() const { return m_nearestPoint; }
bool isOverPoly() const { return m_overPoly; }
void process(const dtMeshTile* tile, dtPoly** polys, dtPolyRef* refs, int count) void process(const dtMeshTile* tile, dtPoly** polys, dtPolyRef* refs, int count)
{ {
@ -672,6 +674,7 @@ public:
m_nearestDistanceSqr = d; m_nearestDistanceSqr = d;
m_nearestRef = ref; m_nearestRef = ref;
m_overPoly = posOverPoly;
} }
} }
} }
@ -686,6 +689,15 @@ public:
dtStatus dtNavMeshQuery::findNearestPoly(const float* center, const float* halfExtents, dtStatus dtNavMeshQuery::findNearestPoly(const float* center, const float* halfExtents,
const dtQueryFilter* filter, const dtQueryFilter* filter,
dtPolyRef* nearestRef, float* nearestPt) const dtPolyRef* nearestRef, float* nearestPt) const
{
return findNearestPoly(center, halfExtents, filter, nearestRef, nearestPt, NULL);
}
// If center and nearestPt point to an equal position, isOverPoly will be true;
// however there's also a special case of climb height inside the polygon (see dtFindNearestPolyQuery)
dtStatus dtNavMeshQuery::findNearestPoly(const float* center, const float* halfExtents,
const dtQueryFilter* filter,
dtPolyRef* nearestRef, float* nearestPt, bool* isOverPoly) const
{ {
dtAssert(m_nav); dtAssert(m_nav);
@ -704,7 +716,11 @@ dtStatus dtNavMeshQuery::findNearestPoly(const float* center, const float* halfE
// Only override nearestPt if we actually found a poly so the nearest point // Only override nearestPt if we actually found a poly so the nearest point
// is valid. // is valid.
if (nearestPt && *nearestRef) if (nearestPt && *nearestRef)
{
dtVcopy(nearestPt, query.nearestPoint()); dtVcopy(nearestPt, query.nearestPoint());
if (isOverPoly)
*isOverPoly = query.isOverPoly();
}
return DT_SUCCESS; return DT_SUCCESS;
} }