mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Recast: group all unconnected poly's (optimization & bug fix)
Reserve poly group ID 1 (defined as DT_STRAY_POLY_GROUP) for unlinked poly's. The game skips all poly's that are marked 1. Previously, before this optimization, the AI would become stuck when they walk over an island who's poly's are marked 1 as we didn't take this engine feature into account in Recast. - Recast will now render all poly's marked 'DT_STRAY_POLY_GROUP' as red. - This patch also reduces the number of poly group id's and therefore reduces the overall size of the NavMesh.
This commit is contained in:
parent
c215fcb220
commit
d03dfe645f
@ -435,11 +435,11 @@ void Editor::saveAll(std::string path, dtNavMesh* mesh)
|
||||
|
||||
// TODO: this has to be done during navmesh init, not here!!!
|
||||
LinkTableData linkData;
|
||||
buildLinkTable(mesh, linkData);
|
||||
const int tableSize = buildLinkTable(mesh, linkData);
|
||||
|
||||
header.params.disjointPolyGroupCount = linkData.setCount;
|
||||
header.params.reachabilityTableCount = m_reachabilityTableCount;
|
||||
header.params.reachabilityTableSize = (linkData.setCount - 1) * ((linkData.setCount + 31) / 32) + (linkData.setCount - 1) / 32;
|
||||
header.params.reachabilityTableSize = tableSize;
|
||||
|
||||
fwrite(&header, sizeof(NavMeshSetHeader), 1, fp);
|
||||
|
||||
@ -458,7 +458,7 @@ void Editor::saveAll(std::string path, dtNavMesh* mesh)
|
||||
fwrite(tile->data, tile->dataSize, 1, fp);
|
||||
}
|
||||
|
||||
std::vector<int> reachability(header.params.reachabilityTableSize, 0);
|
||||
std::vector<int> reachability(tableSize, 0);
|
||||
for (int i = 0; i < linkData.setCount; i++)
|
||||
setReachable(reachability, linkData.setCount, i, i, true);
|
||||
|
||||
|
@ -98,8 +98,12 @@ void unpatchTileGame(dtMeshTile* t)
|
||||
}
|
||||
}
|
||||
|
||||
void buildLinkTable(dtNavMesh* mesh, LinkTableData& data)
|
||||
int buildLinkTable(dtNavMesh* mesh, LinkTableData& data)
|
||||
{
|
||||
// Reserve the first 2 poly groups
|
||||
data.insert_new(); // 0 = technically usable for normal poly groups, but for simplicity we reserve it for now.
|
||||
data.insert_new(); // 1 = DT_STRAY_POLY_GROUP.
|
||||
|
||||
//clear all labels
|
||||
for (int i = 0; i < mesh->getMaxTiles(); ++i)
|
||||
{
|
||||
@ -118,7 +122,7 @@ void buildLinkTable(dtNavMesh* mesh, LinkTableData& data)
|
||||
{
|
||||
dtMeshTile* tile = mesh->getTile(i);
|
||||
if (!tile || !tile->header || !tile->dataSize) continue;
|
||||
int pcount = tile->header->polyCount;
|
||||
const int pcount = tile->header->polyCount;
|
||||
for (int j = 0; j < pcount; j++)
|
||||
{
|
||||
dtPoly& poly = tile->polys[j];
|
||||
@ -132,16 +136,21 @@ void buildLinkTable(dtNavMesh* mesh, LinkTableData& data)
|
||||
|
||||
if (p->disjointSetId != (unsigned short)-1)
|
||||
nlabels.insert(p->disjointSetId);
|
||||
|
||||
plink = l.next;
|
||||
}
|
||||
if (nlabels.empty())
|
||||
{
|
||||
poly.disjointSetId = (unsigned short)data.insert_new();
|
||||
if (poly.firstLink == DT_NULL_LINK)
|
||||
poly.disjointSetId = DT_STRAY_POLY_GROUP;
|
||||
else
|
||||
poly.disjointSetId = (unsigned short)data.insert_new();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto l = *nlabels.begin();
|
||||
int l = *nlabels.begin();
|
||||
poly.disjointSetId = (unsigned short)l;
|
||||
|
||||
for (const int nl : nlabels)
|
||||
data.set_union(l, nl);
|
||||
}
|
||||
@ -149,11 +158,12 @@ void buildLinkTable(dtNavMesh* mesh, LinkTableData& data)
|
||||
}
|
||||
}
|
||||
//second pass
|
||||
// TODO[ AMOS ]: is this necessary?
|
||||
for (int i = 0; i < mesh->getMaxTiles(); ++i)
|
||||
{
|
||||
dtMeshTile* tile = mesh->getTile(i);
|
||||
if (!tile || !tile->header || !tile->dataSize) continue;
|
||||
int pcount = tile->header->polyCount;
|
||||
const int pcount = tile->header->polyCount;
|
||||
for (int j = 0; j < pcount; j++)
|
||||
{
|
||||
dtPoly& poly = tile->polys[j];
|
||||
@ -161,6 +171,8 @@ void buildLinkTable(dtNavMesh* mesh, LinkTableData& data)
|
||||
poly.disjointSetId = (unsigned short)id;
|
||||
}
|
||||
}
|
||||
|
||||
return (data.setCount-1) * ((data.setCount + 31) / 32) + (data.setCount-1) / 32;
|
||||
}
|
||||
void setReachable(std::vector<int>& data, int count, int id1, int id2, bool value)
|
||||
{
|
||||
|
@ -14,7 +14,7 @@ void unpatchHeaderGame(NavMeshSetHeader& h);
|
||||
void patchTileGame(dtMeshTile* t);
|
||||
void unpatchTileGame(dtMeshTile* t);
|
||||
|
||||
void buildLinkTable(dtNavMesh* mesh, LinkTableData& data);
|
||||
int buildLinkTable(dtNavMesh* mesh, LinkTableData& data);
|
||||
void setReachable(std::vector<int>& data, int count, int id1, int id2, bool value);
|
||||
|
||||
#endif // GAMEUTILS_H
|
@ -22,18 +22,31 @@
|
||||
#include "Detour/Include/DetourCommon.h"
|
||||
#include "Detour/Include/DetourNode.h"
|
||||
|
||||
static unsigned int getPolySurfaceColor(const dtPoly* poly, duDebugDraw* dd)
|
||||
{
|
||||
return poly->disjointSetId == DT_STRAY_POLY_GROUP
|
||||
? duTransCol(duRGBA(240,20,10,255), 170)
|
||||
: duTransCol(dd->areaToCol(poly->getArea()), 170);
|
||||
}
|
||||
|
||||
static unsigned int getPolyBoundaryColor(const dtPoly* poly, const bool inner)
|
||||
{
|
||||
return poly->disjointSetId == DT_STRAY_POLY_GROUP
|
||||
? inner ? duRGBA(32,24,0,32) : duRGBA(32,24,0,220)
|
||||
: inner ? duRGBA(0,48,64,32) : duRGBA(0,48,64,220);
|
||||
}
|
||||
|
||||
static void drawOffMeshConnectionRefPosition(duDebugDraw* dd, const dtOffMeshConnection* con)
|
||||
{
|
||||
float refPosDir[3];
|
||||
dtCalcOffMeshRefPos(con->refPos, con->refYaw, DT_OFFMESH_CON_REFPOS_OFFSET, refPosDir);
|
||||
|
||||
duAppendArrow(dd, con->refPos[0], con->refPos[1], con->refPos[2],
|
||||
refPosDir[0], refPosDir[1], refPosDir[2], 0.f, 10.f, duRGBA(255, 255, 0, 255));
|
||||
refPosDir[0], refPosDir[1], refPosDir[2], 0.f, 10.f, duRGBA(255,255,0,255));
|
||||
}
|
||||
|
||||
static void drawPolyBoundaries(duDebugDraw* dd, const dtMeshTile* tile,
|
||||
const unsigned int col, const float linew,
|
||||
bool inner)
|
||||
const float linew, bool inner)
|
||||
{
|
||||
static const float thr = 0.01f*0.01f;
|
||||
|
||||
@ -49,7 +62,7 @@ static void drawPolyBoundaries(duDebugDraw* dd, const dtMeshTile* tile,
|
||||
|
||||
for (int j = 0, nj = (int)p->vertCount; j < nj; ++j)
|
||||
{
|
||||
unsigned int c = col;
|
||||
unsigned int c = getPolyBoundaryColor(p, inner);
|
||||
if (inner)
|
||||
{
|
||||
if (p->neis[j] == 0) continue;
|
||||
@ -147,7 +160,7 @@ static void drawMeshTile(duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMesh
|
||||
if (flags & DU_DRAWNAVMESH_COLOR_TILES)
|
||||
col = tileColor;
|
||||
else
|
||||
col = duTransCol(dd->areaToCol(p->getArea()), 170);
|
||||
col = getPolySurfaceColor(p, dd);
|
||||
}
|
||||
|
||||
for (int j = 0; j < pd->triCount; ++j)
|
||||
@ -164,11 +177,11 @@ static void drawMeshTile(duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMesh
|
||||
}
|
||||
dd->end();
|
||||
|
||||
// Draw inter poly boundaries
|
||||
drawPolyBoundaries(dd, tile, duRGBA(0,48,64,32), 1.5f, true);
|
||||
// Draw inner poly boundaries
|
||||
drawPolyBoundaries(dd, tile, 1.5f, true);
|
||||
|
||||
// Draw outer poly boundaries
|
||||
drawPolyBoundaries(dd, tile, duRGBA(0,48,64,220), 2.5f, false);
|
||||
drawPolyBoundaries(dd, tile, 2.5f, false);
|
||||
|
||||
// Draw poly centers
|
||||
drawPolyCenters(dd, tile, duRGBA(255, 255, 255, 100), 1.0f);
|
||||
|
@ -63,6 +63,10 @@ typedef unsigned int dtTileRef;
|
||||
/// @ingroup detour
|
||||
static const int DT_VERTS_PER_POLYGON = 6;
|
||||
|
||||
/// A poly group that is unconnected and considered 'trash'; see [r5apex_ds + CA88B2].
|
||||
/// For reference, r2 single player NavMeshes also marked everything unconnected as '1'.
|
||||
static const unsigned short DT_STRAY_POLY_GROUP = 1;
|
||||
|
||||
/// @{
|
||||
/// @name Tile Serialization Constants
|
||||
/// These constants are used to detect whether a navigation tile's data
|
||||
|
Loading…
x
Reference in New Issue
Block a user