From 4988ecbaf094df18b1bf61a27a018d7e4eef4225 Mon Sep 17 00:00:00 2001 From: Aurelien Rainone Date: Fri, 5 Jan 2018 12:38:53 +0100 Subject: [PATCH] RecastDemo: add Load & Save buttons for SoloMesh Sample, and fix warnings (#258) * Implement saveAll loadAll for Sample_SoloMesh - Solo mesh sample is loaded and saved as a tiled mesh containing an unique tile, so as to remain compatible with tiled mesh - navmesh is saved to/loaded from `solo_navmesh.bin` binary file - add and connect the corresponding 'Save/Load' GUI elements * Fix `implit-fallthrough` gcc warnings On linux with gcc 7.2.0+ and all warnings treated as errors, implicit fallthroughs in case statements are considered as errors. If the comment just below the next `case` or `default` matches various strings, one of which is `falls through` the fallthrough is then considered explicit. --- RecastDemo/Include/Sample.h | 3 + RecastDemo/Include/Sample_SoloMesh.h | 2 +- RecastDemo/Source/InputGeom.cpp | 1 + RecastDemo/Source/Sample.cpp | 125 ++++++++++++++++++++++++++ RecastDemo/Source/Sample_SoloMesh.cpp | 24 ++++- RecastDemo/Source/Sample_TileMesh.cpp | 112 +---------------------- RecastDemo/Source/TestCase.cpp | 1 + 7 files changed, 154 insertions(+), 114 deletions(-) diff --git a/RecastDemo/Include/Sample.h b/RecastDemo/Include/Sample.h index f59975c..aa46f86 100644 --- a/RecastDemo/Include/Sample.h +++ b/RecastDemo/Include/Sample.h @@ -132,6 +132,9 @@ protected: SampleDebugDraw m_dd; + dtNavMesh* loadAll(const char* path); + void saveAll(const char* path, const dtNavMesh* mesh); + public: Sample(); virtual ~Sample(); diff --git a/RecastDemo/Include/Sample_SoloMesh.h b/RecastDemo/Include/Sample_SoloMesh.h index 70afb11..a278529 100644 --- a/RecastDemo/Include/Sample_SoloMesh.h +++ b/RecastDemo/Include/Sample_SoloMesh.h @@ -62,7 +62,7 @@ protected: DrawMode m_drawMode; void cleanup(); - + public: Sample_SoloMesh(); virtual ~Sample_SoloMesh(); diff --git a/RecastDemo/Source/InputGeom.cpp b/RecastDemo/Source/InputGeom.cpp index 29af6c3..a5f9a0d 100644 --- a/RecastDemo/Source/InputGeom.cpp +++ b/RecastDemo/Source/InputGeom.cpp @@ -92,6 +92,7 @@ static char* parseRow(char* buf, char* bufEnd, char* row, int len) case '\t': case ' ': if (start) break; + // else falls through default: start = false; row[n++] = c; diff --git a/RecastDemo/Source/Sample.cpp b/RecastDemo/Source/Sample.cpp index 26f2f76..d8c4cfd 100644 --- a/RecastDemo/Source/Sample.cpp +++ b/RecastDemo/Source/Sample.cpp @@ -322,3 +322,128 @@ void Sample::renderOverlayToolStates(double* proj, double* model, int* view) } } +static const int NAVMESHSET_MAGIC = 'M'<<24 | 'S'<<16 | 'E'<<8 | 'T'; //'MSET'; +static const int NAVMESHSET_VERSION = 1; + +struct NavMeshSetHeader +{ + int magic; + int version; + int numTiles; + dtNavMeshParams params; +}; + +struct NavMeshTileHeader +{ + dtTileRef tileRef; + int dataSize; +}; + +dtNavMesh* Sample::loadAll(const char* path) +{ + FILE* fp = fopen(path, "rb"); + if (!fp) return 0; + + // Read header. + NavMeshSetHeader header; + size_t readLen = fread(&header, sizeof(NavMeshSetHeader), 1, fp); + if (readLen != 1) + { + fclose(fp); + return 0; + } + if (header.magic != NAVMESHSET_MAGIC) + { + fclose(fp); + return 0; + } + if (header.version != NAVMESHSET_VERSION) + { + fclose(fp); + return 0; + } + + dtNavMesh* mesh = dtAllocNavMesh(); + if (!mesh) + { + fclose(fp); + return 0; + } + dtStatus status = mesh->init(&header.params); + if (dtStatusFailed(status)) + { + fclose(fp); + return 0; + } + + // Read tiles. + for (int i = 0; i < header.numTiles; ++i) + { + NavMeshTileHeader tileHeader; + readLen = fread(&tileHeader, sizeof(tileHeader), 1, fp); + if (readLen != 1) + { + fclose(fp); + return 0; + } + + if (!tileHeader.tileRef || !tileHeader.dataSize) + break; + + unsigned char* data = (unsigned char*)dtAlloc(tileHeader.dataSize, DT_ALLOC_PERM); + if (!data) break; + memset(data, 0, tileHeader.dataSize); + readLen = fread(data, tileHeader.dataSize, 1, fp); + if (readLen != 1) + { + dtFree(data); + fclose(fp); + return 0; + } + + mesh->addTile(data, tileHeader.dataSize, DT_TILE_FREE_DATA, tileHeader.tileRef, 0); + } + + fclose(fp); + + return mesh; +} + +void Sample::saveAll(const char* path, const dtNavMesh* mesh) +{ + if (!mesh) return; + + FILE* fp = fopen(path, "wb"); + if (!fp) + return; + + // Store header. + NavMeshSetHeader header; + header.magic = NAVMESHSET_MAGIC; + header.version = NAVMESHSET_VERSION; + header.numTiles = 0; + for (int i = 0; i < mesh->getMaxTiles(); ++i) + { + const dtMeshTile* tile = mesh->getTile(i); + if (!tile || !tile->header || !tile->dataSize) continue; + header.numTiles++; + } + memcpy(&header.params, mesh->getParams(), sizeof(dtNavMeshParams)); + fwrite(&header, sizeof(NavMeshSetHeader), 1, fp); + + // Store tiles. + for (int i = 0; i < mesh->getMaxTiles(); ++i) + { + const dtMeshTile* tile = mesh->getTile(i); + if (!tile || !tile->header || !tile->dataSize) continue; + + NavMeshTileHeader tileHeader; + tileHeader.tileRef = mesh->getTileRef(tile); + tileHeader.dataSize = tile->dataSize; + fwrite(&tileHeader, sizeof(tileHeader), 1, fp); + + fwrite(tile->data, tile->dataSize, 1, fp); + } + + fclose(fp); +} diff --git a/RecastDemo/Source/Sample_SoloMesh.cpp b/RecastDemo/Source/Sample_SoloMesh.cpp index 68cf7c8..2dd1af1 100644 --- a/RecastDemo/Source/Sample_SoloMesh.cpp +++ b/RecastDemo/Source/Sample_SoloMesh.cpp @@ -79,20 +79,38 @@ void Sample_SoloMesh::cleanup() dtFreeNavMesh(m_navMesh); m_navMesh = 0; } - + void Sample_SoloMesh::handleSettings() { Sample::handleCommonSettings(); - + if (imguiCheck("Keep Itermediate Results", m_keepInterResults)) m_keepInterResults = !m_keepInterResults; imguiSeparator(); + + imguiIndent(); + imguiIndent(); + + if (imguiButton("Save")) + { + Sample::saveAll("solo_navmesh.bin", m_navMesh); + } + + if (imguiButton("Load")) + { + dtFreeNavMesh(m_navMesh); + m_navMesh = Sample::loadAll("solo_navmesh.bin"); + m_navQuery->init(m_navMesh, 2048); + } + + imguiUnindent(); + imguiUnindent(); char msg[64]; snprintf(msg, 64, "Build Time: %.1fms", m_totalBuildTimeMs); imguiLabel(msg); - + imguiSeparator(); } diff --git a/RecastDemo/Source/Sample_TileMesh.cpp b/RecastDemo/Source/Sample_TileMesh.cpp index 7641987..3167cea 100644 --- a/RecastDemo/Source/Sample_TileMesh.cpp +++ b/RecastDemo/Source/Sample_TileMesh.cpp @@ -242,114 +242,6 @@ struct NavMeshTileHeader int dataSize; }; -void Sample_TileMesh::saveAll(const char* path, const dtNavMesh* mesh) -{ - if (!mesh) return; - - FILE* fp = fopen(path, "wb"); - if (!fp) - return; - - // Store header. - NavMeshSetHeader header; - header.magic = NAVMESHSET_MAGIC; - header.version = NAVMESHSET_VERSION; - header.numTiles = 0; - for (int i = 0; i < mesh->getMaxTiles(); ++i) - { - const dtMeshTile* tile = mesh->getTile(i); - if (!tile || !tile->header || !tile->dataSize) continue; - header.numTiles++; - } - memcpy(&header.params, mesh->getParams(), sizeof(dtNavMeshParams)); - fwrite(&header, sizeof(NavMeshSetHeader), 1, fp); - - // Store tiles. - for (int i = 0; i < mesh->getMaxTiles(); ++i) - { - const dtMeshTile* tile = mesh->getTile(i); - if (!tile || !tile->header || !tile->dataSize) continue; - - NavMeshTileHeader tileHeader; - tileHeader.tileRef = mesh->getTileRef(tile); - tileHeader.dataSize = tile->dataSize; - fwrite(&tileHeader, sizeof(tileHeader), 1, fp); - - fwrite(tile->data, tile->dataSize, 1, fp); - } - - fclose(fp); -} - -dtNavMesh* Sample_TileMesh::loadAll(const char* path) -{ - FILE* fp = fopen(path, "rb"); - if (!fp) return 0; - - // Read header. - NavMeshSetHeader header; - size_t readLen = fread(&header, sizeof(NavMeshSetHeader), 1, fp); - if (readLen != 1) - { - fclose(fp); - return 0; - } - if (header.magic != NAVMESHSET_MAGIC) - { - fclose(fp); - return 0; - } - if (header.version != NAVMESHSET_VERSION) - { - fclose(fp); - return 0; - } - - dtNavMesh* mesh = dtAllocNavMesh(); - if (!mesh) - { - fclose(fp); - return 0; - } - dtStatus status = mesh->init(&header.params); - if (dtStatusFailed(status)) - { - fclose(fp); - return 0; - } - - // Read tiles. - for (int i = 0; i < header.numTiles; ++i) - { - NavMeshTileHeader tileHeader; - readLen = fread(&tileHeader, sizeof(tileHeader), 1, fp); - if (readLen != 1) - { - fclose(fp); - return 0; - } - - if (!tileHeader.tileRef || !tileHeader.dataSize) - break; - - unsigned char* data = (unsigned char*)dtAlloc(tileHeader.dataSize, DT_ALLOC_PERM); - if (!data) break; - memset(data, 0, tileHeader.dataSize); - readLen = fread(data, tileHeader.dataSize, 1, fp); - if (readLen != 1) - { - fclose(fp); - return 0; - } - - mesh->addTile(data, tileHeader.dataSize, DT_TILE_FREE_DATA, tileHeader.tileRef, 0); - } - - fclose(fp); - - return mesh; -} - void Sample_TileMesh::handleSettings() { Sample::handleCommonSettings(); @@ -401,13 +293,13 @@ void Sample_TileMesh::handleSettings() if (imguiButton("Save")) { - saveAll("all_tiles_navmesh.bin", m_navMesh); + Sample::saveAll("all_tiles_navmesh.bin", m_navMesh); } if (imguiButton("Load")) { dtFreeNavMesh(m_navMesh); - m_navMesh = loadAll("all_tiles_navmesh.bin"); + m_navMesh = Sample::loadAll("all_tiles_navmesh.bin"); m_navQuery->init(m_navMesh, 2048); } diff --git a/RecastDemo/Source/TestCase.cpp b/RecastDemo/Source/TestCase.cpp index aecf9a8..cf1214a 100644 --- a/RecastDemo/Source/TestCase.cpp +++ b/RecastDemo/Source/TestCase.cpp @@ -76,6 +76,7 @@ static char* parseRow(char* buf, char* bufEnd, char* row, int len) case '\t': case ' ': if (start) break; + // else falls through default: start = false; row[n++] = c;