From 4373d32a3e0795b32d65ec791ea893de21a2cbbd Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Tue, 2 Jul 2024 01:15:33 +0200 Subject: [PATCH] Recast: remove cached dtQueryFilter pointer from dtNavMeshQuery In the game engine, dtNavMeshQuery::m_queryFilter doesn't exist (the class is exactly 0x60 in size, and all members are confirmed and used. In CAI_Pathfinder, the next member next to m_navQuery is a static m_navFilter, which aligned perfectly against dtNavMeshQuery). Passing the filter in manually is also a better approach anyways. --- src/naveditor/NavMeshTesterTool.cpp | 6 +-- .../Detour/Include/DetourNavMeshQuery.h | 14 ++++--- .../Detour/Source/DetourNavMeshQuery.cpp | 38 +++++++++++-------- .../recast/DetourCrowd/Source/DetourCrowd.cpp | 9 +++-- .../DetourCrowd/Source/DetourPathCorridor.cpp | 6 +-- .../DetourCrowd/Source/DetourPathQueue.cpp | 6 +-- 6 files changed, 45 insertions(+), 34 deletions(-) diff --git a/src/naveditor/NavMeshTesterTool.cpp b/src/naveditor/NavMeshTesterTool.cpp index eca4f2e5..4fa3a4a5 100644 --- a/src/naveditor/NavMeshTesterTool.cpp +++ b/src/naveditor/NavMeshTesterTool.cpp @@ -579,11 +579,11 @@ void NavMeshTesterTool::handleUpdate(const float /*dt*/) { if (dtStatusInProgress(m_pathFindStatus)) { - m_pathFindStatus = m_navQuery->updateSlicedFindPath(1,0); + m_pathFindStatus = m_navQuery->updateSlicedFindPath(1,0, &m_filter); } if (dtStatusSucceed(m_pathFindStatus)) { - m_navQuery->finalizeSlicedFindPath(m_polys, &m_npolys, MAX_POLYS); + m_navQuery->finalizeSlicedFindPath(m_polys, &m_npolys, MAX_POLYS, &m_filter); m_nstraightPath = 0; if (m_npolys) { @@ -821,7 +821,7 @@ void NavMeshTesterTool::recalc() m_npolys = 0; m_nstraightPath = 0; - m_pathFindStatus = m_navQuery->initSlicedFindPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, DT_FINDPATH_ANY_ANGLE); + m_pathFindStatus = m_navQuery->initSlicedFindPath(m_startRef, m_endRef, m_spos, m_epos, DT_FINDPATH_ANY_ANGLE); } else { diff --git a/src/thirdparty/recast/Detour/Include/DetourNavMeshQuery.h b/src/thirdparty/recast/Detour/Include/DetourNavMeshQuery.h index 615e9070..e3d27bcc 100644 --- a/src/thirdparty/recast/Detour/Include/DetourNavMeshQuery.h +++ b/src/thirdparty/recast/Detour/Include/DetourNavMeshQuery.h @@ -223,26 +223,27 @@ public: /// @param[in] endRef The reference id of the end polygon. /// @param[in] startPos A position within the start polygon. [(x, y, z)] /// @param[in] endPos A position within the end polygon. [(x, y, z)] - /// @param[in] filter The polygon filter to apply to the query. /// @param[in] options query options (see: #dtFindPathOptions) /// @returns The status flags for the query. dtStatus initSlicedFindPath(dtPolyRef startRef, dtPolyRef endRef, const float* startPos, const float* endPos, - const dtQueryFilter* filter, const unsigned int options = 0); + const unsigned int options = 0); /// Updates an in-progress sliced path query. /// @param[in] maxIter The maximum number of iterations to perform. /// @param[out] doneIters The actual number of iterations completed. [opt] + /// @param[in] filter The polygon filter to apply to the query. /// @returns The status flags for the query. - dtStatus updateSlicedFindPath(const int maxIter, int* doneIters); + dtStatus updateSlicedFindPath(const int maxIter, int* doneIters, const dtQueryFilter* filter); /// Finalizes and returns the results of a sliced path query. /// @param[out] path An ordered list of polygon references representing the path. (Start to end.) /// [(polyRef) * @p pathCount] /// @param[out] pathCount The number of polygons returned in the @p path array. /// @param[in] maxPath The max number of polygons the path array can hold. [Limit: >= 1] + /// @param[in] filter The polygon filter to apply to the query. /// @returns The status flags for the query. - dtStatus finalizeSlicedFindPath(dtPolyRef* path, int* pathCount, const int maxPath); + dtStatus finalizeSlicedFindPath(dtPolyRef* path, int* pathCount, const int maxPath, const dtQueryFilter* filter); /// Finalizes and returns the results of an incomplete sliced path query, returning the path to the furthest /// polygon on the existing path that was visited during the search. @@ -252,9 +253,11 @@ public: /// [(polyRef) * @p pathCount] /// @param[out] pathCount The number of polygons returned in the @p path array. /// @param[in] maxPath The max number of polygons the @p path array can hold. [Limit: >= 1] + /// @param[in] filter The polygon filter to apply to the query. /// @returns The status flags for the query. dtStatus finalizeSlicedFindPathPartial(const dtPolyRef* existing, const int existingSize, - dtPolyRef* path, int* pathCount, const int maxPath); + dtPolyRef* path, int* pathCount, const int maxPath, + const dtQueryFilter* filter); ///@} /// @name Dijkstra Search Functions @@ -574,7 +577,6 @@ private: class dtNodePool* m_tinyNodePool; ///< Pointer to small node pool. class dtNodePool* m_nodePool; ///< Pointer to node pool. class dtNodeQueue* m_openList; ///< Pointer to open list queue. - const dtQueryFilter* m_queryFilter; ///< Pointer to query filter [NOTE: this field is possibly static in r5! Refactoring this in Recast is a big change however..]. }; /// Allocates a query object using the Detour allocator. diff --git a/src/thirdparty/recast/Detour/Source/DetourNavMeshQuery.cpp b/src/thirdparty/recast/Detour/Source/DetourNavMeshQuery.cpp index 83803d2a..63a71cd0 100644 --- a/src/thirdparty/recast/Detour/Source/DetourNavMeshQuery.cpp +++ b/src/thirdparty/recast/Detour/Source/DetourNavMeshQuery.cpp @@ -139,8 +139,7 @@ dtNavMeshQuery::dtNavMeshQuery() : m_nav(0), m_tinyNodePool(0), m_nodePool(0), - m_openList(0), - m_queryFilter(0) + m_openList(0) { memset(&m_query, 0, sizeof(dtQueryData)); } @@ -1198,7 +1197,7 @@ dtStatus dtNavMeshQuery::getPathToNode(dtNode* endNode, dtPolyRef* path, int* pa /// dtStatus dtNavMeshQuery::initSlicedFindPath(dtPolyRef startRef, dtPolyRef endRef, const float* startPos, const float* endPos, - const dtQueryFilter* filter, const unsigned int options) + const unsigned int options) { dtAssert(m_nav); dtAssert(m_nodePool); @@ -1213,14 +1212,13 @@ dtStatus dtNavMeshQuery::initSlicedFindPath(dtPolyRef startRef, dtPolyRef endRef dtVcopy(m_query.startPos, startPos); if (endPos) dtVcopy(m_query.endPos, endPos); - m_queryFilter = filter; m_query.options = options; m_query.raycastLimitSqr = FLT_MAX; // Validate input if (!m_nav->isValidPolyRef(startRef) || !m_nav->isValidPolyRef(endRef) || !startPos || !dtVisfinite(startPos) || - !endPos || !dtVisfinite(endPos) || !filter) + !endPos || !dtVisfinite(endPos)) { return DT_FAILURE | DT_INVALID_PARAM; } @@ -1260,11 +1258,16 @@ dtStatus dtNavMeshQuery::initSlicedFindPath(dtPolyRef startRef, dtPolyRef endRef return m_query.status; } -dtStatus dtNavMeshQuery::updateSlicedFindPath(const int maxIter, int* doneIters) +dtStatus dtNavMeshQuery::updateSlicedFindPath(const int maxIter, int* doneIters, const dtQueryFilter* filter) { + dtAssert(filter); + if (!dtStatusInProgress(m_query.status)) return m_query.status; + if (!filter) + return DT_FAILURE | DT_INVALID_PARAM; + // Make sure the request is still valid. if (!m_nav->isValidPolyRef(m_query.startRef) || !m_nav->isValidPolyRef(m_query.endRef)) { @@ -1357,9 +1360,10 @@ dtStatus dtNavMeshQuery::updateSlicedFindPath(const int maxIter, int* doneIters) const dtPoly* neighbourPoly = 0; m_nav->getTileAndPolyByRefUnsafe(neighbourRef, &neighbourTile, &neighbourPoly); - if (!m_queryFilter->passFilter(neighbourRef, neighbourTile, neighbourPoly)) + if (!filter->passFilter(neighbourRef, neighbourTile, neighbourPoly)) continue; + // get the neighbor node dtNode* neighbourNode = m_nodePool->getNode(neighbourRef, 0); if (!neighbourNode) @@ -1389,7 +1393,7 @@ dtStatus dtNavMeshQuery::updateSlicedFindPath(const int maxIter, int* doneIters) rayHit.pathCost = rayHit.t = 0; if (tryLOS) { - raycast(parentRef, parentNode->pos, neighbourNode->pos, m_queryFilter, DT_RAYCAST_USE_COSTS, &rayHit, grandpaRef); + raycast(parentRef, parentNode->pos, neighbourNode->pos, filter, DT_RAYCAST_USE_COSTS, &rayHit, grandpaRef); foundShortCut = rayHit.t >= 1.0f; } @@ -1402,7 +1406,7 @@ dtStatus dtNavMeshQuery::updateSlicedFindPath(const int maxIter, int* doneIters) else { // No shortcut found. - const float curCost = m_queryFilter->getCost(bestNode->pos, neighbourNode->pos, + const float curCost = filter->getCost(bestNode->pos, neighbourNode->pos, parentRef, parentTile, parentPoly, bestRef, bestTile, bestPoly, neighbourRef, neighbourTile, neighbourPoly); @@ -1412,7 +1416,7 @@ dtStatus dtNavMeshQuery::updateSlicedFindPath(const int maxIter, int* doneIters) // Special case for last node. if (neighbourRef == m_query.endRef) { - const float endCost = m_queryFilter->getCost(neighbourNode->pos, m_query.endPos, + const float endCost = filter->getCost(neighbourNode->pos, m_query.endPos, bestRef, bestTile, bestPoly, neighbourRef, neighbourTile, neighbourPoly, 0, 0, 0); @@ -1477,9 +1481,12 @@ dtStatus dtNavMeshQuery::updateSlicedFindPath(const int maxIter, int* doneIters) return m_query.status; } -dtStatus dtNavMeshQuery::finalizeSlicedFindPath(dtPolyRef* path, int* pathCount, const int maxPath) +dtStatus dtNavMeshQuery::finalizeSlicedFindPath(dtPolyRef* path, int* pathCount, const int maxPath, const dtQueryFilter* filter) { - if (!pathCount) + dtAssert(filter); + dtAssert(pathCount); + + if (!filter || !pathCount) return DT_FAILURE | DT_INVALID_PARAM; *pathCount = 0; @@ -1534,7 +1541,7 @@ dtStatus dtNavMeshQuery::finalizeSlicedFindPath(dtPolyRef* path, int* pathCount, { float t, normal[3]; int m; - status = raycast(node->id, node->pos, next->pos, m_queryFilter, &t, normal, path+n, &m, maxPath-n); + status = raycast(node->id, node->pos, next->pos, filter, &t, normal, path+n, &m, maxPath-n); n += m; // raycast ends on poly boundary and the path might include the next poly boundary. if (path[n-1] == next->id) @@ -1568,7 +1575,8 @@ dtStatus dtNavMeshQuery::finalizeSlicedFindPath(dtPolyRef* path, int* pathCount, } dtStatus dtNavMeshQuery::finalizeSlicedFindPathPartial(const dtPolyRef* existing, const int existingSize, - dtPolyRef* path, int* pathCount, const int maxPath) + dtPolyRef* path, int* pathCount, const int maxPath, + const dtQueryFilter* filter) { if (!pathCount) return DT_FAILURE | DT_INVALID_PARAM; @@ -1635,7 +1643,7 @@ dtStatus dtNavMeshQuery::finalizeSlicedFindPathPartial(const dtPolyRef* existing { float t, normal[3]; int m; - status = raycast(node->id, node->pos, next->pos, m_queryFilter, &t, normal, path+n, &m, maxPath-n); + status = raycast(node->id, node->pos, next->pos, filter, &t, normal, path+n, &m, maxPath-n); n += m; // raycast ends on poly boundary and the path might include the next poly boundary. if (path[n-1] == next->id) diff --git a/src/thirdparty/recast/DetourCrowd/Source/DetourCrowd.cpp b/src/thirdparty/recast/DetourCrowd/Source/DetourCrowd.cpp index e33b3eb7..6028e48f 100644 --- a/src/thirdparty/recast/DetourCrowd/Source/DetourCrowd.cpp +++ b/src/thirdparty/recast/DetourCrowd/Source/DetourCrowd.cpp @@ -472,18 +472,19 @@ void dtCrowd::updateMoveRequest(const float /*dt*/) // Quick search towards the goal. static const int MAX_ITER = 20; - m_navquery->initSlicedFindPath(path[0], ag->targetRef, ag->npos, ag->targetPos, &m_filters[ag->params.queryFilterType]); - m_navquery->updateSlicedFindPath(MAX_ITER, 0); + const dtQueryFilter* queryFilter = &m_filters[ag->params.queryFilterType]; + m_navquery->initSlicedFindPath(path[0], ag->targetRef, ag->npos, ag->targetPos); + m_navquery->updateSlicedFindPath(MAX_ITER, 0, queryFilter); dtStatus status = 0; if (ag->targetReplan) // && npath > 10) { // Try to use existing steady path during replan if possible. - status = m_navquery->finalizeSlicedFindPathPartial(path, npath, reqPath, &reqPathCount, MAX_RES); + status = m_navquery->finalizeSlicedFindPathPartial(path, npath, reqPath, &reqPathCount, MAX_RES, queryFilter); } else { // Try to move towards target when goal changes. - status = m_navquery->finalizeSlicedFindPath(reqPath, &reqPathCount, MAX_RES); + status = m_navquery->finalizeSlicedFindPath(reqPath, &reqPathCount, MAX_RES, queryFilter); } if (!dtStatusFailed(status) && reqPathCount > 0) diff --git a/src/thirdparty/recast/DetourCrowd/Source/DetourPathCorridor.cpp b/src/thirdparty/recast/DetourCrowd/Source/DetourPathCorridor.cpp index 50ecdc05..712f143c 100644 --- a/src/thirdparty/recast/DetourCrowd/Source/DetourPathCorridor.cpp +++ b/src/thirdparty/recast/DetourCrowd/Source/DetourPathCorridor.cpp @@ -364,9 +364,9 @@ bool dtPathCorridor::optimizePathTopology(dtNavMeshQuery* navquery, const dtQuer dtPolyRef res[MAX_RES]; int nres = 0; - navquery->initSlicedFindPath(m_path[0], m_path[m_npath-1], m_pos, m_target, filter); - navquery->updateSlicedFindPath(MAX_ITER, 0); - dtStatus status = navquery->finalizeSlicedFindPathPartial(m_path, m_npath, res, &nres, MAX_RES); + navquery->initSlicedFindPath(m_path[0], m_path[m_npath-1], m_pos, m_target); + navquery->updateSlicedFindPath(MAX_ITER, 0, filter); + dtStatus status = navquery->finalizeSlicedFindPathPartial(m_path, m_npath, res, &nres, MAX_RES, filter); if (dtStatusSucceed(status) && nres > 0) { diff --git a/src/thirdparty/recast/DetourCrowd/Source/DetourPathQueue.cpp b/src/thirdparty/recast/DetourCrowd/Source/DetourPathQueue.cpp index 7e91d2a5..0bd74d1d 100644 --- a/src/thirdparty/recast/DetourCrowd/Source/DetourPathQueue.cpp +++ b/src/thirdparty/recast/DetourCrowd/Source/DetourPathQueue.cpp @@ -111,18 +111,18 @@ void dtPathQueue::update(const int maxIters) // Handle query start. if (q.status == 0) { - q.status = m_navquery->initSlicedFindPath(q.startRef, q.endRef, q.startPos, q.endPos, q.filter); + q.status = m_navquery->initSlicedFindPath(q.startRef, q.endRef, q.startPos, q.endPos); } // Handle query in progress. if (dtStatusInProgress(q.status)) { int iters = 0; - q.status = m_navquery->updateSlicedFindPath(iterCount, &iters); + q.status = m_navquery->updateSlicedFindPath(iterCount, &iters, q.filter); iterCount -= iters; } if (dtStatusSucceed(q.status)) { - q.status = m_navquery->finalizeSlicedFindPath(q.path, &q.npath, m_maxPathSize); + q.status = m_navquery->finalizeSlicedFindPath(q.path, &q.npath, m_maxPathSize, q.filter); } if (iterCount <= 0)