Created
November 13, 2010 00:31
-
-
Save vermie/674959 to your computer and use it in GitHub Desktop.
changes to mmtile format
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/contrib/mmap/src/MapBuilder.cpp b/contrib/mmap/src/MapBuilder.cpp | |
index e7fc2e3..dde03c7 100644 | |
--- a/contrib/mmap/src/MapBuilder.cpp | |
+++ b/contrib/mmap/src/MapBuilder.cpp | |
@@ -31,14 +31,15 @@ namespace MMAP | |
MapBuilder::MapBuilder(float maxWalkableAngle, | |
bool skipLiquid, | |
bool skipContinents, bool skipJunkMaps, bool skipBattlegrounds, | |
- bool hiResHeightmaps, bool debugOutput) : | |
+ bool hiResHeightmaps, bool debugOutput, bool newTilesOnly) : | |
m_vmapManager(NULL), | |
m_terrainBuilder(NULL), | |
m_debugOutput (debugOutput), | |
m_skipContinents (skipContinents), | |
m_skipJunkMaps (skipJunkMaps), | |
m_skipBattlegrounds (skipBattlegrounds), | |
- m_maxWalkableAngle (maxWalkableAngle) | |
+ m_maxWalkableAngle (maxWalkableAngle), | |
+ m_newTilesOnly (newTilesOnly) | |
{ | |
m_vmapManager = new VMapManager2(); | |
@@ -715,6 +716,21 @@ namespace MMAP | |
char tileString[10]; | |
sprintf(tileString, "[%02i,%02i]: ", tileX, tileY); | |
+ // open the file for writing | |
+ char fileName[255]; | |
+ sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); | |
+ FILE* file = fopen(fileName, "wb"); | |
+ if (!file) | |
+ { | |
+ char message[1024]; | |
+ sprintf(message, "Failed to open %s for writing!\n", fileName); | |
+ perror(message); | |
+ return; | |
+ } | |
+ | |
+ mmapTileHeader header; | |
+ fwrite(&header, sizeof(header), 1, file); | |
+ | |
float cellSize = .5f; // larger number => less voxels => faster build time | |
// too large, and tight spaces won't be pathable. | |
float agentHeight = 1.5f; | |
@@ -981,28 +997,21 @@ namespace MMAP | |
continue; | |
} | |
- // file output | |
- char fileName[255]; | |
- sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); | |
- FILE* file = fopen(fileName, "wb"); | |
- if (!file) | |
- { | |
- char message[1024]; | |
- sprintf(message, "Failed to open %s for writing!\n", fileName); | |
- perror(message); | |
- navMesh->removeTile(tileRef, NULL, NULL); | |
- continue; | |
- } | |
- | |
printf("%s Writing to file... \r", tileString); | |
- // should write navDataSize first... for now, just use ftell to find length when reading | |
+ fwrite(&navDataSize, sizeof(navDataSize), 1, file); | |
fwrite(navData, sizeof(unsigned char), navDataSize, file); | |
- fclose(file); | |
+ | |
+ ++header.tileCount; | |
// now that tile is written to disk, we can unload it | |
navMesh->removeTile(tileRef, 0, 0); | |
} while (0); | |
+ // re-write header, so that tilecount is up to date | |
+ fseek(file, 0, SEEK_SET); | |
+ fwrite(&header, sizeof(header), 1, file); | |
+ fclose(file); | |
+ | |
if (m_debugOutput) | |
{ | |
generateObjFile(mapID, tileX, tileY, meshData); | |
@@ -1406,4 +1415,25 @@ namespace MMAP | |
return false; | |
} | |
} | |
+ | |
+ bool MapBuilder::shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY) | |
+ { | |
+ char fileName[255]; | |
+ sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); | |
+ FILE* file = fopen(fileName, "wb"); | |
+ if (!file) | |
+ return false; | |
+ | |
+ mmapTileHeader header; | |
+ fread(&header, sizeof(header), 1, file); | |
+ fclose(file); | |
+ | |
+ if (header.mmapMagic != MMAP_MAGIC || header.dtVersion != DT_NAVMESH_VERSION) | |
+ return false; | |
+ | |
+ if (m_newTilesOnly && header.mmapVersion != MMAP_VERSION) | |
+ return false; | |
+ | |
+ return true; | |
+ } | |
} | |
diff --git a/contrib/mmap/src/MapBuilder.h b/contrib/mmap/src/MapBuilder.h | |
index f9bb9a5..c77975d 100644 | |
--- a/contrib/mmap/src/MapBuilder.h | |
+++ b/contrib/mmap/src/MapBuilder.h | |
@@ -35,6 +35,9 @@ using namespace std; | |
using namespace VMAP; | |
// G3D namespace typedefs conflicts with ACE typedefs | |
+#define MMAP_MAGIC 0x4d4d4150 // 'MMAP' | |
+#define MMAP_VERSION 1 | |
+ | |
namespace MMAP | |
{ | |
typedef map<uint32,set<uint32>*> TileList; | |
@@ -49,16 +52,30 @@ namespace MMAP | |
rcPolyMeshDetail* polyMeshDetail; | |
}; | |
+ struct mmapTileHeader | |
+ { | |
+ uint32 mmapMagic; | |
+ uint32 dtVersion; | |
+ uint32 mmapVersion; | |
+ uint32 tileCount; | |
+ | |
+ mmapTileHeader() : | |
+ mmapMagic(MMAP_MAGIC), dtVersion(DT_NAVMESH_VERSION), | |
+ mmapVersion(MMAP_VERSION), tileCount(0) | |
+ {} | |
+ }; | |
+ | |
class MapBuilder | |
{ | |
public: | |
MapBuilder(float maxWalkableAngle = 60.f, | |
- bool skipLiquid = true, | |
+ bool skipLiquid = false, | |
bool skipContinents = true, | |
bool skipJunkMaps = true, | |
bool skipBattlegrounds = true, | |
bool hiResHeightmaps = false, | |
- bool debugOutput = false); | |
+ bool debugOutput = false, | |
+ bool newTilesOnly = true); | |
~MapBuilder(); | |
@@ -108,6 +125,7 @@ namespace MMAP | |
bool shouldSkipMap(uint32 mapID); | |
bool isTransportMap(uint32 mapID); | |
+ bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY); | |
// debug output | |
void generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData meshData); | |
@@ -130,6 +148,7 @@ namespace MMAP | |
bool m_skipContinents; | |
bool m_skipJunkMaps; | |
bool m_skipBattlegrounds; | |
+ bool m_newTilesOnly; | |
float m_maxWalkableAngle; | |
}; | |
diff --git a/src/game/Makefile.am b/src/game/Makefile.am | |
index e1ce0b3..6a4579d 100644 | |
--- a/src/game/Makefile.am | |
+++ b/src/game/Makefile.am | |
@@ -188,6 +188,7 @@ libmangosgame_a_SOURCES = \ | |
MotionMaster.cpp \ | |
MotionMaster.h \ | |
MoveMap.cpp \ | |
+ MoveMap.h \ | |
MovementGenerator.cpp \ | |
MovementGenerator.h \ | |
MovementGeneratorImpl.h \ | |
diff --git a/src/game/Map.h b/src/game/Map.h | |
index cf79a7e..5d7ed2f 100644 | |
--- a/src/game/Map.h | |
+++ b/src/game/Map.h | |
@@ -35,6 +35,7 @@ | |
#include "GameSystem/GridRefManager.h" | |
#include "MapRefManager.h" | |
#include "Utilities/TypeList.h" | |
+#include "MoveMap.h" | |
#include <bitset> | |
#include <list> | |
@@ -377,7 +378,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj | |
void LoadNavMesh(int gx, int gy); | |
void UnloadNavMesh(int gx, int gy); | |
dtNavMesh* m_navMesh; | |
- UNORDERED_MAP<uint32, dtTileRef> m_mmapLoadedTiles; // maps [map grid coords] to [dtTile] | |
+ TileTracker m_mmapLoadedTiles; // maps [map grid coords] to [dtTile] | |
static std::set<uint32> s_mmapDisabledIds; // stores list of mapids which do not use pathfinding | |
// end movemap-related | |
diff --git a/src/game/MoveMap.cpp b/src/game/MoveMap.cpp | |
index cd347d3..e5c53f5 100644 | |
--- a/src/game/MoveMap.cpp | |
+++ b/src/game/MoveMap.cpp | |
@@ -75,51 +75,74 @@ void Map::LoadNavMesh(int gx, int gy) | |
return; | |
} | |
- fseek(file, 0, SEEK_END); | |
- int length = ftell(file); | |
- fseek(file, 0, SEEK_SET); | |
- | |
- unsigned char* data = (unsigned char*)dtAlloc(length, DT_ALLOC_PERM); | |
- MANGOS_ASSERT(data); | |
- | |
- fread(data, length, 1, file); | |
- fclose(file); | |
- delete [] fileName; | |
+ mmapTileHeader mmapHeader; | |
+ if (sizeof(mmapHeader) != fread(&mmapHeader, sizeof(mmapHeader), 1, file)) | |
+ { | |
+ sLog.outError("%03u%02i%02i.mmtile has an invalid mmap header", i_id, gx, gy); | |
+ } | |
+ else | |
+ { | |
+ // TODO: check header MMAP_VERSION, MMAP_MAGIC, and DT_NAVMESH_VERSION | |
- dtMeshHeader* header = (dtMeshHeader*)data; | |
- dtTileRef tileRef = 0; | |
+ std::set<dtTileRef>* newTiles = new std::set<dtTileRef>; | |
+ m_mmapLoadedTiles.insert(std::pair<uint32, std::set<dtTileRef>*>(packedGridPos, newTiles)); | |
- // memory allocated for data is now managed by detour, and will be deallocated when the tile is removed | |
- dtStatus dtResult = m_navMesh->addTile(data, length, DT_TILE_FREE_DATA, 0, &tileRef); | |
- switch(dtResult) | |
- { | |
- case DT_SUCCESS: | |
- { | |
- m_mmapLoadedTiles.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef)); | |
- sLog.outDetail("Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", i_id, gx, gy, i_id, header->x, header->y); | |
- } | |
- break; | |
- case DT_FAILURE_DATA_MAGIC: | |
+ for (uint32 i = 0; i < mmapHeader.tileCount; ++i) | |
{ | |
- sLog.outError("%03u%02i%02i.mmtile has an invalid header", i_id, gx, gy); | |
- dtFree(data); | |
+ uint32 length; | |
+ fread(&length, sizeof(length), 1, file); | |
+ | |
+ if (!length) | |
+ continue; | |
+ | |
+ unsigned char* data = (unsigned char*)dtAlloc(length, DT_ALLOC_PERM); | |
+ MANGOS_ASSERT(data); | |
+ | |
+ if (length != fread(data, length, 1, file)) | |
+ { | |
+ sLog.outError("Failed reading tile data from %03u%02i%02i.mmtile", i_id, gx, gy); | |
+ dtFree(data); | |
+ break; | |
+ } | |
+ | |
+ dtMeshHeader* header = (dtMeshHeader*)data; | |
+ dtTileRef tileRef = 0; | |
+ | |
+ // memory allocated for data is now managed by detour, and will be deallocated when the tile is removed | |
+ dtStatus dtResult = m_navMesh->addTile(data, length, DT_TILE_FREE_DATA, 0, &tileRef); | |
+ switch(dtResult) | |
+ { | |
+ case DT_SUCCESS: | |
+ { | |
+ newTiles->insert(tileRef); | |
+ sLog.outDetail("Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", i_id, gx, gy, i_id, header->x, header->y); | |
+ } | |
+ break; | |
+ case DT_FAILURE_DATA_MAGIC: | |
+ { | |
+ sLog.outError("%03u%02i%02i.mmtile has an invalid tile header", i_id, gx, gy); | |
+ dtFree(data); | |
+ } | |
+ break; | |
+ case DT_FAILURE_DATA_VERSION: | |
+ { | |
+ sLog.outError("%03u%02i%02i.mmtile was built with Detour v%i, expected v%i",i_id, gx, gy, header->version, DT_NAVMESH_VERSION); | |
+ dtFree(data); | |
+ } | |
+ break; | |
+ case DT_FAILURE_OUT_OF_MEMORY: | |
+ case DT_FAILURE: | |
+ default: | |
+ { | |
+ sLog.outError("Could not load %03u%02i%02i.mmtile into navmesh", i_id, gx, gy); | |
+ dtFree(data); | |
+ } | |
+ break; | |
+ } | |
} | |
- break; | |
- case DT_FAILURE_DATA_VERSION: | |
- { | |
- sLog.outError("%03u%02i%02i.mmtile was built with Detour v%i, expected v%i",i_id, gx, gy, header->version, DT_NAVMESH_VERSION); | |
- dtFree(data); | |
- } | |
- break; | |
- case DT_FAILURE_OUT_OF_MEMORY: | |
- case DT_FAILURE: | |
- default: | |
- { | |
- sLog.outError("Could not load %03u%02i%02i.mmtile into navmesh", i_id, gx, gy); | |
- dtFree(data); | |
- } | |
- break; | |
} | |
+ fclose(file); | |
+ delete [] fileName; | |
} | |
void Map::UnloadNavMesh(int gx, int gy) | |
@@ -135,17 +158,34 @@ void Map::UnloadNavMesh(int gx, int gy) | |
return; | |
} | |
- dtTileRef tileRef = m_mmapLoadedTiles[packedGridPos]; | |
+ std::set<dtTileRef>* tiles = m_mmapLoadedTiles[packedGridPos]; | |
+ std::set<dtTileRef> removedTiles; | |
+ bool success = true; | |
- // unload, and mark as non loaded | |
- if(DT_SUCCESS != m_navMesh->removeTile(tileRef, NULL, NULL)) | |
+ for (std::set<dtTileRef>::iterator it = tiles->begin(); it != tiles->end(); ++it) | |
{ | |
- sLog.outError("Could not unload %03u%02i%02i.mmtile from navmesh", i_id, gx, gy); | |
+ // unload, and mark as non loaded | |
+ if(DT_SUCCESS != m_navMesh->removeTile(*it, NULL, NULL)) | |
+ success = false; | |
+ else | |
+ removedTiles.insert(*it); | |
} | |
- else | |
+ | |
+ if (success) | |
{ | |
- m_mmapLoadedTiles.erase(packedGridPos); | |
sLog.outDetail("Unloaded mmtile %03i[%02i,%02i] from %03i", i_id, gx, gy, i_id); | |
+ delete tiles; | |
+ m_mmapLoadedTiles.erase(packedGridPos); | |
+ } | |
+ else | |
+ { | |
+ for (std::set<dtTileRef>::iterator it = removedTiles.begin(); it != removedTiles.end(); ++it) | |
+ { | |
+ tiles->erase(*it); | |
+ } | |
+ | |
+ // this means a memory leak, and should be handled with more than an error message? | |
+ sLog.outError("Could not unload tile from navmesh (%03u%02i%02i.mmtile)", i_id, gx, gy); | |
} | |
} | |
diff --git a/win/VC100/game.vcxproj b/win/VC100/game.vcxproj | |
index 2463d00..c229aa1 100644 | |
--- a/win/VC100/game.vcxproj | |
+++ b/win/VC100/game.vcxproj | |
@@ -474,7 +474,7 @@ | |
<ClCompile Include="..\..\src\game\SocialMgr.cpp" /> | |
<ClCompile Include="..\..\src\game\Spell.cpp" /> | |
<ClCompile Include="..\..\src\game\SpellAuras.cpp" /> | |
- <ClCompile Include="..\..\src\game\UnitAuraProcHandler.cpp" /> | |
+ <ClCompile Include="..\..\src\game\UnitAuraProcHandler.cpp" /> | |
<ClCompile Include="..\..\src\game\SpellEffects.cpp" /> | |
<ClCompile Include="..\..\src\game\SpellHandler.cpp" /> | |
<ClCompile Include="..\..\src\game\SpellMgr.cpp" /> | |
@@ -580,6 +580,7 @@ | |
<ClInclude Include="..\..\src\game\MapReference.h" /> | |
<ClInclude Include="..\..\src\game\MapRefManager.h" /> | |
<ClInclude Include="..\..\src\game\MotionMaster.h" /> | |
+ <ClInclude Include="..\..\src\game\MoveMap.h" /> | |
<ClInclude Include="..\..\src\game\MovementGenerator.h" /> | |
<ClInclude Include="..\..\src\game\NPCHandler.h" /> | |
<ClInclude Include="..\..\src\game\NullCreatureAI.h" /> | |
diff --git a/win/VC100/game.vcxproj.filters b/win/VC100/game.vcxproj.filters | |
index 7497cde..504a5c5 100644 | |
--- a/win/VC100/game.vcxproj.filters | |
+++ b/win/VC100/game.vcxproj.filters | |
@@ -850,5 +850,8 @@ | |
<ClInclude Include="..\..\src\game\Camera.h"> | |
<Filter>Object</Filter> | |
</ClInclude> | |
+ <ClInclude Include="..\..\src\game\MoveMap.h"> | |
+ <Filter>World/Handlers</Filter> | |
+ </ClInclude> | |
</ItemGroup> | |
</Project> | |
\ No newline at end of file | |
diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj | |
index 1c00959..4a0419f 100644 | |
--- a/win/VC90/game.vcproj | |
+++ b/win/VC90/game.vcproj | |
@@ -859,6 +859,10 @@ | |
> | |
</File> | |
<File | |
+ RelativePath="..\..\src\game\MoveMap.h" | |
+ > | |
+ </File> | |
+ <File | |
RelativePath="..\..\src\game\MovementHandler.cpp" | |
> | |
</File> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment