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.
This commit is contained in:
Kawe Mazidjatari 2024-07-02 01:15:33 +02:00
parent ad44b3f010
commit 4373d32a3e
6 changed files with 45 additions and 34 deletions

View File

@ -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
{

View File

@ -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.

View File

@ -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)

View File

@ -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)

View File

@ -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)
{

View File

@ -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)