aboutsummaryrefslogtreecommitdiff
path: root/src/common/Collision/Maps/TileAssembler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/Collision/Maps/TileAssembler.cpp')
-rw-r--r--src/common/Collision/Maps/TileAssembler.cpp152
1 files changed, 58 insertions, 94 deletions
diff --git a/src/common/Collision/Maps/TileAssembler.cpp b/src/common/Collision/Maps/TileAssembler.cpp
index b0bee33b4b2..47dfadd0947 100644
--- a/src/common/Collision/Maps/TileAssembler.cpp
+++ b/src/common/Collision/Maps/TileAssembler.cpp
@@ -48,7 +48,7 @@ namespace VMAP
{
Vector3 out = pIn * iScale;
out = iRotation * out;
- return(out);
+ return out;
}
//=================================================================
@@ -57,12 +57,10 @@ namespace VMAP
: iDestDir(pDestDirName), iSrcDir(pSrcDirName)
{
boost::filesystem::create_directory(iDestDir);
- //init();
}
TileAssembler::~TileAssembler()
{
- //delete iCoordModelMapping;
}
bool TileAssembler::convertWorld2()
@@ -71,32 +69,39 @@ namespace VMAP
if (!success)
return false;
+ float constexpr invTileSize = 1.0f / 533.33333f;
+
// export Map data
- for (MapData::iterator map_iter = mapData.begin(); map_iter != mapData.end() && success; ++map_iter)
+ while (!mapData.empty())
{
+ MapSpawns data = std::move(mapData.front());
+ mapData.pop_front();
+
// build global map tree
std::vector<ModelSpawn*> mapSpawns;
- UniqueEntryMap::iterator entry;
- printf("Calculating model bounds for map %u...\n", map_iter->first);
- for (entry = map_iter->second->UniqueEntries.begin(); entry != map_iter->second->UniqueEntries.end(); ++entry)
+ mapSpawns.reserve(data.UniqueEntries.size());
+ printf("Calculating model bounds for map %u...\n", data.MapId);
+ for (auto entry = data.UniqueEntries.begin(); entry != data.UniqueEntries.end(); ++entry)
{
// M2 models don't have a bound set in WDT/ADT placement data, i still think they're not used for LoS at all on retail
if (entry->second.flags & MOD_M2)
- {
if (!calculateTransformedBound(entry->second))
continue;
- }
- else if (entry->second.flags & MOD_WORLDSPAWN) // WMO maps and terrain maps use different origin, so we need to adapt :/
- {
- /// @todo remove extractor hack and uncomment below line:
- //entry->second.iPos += Vector3(533.33333f*32, 533.33333f*32, 0.f);
- entry->second.iBound = entry->second.iBound + Vector3(533.33333f*32, 533.33333f*32, 0.f);
- }
+
mapSpawns.push_back(&entry->second);
spawnedModelFiles.insert(entry->second.name);
+
+ std::map<uint32, std::set<TileSpawn>>& tileEntries = (entry->second.flags & MOD_PARENT_SPAWN) ? data.ParentTileEntries : data.TileEntries;
+
+ G3D::AABox const& bounds = entry->second.iBound;
+ G3D::Vector2int16 low(int16(bounds.low().x * invTileSize), int16(bounds.low().y * invTileSize));
+ G3D::Vector2int16 high(int16(bounds.high().x * invTileSize), int16(bounds.high().y * invTileSize));
+ for (int x = low.x; x <= high.x; ++x)
+ for (int y = low.y; y <= high.y; ++y)
+ tileEntries[StaticMapTree::packTileID(x, y)].emplace(entry->second.ID, entry->second.flags);
}
- printf("Creating map tree for map %u...\n", map_iter->first);
+ printf("Creating map tree for map %u...\n", data.MapId);
BIH pTree;
try
@@ -113,7 +118,7 @@ namespace VMAP
// write map tree file
std::stringstream mapfilename;
- mapfilename << iDestDir << '/' << std::setfill('0') << std::setw(4) << map_iter->first << ".vmtree";
+ mapfilename << iDestDir << '/' << std::setfill('0') << std::setw(4) << data.MapId << ".vmtree";
FILE* mapfile = fopen(mapfilename.str().c_str(), "wb");
if (!mapfile)
{
@@ -124,24 +129,13 @@ namespace VMAP
//general info
if (success && fwrite(VMAP_MAGIC, 1, 8, mapfile) != 8) success = false;
- uint32 globalTileID = StaticMapTree::packTileID(65, 65);
- pair<TileMap::iterator, TileMap::iterator> globalRange = map_iter->second->TileEntries.equal_range(globalTileID);
- char isTiled = globalRange.first == globalRange.second; // only maps without terrain (tiles) have global WMO
- if (success && fwrite(&isTiled, sizeof(char), 1, mapfile) != 1) success = false;
// Nodes
if (success && fwrite("NODE", 4, 1, mapfile) != 1) success = false;
if (success) success = pTree.writeToFile(mapfile);
- // global map spawns (WDT), if any (most instances)
- if (success && fwrite("GOBJ", 4, 1, mapfile) != 1) success = false;
-
- for (TileMap::iterator glob=globalRange.first; glob != globalRange.second && success; ++glob)
- {
- success = ModelSpawn::writeToFile(mapfile, map_iter->second->UniqueEntries[glob->second.Id]);
- }
// spawn id to index map
- if (success && fwrite("SIDX", 4, 1, mapfile) != 1) success = false;
uint32 mapSpawnsSize = mapSpawns.size();
+ if (success && fwrite("SIDX", 4, 1, mapfile) != 1) success = false;
if (success && fwrite(&mapSpawnsSize, sizeof(uint32), 1, mapfile) != 1) success = false;
for (uint32 i = 0; i < mapSpawnsSize; ++i)
{
@@ -153,37 +147,30 @@ namespace VMAP
// <====
- // write map tile files, similar to ADT files, only with extra BSP tree node info
- TileMap &tileEntries = map_iter->second->TileEntries;
- TileMap::iterator tile;
- for (tile = tileEntries.begin(); tile != tileEntries.end(); ++tile)
+ // write map tile files, similar to ADT files, only with extra BIH tree node info
+ for (auto tileItr = data.TileEntries.begin(); tileItr != data.TileEntries.end(); ++tileItr)
{
- if (tile->second.Flags & MOD_WORLDSPAWN) // WDT spawn, saved as tile 65/65 currently...
- continue;
- if (tile->second.Flags & MOD_PARENT_SPAWN) // tile belongs to parent map
- continue;
- uint32 nSpawns = tileEntries.count(tile->first);
- std::stringstream tilefilename;
- tilefilename.fill('0');
- tilefilename << iDestDir << '/' << std::setw(4) << map_iter->first << '_';
uint32 x, y;
- StaticMapTree::unpackTileID(tile->first, x, y);
- tilefilename << std::setw(2) << x << '_' << std::setw(2) << y << ".vmtile";
- if (FILE* tilefile = fopen(tilefilename.str().c_str(), "wb"))
+ StaticMapTree::unpackTileID(tileItr->first, x, y);
+ std::string tileFileName = Trinity::StringFormat("%s/%04u_%02u_%02u.vmtile", iDestDir.c_str(), data.MapId, y, x);
+ if (FILE* tileFile = fopen(tileFileName.c_str(), "wb"))
{
+ std::set<TileSpawn> const& parentTileEntries = data.ParentTileEntries[tileItr->first];
+
+ uint32 nSpawns = tileItr->second.size() + parentTileEntries.size();
+
// file header
- if (success && fwrite(VMAP_MAGIC, 1, 8, tilefile) != 8) success = false;
+ if (success && fwrite(VMAP_MAGIC, 1, 8, tileFile) != 8) success = false;
// write number of tile spawns
- if (success && fwrite(&nSpawns, sizeof(uint32), 1, tilefile) != 1) success = false;
+ if (success && fwrite(&nSpawns, sizeof(uint32), 1, tileFile) != 1) success = false;
// write tile spawns
- for (uint32 s=0; s<nSpawns; ++s)
- {
- if (s)
- ++tile;
- const ModelSpawn &spawn2 = map_iter->second->UniqueEntries[tile->second.Id];
- success = success && ModelSpawn::writeToFile(tilefile, spawn2);
- }
- fclose(tilefile);
+ for (auto spawnItr = tileItr->second.begin(); spawnItr != tileItr->second.end() && success; ++spawnItr)
+ success = ModelSpawn::writeToFile(tileFile, data.UniqueEntries[spawnItr->Id]);
+
+ for (auto spawnItr = parentTileEntries.begin(); spawnItr != parentTileEntries.end() && success; ++spawnItr)
+ success = ModelSpawn::writeToFile(tileFile, data.UniqueEntries[spawnItr->Id]);
+
+ fclose(tileFile);
}
}
}
@@ -203,11 +190,6 @@ namespace VMAP
}
}
- //cleanup:
- for (MapData::iterator map_iter = mapData.begin(); map_iter != mapData.end(); ++map_iter)
- {
- delete map_iter->second;
- }
return success;
}
@@ -221,34 +203,35 @@ namespace VMAP
return false;
}
printf("Read coordinate mapping...\n");
- uint32 mapID, tileX, tileY, check=0;
- G3D::Vector3 v1, v2;
- ModelSpawn spawn;
+ uint32 mapID, check=0;
+ std::map<uint32, MapSpawns> data;
while (!feof(dirf))
{
check = 0;
- // read mapID, tileX, tileY, Flags, NameSet, UniqueId, Pos, Rot, Scale, Bound_lo, Bound_hi, name
+ // read mapID, Flags, NameSet, UniqueId, Pos, Rot, Scale, Bound_lo, Bound_hi, name
check += fread(&mapID, sizeof(uint32), 1, dirf);
if (check == 0) // EoF...
break;
- check += fread(&tileX, sizeof(uint32), 1, dirf);
- check += fread(&tileY, sizeof(uint32), 1, dirf);
+
+ ModelSpawn spawn;
if (!ModelSpawn::readFromFile(dirf, spawn))
break;
- MapSpawns *current;
- MapData::iterator map_iter = mapData.find(mapID);
- if (map_iter == mapData.end())
+ auto map_iter = data.emplace(std::piecewise_construct, std::forward_as_tuple(mapID), std::forward_as_tuple());
+ if (map_iter.second)
{
+ map_iter.first->second.MapId = mapID;
printf("spawning Map %u\n", mapID);
- mapData[mapID] = current = new MapSpawns();
}
- else
- current = map_iter->second;
- current->UniqueEntries.emplace(spawn.ID, spawn);
- current->TileEntries.insert(pair<uint32, TileSpawn>(StaticMapTree::packTileID(tileX, tileY), TileSpawn{ spawn.ID, spawn.flags }));
+ map_iter.first->second.UniqueEntries.emplace(spawn.ID, spawn);
}
+
+ mapData.resize(data.size());
+ auto dst = mapData.begin();
+ for (auto src = data.begin(); src != data.end(); ++src, ++dst)
+ *dst = std::move(src->second);
+
bool success = (ferror(dirf) == 0);
fclose(dirf);
return success;
@@ -274,29 +257,10 @@ namespace VMAP
printf("Warning: '%s' does not seem to be a M2 model!\n", modelFilename.c_str());
AABox modelBound;
- bool boundEmpty=true;
-
- for (uint32 g=0; g<groups; ++g) // should be only one for M2 files...
- {
- std::vector<Vector3>& vertices = raw_model.groupsArray[g].vertexArray;
-
- if (vertices.empty())
- {
- std::cout << "error: model '" << spawn.name << "' has no geometry!" << std::endl;
- continue;
- }
- uint32 nvectors = vertices.size();
- for (uint32 i = 0; i < nvectors; ++i)
- {
- Vector3 v = modelPosition.transform(vertices[i]);
+ modelBound.merge(modelPosition.transform(raw_model.groupsArray[0].bounds.low()));
+ modelBound.merge(modelPosition.transform(raw_model.groupsArray[0].bounds.high()));
- if (boundEmpty)
- modelBound = AABox(v, v), boundEmpty=false;
- else
- modelBound.merge(v);
- }
- }
spawn.iBound = modelBound + spawn.iPos;
spawn.flags |= MOD_HAS_BOUND;
return true;