diff options
Diffstat (limited to 'src/server/collision/Maps/TileAssembler.cpp')
| -rw-r--r-- | src/server/collision/Maps/TileAssembler.cpp | 550 |
1 files changed, 0 insertions, 550 deletions
diff --git a/src/server/collision/Maps/TileAssembler.cpp b/src/server/collision/Maps/TileAssembler.cpp deleted file mode 100644 index ec7b759f975..00000000000 --- a/src/server/collision/Maps/TileAssembler.cpp +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "TileAssembler.h" -#include "MapTree.h" -#include "BoundingIntervalHierarchy.h" -#include "VMapDefinitions.h" - -#include <set> -#include <iomanip> -#include <sstream> - -using G3D::Vector3; -using G3D::AABox; -using G3D::inf; -using std::pair; - -template<> struct BoundsTrait<VMAP::ModelSpawn*> -{ - static void getBounds(const VMAP::ModelSpawn* const &obj, G3D::AABox& out) { out = obj->getBounds(); } -}; - -namespace VMAP -{ - bool readChunk(FILE* rf, char *dest, const char *compare, uint32 len) - { - if (fread(dest, sizeof(char), len, rf) != len) return false; - return memcmp(dest, compare, len) == 0; - } - - Vector3 ModelPosition::transform(const Vector3& pIn) const - { - Vector3 out = pIn * iScale; - out = iRotation * out; - return(out); - } - - //================================================================= - - TileAssembler::TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName) - : iDestDir(pDestDirName), iSrcDir(pSrcDirName), iFilterMethod(NULL), iCurrentUniqueNameId(0) - { - //mkdir(iDestDir); - //init(); - } - - TileAssembler::~TileAssembler() - { - //delete iCoordModelMapping; - } - - bool TileAssembler::convertWorld2() - { - bool success = readMapSpawns(); - if (!success) - return false; - - // export Map data - for (MapData::iterator map_iter = mapData.begin(); map_iter != mapData.end() && success; ++map_iter) - { - // 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) - { - // 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)) - break; - } - 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); - } - - printf("Creating map tree for map %u...\n", map_iter->first); - BIH pTree; - - try - { - pTree.build(mapSpawns, BoundsTrait<ModelSpawn*>::getBounds); - } - catch (std::exception& e) - { - printf("Exception ""%s"" when calling pTree.build", e.what()); - return false; - } - - // ===> possibly move this code to StaticMapTree class - std::map<uint32, uint32> modelNodeIdx; - for (uint32 i=0; i<mapSpawns.size(); ++i) - modelNodeIdx.insert(pair<uint32, uint32>(mapSpawns[i]->ID, i)); - - // write map tree file - std::stringstream mapfilename; - mapfilename << iDestDir << '/' << std::setfill('0') << std::setw(3) << map_iter->first << ".vmtree"; - FILE* mapfile = fopen(mapfilename.str().c_str(), "wb"); - if (!mapfile) - { - success = false; - printf("Cannot open %s\n", mapfilename.str().c_str()); - break; - } - - //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]); - } - - fclose(mapfile); - - // <==== - - // 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) - { - const ModelSpawn &spawn = map_iter->second->UniqueEntries[tile->second]; - if (spawn.flags & MOD_WORLDSPAWN) // WDT spawn, saved as tile 65/65 currently... - continue; - uint32 nSpawns = tileEntries.count(tile->first); - std::stringstream tilefilename; - tilefilename.fill('0'); - tilefilename << iDestDir << '/' << std::setw(3) << 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")) - { - // file header - 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; - // write tile spawns - for (uint32 s=0; s<nSpawns; ++s) - { - if (s) - ++tile; - const ModelSpawn &spawn2 = map_iter->second->UniqueEntries[tile->second]; - success = success && ModelSpawn::writeToFile(tilefile, spawn2); - // MapTree nodes to update when loading tile: - std::map<uint32, uint32>::iterator nIdx = modelNodeIdx.find(spawn2.ID); - if (success && fwrite(&nIdx->second, sizeof(uint32), 1, tilefile) != 1) success = false; - } - fclose(tilefile); - } - } - // break; //test, extract only first map; TODO: remvoe this line - } - - // add an object models, listed in temp_gameobject_models file - exportGameobjectModels(); - // export objects - std::cout << "\nConverting Model Files" << std::endl; - for (std::set<std::string>::iterator mfile = spawnedModelFiles.begin(); mfile != spawnedModelFiles.end(); ++mfile) - { - std::cout << "Converting " << *mfile << std::endl; - if (!convertRawFile(*mfile)) - { - std::cout << "error converting " << *mfile << std::endl; - success = false; - break; - } - } - - //cleanup: - for (MapData::iterator map_iter = mapData.begin(); map_iter != mapData.end(); ++map_iter) - { - delete map_iter->second; - } - return success; - } - - bool TileAssembler::readMapSpawns() - { - std::string fname = iSrcDir + "/dir_bin"; - FILE* dirf = fopen(fname.c_str(), "rb"); - if (!dirf) - { - printf("Could not read dir_bin file!\n"); - return false; - } - printf("Read coordinate mapping...\n"); - uint32 mapID, tileX, tileY, check=0; - G3D::Vector3 v1, v2; - ModelSpawn spawn; - while (!feof(dirf)) - { - check = 0; - // read mapID, tileX, tileY, Flags, adtID, ID, 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); - if (!ModelSpawn::readFromFile(dirf, spawn)) - break; - - MapSpawns *current; - MapData::iterator map_iter = mapData.find(mapID); - if (map_iter == mapData.end()) - { - printf("spawning Map %u\n", mapID); - mapData[mapID] = current = new MapSpawns(); - } - else current = (*map_iter).second; - current->UniqueEntries.insert(pair<uint32, ModelSpawn>(spawn.ID, spawn)); - current->TileEntries.insert(pair<uint32, uint32>(StaticMapTree::packTileID(tileX, tileY), spawn.ID)); - } - bool success = (ferror(dirf) == 0); - fclose(dirf); - return success; - } - - bool TileAssembler::calculateTransformedBound(ModelSpawn &spawn) - { - std::string modelFilename(iSrcDir); - modelFilename.push_back('/'); - modelFilename.append(spawn.name); - - ModelPosition modelPosition; - modelPosition.iDir = spawn.iRot; - modelPosition.iScale = spawn.iScale; - modelPosition.init(); - - WorldModel_Raw raw_model; - if (!raw_model.Read(modelFilename.c_str())) - return false; - - uint32 groups = raw_model.groupsArray.size(); - if (groups != 1) - 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]); - - if (boundEmpty) - modelBound = AABox(v, v), boundEmpty=false; - else - modelBound.merge(v); - } - } - spawn.iBound = modelBound + spawn.iPos; - spawn.flags |= MOD_HAS_BOUND; - return true; - } - - struct WMOLiquidHeader - { - int xverts, yverts, xtiles, ytiles; - float pos_x; - float pos_y; - float pos_z; - short type; - }; - //================================================================= - bool TileAssembler::convertRawFile(const std::string& pModelFilename) - { - bool success = true; - std::string filename = iSrcDir; - if (filename.length() >0) - filename.push_back('/'); - filename.append(pModelFilename); - - WorldModel_Raw raw_model; - if (!raw_model.Read(filename.c_str())) - return false; - - // write WorldModel - WorldModel model; - model.setRootWmoID(raw_model.RootWMOID); - if (!raw_model.groupsArray.empty()) - { - std::vector<GroupModel> groupsArray; - - uint32 groups = raw_model.groupsArray.size(); - for (uint32 g = 0; g < groups; ++g) - { - GroupModel_Raw& raw_group = raw_model.groupsArray[g]; - groupsArray.push_back(GroupModel(raw_group.mogpflags, raw_group.GroupWMOID, raw_group.bounds )); - groupsArray.back().setMeshData(raw_group.vertexArray, raw_group.triangles); - groupsArray.back().setLiquidData(raw_group.liquid); - } - - model.setGroupModels(groupsArray); - } - - success = model.writeFile(iDestDir + "/" + pModelFilename + ".vmo"); - //std::cout << "readRawFile2: '" << pModelFilename << "' tris: " << nElements << " nodes: " << nNodes << std::endl; - return success; - } - - void TileAssembler::exportGameobjectModels() - { - FILE* model_list = fopen((iSrcDir + "/" + "temp_gameobject_models").c_str(), "rb"); - if (!model_list) - return; - - FILE* model_list_copy = fopen((iDestDir + "/" + GAMEOBJECT_MODELS).c_str(), "wb"); - if (!model_list_copy) - { - fclose(model_list); - return; - } - - uint32 name_length, displayId; - char buff[500]; - while (!feof(model_list)) - { - if (fread(&displayId, sizeof(uint32), 1, model_list) != 1 - || fread(&name_length, sizeof(uint32), 1, model_list) != 1 - || name_length >= sizeof(buff) - || fread(&buff, sizeof(char), name_length, model_list) != name_length) - { - std::cout << "\nFile 'temp_gameobject_models' seems to be corrupted" << std::endl; - break; - } - - std::string model_name(buff, name_length); - - WorldModel_Raw raw_model; - if ( !raw_model.Read((iSrcDir + "/" + model_name).c_str()) ) - continue; - - spawnedModelFiles.insert(model_name); - AABox bounds; - bool boundEmpty = true; - for (uint32 g = 0; g < raw_model.groupsArray.size(); ++g) - { - std::vector<Vector3>& vertices = raw_model.groupsArray[g].vertexArray; - - uint32 nvectors = vertices.size(); - for (uint32 i = 0; i < nvectors; ++i) - { - Vector3& v = vertices[i]; - if (boundEmpty) - bounds = AABox(v, v), boundEmpty = false; - else - bounds.merge(v); - } - } - - if (bounds.isEmpty()) - { - std::cout << "\nModel " << std::string(buff, name_length) << " has empty bounding box" << std::endl; - continue; - } - - if (!bounds.isFinite()) - { - std::cout << "\nModel " << std::string(buff, name_length) << " has invalid bounding box" << std::endl; - continue; - } - - fwrite(&displayId, sizeof(uint32), 1, model_list_copy); - fwrite(&name_length, sizeof(uint32), 1, model_list_copy); - fwrite(&buff, sizeof(char), name_length, model_list_copy); - fwrite(&bounds.low(), sizeof(Vector3), 1, model_list_copy); - fwrite(&bounds.high(), sizeof(Vector3), 1, model_list_copy); - } - - fclose(model_list); - fclose(model_list_copy); - } - // temporary use defines to simplify read/check code (close file and return at fail) - #define READ_OR_RETURN(V, S) if (fread((V), (S), 1, rf) != 1) { \ - fclose(rf); printf("readfail, op = %i\n", readOperation); return(false); } - #define READ_OR_RETURN_WITH_DELETE(V, S) if (fread((V), (S), 1, rf) != 1) { \ - fclose(rf); printf("readfail, op = %i\n", readOperation); delete[] V; return(false); }; - #define CMP_OR_RETURN(V, S) if (strcmp((V), (S)) != 0) { \ - fclose(rf); printf("cmpfail, %s!=%s\n", V, S);return(false); } - - bool GroupModel_Raw::Read(FILE* rf) - { - char blockId[5]; - blockId[4] = 0; - int blocksize; - int readOperation = 0; - - READ_OR_RETURN(&mogpflags, sizeof(uint32)); - READ_OR_RETURN(&GroupWMOID, sizeof(uint32)); - - - Vector3 vec1, vec2; - READ_OR_RETURN(&vec1, sizeof(Vector3)); - - READ_OR_RETURN(&vec2, sizeof(Vector3)); - bounds.set(vec1, vec2); - - READ_OR_RETURN(&liquidflags, sizeof(uint32)); - - // will this ever be used? what is it good for anyway?? - uint32 branches; - READ_OR_RETURN(&blockId, 4); - CMP_OR_RETURN(blockId, "GRP "); - READ_OR_RETURN(&blocksize, sizeof(int)); - READ_OR_RETURN(&branches, sizeof(uint32)); - for (uint32 b=0; b<branches; ++b) - { - uint32 indexes; - // indexes for each branch (not used jet) - READ_OR_RETURN(&indexes, sizeof(uint32)); - } - - // ---- indexes - READ_OR_RETURN(&blockId, 4); - CMP_OR_RETURN(blockId, "INDX"); - READ_OR_RETURN(&blocksize, sizeof(int)); - uint32 nindexes; - READ_OR_RETURN(&nindexes, sizeof(uint32)); - if (nindexes >0) - { - uint16 *indexarray = new uint16[nindexes]; - READ_OR_RETURN_WITH_DELETE(indexarray, nindexes*sizeof(uint16)); - triangles.reserve(nindexes / 3); - for (uint32 i=0; i<nindexes; i+=3) - triangles.push_back(MeshTriangle(indexarray[i], indexarray[i+1], indexarray[i+2])); - - delete[] indexarray; - } - - // ---- vectors - READ_OR_RETURN(&blockId, 4); - CMP_OR_RETURN(blockId, "VERT"); - READ_OR_RETURN(&blocksize, sizeof(int)); - uint32 nvectors; - READ_OR_RETURN(&nvectors, sizeof(uint32)); - - if (nvectors >0) - { - float *vectorarray = new float[nvectors*3]; - READ_OR_RETURN_WITH_DELETE(vectorarray, nvectors*sizeof(float)*3); - for (uint32 i=0; i<nvectors; ++i) - vertexArray.push_back( Vector3(vectorarray + 3*i) ); - - delete[] vectorarray; - } - // ----- liquid - liquid = 0; - if (liquidflags& 1) - { - WMOLiquidHeader hlq; - READ_OR_RETURN(&blockId, 4); - CMP_OR_RETURN(blockId, "LIQU"); - READ_OR_RETURN(&blocksize, sizeof(int)); - READ_OR_RETURN(&hlq, sizeof(WMOLiquidHeader)); - liquid = new WmoLiquid(hlq.xtiles, hlq.ytiles, Vector3(hlq.pos_x, hlq.pos_y, hlq.pos_z), hlq.type); - uint32 size = hlq.xverts*hlq.yverts; - READ_OR_RETURN(liquid->GetHeightStorage(), size*sizeof(float)); - size = hlq.xtiles*hlq.ytiles; - READ_OR_RETURN(liquid->GetFlagsStorage(), size); - } - - return true; - } - - - GroupModel_Raw::~GroupModel_Raw() - { - delete liquid; - } - - bool WorldModel_Raw::Read(const char * path) - { - FILE* rf = fopen(path, "rb"); - if (!rf) - { - printf("ERROR: Can't open raw model file: %s\n", path); - return false; - } - - char ident[9]; - ident[8] = '\0'; - int readOperation = 0; - - READ_OR_RETURN(&ident, 8); - CMP_OR_RETURN(ident, RAW_VMAP_MAGIC); - - // we have to read one int. This is needed during the export and we have to skip it here - uint32 tempNVectors; - READ_OR_RETURN(&tempNVectors, sizeof(tempNVectors)); - - uint32 groups; - READ_OR_RETURN(&groups, sizeof(uint32)); - READ_OR_RETURN(&RootWMOID, sizeof(uint32)); - - groupsArray.resize(groups); - bool succeed = true; - for (uint32 g = 0; g < groups && succeed; ++g) - succeed = groupsArray[g].Read(rf); - - if (succeed) /// rf will be freed inside Read if the function had any errors. - fclose(rf); - return succeed; - } - - // drop of temporary use defines - #undef READ_OR_RETURN - #undef CMP_OR_RETURN -} |
