From cf4f3e15a85775db643381f32623cfde40720db9 Mon Sep 17 00:00:00 2001 From: Jan Haller Date: Sat, 23 Jan 2021 13:25:41 +0100 Subject: [PATCH] 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() --- Detour/Include/DetourNavMeshQuery.h | 22 +++++++++++++++++++--- Detour/Source/DetourNavMeshQuery.cpp | 18 +++++++++++++++++- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/Detour/Include/DetourNavMeshQuery.h b/Detour/Include/DetourNavMeshQuery.h index 0b40371..08b70a8 100644 --- a/Detour/Include/DetourNavMeshQuery.h +++ b/Detour/Include/DetourNavMeshQuery.h @@ -313,15 +313,31 @@ public: ///@{ /// 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] 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. - /// @param[out] nearestPt The nearest point on the polygon. [opt] [(x, y, z)] + /// @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)] /// @returns The status flags for the query. dtStatus findNearestPoly(const float* center, const float* halfExtents, const dtQueryFilter* filter, 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. /// @param[in] center The center of the search box. [(x, y, z)] diff --git a/Detour/Source/DetourNavMeshQuery.cpp b/Detour/Source/DetourNavMeshQuery.cpp index 839ee1e..8ea09c8 100644 --- a/Detour/Source/DetourNavMeshQuery.cpp +++ b/Detour/Source/DetourNavMeshQuery.cpp @@ -630,15 +630,17 @@ class dtFindNearestPolyQuery : public dtPolyQuery float m_nearestDistanceSqr; dtPolyRef m_nearestRef; float m_nearestPoint[3]; + bool m_overPoly; public: 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; } const float* nearestPoint() const { return m_nearestPoint; } + bool isOverPoly() const { return m_overPoly; } void process(const dtMeshTile* tile, dtPoly** polys, dtPolyRef* refs, int count) { @@ -672,6 +674,7 @@ public: m_nearestDistanceSqr = d; m_nearestRef = ref; + m_overPoly = posOverPoly; } } } @@ -686,6 +689,15 @@ public: dtStatus dtNavMeshQuery::findNearestPoly(const float* center, const float* halfExtents, const dtQueryFilter* filter, 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); @@ -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 // is valid. if (nearestPt && *nearestRef) + { dtVcopy(nearestPt, query.nearestPoint()); + if (isOverPoly) + *isOverPoly = query.isOverPoly(); + } return DT_SUCCESS; }