From 1a0b6efae5855f46b58b2e1f1c7e1b54fe9de22f Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Wed, 18 Sep 2024 11:41:33 +0200 Subject: [PATCH] Recast: properly set traverse type fields in off-mesh connections for MSET 7 or higher The structure was incorrect prior to this patch for MSET 7 or higher. --- src/naveditor/OffMeshConnectionTool.cpp | 3 ++ .../DebugUtils/Source/DetourDebugDraw.cpp | 14 ++++- .../recast/Detour/Include/DetourNavMesh.h | 53 ++++++++++++++++--- .../recast/Detour/Source/DetourNavMesh.cpp | 8 +++ .../Detour/Source/DetourNavMeshBuilder.cpp | 12 +++-- 5 files changed, 76 insertions(+), 14 deletions(-) diff --git a/src/naveditor/OffMeshConnectionTool.cpp b/src/naveditor/OffMeshConnectionTool.cpp index 3e4f3912..da00862b 100644 --- a/src/naveditor/OffMeshConnectionTool.cpp +++ b/src/naveditor/OffMeshConnectionTool.cpp @@ -76,7 +76,10 @@ void OffMeshConnectionTool::reset() void OffMeshConnectionTool::handleMenu() { + // On newer navmesh sets, off-mesh links are always bidirectional. +#if DT_NAVMESH_SET_VERSION < 7 ImGui::Checkbox("Bidirectional", &m_bidir); +#endif ImGui::Checkbox("Invert Lookup Order", &m_invertVertexLookupOrder); ImGui::PushItemWidth(140); diff --git a/src/thirdparty/recast/DebugUtils/Source/DetourDebugDraw.cpp b/src/thirdparty/recast/DebugUtils/Source/DetourDebugDraw.cpp index dc1d7bbb..0364e7bd 100644 --- a/src/thirdparty/recast/DebugUtils/Source/DetourDebugDraw.cpp +++ b/src/thirdparty/recast/DebugUtils/Source/DetourDebugDraw.cpp @@ -462,7 +462,12 @@ static void drawOffMeshLinks(duDebugDraw* dd, const dtNavMesh& mesh, const dtNav // Connection arc. duAppendArc(dd, con->pos[0],con->pos[1],con->pos[2], con->pos[3],con->pos[4],con->pos[5], 0.25f, - (con->flags & DT_OFFMESH_CON_BIDIR) ? 30.0f : 0.0f, 30.0f, col); +#if DT_NAVMESH_SET_VERSION >= 7 + 30.f, +#else + (con->flags & DT_OFFMESH_CON_BIDIR) ? 30.0f : 0.0f, +#endif + 30.0f, col); // Reference positions. drawOffMeshConnectionRefPosition(dd, con); @@ -748,7 +753,12 @@ void duDebugDrawNavMeshPoly(duDebugDraw* dd, const dtNavMesh& mesh, dtPolyRef re // Connection arc. duAppendArc(dd, con->pos[0],con->pos[1],con->pos[2], con->pos[3],con->pos[4],con->pos[5], 0.25f, - (con->flags & DT_OFFMESH_CON_BIDIR) ? 30.0f : 0.0f, 30.0f, c); +#if DT_NAVMESH_SET_VERSION >= 7 + 30.f, +#else + (con->flags & DT_OFFMESH_CON_BIDIR) ? 30.0f : 0.0f, +#endif + 30.0f, c); // Reference positions. drawOffMeshConnectionRefPosition(dd, con); diff --git a/src/thirdparty/recast/Detour/Include/DetourNavMesh.h b/src/thirdparty/recast/Detour/Include/DetourNavMesh.h index 0ef1118b..d29b89e9 100644 --- a/src/thirdparty/recast/Detour/Include/DetourNavMesh.h +++ b/src/thirdparty/recast/Detour/Include/DetourNavMesh.h @@ -349,13 +349,41 @@ struct dtBVNode /// An off-mesh connection is a user defined traversable connection made up to two vertices. struct dtOffMeshConnection { - unsigned char getTraverseType() { return traverseContext & 0xff; } - unsigned char getVertLookupOrder() { return (traverseContext >> 8) & 0xff; } - void setTraverseType(unsigned char type, unsigned char order) { traverseContext = type | (order << 8); } + unsigned char getTraverseType() + { +#if DT_NAVMESH_SET_VERSION >= 7 + return traverseType & (DT_MAX_TRAVERSE_TYPES-1); +#else + return traverseContext & 0xff; +#endif + } + unsigned char getVertLookupOrder() + { +#if DT_NAVMESH_SET_VERSION >= 7 + return traverseType & (1<<6); +#else + return (traverseContext >> 8) & 0xff; +#endif + } + + void setTraverseType(unsigned char type, unsigned char order) + { +#if DT_NAVMESH_SET_VERSION >= 7 + traverseType = type & (DT_MAX_TRAVERSE_TYPES-1); + + if (order) // Inverted, mark it. + traverseType |= (1<<6); +#else + traverseContext = type | (order<<8); +#endif + } + +#if DT_NAVMESH_SET_VERSION < 7 /// The hint index of the off-mesh connection. (Or #DT_NULL_HINT if there is no hint.) unsigned short getHintIndex() { return traverseContext; }; void setHintIndex(unsigned short index) { traverseContext = index; }; +#endif /// The endpoints of the connection. [(ax, ay, az, bx, by, bz)] float pos[6]; @@ -366,18 +394,27 @@ struct dtOffMeshConnection /// The polygon reference of the connection within the tile. unsigned short poly; - /// Link flags. - /// @note These are not the connection's user defined flags. Those are assigned via the +#if DT_NAVMESH_SET_VERSION >= 7 + /// End point side. + unsigned char side; + + /// The traverse type. + unsigned char traverseType; + + /// The hint index. + unsigned short hintIndex; +#else + /// Link flags. + /// @note These are not the connection's user defined flags. Those are assigned via the /// connection's dtPoly definition. These are link flags used for internal purposes. unsigned char flags; /// End point side. unsigned char side; - /// The traverse types or hint indices. (If the off-mesh connection is used for wall running, - /// it needs a corresponding probe which this field will reference. Otherwise this field will - /// contain the traverse type and lookup order.) + /// The traverse type and lookup order. unsigned short traverseContext; +#endif /// The id of the off-mesh connection. (User assigned when the navigation mesh is built.) unsigned short userId; diff --git a/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp b/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp index 82a900e7..d676ebc4 100644 --- a/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp +++ b/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp @@ -616,6 +616,12 @@ dtStatus dtNavMesh::connectExtOffMeshLinks(const dtTileRef tileRef) const unsigned char traverseType = con->getTraverseType(); const bool invertVertLookup = con->getVertLookupOrder(); +#if DT_NAVMESH_SET_VERSION >= 7 + // NOTE: need to remove the vert lookup inversion flag from here as the + // engine uses this value directly to index into the activity array. + con->setTraverseType(traverseType, 0); +#endif + for (int y = miny; y <= maxy; ++y) { for (int x = minx; x <= maxx; ++x) @@ -636,7 +642,9 @@ dtStatus dtNavMesh::connectExtOffMeshLinks(const dtTileRef tileRef) return DT_FAILURE | DT_OUT_OF_MEMORY; // Link target poly to off-mesh connection. +#if DT_NAVMESH_SET_VERSION < 7 if (con->flags & DT_OFFMESH_CON_BIDIR) +#endif { const unsigned int landPolyIdx = decodePolyIdPoly(landPolyRef); dtPoly* landPoly = &neiTile->polys[landPolyIdx]; diff --git a/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp b/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp index e985a395..b7d51991 100644 --- a/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp +++ b/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp @@ -1125,18 +1125,22 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData, if (offMeshConClass[i*2+0] == 0xff) { dtOffMeshConnection* con = &offMeshCons[n]; - con->poly = (unsigned short)(offMeshPolyBase + n); // Copy connection end-points. const float* endPts = ¶ms->offMeshConVerts[i*2*3]; const float* refPos = ¶ms->offMeshConRefPos[i*3]; rdVcopy(&con->pos[0], &endPts[0]); rdVcopy(&con->pos[3], &endPts[3]); - rdVcopy(&con->refPos[0], &refPos[0]); con->rad = params->offMeshConRad[i]; - con->refYaw = params->offMeshConRefYaw[i]; - con->flags = params->offMeshConDir[i] ? DT_OFFMESH_CON_BIDIR : 0; + con->poly = (unsigned short)(offMeshPolyBase + n); con->side = offMeshConClass[i*2+1]; con->setTraverseType(params->offMeshConJumps[i], params->offMeshConOrders[i]); +#if DT_NAVMESH_SET_VERSION >= 7 + con->hintIndex = DT_NULL_HINT; +#else + con->flags = params->offMeshConDir[i] ? DT_OFFMESH_CON_BIDIR : 0; +#endif + rdVcopy(&con->refPos[0], &refPos[0]); + con->refYaw = params->offMeshConRefYaw[i]; n++; } }