From 740c593197f8d1e797e15373def43110e2580667 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Thu, 18 Jul 2024 17:00:31 +0200 Subject: [PATCH] Recast: setup off-mesh connections properly (WIP) Titanfall navmeshes have the dtOffMeshConnection::userId field changed from unsigned into to unsigned short, and the lower half seems to be used for the jump types and (possibly) some flag. Work in progress implementation of the jump system on off-mesh links. --- src/naveditor/Editor_SoloMesh.cpp | 1 + src/naveditor/Editor_TempObstacles.cpp | 3 ++- src/naveditor/Editor_TileMesh.cpp | 1 + src/naveditor/InputGeom.cpp | 16 ++++++++----- src/naveditor/OffMeshConnectionTool.cpp | 7 +++++- src/naveditor/include/InputGeom.h | 10 ++++---- src/naveditor/include/OffMeshConnectionTool.h | 1 + .../recast/Detour/Include/DetourNavMesh.h | 8 +++++-- .../Detour/Include/DetourNavMeshBuilder.h | 4 +++- .../recast/Detour/Source/DetourNavMesh.cpp | 24 +++++++++---------- .../Detour/Source/DetourNavMeshBuilder.cpp | 2 ++ 11 files changed, 50 insertions(+), 27 deletions(-) diff --git a/src/naveditor/Editor_SoloMesh.cpp b/src/naveditor/Editor_SoloMesh.cpp index a0941739..abd42831 100644 --- a/src/naveditor/Editor_SoloMesh.cpp +++ b/src/naveditor/Editor_SoloMesh.cpp @@ -482,6 +482,7 @@ bool Editor_SoloMesh::handleBuild() params.offMeshConVerts = m_geom->getOffMeshConnectionVerts(); params.offMeshConRad = m_geom->getOffMeshConnectionRads(); params.offMeshConDir = m_geom->getOffMeshConnectionDirs(); + params.offMeshConJumps = m_geom->getOffMeshConnectionJumps(); params.offMeshConAreas = m_geom->getOffMeshConnectionAreas(); params.offMeshConFlags = m_geom->getOffMeshConnectionFlags(); params.offMeshConUserID = m_geom->getOffMeshConnectionId(); diff --git a/src/naveditor/Editor_TempObstacles.cpp b/src/naveditor/Editor_TempObstacles.cpp index 16f5822d..06870eaf 100644 --- a/src/naveditor/Editor_TempObstacles.cpp +++ b/src/naveditor/Editor_TempObstacles.cpp @@ -200,10 +200,11 @@ struct MeshProcess : public dtTileCacheMeshProcess params->offMeshConVerts = m_geom->getOffMeshConnectionVerts(); params->offMeshConRad = m_geom->getOffMeshConnectionRads(); params->offMeshConDir = m_geom->getOffMeshConnectionDirs(); + params->offMeshConJumps = m_geom->getOffMeshConnectionJumps(); params->offMeshConAreas = m_geom->getOffMeshConnectionAreas(); params->offMeshConFlags = m_geom->getOffMeshConnectionFlags(); params->offMeshConUserID = m_geom->getOffMeshConnectionId(); - params->offMeshConCount = m_geom->getOffMeshConnectionCount(); + params->offMeshConCount = m_geom->getOffMeshConnectionCount(); } } }; diff --git a/src/naveditor/Editor_TileMesh.cpp b/src/naveditor/Editor_TileMesh.cpp index 12e7d380..fce4059f 100644 --- a/src/naveditor/Editor_TileMesh.cpp +++ b/src/naveditor/Editor_TileMesh.cpp @@ -1005,6 +1005,7 @@ unsigned char* Editor_TileMesh::buildTileMesh(const int tx, const int ty, const params.offMeshConVerts = m_geom->getOffMeshConnectionVerts(); params.offMeshConRad = m_geom->getOffMeshConnectionRads(); params.offMeshConDir = m_geom->getOffMeshConnectionDirs(); + params.offMeshConJumps = m_geom->getOffMeshConnectionJumps(); params.offMeshConAreas = m_geom->getOffMeshConnectionAreas(); params.offMeshConFlags = m_geom->getOffMeshConnectionFlags(); params.offMeshConUserID = m_geom->getOffMeshConnectionId(); diff --git a/src/naveditor/InputGeom.cpp b/src/naveditor/InputGeom.cpp index 3c800656..84fb50c2 100644 --- a/src/naveditor/InputGeom.cpp +++ b/src/naveditor/InputGeom.cpp @@ -284,16 +284,17 @@ bool InputGeom::loadGeomSet(rcContext* ctx, const std::string& filepath) float* refs = &m_offMeshConRefPos[m_offMeshConCount*3]; float rad; float yaw; - int bidir, area = 0, flags = 0; - sscanf(row+1, "%f %f %f %f %f %f %f %d %d %d %f %f %f %f", + int bidir, area = 0, jump = 0, flags = 0; + sscanf(row+1, "%f %f %f %f %f %f %f %d %d %d %d %f %f %f %f", &verts[0], &verts[1], &verts[2], &verts[3], &verts[4], &verts[5], &rad, - &bidir, &area, &flags, + &bidir, &jump, &area, &flags, &refs[0], &refs[1], &refs[2], &yaw); m_offMeshConRads[m_offMeshConCount] = rad; m_offMeshConDirs[m_offMeshConCount] = (unsigned char)bidir; + m_offMeshConJumps[m_offMeshConCount] = (unsigned char)jump; m_offMeshConAreas[m_offMeshConCount] = (unsigned char)area; m_offMeshConFlags[m_offMeshConCount] = (unsigned short)flags; m_offMeshConRefYaws[m_offMeshConCount] = yaw; @@ -428,13 +429,14 @@ bool InputGeom::saveGeomSet(const BuildSettings* settings) const float rad = m_offMeshConRads[i]; const float yaw = m_offMeshConRefYaws[i]; const int bidir = m_offMeshConDirs[i]; + const int jump = m_offMeshConJumps[i]; const int area = m_offMeshConAreas[i]; const int flags = m_offMeshConFlags[i]; - fprintf(fp, "c %f %f %f %f %f %f %f %d %d %d %f %f %f %f\n", + fprintf(fp, "c %f %f %f %f %f %f %f %d %d %d %d %f %f %f %f\n", verts[0], verts[1], verts[2], verts[3], verts[4], verts[5], rad, - bidir, area, flags, + bidir, jump, area, flags, refs[0], refs[1], refs[2], yaw); } @@ -535,7 +537,7 @@ bool InputGeom::raycastMesh(float* src, float* dst, float& tmin) } void InputGeom::addOffMeshConnection(const float* spos, const float* epos, const float rad, - unsigned char bidir, unsigned char area, unsigned short flags) + unsigned char bidir, unsigned char jump, unsigned char area, unsigned short flags) { if (m_offMeshConCount >= MAX_OFFMESH_CONNECTIONS) return; float* refs = &m_offMeshConRefPos[m_offMeshConCount*3]; @@ -547,6 +549,7 @@ void InputGeom::addOffMeshConnection(const float* spos, const float* epos, const m_offMeshConRads[m_offMeshConCount] = rad; m_offMeshConRefYaws[m_offMeshConCount] = yaw; m_offMeshConDirs[m_offMeshConCount] = bidir; + m_offMeshConJumps[m_offMeshConCount] = jump; m_offMeshConAreas[m_offMeshConCount] = area; m_offMeshConFlags[m_offMeshConCount] = flags; m_offMeshConId[m_offMeshConCount] = 1000 + m_offMeshConCount; @@ -568,6 +571,7 @@ void InputGeom::deleteOffMeshConnection(int i) m_offMeshConRads[i] = m_offMeshConRads[m_offMeshConCount]; m_offMeshConRefYaws[i] = m_offMeshConRefYaws[m_offMeshConCount]; m_offMeshConDirs[i] = m_offMeshConDirs[m_offMeshConCount]; + m_offMeshConJumps[i] = m_offMeshConJumps[m_offMeshConCount]; m_offMeshConAreas[i] = m_offMeshConAreas[m_offMeshConCount]; m_offMeshConFlags[i] = m_offMeshConFlags[m_offMeshConCount]; } diff --git a/src/naveditor/OffMeshConnectionTool.cpp b/src/naveditor/OffMeshConnectionTool.cpp index fbebd0b0..c1bdf8f7 100644 --- a/src/naveditor/OffMeshConnectionTool.cpp +++ b/src/naveditor/OffMeshConnectionTool.cpp @@ -31,6 +31,7 @@ OffMeshConnectionTool::OffMeshConnectionTool() : m_editor(0), m_hitPosSet(0), m_bidir(true), + m_jumpType(0), m_oldFlags(0) { } @@ -69,6 +70,10 @@ void OffMeshConnectionTool::handleMenu() if (ImGui::Checkbox("Bidirectional", &isBiDirectional)) m_bidir = true; + + ImGui::PushItemWidth(140); + ImGui::SliderInt("Jump Type", &m_jumpType, 0, 31); + ImGui::PopItemWidth(); } void OffMeshConnectionTool::handleClick(const float* /*s*/, const float* p, bool shift) @@ -113,7 +118,7 @@ void OffMeshConnectionTool::handleClick(const float* /*s*/, const float* p, bool { const unsigned char area = EDITOR_POLYAREA_JUMP; const unsigned short flags = EDITOR_POLYFLAGS_WALK; - geom->addOffMeshConnection(m_hitPos, p, m_editor->getAgentRadius(), m_bidir ? 1 : 0, area, flags); + geom->addOffMeshConnection(m_hitPos, p, m_editor->getAgentRadius(), m_bidir ? 1 : 0, (unsigned char)m_jumpType, area, flags); m_hitPosSet = false; } } diff --git a/src/naveditor/include/InputGeom.h b/src/naveditor/include/InputGeom.h index da2f4f19..355ab2ae 100644 --- a/src/naveditor/include/InputGeom.h +++ b/src/naveditor/include/InputGeom.h @@ -87,12 +87,13 @@ class InputGeom float m_offMeshConVerts[MAX_OFFMESH_CONNECTIONS*3*2]; float m_offMeshConRads[MAX_OFFMESH_CONNECTIONS]; unsigned char m_offMeshConDirs[MAX_OFFMESH_CONNECTIONS]; + unsigned char m_offMeshConJumps[MAX_OFFMESH_CONNECTIONS]; unsigned char m_offMeshConAreas[MAX_OFFMESH_CONNECTIONS]; unsigned short m_offMeshConFlags[MAX_OFFMESH_CONNECTIONS]; - unsigned int m_offMeshConId[MAX_OFFMESH_CONNECTIONS]; + unsigned short m_offMeshConId[MAX_OFFMESH_CONNECTIONS]; float m_offMeshConRefPos[MAX_OFFMESH_CONNECTIONS*3]; float m_offMeshConRefYaws[MAX_OFFMESH_CONNECTIONS]; - int m_offMeshConCount; + short m_offMeshConCount; ///@} /// @name Convex Volumes. @@ -137,13 +138,14 @@ public: const float* getOffMeshConnectionVerts() const { return m_offMeshConVerts; } const float* getOffMeshConnectionRads() const { return m_offMeshConRads; } const unsigned char* getOffMeshConnectionDirs() const { return m_offMeshConDirs; } + const unsigned char* getOffMeshConnectionJumps() const { return m_offMeshConJumps; } const unsigned char* getOffMeshConnectionAreas() const { return m_offMeshConAreas; } const unsigned short* getOffMeshConnectionFlags() const { return m_offMeshConFlags; } - const unsigned int* getOffMeshConnectionId() const { return m_offMeshConId; } + const unsigned short* getOffMeshConnectionId() const { return m_offMeshConId; } const float* getOffMeshConnectionRefPos() const { return m_offMeshConRefPos; } const float* getOffMeshConnectionRefYaws() const { return m_offMeshConRefYaws; } void addOffMeshConnection(const float* spos, const float* epos, const float rad, - unsigned char bidir, unsigned char area, unsigned short flags); + unsigned char bidir, unsigned char jump, unsigned char area, unsigned short flags); void deleteOffMeshConnection(int i); void drawOffMeshConnections(struct duDebugDraw* dd, const float* offset, bool hilight = false); ///@} diff --git a/src/naveditor/include/OffMeshConnectionTool.h b/src/naveditor/include/OffMeshConnectionTool.h index 1b1657e9..50acea1a 100644 --- a/src/naveditor/include/OffMeshConnectionTool.h +++ b/src/naveditor/include/OffMeshConnectionTool.h @@ -29,6 +29,7 @@ class OffMeshConnectionTool : public EditorTool float m_hitPos[3]; bool m_hitPosSet; bool m_bidir; + int m_jumpType; unsigned int m_oldFlags; public: diff --git a/src/thirdparty/recast/Detour/Include/DetourNavMesh.h b/src/thirdparty/recast/Detour/Include/DetourNavMesh.h index 26b9a206..8e6fd5ce 100644 --- a/src/thirdparty/recast/Detour/Include/DetourNavMesh.h +++ b/src/thirdparty/recast/Detour/Include/DetourNavMesh.h @@ -305,8 +305,12 @@ struct dtOffMeshConnection /// End point side. unsigned char side; - /// The id of the offmesh connection. (User assigned when the navigation mesh is built.) - unsigned int userId; + unsigned char jumpType; + + unsigned char unk1; + + /// The id of the off-mesh connection. (User assigned when the navigation mesh is built.) + unsigned short userId; /// The reference position set to the start of the off-mesh connection with an offset of DT_OFFMESH_CON_REFPOS_OFFSET float refPos[3]; // See [r5apex_ds + F114CF], [r5apex_ds + F11B42], [r5apex_ds + F12447]. diff --git a/src/thirdparty/recast/Detour/Include/DetourNavMeshBuilder.h b/src/thirdparty/recast/Detour/Include/DetourNavMeshBuilder.h index 54651e38..13009fcc 100644 --- a/src/thirdparty/recast/Detour/Include/DetourNavMeshBuilder.h +++ b/src/thirdparty/recast/Detour/Include/DetourNavMeshBuilder.h @@ -70,8 +70,10 @@ struct dtNavMeshCreateParams /// 0 = Travel only from endpoint A to endpoint B.
/// #DT_OFFMESH_CON_BIDIR = Bidirectional travel. const unsigned char* offMeshConDir; + /// The user defined jump type of the off-mesh connection. [Size: #offMeshConCount] + const unsigned char* offMeshConJumps; /// The user defined ids of the off-mesh connection. [Size: #offMeshConCount] - const unsigned int* offMeshConUserID; + const unsigned short* offMeshConUserID; /// Off-mesh connection reference positions. [(x, y, z) * #offMeshConCount] [Unit: wu] const float* offMeshConRefPos; /// Off-mesh connection reference yaw. [Size: #offMeshConCount] [Unit: wu] diff --git a/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp b/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp index 8ecb810b..231b4f59 100644 --- a/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp +++ b/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp @@ -464,8 +464,8 @@ void dtNavMesh::connectExtLinks(dtMeshTile* tile, dtMeshTile* target, int side) link->next = poly->firstLink; poly->firstLink = idx; - link->jumpType = DT_NULL_TRAVERSE_TYPE; - link->jumpDist = 0; + link->traverseType = DT_NULL_TRAVERSE_TYPE; + link->traverseDist = 0; link->reverseLink = DT_NULL_TRAVERSE_REVERSE_LINK; // Compress portal limits to a byte value. @@ -540,8 +540,8 @@ void dtNavMesh::connectExtOffMeshLinks(dtMeshTile* tile, dtMeshTile* target, int // Add to linked list. link->next = targetPoly->firstLink; targetPoly->firstLink = idx; - link->jumpType = DT_NULL_TRAVERSE_TYPE; - link->jumpDist = 0; + link->traverseType = DT_NULL_TRAVERSE_TYPE; + link->traverseDist = 0; link->reverseLink = DT_NULL_TRAVERSE_REVERSE_LINK; } @@ -563,8 +563,8 @@ void dtNavMesh::connectExtOffMeshLinks(dtMeshTile* tile, dtMeshTile* target, int // Add to linked list. tlink->next = landPoly->firstLink; landPoly->firstLink = tidx; - tlink->jumpType = DT_NULL_TRAVERSE_TYPE; - tlink->jumpDist = 0; + tlink->traverseType = DT_NULL_TRAVERSE_TYPE; + tlink->traverseDist = 0; tlink->reverseLink = DT_NULL_TRAVERSE_REVERSE_LINK; } } @@ -612,8 +612,8 @@ void dtNavMesh::connectIntLinks(dtMeshTile* tile) // Add to linked list. link->next = poly->firstLink; poly->firstLink = idx; - link->jumpType = DT_NULL_TRAVERSE_TYPE; - link->jumpDist = 0; + link->traverseType = DT_NULL_TRAVERSE_TYPE; + link->traverseDist = 0; link->reverseLink = DT_NULL_TRAVERSE_REVERSE_LINK; } } @@ -658,8 +658,8 @@ void dtNavMesh::baseOffMeshLinks(dtMeshTile* tile) // Add to linked list. link->next = poly->firstLink; poly->firstLink = idx; - link->jumpType = DT_NULL_TRAVERSE_TYPE; - link->jumpDist = 0; + link->traverseType = DT_NULL_TRAVERSE_TYPE; + link->traverseDist = 0; link->reverseLink = DT_NULL_TRAVERSE_REVERSE_LINK; } @@ -677,8 +677,8 @@ void dtNavMesh::baseOffMeshLinks(dtMeshTile* tile) // Add to linked list. link->next = landPoly->firstLink; landPoly->firstLink = tidx; - link->jumpType = DT_NULL_TRAVERSE_TYPE; - link->jumpDist = 0; + link->traverseType = DT_NULL_TRAVERSE_TYPE; + link->traverseDist = 0; link->reverseLink = DT_NULL_TRAVERSE_REVERSE_LINK; } } diff --git a/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp b/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp index 0eb66aef..c4e95c8c 100644 --- a/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp +++ b/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp @@ -903,6 +903,8 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData, con->refYaw = params->offMeshConRefYaw[i]; con->flags = params->offMeshConDir[i] ? DT_OFFMESH_CON_BIDIR : 0; con->side = offMeshConClass[i*2+1]; + con->jumpType = params->offMeshConJumps[i]; + con->unk1 = 1; if (params->offMeshConUserID) con->userId = params->offMeshConUserID[i]; n++;