diff --git a/src/naveditor/Editor.cpp b/src/naveditor/Editor.cpp index b49d61a2..2502455e 100644 --- a/src/naveditor/Editor.cpp +++ b/src/naveditor/Editor.cpp @@ -710,6 +710,11 @@ void Editor::buildStaticPathingData() m_ctx->log(RC_LOG_ERROR, "buildStaticPathingData: Failed to build traverse links."); } + if (!dtUpdateDisjointPolyGroups(m_navMesh, data)) + { + m_ctx->log(RC_LOG_ERROR, "buildStaticPathingData: Failed to update disjoint poly groups."); + } + if (!dtCreateTraverseTableData(m_navMesh, data, NavMesh_GetTraverseTableCountForNavMeshType(m_selectedNavMeshType))) { m_ctx->log(RC_LOG_ERROR, "buildStaticPathingData: Failed to build traverse table data."); diff --git a/src/thirdparty/recast/Detour/Include/DetourNavMeshBuilder.h b/src/thirdparty/recast/Detour/Include/DetourNavMeshBuilder.h index 5ab82f37..31b07d8f 100644 --- a/src/thirdparty/recast/Detour/Include/DetourNavMeshBuilder.h +++ b/src/thirdparty/recast/Detour/Include/DetourNavMeshBuilder.h @@ -182,6 +182,13 @@ private: /// @return True if the disjoint set data was successfully created. bool dtCreateDisjointPolyGroups(dtNavMesh* nav, dtDisjointSet& disjoint); +/// Updates navigation mesh disjoint poly groups from the provided navmesh. +/// @ingroup detour +/// @param[in] nav The navigation mesh to use. +/// @param[Out] disjoint The disjoint set data. +/// @return True if the disjoint set data was successfully updated. +bool dtUpdateDisjointPolyGroups(dtNavMesh* nav, dtDisjointSet& disjoint); + /// Builds navigation mesh static traverse table from the provided navmesh. /// @ingroup detour /// @param[in] nav The navigation mesh to use. diff --git a/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp b/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp index 4b578be2..404237d6 100644 --- a/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp +++ b/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp @@ -277,7 +277,7 @@ bool dtCreateDisjointPolyGroups(dtNavMesh* nav, dtDisjointSet& disjoint) } } - // First pass to group linked and unlinked poly islands. + // First pass to group poly islands. std::set linkedGroups; for (int i = 0; i < nav->getMaxTiles(); ++i) { @@ -315,14 +315,7 @@ bool dtCreateDisjointPolyGroups(dtNavMesh* nav, dtDisjointSet& disjoint) const bool noLinkedGroups = linkedGroups.empty(); if (noLinkedGroups) - { - // This poly isn't connected to anything, mark it so the game - // won't consider this poly in path generation. - if (poly.firstLink == DT_NULL_LINK) - poly.groupId = DT_STRAY_POLY_GROUP; - else - poly.groupId = (unsigned short)disjoint.insertNew(); - } + poly.groupId = (unsigned short)disjoint.insertNew(); else { const unsigned short rootGroup = *linkedGroups.begin(); @@ -354,38 +347,6 @@ bool dtCreateDisjointPolyGroups(dtNavMesh* nav, dtDisjointSet& disjoint) } } - // Gather all unique polygroups and map them to a contiguous range. - std::map groupMap; - disjoint.init(DT_FIRST_USABLE_POLY_GROUP); - - for (int i = 0; i < nav->getMaxTiles(); ++i) - { - dtMeshTile* tile = nav->getTile(i); - if (!tile || !tile->header || !tile->dataSize) continue; - const int pcount = tile->header->polyCount; - for (int j = 0; j < pcount; j++) - { - dtPoly& poly = tile->polys[j]; - unsigned short oldId = poly.groupId; - if (oldId != DT_STRAY_POLY_GROUP && groupMap.find(oldId) == groupMap.end()) - groupMap[oldId] = (unsigned short)disjoint.insertNew(); - } - } - - // Fourth pass to apply the new mapping to all polys. - for (int i = 0; i < nav->getMaxTiles(); ++i) - { - dtMeshTile* tile = nav->getTile(i); - if (!tile || !tile->header || !tile->dataSize) continue; - const int pcount = tile->header->polyCount; - for (int j = 0; j < pcount; j++) - { - dtPoly& poly = tile->polys[j]; - if (poly.groupId != DT_STRAY_POLY_GROUP) - poly.groupId = groupMap[poly.groupId]; - } - } - // Third pass to handle off-mesh connections. // note(amos): this has to happen after the first and second pass as these // are for grouping directly connected polygons together, else groups linked @@ -433,6 +394,61 @@ bool dtCreateDisjointPolyGroups(dtNavMesh* nav, dtDisjointSet& disjoint) return true; } +bool dtUpdateDisjointPolyGroups(dtNavMesh* nav, dtDisjointSet& disjoint) +{ + // Fourth pass to mark all unlinked poly's. + for (int i = 0; i < nav->getMaxTiles(); ++i) + { + dtMeshTile* tile = nav->getTile(i); + if (!tile || !tile->header || !tile->dataSize) continue; + const int pcount = tile->header->polyCount; + for (int j = 0; j < pcount; j++) + { + dtPoly& poly = tile->polys[j]; + + // This poly isn't connected to anything, mark it so the game + // won't consider this poly in path generation. + if (poly.firstLink == DT_NULL_LINK) + poly.groupId = DT_STRAY_POLY_GROUP; + } + } + + // Gather all unique polygroups and map them to a contiguous range. + std::map groupMap; + disjoint.init(DT_FIRST_USABLE_POLY_GROUP); + + for (int i = 0; i < nav->getMaxTiles(); ++i) + { + dtMeshTile* tile = nav->getTile(i); + if (!tile || !tile->header || !tile->dataSize) continue; + const int pcount = tile->header->polyCount; + for (int j = 0; j < pcount; j++) + { + dtPoly& poly = tile->polys[j]; + unsigned short oldId = poly.groupId; + if (oldId != DT_STRAY_POLY_GROUP && groupMap.find(oldId) == groupMap.end()) + groupMap[oldId] = (unsigned short)disjoint.insertNew(); + } + } + + // Apply the new mapping to all polys. + for (int i = 0; i < nav->getMaxTiles(); ++i) + { + dtMeshTile* tile = nav->getTile(i); + if (!tile || !tile->header || !tile->dataSize) continue; + const int pcount = tile->header->polyCount; + for (int j = 0; j < pcount; j++) + { + dtPoly& poly = tile->polys[j]; + if (poly.groupId != DT_STRAY_POLY_GROUP) + poly.groupId = groupMap[poly.groupId]; + } + } + + nav->setPolyGroupcount(disjoint.getSetCount()); + return true; +} + // todo(amos): remove param 'tableCount' and make struct 'dtTraverseTableCreateParams' bool dtCreateTraverseTableData(dtNavMesh* nav, const dtDisjointSet& disjoint, const int tableCount) {