#include #include #include #include #include "Recast.h" #include "DetourCommon.h" #include "DetourNavMesh.h" #include "DetourNavMeshBuilder.h" #include "DetourNavMeshQuery.h" #include "mesh_loader.h" void save_navmesh(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* load_navmesh(const char* path) { FILE* fp = fopen(path, "rb"); if (!fp) return 0; // Read header. NavMeshSetHeader header; fread(&header, sizeof(NavMeshSetHeader), 1, fp); if (header.magic != NAVMESHSET_MAGIC) { fclose(fp); fprintf (stderr, "Bad magic %d\n", header.magic); return 0; } if (header.version != NAVMESHSET_VERSION) { fclose(fp); fprintf (stderr, "Bad version %d\n", header.version); 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; fread(&tileHeader, sizeof(tileHeader), 1, fp); 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); fread(data, tileHeader.dataSize, 1, fp); //fprintf (stderr, "Adding tile %s\n", data); mesh->addTile(data, tileHeader.dataSize, DT_TILE_FREE_DATA, tileHeader.tileRef, 0); } fclose(fp); return mesh; }