aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tools/mmaps_generator/IntermediateValues.cpp2
-rw-r--r--src/tools/mmaps_generator/IntermediateValues.h2
-rw-r--r--src/tools/mmaps_generator/TerrainBuilder.cpp205
-rw-r--r--src/tools/mmaps_generator/TileBuilder.cpp156
4 files changed, 183 insertions, 182 deletions
diff --git a/src/tools/mmaps_generator/IntermediateValues.cpp b/src/tools/mmaps_generator/IntermediateValues.cpp
index 5906cd866bc..f71e36fec0c 100644
--- a/src/tools/mmaps_generator/IntermediateValues.cpp
+++ b/src/tools/mmaps_generator/IntermediateValues.cpp
@@ -188,7 +188,7 @@ namespace MMAP
fwrite(mesh->meshes, sizeof(int), mesh->nmeshes*4, file);
}
- void IntermediateValues::generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData)
+ void IntermediateValues::generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData const& meshData)
{
std::string objFileName;
objFileName = Trinity::StringFormat("meshes/map{:04}{:02}{:02}.obj", mapID, tileY, tileX);
diff --git a/src/tools/mmaps_generator/IntermediateValues.h b/src/tools/mmaps_generator/IntermediateValues.h
index c9bbd1d7d73..5620152c15f 100644
--- a/src/tools/mmaps_generator/IntermediateValues.h
+++ b/src/tools/mmaps_generator/IntermediateValues.h
@@ -44,7 +44,7 @@ namespace MMAP
void debugWrite(FILE* file, rcPolyMesh const* mesh);
void debugWrite(FILE* file, rcPolyMeshDetail const* mesh);
- void generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData);
+ void generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData const& meshData);
};
}
#endif
diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp
index f13a662ec31..ede0c32441d 100644
--- a/src/tools/mmaps_generator/TerrainBuilder.cpp
+++ b/src/tools/mmaps_generator/TerrainBuilder.cpp
@@ -571,136 +571,135 @@ namespace MMAP
bool TerrainBuilder::loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData, VMAP::VMapManager* vmapManager)
{
VMAP::LoadResult result = vmapManager->loadMap("vmaps", mapID, tileX, tileY);
- bool retval = false;
+ if (result != VMAP::LoadResult::Success)
+ return false;
- do
+ auto vmapTile = Trinity::make_unique_ptr_with_deleter(vmapManager, [=](VMAP::VMapManager* mgr)
{
- if (result != VMAP::LoadResult::Success)
- break;
+ mgr->unloadMap(mapID, tileX, tileY);
+ });
- std::span<VMAP::ModelInstance const> models = vmapManager->getModelsOnMap(mapID);
- if (models.empty())
- break;
+ std::span<VMAP::ModelInstance const> models = vmapManager->getModelsOnMap(mapID);
+ if (models.empty())
+ return false;
- for (VMAP::ModelInstance const& instance : models)
- {
- // model instances exist in tree even though there are instances of that model in this tile
- VMAP::WorldModel const* worldModel = instance.getWorldModel();
- if (!worldModel)
- continue;
+ bool retval = false;
- // now we have a model to add to the meshdata
- retval = true;
+ for (VMAP::ModelInstance const& instance : models)
+ {
+ // model instances exist in tree even though there are instances of that model in this tile
+ VMAP::WorldModel const* worldModel = instance.getWorldModel();
+ if (!worldModel)
+ continue;
- std::vector<VMAP::GroupModel> const& groupModels = worldModel->getGroupModels();
+ // now we have a model to add to the meshdata
+ retval = true;
- // all M2s need to have triangle indices reversed
- bool isM2 = worldModel->IsM2();
+ std::vector<VMAP::GroupModel> const& groupModels = worldModel->getGroupModels();
- // transform data
- float scale = instance.iScale;
- G3D::Matrix3 rotation = instance.GetInvRot();
- G3D::Vector3 position = instance.iPos;
- position.x -= 32 * GRID_SIZE;
- position.y -= 32 * GRID_SIZE;
+ // all M2s need to have triangle indices reversed
+ bool isM2 = worldModel->IsM2();
- for (std::vector<VMAP::GroupModel>::const_iterator it = groupModels.begin(); it != groupModels.end(); ++it)
- {
- std::vector<G3D::Vector3> const& tempVertices = it->GetVertices();
- std::vector<G3D::Vector3> transformedVertices;
- std::vector<VMAP::MeshTriangle> const& tempTriangles = it->GetTriangles();
- VMAP::WmoLiquid const* liquid = it->GetLiquid();
+ // transform data
+ float scale = instance.iScale;
+ G3D::Matrix3 rotation = instance.GetInvRot();
+ G3D::Vector3 position = instance.iPos;
+ position.x -= 32 * GRID_SIZE;
+ position.y -= 32 * GRID_SIZE;
+
+ for (std::vector<VMAP::GroupModel>::const_iterator it = groupModels.begin(); it != groupModels.end(); ++it)
+ {
+ std::vector<G3D::Vector3> const& tempVertices = it->GetVertices();
+ std::vector<G3D::Vector3> transformedVertices;
+ std::vector<VMAP::MeshTriangle> const& tempTriangles = it->GetTriangles();
+ VMAP::WmoLiquid const* liquid = it->GetLiquid();
- // first handle collision mesh
- transform(tempVertices, transformedVertices, scale, rotation, position);
+ // first handle collision mesh
+ transform(tempVertices, transformedVertices, scale, rotation, position);
- int offset = meshData.solidVerts.size() / 3;
+ int offset = meshData.solidVerts.size() / 3;
- copyVertices(transformedVertices, meshData.solidVerts);
- copyIndices(tempTriangles, meshData.solidTris, offset, isM2);
+ copyVertices(transformedVertices, meshData.solidVerts);
+ copyIndices(tempTriangles, meshData.solidTris, offset, isM2);
- // now handle liquid data
- if (liquid && liquid->GetFlagsStorage())
+ // now handle liquid data
+ if (liquid && liquid->GetFlagsStorage())
+ {
+ std::vector<G3D::Vector3> liqVerts;
+ std::vector<int> liqTris;
+ uint32 tilesX, tilesY, vertsX, vertsY;
+ G3D::Vector3 corner;
+ liquid->getPosInfo(tilesX, tilesY, corner);
+ vertsX = tilesX + 1;
+ vertsY = tilesY + 1;
+ uint8 const* flags = liquid->GetFlagsStorage();
+ float const* data = liquid->GetHeightStorage();
+ uint8 type = NAV_AREA_EMPTY;
+
+ // convert liquid type to NavTerrain
+ EnumFlag<map_liquidHeaderTypeFlags> liquidFlags = map_liquidHeaderTypeFlags(vmapManager->GetLiquidFlagsPtr(liquid->GetType()));
+ if (liquidFlags.HasFlag(map_liquidHeaderTypeFlags::Water | map_liquidHeaderTypeFlags::Ocean))
+ type = NAV_AREA_WATER;
+ else if (liquidFlags.HasFlag(map_liquidHeaderTypeFlags::Magma | map_liquidHeaderTypeFlags::Slime))
+ type = NAV_AREA_MAGMA_SLIME;
+
+ // indexing is weird...
+ // after a lot of trial and error, this is what works:
+ // vertex = y*vertsX+x
+ // tile = x*tilesY+y
+ // flag = y*tilesY+x
+
+ G3D::Vector3 vert;
+ for (uint32 x = 0; x < vertsX; ++x)
{
- std::vector<G3D::Vector3> liqVerts;
- std::vector<int> liqTris;
- uint32 tilesX, tilesY, vertsX, vertsY;
- G3D::Vector3 corner;
- liquid->getPosInfo(tilesX, tilesY, corner);
- vertsX = tilesX + 1;
- vertsY = tilesY + 1;
- uint8 const* flags = liquid->GetFlagsStorage();
- float const* data = liquid->GetHeightStorage();
- uint8 type = NAV_AREA_EMPTY;
-
- // convert liquid type to NavTerrain
- EnumFlag<map_liquidHeaderTypeFlags> liquidFlags = map_liquidHeaderTypeFlags(vmapManager->GetLiquidFlagsPtr(liquid->GetType()));
- if (liquidFlags.HasFlag(map_liquidHeaderTypeFlags::Water | map_liquidHeaderTypeFlags::Ocean))
- type = NAV_AREA_WATER;
- else if (liquidFlags.HasFlag(map_liquidHeaderTypeFlags::Magma | map_liquidHeaderTypeFlags::Slime))
- type = NAV_AREA_MAGMA_SLIME;
-
- // indexing is weird...
- // after a lot of trial and error, this is what works:
- // vertex = y*vertsX+x
- // tile = x*tilesY+y
- // flag = y*tilesY+x
-
- G3D::Vector3 vert;
- for (uint32 x = 0; x < vertsX; ++x)
+ for (uint32 y = 0; y < vertsY; ++y)
{
- for (uint32 y = 0; y < vertsY; ++y)
- {
- vert = G3D::Vector3(corner.x + x * GRID_PART_SIZE, corner.y + y * GRID_PART_SIZE, data[y * vertsX + x]);
- vert = vert * rotation * scale + position;
- vert.x *= -1.f;
- vert.y *= -1.f;
- liqVerts.push_back(vert);
- }
+ vert = G3D::Vector3(corner.x + x * GRID_PART_SIZE, corner.y + y * GRID_PART_SIZE, data[y * vertsX + x]);
+ vert = vert * rotation * scale + position;
+ vert.x *= -1.f;
+ vert.y *= -1.f;
+ liqVerts.push_back(vert);
}
+ }
- int idx1, idx2, idx3, idx4;
- uint32 square;
- for (uint32 x = 0; x < tilesX; ++x)
+ int idx1, idx2, idx3, idx4;
+ uint32 square;
+ for (uint32 x = 0; x < tilesX; ++x)
+ {
+ for (uint32 y = 0; y < tilesY; ++y)
{
- for (uint32 y = 0; y < tilesY; ++y)
+ if ((flags[x + y * tilesX] & 0x0f) != 0x0f)
{
- if ((flags[x + y * tilesX] & 0x0f) != 0x0f)
- {
- square = x * tilesY + y;
- idx1 = square + x;
- idx2 = square + 1 + x;
- idx3 = square + tilesY + 1 + 1 + x;
- idx4 = square + tilesY + 1 + x;
-
- // top triangle
- liqTris.push_back(idx3);
- liqTris.push_back(idx2);
- liqTris.push_back(idx1);
- // bottom triangle
- liqTris.push_back(idx4);
- liqTris.push_back(idx3);
- liqTris.push_back(idx1);
- }
+ square = x * tilesY + y;
+ idx1 = square + x;
+ idx2 = square + 1 + x;
+ idx3 = square + tilesY + 1 + 1 + x;
+ idx4 = square + tilesY + 1 + x;
+
+ // top triangle
+ liqTris.push_back(idx3);
+ liqTris.push_back(idx2);
+ liqTris.push_back(idx1);
+ // bottom triangle
+ liqTris.push_back(idx4);
+ liqTris.push_back(idx3);
+ liqTris.push_back(idx1);
}
}
+ }
- uint32 liqOffset = meshData.liquidVerts.size() / 3;
- for (uint32 i = 0; i < liqVerts.size(); ++i)
- meshData.liquidVerts.append(liqVerts[i].y, liqVerts[i].z, liqVerts[i].x);
+ uint32 liqOffset = meshData.liquidVerts.size() / 3;
+ for (uint32 i = 0; i < liqVerts.size(); ++i)
+ meshData.liquidVerts.append(liqVerts[i].y, liqVerts[i].z, liqVerts[i].x);
- for (uint32 i = 0; i < liqTris.size() / 3; ++i)
- {
- meshData.liquidTris.append(liqTris[i * 3 + 1] + liqOffset, liqTris[i * 3 + 2] + liqOffset, liqTris[i * 3] + liqOffset);
- meshData.liquidType.append(type);
- }
+ for (uint32 i = 0; i < liqTris.size() / 3; ++i)
+ {
+ meshData.liquidTris.append(liqTris[i * 3 + 1] + liqOffset, liqTris[i * 3 + 2] + liqOffset, liqTris[i * 3] + liqOffset);
+ meshData.liquidType.append(type);
}
}
}
}
- while (false);
-
- vmapManager->unloadMap(mapID, tileX, tileY);
return retval;
}
diff --git a/src/tools/mmaps_generator/TileBuilder.cpp b/src/tools/mmaps_generator/TileBuilder.cpp
index ffd7787f2cd..6cbf3eef99a 100644
--- a/src/tools/mmaps_generator/TileBuilder.cpp
+++ b/src/tools/mmaps_generator/TileBuilder.cpp
@@ -371,98 +371,100 @@ namespace MMAP
unsigned char* navData = nullptr;
int navDataSize = 0;
- do
+ auto debugOutputWriter = Trinity::make_unique_ptr_with_deleter(m_debugOutput ? &iv : nullptr, [=, borderSize = static_cast<unsigned short>(config.borderSize), &meshData](IntermediateValues* intermediate)
{
- // these values are checked within dtCreateNavMeshData - handle them here
- // so we have a clear error message
- if (params.nvp > DT_VERTS_PER_POLYGON)
+ // restore padding so that the debug visualization is correct
+ for (std::ptrdiff_t i = 0; i < intermediate->polyMesh->nverts; ++i)
{
- TC_LOG_ERROR("maps.mmapgen", "{} Invalid verts-per-polygon value!", tileString);
- break;
+ unsigned short* v = &intermediate->polyMesh->verts[i * 3];
+ v[0] += borderSize;
+ v[2] += borderSize;
}
- if (params.vertCount >= 0xffff)
- {
- TC_LOG_ERROR("maps.mmapgen", "{} Too many vertices!", tileString);
- break;
- }
- if (!params.vertCount || !params.verts)
- {
- // occurs mostly when adjacent tiles have models
- // loaded but those models don't span into this tile
- // message is an annoyance
- //TC_LOG_ERROR("maps.mmapgen", "{} No vertices to build tile!", tileString);
- break;
- }
- if (!params.polyCount || !params.polys)
- {
- // we have flat tiles with no actual geometry - don't build those, its useless
- // keep in mind that we do output those into debug info
- TC_LOG_ERROR("maps.mmapgen", "{} No polygons to build on tile!", tileString);
- break;
- }
- if (!params.detailMeshes || !params.detailVerts || !params.detailTris)
- {
- TC_LOG_ERROR("maps.mmapgen", "{} No detail mesh to build tile!", tileString);
- break;
- }
+ intermediate->generateObjFile(mapID, tileX, tileY, meshData);
+ intermediate->writeIV(mapID, tileX, tileY);
+ });
- TC_LOG_DEBUG("maps.mmapgen", "{} Building navmesh tile...", tileString);
- if (!dtCreateNavMeshData(&params, &navData, &navDataSize))
- {
- TC_LOG_ERROR("maps.mmapgen", "{} Failed building navmesh tile!", tileString);
- break;
- }
+ // these values are checked within dtCreateNavMeshData - handle them here
+ // so we have a clear error message
+ if (params.nvp > DT_VERTS_PER_POLYGON)
+ {
+ TC_LOG_ERROR("maps.mmapgen", "{} Invalid verts-per-polygon value!", tileString);
+ return;
+ }
- dtTileRef tileRef = 0;
- TC_LOG_DEBUG("maps.mmapgen", "{} Adding tile to navmesh...", tileString);
- // DT_TILE_FREE_DATA tells detour to unallocate memory when the tile
- // is removed via removeTile()
- dtStatus dtResult = navMesh->addTile(navData, navDataSize, DT_TILE_FREE_DATA, 0, &tileRef);
- if (!tileRef || !dtStatusSucceed(dtResult))
- {
- TC_LOG_ERROR("maps.mmapgen", "{} Failed adding tile to navmesh!", tileString);
- break;
- }
+ if (params.vertCount >= 0xffff)
+ {
+ TC_LOG_ERROR("maps.mmapgen", "{} Too many vertices!", tileString);
+ return;
+ }
- // file output
- std::string fileName = Trinity::StringFormat("mmaps/{:04}{:02}{:02}.mmtile", mapID, tileY, tileX);
- auto file = Trinity::make_unique_ptr_with_deleter<&::fclose>(fopen(fileName.c_str(), "wb"));
- if (!file)
- {
- TC_LOG_ERROR("maps.mmapgen", "{}: [Map {:04}] Failed to open {} for writing!", strerror(errno), mapID, fileName);
- navMesh->removeTile(tileRef, nullptr, nullptr);
- break;
- }
+ if (!params.vertCount || !params.verts)
+ {
+ // occurs mostly when adjacent tiles have models
+ // loaded but those models don't span into this tile
- TC_LOG_DEBUG("maps.mmapgen", "{} Writing to file...", tileString);
+ // message is an annoyance
+ //TC_LOG_ERROR("maps.mmapgen", "{} No vertices to build tile!", tileString);
+ return;
+ }
- // write header
- MmapTileHeader header;
- header.usesLiquids = m_terrainBuilder.usesLiquids();
- header.size = uint32(navDataSize);
- fwrite(&header, sizeof(MmapTileHeader), 1, file.get());
+ if (!params.polyCount || !params.polys)
+ {
+ // we have flat tiles with no actual geometry - don't build those, its useless
+ // keep in mind that we do output those into debug info
+ TC_LOG_ERROR("maps.mmapgen", "{} No polygons to build on tile!", tileString);
+ return;
+ }
- // write data
- fwrite(navData, sizeof(unsigned char), navDataSize, file.get());
+ if (!params.detailMeshes || !params.detailVerts || !params.detailTris)
+ {
+ TC_LOG_ERROR("maps.mmapgen", "{} No detail mesh to build tile!", tileString);
+ return;
+ }
- // now that tile is written to disk, we can unload it
- navMesh->removeTile(tileRef, nullptr, nullptr);
- } while (false);
+ TC_LOG_DEBUG("maps.mmapgen", "{} Building navmesh tile...", tileString);
+ if (!dtCreateNavMeshData(&params, &navData, &navDataSize))
+ {
+ TC_LOG_ERROR("maps.mmapgen", "{} Failed building navmesh tile!", tileString);
+ return;
+ }
- if (m_debugOutput)
+ dtTileRef tileRef = 0;
+ TC_LOG_DEBUG("maps.mmapgen", "{} Adding tile to navmesh...", tileString);
+ // DT_TILE_FREE_DATA tells detour to unallocate memory when the tile
+ // is removed via removeTile()
+ dtStatus dtResult = navMesh->addTile(navData, navDataSize, DT_TILE_FREE_DATA, 0, &tileRef);
+ if (!tileRef || !dtStatusSucceed(dtResult))
{
- // restore padding so that the debug visualization is correct
- for (int i = 0; i < iv.polyMesh->nverts; ++i)
- {
- unsigned short* v = &iv.polyMesh->verts[i * 3];
- v[0] += (unsigned short)config.borderSize;
- v[2] += (unsigned short)config.borderSize;
- }
+ TC_LOG_ERROR("maps.mmapgen", "{} Failed adding tile to navmesh!", tileString);
+ return;
+ }
- iv.generateObjFile(mapID, tileX, tileY, meshData);
- iv.writeIV(mapID, tileX, tileY);
+ auto navMeshTile = Trinity::make_unique_ptr_with_deleter(&tileRef, [navMesh](dtTileRef const* ref)
+ {
+ navMesh->removeTile(*ref, nullptr, nullptr);
+ });
+
+ // file output
+ std::string fileName = Trinity::StringFormat("mmaps/{:04}{:02}{:02}.mmtile", mapID, tileY, tileX);
+ auto file = Trinity::make_unique_ptr_with_deleter<&::fclose>(fopen(fileName.c_str(), "wb"));
+ if (!file)
+ {
+ TC_LOG_ERROR("maps.mmapgen", "{}: [Map {:04}] Failed to open {} for writing!", strerror(errno), mapID, fileName);
+ return;
}
+
+ TC_LOG_DEBUG("maps.mmapgen", "{} Writing to file...", tileString);
+
+ // write header
+ MmapTileHeader header;
+ header.usesLiquids = m_terrainBuilder.usesLiquids();
+ header.size = uint32(navDataSize);
+ fwrite(&header, sizeof(MmapTileHeader), 1, file.get());
+
+ // write data
+ fwrite(navData, sizeof(unsigned char), navDataSize, file.get());
}
/**************************************************************************/