Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions contrib/mmap/offmesh.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
30 32,33 (-759.16 -350.45 68.96) (-758.2 -348.56 67.56) 2.5 // AV
30 32,33 (-761.69 -349.45 69.0) (-761 -347.83 67.61) 2.5
30 32,33 (-765.1 -348 69) (-764.53 -346.58 67.66) 2.5
189 29,28 (1827.839478 1315.610962 17.235508) (1830.25244 1315.189697 19.016930) 2.5
// Format: mapID tileX,tileY (start_x start_y start_z) (end_x end_y end_z) size
// size: width/radius of the connection path
30 32,33 (-759.16 -350.45 68.96) (-758.2 -348.56 67.56) 2.5 // AV - Tower entrance
30 32,33 (-761.69 -349.45 69.0) (-761 -347.83 67.61) 2.5 // AV - Tower entrance
30 32,33 (-765.1 -348 69) (-764.53 -346.58 67.66) 2.5 // AV - Tower entrance
189 29,28 (1827.839478 1315.610962 17.235508) (1830.25244 1315.189697 19.016930) 2.5 // Scarlet Monastery Graveyard - path out of spawn position
36 33,32 (-23.427919 -797.150940 20.145432) (-23.941082 -797.715393 19.456278) 2.5 // The Deadmines - Mr. Smite ship -> bridge
2 changes: 1 addition & 1 deletion contrib/mmap/src/IntermediateValues.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ namespace MMAP
void IntermediateValues::generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData)
{
char objFileName[255];
snprintf(objFileName, sizeof(objFileName), "map%03u%02u%02u", mapID, tileX, tileY);
sprintf(objFileName, "map%03u%02u%02u", mapID, tileY, tileX);
generateObjFile(objFileName, meshData);
}
void IntermediateValues::generateObjFile(std::string filename, MeshData& meshData)
Expand Down
41 changes: 18 additions & 23 deletions contrib/mmap/src/MapBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@ namespace MMAP
m_cancel.store(false);
buildMap(mapID);
processQueuedTiles();
printf("Done.");

printf("[Map %03i] Updated map file: mmaps/%03u.mmap\n", mapID, mapID);
printf("Done.\n");
}

void MapBuilder::buildAllMaps()
Expand All @@ -161,7 +163,7 @@ namespace MMAP
}

processQueuedTiles();
printf("Done.");
printf("Done.\n");
}

void MapBuilder::processQueuedTiles()
Expand Down Expand Up @@ -242,15 +244,17 @@ namespace MMAP
uint32 minX, minY, maxX, maxY;
getGridBounds(mapID, minX, minY, maxX, maxY);

// add all tiles within bounds to tile list.
for (uint32 i = minX; i <= maxX; ++i)
for (uint32 j = minY; j <= maxY; ++j)
if (i == tileX && j == tileY)
tiles.insert(StaticMapTree::packTileID(i, j));
// Only add the requested tile to avoid allocating NavMesh for entire map
// when building a single tile (which would cause massive memory overhead).
if (tileX >= minX && tileX <= maxX && tileY >= minY && tileY <= maxY)
tiles.insert(StaticMapTree::packTileID(tileX, tileY));
}

if (!tiles.size())
{
printf("[Map %03i] Tile [%02u,%02u] not found in valid tile range!\n", mapID, tileX, tileY);
return;
}

dtNavMesh* navMesh = nullptr;
buildNavMesh(mapID, navMesh);
Expand All @@ -260,32 +264,23 @@ namespace MMAP
return;
}

printf("Adding %i, %i, %i", mapID, tileX, tileY);
printf("[Map %03i] Building single tile [%02u,%02u]\n", mapID, tileX, tileY);

TileInfo tileInfo;
tileInfo.m_mapId = mapID;
tileInfo.m_tileX = tileX;
tileInfo.m_tileY = tileY;
tileInfo.m_curTile = 0;
tileInfo.m_tileCount = uint32(tiles.size());
tileInfo.m_curTile = 1;
tileInfo.m_tileCount = 1;
tileInfo.m_forceRebuild = true; // Always rebuild when building a single tile
memcpy(&tileInfo.m_navMeshParams, navMesh->getParams(), sizeof(dtNavMeshParams));
m_tileQueue.Push(tileInfo);

auto worker = std::make_unique<TileWorker>(this, false, m_quick, m_debug, m_config);

while (!m_tileQueue.Empty() && !m_cancel.load())
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}

m_cancel.store(true);
m_tileQueue.Cancel();

worker->WaitCompletion();

dtFreeNavMesh(navMesh);

printf("Building single tile finished.");
processQueuedTiles();

printf("[Map %03i] Generated file: mmaps/%03u%02u%02u.mmtile\n", mapID, mapID, tileY, tileX);
}

void MapBuilder::buildMap(uint32 mapID)
Expand Down
8 changes: 7 additions & 1 deletion contrib/mmap/src/TerrainBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1006,7 +1006,7 @@ namespace MMAP
}

/**************************************************************************/
void TerrainBuilder::loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData, char const* offMeshFilePath)
void TerrainBuilder::loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData, char const* offMeshFilePath, bool printOffmeshData)
{
// no meshfile input given?
if (offMeshFilePath == nullptr)
Expand All @@ -1033,6 +1033,12 @@ namespace MMAP

if (mapID == mid && tileX == tx && tileY == ty)
{
if (printOffmeshData)
{
printf(" loadOffMeshConnections:: Found offmesh connection for map %u tile [%u,%u]: (%.2f %.2f %.2f) -> (%.2f %.2f %.2f) size %.2f\n",
mapID, tileX, tileY, p0[0], p0[1], p0[2], p1[0], p1[1], p1[2], size);
}

meshData.offMeshConnections.append(p0[1]);
meshData.offMeshConnections.append(p0[2]);
meshData.offMeshConnections.append(p0[0]);
Expand Down
2 changes: 1 addition & 1 deletion contrib/mmap/src/TerrainBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ namespace MMAP
void loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData);
bool loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData);
void unloadVMap(uint32 mapID, uint32 tileX, uint32 tileY);
void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData, const char* offMeshFilePath);
void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData, const char* offMeshFilePath, bool printOffmeshData = false);

bool usesLiquids() { return !m_skipLiquid; }

Expand Down
10 changes: 5 additions & 5 deletions contrib/mmap/src/TileWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ namespace MMAP
return;
}

buildTile(tileInfo.m_mapId, tileInfo.m_tileX, tileInfo.m_tileY, navMesh, tileInfo.m_curTile, tileInfo.m_tileCount);
buildTile(tileInfo.m_mapId, tileInfo.m_tileX, tileInfo.m_tileY, navMesh, tileInfo.m_curTile, tileInfo.m_tileCount, tileInfo.m_forceRebuild);
dtFreeNavMesh(navMesh);
}
else
Expand Down Expand Up @@ -374,9 +374,9 @@ namespace MMAP
return true;
}

void TileWorker::buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh, uint32 curTile, uint32 tileCount)
void TileWorker::buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh, uint32 curTile, uint32 tileCount, bool forceRebuild)
{
if (shouldSkipTile(mapID, tileX, tileY))
if (!forceRebuild && shouldSkipTile(mapID, tileX, tileY))
{
return;
}
Expand Down Expand Up @@ -410,8 +410,8 @@ namespace MMAP
float bmin[3], bmax[3];
m_mapBuilder->getTileBounds(tileX, tileY, allVerts.getCArray(), allVerts.size() / 3, bmin, bmax);

// offmesh.txt
m_terrainBuilder->loadOffMeshConnections(mapID, tileX, tileY, meshData, m_mapBuilder->m_offMeshFilePath);
// offmesh.txt (verbose output only for single tile builds)
m_terrainBuilder->loadOffMeshConnections(mapID, tileX, tileY, meshData, m_mapBuilder->m_offMeshFilePath, tileCount == 1);

// build navmesh tile
buildMoveMapTile(mapID, tileX, tileY, meshData, bmin, bmax, navMesh);
Expand Down
5 changes: 3 additions & 2 deletions contrib/mmap/src/TileWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ namespace MMAP
{
struct TileInfo
{
TileInfo() : m_mapId(uint32(-1)), m_tileX(), m_tileY(), m_navMeshParams(), m_curTile(0), m_tileCount(0) {}
TileInfo() : m_mapId(uint32(-1)), m_tileX(), m_tileY(), m_navMeshParams(), m_curTile(0), m_tileCount(0), m_forceRebuild(false) {}

uint32 m_mapId;
uint32 m_tileX;
uint32 m_tileY;
uint32 m_curTile;
uint32 m_tileCount;
dtNavMeshParams m_navMeshParams;
bool m_forceRebuild;
};

template <typename T>
Expand Down Expand Up @@ -153,7 +154,7 @@ namespace MMAP
bool duDumpPolyMeshToObj(rcPolyMesh& pmesh, uint32 mapID, uint32 tileY, uint32 tileX);
bool duDumpPolyMeshDetailToObj(rcPolyMeshDetail& dmesh, uint32 mapID, uint32 tileY, uint32 tileX);
bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY);
void buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh, uint32 curTile, uint32 tileCount);
void buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh, uint32 curTile, uint32 tileCount, bool forceRebuild = false);
void buildMoveMapTile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData, float bmin[3], float bmax[3], dtNavMesh* navMesh);

json getDefaultConfig();
Expand Down
4 changes: 2 additions & 2 deletions contrib/vmap_extractor/vmapextract/adtfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY, StringSet& failed
char* p = buf;
while (p < buf + size)
{
FixNameCase(p, strlen(p));
std::string path(p); // Store copy after name fixed
// Store original path before any modifications for ExtractSingleModel's fallback logic
std::string path(p); // Store copy of original path

std::string fixedName;
ExtractSingleModel(path, fixedName, failedPaths);
Expand Down
70 changes: 54 additions & 16 deletions contrib/vmap_extractor/vmapextract/gameobject_extract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@
#include "dbcfile.h"
#include "wmo.h"
#include "vmapexport.h"
#include "libmpq/mpq_libmpq.h"

#include <algorithm>
#include <stdio.h>

// Check if file exists in MPQ without adding to failedPaths
static bool MPQFileExists(const std::string& path)
{
MPQFile f(path.c_str());
bool exists = !f.isEof();
f.close();
return exists;
}

bool ExtractSingleModel(std::string& origPath, std::string& fixedName, StringSet& failedPaths)
{
if (origPath.length() < 4)
Expand All @@ -23,25 +33,50 @@ bool ExtractSingleModel(std::string& origPath, std::string& fixedName, StringSet
// >= 3.1.0 ADT MMDX section store filename.m2 filenames for corresponded .m2 file
// nothing do

std::string originalPath = origPath;

char* name = GetPlainName((char*)origPath.c_str());
FixNameCase(name, strlen(name));
FixNameSpaces(name, strlen(name)); // Fix a few models with spaces instead of underscores in their filenames (razorfen leanto03)

std::string output(szWorkDirWmo); // Stores output filename (possible changed)
output += "/";
output += name;
FixNameSpaces(name, strlen(name));
fixedName = name;

std::string output = std::string(szWorkDirWmo) + "/" + name;
if (FileExists(output.c_str()))
return true;

// Try 1: Path with underscores
Model mdl(origPath);
if (!mdl.open(failedPaths)) // Possible changed fname
return false;
if (mdl.open(failedPaths))
return mdl.ConvertToVMAPModel(output.c_str());

// Try 2: Original path (with spaces if it had them)
if (originalPath != origPath && MPQFileExists(originalPath))
{
failedPaths.erase(origPath);
Model mdl2(originalPath);
if (mdl2.open(failedPaths))
return mdl2.ConvertToVMAPModel(output.c_str());
}

return mdl.ConvertToVMAPModel(output.c_str());
// Try 3: Filename with underscores converted to spaces
size_t lastSlash = origPath.find_last_of("\\/");
if (lastSlash != std::string::npos)
{
std::string altPath = origPath;
std::replace(altPath.begin() + lastSlash + 1, altPath.end(), '_', ' ');
if (altPath != origPath && altPath != originalPath && MPQFileExists(altPath))
{
failedPaths.erase(origPath);
Model mdl3(altPath);
if (mdl3.open(failedPaths))
return mdl3.ConvertToVMAPModel(output.c_str());
}
}

return false;
}

void ExtractGameobjectModels()
bool ExtractGameobjectModels()
{
printf("\n");
printf("Extracting GameObject models...\n");
Expand All @@ -68,28 +103,29 @@ void ExtractGameobjectModels()

FixNameCase((char*)path.c_str(), path.size());
char* name = GetPlainName((char*)path.c_str());
FixNameSpaces(name, strlen(name));

char const* ch_ext = GetExtension(name);
if (!ch_ext)
continue;

//strToLower(ch_ext);

bool result = false;
std::string fixedName;

if (!strcmp(ch_ext, ".wmo"))
{
result = ExtractSingleWmo(path);
if (result)
FixNameSpaces(name, strlen(name));
}
else if (!strcmp(ch_ext, ".mdl"))
{
// TODO: extract .mdl files, if needed
continue;
}
else //if (!strcmp(ch_ext, ".mdx") || !strcmp(ch_ext, ".m2"))
else
{
std::string fixedName;
result = ExtractSingleModel(path, fixedName, failedPaths);
if (result)
name = (char*)fixedName.c_str();
}

if (result)
Expand All @@ -109,8 +145,10 @@ void ExtractGameobjectModels()
printf("Warning: Some models could not be extracted, see below\n");
for (StringSet::const_iterator itr = failedPaths.begin(); itr != failedPaths.end(); ++itr)
printf("Could not find file of model %s\n", itr->c_str());
printf("A few of these warnings are expected to happen, so be not alarmed!\n");
printf("Done!\n");
return false;
}

printf("Done!\n");
return true;
}
Loading