From ce4d4aa59831fbb6a2b7c32820561b321484dc56 Mon Sep 17 00:00:00 2001 From: Amos Date: Wed, 24 Jul 2024 22:03:09 +0200 Subject: [PATCH] Recast: add ability to load navmesh from file. --- src/naveditor/Editor.cpp | 46 ++++++++++++++++---------- src/naveditor/Editor_Common.cpp | 2 +- src/naveditor/Editor_TempObstacles.cpp | 2 +- src/naveditor/include/Editor.h | 6 ++-- src/naveditor/main.cpp | 32 +++++++++++++++++- 5 files changed, 64 insertions(+), 24 deletions(-) diff --git a/src/naveditor/Editor.cpp b/src/naveditor/Editor.cpp index 27fafb8a..3d61ead3 100644 --- a/src/naveditor/Editor.cpp +++ b/src/naveditor/Editor.cpp @@ -548,20 +548,28 @@ void Editor::selectNavMeshType(const NavMeshType_e navMeshType) m_selectedNavMeshType = navMeshType; } -dtNavMesh* Editor::loadAll(std::string path) +bool Editor::loadAll(std::string path, const bool fullPath) { - fs::path p = "..\\maps\\navmesh\\"; - if (fs::is_directory(p)) - { - path.insert(0, p.string()); - } - + const char* navMeshPath = nullptr; char buffer[256]; - sprintf(buffer, "%s_%s.nm", path.c_str(), m_navmeshName); - FILE* fp = fopen(buffer, "rb"); + if (!fullPath) // Load from model name (e.g. "mp_rr_box"). + { + fs::path p = "..\\maps\\navmesh\\"; + if (fs::is_directory(p)) + { + path.insert(0, p.string()); + } + + sprintf(buffer, "%s_%s.nm", path.c_str(), m_navmeshName); + navMeshPath = buffer; + } + else + navMeshPath = path.c_str(); + + FILE* fp = fopen(navMeshPath, "rb"); if (!fp) - return 0; + return false; // Read header. dtNavMeshSetHeader header; @@ -569,24 +577,24 @@ dtNavMesh* Editor::loadAll(std::string path) if (readLen != 1) { fclose(fp); - return 0; + return false; } if (header.magic != DT_NAVMESH_SET_MAGIC) // todo(amos) check for tool mode since tilecache uses different constants! { fclose(fp); - return 0; + return false; } if (header.version != DT_NAVMESH_SET_VERSION) // todo(amos) check for tool mode since tilecache uses different constants! { fclose(fp); - return 0; + return false; } dtNavMesh* mesh = dtAllocNavMesh(); if (!mesh) { fclose(fp); - return 0; + return false; } @@ -594,7 +602,7 @@ dtNavMesh* Editor::loadAll(std::string path) if (dtStatusFailed(status)) { fclose(fp); - return 0; + return false; } // Read tiles. @@ -605,7 +613,7 @@ dtNavMesh* Editor::loadAll(std::string path) if (readLen != 1) { fclose(fp); - return 0; + return false; } if (!tileHeader.tileRef || !tileHeader.dataSize) @@ -622,7 +630,7 @@ dtNavMesh* Editor::loadAll(std::string path) { rdFree(data); fclose(fp); - return 0; + return false; } mesh->addTile(data, tileHeader.dataSize, DT_TILE_FREE_DATA, tileHeader.tileRef, NULL); @@ -652,7 +660,9 @@ dtNavMesh* Editor::loadAll(std::string path) } fclose(fp); - return mesh; + m_navMesh = mesh; + + return true; } void Editor::saveAll(std::string path, const dtNavMesh* mesh) diff --git a/src/naveditor/Editor_Common.cpp b/src/naveditor/Editor_Common.cpp index 4e1cf5d7..720b10f1 100644 --- a/src/naveditor/Editor_Common.cpp +++ b/src/naveditor/Editor_Common.cpp @@ -405,7 +405,7 @@ void Editor_StaticTileMeshCommon::renderIntermediateTileMeshOptions() if (ImGui::Button("Load", ImVec2(123, 0))) { dtFreeNavMesh(m_navMesh); - m_navMesh = Editor::loadAll(m_modelName.c_str()); + Editor::loadAll(m_modelName.c_str()); m_navQuery->init(m_navMesh, 2048); m_loadedNavMeshType = m_selectedNavMeshType; diff --git a/src/naveditor/Editor_TempObstacles.cpp b/src/naveditor/Editor_TempObstacles.cpp index 4e01d73f..f89e9b7e 100644 --- a/src/naveditor/Editor_TempObstacles.cpp +++ b/src/naveditor/Editor_TempObstacles.cpp @@ -832,7 +832,7 @@ void Editor_TempObstacles::handleSettings() if (ImGui::Button("Load", ImVec2(123, 0))) { dtFreeNavMesh(m_navMesh); - m_navMesh = Editor::loadAll(m_modelName.c_str()); + Editor::loadAll(m_modelName.c_str()); m_navQuery->init(m_navMesh, 2048); m_loadedNavMeshType = m_selectedNavMeshType; diff --git a/src/naveditor/include/Editor.h b/src/naveditor/include/Editor.h index 5dfdb987..4a4e2bba 100644 --- a/src/naveditor/include/Editor.h +++ b/src/naveditor/include/Editor.h @@ -154,15 +154,15 @@ protected: int m_traverseLinkDrawTypes; float m_recastDrawOffset[3]; float m_detourDrawOffset[3]; - - dtNavMesh* loadAll(std::string path); - void saveAll(std::string path, const dtNavMesh* mesh); public: std::string m_modelName; Editor(); virtual ~Editor(); + + bool loadAll(std::string path, const bool fullPath = false); + void saveAll(std::string path, const dtNavMesh* mesh); void setContext(BuildContext* ctx) { m_ctx = ctx; } diff --git a/src/naveditor/main.cpp b/src/naveditor/main.cpp index d0615c07..3abf60bb 100644 --- a/src/naveditor/main.cpp +++ b/src/naveditor/main.cpp @@ -16,9 +16,10 @@ // 3. This notice may not be removed or altered from any source distribution. // -#include "Recast/Include/Recast.h" #include "Shared/Include/SharedAlloc.h" #include "DebugUtils/Include/RecastDebugDraw.h" +#include "Recast/Include/Recast.h" +#include "Detour/Include/DetourNavMeshQuery.h" #include "NavEditor/Include/InputGeom.h" #include "NavEditor/Include/TestCase.h" #include "NavEditor/Include/Filelist.h" @@ -998,6 +999,35 @@ int not_main(int argc, char** argv) meshName = geom_path.substr(geom_path.rfind("\\") + 1); } } + if (geom && editor && ImGui::Button("Load NavMesh...")) + { + char szFile[260]; + OPENFILENAMEA diag = { 0 }; + diag.lStructSize = sizeof(diag); + + SDL_SysWMinfo sdlinfo; + SDL_version sdlver; + SDL_VERSION(&sdlver); + sdlinfo.version = sdlver; + SDL_GetWindowWMInfo(window, &sdlinfo); + + diag.hwndOwner = sdlinfo.info.win.window; + + diag.lpstrFile = szFile; + diag.lpstrFile[0] = 0; + diag.nMaxFile = sizeof(szFile); + diag.lpstrFilter = "NM\0*.nm\0"; + diag.nFilterIndex = 1; + diag.lpstrFileTitle = NULL; + diag.nMaxFileTitle = 0; + diag.lpstrInitialDir = NULL; + diag.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + + if (GetOpenFileNameA(&diag)) + { + editor->loadAll(szFile, true); + } + } if (ImGui::Button(meshName.empty() ? "Choose Level..." : meshName.c_str())) { if (showLevels)