mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Recast: initial working implementation of traverse link generation algorithm
Traversing now works in-game, but there's still work needed to polish the algorithm and creating a proper lookup for jump types as currently only 1 jump type is supported.
This commit is contained in:
parent
c12690b33c
commit
acaf4cf32b
@ -353,6 +353,12 @@ void Editor::handleUpdate(const float dt)
|
||||
updateToolStates(dt);
|
||||
}
|
||||
|
||||
void Editor::buildTraverseLinks()
|
||||
{
|
||||
if (!m_navMesh) return;
|
||||
dtCreateTraverseLinks(m_navMesh);
|
||||
}
|
||||
|
||||
void Editor::buildStaticPathingData()
|
||||
{
|
||||
if (!m_navMesh) return;
|
||||
|
@ -145,6 +145,7 @@ public:
|
||||
else
|
||||
m_editor->buildTile(m_hitPos);
|
||||
|
||||
m_editor->buildTraverseLinks();
|
||||
m_editor->buildStaticPathingData();
|
||||
}
|
||||
}
|
||||
@ -597,6 +598,7 @@ void Editor_TileMesh::buildAllTiles()
|
||||
}
|
||||
}
|
||||
|
||||
buildTraverseLinks();
|
||||
buildStaticPathingData();
|
||||
|
||||
// Start the build process.
|
||||
|
@ -239,6 +239,7 @@ public:
|
||||
void resetCommonSettings();
|
||||
void handleCommonSettings();
|
||||
|
||||
void buildTraverseLinks();
|
||||
void buildStaticPathingData();
|
||||
|
||||
private:
|
||||
|
@ -415,6 +415,10 @@ struct dtMeshHeader
|
||||
/// @ingroup detour
|
||||
struct dtMeshTile
|
||||
{
|
||||
public:
|
||||
unsigned int allocLink();
|
||||
void freeLink(unsigned int link);
|
||||
|
||||
unsigned int salt; ///Counter describing modifications to the tile.
|
||||
|
||||
unsigned int linksFreeList; ///Index to the next free link.
|
||||
|
@ -182,6 +182,12 @@ private:
|
||||
/// @return True if the disjoint set data was successfully created.
|
||||
bool dtCreateDisjointPolyGroups(dtNavMesh* nav, dtDisjointSet& disjoint);
|
||||
|
||||
/// Builds navigation mesh traverse links from the provided navmesh.
|
||||
/// @ingroup detour
|
||||
/// @param[in] nav The navigation mesh to use.
|
||||
/// @return True if the traverse links were successfully created.
|
||||
bool dtCreateTraverseLinks(dtNavMesh* nav);
|
||||
|
||||
/// Builds navigation mesh static traversal table from the provided navmesh.
|
||||
/// @ingroup detour
|
||||
/// @param[in] nav The navigation mesh to use.
|
||||
|
@ -115,19 +115,19 @@ inline int computeTileHash(int x, int y, const int mask)
|
||||
return (int)(n & mask);
|
||||
}
|
||||
|
||||
inline unsigned int allocLink(dtMeshTile* tile)
|
||||
unsigned int dtMeshTile::allocLink()
|
||||
{
|
||||
if (tile->linksFreeList == DT_NULL_LINK)
|
||||
if (linksFreeList == DT_NULL_LINK)
|
||||
return DT_NULL_LINK;
|
||||
unsigned int link = tile->linksFreeList;
|
||||
tile->linksFreeList = tile->links[link].next;
|
||||
unsigned int link = linksFreeList;
|
||||
linksFreeList = links[link].next;
|
||||
return link;
|
||||
}
|
||||
|
||||
inline void freeLink(dtMeshTile* tile, unsigned int link)
|
||||
void dtMeshTile::freeLink(unsigned int link)
|
||||
{
|
||||
tile->links[link].next = tile->linksFreeList;
|
||||
tile->linksFreeList = link;
|
||||
links[link].next = linksFreeList;
|
||||
linksFreeList = link;
|
||||
}
|
||||
|
||||
int dtCalcTraversalTableCellIndex(const int numPolyGroups,
|
||||
@ -409,7 +409,7 @@ void dtNavMesh::unconnectLinks(dtMeshTile* tile, dtMeshTile* target)
|
||||
poly->firstLink = nj;
|
||||
else
|
||||
tile->links[pj].next = nj;
|
||||
freeLink(tile, j);
|
||||
tile->freeLink(j);
|
||||
j = nj;
|
||||
}
|
||||
else
|
||||
@ -453,7 +453,7 @@ void dtNavMesh::connectExtLinks(dtMeshTile* tile, dtMeshTile* target, int side)
|
||||
int nnei = findConnectingPolys(va,vb, target, rdOppositeTile(dir), nei,neia,4);
|
||||
for (int k = 0; k < nnei; ++k)
|
||||
{
|
||||
unsigned int idx = allocLink(tile);
|
||||
unsigned int idx = tile->allocLink();
|
||||
if (idx != DT_NULL_LINK)
|
||||
{
|
||||
dtLink* link = &tile->links[idx];
|
||||
@ -528,7 +528,7 @@ void dtNavMesh::connectExtOffMeshLinks(dtMeshTile* tile, dtMeshTile* target, int
|
||||
rdVcopy(v, nearestPt);
|
||||
|
||||
// Link off-mesh connection to target poly.
|
||||
unsigned int idx = allocLink(target);
|
||||
unsigned int idx = target->allocLink();
|
||||
dtLink* link = nullptr;
|
||||
if (idx != DT_NULL_LINK)
|
||||
{
|
||||
@ -550,7 +550,7 @@ void dtNavMesh::connectExtOffMeshLinks(dtMeshTile* tile, dtMeshTile* target, int
|
||||
dtLink* tlink = nullptr;
|
||||
if (targetCon->flags & DT_OFFMESH_CON_BIDIR)
|
||||
{
|
||||
tidx = allocLink(tile);
|
||||
tidx = tile->allocLink();
|
||||
if (tidx != DT_NULL_LINK)
|
||||
{
|
||||
const unsigned short landPolyIdx = (unsigned short)decodePolyIdPoly(ref);
|
||||
@ -611,7 +611,7 @@ void dtNavMesh::connectIntLinks(dtMeshTile* tile)
|
||||
// Skip hard and non-internal edges.
|
||||
if (poly->neis[j] == 0 || (poly->neis[j] & DT_EXT_LINK)) continue;
|
||||
|
||||
unsigned int idx = allocLink(tile);
|
||||
unsigned int idx = tile->allocLink();
|
||||
if (idx != DT_NULL_LINK)
|
||||
{
|
||||
dtLink* link = &tile->links[idx];
|
||||
@ -657,7 +657,7 @@ void dtNavMesh::baseOffMeshLinks(dtMeshTile* tile)
|
||||
rdVcopy(v, nearestPt);
|
||||
|
||||
// Link off-mesh connection to target poly.
|
||||
unsigned int idx = allocLink(tile);
|
||||
unsigned int idx = tile->allocLink();
|
||||
if (idx != DT_NULL_LINK)
|
||||
{
|
||||
dtLink* link = &tile->links[idx];
|
||||
@ -674,7 +674,7 @@ void dtNavMesh::baseOffMeshLinks(dtMeshTile* tile)
|
||||
}
|
||||
|
||||
// Start end-point is always connect back to off-mesh connection.
|
||||
unsigned int tidx = allocLink(tile);
|
||||
unsigned int tidx = tile->allocLink();
|
||||
if (tidx != DT_NULL_LINK)
|
||||
{
|
||||
const unsigned short landPolyIdx = (unsigned short)decodePolyIdPoly(ref);
|
||||
|
@ -461,6 +461,103 @@ bool dtCreateDisjointPolyGroups(dtNavMesh* nav, dtDisjointSet& disjoint)
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: create lookup table and look for distance + slope to determine the
|
||||
// correct jumpType.
|
||||
// TODO: make sure we don't generate duplicate pairs of jump types between
|
||||
// 2 polygons.
|
||||
static void connectTileTraverseLinks(dtNavMesh* const nav, dtMeshTile* const tile)
|
||||
{
|
||||
for (int i = 0; i < tile->header->polyCount; ++i)
|
||||
{
|
||||
dtPoly* const startPoly = &tile->polys[i];
|
||||
|
||||
for (int j = 0; j < startPoly->vertCount; ++j)
|
||||
{
|
||||
// Hard edges only!
|
||||
if (startPoly->neis[j] != 0)
|
||||
continue;
|
||||
|
||||
// Polygon 1 edge
|
||||
const float* const startPolySpos = &tile->verts[startPoly->verts[j] * 3];
|
||||
const float* const startPolyEpos = &tile->verts[startPoly->verts[(j + 1) % startPoly->vertCount] * 3];
|
||||
|
||||
for (int k = 0; k < tile->header->polyCount; ++k)
|
||||
{
|
||||
if (i == k) continue; // Skip self
|
||||
|
||||
dtPoly* const endPoly = &tile->polys[k];
|
||||
|
||||
for (int m = 0; m < endPoly->vertCount; ++m)
|
||||
{
|
||||
// Hard edges only!
|
||||
if (endPoly->neis[m] != 0)
|
||||
continue;
|
||||
|
||||
// Polygon 2 edge
|
||||
const float* const endPolySpos = &tile->verts[endPoly->verts[m] * 3];
|
||||
const float* const endPolyEpos = &tile->verts[endPoly->verts[(m + 1) % endPoly->vertCount] * 3];
|
||||
|
||||
// TODO: calculate edge midpoint first !!!
|
||||
const unsigned char dist1 = dtCalcLinkDistance(startPolySpos, endPolyEpos);
|
||||
const unsigned char dist2 = dtCalcLinkDistance(startPolyEpos, endPolySpos);
|
||||
|
||||
// TODO: needs lookup table for distance !!!
|
||||
if ((dist1 >= 10 && dist1 <= 30) && (dist2 >= 10 && dist2 <= 30))
|
||||
{
|
||||
const unsigned int idx = tile->allocLink();
|
||||
|
||||
if (idx == DT_NULL_LINK) // TODO: should move on to next tile.
|
||||
continue;
|
||||
|
||||
dtLink* const forwardLink = &tile->links[idx];
|
||||
|
||||
forwardLink->ref = nav->getPolyRefBase(tile) | (unsigned int)k;
|
||||
forwardLink->edge = (unsigned char)j;
|
||||
forwardLink->side = 0xFF;
|
||||
forwardLink->next = startPoly->firstLink;
|
||||
startPoly->firstLink = idx;
|
||||
forwardLink->traverseType = 1;
|
||||
forwardLink->traverseDist = dist1;
|
||||
|
||||
const unsigned int tidx = tile->allocLink();
|
||||
|
||||
if (tidx == DT_NULL_LINK) // TODO: should move on to next tile.
|
||||
continue;
|
||||
|
||||
dtLink* const reverseLink = &tile->links[tidx];
|
||||
|
||||
reverseLink->ref = nav->getPolyRefBase(tile) | (unsigned int)i;
|
||||
reverseLink->edge = (unsigned char)m;
|
||||
reverseLink->side = 0xFF;
|
||||
reverseLink->next = endPoly->firstLink;
|
||||
endPoly->firstLink = tidx;
|
||||
reverseLink->traverseType = 1;
|
||||
reverseLink->traverseDist = dist2;
|
||||
|
||||
forwardLink->reverseLink = (unsigned short)tidx;
|
||||
reverseLink->reverseLink = (unsigned short)idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool dtCreateTraverseLinks(dtNavMesh* nav)
|
||||
{
|
||||
rdAssert(nav);
|
||||
|
||||
for (int i = 0; i < nav->getMaxTiles(); i++)
|
||||
{
|
||||
dtMeshTile* tile = nav->getTile(i);
|
||||
if (!tile->header) continue;
|
||||
|
||||
connectTileTraverseLinks(nav, tile);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// todo(amos): remove param 'tableCount' and make struct 'dtTraversalTableCreateParams'
|
||||
bool dtCreateTraversalTableData(dtNavMesh* nav, const dtDisjointSet& disjoint, const int tableCount)
|
||||
{
|
||||
@ -876,18 +973,6 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
#if DT_NAVMESH_SET_VERSION >= 8
|
||||
// Polygon cells.
|
||||
for (int i = 0; i < (int)cellItems.size(); i++)
|
||||
{
|
||||
const CellItem& cellItem = cellItems[i];
|
||||
dtCell& cell = navCells[i];
|
||||
|
||||
rdVcopy(cell.pos, cellItem.pos);
|
||||
cell.polyIndex = cellItem.polyIndex;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Store polygons
|
||||
// Mesh polys
|
||||
@ -1040,9 +1125,21 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if DT_NAVMESH_SET_VERSION >= 8
|
||||
// Polygon cells.
|
||||
for (int i = 0; i < (int)cellItems.size(); i++)
|
||||
{
|
||||
const CellItem& cellItem = cellItems[i];
|
||||
dtCell& cell = navCells[i];
|
||||
|
||||
rdVcopy(cell.pos, cellItem.pos);
|
||||
cell.polyIndex = cellItem.polyIndex;
|
||||
}
|
||||
#endif
|
||||
|
||||
rdFree(offMeshConClass);
|
||||
|
||||
|
||||
*outData = data;
|
||||
*outDataSize = dataSize;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user