diff options
Diffstat (limited to 'src/common/Collision/Maps/TileAssembler.cpp')
-rw-r--r-- | src/common/Collision/Maps/TileAssembler.cpp | 152 |
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; |