Recast: fix bugs in dtNavMesh::addTile and dtCreateNavMeshData

Some data that is in between the poly's and links weren't skipped properly. The engine skips this data in dtNavMesh::addTile, we didn't. This is now skipped properly by advancing over it before going over the links. The 2nd and 3rd bug was that the poly's end pointer, and off-mesh connections end pointer was set to the data size of the poly's and off-mesh connections rather than the poly and off-mesh con count. This small oversight has been fixed and the end pointers are now set correctly. The function dtCreateNavMeshData has also been updated to take this data into account correctly, it was using the Titanfall 2 NavMesh (NavMesh Set Version 5), structure sizes but this has been changed in Apex (NavMesh Set Version 7 and 8). These fixes did reduce the NavMesh's file size by a few kilobytes per megabyte.
This commit is contained in:
Kawe Mazidjatari 2024-07-16 19:35:08 +02:00
parent 2888930893
commit 961b4e2e51
3 changed files with 18 additions and 17 deletions

View File

@ -329,7 +329,7 @@ struct dtMeshHeader
unsigned int userId; ///< The user defined id of the tile.
int polyCount; ///< The number of polygons in the tile.
int polyCountMultiplier;
int unkPerPoly;
int vertCount; ///< The number of vertices in the tile.
int maxLinkCount; ///< The number of allocated links.

View File

@ -1042,16 +1042,23 @@ dtStatus dtNavMesh::addTile(unsigned char* data, int dataSize, int flags,
const int detailTrisSize = rdAlign4(sizeof(unsigned char)*4*header->detailTriCount);
const int bvtreeSize = rdAlign4(sizeof(dtBVNode)*header->bvNodeCount);
const int offMeshLinksSize = rdAlign4(sizeof(dtOffMeshConnection)*header->offMeshConCount);
const int polyCount = header->polyCount;
const int polyCountMultiplier = header->unkPerPoly;
const int offMeshConCount = header->offMeshConCount;
unsigned char* d = data + headerSize;
tile->verts = rdGetThenAdvanceBufferPointer<float>(d, vertsSize);
tile->polys = rdGetThenAdvanceBufferPointer<dtPoly>(d, polysSize);
tile->polysEnd = &tile->polys[polyCount];
d = (unsigned char*)(tile->polysEnd) + polyCount * polyCountMultiplier;
tile->links = rdGetThenAdvanceBufferPointer<dtLink>(d, linksSize);
tile->detailMeshes = rdGetThenAdvanceBufferPointer<dtPolyDetail>(d, detailMeshesSize);
tile->detailVerts = rdGetThenAdvanceBufferPointer<float>(d, detailVertsSize);
tile->detailTris = rdGetThenAdvanceBufferPointer<unsigned char>(d, detailTrisSize);
tile->bvTree = rdGetThenAdvanceBufferPointer<dtBVNode>(d, bvtreeSize);
tile->offMeshCons = rdGetThenAdvanceBufferPointer<dtOffMeshConnection>(d, offMeshLinksSize);
tile->offMeshConsEnd = &tile->offMeshCons[offMeshConCount];
// If there are no items in the bvtree, reset the tree pointer.
if (!bvtreeSize)
@ -1065,8 +1072,6 @@ dtStatus dtNavMesh::addTile(unsigned char* data, int dataSize, int flags,
// Init tile.
tile->header = header;
tile->polysEnd = &tile->polys[polysSize];
tile->offMeshConsEnd = &tile->offMeshCons[offMeshLinksSize];
tile->data = data;
tile->dataSize = dataSize;
tile->flags = flags;

View File

@ -665,7 +665,7 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
detailTriCount += nv-2;
}
}
int sth_per_poly_thingy = 0;
// Calculate data size
const int headerSize = rdAlign4(sizeof(dtMeshHeader));
const int vertsSize = rdAlign4(sizeof(float)*3*totVertCount);
@ -677,11 +677,12 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
const int bvTreeSize = params->buildBvTree ? rdAlign4(sizeof(dtBVNode)*params->polyCount*2) : 0;
const int offMeshConsSize = rdAlign4(sizeof(dtOffMeshConnection)*storedOffMeshConCount);
const int sthSize = sth_per_poly_thingy * totPolyCount * 4;
int unkPerPoly = 0; // TODO: this data has to be reversed still from the NavMesh!
const int sthSize = unkPerPoly * totPolyCount;
const int dataSize = headerSize + vertsSize + polysSize + linksSize +
detailMeshesSize + detailVertsSize + detailTrisSize +
bvTreeSize + offMeshConsSize+ sthSize;
bvTreeSize + offMeshConsSize + sthSize;
//printf("%i %i %i %i(%i links) %i %i %i %i %i\n", headerSize, vertsSize, polysSize, linksSize, maxLinkCount, detailMeshesSize, detailVertsSize, detailTrisSize, bvTreeSize, offMeshConsSize);
//printf("%i\n", dataSize);
@ -695,17 +696,11 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
memset(data, 0, dataSize);
unsigned char* d = data;
// vertsSize == sizeof(float) * detailVertCount * 3
// polysSize == sizeof(dtPoly) * polyCount
// linksSize == sizeof(dtLink) * maxLinkCount
// detailMeshesSize = sizeof(dtPolyDetail)*params->polyCount
dtMeshHeader* header = rdGetThenAdvanceBufferPointer<dtMeshHeader>(d, headerSize);
float* navVerts = rdGetThenAdvanceBufferPointer<float>(d, vertsSize);
dtPoly* navPolys = rdGetThenAdvanceBufferPointer<dtPoly>(d, polysSize);
//d += sthSize; //dunno hope it crashes
unsigned int* some_arr = rdGetThenAdvanceBufferPointer<unsigned int>(d, sthSize);
unsigned int* unknownArray = rdGetThenAdvanceBufferPointer<unsigned int>(d, sthSize);
d += linksSize; // Ignore links; just leave enough space for them. They'll be created on load.
//dtLink* links = rdGetThenAdvanceBufferPointer<dtLink>(d, linksSize);
dtPolyDetail* navDMeshes = rdGetThenAdvanceBufferPointer<dtPolyDetail>(d, detailMeshesSize);
@ -714,9 +709,10 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
dtBVNode* navBvtree = rdGetThenAdvanceBufferPointer<dtBVNode>(d, bvTreeSize);
dtOffMeshConnection* offMeshCons = rdGetThenAdvanceBufferPointer<dtOffMeshConnection>(d, offMeshConsSize);
for(int i=0;i<sth_per_poly_thingy*totPolyCount;i++)
some_arr[i] = rand();
rdIgnoreUnused(unknownArray);
//for(int i=0;i<unkPerPoly*totPolyCount;i++)
// unknownArray[i] = rand();
// Store header
header->magic = DT_NAVMESH_MAGIC;
header->version = DT_NAVMESH_VERSION;
@ -740,7 +736,7 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
header->walkableClimb = params->walkableClimb;
header->offMeshConCount = storedOffMeshConCount;
header->bvNodeCount = params->buildBvTree ? params->polyCount*2 : 0;
header->polyCountMultiplier = sth_per_poly_thingy;
header->unkPerPoly = unkPerPoly;
const int offMeshVertsBase = params->vertCount;
const int offMeshPolyBase = params->polyCount;