Skip to content

Instantly share code, notes, and snippets.

@vermie
Created November 13, 2010 00:31
Show Gist options
  • Save vermie/674959 to your computer and use it in GitHub Desktop.
Save vermie/674959 to your computer and use it in GitHub Desktop.
changes to mmtile format
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