Recast: start of jump type implementation in findStraightPath

This commit is contained in:
Kawe Mazidjatari 2024-08-31 23:03:44 +02:00
parent ab88364779
commit ec115d7c97
9 changed files with 71 additions and 44 deletions

View File

@ -106,7 +106,7 @@ static int fixupShortcuts(dtPolyRef* path, int npath, dtNavMeshQuery* navQuery)
static bool getSteerTarget(dtNavMeshQuery* navQuery, const float* startPos, const float* endPos,
const float minTargetDist,
const dtPolyRef* path, const int pathSize,
const dtPolyRef* path, const unsigned char* jumpTypes, const int pathSize,
float* steerPos, unsigned char& steerPosFlag, dtPolyRef& steerPosRef,
float* outPoints = 0, int* outPointCount = 0)
{
@ -115,9 +115,10 @@ static bool getSteerTarget(dtNavMeshQuery* navQuery, const float* startPos, cons
float steerPath[MAX_STEER_POINTS*3];
unsigned char steerPathFlags[MAX_STEER_POINTS];
dtPolyRef steerPathPolys[MAX_STEER_POINTS];
unsigned char steerPathJumps[MAX_STEER_POINTS];
int nsteerPath = 0;
navQuery->findStraightPath(startPos, endPos, path, pathSize,
steerPath, steerPathFlags, steerPathPolys, &nsteerPath, MAX_STEER_POINTS);
navQuery->findStraightPath(startPos, endPos, path, jumpTypes, pathSize,
steerPath, steerPathFlags, steerPathPolys, steerPathJumps, &nsteerPath, MAX_STEER_POINTS);
if (!nsteerPath)
return false;
@ -544,7 +545,7 @@ void NavMeshTesterTool::handleToggle()
dtPolyRef steerPosRef;
if (!getSteerTarget(m_navQuery, m_iterPos, m_targetPos, SLOP,
m_pathIterPolys, m_pathIterPolyCount, steerPos, steerPosFlag, steerPosRef,
m_pathIterPolys, m_jumpTypes, m_pathIterPolyCount, steerPos, steerPosFlag, steerPosRef,
m_steerPoints, &m_steerPointCount))
return;
@ -661,9 +662,9 @@ void NavMeshTesterTool::handleUpdate(const float /*dt*/)
if (m_polys[m_npolys-1] != m_endRef)
m_navQuery->closestPointOnPoly(m_polys[m_npolys-1], m_epos, epos, 0);
m_navQuery->findStraightPath(m_spos, epos, m_polys, m_npolys,
m_navQuery->findStraightPath(m_spos, epos, m_polys, m_jumpTypes, m_npolys,
m_straightPath, m_straightPathFlags,
m_straightPathPolys, &m_nstraightPath, MAX_POLYS, DT_STRAIGHTPATH_ALL_CROSSINGS);
m_straightPathPolys, m_straightPathJumps, &m_nstraightPath, MAX_POLYS, DT_STRAIGHTPATH_ALL_CROSSINGS);
}
m_pathFindStatus = DT_FAILURE;
@ -738,6 +739,7 @@ void NavMeshTesterTool::recalc()
dtPolyRef polys[MAX_POLYS];
memcpy(polys, m_polys, sizeof(dtPolyRef)*m_npolys);
int npolys = m_npolys;
unsigned char* jumpTypes = m_jumpTypes;
float iterPos[3], targetPos[3];
m_navQuery->closestPointOnPoly(m_startRef, m_spos, iterPos, 0);
@ -761,7 +763,7 @@ void NavMeshTesterTool::recalc()
dtPolyRef steerPosRef;
if (!getSteerTarget(m_navQuery, iterPos, targetPos, SLOP,
polys, npolys, steerPos, steerPosFlag, steerPosRef))
polys, jumpTypes, npolys, steerPos, steerPosFlag, steerPosRef))
break;
bool endOfPath = (steerPosFlag & DT_STRAIGHTPATH_END) ? true : false;
@ -882,9 +884,9 @@ void NavMeshTesterTool::recalc()
if (m_polys[m_npolys-1] != m_endRef)
m_navQuery->closestPointOnPoly(m_polys[m_npolys-1], m_epos, epos, 0);
m_navQuery->findStraightPath(m_spos, epos, m_polys, m_npolys,
m_navQuery->findStraightPath(m_spos, epos, m_polys, m_jumpTypes, m_npolys,
m_straightPath, m_straightPathFlags,
m_straightPathPolys, &m_nstraightPath, MAX_POLYS, m_straightPathOptions);
m_straightPathPolys, m_straightPathJumps, &m_nstraightPath, MAX_POLYS, m_straightPathOptions);
}
}
else

View File

@ -191,6 +191,7 @@ void TestCase::doTests(dtNavMesh* navmesh, dtNavMeshQuery* navquery)
static const int MAX_POLYS = 256;
dtPolyRef polys[MAX_POLYS];
unsigned char jumps[MAX_POLYS];
float straight[MAX_POLYS*3];
const float polyPickExt[3] = {2,4,2};
@ -235,8 +236,8 @@ void TestCase::doTests(dtNavMesh* navmesh, dtNavMeshQuery* navquery)
{
TimeVal findStraightPathStart = getPerfTime();
navquery->findStraightPath(iter->spos, iter->epos, polys, iter->npolys,
straight, 0, 0, &iter->nstraight, MAX_POLYS);
navquery->findStraightPath(iter->spos, iter->epos, polys, jumps, iter->npolys,
straight, 0, 0, 0, &iter->nstraight, MAX_POLYS);
TimeVal findStraightPathEnd = getPerfTime();
iter->findStraightPathTime += getPerfTimeUsec(findStraightPathEnd - findStraightPathStart);
}

View File

@ -60,10 +60,12 @@ class NavMeshTesterTool : public EditorTool
dtPolyRef m_endRef;
dtPolyRef m_polys[MAX_POLYS];
dtPolyRef m_parent[MAX_POLYS];
unsigned char m_jumpTypes[MAX_POLYS];
int m_npolys;
float m_straightPath[MAX_POLYS*3];
unsigned char m_straightPathFlags[MAX_POLYS];
dtPolyRef m_straightPathPolys[MAX_POLYS];
unsigned char m_straightPathJumps[MAX_POLYS];
int m_nstraightPath;
float m_polyPickExt[3];
float m_smoothPath[MAX_SMOOTH*3];

View File

@ -226,14 +226,16 @@ public:
/// @param[out] straightPath Points describing the straight path. [(x, y, z) * @p straightPathCount].
/// @param[out] straightPathFlags Flags describing each point. (See: #dtStraightPathFlags) [opt]
/// @param[out] straightPathRefs The reference id of the polygon that is being entered at each point. [opt]
/// @param[out] straightPathJumps The jump types that is being entered at each point. [opt]
/// @param[out] straightPathCount The number of points in the straight path.
/// @param[in] maxStraightPath The maximum number of points the straight path arrays can hold. [Limit: > 0]
/// @param[in] options Query options. (see: #dtStraightPathOptions)
/// @returns The status flags for the query.
dtStatus findStraightPath(const float* startPos, const float* endPos,
const dtPolyRef* path, const int pathSize,
const dtPolyRef* path, const unsigned char* jumpTypes, const int pathSize,
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
int* straightPathCount, const int maxStraightPath, const int options = 0) const;
unsigned char* straightPathJumps, int* straightPathCount, const int maxStraightPath,
const int options = 0) const;
///@}
/// @name Sliced Pathfinding Functions
@ -621,13 +623,15 @@ private:
// Appends vertex to a straight path
dtStatus appendVertex(const float* pos, const unsigned char flags, const dtPolyRef ref,
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
int* straightPathCount, const int maxStraightPath) const;
const unsigned char jump, float* straightPath, unsigned char* straightPathFlags,
dtPolyRef* straightPathRefs, unsigned char* straightPathJumps, int* straightPathCount,
const int maxStraightPath) const;
// Appends intermediate portal points to a straight path.
dtStatus appendPortals(const int startIdx, const int endIdx, const float* endPos, const dtPolyRef* path,
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
int* straightPathCount, const int maxStraightPath, const int options) const;
unsigned char* straightPathJumps, int* straightPathCount, const int maxStraightPath,
const int options) const;
// Gets the path leading to the specified end node.
dtStatus getPathToNode(struct dtNode* endNode, dtPolyRef* path, int* pathCount, int maxPath) const;

View File

@ -1682,7 +1682,8 @@ dtStatus dtNavMeshQuery::finalizeSlicedFindPathPartial(const dtPolyRef* existing
dtStatus dtNavMeshQuery::appendVertex(const float* pos, const unsigned char flags, const dtPolyRef ref,
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
const unsigned char jump, float* straightPath, unsigned char* straightPathFlags,
dtPolyRef* straightPathRefs, unsigned char* straightPathJumps,
int* straightPathCount, const int maxStraightPath) const
{
if ((*straightPathCount) > 0 && rdVequal(&straightPath[((*straightPathCount)-1)*3], pos))
@ -1692,6 +1693,8 @@ dtStatus dtNavMeshQuery::appendVertex(const float* pos, const unsigned char flag
straightPathFlags[(*straightPathCount)-1] = flags;
if (straightPathRefs)
straightPathRefs[(*straightPathCount)-1] = ref;
if (straightPathJumps)
straightPathJumps[(*straightPathCount)-1] = jump;
}
else
{
@ -1701,6 +1704,8 @@ dtStatus dtNavMeshQuery::appendVertex(const float* pos, const unsigned char flag
straightPathFlags[(*straightPathCount)] = flags;
if (straightPathRefs)
straightPathRefs[(*straightPathCount)] = ref;
if (straightPathJumps)
straightPathJumps[(*straightPathCount)] = jump;
(*straightPathCount)++;
// If there is no space to append more vertices, return.
@ -1720,7 +1725,8 @@ dtStatus dtNavMeshQuery::appendVertex(const float* pos, const unsigned char flag
dtStatus dtNavMeshQuery::appendPortals(const int startIdx, const int endIdx, const float* endPos, const dtPolyRef* path,
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
int* straightPathCount, const int maxStraightPath, const int options) const
unsigned char* straightPathJumps, int* straightPathCount, const int maxStraightPath,
const int options) const
{
const float* startPos = &straightPath[(*straightPathCount-1)*3];
// Append or update last vertex
@ -1758,9 +1764,9 @@ dtStatus dtNavMeshQuery::appendPortals(const int startIdx, const int endIdx, con
float pt[3];
rdVlerp(pt, left,right, t);
stat = appendVertex(pt, 0, path[i+1],
stat = appendVertex(pt, 0, path[i+1], DT_NULL_TRAVERSE_TYPE,
straightPath, straightPathFlags, straightPathRefs,
straightPathCount, maxStraightPath);
straightPathJumps, straightPathCount, maxStraightPath);
if (stat != DT_IN_PROGRESS)
return stat;
}
@ -1786,9 +1792,9 @@ dtStatus dtNavMeshQuery::appendPortals(const int startIdx, const int endIdx, con
/// position.
///
dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* endPos,
const dtPolyRef* path, const int pathSize,
const dtPolyRef* path, const unsigned char* jumpTypes, const int pathSize,
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
int* straightPathCount, const int maxStraightPath, const int options) const
unsigned char* straightPathJumps, int* straightPathCount, const int maxStraightPath, const int options) const
{
rdAssert(m_nav);
@ -1817,9 +1823,9 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
return DT_FAILURE | DT_INVALID_PARAM;
// Add start point.
stat = appendVertex(closestStartPos, DT_STRAIGHTPATH_START, path[0],
stat = appendVertex(closestStartPos, DT_STRAIGHTPATH_START, path[0], jumpTypes[0],
straightPath, straightPathFlags, straightPathRefs,
straightPathCount, maxStraightPath);
straightPathJumps, straightPathCount, maxStraightPath);
if (stat != DT_IN_PROGRESS)
return stat;
@ -1836,6 +1842,9 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
unsigned char leftPolyType = 0;
unsigned char rightPolyType = 0;
unsigned char leftJumpType = jumpTypes[0];
unsigned char rightJumpType = jumpTypes[0];
dtPolyRef leftPolyRef = path[0];
dtPolyRef rightPolyRef = path[0];
@ -1866,13 +1875,13 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
// Ignore status return value as we're just about to return anyway.
appendPortals(apexIndex, i, closestEndPos, path,
straightPath, straightPathFlags, straightPathRefs,
straightPathCount, maxStraightPath, options);
straightPathJumps, straightPathCount, maxStraightPath, options);
}
// Ignore status return value as we're just about to return anyway.
appendVertex(closestEndPos, 0, path[i],
appendVertex(closestEndPos, 0, path[i], jumpTypes[i],
straightPath, straightPathFlags, straightPathRefs,
straightPathCount, maxStraightPath);
straightPathJumps, straightPathCount, maxStraightPath);
return DT_SUCCESS | DT_PARTIAL_RESULT | ((*straightPathCount >= maxStraightPath) ? DT_BUFFER_TOO_SMALL : 0);
}
@ -1901,6 +1910,7 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
{
rdVcopy(portalLeft, left);
leftPolyRef = (i+1 < pathSize) ? path[i+1] : 0;
leftJumpType = (i+1 < pathSize) ? jumpTypes[i+1] : DT_NULL_TRAVERSE_TYPE;
leftPolyType = toType;
leftIndex = i;
}
@ -1911,7 +1921,7 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
{
stat = appendPortals(apexIndex, rightIndex, portalRight, path,
straightPath, straightPathFlags, straightPathRefs,
straightPathCount, maxStraightPath, options);
straightPathJumps, straightPathCount, maxStraightPath, options);
if (stat != DT_IN_PROGRESS)
return stat;
}
@ -1927,9 +1937,9 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
dtPolyRef ref = rightPolyRef;
// Append or update vertex
stat = appendVertex(portalApex, flags, ref,
stat = appendVertex(portalApex, flags, ref, rightJumpType,
straightPath, straightPathFlags, straightPathRefs,
straightPathCount, maxStraightPath);
straightPathJumps, straightPathCount, maxStraightPath);
if (stat != DT_IN_PROGRESS)
return stat;
@ -1952,6 +1962,7 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
{
rdVcopy(portalRight, right);
rightPolyRef = (i+1 < pathSize) ? path[i+1] : 0;
rightJumpType = (i+1 < pathSize) ? jumpTypes[i+1] : DT_NULL_TRAVERSE_TYPE;
rightPolyType = toType;
rightIndex = i;
}
@ -1962,7 +1973,7 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
{
stat = appendPortals(apexIndex, leftIndex, portalLeft, path,
straightPath, straightPathFlags, straightPathRefs,
straightPathCount, maxStraightPath, options);
straightPathJumps, straightPathCount, maxStraightPath, options);
if (stat != DT_IN_PROGRESS)
return stat;
}
@ -1978,9 +1989,9 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
dtPolyRef ref = leftPolyRef;
// Append or update vertex
stat = appendVertex(portalApex, flags, ref,
stat = appendVertex(portalApex, flags, ref, leftJumpType,
straightPath, straightPathFlags, straightPathRefs,
straightPathCount, maxStraightPath);
straightPathJumps, straightPathCount, maxStraightPath);
if (stat != DT_IN_PROGRESS)
return stat;
@ -2002,16 +2013,16 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
{
stat = appendPortals(apexIndex, pathSize-1, closestEndPos, path,
straightPath, straightPathFlags, straightPathRefs,
straightPathCount, maxStraightPath, options);
straightPathJumps, straightPathCount, maxStraightPath, options);
if (stat != DT_IN_PROGRESS)
return stat;
}
}
// Ignore status return value as we're just about to return anyway.
appendVertex(closestEndPos, DT_STRAIGHTPATH_END, 0,
appendVertex(closestEndPos, DT_STRAIGHTPATH_END, 0, DT_NULL_TRAVERSE_TYPE,
straightPath, straightPathFlags, straightPathRefs,
straightPathCount, maxStraightPath);
straightPathJumps, straightPathCount, maxStraightPath);
return DT_SUCCESS | ((*straightPathCount >= maxStraightPath) ? DT_BUFFER_TOO_SMALL : 0);
}

View File

@ -170,6 +170,9 @@ struct dtCrowdAgent
/// The reference id of the polygon being entered at the corner. [(polyRef) * #ncorners]
dtPolyRef cornerPolys[DT_CROWDAGENT_MAX_CORNERS];
/// The jump types encountered at the corner. [(jumpType) * #ncorners]
unsigned char cornerJumps[DT_CROWDAGENT_MAX_CORNERS];
/// The number of corners.
int ncorners;

View File

@ -26,6 +26,7 @@
class dtPathCorridor
{
dtPolyRef* m_path;
unsigned char* m_jumpTypes;
int m_npath;
int m_maxPath;
@ -49,15 +50,16 @@ public:
/// Finds the corners in the corridor from the position toward the target. (The straightened path.)
/// @param[out] cornerVerts The corner vertices. [(x, y, z) * cornerCount] [Size: <= maxCorners]
/// @param[out] cornerFlags The flag for each corner. [(flag) * cornerCount] [Size: <= maxCorners]
/// @param[out] cornerPolys The polygon reference for each corner. [(polyRef) * cornerCount]
/// @param[out] cornerPolys The polygon reference for each corner. [(polyRef) * cornerCount]
/// @param[out] cornerJumps The jump types for each corner. [(jumpType) * cornerCount]
/// [Size: <= @p maxCorners]
/// @param[in] maxCorners The maximum number of corners the buffers can hold.
/// @param[in] navquery The query object used to build the corridor.
/// @param[in] filter The filter to apply to the operation.
/// @return The number of corners returned in the corner buffers. [0 <= value <= @p maxCorners]
int findCorners(float* cornerVerts, unsigned char* cornerFlags,
dtPolyRef* cornerPolys, const int maxCorners,
dtNavMeshQuery* navquery, const dtQueryFilter* filter);
dtPolyRef* cornerPolys, unsigned char* cornerJumps,
const int maxCorners, dtNavMeshQuery* navquery, const dtQueryFilter* filter);
/// Attempts to optimize the path if the specified point is visible from the current position.
/// @param[in] next The point to search toward. [(x, y, z])

View File

@ -879,7 +879,7 @@ void dtCrowd::update(const float dt, dtCrowdAgentDebugInfo* debug)
continue;
// Find corners for steering
ag->ncorners = ag->corridor.findCorners(ag->cornerVerts, ag->cornerFlags, ag->cornerPolys,
ag->ncorners = ag->corridor.findCorners(ag->cornerVerts, ag->cornerFlags, ag->cornerPolys, ag->cornerJumps,
DT_CROWDAGENT_MAX_CORNERS, m_navquery, &m_filters[ag->params.queryFilterType]);
// Check to see if the corner after the next corner is directly visible,

View File

@ -198,6 +198,7 @@ may be needed. E.g. If you move the target, check #getLastPoly() to see if it i
dtPathCorridor::dtPathCorridor() :
m_path(0),
m_jumpTypes(0),
m_npath(0),
m_maxPath(0)
{
@ -208,6 +209,7 @@ dtPathCorridor::dtPathCorridor() :
dtPathCorridor::~dtPathCorridor()
{
rdFree(m_path);
rdFree(m_jumpTypes);
}
/// @par
@ -250,8 +252,8 @@ So if 10 corners are needed, the buffers should be sized for 11 corners.
If the target is within range, it will be the last corner and have a polygon reference id of zero.
*/
int dtPathCorridor::findCorners(float* cornerVerts, unsigned char* cornerFlags,
dtPolyRef* cornerPolys, const int maxCorners,
dtNavMeshQuery* navquery, const dtQueryFilter* /*filter*/)
dtPolyRef* cornerPolys, unsigned char* cornerJumps,
const int maxCorners, dtNavMeshQuery* navquery, const dtQueryFilter* /*filter*/)
{
rdAssert(m_path);
rdAssert(m_npath);
@ -259,8 +261,8 @@ int dtPathCorridor::findCorners(float* cornerVerts, unsigned char* cornerFlags,
static const float MIN_TARGET_DIST = 0.01f;
int ncorners = 0;
navquery->findStraightPath(m_pos, m_target, m_path, m_npath,
cornerVerts, cornerFlags, cornerPolys, &ncorners, maxCorners);
navquery->findStraightPath(m_pos, m_target, m_path, m_jumpTypes, m_npath,
cornerVerts, cornerFlags, cornerPolys, cornerJumps, &ncorners, maxCorners);
// Prune points in the beginning of the path which are too close.
while (ncorners)