From 204b846fe695768ad56f8f8c832d6deaa6dc2e1c Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 14:45:05 +0200 Subject: Core/Tools: Implemented mmaps_generator. --- src/tools/CMakeLists.txt | 1 + src/tools/mmap_extractor/CMakeLists.txt | 68 ++ src/tools/mmap_extractor/Info/readme.txt | 66 ++ src/tools/mmap_extractor/IntermediateValues.cpp | 277 ++++++++ src/tools/mmap_extractor/IntermediateValues.h | 53 ++ src/tools/mmap_extractor/MapBuilder.cpp | 894 ++++++++++++++++++++++++ src/tools/mmap_extractor/MapBuilder.h | 129 ++++ src/tools/mmap_extractor/PathCommon.h | 128 ++++ src/tools/mmap_extractor/PathGenerator.cpp | 273 ++++++++ src/tools/mmap_extractor/TerrainBuilder.cpp | 854 ++++++++++++++++++++++ src/tools/mmap_extractor/TerrainBuilder.h | 138 ++++ src/tools/mmap_extractor/VMapExtensions.cpp | 72 ++ 12 files changed, 2953 insertions(+) create mode 100644 src/tools/mmap_extractor/CMakeLists.txt create mode 100644 src/tools/mmap_extractor/Info/readme.txt create mode 100644 src/tools/mmap_extractor/IntermediateValues.cpp create mode 100644 src/tools/mmap_extractor/IntermediateValues.h create mode 100644 src/tools/mmap_extractor/MapBuilder.cpp create mode 100644 src/tools/mmap_extractor/MapBuilder.h create mode 100644 src/tools/mmap_extractor/PathCommon.h create mode 100644 src/tools/mmap_extractor/PathGenerator.cpp create mode 100644 src/tools/mmap_extractor/TerrainBuilder.cpp create mode 100644 src/tools/mmap_extractor/TerrainBuilder.h create mode 100644 src/tools/mmap_extractor/VMapExtensions.cpp (limited to 'src/tools') diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index a956655ffaa..f4c5f695b26 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -11,3 +11,4 @@ add_subdirectory(map_extractor) add_subdirectory(vmap4_assembler) add_subdirectory(vmap4_extractor) +add_subdirectory(mmaps_extractor) diff --git a/src/tools/mmap_extractor/CMakeLists.txt b/src/tools/mmap_extractor/CMakeLists.txt new file mode 100644 index 00000000000..c7c1a954371 --- /dev/null +++ b/src/tools/mmap_extractor/CMakeLists.txt @@ -0,0 +1,68 @@ +# Copyright (C) 2008-2011 Trinity +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +file(GLOB_RECURSE sources *.cpp *.h) + +# definitions +add_definitions(-DNO_CORE_FUNCS) +add_definitions(-DDEBUG) +add_definitions(-DNO_vsnprintf) + +include_directories( + ${CMAKE_BINARY_DIR} + ${ACE_INCLUDE_DIR} + ${MYSQL_INCLUDE_DIR} + ${CMAKE_SOURCE_DIR}/dep/libmpq + ${CMAKE_SOURCE_DIR}/dep/zlib + ${CMAKE_SOURCE_DIR}/dep/bzip2 + ${CMAKE_SOURCE_DIR}/dep/acelite + ${CMAKE_SOURCE_DIR}/dep/g3dlite/include + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/src/server/shared/Database + ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation + ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Logging + ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference + ${CMAKE_SOURCE_DIR}/src/server/game/Maps + ${CMAKE_SOURCE_DIR}/src/server/game/DataStores + ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints + ${CMAKE_SOURCE_DIR}/src/server/game/Grids + ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Cells + ${CMAKE_SOURCE_DIR}/src/server/game/Miscellaneous + ${CMAKE_SOURCE_DIR}/src/server/game/Conditions + ${CMAKE_SOURCE_DIR}/src/server/collision + ${CMAKE_SOURCE_DIR}/src/server/collision/Management + ${CMAKE_SOURCE_DIR}/src/server/collision/Maps + ${CMAKE_SOURCE_DIR}/src/server/collision/Models +) + +add_executable(movements_extractor ${sources}) + +target_link_libraries(movements_extractor + ${MYSQL_LIBRARY} + ${ACE_LIBRARY} + ${BZIP2_LIBRARIES} + ${ZLIB_LIBRARIES} + Recast + Detour + collision + g3dlib + shared +) + +if( UNIX ) + install(TARGETS movements_extractor DESTINATION bin) +elseif( WIN32 ) + install(TARGETS movements_extractor DESTINATION "${CMAKE_INSTALL_PREFIX}") +endif() diff --git a/src/tools/mmap_extractor/Info/readme.txt b/src/tools/mmap_extractor/Info/readme.txt new file mode 100644 index 00000000000..8d7c4f9d2e0 --- /dev/null +++ b/src/tools/mmap_extractor/Info/readme.txt @@ -0,0 +1,66 @@ +Generator command line args + +--offMeshInput [file.*] Path to file containing off mesh connections data. + Format must be: (see offmesh_example.txt) + "map_id tile_x,tile_y (start_x start_y start_z) (end_x end_y end_z) size //optional comments" + Single mesh connection per line. + +--silent Make us script friendly. Do not wait for user input + on error or completion. + +--bigBaseUnit [true|false] Generate tile/map using bigger basic unit. + Use this option only if you have unexpected gaps. + + false: use normal metrics (default) + +--maxAngle [#] Max walkable inclination angle + + float between 45 and 90 degrees (default 60) + +--skipLiquid liquid data for maps + + false: include liquid data (default) + +--skipContinents [true|false] continents are maps 0 (Eastern Kingdoms), + 1 (Kalimdor), 530 (Outlands), 571 (Northrend) + + false: build continents (default) + +--skipJunkMaps [true|false] junk maps include some unused + maps, transport maps, and some other + + true: skip junk maps (default) + +--skipBattlegrounds [true|false] does not include PVP arenas + + false: skip battlegrounds (default) + +--debugOutput [true|false] create debugging files for use with RecastDemo + if you are only creating mmaps for use with MaNGOS, + you don't want debugging files + + false: don't create debugging files (default) + +--tile [#,#] Build the specified tile + seperate number with a comma ',' + must specify a map number (see below) + if this option is not used, all tiles are built + + [#] Build only the map specified by # + this command will build the map regardless of --skip* option settings + if you do not specify a map number, builds all maps that pass the filters specified by --skip* options + + +examples: + +movement_extractor +builds maps using the default settings (see above for defaults) + +movement_extractor --skipContinents true +builds the default maps, except continents + +movement_extractor 0 +builds all tiles of map 0 + +movement_extractor 0 --tile 34,46 +builds only tile 34,46 of map 0 (this is the southern face of blackrock mountain) \ No newline at end of file diff --git a/src/tools/mmap_extractor/IntermediateValues.cpp b/src/tools/mmap_extractor/IntermediateValues.cpp new file mode 100644 index 00000000000..9eefb1e65f0 --- /dev/null +++ b/src/tools/mmap_extractor/IntermediateValues.cpp @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 MaNGOS + * + * 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 . + */ + +#include "IntermediateValues.h" + +namespace MMAP +{ + IntermediateValues::~IntermediateValues() + { + rcFreeCompactHeightfield(compactHeightfield); + rcFreeHeightField(heightfield); + rcFreeContourSet(contours); + rcFreePolyMesh(polyMesh); + rcFreePolyMeshDetail(polyMeshDetail); + } + + void IntermediateValues::writeIV(uint32 mapID, uint32 tileX, uint32 tileY) + { + char fileName[255]; + char tileString[25]; + sprintf(tileString, "[%02u,%02u]: ", tileX, tileY); + + printf("%sWriting debug output... \r", tileString); + + string name("meshes/%03u%02i%02i."); + +#define DEBUG_WRITE(fileExtension,data) \ + do { \ + sprintf(fileName, (name + fileExtension).c_str(), mapID, tileY, tileX); \ + FILE* file = fopen(fileName, "wb"); \ + if (!file) \ + { \ + char message[1024]; \ + sprintf(message, "%sFailed to open %s for writing!\n", tileString, fileName); \ + perror(message); \ + } \ + else \ + debugWrite(file, data); \ + if (file) fclose(file); \ + printf("%sWriting debug output... \r", tileString); \ + } while (false) + + if (heightfield) + DEBUG_WRITE("hf", heightfield); + if (compactHeightfield) + DEBUG_WRITE("chf", compactHeightfield); + if (contours) + DEBUG_WRITE("cs", contours); + if (polyMesh) + DEBUG_WRITE("pmesh", polyMesh); + if (polyMeshDetail) + DEBUG_WRITE("dmesh", polyMeshDetail); + +#undef DEBUG_WRITE + } + + void IntermediateValues::debugWrite(FILE* file, const rcHeightfield* mesh) + { + if (!file || !mesh) + return; + + fwrite(&(mesh->cs), sizeof(float), 1, file); + fwrite(&(mesh->ch), sizeof(float), 1, file); + fwrite(&(mesh->width), sizeof(int), 1, file); + fwrite(&(mesh->height), sizeof(int), 1, file); + fwrite(mesh->bmin, sizeof(float), 3, file); + fwrite(mesh->bmax, sizeof(float), 3, file); + + for (int y = 0; y < mesh->height; ++y) + for (int x = 0; x < mesh->width; ++x) + { + rcSpan* span = mesh->spans[x+y*mesh->width]; + + // first, count the number of spans + int spanCount = 0; + while (span) + { + spanCount++; + span = span->next; + } + + // write the span count + fwrite(&spanCount, sizeof(int), 1, file); + + // write the spans + span = mesh->spans[x+y*mesh->width]; + while (span) + { + fwrite(span, sizeof(rcSpan), 1, file); + span = span->next; + } + } + } + + void IntermediateValues::debugWrite(FILE* file, const rcCompactHeightfield* chf) + { + if (!file | !chf) + return; + + fwrite(&(chf->width), sizeof(chf->width), 1, file); + fwrite(&(chf->height), sizeof(chf->height), 1, file); + fwrite(&(chf->spanCount), sizeof(chf->spanCount), 1, file); + + fwrite(&(chf->walkableHeight), sizeof(chf->walkableHeight), 1, file); + fwrite(&(chf->walkableClimb), sizeof(chf->walkableClimb), 1, file); + + fwrite(&(chf->maxDistance), sizeof(chf->maxDistance), 1, file); + fwrite(&(chf->maxRegions), sizeof(chf->maxRegions), 1, file); + + fwrite(chf->bmin, sizeof(chf->bmin), 1, file); + fwrite(chf->bmax, sizeof(chf->bmax), 1, file); + + fwrite(&(chf->cs), sizeof(chf->cs), 1, file); + fwrite(&(chf->ch), sizeof(chf->ch), 1, file); + + int tmp = 0; + if (chf->cells) tmp |= 1; + if (chf->spans) tmp |= 2; + if (chf->dist) tmp |= 4; + if (chf->areas) tmp |= 8; + + fwrite(&tmp, sizeof(tmp), 1, file); + + if (chf->cells) + fwrite(chf->cells, sizeof(rcCompactCell), chf->width*chf->height, file); + if (chf->spans) + fwrite(chf->spans, sizeof(rcCompactSpan), chf->spanCount, file); + if (chf->dist) + fwrite(chf->dist, sizeof(unsigned short), chf->spanCount, file); + if (chf->areas) + fwrite(chf->areas, sizeof(unsigned char), chf->spanCount, file); + } + + void IntermediateValues::debugWrite(FILE* file, const rcContourSet* cs) + { + if (!file || !cs) + return; + + fwrite(&(cs->cs), sizeof(float), 1, file); + fwrite(&(cs->ch), sizeof(float), 1, file); + fwrite(cs->bmin, sizeof(float), 3, file); + fwrite(cs->bmax, sizeof(float), 3, file); + fwrite(&(cs->nconts), sizeof(int), 1, file); + for (int i = 0; i < cs->nconts; ++i) + { + fwrite(&cs->conts[i].area, sizeof(unsigned char), 1, file); + fwrite(&cs->conts[i].reg, sizeof(unsigned short), 1, file); + fwrite(&cs->conts[i].nverts, sizeof(int), 1, file); + fwrite(cs->conts[i].verts, sizeof(int), cs->conts[i].nverts*4, file); + fwrite(&cs->conts[i].nrverts, sizeof(int), 1, file); + fwrite(cs->conts[i].rverts, sizeof(int), cs->conts[i].nrverts*4, file); + } + } + + void IntermediateValues::debugWrite(FILE* file, const rcPolyMesh* mesh) + { + if (!file || !mesh) + return; + + fwrite(&(mesh->cs), sizeof(float), 1, file); + fwrite(&(mesh->ch), sizeof(float), 1, file); + fwrite(&(mesh->nvp), sizeof(int), 1, file); + fwrite(mesh->bmin, sizeof(float), 3, file); + fwrite(mesh->bmax, sizeof(float), 3, file); + fwrite(&(mesh->nverts), sizeof(int), 1, file); + fwrite(mesh->verts, sizeof(unsigned short), mesh->nverts*3, file); + fwrite(&(mesh->npolys), sizeof(int), 1, file); + fwrite(mesh->polys, sizeof(unsigned short), mesh->npolys*mesh->nvp*2, file); + fwrite(mesh->flags, sizeof(unsigned short), mesh->npolys, file); + fwrite(mesh->areas, sizeof(unsigned char), mesh->npolys, file); + fwrite(mesh->regs, sizeof(unsigned short), mesh->npolys, file); + } + + void IntermediateValues::debugWrite(FILE* file, const rcPolyMeshDetail* mesh) + { + if (!file || !mesh) + return; + + fwrite(&(mesh->nverts), sizeof(int), 1, file); + fwrite(mesh->verts, sizeof(float), mesh->nverts*3, file); + fwrite(&(mesh->ntris), sizeof(int), 1, file); + fwrite(mesh->tris, sizeof(char), mesh->ntris*4, file); + fwrite(&(mesh->nmeshes), sizeof(int), 1, file); + fwrite(mesh->meshes, sizeof(int), mesh->nmeshes*4, file); + } + + void IntermediateValues::generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) + { + char objFileName[255]; + sprintf(objFileName, "meshes/map%03u.obj", mapID); + + FILE* objFile = fopen(objFileName, "wb"); + if (!objFile) + { + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", objFileName); + perror(message); + return; + } + + G3D::Array allVerts; + G3D::Array allTris; + + allTris.append(meshData.liquidTris); + allVerts.append(meshData.liquidVerts); + TerrainBuilder::copyIndices(meshData.solidTris, allTris, allVerts.size() / 3); + allVerts.append(meshData.solidVerts); + + float* verts = allVerts.getCArray(); + int vertCount = allVerts.size() / 3; + int* tris = allTris.getCArray(); + int triCount = allTris.size() / 3; + + for (int i = 0; i < allVerts.size() / 3; i++) + fprintf(objFile, "v %f %f %f\n", verts[i*3], verts[i*3 + 1], verts[i*3 + 2]); + + for (int i = 0; i < allTris.size() / 3; i++) + fprintf(objFile, "f %i %i %i\n", tris[i*3] + 1, tris[i*3 + 1] + 1, tris[i*3 + 2] + 1); + + fclose(objFile); + + + char tileString[25]; + sprintf(tileString, "[%02u,%02u]: ", tileY, tileX); + printf("%sWriting debug output... \r", tileString); + + sprintf(objFileName, "meshes/%03u.map", mapID); + + objFile = fopen(objFileName, "wb"); + if (!objFile) + { + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", objFileName); + perror(message); + return; + } + + char b = '\0'; + fwrite(&b, sizeof(char), 1, objFile); + fclose(objFile); + + sprintf(objFileName, "meshes/%03u%02u%02u.mesh", mapID, tileY, tileX); + objFile = fopen(objFileName, "wb"); + if (!objFile) + { + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", objFileName); + perror(message); + return; + } + + fwrite(&vertCount, sizeof(int), 1, objFile); + fwrite(verts, sizeof(float), vertCount*3, objFile); + fflush(objFile); + + fwrite(&triCount, sizeof(int), 1, objFile); + fwrite(tris, sizeof(int), triCount*3, objFile); + fflush(objFile); + + fclose(objFile); + } +} diff --git a/src/tools/mmap_extractor/IntermediateValues.h b/src/tools/mmap_extractor/IntermediateValues.h new file mode 100644 index 00000000000..a267a0f6412 --- /dev/null +++ b/src/tools/mmap_extractor/IntermediateValues.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 MaNGOS + * + * 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 . + */ + +#ifndef _INTERMEDIATE_VALUES_H +#define _INTERMEDIATE_VALUES_H + +#include "PathCommon.h" +#include "TerrainBuilder.h" +#include "Recast.h" +#include "DetourNavMesh.h" + +namespace MMAP +{ + // this class gathers all debug info holding and output + struct IntermediateValues + { + rcHeightfield* heightfield; + rcCompactHeightfield* compactHeightfield; + rcContourSet* contours; + rcPolyMesh* polyMesh; + rcPolyMeshDetail* polyMeshDetail; + + IntermediateValues() : compactHeightfield(NULL), heightfield(NULL), + contours(NULL), polyMesh(NULL), polyMeshDetail(NULL) {} + ~IntermediateValues(); + + void writeIV(uint32 mapID, uint32 tileX, uint32 tileY); + + void debugWrite(FILE* file, const rcHeightfield* mesh); + void debugWrite(FILE* file, const rcCompactHeightfield* chf); + void debugWrite(FILE* file, const rcContourSet* cs); + void debugWrite(FILE* file, const rcPolyMesh* mesh); + void debugWrite(FILE* file, const rcPolyMeshDetail* mesh); + + void generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); + }; +} +#endif diff --git a/src/tools/mmap_extractor/MapBuilder.cpp b/src/tools/mmap_extractor/MapBuilder.cpp new file mode 100644 index 00000000000..3ca158f0127 --- /dev/null +++ b/src/tools/mmap_extractor/MapBuilder.cpp @@ -0,0 +1,894 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 MaNGOS + * + * 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 . + */ + +#include "PathCommon.h" +#include "MapBuilder.h" + +#include "MapTree.h" +#include "ModelInstance.h" +#include "LoginDatabase.h" + +#include "DetourNavMeshBuilder.h" +#include "DetourCommon.h" + +// These make the linker happy. +LoginDatabaseWorkerPool LoginDatabase; +#include "DisableMgr.h" +namespace DisableMgr +{ + bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags) + { + return 0; + } +} + +using namespace VMAP; + +namespace MMAP +{ + MapBuilder::MapBuilder(float maxWalkableAngle, bool skipLiquid, + bool skipContinents, bool skipJunkMaps, bool skipBattlegrounds, + bool debugOutput, bool bigBaseUnit, const char* offMeshFilePath) : + m_terrainBuilder(NULL), + m_debugOutput (debugOutput), + m_skipContinents (skipContinents), + m_skipJunkMaps (skipJunkMaps), + m_skipBattlegrounds (skipBattlegrounds), + m_maxWalkableAngle (maxWalkableAngle), + m_bigBaseUnit (bigBaseUnit), + m_rcContext (NULL), + m_offMeshFilePath (offMeshFilePath) + { + m_terrainBuilder = new TerrainBuilder(skipLiquid); + + m_rcContext = new rcContext(false); + + discoverTiles(); + } + + /**************************************************************************/ + MapBuilder::~MapBuilder() + { + for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) + { + (*it).second->clear(); + delete (*it).second; + } + + delete m_terrainBuilder; + delete m_rcContext; + } + + /**************************************************************************/ + void MapBuilder::discoverTiles() + { + vector files; + uint32 mapID, tileX, tileY, tileID, count = 0; + char filter[12]; + + printf("Discovering maps... "); + getDirContents(files, "maps"); + for (uint32 i = 0; i < files.size(); ++i) + { + mapID = uint32(atoi(files[i].substr(0,3).c_str())); + if (m_tiles.find(mapID) == m_tiles.end()) + { + m_tiles.insert(pair*>(mapID, new set)); + count++; + } + } + + files.clear(); + getDirContents(files, "vmaps", "*.vmtree"); + for (uint32 i = 0; i < files.size(); ++i) + { + mapID = uint32(atoi(files[i].substr(0,3).c_str())); + m_tiles.insert(pair*>(mapID, new set)); + count++; + } + printf("found %u.\n", count); + + count = 0; + printf("Discovering tiles... "); + for (TileList::iterator itr = m_tiles.begin(); itr != m_tiles.end(); ++itr) + { + set* tiles = (*itr).second; + mapID = (*itr).first; + + sprintf(filter, "%03u*.vmtile", mapID); + files.clear(); + getDirContents(files, "vmaps", filter); + for (uint32 i = 0; i < files.size(); ++i) + { + tileX = uint32(atoi(files[i].substr(7,2).c_str())); + tileY = uint32(atoi(files[i].substr(4,2).c_str())); + tileID = StaticMapTree::packTileID(tileY, tileX); + + tiles->insert(tileID); + count++; + } + + sprintf(filter, "%03u*", mapID); + files.clear(); + getDirContents(files, "maps", filter); + for (uint32 i = 0; i < files.size(); ++i) + { + tileY = uint32(atoi(files[i].substr(3,2).c_str())); + tileX = uint32(atoi(files[i].substr(5,2).c_str())); + tileID = StaticMapTree::packTileID(tileX, tileY); + + if (tiles->insert(tileID).second) + count++; + } + } + printf("found %u.\n\n", count); + } + + /**************************************************************************/ + set* MapBuilder::getTileList(uint32 mapID) + { + TileList::iterator itr = m_tiles.find(mapID); + if (itr != m_tiles.end()) + return (*itr).second; + + set* tiles = new set(); + m_tiles.insert(pair*>(mapID, tiles)); + return tiles; + } + + /**************************************************************************/ + void MapBuilder::buildAllMaps() + { + for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) + { + uint32 mapID = (*it).first; + if (!shouldSkipMap(mapID)) + buildMap(mapID); + } + } + + /**************************************************************************/ + void MapBuilder::getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY) + { + maxX = INT_MAX; + maxY = INT_MAX; + minX = INT_MIN; + minY = INT_MIN; + + float bmin[3], bmax[3], lmin[3], lmax[3]; + MeshData meshData; + + // make sure we process maps which don't have tiles + // initialize the static tree, which loads WDT models + if (!m_terrainBuilder->loadVMap(mapID, 64, 64, meshData)) + return; + + // get the coord bounds of the model data + if (meshData.solidVerts.size() + meshData.liquidVerts.size() == 0) + return; + + // get the coord bounds of the model data + if (meshData.solidVerts.size() && meshData.liquidVerts.size()) + { + rcCalcBounds(meshData.solidVerts.getCArray(), meshData.solidVerts.size() / 3, bmin, bmax); + rcCalcBounds(meshData.liquidVerts.getCArray(), meshData.liquidVerts.size() / 3, lmin, lmax); + rcVmin(bmin, lmin); + rcVmax(bmax, lmax); + } + else if (meshData.solidVerts.size()) + rcCalcBounds(meshData.solidVerts.getCArray(), meshData.solidVerts.size() / 3, bmin, bmax); + else + rcCalcBounds(meshData.liquidVerts.getCArray(), meshData.liquidVerts.size() / 3, lmin, lmax); + + // convert coord bounds to grid bounds + maxX = 32 - bmin[0] / GRID_SIZE; + maxY = 32 - bmin[2] / GRID_SIZE; + minX = 32 - bmax[0] / GRID_SIZE; + minY = 32 - bmax[2] / GRID_SIZE; + } + + /**************************************************************************/ + void MapBuilder::buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY) + { + dtNavMesh* navMesh = NULL; + buildNavMesh(mapID, navMesh); + if (!navMesh) + { + printf("Failed creating navmesh! \n"); + return; + } + + buildTile(mapID, tileX, tileY, navMesh); + dtFreeNavMesh(navMesh); + } + + /**************************************************************************/ + void MapBuilder::buildMap(uint32 mapID) + { + printf("Building map %03u:\n", mapID); + + set* tiles = getTileList(mapID); + + // make sure we process maps which don't have tiles + if (!tiles->size()) + { + // convert coord bounds to grid bounds + 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) + tiles->insert(StaticMapTree::packTileID(i, j)); + } + + if (!tiles->size()) + return; + + // build navMesh + dtNavMesh* navMesh = NULL; + buildNavMesh(mapID, navMesh); + if (!navMesh) + { + printf("Failed creating navmesh! \n"); + return; + } + + // now start building mmtiles for each tile + printf("We have %u tiles. \n", (unsigned int)tiles->size()); + for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) + { + uint32 tileX, tileY; + + // unpack tile coords + StaticMapTree::unpackTileID((*it), tileX, tileY); + + if (shouldSkipTile(mapID, tileX, tileY)) + continue; + + buildTile(mapID, tileX, tileY, navMesh); + } + + dtFreeNavMesh(navMesh); + + printf("Complete! \n\n"); + } + + /**************************************************************************/ + void MapBuilder::buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh) + { + printf("Building map %03u, tile [%02u,%02u]\n", mapID, tileX, tileY); + + MeshData meshData; + + // get heightmap data + m_terrainBuilder->loadMap(mapID, tileX, tileY, meshData); + + // get model data + m_terrainBuilder->loadVMap(mapID, tileY, tileX, meshData); + + // if there is no data, give up now + if (!meshData.solidVerts.size() && !meshData.liquidVerts.size()) + return; + + // remove unused vertices + TerrainBuilder::cleanVertices(meshData.solidVerts, meshData.solidTris); + TerrainBuilder::cleanVertices(meshData.liquidVerts, meshData.liquidTris); + + // gather all mesh data for final data check, and bounds calculation + G3D::Array allVerts; + allVerts.append(meshData.liquidVerts); + allVerts.append(meshData.solidVerts); + + if (!allVerts.size()) + return; + + // get bounds of current tile + float bmin[3], bmax[3]; + getTileBounds(tileX, tileY, allVerts.getCArray(), allVerts.size() / 3, bmin, bmax); + + m_terrainBuilder->loadOffMeshConnections(mapID, tileX, tileY, meshData, m_offMeshFilePath); + + // build navmesh tile + buildMoveMapTile(mapID, tileX, tileY, meshData, bmin, bmax, navMesh); + } + + /**************************************************************************/ + void MapBuilder::buildNavMesh(uint32 mapID, dtNavMesh* &navMesh) + { + set* tiles = getTileList(mapID); + + // old code for non-statically assigned bitmask sizes: + ///*** calculate number of bits needed to store tiles & polys ***/ + //int tileBits = dtIlog2(dtNextPow2(tiles->size())); + //if (tileBits < 1) tileBits = 1; // need at least one bit! + //int polyBits = sizeof(dtPolyRef)*8 - SALT_MIN_BITS - tileBits; + + int tileBits = STATIC_TILE_BITS; + int polyBits = STATIC_POLY_BITS; + + int maxTiles = tiles->size(); + int maxPolysPerTile = 1 << polyBits; + + /*** calculate bounds of map ***/ + + uint32 tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0, tileX, tileY; + for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) + { + StaticMapTree::unpackTileID((*it), tileX, tileY); + + if (tileX > tileXMax) + tileXMax = tileX; + else if (tileX < tileXMin) + tileXMin = tileX; + + if (tileY > tileYMax) + tileYMax = tileY; + else if (tileY < tileYMin) + tileYMin = tileY; + } + + // use Max because '32 - tileX' is negative for values over 32 + float bmin[3], bmax[3]; + getTileBounds(tileXMax, tileYMax, NULL, 0, bmin, bmax); + + /*** now create the navmesh ***/ + + // navmesh creation params + dtNavMeshParams navMeshParams; + memset(&navMeshParams, 0, sizeof(dtNavMeshParams)); + navMeshParams.tileWidth = GRID_SIZE; + navMeshParams.tileHeight = GRID_SIZE; + rcVcopy(navMeshParams.orig, bmin); + navMeshParams.maxTiles = maxTiles; + navMeshParams.maxPolys = maxPolysPerTile; + + navMesh = dtAllocNavMesh(); + printf("Creating navMesh... \r"); + if (!navMesh->init(&navMeshParams)) + { + printf("Failed creating navmesh! \n"); + return; + } + + char fileName[25]; + sprintf(fileName, "mmaps/%03u.mmap", mapID); + + FILE* file = fopen(fileName, "wb"); + if (!file) + { + dtFreeNavMesh(navMesh); + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", fileName); + perror(message); + return; + } + + // now that we know navMesh params are valid, we can write them to file + fwrite(&navMeshParams, sizeof(dtNavMeshParams), 1, file); + fclose(file); + } + + /**************************************************************************/ + void MapBuilder::buildMoveMapTile(uint32 mapID, uint32 tileX, uint32 tileY, + MeshData &meshData, float bmin[3], float bmax[3], + dtNavMesh* navMesh) + { + // console output + char tileString[10]; + sprintf(tileString, "[%02i,%02i]: ", tileX, tileY); + printf("%s Building movemap tiles... \r", tileString); + + IntermediateValues iv; + + float* tVerts = meshData.solidVerts.getCArray(); + int tVertCount = meshData.solidVerts.size() / 3; + int* tTris = meshData.solidTris.getCArray(); + int tTriCount = meshData.solidTris.size() / 3; + + float* lVerts = meshData.liquidVerts.getCArray(); + int lVertCount = meshData.liquidVerts.size() / 3; + int* lTris = meshData.liquidTris.getCArray(); + int lTriCount = meshData.liquidTris.size() / 3; + uint8* lTriFlags = meshData.liquidType.getCArray(); + + // these are WORLD UNIT based metrics + // this are basic unit dimentions + // value have to divide GRID_SIZE(533.33333f) ( aka: 0.5333, 0.2666, 0.3333, 0.1333, etc ) + const static float BASE_UNIT_DIM = m_bigBaseUnit ? 0.533333f : 0.266666f; + + // All are in UNIT metrics! + const static int VERTEX_PER_MAP = int(GRID_SIZE/BASE_UNIT_DIM + 0.5f); + const static int VERTEX_PER_TILE = m_bigBaseUnit ? 40 : 80; // must divide VERTEX_PER_MAP + const static int TILES_PER_MAP = VERTEX_PER_MAP/VERTEX_PER_TILE; + + rcConfig config; + memset(&config, 0, sizeof(rcConfig)); + + rcVcopy(config.bmin, bmin); + rcVcopy(config.bmax, bmax); + + config.maxVertsPerPoly = DT_VERTS_PER_POLYGON; + config.cs = BASE_UNIT_DIM; + config.ch = BASE_UNIT_DIM; + config.walkableSlopeAngle = m_maxWalkableAngle; + config.tileSize = VERTEX_PER_TILE; + config.walkableRadius = m_bigBaseUnit ? 1 : 2; + config.borderSize = config.walkableRadius + 3; + config.maxEdgeLen = VERTEX_PER_TILE + 1; //anything bigger than tileSize + config.walkableHeight = m_bigBaseUnit ? 3 : 6; + config.walkableClimb = m_bigBaseUnit ? 2 : 4; // keep less than walkableHeight + config.minRegionArea = rcSqr(60); + config.mergeRegionArea = rcSqr(50); + config.maxSimplificationError = 2.0f; // eliminates most jagged edges (tinny polygons) + config.detailSampleDist = config.cs * 64; + config.detailSampleMaxError = config.ch * 2; + + // this sets the dimensions of the heightfield - should maybe happen before border padding + rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height); + + // allocate subregions : tiles + Tile* tiles = new Tile[TILES_PER_MAP * TILES_PER_MAP]; + + // Initialize per tile config. + rcConfig tileCfg; + memcpy(&tileCfg, &config, sizeof(rcConfig)); + tileCfg.width = config.tileSize + config.borderSize*2; + tileCfg.height = config.tileSize + config.borderSize*2; + + // build all tiles + for (int y = 0; y < TILES_PER_MAP; ++y) + { + for (int x = 0; x < TILES_PER_MAP; ++x) + { + Tile& tile = tiles[x + y*TILES_PER_MAP]; + + // Calculate the per tile bounding box. + tileCfg.bmin[0] = config.bmin[0] + (x*config.tileSize - config.borderSize)*config.cs; + tileCfg.bmin[2] = config.bmin[2] + (y*config.tileSize - config.borderSize)*config.cs; + tileCfg.bmax[0] = config.bmin[0] + ((x+1)*config.tileSize + config.borderSize)*config.cs; + tileCfg.bmax[2] = config.bmin[2] + ((y+1)*config.tileSize + config.borderSize)*config.cs; + + float tbmin[2], tbmax[2]; + tbmin[0] = tileCfg.bmin[0]; + tbmin[1] = tileCfg.bmin[2]; + tbmax[0] = tileCfg.bmax[0]; + tbmax[1] = tileCfg.bmax[2]; + + // build heightfield + tile.solid = rcAllocHeightfield(); + if (!tile.solid || !rcCreateHeightfield(m_rcContext, *tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch)) + { + printf("%sFailed building heightfield! \n", tileString); + continue; + } + + // mark all walkable tiles, both liquids and solids + unsigned char* triFlags = new unsigned char[tTriCount]; + memset(triFlags, NAV_GROUND, tTriCount*sizeof(unsigned char)); + rcClearUnwalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags); + rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.solid, config.walkableClimb); + delete [] triFlags; + + rcFilterLowHangingWalkableObstacles(m_rcContext, config.walkableClimb, *tile.solid); + rcFilterLedgeSpans(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid); + rcFilterWalkableLowHeightSpans(m_rcContext, tileCfg.walkableHeight, *tile.solid); + + rcRasterizeTriangles(m_rcContext, lVerts, lVertCount, lTris, lTriFlags, lTriCount, *tile.solid, config.walkableClimb); + + // compact heightfield spans + tile.chf = rcAllocCompactHeightfield(); + if (!tile.chf || !rcBuildCompactHeightfield(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid, *tile.chf)) + { + printf("%sFailed compacting heightfield! \n", tileString); + continue; + } + + // build polymesh intermediates + if (!rcErodeWalkableArea(m_rcContext, config.walkableRadius, *tile.chf)) + { + printf("%sFailed eroding area! \n", tileString); + continue; + } + + if (!rcBuildDistanceField(m_rcContext, *tile.chf)) + { + printf("%sFailed building distance field! \n", tileString); + continue; + } + + if (!rcBuildRegions(m_rcContext, *tile.chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea)) + { + printf("%sFailed building regions! \n", tileString); + continue; + } + + tile.cset = rcAllocContourSet(); + if (!tile.cset || !rcBuildContours(m_rcContext, *tile.chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *tile.cset)) + { + printf("%sFailed building contours! \n", tileString); + continue; + } + + // build polymesh + tile.pmesh = rcAllocPolyMesh(); + if (!tile.pmesh || !rcBuildPolyMesh(m_rcContext, *tile.cset, tileCfg.maxVertsPerPoly, *tile.pmesh)) + { + printf("%sFailed building polymesh! \n", tileString); + continue; + } + + tile.dmesh = rcAllocPolyMeshDetail(); + if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg .detailSampleMaxError, *tile.dmesh)) + { + printf("%sFailed building polymesh detail! \n", tileString); + continue; + } + + // free those up + // we may want to keep them in the future for debug + // but right now, we don't have the code to merge them + rcFreeHeightField(tile.solid); + tile.solid = NULL; + rcFreeCompactHeightfield(tile.chf); + tile.chf = NULL; + rcFreeContourSet(tile.cset); + tile.cset = NULL; + } + } + + // merge per tile poly and detail meshes + rcPolyMesh** pmmerge = new rcPolyMesh*[TILES_PER_MAP * TILES_PER_MAP]; + if (!pmmerge) + { + printf("%s alloc pmmerge FIALED! \r", tileString); + return; + } + + rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP]; + if (!dmmerge) + { + printf("%s alloc dmmerge FIALED! \r", tileString); + return; + } + + int nmerge = 0; + for (int y = 0; y < TILES_PER_MAP; ++y) + { + for (int x = 0; x < TILES_PER_MAP; ++x) + { + Tile& tile = tiles[x + y*TILES_PER_MAP]; + if (tile.pmesh) + { + pmmerge[nmerge] = tile.pmesh; + dmmerge[nmerge] = tile.dmesh; + nmerge++; + } + } + } + + iv.polyMesh = rcAllocPolyMesh(); + if (!iv.polyMesh) + { + printf("%s alloc iv.polyMesh FIALED! \r", tileString); + return; + } + rcMergePolyMeshes(m_rcContext, pmmerge, nmerge, *iv.polyMesh); + + iv.polyMeshDetail = rcAllocPolyMeshDetail(); + if (!iv.polyMeshDetail) + { + printf("%s alloc m_dmesh FIALED! \r", tileString); + return; + } + rcMergePolyMeshDetails(m_rcContext, dmmerge, nmerge, *iv.polyMeshDetail); + + // free things up + delete [] pmmerge; + delete [] dmmerge; + + delete [] tiles; + + // remove padding for extraction + 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; + } + + // set polygons as walkable + // TODO: special flags for DYNAMIC polygons, ie surfaces that can be turned on and off + for (int i = 0; i < iv.polyMesh->npolys; ++i) + if (iv.polyMesh->areas[i] & RC_WALKABLE_AREA) + iv.polyMesh->flags[i] = iv.polyMesh->areas[i]; + + // setup mesh parameters + dtNavMeshCreateParams params; + memset(¶ms, 0, sizeof(params)); + params.verts = iv.polyMesh->verts; + params.vertCount = iv.polyMesh->nverts; + params.polys = iv.polyMesh->polys; + params.polyAreas = iv.polyMesh->areas; + params.polyFlags = iv.polyMesh->flags; + params.polyCount = iv.polyMesh->npolys; + params.nvp = iv.polyMesh->nvp; + params.detailMeshes = iv.polyMeshDetail->meshes; + params.detailVerts = iv.polyMeshDetail->verts; + params.detailVertsCount = iv.polyMeshDetail->nverts; + params.detailTris = iv.polyMeshDetail->tris; + params.detailTriCount = iv.polyMeshDetail->ntris; + + params.offMeshConVerts = meshData.offMeshConnections.getCArray(); + params.offMeshConCount = meshData.offMeshConnections.size()/6; + params.offMeshConRad = meshData.offMeshConnectionRads.getCArray(); + params.offMeshConDir = meshData.offMeshConnectionDirs.getCArray(); + params.offMeshConAreas = meshData.offMeshConnectionsAreas.getCArray(); + params.offMeshConFlags = meshData.offMeshConnectionsFlags.getCArray(); + + params.walkableHeight = BASE_UNIT_DIM*config.walkableHeight; // agent height + params.walkableRadius = BASE_UNIT_DIM*config.walkableRadius; // agent radius + params.walkableClimb = BASE_UNIT_DIM*config.walkableClimb; // keep less that walkableHeight (aka agent height)! + params.tileX = (((bmin[0] + bmax[0]) / 2) - navMesh->getParams()->orig[0]) / GRID_SIZE; + params.tileY = (((bmin[2] + bmax[2]) / 2) - navMesh->getParams()->orig[2]) / GRID_SIZE; + rcVcopy(params.bmin, bmin); + rcVcopy(params.bmax, bmax); + params.cs = config.cs; + params.ch = config.ch; + params.tileSize = VERTEX_PER_MAP; + + // will hold final navmesh + unsigned char* navData = NULL; + int navDataSize = 0; + + do + { + // these values are checked within dtCreateNavMeshData - handle them here + // so we have a clear error message + if (params.nvp > DT_VERTS_PER_POLYGON) + { + printf("%s Invalid verts-per-polygon value! \n", tileString); + continue; + } + if (params.vertCount >= 0xffff) + { + printf("%s Too many vertices! \n", tileString); + continue; + } + 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 + //printf("%sNo vertices to build tile! \n", tileString); + continue; + } + if (!params.polyCount || !params.polys || + TILES_PER_MAP*TILES_PER_MAP == params.polyCount) + { + // 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 + // drop tiles with only exact count - some tiles may have geometry while having less tiles + printf("%s No polygons to build on tile! \n", tileString); + continue; + } + if (!params.detailMeshes || !params.detailVerts || !params.detailTris) + { + printf("%s No detail mesh to build tile! \n", tileString); + continue; + } + + printf("%s Building navmesh tile... \r", tileString); + if (!dtCreateNavMeshData(¶ms, &navData, &navDataSize)) + { + printf("%s Failed building navmesh tile! \n", tileString); + continue; + } + + dtTileRef tileRef = 0; + printf("%s Adding tile to navmesh... \r", 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 || dtResult != DT_SUCCESS) + { + printf("%s Failed adding tile to navmesh! \n", tileString); + continue; + } + + // file output + char fileName[255]; + sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); + FILE* file = fopen(fileName, "wb"); + if (!file) + { + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", fileName); + perror(message); + navMesh->removeTile(tileRef, NULL, NULL); + continue; + } + + printf("%s Writing to file... \r", tileString); + + // write header + MmapTileHeader header; + header.usesLiquids = m_terrainBuilder->usesLiquids(); + header.size = uint32(navDataSize); + fwrite(&header, sizeof(MmapTileHeader), 1, file); + + // write data + fwrite(navData, sizeof(unsigned char), navDataSize, file); + fclose(file); + + // now that tile is written to disk, we can unload it + navMesh->removeTile(tileRef, NULL, NULL); + } + while (0); + + if (m_debugOutput) + { + // 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; + } + + iv.generateObjFile(mapID, tileX, tileY, meshData); + iv.writeIV(mapID, tileX, tileY); + } + } + + /**************************************************************************/ + void MapBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) + { + // this is for elevation + if (verts && vertCount) + rcCalcBounds(verts, vertCount, bmin, bmax); + else + { + bmin[1] = FLT_MIN; + bmax[1] = FLT_MAX; + } + + // this is for width and depth + bmax[0] = (32 - int(tileX)) * GRID_SIZE; + bmax[2] = (32 - int(tileY)) * GRID_SIZE; + bmin[0] = bmax[0] - GRID_SIZE; + bmin[2] = bmax[2] - GRID_SIZE; + } + + /**************************************************************************/ + bool MapBuilder::shouldSkipMap(uint32 mapID) + { + if (m_skipContinents) + switch (mapID) + { + case 0: + case 1: + case 530: + case 571: + return true; + default: + break; + } + + if (m_skipJunkMaps) + switch (mapID) + { + case 13: // test.wdt + case 25: // ScottTest.wdt + case 29: // Test.wdt + case 42: // Colin.wdt + case 169: // EmeraldDream.wdt (unused, and very large) + case 451: // development.wdt + case 573: // ExteriorTest.wdt + case 597: // CraigTest.wdt + case 605: // development_nonweighted.wdt + case 606: // QA_DVD.wdt + return true; + default: + if (isTransportMap(mapID)) + return true; + break; + } + + if (m_skipBattlegrounds) + switch (mapID) + { + case 30: // AV + case 37: // ? + case 489: // WSG + case 529: // AB + case 566: // EotS + case 607: // SotA + case 628: // IoC + return true; + default: + break; + } + + return false; + } + + /**************************************************************************/ + bool MapBuilder::isTransportMap(uint32 mapID) + { + switch (mapID) + { + // transport maps + case 582: + case 584: + case 586: + case 587: + case 588: + case 589: + case 590: + case 591: + case 592: + case 593: + case 594: + case 596: + case 610: + case 612: + case 613: + case 614: + case 620: + case 621: + case 622: + case 623: + case 641: + case 642: + case 647: + case 672: + case 673: + case 712: + case 713: + case 718: + return true; + default: + return false; + } + } + + /**************************************************************************/ + bool MapBuilder::shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY) + { + char fileName[255]; + sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); + FILE* file = fopen(fileName, "rb"); + if (!file) + return false; + + MmapTileHeader header; + fread(&header, sizeof(MmapTileHeader), 1, file); + fclose(file); + + if (header.mmapMagic != MMAP_MAGIC || header.dtVersion != DT_NAVMESH_VERSION) + return false; + + if (header.mmapVersion != MMAP_VERSION) + return false; + + return true; + } + +} diff --git a/src/tools/mmap_extractor/MapBuilder.h b/src/tools/mmap_extractor/MapBuilder.h new file mode 100644 index 00000000000..d0f33ce9a79 --- /dev/null +++ b/src/tools/mmap_extractor/MapBuilder.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 MaNGOS + * + * 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 . + */ + +#ifndef _MAP_BUILDER_H +#define _MAP_BUILDER_H + +#include +#include +#include + +#include "TerrainBuilder.h" +#include "IntermediateValues.h" + +#include "IVMapManager.h" +#include "WorldModel.h" + +#include "Recast.h" +#include "DetourNavMesh.h" + +using namespace std; +using namespace VMAP; + +// G3D namespace typedefs conflicts with ACE typedefs + +namespace MMAP +{ + typedef map*> TileList; + struct Tile + { + Tile() : chf(NULL), solid(NULL), cset(NULL), pmesh(NULL), dmesh(NULL) {} + ~Tile() + { + rcFreeCompactHeightfield(chf); + rcFreeContourSet(cset); + rcFreeHeightField(solid); + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + } + rcCompactHeightfield* chf; + rcHeightfield* solid; + rcContourSet* cset; + rcPolyMesh* pmesh; + rcPolyMeshDetail* dmesh; + }; + + class MapBuilder + { + public: + MapBuilder(float maxWalkableAngle = 60.f, + bool skipLiquid = false, + bool skipContinents = false, + bool skipJunkMaps = true, + bool skipBattlegrounds = false, + bool debugOutput = false, + bool bigBaseUnit = false, + const char* offMeshFilePath = NULL); + + ~MapBuilder(); + + // builds all mmap tiles for the specified map id (ignores skip settings) + void buildMap(uint32 mapID); + + // builds an mmap tile for the specified map and its mesh + void buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY); + + // builds list of maps, then builds all of mmap tiles (based on the skip settings) + void buildAllMaps(); + + private: + // detect maps and tiles + void discoverTiles(); + set* getTileList(uint32 mapID); + + void buildNavMesh(uint32 mapID, dtNavMesh* &navMesh); + + void buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh); + + // move map building + void buildMoveMapTile(uint32 mapID, + uint32 tileX, + uint32 tileY, + MeshData &meshData, + float bmin[3], + float bmax[3], + dtNavMesh* navMesh); + + void getTileBounds(uint32 tileX, uint32 tileY, + float* verts, int vertCount, + float* bmin, float* bmax); + void getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY); + + bool shouldSkipMap(uint32 mapID); + bool isTransportMap(uint32 mapID); + bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY); + + TerrainBuilder* m_terrainBuilder; + TileList m_tiles; + + bool m_debugOutput; + + const char* m_offMeshFilePath; + bool m_skipContinents; + bool m_skipJunkMaps; + bool m_skipBattlegrounds; + + float m_maxWalkableAngle; + bool m_bigBaseUnit; + + // build performance - not really used for now + rcContext* m_rcContext; + }; +} + +#endif diff --git a/src/tools/mmap_extractor/PathCommon.h b/src/tools/mmap_extractor/PathCommon.h new file mode 100644 index 00000000000..fd02ec02d50 --- /dev/null +++ b/src/tools/mmap_extractor/PathCommon.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 MaNGOS + * + * 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 . + */ + +#ifndef _MMAP_COMMON_H +#define _MMAP_COMMON_H + +#include +#include + +#include "Define.h" + +#ifndef _WIN32 + #include + #include +#endif + +#ifdef __linux__ + #include +#endif + +using namespace std; + +namespace MMAP +{ + inline bool matchWildcardFilter(const char* filter, const char* str) + { + if (!filter || !str) + return false; + + // end on null character + while (*filter && *str) + { + if (*filter == '*') + { + if (*++filter == '\0') // wildcard at end of filter means all remaing chars match + return true; + + while (true) + { + if (*filter == *str) + break; + if (*str == '\0') + return false; // reached end of string without matching next filter character + str++; + } + } + else if (*filter != *str) + return false; // mismatch + + filter++; + str++; + } + + return ((*filter == '\0' || (*filter == '*' && *++filter == '\0')) && *str == '\0'); + } + + enum ListFilesResult + { + LISTFILE_DIRECTORY_NOT_FOUND = 0, + LISTFILE_OK = 1 + }; + + inline ListFilesResult getDirContents(vector &fileList, string dirpath = ".", string filter = "*", bool includeSubDirs = false) + { + #ifdef WIN32 + HANDLE hFind; + WIN32_FIND_DATA findFileInfo; + string directory; + + directory = dirpath + "/" + filter; + + hFind = FindFirstFile(directory.c_str(), &findFileInfo); + + if (hFind == INVALID_HANDLE_VALUE) + return LISTFILE_DIRECTORY_NOT_FOUND; + do + { + if (includeSubDirs || (findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + fileList.push_back(string(findFileInfo.cFileName)); + } + while (FindNextFile(hFind, &findFileInfo)); + + FindClose(hFind); + + #else + const char *p = dirpath.c_str(); + DIR * dirp = opendir(p); + struct dirent * dp; + dirp = opendir(p); + + while (dirp) + { + errno = 0; + if ((dp = readdir(dirp)) != NULL) + { + if (matchWildcardFilter(filter.c_str(), dp->d_name)) + fileList.push_back(string(dp->d_name)); + } + else + break; + } + + if (dirp) + closedir(dirp); + else + return LISTFILE_DIRECTORY_NOT_FOUND; + #endif + + return LISTFILE_OK; + } +} + +#endif diff --git a/src/tools/mmap_extractor/PathGenerator.cpp b/src/tools/mmap_extractor/PathGenerator.cpp new file mode 100644 index 00000000000..2eb2c6545c4 --- /dev/null +++ b/src/tools/mmap_extractor/PathGenerator.cpp @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2005-2011 MaNGOS + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "PathCommon.h" +#include "MapBuilder.h" + +using namespace MMAP; + +bool checkDirectories(bool debugOutput) +{ + vector dirFiles; + + if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size()) + { + printf("'maps' directory is empty or does not exist\n"); + return false; + } + + dirFiles.clear(); + if (getDirContents(dirFiles, "vmaps", "*.vmtree") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size()) + { + printf("'vmaps' directory is empty or does not exist\n"); + return false; + } + + dirFiles.clear(); + if (getDirContents(dirFiles, "mmaps") == LISTFILE_DIRECTORY_NOT_FOUND) + { + printf("'mmaps' directory does not exist\n"); + return false; + } + + dirFiles.clear(); + if (debugOutput) + { + if (getDirContents(dirFiles, "meshes") == LISTFILE_DIRECTORY_NOT_FOUND) + { + printf("'meshes' directory does not exist (no place to put debugOutput files)\n"); + return false; + } + } + + return true; +} + +bool handleArgs(int argc, char** argv, + int &mapnum, + int &tileX, + int &tileY, + float &maxAngle, + bool &skipLiquid, + bool &skipContinents, + bool &skipJunkMaps, + bool &skipBattlegrounds, + bool &debugOutput, + bool &silent, + bool &bigBaseUnit, + char* &offMeshInputPath) +{ + char* param = NULL; + for (int i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "--maxAngle") == 0) + { + param = argv[++i]; + if (!param) + return false; + + float maxangle = atof(param); + if (maxangle <= 90.f && maxangle >= 45.f) + maxAngle = maxangle; + else + printf("invalid option for '--maxAngle', using default\n"); + } + else if (strcmp(argv[i], "--tile") == 0) + { + param = argv[++i]; + if (!param) + return false; + + char* stileX = strtok(param, ","); + char* stileY = strtok(NULL, ","); + int tilex = atoi(stileX); + int tiley = atoi(stileY); + + if ((tilex > 0 && tilex < 64) || (tilex == 0 && strcmp(stileX, "0") == 0)) + tileX = tilex; + if ((tiley > 0 && tiley < 64) || (tiley == 0 && strcmp(stileY, "0") == 0)) + tileY = tiley; + + if (tileX < 0 || tileY < 0) + { + printf("invalid tile coords.\n"); + return false; + } + } + else if (strcmp(argv[i], "--skipLiquid") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + skipLiquid = true; + else if (strcmp(param, "false") == 0) + skipLiquid = false; + else + printf("invalid option for '--skipLiquid', using default\n"); + } + else if (strcmp(argv[i], "--skipContinents") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + skipContinents = true; + else if (strcmp(param, "false") == 0) + skipContinents = false; + else + printf("invalid option for '--skipContinents', using default\n"); + } + else if (strcmp(argv[i], "--skipJunkMaps") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + skipJunkMaps = true; + else if (strcmp(param, "false") == 0) + skipJunkMaps = false; + else + printf("invalid option for '--skipJunkMaps', using default\n"); + } + else if (strcmp(argv[i], "--skipBattlegrounds") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + skipBattlegrounds = true; + else if (strcmp(param, "false") == 0) + skipBattlegrounds = false; + else + printf("invalid option for '--skipBattlegrounds', using default\n"); + } + else if (strcmp(argv[i], "--debugOutput") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + debugOutput = true; + else if (strcmp(param, "false") == 0) + debugOutput = false; + else + printf("invalid option for '--debugOutput', using default true\n"); + } + else if (strcmp(argv[i], "--silent") == 0) + { + silent = true; + } + else if (strcmp(argv[i], "--bigBaseUnit") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + bigBaseUnit = true; + else if (strcmp(param, "false") == 0) + bigBaseUnit = false; + else + printf("invalid option for '--bigBaseUnit', using default false\n"); + } + else if (strcmp(argv[i], "--offMeshInput") == 0) + { + param = argv[++i]; + if (!param) + return false; + + offMeshInputPath = param; + } + else + { + int map = atoi(argv[i]); + if (map > 0 || (map == 0 && (strcmp(argv[i], "0") == 0))) + mapnum = map; + else + { + printf("invalid map id\n"); + return false; + } + } + } + + return true; +} + +int finish(const char* message, int returnValue) +{ + printf("%s", message); + getchar(); + return returnValue; +} + +int main(int argc, char** argv) +{ + int mapnum = -1; + float maxAngle = 60.0f; + int tileX = -1, tileY = -1; + bool skipLiquid = false, + skipContinents = false, + skipJunkMaps = true, + skipBattlegrounds = false, + debugOutput = false, + silent = false, + bigBaseUnit = false; + char* offMeshInputPath = NULL; + + bool validParam = handleArgs(argc, argv, mapnum, + tileX, tileY, maxAngle, + skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, + debugOutput, silent, bigBaseUnit, offMeshInputPath); + + if (!validParam) + return silent ? -1 : finish("You have specified invalid parameters", -1); + + if (mapnum == -1 && debugOutput) + { + if (silent) + return -2; + + printf("You have specifed debug output, but didn't specify a map to generate.\n"); + printf("This will generate debug output for ALL maps.\n"); + printf("Are you sure you want to continue? (y/n) "); + if (getchar() != 'y') + return 0; + } + + if (!checkDirectories(debugOutput)) + return silent ? -3 : finish("Press any key to close...", -3); + + MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps, + skipBattlegrounds, debugOutput, bigBaseUnit, offMeshInputPath); + + if (tileX > -1 && tileY > -1 && mapnum >= 0) + builder.buildSingleTile(mapnum, tileX, tileY); + else if (mapnum >= 0) + builder.buildMap(uint32(mapnum)); + else + builder.buildAllMaps(); + + return silent ? 1 : finish("Movemap build is complete!", 1); +} diff --git a/src/tools/mmap_extractor/TerrainBuilder.cpp b/src/tools/mmap_extractor/TerrainBuilder.cpp new file mode 100644 index 00000000000..c696f6017a5 --- /dev/null +++ b/src/tools/mmap_extractor/TerrainBuilder.cpp @@ -0,0 +1,854 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 MaNGOS + * + * 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 . + */ + +#include "TerrainBuilder.h" + +#include "PathCommon.h" +#include "MapBuilder.h" + +#include "VMapManager2.h" +#include "MapTree.h" +#include "ModelInstance.h" + +namespace MMAP +{ + TerrainBuilder::TerrainBuilder(bool skipLiquid) : m_skipLiquid (skipLiquid){ } + TerrainBuilder::~TerrainBuilder() { } + + /**************************************************************************/ + void TerrainBuilder::getLoopVars(Spot portion, int &loopStart, int &loopEnd, int &loopInc) + { + switch (portion) + { + case ENTIRE: + loopStart = 0; + loopEnd = V8_SIZE_SQ; + loopInc = 1; + break; + case TOP: + loopStart = 0; + loopEnd = V8_SIZE; + loopInc = 1; + break; + case LEFT: + loopStart = 0; + loopEnd = V8_SIZE_SQ - V8_SIZE + 1; + loopInc = V8_SIZE; + break; + case RIGHT: + loopStart = V8_SIZE - 1; + loopEnd = V8_SIZE_SQ; + loopInc = V8_SIZE; + break; + case BOTTOM: + loopStart = V8_SIZE_SQ - V8_SIZE; + loopEnd = V8_SIZE_SQ; + loopInc = 1; + break; + } + } + + /**************************************************************************/ + void TerrainBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) + { + if (loadMap(mapID, tileX, tileY, meshData, ENTIRE)) + { + loadMap(mapID, tileX+1, tileY, meshData, LEFT); + loadMap(mapID, tileX-1, tileY, meshData, RIGHT); + loadMap(mapID, tileX, tileY+1, meshData, TOP); + loadMap(mapID, tileX, tileY-1, meshData, BOTTOM); + } + } + + /**************************************************************************/ + bool TerrainBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, Spot portion) + { + char mapFileName[255]; + sprintf(mapFileName, "maps/%03u%02u%02u.map", mapID, tileY, tileX); + + FILE* mapFile = fopen(mapFileName, "rb"); + if (!mapFile) + return false; + + map_fileheader fheader; + fread(&fheader, sizeof(map_fileheader), 1, mapFile); + + if (fheader.versionMagic != *((uint32 const*)(MAP_VERSION_MAGIC))) + { + fclose(mapFile); + printf("%s is the wrong version, please extract new .map files\n", mapFileName); + return false; + } + + map_heightHeader hheader; + fseek(mapFile, fheader.heightMapOffset, SEEK_SET); + fread(&hheader, sizeof(map_heightHeader), 1, mapFile); + + bool haveTerrain = !(hheader.flags & MAP_HEIGHT_NO_HEIGHT); + bool haveLiquid = fheader.liquidMapOffset && !m_skipLiquid; + + // no data in this map file + if (!haveTerrain && !haveLiquid) + { + fclose(mapFile); + return false; + } + + // data used later + uint16 holes[16][16]; + memset(holes, 0, sizeof(holes)); + uint8 liquid_type[16][16]; + memset(liquid_type, 0, sizeof(liquid_type)); + G3D::Array ltriangles; + G3D::Array ttriangles; + + // terrain data + if (haveTerrain) + { + int i; + float heightMultiplier; + float V9[V9_SIZE_SQ], V8[V8_SIZE_SQ]; + + if (hheader.flags & MAP_HEIGHT_AS_INT8) + { + uint8 v9[V9_SIZE_SQ]; + uint8 v8[V8_SIZE_SQ]; + fread(v9, sizeof(uint8), V9_SIZE_SQ, mapFile); + fread(v8, sizeof(uint8), V8_SIZE_SQ, mapFile); + heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 255; + + for (i = 0; i < V9_SIZE_SQ; ++i) + V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight; + + for (i = 0; i < V8_SIZE_SQ; ++i) + V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight; + } + else if (hheader.flags & MAP_HEIGHT_AS_INT16) + { + uint16 v9[V9_SIZE_SQ]; + uint16 v8[V8_SIZE_SQ]; + fread(v9, sizeof(uint16), V9_SIZE_SQ, mapFile); + fread(v8, sizeof(uint16), V8_SIZE_SQ, mapFile); + heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 65535; + + for (i = 0; i < V9_SIZE_SQ; ++i) + V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight; + + for (i = 0; i < V8_SIZE_SQ; ++i) + V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight; + } + else + { + fread (V9, sizeof(float), V9_SIZE_SQ, mapFile); + fread(V8, sizeof(float), V8_SIZE_SQ, mapFile); + } + + // hole data + memset(holes, 0, fheader.holesSize); + fseek(mapFile, fheader.holesOffset, SEEK_SET); + fread(holes, fheader.holesSize, 1, mapFile); + + int count = meshData.solidVerts.size() / 3; + float xoffset = (float(tileX)-32)*GRID_SIZE; + float yoffset = (float(tileY)-32)*GRID_SIZE; + + float coord[3]; + + for (i = 0; i < V9_SIZE_SQ; ++i) + { + getHeightCoord(i, GRID_V9, xoffset, yoffset, coord, V9); + meshData.solidVerts.append(coord[0]); + meshData.solidVerts.append(coord[2]); + meshData.solidVerts.append(coord[1]); + } + + for (i = 0; i < V8_SIZE_SQ; ++i) + { + getHeightCoord(i, GRID_V8, xoffset, yoffset, coord, V8); + meshData.solidVerts.append(coord[0]); + meshData.solidVerts.append(coord[2]); + meshData.solidVerts.append(coord[1]); + } + + int j, indices[3], loopStart, loopEnd, loopInc; + getLoopVars(portion, loopStart, loopEnd, loopInc); + for (i = loopStart; i < loopEnd; i+=loopInc) + for (j = TOP; j <= BOTTOM; j+=1) + { + getHeightTriangle(i, Spot(j), indices); + ttriangles.append(indices[2] + count); + ttriangles.append(indices[1] + count); + ttriangles.append(indices[0] + count); + } + } + + // liquid data + if (haveLiquid) + { + map_liquidHeader lheader; + fseek(mapFile, fheader.liquidMapOffset, SEEK_SET); + fread(&lheader, sizeof(map_liquidHeader), 1, mapFile); + + float* liquid_map = NULL; + + if (!(lheader.flags & MAP_LIQUID_NO_TYPE)) + fread(liquid_type, sizeof(liquid_type), 1, mapFile); + + if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) + { + liquid_map = new float [lheader.width*lheader.height]; + fread(liquid_map, sizeof(float), lheader.width*lheader.height, mapFile); + } + + if (liquid_type && liquid_map) + { + int count = meshData.liquidVerts.size() / 3; + float xoffset = (float(tileX)-32)*GRID_SIZE; + float yoffset = (float(tileY)-32)*GRID_SIZE; + + float coord[3]; + int row, col; + + // generate coordinates + if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) + { + int j = 0; + for (int i = 0; i < V9_SIZE_SQ; ++i) + { + row = i / V9_SIZE; + col = i % V9_SIZE; + + if (row < lheader.offsetY || row >= lheader.offsetY + lheader.height || + col < lheader.offsetX || col >= lheader.offsetX + lheader.width) + { + // dummy vert using invalid height + meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, INVALID_MAP_LIQ_HEIGHT, (yoffset+row*GRID_PART_SIZE)*-1); + continue; + } + + getLiquidCoord(i, j, xoffset, yoffset, coord, liquid_map); + meshData.liquidVerts.append(coord[0]); + meshData.liquidVerts.append(coord[2]); + meshData.liquidVerts.append(coord[1]); + j++; + } + } + else + { + for (int i = 0; i < V9_SIZE_SQ; ++i) + { + row = i / V9_SIZE; + col = i % V9_SIZE; + meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, lheader.liquidLevel, (yoffset+row*GRID_PART_SIZE)*-1); + } + } + + delete [] liquid_map; + + int indices[3], loopStart, loopEnd, loopInc, triInc; + getLoopVars(portion, loopStart, loopEnd, loopInc); + triInc = BOTTOM-TOP; + + // generate triangles + for (int i = loopStart; i < loopEnd; i+=loopInc) + for (int j = TOP; j <= BOTTOM; j+= triInc) + { + getHeightTriangle(i, Spot(j), indices, true); + ltriangles.append(indices[2] + count); + ltriangles.append(indices[1] + count); + ltriangles.append(indices[0] + count); + } + } + } + + fclose(mapFile); + + // now that we have gathered the data, we can figure out which parts to keep: + // liquid above ground, ground above liquid + int loopStart, loopEnd, loopInc, tTriCount = 4; + bool useTerrain, useLiquid; + + float* lverts = meshData.liquidVerts.getCArray(); + int* ltris = ltriangles.getCArray(); + + float* tverts = meshData.solidVerts.getCArray(); + int* ttris = ttriangles.getCArray(); + + if (ltriangles.size() + ttriangles.size() == 0) + return false; + + // make a copy of liquid vertices + // used to pad right-bottom frame due to lost vertex data at extraction + float* lverts_copy = NULL; + if (meshData.liquidVerts.size()) + { + lverts_copy = new float[meshData.liquidVerts.size()]; + memcpy(lverts_copy, lverts, sizeof(float)*meshData.liquidVerts.size()); + } + + getLoopVars(portion, loopStart, loopEnd, loopInc); + for (int i = loopStart; i < loopEnd; i+=loopInc) + { + for (int j = 0; j < 2; ++j) + { + // default is true, will change to false if needed + useTerrain = true; + useLiquid = true; + uint8 liquidType = MAP_LIQUID_TYPE_NO_WATER; + + // if there is no liquid, don't use liquid + if (!liquid_type || !meshData.liquidVerts.size() || !ltriangles.size()) + useLiquid = false; + else + { + liquidType = getLiquidType(i, liquid_type); + switch (liquidType) + { + default: + useLiquid = false; + break; + case MAP_LIQUID_TYPE_WATER: + case MAP_LIQUID_TYPE_OCEAN: + // merge different types of water + liquidType = NAV_WATER; + break; + case MAP_LIQUID_TYPE_MAGMA: + liquidType = NAV_MAGMA; + break; + case MAP_LIQUID_TYPE_SLIME: + liquidType = NAV_SLIME; + break; + case MAP_LIQUID_TYPE_DARK_WATER: + // players should not be here, so logically neither should creatures + useTerrain = false; + useLiquid = false; + break; + } + } + + // if there is no terrain, don't use terrain + if (!ttriangles.size()) + useTerrain = false; + + // while extracting ADT data we are losing right-bottom vertices + // this code adds fair approximation of lost data + if (useLiquid) + { + float quadHeight = 0; + uint32 validCount = 0; + for(uint32 idx = 0; idx < 3; idx++) + { + float h = lverts_copy[ltris[idx]*3 + 1]; + if (h != INVALID_MAP_LIQ_HEIGHT && h < INVALID_MAP_LIQ_HEIGHT_MAX) + { + quadHeight += h; + validCount++; + } + } + + // update vertex height data + if (validCount > 0 && validCount < 3) + { + quadHeight /= validCount; + for(uint32 idx = 0; idx < 3; idx++) + { + float h = lverts[ltris[idx]*3 + 1]; + if (h == INVALID_MAP_LIQ_HEIGHT || h > INVALID_MAP_LIQ_HEIGHT_MAX) + lverts[ltris[idx]*3 + 1] = quadHeight; + } + } + + // no valid vertexes - don't use this poly at all + if (validCount == 0) + useLiquid = false; + } + + // if there is a hole here, don't use the terrain + if (useTerrain) + useTerrain = !isHole(i, holes); + + // we use only one terrain kind per quad - pick higher one + if (useTerrain && useLiquid) + { + float minLLevel = INVALID_MAP_LIQ_HEIGHT_MAX; + float maxLLevel = INVALID_MAP_LIQ_HEIGHT; + for(uint32 x = 0; x < 3; x++) + { + float h = lverts[ltris[x]*3 + 1]; + if (minLLevel > h) + minLLevel = h; + + if (maxLLevel < h) + maxLLevel = h; + } + + float maxTLevel = INVALID_MAP_LIQ_HEIGHT; + float minTLevel = INVALID_MAP_LIQ_HEIGHT_MAX; + for(uint32 x = 0; x < 6; x++) + { + float h = tverts[ttris[x]*3 + 1]; + if (maxTLevel < h) + maxTLevel = h; + + if (minTLevel > h) + minTLevel = h; + } + + // terrain under the liquid? + if (minLLevel > maxTLevel) + useTerrain = false; + + //liquid under the terrain? + if (minTLevel > maxLLevel) + useLiquid = false; + } + + // store the result + if (useLiquid) + { + meshData.liquidType.append(liquidType); + for (int k = 0; k < 3; ++k) + meshData.liquidTris.append(ltris[k]); + } + + if (useTerrain) + for (int k = 0; k < 3*tTriCount/2; ++k) + meshData.solidTris.append(ttris[k]); + + // advance to next set of triangles + ltris += 3; + ttris += 3*tTriCount/2; + } + } + + if (lverts_copy) + delete [] lverts_copy; + + return meshData.solidTris.size() || meshData.liquidTris.size(); + } + + /**************************************************************************/ + void TerrainBuilder::getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v) + { + // wow coords: x, y, height + // coord is mirroed about the horizontal axes + switch (grid) + { + case GRID_V9: + coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f; + coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f; + coord[2] = v[index]; + break; + case GRID_V8: + coord[0] = (xOffset + index%(V8_SIZE)*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f; + coord[1] = (yOffset + (int)(index/(V8_SIZE))*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f; + coord[2] = v[index]; + break; + } + } + + /**************************************************************************/ + void TerrainBuilder::getHeightTriangle(int square, Spot triangle, int* indices, bool liquid/* = false*/) + { + int rowOffset = square/V8_SIZE; + if (!liquid) + switch (triangle) + { + case TOP: + indices[0] = square+rowOffset; // 0-----1 .... 128 + indices[1] = square+1+rowOffset; // |\ T /| + indices[2] = (V9_SIZE_SQ)+square; // | \ / | + break; // |L 0 R| .. 127 + case LEFT: // | / \ | + indices[0] = square+rowOffset; // |/ B \| + indices[1] = (V9_SIZE_SQ)+square; // 129---130 ... 386 + indices[2] = square+V9_SIZE+rowOffset; // |\ /| + break; // | \ / | + case RIGHT: // | 128 | .. 255 + indices[0] = square+1+rowOffset; // | / \ | + indices[1] = square+V9_SIZE+1+rowOffset; // |/ \| + indices[2] = (V9_SIZE_SQ)+square; // 258---259 ... 515 + break; + case BOTTOM: + indices[0] = (V9_SIZE_SQ)+square; + indices[1] = square+V9_SIZE+1+rowOffset; + indices[2] = square+V9_SIZE+rowOffset; + break; + default: break; + } + else + switch (triangle) + { // 0-----1 .... 128 + case TOP: // |\ | + indices[0] = square+rowOffset; // | \ T | + indices[1] = square+1+rowOffset; // | \ | + indices[2] = square+V9_SIZE+1+rowOffset; // | B \ | + break; // | \| + case BOTTOM: // 129---130 ... 386 + indices[0] = square+rowOffset; // |\ | + indices[1] = square+V9_SIZE+1+rowOffset; // | \ | + indices[2] = square+V9_SIZE+rowOffset; // | \ | + break; // | \ | + default: break; // | \| + } // 258---259 ... 515 + + } + + /**************************************************************************/ + void TerrainBuilder::getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v) + { + // wow coords: x, y, height + // coord is mirroed about the horizontal axes + coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f; + coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f; + coord[2] = v[index2]; + } + + static uint16 holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888}; + static uint16 holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; + + /**************************************************************************/ + bool TerrainBuilder::isHole(int square, const uint16 holes[16][16]) + { + int row = square / 128; + int col = square % 128; + int cellRow = row / 8; // 8 squares per cell + int cellCol = col / 8; + int holeRow = row % 8 / 2; + int holeCol = (square - (row * 128 + cellCol * 8)) / 2; + + uint16 hole = holes[cellRow][cellCol]; + + return (hole & holetab_h[holeCol] & holetab_v[holeRow]) != 0; + } + + /**************************************************************************/ + uint8 TerrainBuilder::getLiquidType(int square, const uint8 liquid_type[16][16]) + { + int row = square / 128; + int col = square % 128; + int cellRow = row / 8; // 8 squares per cell + int cellCol = col / 8; + + return liquid_type[cellRow][cellCol]; + } + + /**************************************************************************/ + bool TerrainBuilder::loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) + { + IVMapManager* vmapManager = new VMapManager2(); + int result = vmapManager->loadMap("vmaps", mapID, tileX, tileY); + bool retval = false; + + do + { + if (result == VMAP_LOAD_RESULT_ERROR) + break; + + InstanceTreeMap instanceTrees; + ((VMapManager2*)vmapManager)->getInstanceMapTree(instanceTrees); + + if (!instanceTrees[mapID]) + break; + + ModelInstance* models = NULL; + uint32 count = 0; + instanceTrees[mapID]->getModelInstances(models, count); + + if (!models) + break; + + for (uint32 i = 0; i < count; ++i) + { + ModelInstance instance = models[i]; + + // model instances exist in tree even though there are instances of that model in this tile + WorldModel* worldModel = instance.getWorldModel(); + if (!worldModel) + continue; + + // now we have a model to add to the meshdata + retval = true; + + vector groupModels; + worldModel->getGroupModels(groupModels); + + // all M2s need to have triangle indices reversed + bool isM2 = instance.name.find(".m2") != instance.name.npos || instance.name.find(".M2") != instance.name.npos; + + // transform data + float scale = instance.iScale; + G3D::Matrix3 rotation = G3D::Matrix3::fromEulerAnglesXYZ(G3D::pi()*instance.iRot.z/-180.f, G3D::pi()*instance.iRot.x/-180.f, G3D::pi()*instance.iRot.y/-180.f); + Vector3 position = instance.iPos; + position.x -= 32*GRID_SIZE; + position.y -= 32*GRID_SIZE; + + for (vector::iterator it = groupModels.begin(); it != groupModels.end(); ++it) + { + vector tempVertices; + vector transformedVertices; + vector tempTriangles; + WmoLiquid* liquid = NULL; + + (*it).getMeshData(tempVertices, tempTriangles, liquid); + + // first handle collision mesh + transform(tempVertices, transformedVertices, scale, rotation, position); + + int offset = meshData.solidVerts.size() / 3; + + copyVertices(transformedVertices, meshData.solidVerts); + copyIndices(tempTriangles, meshData.solidTris, offset, isM2); + + // now handle liquid data + if (liquid) + { + vector liqVerts; + vector liqTris; + uint32 tilesX, tilesY, vertsX, vertsY; + Vector3 corner; + liquid->getPosInfo(tilesX, tilesY, corner); + vertsX = tilesX + 1; + vertsY = tilesY + 1; + uint8* flags = liquid->GetFlagsStorage(); + float* data = liquid->GetHeightStorage(); + uint8 type = NAV_EMPTY; + + // convert liquid type to NavTerrain + switch (liquid->GetType()) + { + case 0: + case 1: + type = NAV_WATER; + break; + case 2: + type = NAV_MAGMA; + break; + case 3: + type = NAV_SLIME; + break; + } + + // 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 + + Vector3 vert; + for (uint32 x = 0; x < vertsX; ++x) + for (uint32 y = 0; y < vertsY; ++y) + { + vert = 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) + for (uint32 y = 0; y < tilesY; ++y) + 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); + } + + 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); + } + } + } + } + } + while (false); + + vmapManager->unloadMap(mapID, tileX, tileY); + delete vmapManager; + + return retval; + } + + /**************************************************************************/ + void TerrainBuilder::transform(vector &source, vector &transformedVertices, float scale, G3D::Matrix3 &rotation, Vector3 &position) + { + for (vector::iterator it = source.begin(); it != source.end(); ++it) + { + // apply tranform, then mirror along the horizontal axes + Vector3 v((*it) * rotation * scale + position); + v.x *= -1.f; + v.y *= -1.f; + transformedVertices.push_back(v); + } + } + + /**************************************************************************/ + void TerrainBuilder::copyVertices(vector &source, G3D::Array &dest) + { + for (vector::iterator it = source.begin(); it != source.end(); ++it) + { + dest.push_back((*it).y); + dest.push_back((*it).z); + dest.push_back((*it).x); + } + } + + /**************************************************************************/ + void TerrainBuilder::copyIndices(vector &source, G3D::Array &dest, int offset, bool flip) + { + if (flip) + { + for (vector::iterator it = source.begin(); it != source.end(); ++it) + { + dest.push_back((*it).idx2+offset); + dest.push_back((*it).idx1+offset); + dest.push_back((*it).idx0+offset); + } + } + else + { + for (vector::iterator it = source.begin(); it != source.end(); ++it) + { + dest.push_back((*it).idx0+offset); + dest.push_back((*it).idx1+offset); + dest.push_back((*it).idx2+offset); + } + } + } + + /**************************************************************************/ + void TerrainBuilder::copyIndices(G3D::Array &source, G3D::Array &dest, int offset) + { + int* src = source.getCArray(); + for (int32 i = 0; i < source.size(); ++i) + dest.append(src[i] + offset); + } + + /**************************************************************************/ + void TerrainBuilder::cleanVertices(G3D::Array &verts, G3D::Array &tris) + { + map vertMap; + + int* t = tris.getCArray(); + float* v = verts.getCArray(); + + // collect all the vertex indices from triangle + for (int i = 0; i < tris.size(); ++i) + { + if (vertMap.find(t[i]) != vertMap.end()) + continue; + + vertMap.insert(std::pair(t[i], 0)); + } + + // collect the vertices + G3D::Array cleanVerts; + int index, count = 0; + for (map::iterator it = vertMap.begin(); it != vertMap.end(); ++it) + { + index = (*it).first; + (*it).second = count; + cleanVerts.append(v[index*3], v[index*3+1], v[index*3+2]); + count++; + } + verts.fastClear(); + verts.append(cleanVerts); + cleanVerts.clear(); + + // update triangles to use new indices + for (int i = 0; i < tris.size(); ++i) + { + map::iterator it; + if ((it = vertMap.find(t[i])) == vertMap.end()) + continue; + + t[i] = (*it).second; + } + + vertMap.clear(); + } + + /**************************************************************************/ + void TerrainBuilder::loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char* offMeshFilePath) + { + // no meshfile input given? + if (offMeshFilePath == NULL) + return; + + FILE* fp = fopen(offMeshFilePath, "rb"); + if (!fp) + { + printf(" loadOffMeshConnections:: input file %s not found!\n", offMeshFilePath); + return; + } + + // pretty silly thing, as we parse entire file and load only the tile we need + // but we don't expect this file to be too large + char* buf = new char[512]; + while(fgets(buf, 512, fp)) + { + float p0[3], p1[3]; + int mid, tx, ty; + float size; + if (10 != sscanf(buf, "%d %d,%d (%f %f %f) (%f %f %f) %f", &mid, &tx, &ty, + &p0[0], &p0[1], &p0[2], &p1[0], &p1[1], &p1[2], &size)) + continue; + + if (mapID == mid, tileX == tx, tileY == ty) + { + meshData.offMeshConnections.append(p0[1]); + meshData.offMeshConnections.append(p0[2]); + meshData.offMeshConnections.append(p0[0]); + + meshData.offMeshConnections.append(p1[1]); + meshData.offMeshConnections.append(p1[2]); + meshData.offMeshConnections.append(p1[0]); + + meshData.offMeshConnectionDirs.append(1); // 1 - both direction, 0 - one sided + meshData.offMeshConnectionRads.append(size); // agent size equivalent + // can be used same way as polygon flags + meshData.offMeshConnectionsAreas.append((unsigned char)0xFF); + meshData.offMeshConnectionsFlags.append((unsigned short)0xFF); // all movement masks can make this path + } + + } + + delete [] buf; + fclose(fp); + } +} diff --git a/src/tools/mmap_extractor/TerrainBuilder.h b/src/tools/mmap_extractor/TerrainBuilder.h new file mode 100644 index 00000000000..a7f21883af2 --- /dev/null +++ b/src/tools/mmap_extractor/TerrainBuilder.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 MaNGOS + * + * 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 . + */ + +#ifndef _MMAP_TERRAIN_BUILDER_H +#define _MMAP_TERRAIN_BUILDER_H + +#include "PathCommon.h" +#include "Map.h" +#include "SharedDefines.h" + +#include "WorldModel.h" + +#include "G3D/Array.h" +#include "G3D/Vector3.h" +#include "G3D/Matrix3.h" + +using namespace Trinity; + +namespace MMAP +{ + enum Spot + { + TOP = 1, + RIGHT = 2, + LEFT = 3, + BOTTOM = 4, + ENTIRE = 5 + }; + + enum Grid + { + GRID_V8, + GRID_V9 + }; + + static const int V9_SIZE = 129; + static const int V9_SIZE_SQ = V9_SIZE*V9_SIZE; + static const int V8_SIZE = 128; + static const int V8_SIZE_SQ = V8_SIZE*V8_SIZE; + static const float GRID_SIZE = 533.33333f; + static const float GRID_PART_SIZE = GRID_SIZE/V8_SIZE; + + // see contrib/extractor/system.cpp, CONF_use_minHeight + static const float INVALID_MAP_LIQ_HEIGHT = -500.f; + static const float INVALID_MAP_LIQ_HEIGHT_MAX = 5000.0f; + + // see following files: + // contrib/extractor/system.cpp + // src/game/Map.cpp + static char const* MAP_VERSION_MAGIC = "v1.2"; + + struct MeshData + { + G3D::Array solidVerts; + G3D::Array solidTris; + + G3D::Array liquidVerts; + G3D::Array liquidTris; + G3D::Array liquidType; + + // offmesh connection data + G3D::Array offMeshConnections; // [p0y,p0z,p0x,p1y,p1z,p1x] - per connection + G3D::Array offMeshConnectionRads; + G3D::Array offMeshConnectionDirs; + G3D::Array offMeshConnectionsAreas; + G3D::Array offMeshConnectionsFlags; + }; + + class TerrainBuilder + { + public: + TerrainBuilder(bool skipLiquid); + ~TerrainBuilder(); + + void loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); + bool loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); + void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char* offMeshFilePath); + + bool usesLiquids() { return !m_skipLiquid; } + + // vert and triangle methods + static void transform(vector &original, vector &transformed, + float scale, G3D::Matrix3 &rotation, G3D::Vector3 &position); + static void copyVertices(vector &source, G3D::Array &dest); + static void copyIndices(vector &source, G3D::Array &dest, int offest, bool flip); + static void copyIndices(G3D::Array &src, G3D::Array &dest, int offset); + static void cleanVertices(G3D::Array &verts, G3D::Array &tris); + private: + /// Loads a portion of a map's terrain + bool loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, Spot portion); + + /// Sets loop variables for selecting only certain parts of a map's terrain + void getLoopVars(Spot portion, int &loopStart, int &loopEnd, int &loopInc); + + /// Controls whether liquids are loaded + bool m_skipLiquid; + + /// Load the map terrain from file + bool loadHeightMap(uint32 mapID, uint32 tileX, uint32 tileY, G3D::Array &vertices, G3D::Array &triangles, Spot portion); + + /// Get the vector coordinate for a specific position + void getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v); + + /// Get the triangle's vector indices for a specific position + void getHeightTriangle(int square, Spot triangle, int* indices, bool liquid = false); + + /// Determines if the specific position's triangles should be rendered + bool isHole(int square, const uint16 holes[16][16]); + + /// Get the liquid vector coordinate for a specific position + void getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v); + + /// Get the liquid type for a specific position + uint8 getLiquidType(int square, const uint8 liquid_type[16][16]); + + // hide parameterless and copy constructor + TerrainBuilder(); + TerrainBuilder(const TerrainBuilder &tb); + }; +} + +#endif + diff --git a/src/tools/mmap_extractor/VMapExtensions.cpp b/src/tools/mmap_extractor/VMapExtensions.cpp new file mode 100644 index 00000000000..4f203e11c21 --- /dev/null +++ b/src/tools/mmap_extractor/VMapExtensions.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 MaNGOS + * + * 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 . + */ + +#include +#include "MapTree.h" +#include "VMapManager2.h" +#include "WorldModel.h" +#include "ModelInstance.h" + +using namespace std; + +namespace VMAP +{ + // Need direct access to encapsulated VMAP data, so we add functions for MMAP generator + // maybe add MapBuilder as friend to all of the below classes would be better? + + // declared in src/shared/vmap/MapTree.h + void StaticMapTree::getModelInstances(ModelInstance* &models, uint32 &count) + { + models = iTreeValues; + count = iNTreeValues; + } + + // declared in src/shared/vmap/VMapManager2.h + void VMapManager2::getInstanceMapTree(InstanceTreeMap &instanceMapTree) + { + instanceMapTree = iInstanceMapTrees; + } + + // declared in src/shared/vmap/WorldModel.h + void WorldModel::getGroupModels(vector &groupModels) + { + groupModels = this->groupModels; + } + + // declared in src/shared/vmap/WorldModel.h + void GroupModel::getMeshData(vector &vertices, vector &triangles, WmoLiquid* &liquid) + { + vertices = this->vertices; + triangles = this->triangles; + liquid = iLiquid; + } + + // declared in src/shared/vmap/ModelInstance.h + WorldModel* const ModelInstance::getWorldModel() + { + return iModel; + } + + // declared in src/shared/vmap/WorldModel.h + void WmoLiquid::getPosInfo(uint32 &tilesX, uint32 &tilesY, Vector3 &corner) const + { + tilesX = iTilesX; + tilesY = iTilesY; + corner = iCorner; + } +} -- cgit v1.2.3 From 710a617a3cf7b0f59c268fd0a6396d1e6e7393ba Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 15:52:00 +0200 Subject: Core/Tools: Store hole data. --- src/tools/map_extractor/System.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src/tools') diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index bbde9f4675e..29836506861 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -292,6 +292,8 @@ struct map_fileheader uint32 heightMapSize; uint32 liquidMapOffset; uint32 liquidMapSize; + uint32 holesOffset; + uint32 holesSize; }; #define MAP_AREA_NO_AREA 0x0001 @@ -826,6 +828,28 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32 map.liquidMapSize += sizeof(float)*liquidHeader.width*liquidHeader.height; } + // map hole info + uint16 holes[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]; + + if (map.liquidMapOffset) + map.holesOffset = map.liquidMapOffset + map.liquidMapSize; + else + map.holesOffset = map.heightMapOffset + map.heightMapSize; + + map.holesSize = sizeof(holes); + memset(holes, 0, map.holesSize); + + for (int i = 0; i < ADT_CELLS_PER_GRID; ++i) + { + for (int j = 0; j < ADT_CELLS_PER_GRID; ++j) + { + adt_MCNK * cell = cells->getMCNK(i,j); + if (!cell) + continue; + holes[i][j] = cell->holes; + } + } + // Ok all data prepared - store it FILE *output=fopen(filename2, "wb"); if(!output) @@ -875,6 +899,9 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32 fwrite(&liquid_height[y+liquidHeader.offsetY][liquidHeader.offsetX], sizeof(float), liquidHeader.width, output); } } + // store hole data + fwrite(holes, map.holesSize, 1, output); + fclose(output); return true; -- cgit v1.2.3 From 2181b123ba1b45ae8725d4e06799bf3d3bee282d Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 15:55:27 +0200 Subject: Give mmap generator the correct name. --- src/tools/CMakeLists.txt | 2 +- src/tools/mmap_extractor/CMakeLists.txt | 68 -- src/tools/mmap_extractor/Info/readme.txt | 66 -- src/tools/mmap_extractor/IntermediateValues.cpp | 277 ------- src/tools/mmap_extractor/IntermediateValues.h | 53 -- src/tools/mmap_extractor/MapBuilder.cpp | 894 ----------------------- src/tools/mmap_extractor/MapBuilder.h | 129 ---- src/tools/mmap_extractor/PathCommon.h | 128 ---- src/tools/mmap_extractor/PathGenerator.cpp | 273 ------- src/tools/mmap_extractor/TerrainBuilder.cpp | 854 ---------------------- src/tools/mmap_extractor/TerrainBuilder.h | 138 ---- src/tools/mmap_extractor/VMapExtensions.cpp | 72 -- src/tools/mmaps_generator/CMakeLists.txt | 68 ++ src/tools/mmaps_generator/Info/readme.txt | 66 ++ src/tools/mmaps_generator/IntermediateValues.cpp | 277 +++++++ src/tools/mmaps_generator/IntermediateValues.h | 53 ++ src/tools/mmaps_generator/MapBuilder.cpp | 894 +++++++++++++++++++++++ src/tools/mmaps_generator/MapBuilder.h | 129 ++++ src/tools/mmaps_generator/PathCommon.h | 128 ++++ src/tools/mmaps_generator/PathGenerator.cpp | 273 +++++++ src/tools/mmaps_generator/TerrainBuilder.cpp | 854 ++++++++++++++++++++++ src/tools/mmaps_generator/TerrainBuilder.h | 138 ++++ src/tools/mmaps_generator/VMapExtensions.cpp | 72 ++ 23 files changed, 2953 insertions(+), 2953 deletions(-) delete mode 100644 src/tools/mmap_extractor/CMakeLists.txt delete mode 100644 src/tools/mmap_extractor/Info/readme.txt delete mode 100644 src/tools/mmap_extractor/IntermediateValues.cpp delete mode 100644 src/tools/mmap_extractor/IntermediateValues.h delete mode 100644 src/tools/mmap_extractor/MapBuilder.cpp delete mode 100644 src/tools/mmap_extractor/MapBuilder.h delete mode 100644 src/tools/mmap_extractor/PathCommon.h delete mode 100644 src/tools/mmap_extractor/PathGenerator.cpp delete mode 100644 src/tools/mmap_extractor/TerrainBuilder.cpp delete mode 100644 src/tools/mmap_extractor/TerrainBuilder.h delete mode 100644 src/tools/mmap_extractor/VMapExtensions.cpp create mode 100644 src/tools/mmaps_generator/CMakeLists.txt create mode 100644 src/tools/mmaps_generator/Info/readme.txt create mode 100644 src/tools/mmaps_generator/IntermediateValues.cpp create mode 100644 src/tools/mmaps_generator/IntermediateValues.h create mode 100644 src/tools/mmaps_generator/MapBuilder.cpp create mode 100644 src/tools/mmaps_generator/MapBuilder.h create mode 100644 src/tools/mmaps_generator/PathCommon.h create mode 100644 src/tools/mmaps_generator/PathGenerator.cpp create mode 100644 src/tools/mmaps_generator/TerrainBuilder.cpp create mode 100644 src/tools/mmaps_generator/TerrainBuilder.h create mode 100644 src/tools/mmaps_generator/VMapExtensions.cpp (limited to 'src/tools') diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index f4c5f695b26..2d378966aff 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -11,4 +11,4 @@ add_subdirectory(map_extractor) add_subdirectory(vmap4_assembler) add_subdirectory(vmap4_extractor) -add_subdirectory(mmaps_extractor) +add_subdirectory(mmaps_generator) diff --git a/src/tools/mmap_extractor/CMakeLists.txt b/src/tools/mmap_extractor/CMakeLists.txt deleted file mode 100644 index c7c1a954371..00000000000 --- a/src/tools/mmap_extractor/CMakeLists.txt +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (C) 2008-2011 Trinity -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -file(GLOB_RECURSE sources *.cpp *.h) - -# definitions -add_definitions(-DNO_CORE_FUNCS) -add_definitions(-DDEBUG) -add_definitions(-DNO_vsnprintf) - -include_directories( - ${CMAKE_BINARY_DIR} - ${ACE_INCLUDE_DIR} - ${MYSQL_INCLUDE_DIR} - ${CMAKE_SOURCE_DIR}/dep/libmpq - ${CMAKE_SOURCE_DIR}/dep/zlib - ${CMAKE_SOURCE_DIR}/dep/bzip2 - ${CMAKE_SOURCE_DIR}/dep/acelite - ${CMAKE_SOURCE_DIR}/dep/g3dlite/include - ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast - ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour - ${CMAKE_SOURCE_DIR}/src/server/shared - ${CMAKE_SOURCE_DIR}/src/server/shared/Database - ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation - ${CMAKE_SOURCE_DIR}/src/server/shared/Threading - ${CMAKE_SOURCE_DIR}/src/server/shared/Logging - ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference - ${CMAKE_SOURCE_DIR}/src/server/game/Maps - ${CMAKE_SOURCE_DIR}/src/server/game/DataStores - ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints - ${CMAKE_SOURCE_DIR}/src/server/game/Grids - ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Cells - ${CMAKE_SOURCE_DIR}/src/server/game/Miscellaneous - ${CMAKE_SOURCE_DIR}/src/server/game/Conditions - ${CMAKE_SOURCE_DIR}/src/server/collision - ${CMAKE_SOURCE_DIR}/src/server/collision/Management - ${CMAKE_SOURCE_DIR}/src/server/collision/Maps - ${CMAKE_SOURCE_DIR}/src/server/collision/Models -) - -add_executable(movements_extractor ${sources}) - -target_link_libraries(movements_extractor - ${MYSQL_LIBRARY} - ${ACE_LIBRARY} - ${BZIP2_LIBRARIES} - ${ZLIB_LIBRARIES} - Recast - Detour - collision - g3dlib - shared -) - -if( UNIX ) - install(TARGETS movements_extractor DESTINATION bin) -elseif( WIN32 ) - install(TARGETS movements_extractor DESTINATION "${CMAKE_INSTALL_PREFIX}") -endif() diff --git a/src/tools/mmap_extractor/Info/readme.txt b/src/tools/mmap_extractor/Info/readme.txt deleted file mode 100644 index 8d7c4f9d2e0..00000000000 --- a/src/tools/mmap_extractor/Info/readme.txt +++ /dev/null @@ -1,66 +0,0 @@ -Generator command line args - ---offMeshInput [file.*] Path to file containing off mesh connections data. - Format must be: (see offmesh_example.txt) - "map_id tile_x,tile_y (start_x start_y start_z) (end_x end_y end_z) size //optional comments" - Single mesh connection per line. - ---silent Make us script friendly. Do not wait for user input - on error or completion. - ---bigBaseUnit [true|false] Generate tile/map using bigger basic unit. - Use this option only if you have unexpected gaps. - - false: use normal metrics (default) - ---maxAngle [#] Max walkable inclination angle - - float between 45 and 90 degrees (default 60) - ---skipLiquid liquid data for maps - - false: include liquid data (default) - ---skipContinents [true|false] continents are maps 0 (Eastern Kingdoms), - 1 (Kalimdor), 530 (Outlands), 571 (Northrend) - - false: build continents (default) - ---skipJunkMaps [true|false] junk maps include some unused - maps, transport maps, and some other - - true: skip junk maps (default) - ---skipBattlegrounds [true|false] does not include PVP arenas - - false: skip battlegrounds (default) - ---debugOutput [true|false] create debugging files for use with RecastDemo - if you are only creating mmaps for use with MaNGOS, - you don't want debugging files - - false: don't create debugging files (default) - ---tile [#,#] Build the specified tile - seperate number with a comma ',' - must specify a map number (see below) - if this option is not used, all tiles are built - - [#] Build only the map specified by # - this command will build the map regardless of --skip* option settings - if you do not specify a map number, builds all maps that pass the filters specified by --skip* options - - -examples: - -movement_extractor -builds maps using the default settings (see above for defaults) - -movement_extractor --skipContinents true -builds the default maps, except continents - -movement_extractor 0 -builds all tiles of map 0 - -movement_extractor 0 --tile 34,46 -builds only tile 34,46 of map 0 (this is the southern face of blackrock mountain) \ No newline at end of file diff --git a/src/tools/mmap_extractor/IntermediateValues.cpp b/src/tools/mmap_extractor/IntermediateValues.cpp deleted file mode 100644 index 9eefb1e65f0..00000000000 --- a/src/tools/mmap_extractor/IntermediateValues.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (C) 2008-2011 TrinityCore - * Copyright (C) 2005-2011 MaNGOS - * - * 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 . - */ - -#include "IntermediateValues.h" - -namespace MMAP -{ - IntermediateValues::~IntermediateValues() - { - rcFreeCompactHeightfield(compactHeightfield); - rcFreeHeightField(heightfield); - rcFreeContourSet(contours); - rcFreePolyMesh(polyMesh); - rcFreePolyMeshDetail(polyMeshDetail); - } - - void IntermediateValues::writeIV(uint32 mapID, uint32 tileX, uint32 tileY) - { - char fileName[255]; - char tileString[25]; - sprintf(tileString, "[%02u,%02u]: ", tileX, tileY); - - printf("%sWriting debug output... \r", tileString); - - string name("meshes/%03u%02i%02i."); - -#define DEBUG_WRITE(fileExtension,data) \ - do { \ - sprintf(fileName, (name + fileExtension).c_str(), mapID, tileY, tileX); \ - FILE* file = fopen(fileName, "wb"); \ - if (!file) \ - { \ - char message[1024]; \ - sprintf(message, "%sFailed to open %s for writing!\n", tileString, fileName); \ - perror(message); \ - } \ - else \ - debugWrite(file, data); \ - if (file) fclose(file); \ - printf("%sWriting debug output... \r", tileString); \ - } while (false) - - if (heightfield) - DEBUG_WRITE("hf", heightfield); - if (compactHeightfield) - DEBUG_WRITE("chf", compactHeightfield); - if (contours) - DEBUG_WRITE("cs", contours); - if (polyMesh) - DEBUG_WRITE("pmesh", polyMesh); - if (polyMeshDetail) - DEBUG_WRITE("dmesh", polyMeshDetail); - -#undef DEBUG_WRITE - } - - void IntermediateValues::debugWrite(FILE* file, const rcHeightfield* mesh) - { - if (!file || !mesh) - return; - - fwrite(&(mesh->cs), sizeof(float), 1, file); - fwrite(&(mesh->ch), sizeof(float), 1, file); - fwrite(&(mesh->width), sizeof(int), 1, file); - fwrite(&(mesh->height), sizeof(int), 1, file); - fwrite(mesh->bmin, sizeof(float), 3, file); - fwrite(mesh->bmax, sizeof(float), 3, file); - - for (int y = 0; y < mesh->height; ++y) - for (int x = 0; x < mesh->width; ++x) - { - rcSpan* span = mesh->spans[x+y*mesh->width]; - - // first, count the number of spans - int spanCount = 0; - while (span) - { - spanCount++; - span = span->next; - } - - // write the span count - fwrite(&spanCount, sizeof(int), 1, file); - - // write the spans - span = mesh->spans[x+y*mesh->width]; - while (span) - { - fwrite(span, sizeof(rcSpan), 1, file); - span = span->next; - } - } - } - - void IntermediateValues::debugWrite(FILE* file, const rcCompactHeightfield* chf) - { - if (!file | !chf) - return; - - fwrite(&(chf->width), sizeof(chf->width), 1, file); - fwrite(&(chf->height), sizeof(chf->height), 1, file); - fwrite(&(chf->spanCount), sizeof(chf->spanCount), 1, file); - - fwrite(&(chf->walkableHeight), sizeof(chf->walkableHeight), 1, file); - fwrite(&(chf->walkableClimb), sizeof(chf->walkableClimb), 1, file); - - fwrite(&(chf->maxDistance), sizeof(chf->maxDistance), 1, file); - fwrite(&(chf->maxRegions), sizeof(chf->maxRegions), 1, file); - - fwrite(chf->bmin, sizeof(chf->bmin), 1, file); - fwrite(chf->bmax, sizeof(chf->bmax), 1, file); - - fwrite(&(chf->cs), sizeof(chf->cs), 1, file); - fwrite(&(chf->ch), sizeof(chf->ch), 1, file); - - int tmp = 0; - if (chf->cells) tmp |= 1; - if (chf->spans) tmp |= 2; - if (chf->dist) tmp |= 4; - if (chf->areas) tmp |= 8; - - fwrite(&tmp, sizeof(tmp), 1, file); - - if (chf->cells) - fwrite(chf->cells, sizeof(rcCompactCell), chf->width*chf->height, file); - if (chf->spans) - fwrite(chf->spans, sizeof(rcCompactSpan), chf->spanCount, file); - if (chf->dist) - fwrite(chf->dist, sizeof(unsigned short), chf->spanCount, file); - if (chf->areas) - fwrite(chf->areas, sizeof(unsigned char), chf->spanCount, file); - } - - void IntermediateValues::debugWrite(FILE* file, const rcContourSet* cs) - { - if (!file || !cs) - return; - - fwrite(&(cs->cs), sizeof(float), 1, file); - fwrite(&(cs->ch), sizeof(float), 1, file); - fwrite(cs->bmin, sizeof(float), 3, file); - fwrite(cs->bmax, sizeof(float), 3, file); - fwrite(&(cs->nconts), sizeof(int), 1, file); - for (int i = 0; i < cs->nconts; ++i) - { - fwrite(&cs->conts[i].area, sizeof(unsigned char), 1, file); - fwrite(&cs->conts[i].reg, sizeof(unsigned short), 1, file); - fwrite(&cs->conts[i].nverts, sizeof(int), 1, file); - fwrite(cs->conts[i].verts, sizeof(int), cs->conts[i].nverts*4, file); - fwrite(&cs->conts[i].nrverts, sizeof(int), 1, file); - fwrite(cs->conts[i].rverts, sizeof(int), cs->conts[i].nrverts*4, file); - } - } - - void IntermediateValues::debugWrite(FILE* file, const rcPolyMesh* mesh) - { - if (!file || !mesh) - return; - - fwrite(&(mesh->cs), sizeof(float), 1, file); - fwrite(&(mesh->ch), sizeof(float), 1, file); - fwrite(&(mesh->nvp), sizeof(int), 1, file); - fwrite(mesh->bmin, sizeof(float), 3, file); - fwrite(mesh->bmax, sizeof(float), 3, file); - fwrite(&(mesh->nverts), sizeof(int), 1, file); - fwrite(mesh->verts, sizeof(unsigned short), mesh->nverts*3, file); - fwrite(&(mesh->npolys), sizeof(int), 1, file); - fwrite(mesh->polys, sizeof(unsigned short), mesh->npolys*mesh->nvp*2, file); - fwrite(mesh->flags, sizeof(unsigned short), mesh->npolys, file); - fwrite(mesh->areas, sizeof(unsigned char), mesh->npolys, file); - fwrite(mesh->regs, sizeof(unsigned short), mesh->npolys, file); - } - - void IntermediateValues::debugWrite(FILE* file, const rcPolyMeshDetail* mesh) - { - if (!file || !mesh) - return; - - fwrite(&(mesh->nverts), sizeof(int), 1, file); - fwrite(mesh->verts, sizeof(float), mesh->nverts*3, file); - fwrite(&(mesh->ntris), sizeof(int), 1, file); - fwrite(mesh->tris, sizeof(char), mesh->ntris*4, file); - fwrite(&(mesh->nmeshes), sizeof(int), 1, file); - fwrite(mesh->meshes, sizeof(int), mesh->nmeshes*4, file); - } - - void IntermediateValues::generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) - { - char objFileName[255]; - sprintf(objFileName, "meshes/map%03u.obj", mapID); - - FILE* objFile = fopen(objFileName, "wb"); - if (!objFile) - { - char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", objFileName); - perror(message); - return; - } - - G3D::Array allVerts; - G3D::Array allTris; - - allTris.append(meshData.liquidTris); - allVerts.append(meshData.liquidVerts); - TerrainBuilder::copyIndices(meshData.solidTris, allTris, allVerts.size() / 3); - allVerts.append(meshData.solidVerts); - - float* verts = allVerts.getCArray(); - int vertCount = allVerts.size() / 3; - int* tris = allTris.getCArray(); - int triCount = allTris.size() / 3; - - for (int i = 0; i < allVerts.size() / 3; i++) - fprintf(objFile, "v %f %f %f\n", verts[i*3], verts[i*3 + 1], verts[i*3 + 2]); - - for (int i = 0; i < allTris.size() / 3; i++) - fprintf(objFile, "f %i %i %i\n", tris[i*3] + 1, tris[i*3 + 1] + 1, tris[i*3 + 2] + 1); - - fclose(objFile); - - - char tileString[25]; - sprintf(tileString, "[%02u,%02u]: ", tileY, tileX); - printf("%sWriting debug output... \r", tileString); - - sprintf(objFileName, "meshes/%03u.map", mapID); - - objFile = fopen(objFileName, "wb"); - if (!objFile) - { - char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", objFileName); - perror(message); - return; - } - - char b = '\0'; - fwrite(&b, sizeof(char), 1, objFile); - fclose(objFile); - - sprintf(objFileName, "meshes/%03u%02u%02u.mesh", mapID, tileY, tileX); - objFile = fopen(objFileName, "wb"); - if (!objFile) - { - char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", objFileName); - perror(message); - return; - } - - fwrite(&vertCount, sizeof(int), 1, objFile); - fwrite(verts, sizeof(float), vertCount*3, objFile); - fflush(objFile); - - fwrite(&triCount, sizeof(int), 1, objFile); - fwrite(tris, sizeof(int), triCount*3, objFile); - fflush(objFile); - - fclose(objFile); - } -} diff --git a/src/tools/mmap_extractor/IntermediateValues.h b/src/tools/mmap_extractor/IntermediateValues.h deleted file mode 100644 index a267a0f6412..00000000000 --- a/src/tools/mmap_extractor/IntermediateValues.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2008-2011 TrinityCore - * Copyright (C) 2005-2011 MaNGOS - * - * 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 . - */ - -#ifndef _INTERMEDIATE_VALUES_H -#define _INTERMEDIATE_VALUES_H - -#include "PathCommon.h" -#include "TerrainBuilder.h" -#include "Recast.h" -#include "DetourNavMesh.h" - -namespace MMAP -{ - // this class gathers all debug info holding and output - struct IntermediateValues - { - rcHeightfield* heightfield; - rcCompactHeightfield* compactHeightfield; - rcContourSet* contours; - rcPolyMesh* polyMesh; - rcPolyMeshDetail* polyMeshDetail; - - IntermediateValues() : compactHeightfield(NULL), heightfield(NULL), - contours(NULL), polyMesh(NULL), polyMeshDetail(NULL) {} - ~IntermediateValues(); - - void writeIV(uint32 mapID, uint32 tileX, uint32 tileY); - - void debugWrite(FILE* file, const rcHeightfield* mesh); - void debugWrite(FILE* file, const rcCompactHeightfield* chf); - void debugWrite(FILE* file, const rcContourSet* cs); - void debugWrite(FILE* file, const rcPolyMesh* mesh); - void debugWrite(FILE* file, const rcPolyMeshDetail* mesh); - - void generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); - }; -} -#endif diff --git a/src/tools/mmap_extractor/MapBuilder.cpp b/src/tools/mmap_extractor/MapBuilder.cpp deleted file mode 100644 index 3ca158f0127..00000000000 --- a/src/tools/mmap_extractor/MapBuilder.cpp +++ /dev/null @@ -1,894 +0,0 @@ -/* - * Copyright (C) 2008-2011 TrinityCore - * Copyright (C) 2005-2011 MaNGOS - * - * 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 . - */ - -#include "PathCommon.h" -#include "MapBuilder.h" - -#include "MapTree.h" -#include "ModelInstance.h" -#include "LoginDatabase.h" - -#include "DetourNavMeshBuilder.h" -#include "DetourCommon.h" - -// These make the linker happy. -LoginDatabaseWorkerPool LoginDatabase; -#include "DisableMgr.h" -namespace DisableMgr -{ - bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags) - { - return 0; - } -} - -using namespace VMAP; - -namespace MMAP -{ - MapBuilder::MapBuilder(float maxWalkableAngle, bool skipLiquid, - bool skipContinents, bool skipJunkMaps, bool skipBattlegrounds, - bool debugOutput, bool bigBaseUnit, const char* offMeshFilePath) : - m_terrainBuilder(NULL), - m_debugOutput (debugOutput), - m_skipContinents (skipContinents), - m_skipJunkMaps (skipJunkMaps), - m_skipBattlegrounds (skipBattlegrounds), - m_maxWalkableAngle (maxWalkableAngle), - m_bigBaseUnit (bigBaseUnit), - m_rcContext (NULL), - m_offMeshFilePath (offMeshFilePath) - { - m_terrainBuilder = new TerrainBuilder(skipLiquid); - - m_rcContext = new rcContext(false); - - discoverTiles(); - } - - /**************************************************************************/ - MapBuilder::~MapBuilder() - { - for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) - { - (*it).second->clear(); - delete (*it).second; - } - - delete m_terrainBuilder; - delete m_rcContext; - } - - /**************************************************************************/ - void MapBuilder::discoverTiles() - { - vector files; - uint32 mapID, tileX, tileY, tileID, count = 0; - char filter[12]; - - printf("Discovering maps... "); - getDirContents(files, "maps"); - for (uint32 i = 0; i < files.size(); ++i) - { - mapID = uint32(atoi(files[i].substr(0,3).c_str())); - if (m_tiles.find(mapID) == m_tiles.end()) - { - m_tiles.insert(pair*>(mapID, new set)); - count++; - } - } - - files.clear(); - getDirContents(files, "vmaps", "*.vmtree"); - for (uint32 i = 0; i < files.size(); ++i) - { - mapID = uint32(atoi(files[i].substr(0,3).c_str())); - m_tiles.insert(pair*>(mapID, new set)); - count++; - } - printf("found %u.\n", count); - - count = 0; - printf("Discovering tiles... "); - for (TileList::iterator itr = m_tiles.begin(); itr != m_tiles.end(); ++itr) - { - set* tiles = (*itr).second; - mapID = (*itr).first; - - sprintf(filter, "%03u*.vmtile", mapID); - files.clear(); - getDirContents(files, "vmaps", filter); - for (uint32 i = 0; i < files.size(); ++i) - { - tileX = uint32(atoi(files[i].substr(7,2).c_str())); - tileY = uint32(atoi(files[i].substr(4,2).c_str())); - tileID = StaticMapTree::packTileID(tileY, tileX); - - tiles->insert(tileID); - count++; - } - - sprintf(filter, "%03u*", mapID); - files.clear(); - getDirContents(files, "maps", filter); - for (uint32 i = 0; i < files.size(); ++i) - { - tileY = uint32(atoi(files[i].substr(3,2).c_str())); - tileX = uint32(atoi(files[i].substr(5,2).c_str())); - tileID = StaticMapTree::packTileID(tileX, tileY); - - if (tiles->insert(tileID).second) - count++; - } - } - printf("found %u.\n\n", count); - } - - /**************************************************************************/ - set* MapBuilder::getTileList(uint32 mapID) - { - TileList::iterator itr = m_tiles.find(mapID); - if (itr != m_tiles.end()) - return (*itr).second; - - set* tiles = new set(); - m_tiles.insert(pair*>(mapID, tiles)); - return tiles; - } - - /**************************************************************************/ - void MapBuilder::buildAllMaps() - { - for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) - { - uint32 mapID = (*it).first; - if (!shouldSkipMap(mapID)) - buildMap(mapID); - } - } - - /**************************************************************************/ - void MapBuilder::getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY) - { - maxX = INT_MAX; - maxY = INT_MAX; - minX = INT_MIN; - minY = INT_MIN; - - float bmin[3], bmax[3], lmin[3], lmax[3]; - MeshData meshData; - - // make sure we process maps which don't have tiles - // initialize the static tree, which loads WDT models - if (!m_terrainBuilder->loadVMap(mapID, 64, 64, meshData)) - return; - - // get the coord bounds of the model data - if (meshData.solidVerts.size() + meshData.liquidVerts.size() == 0) - return; - - // get the coord bounds of the model data - if (meshData.solidVerts.size() && meshData.liquidVerts.size()) - { - rcCalcBounds(meshData.solidVerts.getCArray(), meshData.solidVerts.size() / 3, bmin, bmax); - rcCalcBounds(meshData.liquidVerts.getCArray(), meshData.liquidVerts.size() / 3, lmin, lmax); - rcVmin(bmin, lmin); - rcVmax(bmax, lmax); - } - else if (meshData.solidVerts.size()) - rcCalcBounds(meshData.solidVerts.getCArray(), meshData.solidVerts.size() / 3, bmin, bmax); - else - rcCalcBounds(meshData.liquidVerts.getCArray(), meshData.liquidVerts.size() / 3, lmin, lmax); - - // convert coord bounds to grid bounds - maxX = 32 - bmin[0] / GRID_SIZE; - maxY = 32 - bmin[2] / GRID_SIZE; - minX = 32 - bmax[0] / GRID_SIZE; - minY = 32 - bmax[2] / GRID_SIZE; - } - - /**************************************************************************/ - void MapBuilder::buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY) - { - dtNavMesh* navMesh = NULL; - buildNavMesh(mapID, navMesh); - if (!navMesh) - { - printf("Failed creating navmesh! \n"); - return; - } - - buildTile(mapID, tileX, tileY, navMesh); - dtFreeNavMesh(navMesh); - } - - /**************************************************************************/ - void MapBuilder::buildMap(uint32 mapID) - { - printf("Building map %03u:\n", mapID); - - set* tiles = getTileList(mapID); - - // make sure we process maps which don't have tiles - if (!tiles->size()) - { - // convert coord bounds to grid bounds - 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) - tiles->insert(StaticMapTree::packTileID(i, j)); - } - - if (!tiles->size()) - return; - - // build navMesh - dtNavMesh* navMesh = NULL; - buildNavMesh(mapID, navMesh); - if (!navMesh) - { - printf("Failed creating navmesh! \n"); - return; - } - - // now start building mmtiles for each tile - printf("We have %u tiles. \n", (unsigned int)tiles->size()); - for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) - { - uint32 tileX, tileY; - - // unpack tile coords - StaticMapTree::unpackTileID((*it), tileX, tileY); - - if (shouldSkipTile(mapID, tileX, tileY)) - continue; - - buildTile(mapID, tileX, tileY, navMesh); - } - - dtFreeNavMesh(navMesh); - - printf("Complete! \n\n"); - } - - /**************************************************************************/ - void MapBuilder::buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh) - { - printf("Building map %03u, tile [%02u,%02u]\n", mapID, tileX, tileY); - - MeshData meshData; - - // get heightmap data - m_terrainBuilder->loadMap(mapID, tileX, tileY, meshData); - - // get model data - m_terrainBuilder->loadVMap(mapID, tileY, tileX, meshData); - - // if there is no data, give up now - if (!meshData.solidVerts.size() && !meshData.liquidVerts.size()) - return; - - // remove unused vertices - TerrainBuilder::cleanVertices(meshData.solidVerts, meshData.solidTris); - TerrainBuilder::cleanVertices(meshData.liquidVerts, meshData.liquidTris); - - // gather all mesh data for final data check, and bounds calculation - G3D::Array allVerts; - allVerts.append(meshData.liquidVerts); - allVerts.append(meshData.solidVerts); - - if (!allVerts.size()) - return; - - // get bounds of current tile - float bmin[3], bmax[3]; - getTileBounds(tileX, tileY, allVerts.getCArray(), allVerts.size() / 3, bmin, bmax); - - m_terrainBuilder->loadOffMeshConnections(mapID, tileX, tileY, meshData, m_offMeshFilePath); - - // build navmesh tile - buildMoveMapTile(mapID, tileX, tileY, meshData, bmin, bmax, navMesh); - } - - /**************************************************************************/ - void MapBuilder::buildNavMesh(uint32 mapID, dtNavMesh* &navMesh) - { - set* tiles = getTileList(mapID); - - // old code for non-statically assigned bitmask sizes: - ///*** calculate number of bits needed to store tiles & polys ***/ - //int tileBits = dtIlog2(dtNextPow2(tiles->size())); - //if (tileBits < 1) tileBits = 1; // need at least one bit! - //int polyBits = sizeof(dtPolyRef)*8 - SALT_MIN_BITS - tileBits; - - int tileBits = STATIC_TILE_BITS; - int polyBits = STATIC_POLY_BITS; - - int maxTiles = tiles->size(); - int maxPolysPerTile = 1 << polyBits; - - /*** calculate bounds of map ***/ - - uint32 tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0, tileX, tileY; - for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) - { - StaticMapTree::unpackTileID((*it), tileX, tileY); - - if (tileX > tileXMax) - tileXMax = tileX; - else if (tileX < tileXMin) - tileXMin = tileX; - - if (tileY > tileYMax) - tileYMax = tileY; - else if (tileY < tileYMin) - tileYMin = tileY; - } - - // use Max because '32 - tileX' is negative for values over 32 - float bmin[3], bmax[3]; - getTileBounds(tileXMax, tileYMax, NULL, 0, bmin, bmax); - - /*** now create the navmesh ***/ - - // navmesh creation params - dtNavMeshParams navMeshParams; - memset(&navMeshParams, 0, sizeof(dtNavMeshParams)); - navMeshParams.tileWidth = GRID_SIZE; - navMeshParams.tileHeight = GRID_SIZE; - rcVcopy(navMeshParams.orig, bmin); - navMeshParams.maxTiles = maxTiles; - navMeshParams.maxPolys = maxPolysPerTile; - - navMesh = dtAllocNavMesh(); - printf("Creating navMesh... \r"); - if (!navMesh->init(&navMeshParams)) - { - printf("Failed creating navmesh! \n"); - return; - } - - char fileName[25]; - sprintf(fileName, "mmaps/%03u.mmap", mapID); - - FILE* file = fopen(fileName, "wb"); - if (!file) - { - dtFreeNavMesh(navMesh); - char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", fileName); - perror(message); - return; - } - - // now that we know navMesh params are valid, we can write them to file - fwrite(&navMeshParams, sizeof(dtNavMeshParams), 1, file); - fclose(file); - } - - /**************************************************************************/ - void MapBuilder::buildMoveMapTile(uint32 mapID, uint32 tileX, uint32 tileY, - MeshData &meshData, float bmin[3], float bmax[3], - dtNavMesh* navMesh) - { - // console output - char tileString[10]; - sprintf(tileString, "[%02i,%02i]: ", tileX, tileY); - printf("%s Building movemap tiles... \r", tileString); - - IntermediateValues iv; - - float* tVerts = meshData.solidVerts.getCArray(); - int tVertCount = meshData.solidVerts.size() / 3; - int* tTris = meshData.solidTris.getCArray(); - int tTriCount = meshData.solidTris.size() / 3; - - float* lVerts = meshData.liquidVerts.getCArray(); - int lVertCount = meshData.liquidVerts.size() / 3; - int* lTris = meshData.liquidTris.getCArray(); - int lTriCount = meshData.liquidTris.size() / 3; - uint8* lTriFlags = meshData.liquidType.getCArray(); - - // these are WORLD UNIT based metrics - // this are basic unit dimentions - // value have to divide GRID_SIZE(533.33333f) ( aka: 0.5333, 0.2666, 0.3333, 0.1333, etc ) - const static float BASE_UNIT_DIM = m_bigBaseUnit ? 0.533333f : 0.266666f; - - // All are in UNIT metrics! - const static int VERTEX_PER_MAP = int(GRID_SIZE/BASE_UNIT_DIM + 0.5f); - const static int VERTEX_PER_TILE = m_bigBaseUnit ? 40 : 80; // must divide VERTEX_PER_MAP - const static int TILES_PER_MAP = VERTEX_PER_MAP/VERTEX_PER_TILE; - - rcConfig config; - memset(&config, 0, sizeof(rcConfig)); - - rcVcopy(config.bmin, bmin); - rcVcopy(config.bmax, bmax); - - config.maxVertsPerPoly = DT_VERTS_PER_POLYGON; - config.cs = BASE_UNIT_DIM; - config.ch = BASE_UNIT_DIM; - config.walkableSlopeAngle = m_maxWalkableAngle; - config.tileSize = VERTEX_PER_TILE; - config.walkableRadius = m_bigBaseUnit ? 1 : 2; - config.borderSize = config.walkableRadius + 3; - config.maxEdgeLen = VERTEX_PER_TILE + 1; //anything bigger than tileSize - config.walkableHeight = m_bigBaseUnit ? 3 : 6; - config.walkableClimb = m_bigBaseUnit ? 2 : 4; // keep less than walkableHeight - config.minRegionArea = rcSqr(60); - config.mergeRegionArea = rcSqr(50); - config.maxSimplificationError = 2.0f; // eliminates most jagged edges (tinny polygons) - config.detailSampleDist = config.cs * 64; - config.detailSampleMaxError = config.ch * 2; - - // this sets the dimensions of the heightfield - should maybe happen before border padding - rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height); - - // allocate subregions : tiles - Tile* tiles = new Tile[TILES_PER_MAP * TILES_PER_MAP]; - - // Initialize per tile config. - rcConfig tileCfg; - memcpy(&tileCfg, &config, sizeof(rcConfig)); - tileCfg.width = config.tileSize + config.borderSize*2; - tileCfg.height = config.tileSize + config.borderSize*2; - - // build all tiles - for (int y = 0; y < TILES_PER_MAP; ++y) - { - for (int x = 0; x < TILES_PER_MAP; ++x) - { - Tile& tile = tiles[x + y*TILES_PER_MAP]; - - // Calculate the per tile bounding box. - tileCfg.bmin[0] = config.bmin[0] + (x*config.tileSize - config.borderSize)*config.cs; - tileCfg.bmin[2] = config.bmin[2] + (y*config.tileSize - config.borderSize)*config.cs; - tileCfg.bmax[0] = config.bmin[0] + ((x+1)*config.tileSize + config.borderSize)*config.cs; - tileCfg.bmax[2] = config.bmin[2] + ((y+1)*config.tileSize + config.borderSize)*config.cs; - - float tbmin[2], tbmax[2]; - tbmin[0] = tileCfg.bmin[0]; - tbmin[1] = tileCfg.bmin[2]; - tbmax[0] = tileCfg.bmax[0]; - tbmax[1] = tileCfg.bmax[2]; - - // build heightfield - tile.solid = rcAllocHeightfield(); - if (!tile.solid || !rcCreateHeightfield(m_rcContext, *tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch)) - { - printf("%sFailed building heightfield! \n", tileString); - continue; - } - - // mark all walkable tiles, both liquids and solids - unsigned char* triFlags = new unsigned char[tTriCount]; - memset(triFlags, NAV_GROUND, tTriCount*sizeof(unsigned char)); - rcClearUnwalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags); - rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.solid, config.walkableClimb); - delete [] triFlags; - - rcFilterLowHangingWalkableObstacles(m_rcContext, config.walkableClimb, *tile.solid); - rcFilterLedgeSpans(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid); - rcFilterWalkableLowHeightSpans(m_rcContext, tileCfg.walkableHeight, *tile.solid); - - rcRasterizeTriangles(m_rcContext, lVerts, lVertCount, lTris, lTriFlags, lTriCount, *tile.solid, config.walkableClimb); - - // compact heightfield spans - tile.chf = rcAllocCompactHeightfield(); - if (!tile.chf || !rcBuildCompactHeightfield(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid, *tile.chf)) - { - printf("%sFailed compacting heightfield! \n", tileString); - continue; - } - - // build polymesh intermediates - if (!rcErodeWalkableArea(m_rcContext, config.walkableRadius, *tile.chf)) - { - printf("%sFailed eroding area! \n", tileString); - continue; - } - - if (!rcBuildDistanceField(m_rcContext, *tile.chf)) - { - printf("%sFailed building distance field! \n", tileString); - continue; - } - - if (!rcBuildRegions(m_rcContext, *tile.chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea)) - { - printf("%sFailed building regions! \n", tileString); - continue; - } - - tile.cset = rcAllocContourSet(); - if (!tile.cset || !rcBuildContours(m_rcContext, *tile.chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *tile.cset)) - { - printf("%sFailed building contours! \n", tileString); - continue; - } - - // build polymesh - tile.pmesh = rcAllocPolyMesh(); - if (!tile.pmesh || !rcBuildPolyMesh(m_rcContext, *tile.cset, tileCfg.maxVertsPerPoly, *tile.pmesh)) - { - printf("%sFailed building polymesh! \n", tileString); - continue; - } - - tile.dmesh = rcAllocPolyMeshDetail(); - if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg .detailSampleMaxError, *tile.dmesh)) - { - printf("%sFailed building polymesh detail! \n", tileString); - continue; - } - - // free those up - // we may want to keep them in the future for debug - // but right now, we don't have the code to merge them - rcFreeHeightField(tile.solid); - tile.solid = NULL; - rcFreeCompactHeightfield(tile.chf); - tile.chf = NULL; - rcFreeContourSet(tile.cset); - tile.cset = NULL; - } - } - - // merge per tile poly and detail meshes - rcPolyMesh** pmmerge = new rcPolyMesh*[TILES_PER_MAP * TILES_PER_MAP]; - if (!pmmerge) - { - printf("%s alloc pmmerge FIALED! \r", tileString); - return; - } - - rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP]; - if (!dmmerge) - { - printf("%s alloc dmmerge FIALED! \r", tileString); - return; - } - - int nmerge = 0; - for (int y = 0; y < TILES_PER_MAP; ++y) - { - for (int x = 0; x < TILES_PER_MAP; ++x) - { - Tile& tile = tiles[x + y*TILES_PER_MAP]; - if (tile.pmesh) - { - pmmerge[nmerge] = tile.pmesh; - dmmerge[nmerge] = tile.dmesh; - nmerge++; - } - } - } - - iv.polyMesh = rcAllocPolyMesh(); - if (!iv.polyMesh) - { - printf("%s alloc iv.polyMesh FIALED! \r", tileString); - return; - } - rcMergePolyMeshes(m_rcContext, pmmerge, nmerge, *iv.polyMesh); - - iv.polyMeshDetail = rcAllocPolyMeshDetail(); - if (!iv.polyMeshDetail) - { - printf("%s alloc m_dmesh FIALED! \r", tileString); - return; - } - rcMergePolyMeshDetails(m_rcContext, dmmerge, nmerge, *iv.polyMeshDetail); - - // free things up - delete [] pmmerge; - delete [] dmmerge; - - delete [] tiles; - - // remove padding for extraction - 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; - } - - // set polygons as walkable - // TODO: special flags for DYNAMIC polygons, ie surfaces that can be turned on and off - for (int i = 0; i < iv.polyMesh->npolys; ++i) - if (iv.polyMesh->areas[i] & RC_WALKABLE_AREA) - iv.polyMesh->flags[i] = iv.polyMesh->areas[i]; - - // setup mesh parameters - dtNavMeshCreateParams params; - memset(¶ms, 0, sizeof(params)); - params.verts = iv.polyMesh->verts; - params.vertCount = iv.polyMesh->nverts; - params.polys = iv.polyMesh->polys; - params.polyAreas = iv.polyMesh->areas; - params.polyFlags = iv.polyMesh->flags; - params.polyCount = iv.polyMesh->npolys; - params.nvp = iv.polyMesh->nvp; - params.detailMeshes = iv.polyMeshDetail->meshes; - params.detailVerts = iv.polyMeshDetail->verts; - params.detailVertsCount = iv.polyMeshDetail->nverts; - params.detailTris = iv.polyMeshDetail->tris; - params.detailTriCount = iv.polyMeshDetail->ntris; - - params.offMeshConVerts = meshData.offMeshConnections.getCArray(); - params.offMeshConCount = meshData.offMeshConnections.size()/6; - params.offMeshConRad = meshData.offMeshConnectionRads.getCArray(); - params.offMeshConDir = meshData.offMeshConnectionDirs.getCArray(); - params.offMeshConAreas = meshData.offMeshConnectionsAreas.getCArray(); - params.offMeshConFlags = meshData.offMeshConnectionsFlags.getCArray(); - - params.walkableHeight = BASE_UNIT_DIM*config.walkableHeight; // agent height - params.walkableRadius = BASE_UNIT_DIM*config.walkableRadius; // agent radius - params.walkableClimb = BASE_UNIT_DIM*config.walkableClimb; // keep less that walkableHeight (aka agent height)! - params.tileX = (((bmin[0] + bmax[0]) / 2) - navMesh->getParams()->orig[0]) / GRID_SIZE; - params.tileY = (((bmin[2] + bmax[2]) / 2) - navMesh->getParams()->orig[2]) / GRID_SIZE; - rcVcopy(params.bmin, bmin); - rcVcopy(params.bmax, bmax); - params.cs = config.cs; - params.ch = config.ch; - params.tileSize = VERTEX_PER_MAP; - - // will hold final navmesh - unsigned char* navData = NULL; - int navDataSize = 0; - - do - { - // these values are checked within dtCreateNavMeshData - handle them here - // so we have a clear error message - if (params.nvp > DT_VERTS_PER_POLYGON) - { - printf("%s Invalid verts-per-polygon value! \n", tileString); - continue; - } - if (params.vertCount >= 0xffff) - { - printf("%s Too many vertices! \n", tileString); - continue; - } - 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 - //printf("%sNo vertices to build tile! \n", tileString); - continue; - } - if (!params.polyCount || !params.polys || - TILES_PER_MAP*TILES_PER_MAP == params.polyCount) - { - // 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 - // drop tiles with only exact count - some tiles may have geometry while having less tiles - printf("%s No polygons to build on tile! \n", tileString); - continue; - } - if (!params.detailMeshes || !params.detailVerts || !params.detailTris) - { - printf("%s No detail mesh to build tile! \n", tileString); - continue; - } - - printf("%s Building navmesh tile... \r", tileString); - if (!dtCreateNavMeshData(¶ms, &navData, &navDataSize)) - { - printf("%s Failed building navmesh tile! \n", tileString); - continue; - } - - dtTileRef tileRef = 0; - printf("%s Adding tile to navmesh... \r", 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 || dtResult != DT_SUCCESS) - { - printf("%s Failed adding tile to navmesh! \n", tileString); - continue; - } - - // file output - char fileName[255]; - sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); - FILE* file = fopen(fileName, "wb"); - if (!file) - { - char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", fileName); - perror(message); - navMesh->removeTile(tileRef, NULL, NULL); - continue; - } - - printf("%s Writing to file... \r", tileString); - - // write header - MmapTileHeader header; - header.usesLiquids = m_terrainBuilder->usesLiquids(); - header.size = uint32(navDataSize); - fwrite(&header, sizeof(MmapTileHeader), 1, file); - - // write data - fwrite(navData, sizeof(unsigned char), navDataSize, file); - fclose(file); - - // now that tile is written to disk, we can unload it - navMesh->removeTile(tileRef, NULL, NULL); - } - while (0); - - if (m_debugOutput) - { - // 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; - } - - iv.generateObjFile(mapID, tileX, tileY, meshData); - iv.writeIV(mapID, tileX, tileY); - } - } - - /**************************************************************************/ - void MapBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) - { - // this is for elevation - if (verts && vertCount) - rcCalcBounds(verts, vertCount, bmin, bmax); - else - { - bmin[1] = FLT_MIN; - bmax[1] = FLT_MAX; - } - - // this is for width and depth - bmax[0] = (32 - int(tileX)) * GRID_SIZE; - bmax[2] = (32 - int(tileY)) * GRID_SIZE; - bmin[0] = bmax[0] - GRID_SIZE; - bmin[2] = bmax[2] - GRID_SIZE; - } - - /**************************************************************************/ - bool MapBuilder::shouldSkipMap(uint32 mapID) - { - if (m_skipContinents) - switch (mapID) - { - case 0: - case 1: - case 530: - case 571: - return true; - default: - break; - } - - if (m_skipJunkMaps) - switch (mapID) - { - case 13: // test.wdt - case 25: // ScottTest.wdt - case 29: // Test.wdt - case 42: // Colin.wdt - case 169: // EmeraldDream.wdt (unused, and very large) - case 451: // development.wdt - case 573: // ExteriorTest.wdt - case 597: // CraigTest.wdt - case 605: // development_nonweighted.wdt - case 606: // QA_DVD.wdt - return true; - default: - if (isTransportMap(mapID)) - return true; - break; - } - - if (m_skipBattlegrounds) - switch (mapID) - { - case 30: // AV - case 37: // ? - case 489: // WSG - case 529: // AB - case 566: // EotS - case 607: // SotA - case 628: // IoC - return true; - default: - break; - } - - return false; - } - - /**************************************************************************/ - bool MapBuilder::isTransportMap(uint32 mapID) - { - switch (mapID) - { - // transport maps - case 582: - case 584: - case 586: - case 587: - case 588: - case 589: - case 590: - case 591: - case 592: - case 593: - case 594: - case 596: - case 610: - case 612: - case 613: - case 614: - case 620: - case 621: - case 622: - case 623: - case 641: - case 642: - case 647: - case 672: - case 673: - case 712: - case 713: - case 718: - return true; - default: - return false; - } - } - - /**************************************************************************/ - bool MapBuilder::shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY) - { - char fileName[255]; - sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); - FILE* file = fopen(fileName, "rb"); - if (!file) - return false; - - MmapTileHeader header; - fread(&header, sizeof(MmapTileHeader), 1, file); - fclose(file); - - if (header.mmapMagic != MMAP_MAGIC || header.dtVersion != DT_NAVMESH_VERSION) - return false; - - if (header.mmapVersion != MMAP_VERSION) - return false; - - return true; - } - -} diff --git a/src/tools/mmap_extractor/MapBuilder.h b/src/tools/mmap_extractor/MapBuilder.h deleted file mode 100644 index d0f33ce9a79..00000000000 --- a/src/tools/mmap_extractor/MapBuilder.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2008-2011 TrinityCore - * Copyright (C) 2005-2011 MaNGOS - * - * 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 . - */ - -#ifndef _MAP_BUILDER_H -#define _MAP_BUILDER_H - -#include -#include -#include - -#include "TerrainBuilder.h" -#include "IntermediateValues.h" - -#include "IVMapManager.h" -#include "WorldModel.h" - -#include "Recast.h" -#include "DetourNavMesh.h" - -using namespace std; -using namespace VMAP; - -// G3D namespace typedefs conflicts with ACE typedefs - -namespace MMAP -{ - typedef map*> TileList; - struct Tile - { - Tile() : chf(NULL), solid(NULL), cset(NULL), pmesh(NULL), dmesh(NULL) {} - ~Tile() - { - rcFreeCompactHeightfield(chf); - rcFreeContourSet(cset); - rcFreeHeightField(solid); - rcFreePolyMesh(pmesh); - rcFreePolyMeshDetail(dmesh); - } - rcCompactHeightfield* chf; - rcHeightfield* solid; - rcContourSet* cset; - rcPolyMesh* pmesh; - rcPolyMeshDetail* dmesh; - }; - - class MapBuilder - { - public: - MapBuilder(float maxWalkableAngle = 60.f, - bool skipLiquid = false, - bool skipContinents = false, - bool skipJunkMaps = true, - bool skipBattlegrounds = false, - bool debugOutput = false, - bool bigBaseUnit = false, - const char* offMeshFilePath = NULL); - - ~MapBuilder(); - - // builds all mmap tiles for the specified map id (ignores skip settings) - void buildMap(uint32 mapID); - - // builds an mmap tile for the specified map and its mesh - void buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY); - - // builds list of maps, then builds all of mmap tiles (based on the skip settings) - void buildAllMaps(); - - private: - // detect maps and tiles - void discoverTiles(); - set* getTileList(uint32 mapID); - - void buildNavMesh(uint32 mapID, dtNavMesh* &navMesh); - - void buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh); - - // move map building - void buildMoveMapTile(uint32 mapID, - uint32 tileX, - uint32 tileY, - MeshData &meshData, - float bmin[3], - float bmax[3], - dtNavMesh* navMesh); - - void getTileBounds(uint32 tileX, uint32 tileY, - float* verts, int vertCount, - float* bmin, float* bmax); - void getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY); - - bool shouldSkipMap(uint32 mapID); - bool isTransportMap(uint32 mapID); - bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY); - - TerrainBuilder* m_terrainBuilder; - TileList m_tiles; - - bool m_debugOutput; - - const char* m_offMeshFilePath; - bool m_skipContinents; - bool m_skipJunkMaps; - bool m_skipBattlegrounds; - - float m_maxWalkableAngle; - bool m_bigBaseUnit; - - // build performance - not really used for now - rcContext* m_rcContext; - }; -} - -#endif diff --git a/src/tools/mmap_extractor/PathCommon.h b/src/tools/mmap_extractor/PathCommon.h deleted file mode 100644 index fd02ec02d50..00000000000 --- a/src/tools/mmap_extractor/PathCommon.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2008-2011 TrinityCore - * Copyright (C) 2005-2011 MaNGOS - * - * 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 . - */ - -#ifndef _MMAP_COMMON_H -#define _MMAP_COMMON_H - -#include -#include - -#include "Define.h" - -#ifndef _WIN32 - #include - #include -#endif - -#ifdef __linux__ - #include -#endif - -using namespace std; - -namespace MMAP -{ - inline bool matchWildcardFilter(const char* filter, const char* str) - { - if (!filter || !str) - return false; - - // end on null character - while (*filter && *str) - { - if (*filter == '*') - { - if (*++filter == '\0') // wildcard at end of filter means all remaing chars match - return true; - - while (true) - { - if (*filter == *str) - break; - if (*str == '\0') - return false; // reached end of string without matching next filter character - str++; - } - } - else if (*filter != *str) - return false; // mismatch - - filter++; - str++; - } - - return ((*filter == '\0' || (*filter == '*' && *++filter == '\0')) && *str == '\0'); - } - - enum ListFilesResult - { - LISTFILE_DIRECTORY_NOT_FOUND = 0, - LISTFILE_OK = 1 - }; - - inline ListFilesResult getDirContents(vector &fileList, string dirpath = ".", string filter = "*", bool includeSubDirs = false) - { - #ifdef WIN32 - HANDLE hFind; - WIN32_FIND_DATA findFileInfo; - string directory; - - directory = dirpath + "/" + filter; - - hFind = FindFirstFile(directory.c_str(), &findFileInfo); - - if (hFind == INVALID_HANDLE_VALUE) - return LISTFILE_DIRECTORY_NOT_FOUND; - do - { - if (includeSubDirs || (findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) - fileList.push_back(string(findFileInfo.cFileName)); - } - while (FindNextFile(hFind, &findFileInfo)); - - FindClose(hFind); - - #else - const char *p = dirpath.c_str(); - DIR * dirp = opendir(p); - struct dirent * dp; - dirp = opendir(p); - - while (dirp) - { - errno = 0; - if ((dp = readdir(dirp)) != NULL) - { - if (matchWildcardFilter(filter.c_str(), dp->d_name)) - fileList.push_back(string(dp->d_name)); - } - else - break; - } - - if (dirp) - closedir(dirp); - else - return LISTFILE_DIRECTORY_NOT_FOUND; - #endif - - return LISTFILE_OK; - } -} - -#endif diff --git a/src/tools/mmap_extractor/PathGenerator.cpp b/src/tools/mmap_extractor/PathGenerator.cpp deleted file mode 100644 index 2eb2c6545c4..00000000000 --- a/src/tools/mmap_extractor/PathGenerator.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2005-2011 MaNGOS - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "PathCommon.h" -#include "MapBuilder.h" - -using namespace MMAP; - -bool checkDirectories(bool debugOutput) -{ - vector dirFiles; - - if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size()) - { - printf("'maps' directory is empty or does not exist\n"); - return false; - } - - dirFiles.clear(); - if (getDirContents(dirFiles, "vmaps", "*.vmtree") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size()) - { - printf("'vmaps' directory is empty or does not exist\n"); - return false; - } - - dirFiles.clear(); - if (getDirContents(dirFiles, "mmaps") == LISTFILE_DIRECTORY_NOT_FOUND) - { - printf("'mmaps' directory does not exist\n"); - return false; - } - - dirFiles.clear(); - if (debugOutput) - { - if (getDirContents(dirFiles, "meshes") == LISTFILE_DIRECTORY_NOT_FOUND) - { - printf("'meshes' directory does not exist (no place to put debugOutput files)\n"); - return false; - } - } - - return true; -} - -bool handleArgs(int argc, char** argv, - int &mapnum, - int &tileX, - int &tileY, - float &maxAngle, - bool &skipLiquid, - bool &skipContinents, - bool &skipJunkMaps, - bool &skipBattlegrounds, - bool &debugOutput, - bool &silent, - bool &bigBaseUnit, - char* &offMeshInputPath) -{ - char* param = NULL; - for (int i = 1; i < argc; ++i) - { - if (strcmp(argv[i], "--maxAngle") == 0) - { - param = argv[++i]; - if (!param) - return false; - - float maxangle = atof(param); - if (maxangle <= 90.f && maxangle >= 45.f) - maxAngle = maxangle; - else - printf("invalid option for '--maxAngle', using default\n"); - } - else if (strcmp(argv[i], "--tile") == 0) - { - param = argv[++i]; - if (!param) - return false; - - char* stileX = strtok(param, ","); - char* stileY = strtok(NULL, ","); - int tilex = atoi(stileX); - int tiley = atoi(stileY); - - if ((tilex > 0 && tilex < 64) || (tilex == 0 && strcmp(stileX, "0") == 0)) - tileX = tilex; - if ((tiley > 0 && tiley < 64) || (tiley == 0 && strcmp(stileY, "0") == 0)) - tileY = tiley; - - if (tileX < 0 || tileY < 0) - { - printf("invalid tile coords.\n"); - return false; - } - } - else if (strcmp(argv[i], "--skipLiquid") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - skipLiquid = true; - else if (strcmp(param, "false") == 0) - skipLiquid = false; - else - printf("invalid option for '--skipLiquid', using default\n"); - } - else if (strcmp(argv[i], "--skipContinents") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - skipContinents = true; - else if (strcmp(param, "false") == 0) - skipContinents = false; - else - printf("invalid option for '--skipContinents', using default\n"); - } - else if (strcmp(argv[i], "--skipJunkMaps") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - skipJunkMaps = true; - else if (strcmp(param, "false") == 0) - skipJunkMaps = false; - else - printf("invalid option for '--skipJunkMaps', using default\n"); - } - else if (strcmp(argv[i], "--skipBattlegrounds") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - skipBattlegrounds = true; - else if (strcmp(param, "false") == 0) - skipBattlegrounds = false; - else - printf("invalid option for '--skipBattlegrounds', using default\n"); - } - else if (strcmp(argv[i], "--debugOutput") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - debugOutput = true; - else if (strcmp(param, "false") == 0) - debugOutput = false; - else - printf("invalid option for '--debugOutput', using default true\n"); - } - else if (strcmp(argv[i], "--silent") == 0) - { - silent = true; - } - else if (strcmp(argv[i], "--bigBaseUnit") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - bigBaseUnit = true; - else if (strcmp(param, "false") == 0) - bigBaseUnit = false; - else - printf("invalid option for '--bigBaseUnit', using default false\n"); - } - else if (strcmp(argv[i], "--offMeshInput") == 0) - { - param = argv[++i]; - if (!param) - return false; - - offMeshInputPath = param; - } - else - { - int map = atoi(argv[i]); - if (map > 0 || (map == 0 && (strcmp(argv[i], "0") == 0))) - mapnum = map; - else - { - printf("invalid map id\n"); - return false; - } - } - } - - return true; -} - -int finish(const char* message, int returnValue) -{ - printf("%s", message); - getchar(); - return returnValue; -} - -int main(int argc, char** argv) -{ - int mapnum = -1; - float maxAngle = 60.0f; - int tileX = -1, tileY = -1; - bool skipLiquid = false, - skipContinents = false, - skipJunkMaps = true, - skipBattlegrounds = false, - debugOutput = false, - silent = false, - bigBaseUnit = false; - char* offMeshInputPath = NULL; - - bool validParam = handleArgs(argc, argv, mapnum, - tileX, tileY, maxAngle, - skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, - debugOutput, silent, bigBaseUnit, offMeshInputPath); - - if (!validParam) - return silent ? -1 : finish("You have specified invalid parameters", -1); - - if (mapnum == -1 && debugOutput) - { - if (silent) - return -2; - - printf("You have specifed debug output, but didn't specify a map to generate.\n"); - printf("This will generate debug output for ALL maps.\n"); - printf("Are you sure you want to continue? (y/n) "); - if (getchar() != 'y') - return 0; - } - - if (!checkDirectories(debugOutput)) - return silent ? -3 : finish("Press any key to close...", -3); - - MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps, - skipBattlegrounds, debugOutput, bigBaseUnit, offMeshInputPath); - - if (tileX > -1 && tileY > -1 && mapnum >= 0) - builder.buildSingleTile(mapnum, tileX, tileY); - else if (mapnum >= 0) - builder.buildMap(uint32(mapnum)); - else - builder.buildAllMaps(); - - return silent ? 1 : finish("Movemap build is complete!", 1); -} diff --git a/src/tools/mmap_extractor/TerrainBuilder.cpp b/src/tools/mmap_extractor/TerrainBuilder.cpp deleted file mode 100644 index c696f6017a5..00000000000 --- a/src/tools/mmap_extractor/TerrainBuilder.cpp +++ /dev/null @@ -1,854 +0,0 @@ -/* - * Copyright (C) 2008-2011 TrinityCore - * Copyright (C) 2005-2011 MaNGOS - * - * 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 . - */ - -#include "TerrainBuilder.h" - -#include "PathCommon.h" -#include "MapBuilder.h" - -#include "VMapManager2.h" -#include "MapTree.h" -#include "ModelInstance.h" - -namespace MMAP -{ - TerrainBuilder::TerrainBuilder(bool skipLiquid) : m_skipLiquid (skipLiquid){ } - TerrainBuilder::~TerrainBuilder() { } - - /**************************************************************************/ - void TerrainBuilder::getLoopVars(Spot portion, int &loopStart, int &loopEnd, int &loopInc) - { - switch (portion) - { - case ENTIRE: - loopStart = 0; - loopEnd = V8_SIZE_SQ; - loopInc = 1; - break; - case TOP: - loopStart = 0; - loopEnd = V8_SIZE; - loopInc = 1; - break; - case LEFT: - loopStart = 0; - loopEnd = V8_SIZE_SQ - V8_SIZE + 1; - loopInc = V8_SIZE; - break; - case RIGHT: - loopStart = V8_SIZE - 1; - loopEnd = V8_SIZE_SQ; - loopInc = V8_SIZE; - break; - case BOTTOM: - loopStart = V8_SIZE_SQ - V8_SIZE; - loopEnd = V8_SIZE_SQ; - loopInc = 1; - break; - } - } - - /**************************************************************************/ - void TerrainBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) - { - if (loadMap(mapID, tileX, tileY, meshData, ENTIRE)) - { - loadMap(mapID, tileX+1, tileY, meshData, LEFT); - loadMap(mapID, tileX-1, tileY, meshData, RIGHT); - loadMap(mapID, tileX, tileY+1, meshData, TOP); - loadMap(mapID, tileX, tileY-1, meshData, BOTTOM); - } - } - - /**************************************************************************/ - bool TerrainBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, Spot portion) - { - char mapFileName[255]; - sprintf(mapFileName, "maps/%03u%02u%02u.map", mapID, tileY, tileX); - - FILE* mapFile = fopen(mapFileName, "rb"); - if (!mapFile) - return false; - - map_fileheader fheader; - fread(&fheader, sizeof(map_fileheader), 1, mapFile); - - if (fheader.versionMagic != *((uint32 const*)(MAP_VERSION_MAGIC))) - { - fclose(mapFile); - printf("%s is the wrong version, please extract new .map files\n", mapFileName); - return false; - } - - map_heightHeader hheader; - fseek(mapFile, fheader.heightMapOffset, SEEK_SET); - fread(&hheader, sizeof(map_heightHeader), 1, mapFile); - - bool haveTerrain = !(hheader.flags & MAP_HEIGHT_NO_HEIGHT); - bool haveLiquid = fheader.liquidMapOffset && !m_skipLiquid; - - // no data in this map file - if (!haveTerrain && !haveLiquid) - { - fclose(mapFile); - return false; - } - - // data used later - uint16 holes[16][16]; - memset(holes, 0, sizeof(holes)); - uint8 liquid_type[16][16]; - memset(liquid_type, 0, sizeof(liquid_type)); - G3D::Array ltriangles; - G3D::Array ttriangles; - - // terrain data - if (haveTerrain) - { - int i; - float heightMultiplier; - float V9[V9_SIZE_SQ], V8[V8_SIZE_SQ]; - - if (hheader.flags & MAP_HEIGHT_AS_INT8) - { - uint8 v9[V9_SIZE_SQ]; - uint8 v8[V8_SIZE_SQ]; - fread(v9, sizeof(uint8), V9_SIZE_SQ, mapFile); - fread(v8, sizeof(uint8), V8_SIZE_SQ, mapFile); - heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 255; - - for (i = 0; i < V9_SIZE_SQ; ++i) - V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight; - - for (i = 0; i < V8_SIZE_SQ; ++i) - V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight; - } - else if (hheader.flags & MAP_HEIGHT_AS_INT16) - { - uint16 v9[V9_SIZE_SQ]; - uint16 v8[V8_SIZE_SQ]; - fread(v9, sizeof(uint16), V9_SIZE_SQ, mapFile); - fread(v8, sizeof(uint16), V8_SIZE_SQ, mapFile); - heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 65535; - - for (i = 0; i < V9_SIZE_SQ; ++i) - V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight; - - for (i = 0; i < V8_SIZE_SQ; ++i) - V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight; - } - else - { - fread (V9, sizeof(float), V9_SIZE_SQ, mapFile); - fread(V8, sizeof(float), V8_SIZE_SQ, mapFile); - } - - // hole data - memset(holes, 0, fheader.holesSize); - fseek(mapFile, fheader.holesOffset, SEEK_SET); - fread(holes, fheader.holesSize, 1, mapFile); - - int count = meshData.solidVerts.size() / 3; - float xoffset = (float(tileX)-32)*GRID_SIZE; - float yoffset = (float(tileY)-32)*GRID_SIZE; - - float coord[3]; - - for (i = 0; i < V9_SIZE_SQ; ++i) - { - getHeightCoord(i, GRID_V9, xoffset, yoffset, coord, V9); - meshData.solidVerts.append(coord[0]); - meshData.solidVerts.append(coord[2]); - meshData.solidVerts.append(coord[1]); - } - - for (i = 0; i < V8_SIZE_SQ; ++i) - { - getHeightCoord(i, GRID_V8, xoffset, yoffset, coord, V8); - meshData.solidVerts.append(coord[0]); - meshData.solidVerts.append(coord[2]); - meshData.solidVerts.append(coord[1]); - } - - int j, indices[3], loopStart, loopEnd, loopInc; - getLoopVars(portion, loopStart, loopEnd, loopInc); - for (i = loopStart; i < loopEnd; i+=loopInc) - for (j = TOP; j <= BOTTOM; j+=1) - { - getHeightTriangle(i, Spot(j), indices); - ttriangles.append(indices[2] + count); - ttriangles.append(indices[1] + count); - ttriangles.append(indices[0] + count); - } - } - - // liquid data - if (haveLiquid) - { - map_liquidHeader lheader; - fseek(mapFile, fheader.liquidMapOffset, SEEK_SET); - fread(&lheader, sizeof(map_liquidHeader), 1, mapFile); - - float* liquid_map = NULL; - - if (!(lheader.flags & MAP_LIQUID_NO_TYPE)) - fread(liquid_type, sizeof(liquid_type), 1, mapFile); - - if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) - { - liquid_map = new float [lheader.width*lheader.height]; - fread(liquid_map, sizeof(float), lheader.width*lheader.height, mapFile); - } - - if (liquid_type && liquid_map) - { - int count = meshData.liquidVerts.size() / 3; - float xoffset = (float(tileX)-32)*GRID_SIZE; - float yoffset = (float(tileY)-32)*GRID_SIZE; - - float coord[3]; - int row, col; - - // generate coordinates - if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) - { - int j = 0; - for (int i = 0; i < V9_SIZE_SQ; ++i) - { - row = i / V9_SIZE; - col = i % V9_SIZE; - - if (row < lheader.offsetY || row >= lheader.offsetY + lheader.height || - col < lheader.offsetX || col >= lheader.offsetX + lheader.width) - { - // dummy vert using invalid height - meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, INVALID_MAP_LIQ_HEIGHT, (yoffset+row*GRID_PART_SIZE)*-1); - continue; - } - - getLiquidCoord(i, j, xoffset, yoffset, coord, liquid_map); - meshData.liquidVerts.append(coord[0]); - meshData.liquidVerts.append(coord[2]); - meshData.liquidVerts.append(coord[1]); - j++; - } - } - else - { - for (int i = 0; i < V9_SIZE_SQ; ++i) - { - row = i / V9_SIZE; - col = i % V9_SIZE; - meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, lheader.liquidLevel, (yoffset+row*GRID_PART_SIZE)*-1); - } - } - - delete [] liquid_map; - - int indices[3], loopStart, loopEnd, loopInc, triInc; - getLoopVars(portion, loopStart, loopEnd, loopInc); - triInc = BOTTOM-TOP; - - // generate triangles - for (int i = loopStart; i < loopEnd; i+=loopInc) - for (int j = TOP; j <= BOTTOM; j+= triInc) - { - getHeightTriangle(i, Spot(j), indices, true); - ltriangles.append(indices[2] + count); - ltriangles.append(indices[1] + count); - ltriangles.append(indices[0] + count); - } - } - } - - fclose(mapFile); - - // now that we have gathered the data, we can figure out which parts to keep: - // liquid above ground, ground above liquid - int loopStart, loopEnd, loopInc, tTriCount = 4; - bool useTerrain, useLiquid; - - float* lverts = meshData.liquidVerts.getCArray(); - int* ltris = ltriangles.getCArray(); - - float* tverts = meshData.solidVerts.getCArray(); - int* ttris = ttriangles.getCArray(); - - if (ltriangles.size() + ttriangles.size() == 0) - return false; - - // make a copy of liquid vertices - // used to pad right-bottom frame due to lost vertex data at extraction - float* lverts_copy = NULL; - if (meshData.liquidVerts.size()) - { - lverts_copy = new float[meshData.liquidVerts.size()]; - memcpy(lverts_copy, lverts, sizeof(float)*meshData.liquidVerts.size()); - } - - getLoopVars(portion, loopStart, loopEnd, loopInc); - for (int i = loopStart; i < loopEnd; i+=loopInc) - { - for (int j = 0; j < 2; ++j) - { - // default is true, will change to false if needed - useTerrain = true; - useLiquid = true; - uint8 liquidType = MAP_LIQUID_TYPE_NO_WATER; - - // if there is no liquid, don't use liquid - if (!liquid_type || !meshData.liquidVerts.size() || !ltriangles.size()) - useLiquid = false; - else - { - liquidType = getLiquidType(i, liquid_type); - switch (liquidType) - { - default: - useLiquid = false; - break; - case MAP_LIQUID_TYPE_WATER: - case MAP_LIQUID_TYPE_OCEAN: - // merge different types of water - liquidType = NAV_WATER; - break; - case MAP_LIQUID_TYPE_MAGMA: - liquidType = NAV_MAGMA; - break; - case MAP_LIQUID_TYPE_SLIME: - liquidType = NAV_SLIME; - break; - case MAP_LIQUID_TYPE_DARK_WATER: - // players should not be here, so logically neither should creatures - useTerrain = false; - useLiquid = false; - break; - } - } - - // if there is no terrain, don't use terrain - if (!ttriangles.size()) - useTerrain = false; - - // while extracting ADT data we are losing right-bottom vertices - // this code adds fair approximation of lost data - if (useLiquid) - { - float quadHeight = 0; - uint32 validCount = 0; - for(uint32 idx = 0; idx < 3; idx++) - { - float h = lverts_copy[ltris[idx]*3 + 1]; - if (h != INVALID_MAP_LIQ_HEIGHT && h < INVALID_MAP_LIQ_HEIGHT_MAX) - { - quadHeight += h; - validCount++; - } - } - - // update vertex height data - if (validCount > 0 && validCount < 3) - { - quadHeight /= validCount; - for(uint32 idx = 0; idx < 3; idx++) - { - float h = lverts[ltris[idx]*3 + 1]; - if (h == INVALID_MAP_LIQ_HEIGHT || h > INVALID_MAP_LIQ_HEIGHT_MAX) - lverts[ltris[idx]*3 + 1] = quadHeight; - } - } - - // no valid vertexes - don't use this poly at all - if (validCount == 0) - useLiquid = false; - } - - // if there is a hole here, don't use the terrain - if (useTerrain) - useTerrain = !isHole(i, holes); - - // we use only one terrain kind per quad - pick higher one - if (useTerrain && useLiquid) - { - float minLLevel = INVALID_MAP_LIQ_HEIGHT_MAX; - float maxLLevel = INVALID_MAP_LIQ_HEIGHT; - for(uint32 x = 0; x < 3; x++) - { - float h = lverts[ltris[x]*3 + 1]; - if (minLLevel > h) - minLLevel = h; - - if (maxLLevel < h) - maxLLevel = h; - } - - float maxTLevel = INVALID_MAP_LIQ_HEIGHT; - float minTLevel = INVALID_MAP_LIQ_HEIGHT_MAX; - for(uint32 x = 0; x < 6; x++) - { - float h = tverts[ttris[x]*3 + 1]; - if (maxTLevel < h) - maxTLevel = h; - - if (minTLevel > h) - minTLevel = h; - } - - // terrain under the liquid? - if (minLLevel > maxTLevel) - useTerrain = false; - - //liquid under the terrain? - if (minTLevel > maxLLevel) - useLiquid = false; - } - - // store the result - if (useLiquid) - { - meshData.liquidType.append(liquidType); - for (int k = 0; k < 3; ++k) - meshData.liquidTris.append(ltris[k]); - } - - if (useTerrain) - for (int k = 0; k < 3*tTriCount/2; ++k) - meshData.solidTris.append(ttris[k]); - - // advance to next set of triangles - ltris += 3; - ttris += 3*tTriCount/2; - } - } - - if (lverts_copy) - delete [] lverts_copy; - - return meshData.solidTris.size() || meshData.liquidTris.size(); - } - - /**************************************************************************/ - void TerrainBuilder::getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v) - { - // wow coords: x, y, height - // coord is mirroed about the horizontal axes - switch (grid) - { - case GRID_V9: - coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f; - coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f; - coord[2] = v[index]; - break; - case GRID_V8: - coord[0] = (xOffset + index%(V8_SIZE)*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f; - coord[1] = (yOffset + (int)(index/(V8_SIZE))*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f; - coord[2] = v[index]; - break; - } - } - - /**************************************************************************/ - void TerrainBuilder::getHeightTriangle(int square, Spot triangle, int* indices, bool liquid/* = false*/) - { - int rowOffset = square/V8_SIZE; - if (!liquid) - switch (triangle) - { - case TOP: - indices[0] = square+rowOffset; // 0-----1 .... 128 - indices[1] = square+1+rowOffset; // |\ T /| - indices[2] = (V9_SIZE_SQ)+square; // | \ / | - break; // |L 0 R| .. 127 - case LEFT: // | / \ | - indices[0] = square+rowOffset; // |/ B \| - indices[1] = (V9_SIZE_SQ)+square; // 129---130 ... 386 - indices[2] = square+V9_SIZE+rowOffset; // |\ /| - break; // | \ / | - case RIGHT: // | 128 | .. 255 - indices[0] = square+1+rowOffset; // | / \ | - indices[1] = square+V9_SIZE+1+rowOffset; // |/ \| - indices[2] = (V9_SIZE_SQ)+square; // 258---259 ... 515 - break; - case BOTTOM: - indices[0] = (V9_SIZE_SQ)+square; - indices[1] = square+V9_SIZE+1+rowOffset; - indices[2] = square+V9_SIZE+rowOffset; - break; - default: break; - } - else - switch (triangle) - { // 0-----1 .... 128 - case TOP: // |\ | - indices[0] = square+rowOffset; // | \ T | - indices[1] = square+1+rowOffset; // | \ | - indices[2] = square+V9_SIZE+1+rowOffset; // | B \ | - break; // | \| - case BOTTOM: // 129---130 ... 386 - indices[0] = square+rowOffset; // |\ | - indices[1] = square+V9_SIZE+1+rowOffset; // | \ | - indices[2] = square+V9_SIZE+rowOffset; // | \ | - break; // | \ | - default: break; // | \| - } // 258---259 ... 515 - - } - - /**************************************************************************/ - void TerrainBuilder::getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v) - { - // wow coords: x, y, height - // coord is mirroed about the horizontal axes - coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f; - coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f; - coord[2] = v[index2]; - } - - static uint16 holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888}; - static uint16 holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; - - /**************************************************************************/ - bool TerrainBuilder::isHole(int square, const uint16 holes[16][16]) - { - int row = square / 128; - int col = square % 128; - int cellRow = row / 8; // 8 squares per cell - int cellCol = col / 8; - int holeRow = row % 8 / 2; - int holeCol = (square - (row * 128 + cellCol * 8)) / 2; - - uint16 hole = holes[cellRow][cellCol]; - - return (hole & holetab_h[holeCol] & holetab_v[holeRow]) != 0; - } - - /**************************************************************************/ - uint8 TerrainBuilder::getLiquidType(int square, const uint8 liquid_type[16][16]) - { - int row = square / 128; - int col = square % 128; - int cellRow = row / 8; // 8 squares per cell - int cellCol = col / 8; - - return liquid_type[cellRow][cellCol]; - } - - /**************************************************************************/ - bool TerrainBuilder::loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) - { - IVMapManager* vmapManager = new VMapManager2(); - int result = vmapManager->loadMap("vmaps", mapID, tileX, tileY); - bool retval = false; - - do - { - if (result == VMAP_LOAD_RESULT_ERROR) - break; - - InstanceTreeMap instanceTrees; - ((VMapManager2*)vmapManager)->getInstanceMapTree(instanceTrees); - - if (!instanceTrees[mapID]) - break; - - ModelInstance* models = NULL; - uint32 count = 0; - instanceTrees[mapID]->getModelInstances(models, count); - - if (!models) - break; - - for (uint32 i = 0; i < count; ++i) - { - ModelInstance instance = models[i]; - - // model instances exist in tree even though there are instances of that model in this tile - WorldModel* worldModel = instance.getWorldModel(); - if (!worldModel) - continue; - - // now we have a model to add to the meshdata - retval = true; - - vector groupModels; - worldModel->getGroupModels(groupModels); - - // all M2s need to have triangle indices reversed - bool isM2 = instance.name.find(".m2") != instance.name.npos || instance.name.find(".M2") != instance.name.npos; - - // transform data - float scale = instance.iScale; - G3D::Matrix3 rotation = G3D::Matrix3::fromEulerAnglesXYZ(G3D::pi()*instance.iRot.z/-180.f, G3D::pi()*instance.iRot.x/-180.f, G3D::pi()*instance.iRot.y/-180.f); - Vector3 position = instance.iPos; - position.x -= 32*GRID_SIZE; - position.y -= 32*GRID_SIZE; - - for (vector::iterator it = groupModels.begin(); it != groupModels.end(); ++it) - { - vector tempVertices; - vector transformedVertices; - vector tempTriangles; - WmoLiquid* liquid = NULL; - - (*it).getMeshData(tempVertices, tempTriangles, liquid); - - // first handle collision mesh - transform(tempVertices, transformedVertices, scale, rotation, position); - - int offset = meshData.solidVerts.size() / 3; - - copyVertices(transformedVertices, meshData.solidVerts); - copyIndices(tempTriangles, meshData.solidTris, offset, isM2); - - // now handle liquid data - if (liquid) - { - vector liqVerts; - vector liqTris; - uint32 tilesX, tilesY, vertsX, vertsY; - Vector3 corner; - liquid->getPosInfo(tilesX, tilesY, corner); - vertsX = tilesX + 1; - vertsY = tilesY + 1; - uint8* flags = liquid->GetFlagsStorage(); - float* data = liquid->GetHeightStorage(); - uint8 type = NAV_EMPTY; - - // convert liquid type to NavTerrain - switch (liquid->GetType()) - { - case 0: - case 1: - type = NAV_WATER; - break; - case 2: - type = NAV_MAGMA; - break; - case 3: - type = NAV_SLIME; - break; - } - - // 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 - - Vector3 vert; - for (uint32 x = 0; x < vertsX; ++x) - for (uint32 y = 0; y < vertsY; ++y) - { - vert = 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) - for (uint32 y = 0; y < tilesY; ++y) - 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); - } - - 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); - } - } - } - } - } - while (false); - - vmapManager->unloadMap(mapID, tileX, tileY); - delete vmapManager; - - return retval; - } - - /**************************************************************************/ - void TerrainBuilder::transform(vector &source, vector &transformedVertices, float scale, G3D::Matrix3 &rotation, Vector3 &position) - { - for (vector::iterator it = source.begin(); it != source.end(); ++it) - { - // apply tranform, then mirror along the horizontal axes - Vector3 v((*it) * rotation * scale + position); - v.x *= -1.f; - v.y *= -1.f; - transformedVertices.push_back(v); - } - } - - /**************************************************************************/ - void TerrainBuilder::copyVertices(vector &source, G3D::Array &dest) - { - for (vector::iterator it = source.begin(); it != source.end(); ++it) - { - dest.push_back((*it).y); - dest.push_back((*it).z); - dest.push_back((*it).x); - } - } - - /**************************************************************************/ - void TerrainBuilder::copyIndices(vector &source, G3D::Array &dest, int offset, bool flip) - { - if (flip) - { - for (vector::iterator it = source.begin(); it != source.end(); ++it) - { - dest.push_back((*it).idx2+offset); - dest.push_back((*it).idx1+offset); - dest.push_back((*it).idx0+offset); - } - } - else - { - for (vector::iterator it = source.begin(); it != source.end(); ++it) - { - dest.push_back((*it).idx0+offset); - dest.push_back((*it).idx1+offset); - dest.push_back((*it).idx2+offset); - } - } - } - - /**************************************************************************/ - void TerrainBuilder::copyIndices(G3D::Array &source, G3D::Array &dest, int offset) - { - int* src = source.getCArray(); - for (int32 i = 0; i < source.size(); ++i) - dest.append(src[i] + offset); - } - - /**************************************************************************/ - void TerrainBuilder::cleanVertices(G3D::Array &verts, G3D::Array &tris) - { - map vertMap; - - int* t = tris.getCArray(); - float* v = verts.getCArray(); - - // collect all the vertex indices from triangle - for (int i = 0; i < tris.size(); ++i) - { - if (vertMap.find(t[i]) != vertMap.end()) - continue; - - vertMap.insert(std::pair(t[i], 0)); - } - - // collect the vertices - G3D::Array cleanVerts; - int index, count = 0; - for (map::iterator it = vertMap.begin(); it != vertMap.end(); ++it) - { - index = (*it).first; - (*it).second = count; - cleanVerts.append(v[index*3], v[index*3+1], v[index*3+2]); - count++; - } - verts.fastClear(); - verts.append(cleanVerts); - cleanVerts.clear(); - - // update triangles to use new indices - for (int i = 0; i < tris.size(); ++i) - { - map::iterator it; - if ((it = vertMap.find(t[i])) == vertMap.end()) - continue; - - t[i] = (*it).second; - } - - vertMap.clear(); - } - - /**************************************************************************/ - void TerrainBuilder::loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char* offMeshFilePath) - { - // no meshfile input given? - if (offMeshFilePath == NULL) - return; - - FILE* fp = fopen(offMeshFilePath, "rb"); - if (!fp) - { - printf(" loadOffMeshConnections:: input file %s not found!\n", offMeshFilePath); - return; - } - - // pretty silly thing, as we parse entire file and load only the tile we need - // but we don't expect this file to be too large - char* buf = new char[512]; - while(fgets(buf, 512, fp)) - { - float p0[3], p1[3]; - int mid, tx, ty; - float size; - if (10 != sscanf(buf, "%d %d,%d (%f %f %f) (%f %f %f) %f", &mid, &tx, &ty, - &p0[0], &p0[1], &p0[2], &p1[0], &p1[1], &p1[2], &size)) - continue; - - if (mapID == mid, tileX == tx, tileY == ty) - { - meshData.offMeshConnections.append(p0[1]); - meshData.offMeshConnections.append(p0[2]); - meshData.offMeshConnections.append(p0[0]); - - meshData.offMeshConnections.append(p1[1]); - meshData.offMeshConnections.append(p1[2]); - meshData.offMeshConnections.append(p1[0]); - - meshData.offMeshConnectionDirs.append(1); // 1 - both direction, 0 - one sided - meshData.offMeshConnectionRads.append(size); // agent size equivalent - // can be used same way as polygon flags - meshData.offMeshConnectionsAreas.append((unsigned char)0xFF); - meshData.offMeshConnectionsFlags.append((unsigned short)0xFF); // all movement masks can make this path - } - - } - - delete [] buf; - fclose(fp); - } -} diff --git a/src/tools/mmap_extractor/TerrainBuilder.h b/src/tools/mmap_extractor/TerrainBuilder.h deleted file mode 100644 index a7f21883af2..00000000000 --- a/src/tools/mmap_extractor/TerrainBuilder.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2008-2011 TrinityCore - * Copyright (C) 2005-2011 MaNGOS - * - * 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 . - */ - -#ifndef _MMAP_TERRAIN_BUILDER_H -#define _MMAP_TERRAIN_BUILDER_H - -#include "PathCommon.h" -#include "Map.h" -#include "SharedDefines.h" - -#include "WorldModel.h" - -#include "G3D/Array.h" -#include "G3D/Vector3.h" -#include "G3D/Matrix3.h" - -using namespace Trinity; - -namespace MMAP -{ - enum Spot - { - TOP = 1, - RIGHT = 2, - LEFT = 3, - BOTTOM = 4, - ENTIRE = 5 - }; - - enum Grid - { - GRID_V8, - GRID_V9 - }; - - static const int V9_SIZE = 129; - static const int V9_SIZE_SQ = V9_SIZE*V9_SIZE; - static const int V8_SIZE = 128; - static const int V8_SIZE_SQ = V8_SIZE*V8_SIZE; - static const float GRID_SIZE = 533.33333f; - static const float GRID_PART_SIZE = GRID_SIZE/V8_SIZE; - - // see contrib/extractor/system.cpp, CONF_use_minHeight - static const float INVALID_MAP_LIQ_HEIGHT = -500.f; - static const float INVALID_MAP_LIQ_HEIGHT_MAX = 5000.0f; - - // see following files: - // contrib/extractor/system.cpp - // src/game/Map.cpp - static char const* MAP_VERSION_MAGIC = "v1.2"; - - struct MeshData - { - G3D::Array solidVerts; - G3D::Array solidTris; - - G3D::Array liquidVerts; - G3D::Array liquidTris; - G3D::Array liquidType; - - // offmesh connection data - G3D::Array offMeshConnections; // [p0y,p0z,p0x,p1y,p1z,p1x] - per connection - G3D::Array offMeshConnectionRads; - G3D::Array offMeshConnectionDirs; - G3D::Array offMeshConnectionsAreas; - G3D::Array offMeshConnectionsFlags; - }; - - class TerrainBuilder - { - public: - TerrainBuilder(bool skipLiquid); - ~TerrainBuilder(); - - void loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); - bool loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); - void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char* offMeshFilePath); - - bool usesLiquids() { return !m_skipLiquid; } - - // vert and triangle methods - static void transform(vector &original, vector &transformed, - float scale, G3D::Matrix3 &rotation, G3D::Vector3 &position); - static void copyVertices(vector &source, G3D::Array &dest); - static void copyIndices(vector &source, G3D::Array &dest, int offest, bool flip); - static void copyIndices(G3D::Array &src, G3D::Array &dest, int offset); - static void cleanVertices(G3D::Array &verts, G3D::Array &tris); - private: - /// Loads a portion of a map's terrain - bool loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, Spot portion); - - /// Sets loop variables for selecting only certain parts of a map's terrain - void getLoopVars(Spot portion, int &loopStart, int &loopEnd, int &loopInc); - - /// Controls whether liquids are loaded - bool m_skipLiquid; - - /// Load the map terrain from file - bool loadHeightMap(uint32 mapID, uint32 tileX, uint32 tileY, G3D::Array &vertices, G3D::Array &triangles, Spot portion); - - /// Get the vector coordinate for a specific position - void getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v); - - /// Get the triangle's vector indices for a specific position - void getHeightTriangle(int square, Spot triangle, int* indices, bool liquid = false); - - /// Determines if the specific position's triangles should be rendered - bool isHole(int square, const uint16 holes[16][16]); - - /// Get the liquid vector coordinate for a specific position - void getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v); - - /// Get the liquid type for a specific position - uint8 getLiquidType(int square, const uint8 liquid_type[16][16]); - - // hide parameterless and copy constructor - TerrainBuilder(); - TerrainBuilder(const TerrainBuilder &tb); - }; -} - -#endif - diff --git a/src/tools/mmap_extractor/VMapExtensions.cpp b/src/tools/mmap_extractor/VMapExtensions.cpp deleted file mode 100644 index 4f203e11c21..00000000000 --- a/src/tools/mmap_extractor/VMapExtensions.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2008-2011 TrinityCore - * Copyright (C) 2005-2011 MaNGOS - * - * 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 . - */ - -#include -#include "MapTree.h" -#include "VMapManager2.h" -#include "WorldModel.h" -#include "ModelInstance.h" - -using namespace std; - -namespace VMAP -{ - // Need direct access to encapsulated VMAP data, so we add functions for MMAP generator - // maybe add MapBuilder as friend to all of the below classes would be better? - - // declared in src/shared/vmap/MapTree.h - void StaticMapTree::getModelInstances(ModelInstance* &models, uint32 &count) - { - models = iTreeValues; - count = iNTreeValues; - } - - // declared in src/shared/vmap/VMapManager2.h - void VMapManager2::getInstanceMapTree(InstanceTreeMap &instanceMapTree) - { - instanceMapTree = iInstanceMapTrees; - } - - // declared in src/shared/vmap/WorldModel.h - void WorldModel::getGroupModels(vector &groupModels) - { - groupModels = this->groupModels; - } - - // declared in src/shared/vmap/WorldModel.h - void GroupModel::getMeshData(vector &vertices, vector &triangles, WmoLiquid* &liquid) - { - vertices = this->vertices; - triangles = this->triangles; - liquid = iLiquid; - } - - // declared in src/shared/vmap/ModelInstance.h - WorldModel* const ModelInstance::getWorldModel() - { - return iModel; - } - - // declared in src/shared/vmap/WorldModel.h - void WmoLiquid::getPosInfo(uint32 &tilesX, uint32 &tilesY, Vector3 &corner) const - { - tilesX = iTilesX; - tilesY = iTilesY; - corner = iCorner; - } -} diff --git a/src/tools/mmaps_generator/CMakeLists.txt b/src/tools/mmaps_generator/CMakeLists.txt new file mode 100644 index 00000000000..46bf9d00d43 --- /dev/null +++ b/src/tools/mmaps_generator/CMakeLists.txt @@ -0,0 +1,68 @@ +# Copyright (C) 2008-2011 Trinity +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +file(GLOB_RECURSE sources *.cpp *.h) + +# definitions +add_definitions(-DNO_CORE_FUNCS) +add_definitions(-DDEBUG) +add_definitions(-DNO_vsnprintf) + +include_directories( + ${CMAKE_BINARY_DIR} + ${ACE_INCLUDE_DIR} + ${MYSQL_INCLUDE_DIR} + ${CMAKE_SOURCE_DIR}/dep/libmpq + ${CMAKE_SOURCE_DIR}/dep/zlib + ${CMAKE_SOURCE_DIR}/dep/bzip2 + ${CMAKE_SOURCE_DIR}/dep/acelite + ${CMAKE_SOURCE_DIR}/dep/g3dlite/include + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/src/server/shared/Database + ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation + ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Logging + ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference + ${CMAKE_SOURCE_DIR}/src/server/game/Maps + ${CMAKE_SOURCE_DIR}/src/server/game/DataStores + ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints + ${CMAKE_SOURCE_DIR}/src/server/game/Grids + ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Cells + ${CMAKE_SOURCE_DIR}/src/server/game/Miscellaneous + ${CMAKE_SOURCE_DIR}/src/server/game/Conditions + ${CMAKE_SOURCE_DIR}/src/server/collision + ${CMAKE_SOURCE_DIR}/src/server/collision/Management + ${CMAKE_SOURCE_DIR}/src/server/collision/Maps + ${CMAKE_SOURCE_DIR}/src/server/collision/Models +) + +add_executable(mmaps_generator ${sources}) + +target_link_libraries(mmaps_generator + ${MYSQL_LIBRARY} + ${ACE_LIBRARY} + ${BZIP2_LIBRARIES} + ${ZLIB_LIBRARIES} + Recast + Detour + collision + g3dlib + shared +) + +if( UNIX ) + install(TARGETS mmaps_generator DESTINATION bin) +elseif( WIN32 ) + install(TARGETS mmaps_generator DESTINATION "${CMAKE_INSTALL_PREFIX}") +endif() diff --git a/src/tools/mmaps_generator/Info/readme.txt b/src/tools/mmaps_generator/Info/readme.txt new file mode 100644 index 00000000000..8d7c4f9d2e0 --- /dev/null +++ b/src/tools/mmaps_generator/Info/readme.txt @@ -0,0 +1,66 @@ +Generator command line args + +--offMeshInput [file.*] Path to file containing off mesh connections data. + Format must be: (see offmesh_example.txt) + "map_id tile_x,tile_y (start_x start_y start_z) (end_x end_y end_z) size //optional comments" + Single mesh connection per line. + +--silent Make us script friendly. Do not wait for user input + on error or completion. + +--bigBaseUnit [true|false] Generate tile/map using bigger basic unit. + Use this option only if you have unexpected gaps. + + false: use normal metrics (default) + +--maxAngle [#] Max walkable inclination angle + + float between 45 and 90 degrees (default 60) + +--skipLiquid liquid data for maps + + false: include liquid data (default) + +--skipContinents [true|false] continents are maps 0 (Eastern Kingdoms), + 1 (Kalimdor), 530 (Outlands), 571 (Northrend) + + false: build continents (default) + +--skipJunkMaps [true|false] junk maps include some unused + maps, transport maps, and some other + + true: skip junk maps (default) + +--skipBattlegrounds [true|false] does not include PVP arenas + + false: skip battlegrounds (default) + +--debugOutput [true|false] create debugging files for use with RecastDemo + if you are only creating mmaps for use with MaNGOS, + you don't want debugging files + + false: don't create debugging files (default) + +--tile [#,#] Build the specified tile + seperate number with a comma ',' + must specify a map number (see below) + if this option is not used, all tiles are built + + [#] Build only the map specified by # + this command will build the map regardless of --skip* option settings + if you do not specify a map number, builds all maps that pass the filters specified by --skip* options + + +examples: + +movement_extractor +builds maps using the default settings (see above for defaults) + +movement_extractor --skipContinents true +builds the default maps, except continents + +movement_extractor 0 +builds all tiles of map 0 + +movement_extractor 0 --tile 34,46 +builds only tile 34,46 of map 0 (this is the southern face of blackrock mountain) \ No newline at end of file diff --git a/src/tools/mmaps_generator/IntermediateValues.cpp b/src/tools/mmaps_generator/IntermediateValues.cpp new file mode 100644 index 00000000000..9eefb1e65f0 --- /dev/null +++ b/src/tools/mmaps_generator/IntermediateValues.cpp @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 MaNGOS + * + * 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 . + */ + +#include "IntermediateValues.h" + +namespace MMAP +{ + IntermediateValues::~IntermediateValues() + { + rcFreeCompactHeightfield(compactHeightfield); + rcFreeHeightField(heightfield); + rcFreeContourSet(contours); + rcFreePolyMesh(polyMesh); + rcFreePolyMeshDetail(polyMeshDetail); + } + + void IntermediateValues::writeIV(uint32 mapID, uint32 tileX, uint32 tileY) + { + char fileName[255]; + char tileString[25]; + sprintf(tileString, "[%02u,%02u]: ", tileX, tileY); + + printf("%sWriting debug output... \r", tileString); + + string name("meshes/%03u%02i%02i."); + +#define DEBUG_WRITE(fileExtension,data) \ + do { \ + sprintf(fileName, (name + fileExtension).c_str(), mapID, tileY, tileX); \ + FILE* file = fopen(fileName, "wb"); \ + if (!file) \ + { \ + char message[1024]; \ + sprintf(message, "%sFailed to open %s for writing!\n", tileString, fileName); \ + perror(message); \ + } \ + else \ + debugWrite(file, data); \ + if (file) fclose(file); \ + printf("%sWriting debug output... \r", tileString); \ + } while (false) + + if (heightfield) + DEBUG_WRITE("hf", heightfield); + if (compactHeightfield) + DEBUG_WRITE("chf", compactHeightfield); + if (contours) + DEBUG_WRITE("cs", contours); + if (polyMesh) + DEBUG_WRITE("pmesh", polyMesh); + if (polyMeshDetail) + DEBUG_WRITE("dmesh", polyMeshDetail); + +#undef DEBUG_WRITE + } + + void IntermediateValues::debugWrite(FILE* file, const rcHeightfield* mesh) + { + if (!file || !mesh) + return; + + fwrite(&(mesh->cs), sizeof(float), 1, file); + fwrite(&(mesh->ch), sizeof(float), 1, file); + fwrite(&(mesh->width), sizeof(int), 1, file); + fwrite(&(mesh->height), sizeof(int), 1, file); + fwrite(mesh->bmin, sizeof(float), 3, file); + fwrite(mesh->bmax, sizeof(float), 3, file); + + for (int y = 0; y < mesh->height; ++y) + for (int x = 0; x < mesh->width; ++x) + { + rcSpan* span = mesh->spans[x+y*mesh->width]; + + // first, count the number of spans + int spanCount = 0; + while (span) + { + spanCount++; + span = span->next; + } + + // write the span count + fwrite(&spanCount, sizeof(int), 1, file); + + // write the spans + span = mesh->spans[x+y*mesh->width]; + while (span) + { + fwrite(span, sizeof(rcSpan), 1, file); + span = span->next; + } + } + } + + void IntermediateValues::debugWrite(FILE* file, const rcCompactHeightfield* chf) + { + if (!file | !chf) + return; + + fwrite(&(chf->width), sizeof(chf->width), 1, file); + fwrite(&(chf->height), sizeof(chf->height), 1, file); + fwrite(&(chf->spanCount), sizeof(chf->spanCount), 1, file); + + fwrite(&(chf->walkableHeight), sizeof(chf->walkableHeight), 1, file); + fwrite(&(chf->walkableClimb), sizeof(chf->walkableClimb), 1, file); + + fwrite(&(chf->maxDistance), sizeof(chf->maxDistance), 1, file); + fwrite(&(chf->maxRegions), sizeof(chf->maxRegions), 1, file); + + fwrite(chf->bmin, sizeof(chf->bmin), 1, file); + fwrite(chf->bmax, sizeof(chf->bmax), 1, file); + + fwrite(&(chf->cs), sizeof(chf->cs), 1, file); + fwrite(&(chf->ch), sizeof(chf->ch), 1, file); + + int tmp = 0; + if (chf->cells) tmp |= 1; + if (chf->spans) tmp |= 2; + if (chf->dist) tmp |= 4; + if (chf->areas) tmp |= 8; + + fwrite(&tmp, sizeof(tmp), 1, file); + + if (chf->cells) + fwrite(chf->cells, sizeof(rcCompactCell), chf->width*chf->height, file); + if (chf->spans) + fwrite(chf->spans, sizeof(rcCompactSpan), chf->spanCount, file); + if (chf->dist) + fwrite(chf->dist, sizeof(unsigned short), chf->spanCount, file); + if (chf->areas) + fwrite(chf->areas, sizeof(unsigned char), chf->spanCount, file); + } + + void IntermediateValues::debugWrite(FILE* file, const rcContourSet* cs) + { + if (!file || !cs) + return; + + fwrite(&(cs->cs), sizeof(float), 1, file); + fwrite(&(cs->ch), sizeof(float), 1, file); + fwrite(cs->bmin, sizeof(float), 3, file); + fwrite(cs->bmax, sizeof(float), 3, file); + fwrite(&(cs->nconts), sizeof(int), 1, file); + for (int i = 0; i < cs->nconts; ++i) + { + fwrite(&cs->conts[i].area, sizeof(unsigned char), 1, file); + fwrite(&cs->conts[i].reg, sizeof(unsigned short), 1, file); + fwrite(&cs->conts[i].nverts, sizeof(int), 1, file); + fwrite(cs->conts[i].verts, sizeof(int), cs->conts[i].nverts*4, file); + fwrite(&cs->conts[i].nrverts, sizeof(int), 1, file); + fwrite(cs->conts[i].rverts, sizeof(int), cs->conts[i].nrverts*4, file); + } + } + + void IntermediateValues::debugWrite(FILE* file, const rcPolyMesh* mesh) + { + if (!file || !mesh) + return; + + fwrite(&(mesh->cs), sizeof(float), 1, file); + fwrite(&(mesh->ch), sizeof(float), 1, file); + fwrite(&(mesh->nvp), sizeof(int), 1, file); + fwrite(mesh->bmin, sizeof(float), 3, file); + fwrite(mesh->bmax, sizeof(float), 3, file); + fwrite(&(mesh->nverts), sizeof(int), 1, file); + fwrite(mesh->verts, sizeof(unsigned short), mesh->nverts*3, file); + fwrite(&(mesh->npolys), sizeof(int), 1, file); + fwrite(mesh->polys, sizeof(unsigned short), mesh->npolys*mesh->nvp*2, file); + fwrite(mesh->flags, sizeof(unsigned short), mesh->npolys, file); + fwrite(mesh->areas, sizeof(unsigned char), mesh->npolys, file); + fwrite(mesh->regs, sizeof(unsigned short), mesh->npolys, file); + } + + void IntermediateValues::debugWrite(FILE* file, const rcPolyMeshDetail* mesh) + { + if (!file || !mesh) + return; + + fwrite(&(mesh->nverts), sizeof(int), 1, file); + fwrite(mesh->verts, sizeof(float), mesh->nverts*3, file); + fwrite(&(mesh->ntris), sizeof(int), 1, file); + fwrite(mesh->tris, sizeof(char), mesh->ntris*4, file); + fwrite(&(mesh->nmeshes), sizeof(int), 1, file); + fwrite(mesh->meshes, sizeof(int), mesh->nmeshes*4, file); + } + + void IntermediateValues::generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) + { + char objFileName[255]; + sprintf(objFileName, "meshes/map%03u.obj", mapID); + + FILE* objFile = fopen(objFileName, "wb"); + if (!objFile) + { + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", objFileName); + perror(message); + return; + } + + G3D::Array allVerts; + G3D::Array allTris; + + allTris.append(meshData.liquidTris); + allVerts.append(meshData.liquidVerts); + TerrainBuilder::copyIndices(meshData.solidTris, allTris, allVerts.size() / 3); + allVerts.append(meshData.solidVerts); + + float* verts = allVerts.getCArray(); + int vertCount = allVerts.size() / 3; + int* tris = allTris.getCArray(); + int triCount = allTris.size() / 3; + + for (int i = 0; i < allVerts.size() / 3; i++) + fprintf(objFile, "v %f %f %f\n", verts[i*3], verts[i*3 + 1], verts[i*3 + 2]); + + for (int i = 0; i < allTris.size() / 3; i++) + fprintf(objFile, "f %i %i %i\n", tris[i*3] + 1, tris[i*3 + 1] + 1, tris[i*3 + 2] + 1); + + fclose(objFile); + + + char tileString[25]; + sprintf(tileString, "[%02u,%02u]: ", tileY, tileX); + printf("%sWriting debug output... \r", tileString); + + sprintf(objFileName, "meshes/%03u.map", mapID); + + objFile = fopen(objFileName, "wb"); + if (!objFile) + { + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", objFileName); + perror(message); + return; + } + + char b = '\0'; + fwrite(&b, sizeof(char), 1, objFile); + fclose(objFile); + + sprintf(objFileName, "meshes/%03u%02u%02u.mesh", mapID, tileY, tileX); + objFile = fopen(objFileName, "wb"); + if (!objFile) + { + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", objFileName); + perror(message); + return; + } + + fwrite(&vertCount, sizeof(int), 1, objFile); + fwrite(verts, sizeof(float), vertCount*3, objFile); + fflush(objFile); + + fwrite(&triCount, sizeof(int), 1, objFile); + fwrite(tris, sizeof(int), triCount*3, objFile); + fflush(objFile); + + fclose(objFile); + } +} diff --git a/src/tools/mmaps_generator/IntermediateValues.h b/src/tools/mmaps_generator/IntermediateValues.h new file mode 100644 index 00000000000..a267a0f6412 --- /dev/null +++ b/src/tools/mmaps_generator/IntermediateValues.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 MaNGOS + * + * 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 . + */ + +#ifndef _INTERMEDIATE_VALUES_H +#define _INTERMEDIATE_VALUES_H + +#include "PathCommon.h" +#include "TerrainBuilder.h" +#include "Recast.h" +#include "DetourNavMesh.h" + +namespace MMAP +{ + // this class gathers all debug info holding and output + struct IntermediateValues + { + rcHeightfield* heightfield; + rcCompactHeightfield* compactHeightfield; + rcContourSet* contours; + rcPolyMesh* polyMesh; + rcPolyMeshDetail* polyMeshDetail; + + IntermediateValues() : compactHeightfield(NULL), heightfield(NULL), + contours(NULL), polyMesh(NULL), polyMeshDetail(NULL) {} + ~IntermediateValues(); + + void writeIV(uint32 mapID, uint32 tileX, uint32 tileY); + + void debugWrite(FILE* file, const rcHeightfield* mesh); + void debugWrite(FILE* file, const rcCompactHeightfield* chf); + void debugWrite(FILE* file, const rcContourSet* cs); + void debugWrite(FILE* file, const rcPolyMesh* mesh); + void debugWrite(FILE* file, const rcPolyMeshDetail* mesh); + + void generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); + }; +} +#endif diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp new file mode 100644 index 00000000000..3ca158f0127 --- /dev/null +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -0,0 +1,894 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 MaNGOS + * + * 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 . + */ + +#include "PathCommon.h" +#include "MapBuilder.h" + +#include "MapTree.h" +#include "ModelInstance.h" +#include "LoginDatabase.h" + +#include "DetourNavMeshBuilder.h" +#include "DetourCommon.h" + +// These make the linker happy. +LoginDatabaseWorkerPool LoginDatabase; +#include "DisableMgr.h" +namespace DisableMgr +{ + bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags) + { + return 0; + } +} + +using namespace VMAP; + +namespace MMAP +{ + MapBuilder::MapBuilder(float maxWalkableAngle, bool skipLiquid, + bool skipContinents, bool skipJunkMaps, bool skipBattlegrounds, + bool debugOutput, bool bigBaseUnit, const char* offMeshFilePath) : + m_terrainBuilder(NULL), + m_debugOutput (debugOutput), + m_skipContinents (skipContinents), + m_skipJunkMaps (skipJunkMaps), + m_skipBattlegrounds (skipBattlegrounds), + m_maxWalkableAngle (maxWalkableAngle), + m_bigBaseUnit (bigBaseUnit), + m_rcContext (NULL), + m_offMeshFilePath (offMeshFilePath) + { + m_terrainBuilder = new TerrainBuilder(skipLiquid); + + m_rcContext = new rcContext(false); + + discoverTiles(); + } + + /**************************************************************************/ + MapBuilder::~MapBuilder() + { + for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) + { + (*it).second->clear(); + delete (*it).second; + } + + delete m_terrainBuilder; + delete m_rcContext; + } + + /**************************************************************************/ + void MapBuilder::discoverTiles() + { + vector files; + uint32 mapID, tileX, tileY, tileID, count = 0; + char filter[12]; + + printf("Discovering maps... "); + getDirContents(files, "maps"); + for (uint32 i = 0; i < files.size(); ++i) + { + mapID = uint32(atoi(files[i].substr(0,3).c_str())); + if (m_tiles.find(mapID) == m_tiles.end()) + { + m_tiles.insert(pair*>(mapID, new set)); + count++; + } + } + + files.clear(); + getDirContents(files, "vmaps", "*.vmtree"); + for (uint32 i = 0; i < files.size(); ++i) + { + mapID = uint32(atoi(files[i].substr(0,3).c_str())); + m_tiles.insert(pair*>(mapID, new set)); + count++; + } + printf("found %u.\n", count); + + count = 0; + printf("Discovering tiles... "); + for (TileList::iterator itr = m_tiles.begin(); itr != m_tiles.end(); ++itr) + { + set* tiles = (*itr).second; + mapID = (*itr).first; + + sprintf(filter, "%03u*.vmtile", mapID); + files.clear(); + getDirContents(files, "vmaps", filter); + for (uint32 i = 0; i < files.size(); ++i) + { + tileX = uint32(atoi(files[i].substr(7,2).c_str())); + tileY = uint32(atoi(files[i].substr(4,2).c_str())); + tileID = StaticMapTree::packTileID(tileY, tileX); + + tiles->insert(tileID); + count++; + } + + sprintf(filter, "%03u*", mapID); + files.clear(); + getDirContents(files, "maps", filter); + for (uint32 i = 0; i < files.size(); ++i) + { + tileY = uint32(atoi(files[i].substr(3,2).c_str())); + tileX = uint32(atoi(files[i].substr(5,2).c_str())); + tileID = StaticMapTree::packTileID(tileX, tileY); + + if (tiles->insert(tileID).second) + count++; + } + } + printf("found %u.\n\n", count); + } + + /**************************************************************************/ + set* MapBuilder::getTileList(uint32 mapID) + { + TileList::iterator itr = m_tiles.find(mapID); + if (itr != m_tiles.end()) + return (*itr).second; + + set* tiles = new set(); + m_tiles.insert(pair*>(mapID, tiles)); + return tiles; + } + + /**************************************************************************/ + void MapBuilder::buildAllMaps() + { + for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) + { + uint32 mapID = (*it).first; + if (!shouldSkipMap(mapID)) + buildMap(mapID); + } + } + + /**************************************************************************/ + void MapBuilder::getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY) + { + maxX = INT_MAX; + maxY = INT_MAX; + minX = INT_MIN; + minY = INT_MIN; + + float bmin[3], bmax[3], lmin[3], lmax[3]; + MeshData meshData; + + // make sure we process maps which don't have tiles + // initialize the static tree, which loads WDT models + if (!m_terrainBuilder->loadVMap(mapID, 64, 64, meshData)) + return; + + // get the coord bounds of the model data + if (meshData.solidVerts.size() + meshData.liquidVerts.size() == 0) + return; + + // get the coord bounds of the model data + if (meshData.solidVerts.size() && meshData.liquidVerts.size()) + { + rcCalcBounds(meshData.solidVerts.getCArray(), meshData.solidVerts.size() / 3, bmin, bmax); + rcCalcBounds(meshData.liquidVerts.getCArray(), meshData.liquidVerts.size() / 3, lmin, lmax); + rcVmin(bmin, lmin); + rcVmax(bmax, lmax); + } + else if (meshData.solidVerts.size()) + rcCalcBounds(meshData.solidVerts.getCArray(), meshData.solidVerts.size() / 3, bmin, bmax); + else + rcCalcBounds(meshData.liquidVerts.getCArray(), meshData.liquidVerts.size() / 3, lmin, lmax); + + // convert coord bounds to grid bounds + maxX = 32 - bmin[0] / GRID_SIZE; + maxY = 32 - bmin[2] / GRID_SIZE; + minX = 32 - bmax[0] / GRID_SIZE; + minY = 32 - bmax[2] / GRID_SIZE; + } + + /**************************************************************************/ + void MapBuilder::buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY) + { + dtNavMesh* navMesh = NULL; + buildNavMesh(mapID, navMesh); + if (!navMesh) + { + printf("Failed creating navmesh! \n"); + return; + } + + buildTile(mapID, tileX, tileY, navMesh); + dtFreeNavMesh(navMesh); + } + + /**************************************************************************/ + void MapBuilder::buildMap(uint32 mapID) + { + printf("Building map %03u:\n", mapID); + + set* tiles = getTileList(mapID); + + // make sure we process maps which don't have tiles + if (!tiles->size()) + { + // convert coord bounds to grid bounds + 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) + tiles->insert(StaticMapTree::packTileID(i, j)); + } + + if (!tiles->size()) + return; + + // build navMesh + dtNavMesh* navMesh = NULL; + buildNavMesh(mapID, navMesh); + if (!navMesh) + { + printf("Failed creating navmesh! \n"); + return; + } + + // now start building mmtiles for each tile + printf("We have %u tiles. \n", (unsigned int)tiles->size()); + for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) + { + uint32 tileX, tileY; + + // unpack tile coords + StaticMapTree::unpackTileID((*it), tileX, tileY); + + if (shouldSkipTile(mapID, tileX, tileY)) + continue; + + buildTile(mapID, tileX, tileY, navMesh); + } + + dtFreeNavMesh(navMesh); + + printf("Complete! \n\n"); + } + + /**************************************************************************/ + void MapBuilder::buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh) + { + printf("Building map %03u, tile [%02u,%02u]\n", mapID, tileX, tileY); + + MeshData meshData; + + // get heightmap data + m_terrainBuilder->loadMap(mapID, tileX, tileY, meshData); + + // get model data + m_terrainBuilder->loadVMap(mapID, tileY, tileX, meshData); + + // if there is no data, give up now + if (!meshData.solidVerts.size() && !meshData.liquidVerts.size()) + return; + + // remove unused vertices + TerrainBuilder::cleanVertices(meshData.solidVerts, meshData.solidTris); + TerrainBuilder::cleanVertices(meshData.liquidVerts, meshData.liquidTris); + + // gather all mesh data for final data check, and bounds calculation + G3D::Array allVerts; + allVerts.append(meshData.liquidVerts); + allVerts.append(meshData.solidVerts); + + if (!allVerts.size()) + return; + + // get bounds of current tile + float bmin[3], bmax[3]; + getTileBounds(tileX, tileY, allVerts.getCArray(), allVerts.size() / 3, bmin, bmax); + + m_terrainBuilder->loadOffMeshConnections(mapID, tileX, tileY, meshData, m_offMeshFilePath); + + // build navmesh tile + buildMoveMapTile(mapID, tileX, tileY, meshData, bmin, bmax, navMesh); + } + + /**************************************************************************/ + void MapBuilder::buildNavMesh(uint32 mapID, dtNavMesh* &navMesh) + { + set* tiles = getTileList(mapID); + + // old code for non-statically assigned bitmask sizes: + ///*** calculate number of bits needed to store tiles & polys ***/ + //int tileBits = dtIlog2(dtNextPow2(tiles->size())); + //if (tileBits < 1) tileBits = 1; // need at least one bit! + //int polyBits = sizeof(dtPolyRef)*8 - SALT_MIN_BITS - tileBits; + + int tileBits = STATIC_TILE_BITS; + int polyBits = STATIC_POLY_BITS; + + int maxTiles = tiles->size(); + int maxPolysPerTile = 1 << polyBits; + + /*** calculate bounds of map ***/ + + uint32 tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0, tileX, tileY; + for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) + { + StaticMapTree::unpackTileID((*it), tileX, tileY); + + if (tileX > tileXMax) + tileXMax = tileX; + else if (tileX < tileXMin) + tileXMin = tileX; + + if (tileY > tileYMax) + tileYMax = tileY; + else if (tileY < tileYMin) + tileYMin = tileY; + } + + // use Max because '32 - tileX' is negative for values over 32 + float bmin[3], bmax[3]; + getTileBounds(tileXMax, tileYMax, NULL, 0, bmin, bmax); + + /*** now create the navmesh ***/ + + // navmesh creation params + dtNavMeshParams navMeshParams; + memset(&navMeshParams, 0, sizeof(dtNavMeshParams)); + navMeshParams.tileWidth = GRID_SIZE; + navMeshParams.tileHeight = GRID_SIZE; + rcVcopy(navMeshParams.orig, bmin); + navMeshParams.maxTiles = maxTiles; + navMeshParams.maxPolys = maxPolysPerTile; + + navMesh = dtAllocNavMesh(); + printf("Creating navMesh... \r"); + if (!navMesh->init(&navMeshParams)) + { + printf("Failed creating navmesh! \n"); + return; + } + + char fileName[25]; + sprintf(fileName, "mmaps/%03u.mmap", mapID); + + FILE* file = fopen(fileName, "wb"); + if (!file) + { + dtFreeNavMesh(navMesh); + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", fileName); + perror(message); + return; + } + + // now that we know navMesh params are valid, we can write them to file + fwrite(&navMeshParams, sizeof(dtNavMeshParams), 1, file); + fclose(file); + } + + /**************************************************************************/ + void MapBuilder::buildMoveMapTile(uint32 mapID, uint32 tileX, uint32 tileY, + MeshData &meshData, float bmin[3], float bmax[3], + dtNavMesh* navMesh) + { + // console output + char tileString[10]; + sprintf(tileString, "[%02i,%02i]: ", tileX, tileY); + printf("%s Building movemap tiles... \r", tileString); + + IntermediateValues iv; + + float* tVerts = meshData.solidVerts.getCArray(); + int tVertCount = meshData.solidVerts.size() / 3; + int* tTris = meshData.solidTris.getCArray(); + int tTriCount = meshData.solidTris.size() / 3; + + float* lVerts = meshData.liquidVerts.getCArray(); + int lVertCount = meshData.liquidVerts.size() / 3; + int* lTris = meshData.liquidTris.getCArray(); + int lTriCount = meshData.liquidTris.size() / 3; + uint8* lTriFlags = meshData.liquidType.getCArray(); + + // these are WORLD UNIT based metrics + // this are basic unit dimentions + // value have to divide GRID_SIZE(533.33333f) ( aka: 0.5333, 0.2666, 0.3333, 0.1333, etc ) + const static float BASE_UNIT_DIM = m_bigBaseUnit ? 0.533333f : 0.266666f; + + // All are in UNIT metrics! + const static int VERTEX_PER_MAP = int(GRID_SIZE/BASE_UNIT_DIM + 0.5f); + const static int VERTEX_PER_TILE = m_bigBaseUnit ? 40 : 80; // must divide VERTEX_PER_MAP + const static int TILES_PER_MAP = VERTEX_PER_MAP/VERTEX_PER_TILE; + + rcConfig config; + memset(&config, 0, sizeof(rcConfig)); + + rcVcopy(config.bmin, bmin); + rcVcopy(config.bmax, bmax); + + config.maxVertsPerPoly = DT_VERTS_PER_POLYGON; + config.cs = BASE_UNIT_DIM; + config.ch = BASE_UNIT_DIM; + config.walkableSlopeAngle = m_maxWalkableAngle; + config.tileSize = VERTEX_PER_TILE; + config.walkableRadius = m_bigBaseUnit ? 1 : 2; + config.borderSize = config.walkableRadius + 3; + config.maxEdgeLen = VERTEX_PER_TILE + 1; //anything bigger than tileSize + config.walkableHeight = m_bigBaseUnit ? 3 : 6; + config.walkableClimb = m_bigBaseUnit ? 2 : 4; // keep less than walkableHeight + config.minRegionArea = rcSqr(60); + config.mergeRegionArea = rcSqr(50); + config.maxSimplificationError = 2.0f; // eliminates most jagged edges (tinny polygons) + config.detailSampleDist = config.cs * 64; + config.detailSampleMaxError = config.ch * 2; + + // this sets the dimensions of the heightfield - should maybe happen before border padding + rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height); + + // allocate subregions : tiles + Tile* tiles = new Tile[TILES_PER_MAP * TILES_PER_MAP]; + + // Initialize per tile config. + rcConfig tileCfg; + memcpy(&tileCfg, &config, sizeof(rcConfig)); + tileCfg.width = config.tileSize + config.borderSize*2; + tileCfg.height = config.tileSize + config.borderSize*2; + + // build all tiles + for (int y = 0; y < TILES_PER_MAP; ++y) + { + for (int x = 0; x < TILES_PER_MAP; ++x) + { + Tile& tile = tiles[x + y*TILES_PER_MAP]; + + // Calculate the per tile bounding box. + tileCfg.bmin[0] = config.bmin[0] + (x*config.tileSize - config.borderSize)*config.cs; + tileCfg.bmin[2] = config.bmin[2] + (y*config.tileSize - config.borderSize)*config.cs; + tileCfg.bmax[0] = config.bmin[0] + ((x+1)*config.tileSize + config.borderSize)*config.cs; + tileCfg.bmax[2] = config.bmin[2] + ((y+1)*config.tileSize + config.borderSize)*config.cs; + + float tbmin[2], tbmax[2]; + tbmin[0] = tileCfg.bmin[0]; + tbmin[1] = tileCfg.bmin[2]; + tbmax[0] = tileCfg.bmax[0]; + tbmax[1] = tileCfg.bmax[2]; + + // build heightfield + tile.solid = rcAllocHeightfield(); + if (!tile.solid || !rcCreateHeightfield(m_rcContext, *tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch)) + { + printf("%sFailed building heightfield! \n", tileString); + continue; + } + + // mark all walkable tiles, both liquids and solids + unsigned char* triFlags = new unsigned char[tTriCount]; + memset(triFlags, NAV_GROUND, tTriCount*sizeof(unsigned char)); + rcClearUnwalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags); + rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.solid, config.walkableClimb); + delete [] triFlags; + + rcFilterLowHangingWalkableObstacles(m_rcContext, config.walkableClimb, *tile.solid); + rcFilterLedgeSpans(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid); + rcFilterWalkableLowHeightSpans(m_rcContext, tileCfg.walkableHeight, *tile.solid); + + rcRasterizeTriangles(m_rcContext, lVerts, lVertCount, lTris, lTriFlags, lTriCount, *tile.solid, config.walkableClimb); + + // compact heightfield spans + tile.chf = rcAllocCompactHeightfield(); + if (!tile.chf || !rcBuildCompactHeightfield(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid, *tile.chf)) + { + printf("%sFailed compacting heightfield! \n", tileString); + continue; + } + + // build polymesh intermediates + if (!rcErodeWalkableArea(m_rcContext, config.walkableRadius, *tile.chf)) + { + printf("%sFailed eroding area! \n", tileString); + continue; + } + + if (!rcBuildDistanceField(m_rcContext, *tile.chf)) + { + printf("%sFailed building distance field! \n", tileString); + continue; + } + + if (!rcBuildRegions(m_rcContext, *tile.chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea)) + { + printf("%sFailed building regions! \n", tileString); + continue; + } + + tile.cset = rcAllocContourSet(); + if (!tile.cset || !rcBuildContours(m_rcContext, *tile.chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *tile.cset)) + { + printf("%sFailed building contours! \n", tileString); + continue; + } + + // build polymesh + tile.pmesh = rcAllocPolyMesh(); + if (!tile.pmesh || !rcBuildPolyMesh(m_rcContext, *tile.cset, tileCfg.maxVertsPerPoly, *tile.pmesh)) + { + printf("%sFailed building polymesh! \n", tileString); + continue; + } + + tile.dmesh = rcAllocPolyMeshDetail(); + if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg .detailSampleMaxError, *tile.dmesh)) + { + printf("%sFailed building polymesh detail! \n", tileString); + continue; + } + + // free those up + // we may want to keep them in the future for debug + // but right now, we don't have the code to merge them + rcFreeHeightField(tile.solid); + tile.solid = NULL; + rcFreeCompactHeightfield(tile.chf); + tile.chf = NULL; + rcFreeContourSet(tile.cset); + tile.cset = NULL; + } + } + + // merge per tile poly and detail meshes + rcPolyMesh** pmmerge = new rcPolyMesh*[TILES_PER_MAP * TILES_PER_MAP]; + if (!pmmerge) + { + printf("%s alloc pmmerge FIALED! \r", tileString); + return; + } + + rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP]; + if (!dmmerge) + { + printf("%s alloc dmmerge FIALED! \r", tileString); + return; + } + + int nmerge = 0; + for (int y = 0; y < TILES_PER_MAP; ++y) + { + for (int x = 0; x < TILES_PER_MAP; ++x) + { + Tile& tile = tiles[x + y*TILES_PER_MAP]; + if (tile.pmesh) + { + pmmerge[nmerge] = tile.pmesh; + dmmerge[nmerge] = tile.dmesh; + nmerge++; + } + } + } + + iv.polyMesh = rcAllocPolyMesh(); + if (!iv.polyMesh) + { + printf("%s alloc iv.polyMesh FIALED! \r", tileString); + return; + } + rcMergePolyMeshes(m_rcContext, pmmerge, nmerge, *iv.polyMesh); + + iv.polyMeshDetail = rcAllocPolyMeshDetail(); + if (!iv.polyMeshDetail) + { + printf("%s alloc m_dmesh FIALED! \r", tileString); + return; + } + rcMergePolyMeshDetails(m_rcContext, dmmerge, nmerge, *iv.polyMeshDetail); + + // free things up + delete [] pmmerge; + delete [] dmmerge; + + delete [] tiles; + + // remove padding for extraction + 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; + } + + // set polygons as walkable + // TODO: special flags for DYNAMIC polygons, ie surfaces that can be turned on and off + for (int i = 0; i < iv.polyMesh->npolys; ++i) + if (iv.polyMesh->areas[i] & RC_WALKABLE_AREA) + iv.polyMesh->flags[i] = iv.polyMesh->areas[i]; + + // setup mesh parameters + dtNavMeshCreateParams params; + memset(¶ms, 0, sizeof(params)); + params.verts = iv.polyMesh->verts; + params.vertCount = iv.polyMesh->nverts; + params.polys = iv.polyMesh->polys; + params.polyAreas = iv.polyMesh->areas; + params.polyFlags = iv.polyMesh->flags; + params.polyCount = iv.polyMesh->npolys; + params.nvp = iv.polyMesh->nvp; + params.detailMeshes = iv.polyMeshDetail->meshes; + params.detailVerts = iv.polyMeshDetail->verts; + params.detailVertsCount = iv.polyMeshDetail->nverts; + params.detailTris = iv.polyMeshDetail->tris; + params.detailTriCount = iv.polyMeshDetail->ntris; + + params.offMeshConVerts = meshData.offMeshConnections.getCArray(); + params.offMeshConCount = meshData.offMeshConnections.size()/6; + params.offMeshConRad = meshData.offMeshConnectionRads.getCArray(); + params.offMeshConDir = meshData.offMeshConnectionDirs.getCArray(); + params.offMeshConAreas = meshData.offMeshConnectionsAreas.getCArray(); + params.offMeshConFlags = meshData.offMeshConnectionsFlags.getCArray(); + + params.walkableHeight = BASE_UNIT_DIM*config.walkableHeight; // agent height + params.walkableRadius = BASE_UNIT_DIM*config.walkableRadius; // agent radius + params.walkableClimb = BASE_UNIT_DIM*config.walkableClimb; // keep less that walkableHeight (aka agent height)! + params.tileX = (((bmin[0] + bmax[0]) / 2) - navMesh->getParams()->orig[0]) / GRID_SIZE; + params.tileY = (((bmin[2] + bmax[2]) / 2) - navMesh->getParams()->orig[2]) / GRID_SIZE; + rcVcopy(params.bmin, bmin); + rcVcopy(params.bmax, bmax); + params.cs = config.cs; + params.ch = config.ch; + params.tileSize = VERTEX_PER_MAP; + + // will hold final navmesh + unsigned char* navData = NULL; + int navDataSize = 0; + + do + { + // these values are checked within dtCreateNavMeshData - handle them here + // so we have a clear error message + if (params.nvp > DT_VERTS_PER_POLYGON) + { + printf("%s Invalid verts-per-polygon value! \n", tileString); + continue; + } + if (params.vertCount >= 0xffff) + { + printf("%s Too many vertices! \n", tileString); + continue; + } + 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 + //printf("%sNo vertices to build tile! \n", tileString); + continue; + } + if (!params.polyCount || !params.polys || + TILES_PER_MAP*TILES_PER_MAP == params.polyCount) + { + // 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 + // drop tiles with only exact count - some tiles may have geometry while having less tiles + printf("%s No polygons to build on tile! \n", tileString); + continue; + } + if (!params.detailMeshes || !params.detailVerts || !params.detailTris) + { + printf("%s No detail mesh to build tile! \n", tileString); + continue; + } + + printf("%s Building navmesh tile... \r", tileString); + if (!dtCreateNavMeshData(¶ms, &navData, &navDataSize)) + { + printf("%s Failed building navmesh tile! \n", tileString); + continue; + } + + dtTileRef tileRef = 0; + printf("%s Adding tile to navmesh... \r", 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 || dtResult != DT_SUCCESS) + { + printf("%s Failed adding tile to navmesh! \n", tileString); + continue; + } + + // file output + char fileName[255]; + sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); + FILE* file = fopen(fileName, "wb"); + if (!file) + { + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", fileName); + perror(message); + navMesh->removeTile(tileRef, NULL, NULL); + continue; + } + + printf("%s Writing to file... \r", tileString); + + // write header + MmapTileHeader header; + header.usesLiquids = m_terrainBuilder->usesLiquids(); + header.size = uint32(navDataSize); + fwrite(&header, sizeof(MmapTileHeader), 1, file); + + // write data + fwrite(navData, sizeof(unsigned char), navDataSize, file); + fclose(file); + + // now that tile is written to disk, we can unload it + navMesh->removeTile(tileRef, NULL, NULL); + } + while (0); + + if (m_debugOutput) + { + // 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; + } + + iv.generateObjFile(mapID, tileX, tileY, meshData); + iv.writeIV(mapID, tileX, tileY); + } + } + + /**************************************************************************/ + void MapBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) + { + // this is for elevation + if (verts && vertCount) + rcCalcBounds(verts, vertCount, bmin, bmax); + else + { + bmin[1] = FLT_MIN; + bmax[1] = FLT_MAX; + } + + // this is for width and depth + bmax[0] = (32 - int(tileX)) * GRID_SIZE; + bmax[2] = (32 - int(tileY)) * GRID_SIZE; + bmin[0] = bmax[0] - GRID_SIZE; + bmin[2] = bmax[2] - GRID_SIZE; + } + + /**************************************************************************/ + bool MapBuilder::shouldSkipMap(uint32 mapID) + { + if (m_skipContinents) + switch (mapID) + { + case 0: + case 1: + case 530: + case 571: + return true; + default: + break; + } + + if (m_skipJunkMaps) + switch (mapID) + { + case 13: // test.wdt + case 25: // ScottTest.wdt + case 29: // Test.wdt + case 42: // Colin.wdt + case 169: // EmeraldDream.wdt (unused, and very large) + case 451: // development.wdt + case 573: // ExteriorTest.wdt + case 597: // CraigTest.wdt + case 605: // development_nonweighted.wdt + case 606: // QA_DVD.wdt + return true; + default: + if (isTransportMap(mapID)) + return true; + break; + } + + if (m_skipBattlegrounds) + switch (mapID) + { + case 30: // AV + case 37: // ? + case 489: // WSG + case 529: // AB + case 566: // EotS + case 607: // SotA + case 628: // IoC + return true; + default: + break; + } + + return false; + } + + /**************************************************************************/ + bool MapBuilder::isTransportMap(uint32 mapID) + { + switch (mapID) + { + // transport maps + case 582: + case 584: + case 586: + case 587: + case 588: + case 589: + case 590: + case 591: + case 592: + case 593: + case 594: + case 596: + case 610: + case 612: + case 613: + case 614: + case 620: + case 621: + case 622: + case 623: + case 641: + case 642: + case 647: + case 672: + case 673: + case 712: + case 713: + case 718: + return true; + default: + return false; + } + } + + /**************************************************************************/ + bool MapBuilder::shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY) + { + char fileName[255]; + sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); + FILE* file = fopen(fileName, "rb"); + if (!file) + return false; + + MmapTileHeader header; + fread(&header, sizeof(MmapTileHeader), 1, file); + fclose(file); + + if (header.mmapMagic != MMAP_MAGIC || header.dtVersion != DT_NAVMESH_VERSION) + return false; + + if (header.mmapVersion != MMAP_VERSION) + return false; + + return true; + } + +} diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h new file mode 100644 index 00000000000..d0f33ce9a79 --- /dev/null +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 MaNGOS + * + * 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 . + */ + +#ifndef _MAP_BUILDER_H +#define _MAP_BUILDER_H + +#include +#include +#include + +#include "TerrainBuilder.h" +#include "IntermediateValues.h" + +#include "IVMapManager.h" +#include "WorldModel.h" + +#include "Recast.h" +#include "DetourNavMesh.h" + +using namespace std; +using namespace VMAP; + +// G3D namespace typedefs conflicts with ACE typedefs + +namespace MMAP +{ + typedef map*> TileList; + struct Tile + { + Tile() : chf(NULL), solid(NULL), cset(NULL), pmesh(NULL), dmesh(NULL) {} + ~Tile() + { + rcFreeCompactHeightfield(chf); + rcFreeContourSet(cset); + rcFreeHeightField(solid); + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + } + rcCompactHeightfield* chf; + rcHeightfield* solid; + rcContourSet* cset; + rcPolyMesh* pmesh; + rcPolyMeshDetail* dmesh; + }; + + class MapBuilder + { + public: + MapBuilder(float maxWalkableAngle = 60.f, + bool skipLiquid = false, + bool skipContinents = false, + bool skipJunkMaps = true, + bool skipBattlegrounds = false, + bool debugOutput = false, + bool bigBaseUnit = false, + const char* offMeshFilePath = NULL); + + ~MapBuilder(); + + // builds all mmap tiles for the specified map id (ignores skip settings) + void buildMap(uint32 mapID); + + // builds an mmap tile for the specified map and its mesh + void buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY); + + // builds list of maps, then builds all of mmap tiles (based on the skip settings) + void buildAllMaps(); + + private: + // detect maps and tiles + void discoverTiles(); + set* getTileList(uint32 mapID); + + void buildNavMesh(uint32 mapID, dtNavMesh* &navMesh); + + void buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh); + + // move map building + void buildMoveMapTile(uint32 mapID, + uint32 tileX, + uint32 tileY, + MeshData &meshData, + float bmin[3], + float bmax[3], + dtNavMesh* navMesh); + + void getTileBounds(uint32 tileX, uint32 tileY, + float* verts, int vertCount, + float* bmin, float* bmax); + void getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY); + + bool shouldSkipMap(uint32 mapID); + bool isTransportMap(uint32 mapID); + bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY); + + TerrainBuilder* m_terrainBuilder; + TileList m_tiles; + + bool m_debugOutput; + + const char* m_offMeshFilePath; + bool m_skipContinents; + bool m_skipJunkMaps; + bool m_skipBattlegrounds; + + float m_maxWalkableAngle; + bool m_bigBaseUnit; + + // build performance - not really used for now + rcContext* m_rcContext; + }; +} + +#endif diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h new file mode 100644 index 00000000000..fd02ec02d50 --- /dev/null +++ b/src/tools/mmaps_generator/PathCommon.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 MaNGOS + * + * 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 . + */ + +#ifndef _MMAP_COMMON_H +#define _MMAP_COMMON_H + +#include +#include + +#include "Define.h" + +#ifndef _WIN32 + #include + #include +#endif + +#ifdef __linux__ + #include +#endif + +using namespace std; + +namespace MMAP +{ + inline bool matchWildcardFilter(const char* filter, const char* str) + { + if (!filter || !str) + return false; + + // end on null character + while (*filter && *str) + { + if (*filter == '*') + { + if (*++filter == '\0') // wildcard at end of filter means all remaing chars match + return true; + + while (true) + { + if (*filter == *str) + break; + if (*str == '\0') + return false; // reached end of string without matching next filter character + str++; + } + } + else if (*filter != *str) + return false; // mismatch + + filter++; + str++; + } + + return ((*filter == '\0' || (*filter == '*' && *++filter == '\0')) && *str == '\0'); + } + + enum ListFilesResult + { + LISTFILE_DIRECTORY_NOT_FOUND = 0, + LISTFILE_OK = 1 + }; + + inline ListFilesResult getDirContents(vector &fileList, string dirpath = ".", string filter = "*", bool includeSubDirs = false) + { + #ifdef WIN32 + HANDLE hFind; + WIN32_FIND_DATA findFileInfo; + string directory; + + directory = dirpath + "/" + filter; + + hFind = FindFirstFile(directory.c_str(), &findFileInfo); + + if (hFind == INVALID_HANDLE_VALUE) + return LISTFILE_DIRECTORY_NOT_FOUND; + do + { + if (includeSubDirs || (findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + fileList.push_back(string(findFileInfo.cFileName)); + } + while (FindNextFile(hFind, &findFileInfo)); + + FindClose(hFind); + + #else + const char *p = dirpath.c_str(); + DIR * dirp = opendir(p); + struct dirent * dp; + dirp = opendir(p); + + while (dirp) + { + errno = 0; + if ((dp = readdir(dirp)) != NULL) + { + if (matchWildcardFilter(filter.c_str(), dp->d_name)) + fileList.push_back(string(dp->d_name)); + } + else + break; + } + + if (dirp) + closedir(dirp); + else + return LISTFILE_DIRECTORY_NOT_FOUND; + #endif + + return LISTFILE_OK; + } +} + +#endif diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp new file mode 100644 index 00000000000..2eb2c6545c4 --- /dev/null +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2005-2011 MaNGOS + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "PathCommon.h" +#include "MapBuilder.h" + +using namespace MMAP; + +bool checkDirectories(bool debugOutput) +{ + vector dirFiles; + + if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size()) + { + printf("'maps' directory is empty or does not exist\n"); + return false; + } + + dirFiles.clear(); + if (getDirContents(dirFiles, "vmaps", "*.vmtree") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size()) + { + printf("'vmaps' directory is empty or does not exist\n"); + return false; + } + + dirFiles.clear(); + if (getDirContents(dirFiles, "mmaps") == LISTFILE_DIRECTORY_NOT_FOUND) + { + printf("'mmaps' directory does not exist\n"); + return false; + } + + dirFiles.clear(); + if (debugOutput) + { + if (getDirContents(dirFiles, "meshes") == LISTFILE_DIRECTORY_NOT_FOUND) + { + printf("'meshes' directory does not exist (no place to put debugOutput files)\n"); + return false; + } + } + + return true; +} + +bool handleArgs(int argc, char** argv, + int &mapnum, + int &tileX, + int &tileY, + float &maxAngle, + bool &skipLiquid, + bool &skipContinents, + bool &skipJunkMaps, + bool &skipBattlegrounds, + bool &debugOutput, + bool &silent, + bool &bigBaseUnit, + char* &offMeshInputPath) +{ + char* param = NULL; + for (int i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "--maxAngle") == 0) + { + param = argv[++i]; + if (!param) + return false; + + float maxangle = atof(param); + if (maxangle <= 90.f && maxangle >= 45.f) + maxAngle = maxangle; + else + printf("invalid option for '--maxAngle', using default\n"); + } + else if (strcmp(argv[i], "--tile") == 0) + { + param = argv[++i]; + if (!param) + return false; + + char* stileX = strtok(param, ","); + char* stileY = strtok(NULL, ","); + int tilex = atoi(stileX); + int tiley = atoi(stileY); + + if ((tilex > 0 && tilex < 64) || (tilex == 0 && strcmp(stileX, "0") == 0)) + tileX = tilex; + if ((tiley > 0 && tiley < 64) || (tiley == 0 && strcmp(stileY, "0") == 0)) + tileY = tiley; + + if (tileX < 0 || tileY < 0) + { + printf("invalid tile coords.\n"); + return false; + } + } + else if (strcmp(argv[i], "--skipLiquid") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + skipLiquid = true; + else if (strcmp(param, "false") == 0) + skipLiquid = false; + else + printf("invalid option for '--skipLiquid', using default\n"); + } + else if (strcmp(argv[i], "--skipContinents") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + skipContinents = true; + else if (strcmp(param, "false") == 0) + skipContinents = false; + else + printf("invalid option for '--skipContinents', using default\n"); + } + else if (strcmp(argv[i], "--skipJunkMaps") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + skipJunkMaps = true; + else if (strcmp(param, "false") == 0) + skipJunkMaps = false; + else + printf("invalid option for '--skipJunkMaps', using default\n"); + } + else if (strcmp(argv[i], "--skipBattlegrounds") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + skipBattlegrounds = true; + else if (strcmp(param, "false") == 0) + skipBattlegrounds = false; + else + printf("invalid option for '--skipBattlegrounds', using default\n"); + } + else if (strcmp(argv[i], "--debugOutput") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + debugOutput = true; + else if (strcmp(param, "false") == 0) + debugOutput = false; + else + printf("invalid option for '--debugOutput', using default true\n"); + } + else if (strcmp(argv[i], "--silent") == 0) + { + silent = true; + } + else if (strcmp(argv[i], "--bigBaseUnit") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + bigBaseUnit = true; + else if (strcmp(param, "false") == 0) + bigBaseUnit = false; + else + printf("invalid option for '--bigBaseUnit', using default false\n"); + } + else if (strcmp(argv[i], "--offMeshInput") == 0) + { + param = argv[++i]; + if (!param) + return false; + + offMeshInputPath = param; + } + else + { + int map = atoi(argv[i]); + if (map > 0 || (map == 0 && (strcmp(argv[i], "0") == 0))) + mapnum = map; + else + { + printf("invalid map id\n"); + return false; + } + } + } + + return true; +} + +int finish(const char* message, int returnValue) +{ + printf("%s", message); + getchar(); + return returnValue; +} + +int main(int argc, char** argv) +{ + int mapnum = -1; + float maxAngle = 60.0f; + int tileX = -1, tileY = -1; + bool skipLiquid = false, + skipContinents = false, + skipJunkMaps = true, + skipBattlegrounds = false, + debugOutput = false, + silent = false, + bigBaseUnit = false; + char* offMeshInputPath = NULL; + + bool validParam = handleArgs(argc, argv, mapnum, + tileX, tileY, maxAngle, + skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, + debugOutput, silent, bigBaseUnit, offMeshInputPath); + + if (!validParam) + return silent ? -1 : finish("You have specified invalid parameters", -1); + + if (mapnum == -1 && debugOutput) + { + if (silent) + return -2; + + printf("You have specifed debug output, but didn't specify a map to generate.\n"); + printf("This will generate debug output for ALL maps.\n"); + printf("Are you sure you want to continue? (y/n) "); + if (getchar() != 'y') + return 0; + } + + if (!checkDirectories(debugOutput)) + return silent ? -3 : finish("Press any key to close...", -3); + + MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps, + skipBattlegrounds, debugOutput, bigBaseUnit, offMeshInputPath); + + if (tileX > -1 && tileY > -1 && mapnum >= 0) + builder.buildSingleTile(mapnum, tileX, tileY); + else if (mapnum >= 0) + builder.buildMap(uint32(mapnum)); + else + builder.buildAllMaps(); + + return silent ? 1 : finish("Movemap build is complete!", 1); +} diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp new file mode 100644 index 00000000000..c696f6017a5 --- /dev/null +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -0,0 +1,854 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 MaNGOS + * + * 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 . + */ + +#include "TerrainBuilder.h" + +#include "PathCommon.h" +#include "MapBuilder.h" + +#include "VMapManager2.h" +#include "MapTree.h" +#include "ModelInstance.h" + +namespace MMAP +{ + TerrainBuilder::TerrainBuilder(bool skipLiquid) : m_skipLiquid (skipLiquid){ } + TerrainBuilder::~TerrainBuilder() { } + + /**************************************************************************/ + void TerrainBuilder::getLoopVars(Spot portion, int &loopStart, int &loopEnd, int &loopInc) + { + switch (portion) + { + case ENTIRE: + loopStart = 0; + loopEnd = V8_SIZE_SQ; + loopInc = 1; + break; + case TOP: + loopStart = 0; + loopEnd = V8_SIZE; + loopInc = 1; + break; + case LEFT: + loopStart = 0; + loopEnd = V8_SIZE_SQ - V8_SIZE + 1; + loopInc = V8_SIZE; + break; + case RIGHT: + loopStart = V8_SIZE - 1; + loopEnd = V8_SIZE_SQ; + loopInc = V8_SIZE; + break; + case BOTTOM: + loopStart = V8_SIZE_SQ - V8_SIZE; + loopEnd = V8_SIZE_SQ; + loopInc = 1; + break; + } + } + + /**************************************************************************/ + void TerrainBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) + { + if (loadMap(mapID, tileX, tileY, meshData, ENTIRE)) + { + loadMap(mapID, tileX+1, tileY, meshData, LEFT); + loadMap(mapID, tileX-1, tileY, meshData, RIGHT); + loadMap(mapID, tileX, tileY+1, meshData, TOP); + loadMap(mapID, tileX, tileY-1, meshData, BOTTOM); + } + } + + /**************************************************************************/ + bool TerrainBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, Spot portion) + { + char mapFileName[255]; + sprintf(mapFileName, "maps/%03u%02u%02u.map", mapID, tileY, tileX); + + FILE* mapFile = fopen(mapFileName, "rb"); + if (!mapFile) + return false; + + map_fileheader fheader; + fread(&fheader, sizeof(map_fileheader), 1, mapFile); + + if (fheader.versionMagic != *((uint32 const*)(MAP_VERSION_MAGIC))) + { + fclose(mapFile); + printf("%s is the wrong version, please extract new .map files\n", mapFileName); + return false; + } + + map_heightHeader hheader; + fseek(mapFile, fheader.heightMapOffset, SEEK_SET); + fread(&hheader, sizeof(map_heightHeader), 1, mapFile); + + bool haveTerrain = !(hheader.flags & MAP_HEIGHT_NO_HEIGHT); + bool haveLiquid = fheader.liquidMapOffset && !m_skipLiquid; + + // no data in this map file + if (!haveTerrain && !haveLiquid) + { + fclose(mapFile); + return false; + } + + // data used later + uint16 holes[16][16]; + memset(holes, 0, sizeof(holes)); + uint8 liquid_type[16][16]; + memset(liquid_type, 0, sizeof(liquid_type)); + G3D::Array ltriangles; + G3D::Array ttriangles; + + // terrain data + if (haveTerrain) + { + int i; + float heightMultiplier; + float V9[V9_SIZE_SQ], V8[V8_SIZE_SQ]; + + if (hheader.flags & MAP_HEIGHT_AS_INT8) + { + uint8 v9[V9_SIZE_SQ]; + uint8 v8[V8_SIZE_SQ]; + fread(v9, sizeof(uint8), V9_SIZE_SQ, mapFile); + fread(v8, sizeof(uint8), V8_SIZE_SQ, mapFile); + heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 255; + + for (i = 0; i < V9_SIZE_SQ; ++i) + V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight; + + for (i = 0; i < V8_SIZE_SQ; ++i) + V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight; + } + else if (hheader.flags & MAP_HEIGHT_AS_INT16) + { + uint16 v9[V9_SIZE_SQ]; + uint16 v8[V8_SIZE_SQ]; + fread(v9, sizeof(uint16), V9_SIZE_SQ, mapFile); + fread(v8, sizeof(uint16), V8_SIZE_SQ, mapFile); + heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 65535; + + for (i = 0; i < V9_SIZE_SQ; ++i) + V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight; + + for (i = 0; i < V8_SIZE_SQ; ++i) + V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight; + } + else + { + fread (V9, sizeof(float), V9_SIZE_SQ, mapFile); + fread(V8, sizeof(float), V8_SIZE_SQ, mapFile); + } + + // hole data + memset(holes, 0, fheader.holesSize); + fseek(mapFile, fheader.holesOffset, SEEK_SET); + fread(holes, fheader.holesSize, 1, mapFile); + + int count = meshData.solidVerts.size() / 3; + float xoffset = (float(tileX)-32)*GRID_SIZE; + float yoffset = (float(tileY)-32)*GRID_SIZE; + + float coord[3]; + + for (i = 0; i < V9_SIZE_SQ; ++i) + { + getHeightCoord(i, GRID_V9, xoffset, yoffset, coord, V9); + meshData.solidVerts.append(coord[0]); + meshData.solidVerts.append(coord[2]); + meshData.solidVerts.append(coord[1]); + } + + for (i = 0; i < V8_SIZE_SQ; ++i) + { + getHeightCoord(i, GRID_V8, xoffset, yoffset, coord, V8); + meshData.solidVerts.append(coord[0]); + meshData.solidVerts.append(coord[2]); + meshData.solidVerts.append(coord[1]); + } + + int j, indices[3], loopStart, loopEnd, loopInc; + getLoopVars(portion, loopStart, loopEnd, loopInc); + for (i = loopStart; i < loopEnd; i+=loopInc) + for (j = TOP; j <= BOTTOM; j+=1) + { + getHeightTriangle(i, Spot(j), indices); + ttriangles.append(indices[2] + count); + ttriangles.append(indices[1] + count); + ttriangles.append(indices[0] + count); + } + } + + // liquid data + if (haveLiquid) + { + map_liquidHeader lheader; + fseek(mapFile, fheader.liquidMapOffset, SEEK_SET); + fread(&lheader, sizeof(map_liquidHeader), 1, mapFile); + + float* liquid_map = NULL; + + if (!(lheader.flags & MAP_LIQUID_NO_TYPE)) + fread(liquid_type, sizeof(liquid_type), 1, mapFile); + + if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) + { + liquid_map = new float [lheader.width*lheader.height]; + fread(liquid_map, sizeof(float), lheader.width*lheader.height, mapFile); + } + + if (liquid_type && liquid_map) + { + int count = meshData.liquidVerts.size() / 3; + float xoffset = (float(tileX)-32)*GRID_SIZE; + float yoffset = (float(tileY)-32)*GRID_SIZE; + + float coord[3]; + int row, col; + + // generate coordinates + if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) + { + int j = 0; + for (int i = 0; i < V9_SIZE_SQ; ++i) + { + row = i / V9_SIZE; + col = i % V9_SIZE; + + if (row < lheader.offsetY || row >= lheader.offsetY + lheader.height || + col < lheader.offsetX || col >= lheader.offsetX + lheader.width) + { + // dummy vert using invalid height + meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, INVALID_MAP_LIQ_HEIGHT, (yoffset+row*GRID_PART_SIZE)*-1); + continue; + } + + getLiquidCoord(i, j, xoffset, yoffset, coord, liquid_map); + meshData.liquidVerts.append(coord[0]); + meshData.liquidVerts.append(coord[2]); + meshData.liquidVerts.append(coord[1]); + j++; + } + } + else + { + for (int i = 0; i < V9_SIZE_SQ; ++i) + { + row = i / V9_SIZE; + col = i % V9_SIZE; + meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, lheader.liquidLevel, (yoffset+row*GRID_PART_SIZE)*-1); + } + } + + delete [] liquid_map; + + int indices[3], loopStart, loopEnd, loopInc, triInc; + getLoopVars(portion, loopStart, loopEnd, loopInc); + triInc = BOTTOM-TOP; + + // generate triangles + for (int i = loopStart; i < loopEnd; i+=loopInc) + for (int j = TOP; j <= BOTTOM; j+= triInc) + { + getHeightTriangle(i, Spot(j), indices, true); + ltriangles.append(indices[2] + count); + ltriangles.append(indices[1] + count); + ltriangles.append(indices[0] + count); + } + } + } + + fclose(mapFile); + + // now that we have gathered the data, we can figure out which parts to keep: + // liquid above ground, ground above liquid + int loopStart, loopEnd, loopInc, tTriCount = 4; + bool useTerrain, useLiquid; + + float* lverts = meshData.liquidVerts.getCArray(); + int* ltris = ltriangles.getCArray(); + + float* tverts = meshData.solidVerts.getCArray(); + int* ttris = ttriangles.getCArray(); + + if (ltriangles.size() + ttriangles.size() == 0) + return false; + + // make a copy of liquid vertices + // used to pad right-bottom frame due to lost vertex data at extraction + float* lverts_copy = NULL; + if (meshData.liquidVerts.size()) + { + lverts_copy = new float[meshData.liquidVerts.size()]; + memcpy(lverts_copy, lverts, sizeof(float)*meshData.liquidVerts.size()); + } + + getLoopVars(portion, loopStart, loopEnd, loopInc); + for (int i = loopStart; i < loopEnd; i+=loopInc) + { + for (int j = 0; j < 2; ++j) + { + // default is true, will change to false if needed + useTerrain = true; + useLiquid = true; + uint8 liquidType = MAP_LIQUID_TYPE_NO_WATER; + + // if there is no liquid, don't use liquid + if (!liquid_type || !meshData.liquidVerts.size() || !ltriangles.size()) + useLiquid = false; + else + { + liquidType = getLiquidType(i, liquid_type); + switch (liquidType) + { + default: + useLiquid = false; + break; + case MAP_LIQUID_TYPE_WATER: + case MAP_LIQUID_TYPE_OCEAN: + // merge different types of water + liquidType = NAV_WATER; + break; + case MAP_LIQUID_TYPE_MAGMA: + liquidType = NAV_MAGMA; + break; + case MAP_LIQUID_TYPE_SLIME: + liquidType = NAV_SLIME; + break; + case MAP_LIQUID_TYPE_DARK_WATER: + // players should not be here, so logically neither should creatures + useTerrain = false; + useLiquid = false; + break; + } + } + + // if there is no terrain, don't use terrain + if (!ttriangles.size()) + useTerrain = false; + + // while extracting ADT data we are losing right-bottom vertices + // this code adds fair approximation of lost data + if (useLiquid) + { + float quadHeight = 0; + uint32 validCount = 0; + for(uint32 idx = 0; idx < 3; idx++) + { + float h = lverts_copy[ltris[idx]*3 + 1]; + if (h != INVALID_MAP_LIQ_HEIGHT && h < INVALID_MAP_LIQ_HEIGHT_MAX) + { + quadHeight += h; + validCount++; + } + } + + // update vertex height data + if (validCount > 0 && validCount < 3) + { + quadHeight /= validCount; + for(uint32 idx = 0; idx < 3; idx++) + { + float h = lverts[ltris[idx]*3 + 1]; + if (h == INVALID_MAP_LIQ_HEIGHT || h > INVALID_MAP_LIQ_HEIGHT_MAX) + lverts[ltris[idx]*3 + 1] = quadHeight; + } + } + + // no valid vertexes - don't use this poly at all + if (validCount == 0) + useLiquid = false; + } + + // if there is a hole here, don't use the terrain + if (useTerrain) + useTerrain = !isHole(i, holes); + + // we use only one terrain kind per quad - pick higher one + if (useTerrain && useLiquid) + { + float minLLevel = INVALID_MAP_LIQ_HEIGHT_MAX; + float maxLLevel = INVALID_MAP_LIQ_HEIGHT; + for(uint32 x = 0; x < 3; x++) + { + float h = lverts[ltris[x]*3 + 1]; + if (minLLevel > h) + minLLevel = h; + + if (maxLLevel < h) + maxLLevel = h; + } + + float maxTLevel = INVALID_MAP_LIQ_HEIGHT; + float minTLevel = INVALID_MAP_LIQ_HEIGHT_MAX; + for(uint32 x = 0; x < 6; x++) + { + float h = tverts[ttris[x]*3 + 1]; + if (maxTLevel < h) + maxTLevel = h; + + if (minTLevel > h) + minTLevel = h; + } + + // terrain under the liquid? + if (minLLevel > maxTLevel) + useTerrain = false; + + //liquid under the terrain? + if (minTLevel > maxLLevel) + useLiquid = false; + } + + // store the result + if (useLiquid) + { + meshData.liquidType.append(liquidType); + for (int k = 0; k < 3; ++k) + meshData.liquidTris.append(ltris[k]); + } + + if (useTerrain) + for (int k = 0; k < 3*tTriCount/2; ++k) + meshData.solidTris.append(ttris[k]); + + // advance to next set of triangles + ltris += 3; + ttris += 3*tTriCount/2; + } + } + + if (lverts_copy) + delete [] lverts_copy; + + return meshData.solidTris.size() || meshData.liquidTris.size(); + } + + /**************************************************************************/ + void TerrainBuilder::getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v) + { + // wow coords: x, y, height + // coord is mirroed about the horizontal axes + switch (grid) + { + case GRID_V9: + coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f; + coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f; + coord[2] = v[index]; + break; + case GRID_V8: + coord[0] = (xOffset + index%(V8_SIZE)*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f; + coord[1] = (yOffset + (int)(index/(V8_SIZE))*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f; + coord[2] = v[index]; + break; + } + } + + /**************************************************************************/ + void TerrainBuilder::getHeightTriangle(int square, Spot triangle, int* indices, bool liquid/* = false*/) + { + int rowOffset = square/V8_SIZE; + if (!liquid) + switch (triangle) + { + case TOP: + indices[0] = square+rowOffset; // 0-----1 .... 128 + indices[1] = square+1+rowOffset; // |\ T /| + indices[2] = (V9_SIZE_SQ)+square; // | \ / | + break; // |L 0 R| .. 127 + case LEFT: // | / \ | + indices[0] = square+rowOffset; // |/ B \| + indices[1] = (V9_SIZE_SQ)+square; // 129---130 ... 386 + indices[2] = square+V9_SIZE+rowOffset; // |\ /| + break; // | \ / | + case RIGHT: // | 128 | .. 255 + indices[0] = square+1+rowOffset; // | / \ | + indices[1] = square+V9_SIZE+1+rowOffset; // |/ \| + indices[2] = (V9_SIZE_SQ)+square; // 258---259 ... 515 + break; + case BOTTOM: + indices[0] = (V9_SIZE_SQ)+square; + indices[1] = square+V9_SIZE+1+rowOffset; + indices[2] = square+V9_SIZE+rowOffset; + break; + default: break; + } + else + switch (triangle) + { // 0-----1 .... 128 + case TOP: // |\ | + indices[0] = square+rowOffset; // | \ T | + indices[1] = square+1+rowOffset; // | \ | + indices[2] = square+V9_SIZE+1+rowOffset; // | B \ | + break; // | \| + case BOTTOM: // 129---130 ... 386 + indices[0] = square+rowOffset; // |\ | + indices[1] = square+V9_SIZE+1+rowOffset; // | \ | + indices[2] = square+V9_SIZE+rowOffset; // | \ | + break; // | \ | + default: break; // | \| + } // 258---259 ... 515 + + } + + /**************************************************************************/ + void TerrainBuilder::getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v) + { + // wow coords: x, y, height + // coord is mirroed about the horizontal axes + coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f; + coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f; + coord[2] = v[index2]; + } + + static uint16 holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888}; + static uint16 holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; + + /**************************************************************************/ + bool TerrainBuilder::isHole(int square, const uint16 holes[16][16]) + { + int row = square / 128; + int col = square % 128; + int cellRow = row / 8; // 8 squares per cell + int cellCol = col / 8; + int holeRow = row % 8 / 2; + int holeCol = (square - (row * 128 + cellCol * 8)) / 2; + + uint16 hole = holes[cellRow][cellCol]; + + return (hole & holetab_h[holeCol] & holetab_v[holeRow]) != 0; + } + + /**************************************************************************/ + uint8 TerrainBuilder::getLiquidType(int square, const uint8 liquid_type[16][16]) + { + int row = square / 128; + int col = square % 128; + int cellRow = row / 8; // 8 squares per cell + int cellCol = col / 8; + + return liquid_type[cellRow][cellCol]; + } + + /**************************************************************************/ + bool TerrainBuilder::loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) + { + IVMapManager* vmapManager = new VMapManager2(); + int result = vmapManager->loadMap("vmaps", mapID, tileX, tileY); + bool retval = false; + + do + { + if (result == VMAP_LOAD_RESULT_ERROR) + break; + + InstanceTreeMap instanceTrees; + ((VMapManager2*)vmapManager)->getInstanceMapTree(instanceTrees); + + if (!instanceTrees[mapID]) + break; + + ModelInstance* models = NULL; + uint32 count = 0; + instanceTrees[mapID]->getModelInstances(models, count); + + if (!models) + break; + + for (uint32 i = 0; i < count; ++i) + { + ModelInstance instance = models[i]; + + // model instances exist in tree even though there are instances of that model in this tile + WorldModel* worldModel = instance.getWorldModel(); + if (!worldModel) + continue; + + // now we have a model to add to the meshdata + retval = true; + + vector groupModels; + worldModel->getGroupModels(groupModels); + + // all M2s need to have triangle indices reversed + bool isM2 = instance.name.find(".m2") != instance.name.npos || instance.name.find(".M2") != instance.name.npos; + + // transform data + float scale = instance.iScale; + G3D::Matrix3 rotation = G3D::Matrix3::fromEulerAnglesXYZ(G3D::pi()*instance.iRot.z/-180.f, G3D::pi()*instance.iRot.x/-180.f, G3D::pi()*instance.iRot.y/-180.f); + Vector3 position = instance.iPos; + position.x -= 32*GRID_SIZE; + position.y -= 32*GRID_SIZE; + + for (vector::iterator it = groupModels.begin(); it != groupModels.end(); ++it) + { + vector tempVertices; + vector transformedVertices; + vector tempTriangles; + WmoLiquid* liquid = NULL; + + (*it).getMeshData(tempVertices, tempTriangles, liquid); + + // first handle collision mesh + transform(tempVertices, transformedVertices, scale, rotation, position); + + int offset = meshData.solidVerts.size() / 3; + + copyVertices(transformedVertices, meshData.solidVerts); + copyIndices(tempTriangles, meshData.solidTris, offset, isM2); + + // now handle liquid data + if (liquid) + { + vector liqVerts; + vector liqTris; + uint32 tilesX, tilesY, vertsX, vertsY; + Vector3 corner; + liquid->getPosInfo(tilesX, tilesY, corner); + vertsX = tilesX + 1; + vertsY = tilesY + 1; + uint8* flags = liquid->GetFlagsStorage(); + float* data = liquid->GetHeightStorage(); + uint8 type = NAV_EMPTY; + + // convert liquid type to NavTerrain + switch (liquid->GetType()) + { + case 0: + case 1: + type = NAV_WATER; + break; + case 2: + type = NAV_MAGMA; + break; + case 3: + type = NAV_SLIME; + break; + } + + // 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 + + Vector3 vert; + for (uint32 x = 0; x < vertsX; ++x) + for (uint32 y = 0; y < vertsY; ++y) + { + vert = 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) + for (uint32 y = 0; y < tilesY; ++y) + 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); + } + + 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); + } + } + } + } + } + while (false); + + vmapManager->unloadMap(mapID, tileX, tileY); + delete vmapManager; + + return retval; + } + + /**************************************************************************/ + void TerrainBuilder::transform(vector &source, vector &transformedVertices, float scale, G3D::Matrix3 &rotation, Vector3 &position) + { + for (vector::iterator it = source.begin(); it != source.end(); ++it) + { + // apply tranform, then mirror along the horizontal axes + Vector3 v((*it) * rotation * scale + position); + v.x *= -1.f; + v.y *= -1.f; + transformedVertices.push_back(v); + } + } + + /**************************************************************************/ + void TerrainBuilder::copyVertices(vector &source, G3D::Array &dest) + { + for (vector::iterator it = source.begin(); it != source.end(); ++it) + { + dest.push_back((*it).y); + dest.push_back((*it).z); + dest.push_back((*it).x); + } + } + + /**************************************************************************/ + void TerrainBuilder::copyIndices(vector &source, G3D::Array &dest, int offset, bool flip) + { + if (flip) + { + for (vector::iterator it = source.begin(); it != source.end(); ++it) + { + dest.push_back((*it).idx2+offset); + dest.push_back((*it).idx1+offset); + dest.push_back((*it).idx0+offset); + } + } + else + { + for (vector::iterator it = source.begin(); it != source.end(); ++it) + { + dest.push_back((*it).idx0+offset); + dest.push_back((*it).idx1+offset); + dest.push_back((*it).idx2+offset); + } + } + } + + /**************************************************************************/ + void TerrainBuilder::copyIndices(G3D::Array &source, G3D::Array &dest, int offset) + { + int* src = source.getCArray(); + for (int32 i = 0; i < source.size(); ++i) + dest.append(src[i] + offset); + } + + /**************************************************************************/ + void TerrainBuilder::cleanVertices(G3D::Array &verts, G3D::Array &tris) + { + map vertMap; + + int* t = tris.getCArray(); + float* v = verts.getCArray(); + + // collect all the vertex indices from triangle + for (int i = 0; i < tris.size(); ++i) + { + if (vertMap.find(t[i]) != vertMap.end()) + continue; + + vertMap.insert(std::pair(t[i], 0)); + } + + // collect the vertices + G3D::Array cleanVerts; + int index, count = 0; + for (map::iterator it = vertMap.begin(); it != vertMap.end(); ++it) + { + index = (*it).first; + (*it).second = count; + cleanVerts.append(v[index*3], v[index*3+1], v[index*3+2]); + count++; + } + verts.fastClear(); + verts.append(cleanVerts); + cleanVerts.clear(); + + // update triangles to use new indices + for (int i = 0; i < tris.size(); ++i) + { + map::iterator it; + if ((it = vertMap.find(t[i])) == vertMap.end()) + continue; + + t[i] = (*it).second; + } + + vertMap.clear(); + } + + /**************************************************************************/ + void TerrainBuilder::loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char* offMeshFilePath) + { + // no meshfile input given? + if (offMeshFilePath == NULL) + return; + + FILE* fp = fopen(offMeshFilePath, "rb"); + if (!fp) + { + printf(" loadOffMeshConnections:: input file %s not found!\n", offMeshFilePath); + return; + } + + // pretty silly thing, as we parse entire file and load only the tile we need + // but we don't expect this file to be too large + char* buf = new char[512]; + while(fgets(buf, 512, fp)) + { + float p0[3], p1[3]; + int mid, tx, ty; + float size; + if (10 != sscanf(buf, "%d %d,%d (%f %f %f) (%f %f %f) %f", &mid, &tx, &ty, + &p0[0], &p0[1], &p0[2], &p1[0], &p1[1], &p1[2], &size)) + continue; + + if (mapID == mid, tileX == tx, tileY == ty) + { + meshData.offMeshConnections.append(p0[1]); + meshData.offMeshConnections.append(p0[2]); + meshData.offMeshConnections.append(p0[0]); + + meshData.offMeshConnections.append(p1[1]); + meshData.offMeshConnections.append(p1[2]); + meshData.offMeshConnections.append(p1[0]); + + meshData.offMeshConnectionDirs.append(1); // 1 - both direction, 0 - one sided + meshData.offMeshConnectionRads.append(size); // agent size equivalent + // can be used same way as polygon flags + meshData.offMeshConnectionsAreas.append((unsigned char)0xFF); + meshData.offMeshConnectionsFlags.append((unsigned short)0xFF); // all movement masks can make this path + } + + } + + delete [] buf; + fclose(fp); + } +} diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h new file mode 100644 index 00000000000..a7f21883af2 --- /dev/null +++ b/src/tools/mmaps_generator/TerrainBuilder.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 MaNGOS + * + * 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 . + */ + +#ifndef _MMAP_TERRAIN_BUILDER_H +#define _MMAP_TERRAIN_BUILDER_H + +#include "PathCommon.h" +#include "Map.h" +#include "SharedDefines.h" + +#include "WorldModel.h" + +#include "G3D/Array.h" +#include "G3D/Vector3.h" +#include "G3D/Matrix3.h" + +using namespace Trinity; + +namespace MMAP +{ + enum Spot + { + TOP = 1, + RIGHT = 2, + LEFT = 3, + BOTTOM = 4, + ENTIRE = 5 + }; + + enum Grid + { + GRID_V8, + GRID_V9 + }; + + static const int V9_SIZE = 129; + static const int V9_SIZE_SQ = V9_SIZE*V9_SIZE; + static const int V8_SIZE = 128; + static const int V8_SIZE_SQ = V8_SIZE*V8_SIZE; + static const float GRID_SIZE = 533.33333f; + static const float GRID_PART_SIZE = GRID_SIZE/V8_SIZE; + + // see contrib/extractor/system.cpp, CONF_use_minHeight + static const float INVALID_MAP_LIQ_HEIGHT = -500.f; + static const float INVALID_MAP_LIQ_HEIGHT_MAX = 5000.0f; + + // see following files: + // contrib/extractor/system.cpp + // src/game/Map.cpp + static char const* MAP_VERSION_MAGIC = "v1.2"; + + struct MeshData + { + G3D::Array solidVerts; + G3D::Array solidTris; + + G3D::Array liquidVerts; + G3D::Array liquidTris; + G3D::Array liquidType; + + // offmesh connection data + G3D::Array offMeshConnections; // [p0y,p0z,p0x,p1y,p1z,p1x] - per connection + G3D::Array offMeshConnectionRads; + G3D::Array offMeshConnectionDirs; + G3D::Array offMeshConnectionsAreas; + G3D::Array offMeshConnectionsFlags; + }; + + class TerrainBuilder + { + public: + TerrainBuilder(bool skipLiquid); + ~TerrainBuilder(); + + void loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); + bool loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); + void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char* offMeshFilePath); + + bool usesLiquids() { return !m_skipLiquid; } + + // vert and triangle methods + static void transform(vector &original, vector &transformed, + float scale, G3D::Matrix3 &rotation, G3D::Vector3 &position); + static void copyVertices(vector &source, G3D::Array &dest); + static void copyIndices(vector &source, G3D::Array &dest, int offest, bool flip); + static void copyIndices(G3D::Array &src, G3D::Array &dest, int offset); + static void cleanVertices(G3D::Array &verts, G3D::Array &tris); + private: + /// Loads a portion of a map's terrain + bool loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, Spot portion); + + /// Sets loop variables for selecting only certain parts of a map's terrain + void getLoopVars(Spot portion, int &loopStart, int &loopEnd, int &loopInc); + + /// Controls whether liquids are loaded + bool m_skipLiquid; + + /// Load the map terrain from file + bool loadHeightMap(uint32 mapID, uint32 tileX, uint32 tileY, G3D::Array &vertices, G3D::Array &triangles, Spot portion); + + /// Get the vector coordinate for a specific position + void getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v); + + /// Get the triangle's vector indices for a specific position + void getHeightTriangle(int square, Spot triangle, int* indices, bool liquid = false); + + /// Determines if the specific position's triangles should be rendered + bool isHole(int square, const uint16 holes[16][16]); + + /// Get the liquid vector coordinate for a specific position + void getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v); + + /// Get the liquid type for a specific position + uint8 getLiquidType(int square, const uint8 liquid_type[16][16]); + + // hide parameterless and copy constructor + TerrainBuilder(); + TerrainBuilder(const TerrainBuilder &tb); + }; +} + +#endif + diff --git a/src/tools/mmaps_generator/VMapExtensions.cpp b/src/tools/mmaps_generator/VMapExtensions.cpp new file mode 100644 index 00000000000..4f203e11c21 --- /dev/null +++ b/src/tools/mmaps_generator/VMapExtensions.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 MaNGOS + * + * 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 . + */ + +#include +#include "MapTree.h" +#include "VMapManager2.h" +#include "WorldModel.h" +#include "ModelInstance.h" + +using namespace std; + +namespace VMAP +{ + // Need direct access to encapsulated VMAP data, so we add functions for MMAP generator + // maybe add MapBuilder as friend to all of the below classes would be better? + + // declared in src/shared/vmap/MapTree.h + void StaticMapTree::getModelInstances(ModelInstance* &models, uint32 &count) + { + models = iTreeValues; + count = iNTreeValues; + } + + // declared in src/shared/vmap/VMapManager2.h + void VMapManager2::getInstanceMapTree(InstanceTreeMap &instanceMapTree) + { + instanceMapTree = iInstanceMapTrees; + } + + // declared in src/shared/vmap/WorldModel.h + void WorldModel::getGroupModels(vector &groupModels) + { + groupModels = this->groupModels; + } + + // declared in src/shared/vmap/WorldModel.h + void GroupModel::getMeshData(vector &vertices, vector &triangles, WmoLiquid* &liquid) + { + vertices = this->vertices; + triangles = this->triangles; + liquid = iLiquid; + } + + // declared in src/shared/vmap/ModelInstance.h + WorldModel* const ModelInstance::getWorldModel() + { + return iModel; + } + + // declared in src/shared/vmap/WorldModel.h + void WmoLiquid::getPosInfo(uint32 &tilesX, uint32 &tilesY, Vector3 &corner) const + { + tilesX = iTilesX; + tilesY = iTilesY; + corner = iCorner; + } +} -- cgit v1.2.3 From d06c09271295f8199fa45ae9b7d8e2eb600bbe26 Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 17:17:31 +0200 Subject: fix linker error. --- src/tools/mmaps_generator/MapBuilder.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/tools') diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 3ca158f0127..2987e6596dd 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -28,6 +28,11 @@ // These make the linker happy. LoginDatabaseWorkerPool LoginDatabase; +uint32 GetLiquidFlags(uint32 liquidType) +{ + return 0; +} + #include "DisableMgr.h" namespace DisableMgr { -- cgit v1.2.3 From 5061fa626a72fa7c2632a4b2cef318633c56d85b Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 22 Aug 2012 17:39:25 -0500 Subject: Core/Mmaps: * Unload instanced mmaps before unloading the base map * Load only mmaps for base map on map creation * Extractor: Somewhat speed improvement --- src/server/game/Maps/Map.cpp | 9 +- src/server/game/Movement/MotionMaster.h | 4 +- src/tools/mmaps_generator/IntermediateValues.cpp | 2 +- src/tools/mmaps_generator/MapBuilder.cpp | 105 +++++++++++++++-------- src/tools/mmaps_generator/MapBuilder.h | 1 + src/tools/mmaps_generator/PathGenerator.cpp | 17 +++- src/tools/mmaps_generator/TerrainBuilder.cpp | 23 +++-- 7 files changed, 106 insertions(+), 55 deletions(-) (limited to 'src/tools') diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index b38f89eab8f..5e3699146f2 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -71,8 +71,8 @@ Map::~Map() if (!m_scriptSchedule.empty()) sScriptMgr->DecreaseScheduledScriptCount(m_scriptSchedule.size()); - MMAP::MMapFactory::createOrGetMMapManager()->unloadMap(GetId()); MMAP::MMapFactory::createOrGetMMapManager()->unloadMapInstance(GetId(), i_InstanceId); + MMAP::MMapFactory::createOrGetMMapManager()->unloadMap(GetId()); } bool Map::ExistMap(uint32 mapid, int gx, int gy) @@ -206,9 +206,12 @@ void Map::LoadMap(int gx, int gy, bool reload) void Map::LoadMapAndVMap(int gx, int gy) { LoadMap(gx, gy); - LoadMMap(gx, gy); + // Only load the data for the base map if (i_InstanceId == 0) - LoadVMap(gx, gy); // Only load the data for the base map + { + LoadVMap(gx, gy); + LoadMMap(gx, gy); + } } void Map::InitStateMachine() diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index f10c6569cad..918896a5a81 100755 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -154,13 +154,13 @@ class MotionMaster //: private std::stack void MoveFleeing(Unit* enemy, uint32 time = 0); void MovePoint(uint32 id, const Position &pos) { MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ); } - void MovePoint(uint32 id, float x, float y, float z, bool generatePath = false); + void MovePoint(uint32 id, float x, float y, float z, bool generatePath = true); // These two movement types should only be used with creatures having landing/takeoff animations void MoveLand(uint32 id, Position const& pos); void MoveTakeoff(uint32 id, Position const& pos); - void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE, bool generatePath = false); + void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE, bool generatePath = true); void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ); void MoveJumpTo(float angle, float speedXY, float speedZ); void MoveJump(float x, float y, float z, float speedXY, float speedZ, uint32 id = 0); diff --git a/src/tools/mmaps_generator/IntermediateValues.cpp b/src/tools/mmaps_generator/IntermediateValues.cpp index 9eefb1e65f0..b473d6472a0 100644 --- a/src/tools/mmaps_generator/IntermediateValues.cpp +++ b/src/tools/mmaps_generator/IntermediateValues.cpp @@ -202,7 +202,7 @@ namespace MMAP void IntermediateValues::generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) { char objFileName[255]; - sprintf(objFileName, "meshes/map%03u.obj", mapID); + sprintf(objFileName, "meshes/map%03u%02u%02u.obj", mapID, tileY, tileX); FILE* objFile = fopen(objFileName, "wb"); if (!objFile) diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 2987e6596dd..e47b2e5b44f 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -24,6 +24,7 @@ #include "LoginDatabase.h" #include "DetourNavMeshBuilder.h" +#include "DetourNavMesh.h" #include "DetourCommon.h" // These make the linker happy. @@ -206,6 +207,56 @@ namespace MMAP minX = 32 - bmax[0] / GRID_SIZE; minY = 32 - bmax[2] / GRID_SIZE; } + + void MapBuilder::buildMeshFromFile(char* name) + { + FILE* file = fopen(name, "rb"); + if (!file) + return; + + printf("Building mesh from file\n"); + int tileX, tileY, mapId; + fread(&mapId, sizeof(int), 1, file); + fread(&tileX, sizeof(int), 1, file); + fread(&tileY, sizeof(int), 1, file); + + dtNavMesh* navMesh = NULL; + buildNavMesh(mapId, navMesh); + if (!navMesh) + { + printf("Failed creating navmesh! \n"); + fclose(file); + return; + } + + + int verticesCount, indicesCount; + fread(&verticesCount, sizeof(int), 1, file); + fread(&indicesCount, sizeof(int), 1, file); + + float* verts = new float[verticesCount]; + int* inds = new int[indicesCount]; + + fread(verts, sizeof(float), verticesCount, file); + fread(inds, sizeof(int), indicesCount, file); + + MeshData data; + + for (int i = 0; i < verticesCount; ++i) + data.solidVerts.append(verts[i]); + + for (int i = 0; i < indicesCount; ++i) + data.solidTris.append(inds[i]); + + TerrainBuilder::cleanVertices(data.solidVerts, data.solidTris); + // get bounds of current tile + float bmin[3], bmax[3]; + getTileBounds(tileX, tileY, data.solidVerts.getCArray(), data.solidVerts.size() / 3, bmin, bmax); + + // build navmesh tile + buildMoveMapTile(mapId, tileX, tileY, data, bmin, bmax, navMesh); + fclose(file); + } /**************************************************************************/ void MapBuilder::buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY) @@ -451,17 +502,32 @@ namespace MMAP Tile* tiles = new Tile[TILES_PER_MAP * TILES_PER_MAP]; // Initialize per tile config. - rcConfig tileCfg; - memcpy(&tileCfg, &config, sizeof(rcConfig)); + rcConfig tileCfg = config; tileCfg.width = config.tileSize + config.borderSize*2; tileCfg.height = config.tileSize + config.borderSize*2; + // merge per tile poly and detail meshes + rcPolyMesh** pmmerge = new rcPolyMesh*[TILES_PER_MAP * TILES_PER_MAP]; + if (!pmmerge) + { + printf("%s alloc pmmerge FIALED! \r", tileString); + return; + } + + rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP]; + if (!dmmerge) + { + printf("%s alloc dmmerge FIALED! \r", tileString); + return; + } + + int nmerge = 0; // build all tiles for (int y = 0; y < TILES_PER_MAP; ++y) { for (int x = 0; x < TILES_PER_MAP; ++x) { - Tile& tile = tiles[x + y*TILES_PER_MAP]; + Tile& tile = tiles[x + y * TILES_PER_MAP]; // Calculate the per tile bounding box. tileCfg.bmin[0] = config.bmin[0] + (x*config.tileSize - config.borderSize)*config.cs; @@ -469,12 +535,6 @@ namespace MMAP tileCfg.bmax[0] = config.bmin[0] + ((x+1)*config.tileSize + config.borderSize)*config.cs; tileCfg.bmax[2] = config.bmin[2] + ((y+1)*config.tileSize + config.borderSize)*config.cs; - float tbmin[2], tbmax[2]; - tbmin[0] = tileCfg.bmin[0]; - tbmin[1] = tileCfg.bmin[2]; - tbmax[0] = tileCfg.bmax[0]; - tbmax[1] = tileCfg.bmax[2]; - // build heightfield tile.solid = rcAllocHeightfield(); if (!tile.solid || !rcCreateHeightfield(m_rcContext, *tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch)) @@ -488,7 +548,7 @@ namespace MMAP memset(triFlags, NAV_GROUND, tTriCount*sizeof(unsigned char)); rcClearUnwalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags); rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.solid, config.walkableClimb); - delete [] triFlags; + delete[] triFlags; rcFilterLowHangingWalkableObstacles(m_rcContext, config.walkableClimb, *tile.solid); rcFilterLedgeSpans(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid); @@ -554,30 +614,7 @@ namespace MMAP tile.chf = NULL; rcFreeContourSet(tile.cset); tile.cset = NULL; - } - } - - // merge per tile poly and detail meshes - rcPolyMesh** pmmerge = new rcPolyMesh*[TILES_PER_MAP * TILES_PER_MAP]; - if (!pmmerge) - { - printf("%s alloc pmmerge FIALED! \r", tileString); - return; - } - - rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP]; - if (!dmmerge) - { - printf("%s alloc dmmerge FIALED! \r", tileString); - return; - } - - int nmerge = 0; - for (int y = 0; y < TILES_PER_MAP; ++y) - { - for (int x = 0; x < TILES_PER_MAP; ++x) - { - Tile& tile = tiles[x + y*TILES_PER_MAP]; + if (tile.pmesh) { pmmerge[nmerge] = tile.pmesh; diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index d0f33ce9a79..20789bf9bff 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -74,6 +74,7 @@ namespace MMAP // builds all mmap tiles for the specified map id (ignores skip settings) void buildMap(uint32 mapID); + void buildMeshFromFile(char* name); // builds an mmap tile for the specified map and its mesh void buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY); diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 2eb2c6545c4..7d9f59ed138 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -70,7 +70,8 @@ bool handleArgs(int argc, char** argv, bool &debugOutput, bool &silent, bool &bigBaseUnit, - char* &offMeshInputPath) + char* &offMeshInputPath, + char* &file) { char* param = NULL; for (int i = 1; i < argc; ++i) @@ -87,6 +88,13 @@ bool handleArgs(int argc, char** argv, else printf("invalid option for '--maxAngle', using default\n"); } + else if (strcmp(argv[i], "--file") == 0) + { + param = argv[++i]; + if (!param) + return false; + file = param; + } else if (strcmp(argv[i], "--tile") == 0) { param = argv[++i]; @@ -235,11 +243,12 @@ int main(int argc, char** argv) silent = false, bigBaseUnit = false; char* offMeshInputPath = NULL; + char* file = NULL; bool validParam = handleArgs(argc, argv, mapnum, tileX, tileY, maxAngle, skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, - debugOutput, silent, bigBaseUnit, offMeshInputPath); + debugOutput, silent, bigBaseUnit, offMeshInputPath, file); if (!validParam) return silent ? -1 : finish("You have specified invalid parameters", -1); @@ -262,7 +271,9 @@ int main(int argc, char** argv) MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, debugOutput, bigBaseUnit, offMeshInputPath); - if (tileX > -1 && tileY > -1 && mapnum >= 0) + if (file) + builder.buildMeshFromFile(file); + else if (tileX > -1 && tileY > -1 && mapnum >= 0) builder.buildSingleTile(mapnum, tileX, tileY); else if (mapnum >= 0) builder.buildMap(uint32(mapnum)); diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index c696f6017a5..e16dd16707b 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -767,25 +767,24 @@ namespace MMAP int* t = tris.getCArray(); float* v = verts.getCArray(); + G3D::Array cleanVerts; + int index, count = 0; // collect all the vertex indices from triangle for (int i = 0; i < tris.size(); ++i) { if (vertMap.find(t[i]) != vertMap.end()) continue; - - vertMap.insert(std::pair(t[i], 0)); - } - - // collect the vertices - G3D::Array cleanVerts; - int index, count = 0; - for (map::iterator it = vertMap.begin(); it != vertMap.end(); ++it) - { - index = (*it).first; - (*it).second = count; - cleanVerts.append(v[index*3], v[index*3+1], v[index*3+2]); + std::pair val; + val.first = t[i]; + + index = val.first; + val.second = count; + + vertMap.insert(val); + cleanVerts.append(v[index * 3], v[index * 3 + 1], v[index * 3 + 2]); count++; } + verts.fastClear(); verts.append(cleanVerts); cleanVerts.clear(); -- cgit v1.2.3 From 4c765aad3ddb0e8a890ee163cf3162d14c396d7e Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 22 Aug 2012 18:00:58 -0500 Subject: Core/Maps: Reduce the output map file size in the maps extractor for maps that do not have any hole information Core/Mmaps: Fixed swimming creatures stuck in water. (Thanks Vlad and @Chevron ) Note: Re-extract maps --- src/server/game/Maps/Map.cpp | 33 ++++++++-------------- .../TargetedMovementGenerator.cpp | 3 -- src/tools/map_extractor/System.cpp | 19 +++++++++---- src/tools/mmaps_generator/TerrainBuilder.cpp | 11 +++++--- 4 files changed, 33 insertions(+), 33 deletions(-) (limited to 'src/tools') diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 5e3699146f2..80668d23ed8 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -42,7 +42,7 @@ union u_map_magic }; u_map_magic MapMagic = { {'M','A','P','S'} }; -u_map_magic MapVersionMagic = { {'v','1','.','2'} }; +u_map_magic MapVersionMagic = { {'v','1','.','3'} }; u_map_magic MapAreaMagic = { {'A','R','E','A'} }; u_map_magic MapHeightMagic = { {'M','H','G','T'} }; u_map_magic MapLiquidMagic = { {'M','L','I','Q'} }; @@ -124,19 +124,12 @@ bool Map::ExistVMap(uint32 mapid, int gx, int gy) void Map::LoadMMap(int gx, int gy) { // DONT CHANGE "gy" and "gx" - Its necessary ! - int mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gy, gx); - switch (mmapLoadResult) - { - case MMAP::MMAP_LOAD_RESULT_OK: - sLog->outDetail("MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); - break; - case MMAP::MMAP_LOAD_RESULT_ERROR: - sLog->outDetail("Could not load MMAP name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); - break; - case MMAP::MMAP_LOAD_RESULT_IGNORED: - sLog->outStaticDebug("Ignored MMAP name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); - break; - } + bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gy, gx); + + if (result) + sLog->outDetail("MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); + else + sLog->outDetail("Could not load MMAP name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); } void Map::LoadVMap(int gx, int gy) @@ -187,18 +180,16 @@ void Map::LoadMap(int gx, int gy, bool reload) } // map file name - char *tmp=NULL; - int len = sWorld->GetDataPath().length()+strlen("maps/%03u%02u%02u.map")+1; + char* tmp = NULL; + int len = sWorld->GetDataPath().length() + strlen("maps/%03u%02u%02u.map") + 1; tmp = new char[len]; - snprintf(tmp, len, (char *)(sWorld->GetDataPath()+"maps/%03u%02u%02u.map").c_str(), GetId(), gx, gy); + snprintf(tmp, len, (char *)(sWorld->GetDataPath() + "maps/%03u%02u%02u.map").c_str(), GetId(), gx, gy); sLog->outInfo(LOG_FILTER_MAPS, "Loading map %s", tmp); // loading data GridMaps[gx][gy] = new GridMap(); if (!GridMaps[gx][gy]->loadData(tmp)) - { sLog->outError(LOG_FILTER_MAPS, "Error loading map file: \n %s\n", tmp); - } - delete [] tmp; + delete[] tmp; sScriptMgr->OnLoadGridMap(this, GridMaps[gx][gy], gx, gy); } @@ -1094,7 +1085,7 @@ GridMap::~GridMap() unloadData(); } -bool GridMap::loadData(char *filename) +bool GridMap::loadData(char* filename) { // Unload old data if exist unloadData(); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 766fe0b8032..1fc2ab5a6cb 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -125,9 +125,6 @@ bool TargetedMovementGeneratorMedium::Update(T &owner, const uint32 & time_ return true; } - if (owner.GetTypeId() == TYPEID_UNIT && !i_target->isInAccessiblePlaceFor((const Creature*)&owner)) - return false; - // prevent movement while casting spells with cast time or channel time if (owner.HasUnitState(UNIT_STATE_CASTING)) { diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index e34bc4221e7..ad9a663ac27 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -276,7 +276,7 @@ void ReadLiquidTypeTableDBC() // Map file format data static char const* MAP_MAGIC = "MAPS"; -static char const* MAP_VERSION_MAGIC = "v1.2"; +static char const* MAP_VERSION_MAGIC = "v1.3"; static char const* MAP_AREA_MAGIC = "AREA"; static char const* MAP_HEIGHT_MAGIC = "MHGT"; static char const* MAP_LIQUID_MAGIC = "MLIQ"; @@ -836,8 +836,8 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, else map.holesOffset = map.heightMapOffset + map.heightMapSize; - map.holesSize = sizeof(holes); memset(holes, 0, map.holesSize); + bool hasHoles = false; for (int i = 0; i < ADT_CELLS_PER_GRID; ++i) { @@ -847,12 +847,19 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, if (!cell) continue; holes[i][j] = cell->holes; + if (!hasHoles && cell->holes != 0) + hasHoles = true; } } + + if (hasHoles) + map.holesSize = sizeof(holes); + else + map.holesSize = 0; // Ok all data prepared - store it - FILE *output=fopen(filename2, "wb"); - if(!output) + FILE* output = fopen(filename2, "wb"); + if (!output) { printf("Can't create the output file '%s'\n", filename2); return false; @@ -899,8 +906,10 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, fwrite(&liquid_height[y+liquidHeader.offsetY][liquidHeader.offsetX], sizeof(float), liquidHeader.width, output); } } + // store hole data - fwrite(holes, map.holesSize, 1, output); + if (hasHoles) + fwrite(holes, map.holesSize, 1, output); fclose(output); diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index e16dd16707b..7ee4dc7f46c 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -159,9 +159,12 @@ namespace MMAP } // hole data - memset(holes, 0, fheader.holesSize); - fseek(mapFile, fheader.holesOffset, SEEK_SET); - fread(holes, fheader.holesSize, 1, mapFile); + if (fheader.holesSize != 0) + { + memset(holes, 0, fheader.holesSize); + fseek(mapFile, fheader.holesOffset, SEEK_SET); + fread(holes, fheader.holesSize, 1, mapFile); + } int count = meshData.solidVerts.size() / 3; float xoffset = (float(tileX)-32)*GRID_SIZE; @@ -379,7 +382,7 @@ namespace MMAP } // if there is a hole here, don't use the terrain - if (useTerrain) + if (useTerrain && fheader.holesSize != 0) useTerrain = !isHole(i, holes); // we use only one terrain kind per quad - pick higher one -- cgit v1.2.3 From 937518181f2513e4ef43700d5b856349ebb7c7e6 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 24 Aug 2012 11:38:39 -0500 Subject: Core/Mmaps: Fixed build after last merge --- src/server/collision/Management/MMapManager.cpp | 30 +++++++++++----------- src/server/game/Maps/Map.cpp | 6 ++--- .../PathFinderMovementGenerator.cpp | 6 ++--- src/server/game/Movement/Spline/MoveSplineInit.cpp | 21 ++++++++++----- src/server/game/Movement/Spline/MoveSplineInit.h | 18 +------------ src/server/game/World/World.cpp | 4 +-- src/tools/mmaps_generator/TerrainBuilder.h | 2 +- 7 files changed, 40 insertions(+), 47 deletions(-) (limited to 'src/tools') diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp index 449abcb967d..0222f1a5995 100644 --- a/src/server/collision/Management/MMapManager.cpp +++ b/src/server/collision/Management/MMapManager.cpp @@ -60,14 +60,14 @@ namespace MMAP if (DT_SUCCESS != mesh->init(¶ms)) { dtFreeNavMesh(mesh); - sLog->outError("MMAP:loadMapData: Failed to initialize dtNavMesh for mmap %03u from file %s", mapId, fileName); + sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap %03u from file %s", mapId, fileName); delete [] fileName; return false; } delete [] fileName; - sLog->outDetail("MMAP:loadMapData: Loaded %03i.mmap", mapId); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:loadMapData: Loaded %03i.mmap", mapId); // store inside our map list MMapData* mmap_data = new MMapData(mesh); @@ -118,13 +118,13 @@ namespace MMAP if (fileHeader.mmapMagic != MMAP_MAGIC) { - sLog->outError("MMAP:loadMap: Bad header in mmap %03u%02i%02i.mmtile", mapId, y, x); + sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Bad header in mmap %03u%02i%02i.mmtile", mapId, y, x); return false; } if (fileHeader.mmapVersion != MMAP_VERSION) { - sLog->outError("MMAP:loadMap: %03u%02i%02i.mmtile was built with generator v%i, expected v%i", + sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: %03u%02i%02i.mmtile was built with generator v%i, expected v%i", mapId, x, y, fileHeader.mmapVersion, MMAP_VERSION); return false; } @@ -135,7 +135,7 @@ namespace MMAP size_t result = fread(data, fileHeader.size, 1, file); if (!result) { - sLog->outError("MMAP:loadMap: Bad header or data in mmap %03u%02i%02i.mmtile", mapId, y, x); + sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Bad header or data in mmap %03u%02i%02i.mmtile", mapId, y, x); fclose(file); return false; } @@ -150,12 +150,12 @@ namespace MMAP { mmap->mmapLoadedTiles.insert(std::pair(packedGridPos, tileRef)); ++loadedTiles; - sLog->outDetail("MMAP:loadMap: Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", mapId, y, x, mapId, header->x, header->y); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:loadMap: Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", mapId, y, x, mapId, header->x, header->y); return true; } else { - sLog->outError("MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, y, x); + sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, y, x); dtFree(data); return false; } @@ -192,14 +192,14 @@ namespace MMAP // this is technically a memory leak // if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used // we cannot recover from this error - assert out - sLog->outError("MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, y, x); + sLog->outError(LOG_FILTER_MAPS, "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, y, x); ASSERT(false); } else { mmap->mmapLoadedTiles.erase(packedGridPos); --loadedTiles; - sLog->outDetail("MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, y, x, mapId); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, y, x, mapId); return true; } @@ -222,17 +222,17 @@ namespace MMAP uint32 x = (i->first >> 16); uint32 y = (i->first & 0x0000FFFF); if (DT_SUCCESS != mmap->navMesh->removeTile(i->second, NULL, NULL)) - sLog->outError("MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, y, x); + sLog->outError(LOG_FILTER_MAPS, "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, y, x); else { --loadedTiles; - sLog->outDetail("MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, y, x, mapId); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, y, x, mapId); } } delete mmap; loadedMMaps.erase(mapId); - sLog->outDetail("MMAP:unloadMap: Unloaded %03i.mmap", mapId); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded %03i.mmap", mapId); return true; } @@ -258,7 +258,7 @@ namespace MMAP dtFreeNavMeshQuery(query); mmap->navMeshQueries.erase(instanceId); - sLog->outDetail("MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId); return true; } @@ -285,11 +285,11 @@ namespace MMAP if (DT_SUCCESS != query->init(mmap->navMesh, 1024)) { dtFreeNavMeshQuery(query); - sLog->outError("MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); + sLog->outError(LOG_FILTER_MAPS, "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); return NULL; } - sLog->outDetail("MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); mmap->navMeshQueries.insert(std::pair(instanceId, query)); } diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 80668d23ed8..c960d8123fe 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -126,10 +126,10 @@ void Map::LoadMMap(int gx, int gy) // DONT CHANGE "gy" and "gx" - Its necessary ! bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gy, gx); - if (result) - sLog->outDetail("MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); + if (mmapLoadResult) + sLog->outInfo(LOG_FILTER_MAPS, "MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); else - sLog->outDetail("Could not load MMAP name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); + sLog->outInfo(LOG_FILTER_MAPS, "Could not load MMAP name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); } void Map::LoadVMap(int gx, int gy) diff --git a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp index 82dcbc07648..8988aa599da 100644 --- a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp @@ -88,7 +88,7 @@ bool PathFinderMovementGenerator::calculate(float destX, float destY, float dest { // our target is not moving - we just coming closer // we are moving on precalculated path - enjoy the ride - sLog->outStaticDebug("++ PathFinderMovementGenerator::calculate:: precalculated path\n"); + sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::calculate:: precalculated path\n"); m_pathPoints.erase(m_pathPoints.begin()); return false; @@ -367,7 +367,7 @@ void PathFinderMovementGenerator::BuildPolyPath(const Vector3 &startPos, const V // this is probably an error state, but we'll leave it // and hopefully recover on the next Update // we still need to copy our preffix - sLog->outError("%u's Path Build failed: 0 length path", m_sourceUnit->GetGUIDLow()); + sLog->outError(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", m_sourceUnit->GetGUIDLow()); } sLog->outDebug(LOG_FILTER_MAPS, "++ m_polyLength=%u prefixPolyLength=%u suffixPolyLength=%u \n",m_polyLength, prefixPolyLength, suffixPolyLength); @@ -399,7 +399,7 @@ void PathFinderMovementGenerator::BuildPolyPath(const Vector3 &startPos, const V if (!m_polyLength || dtResult != DT_SUCCESS) { // only happens if we passed bad data to findPath(), or navmesh is messed up - sLog->outError("%u's Path Build failed: 0 length path", m_sourceUnit->GetGUIDLow()); + sLog->outError(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", m_sourceUnit->GetGUIDLow()); BuildShortcut(); m_type = PATHFIND_NOPATH; return; diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index 5fca373503e..7452efc94ca 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -79,7 +79,7 @@ namespace Movement // should i do the things that user should do? - no. if (args.path.empty()) - return; + return 0; // corrent first vertex args.path[0] = real_position; @@ -148,12 +148,21 @@ namespace Movement args.flags.EnableFacingAngle(); } - void MoveSplineInit::MoveTo(Vector3 const& dest) + void MoveSplineInit::MoveTo(const Vector3& dest, bool generatePath, bool forceDestination) { - args.path_Idx_offset = 0; - args.path.resize(2); - TransportPathTransform transform(unit, args.TransformForTransport); - args.path[1] = transform(dest); + if (generatePath) + { + PathFinderMovementGenerator path(&unit); + path.calculate(dest.x, dest.y, dest.z, forceDestination); + MovebyPath(path.getPath()); + } + else + { + args.path_Idx_offset = 0; + args.path.resize(2); + TransportPathTransform transform(unit, args.TransformForTransport); + args.path[1] = transform(dest); + } } Vector3 TransportPathTransform::operator()(Vector3 input) diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h index 740914c59db..9130d2827e6 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.h +++ b/src/server/game/Movement/Spline/MoveSplineInit.h @@ -161,26 +161,10 @@ namespace Movement inline void MoveSplineInit::MoveTo(float x, float y, float z, bool generatePath, bool forceDestination) { - Vector3 v(x,y,z); + Vector3 v(x, y, z); MoveTo(v, generatePath, forceDestination); } - inline void MoveSplineInit::MoveTo(const Vector3& dest, bool generatePath, bool forceDestination) - { - if (generatePath) - { - PathFinderMovementGenerator path(&unit); - path.calculate(dest.x, dest.y, dest.z, forceDestination); - MovebyPath(path.getPath()); - } - else - { - args.path_Idx_offset = 0; - args.path.resize(2); - args.path[1] = dest; - } - } - inline void MoveSplineInit::SetParabolic(float amplitude, float time_shift) { args.time_perc = time_shift; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 0d55d7a52e8..dee1b6dcdb8 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1125,8 +1125,8 @@ void World::LoadConfigSettings(bool reload) } m_bool_configs[CONFIG_ENABLE_MMAPS] = ConfigMgr::GetBoolDefault("mmap.enablePathFinding", true); - sLog->outString("WORLD: MMap data directory is: %smmaps", m_dataPath.c_str()); - MMap::MMapFactory::preventPathfindingOnMaps(ConfigMgr::GetStringDefault("mmap.ignoreMapIds", "").c_str()); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "WORLD: MMap data directory is: %smmaps", m_dataPath.c_str()); + MMAP::MMapFactory::preventPathfindingOnMaps(ConfigMgr::GetStringDefault("mmap.ignoreMapIds", "").c_str()); m_bool_configs[CONFIG_VMAP_INDOOR_CHECK] = ConfigMgr::GetBoolDefault("vmap.enableIndoorCheck", 0); bool enableIndoor = ConfigMgr::GetBoolDefault("vmap.enableIndoorCheck", true); diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h index a7f21883af2..6d478753279 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.h +++ b/src/tools/mmaps_generator/TerrainBuilder.h @@ -62,7 +62,7 @@ namespace MMAP // see following files: // contrib/extractor/system.cpp // src/game/Map.cpp - static char const* MAP_VERSION_MAGIC = "v1.2"; + static char const* MAP_VERSION_MAGIC = "v1.3"; struct MeshData { -- cgit v1.2.3 From 4351548c750f94425d8b7c24180a813acb6ac443 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 24 Aug 2012 15:33:38 -0500 Subject: Tools/MapExtractor: Fixed a crash caused by using a variable before it was initialized --- src/tools/map_extractor/System.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index ad9a663ac27..44e852b12b9 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -836,7 +836,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, else map.holesOffset = map.heightMapOffset + map.heightMapSize; - memset(holes, 0, map.holesSize); + memset(holes, 0, sizeof(holes)); bool hasHoles = false; for (int i = 0; i < ADT_CELLS_PER_GRID; ++i) -- cgit v1.2.3 From f8cc38d65a3b8bca5f93f57e7f4cf7f93df2b38b Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 25 Aug 2012 11:38:33 -0500 Subject: Core/Mmaps: Make the mmaps_generator multithreaded, you can specify the max number of threads that are spawned at the same time (default 3) by using "--threads x" in the command line, where x is the number of threads you want. Core/Mmaps: Removed now useless sh script --- contrib/extract/extract_data.sh | 162 ---------------------------- contrib/extract/libmysql.dll | Bin 2316288 -> 0 bytes contrib/extract/mapextractor.exe | Bin 314368 -> 0 bytes contrib/extract/mmaps_generator.exe | Bin 2224128 -> 0 bytes contrib/extract/offmesh.txt | 3 - contrib/extract/only_extract_offmesh.sh | 158 --------------------------- contrib/extract/vmap4assembler.exe | Bin 1427456 -> 0 bytes contrib/extract/vmap4extractor.exe | Bin 321536 -> 0 bytes src/tools/mmaps_generator/MapBuilder.cpp | 74 ++++++++----- src/tools/mmaps_generator/MapBuilder.h | 20 +++- src/tools/mmaps_generator/PathGenerator.cpp | 17 ++- 11 files changed, 78 insertions(+), 356 deletions(-) delete mode 100644 contrib/extract/extract_data.sh delete mode 100644 contrib/extract/libmysql.dll delete mode 100644 contrib/extract/mapextractor.exe delete mode 100644 contrib/extract/mmaps_generator.exe delete mode 100644 contrib/extract/offmesh.txt delete mode 100644 contrib/extract/only_extract_offmesh.sh delete mode 100644 contrib/extract/vmap4assembler.exe delete mode 100644 contrib/extract/vmap4extractor.exe (limited to 'src/tools') diff --git a/contrib/extract/extract_data.sh b/contrib/extract/extract_data.sh deleted file mode 100644 index d28c7b7d7f5..00000000000 --- a/contrib/extract/extract_data.sh +++ /dev/null @@ -1,162 +0,0 @@ -#!/bin/sh - -# Copyright (C) 2005-2012 MaNGOS project -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -## Expected param 1 to be 'a' for all, else ask some questions - -## Normal log file (if not overwritten by second param -LOG_FILE="TrinityCoreExtractor.log" -## Detailed log file -DETAIL_LOG_FILE="TrinityCoreExtractor_detailed.log" - -## Change this to a value fitting for your sys! -NUM_CPU="2" - -## ! Use below only for finetuning or if you know what you are doing ! - -USE_MAPS="0" -USE_VMAPS="0" -USE_MMAPS="0" -USE_MMAPS_OFFMESH="0" - -if [ "$1" = "a" ] -then - ## extract all - USE_MAPS="1" - USE_VMAPS="1" - USE_MMAPS="1" -else - ## do some questioning! - echo - echo "Welcome to helper script to extract required dataz for TrinityCore!" - echo "Should all dataz (dbc, maps, vmaps and mmaps be extracted? (y/n)" - read line - if [ "$line" = "y" ] - then - ## extract all - USE_MAPS="1" - USE_VMAPS="1" - USE_MMAPS="1" - else - echo - echo "Should dbc and maps be extracted? (y/n)" - read line - if [ "$line" = "y" ]; then USE_MAPS="1"; fi - - echo - echo "Should vmaps be extracted? (y/n)" - read line - if [ "$line" = "y" ]; then USE_VMAPS="1"; fi - - echo - echo "Should mmaps be extracted? (y/n)" - echo "WARNING! This will take several hours!" - read line - if [ "$line" = "y" ] - then - USE_MMAPS="1"; - else - echo "Only reextract offmesh tiles for mmaps?" - read line - if [ "$line" = "y" ] - then - USE_MMAPS_OFFMESH="1"; - fi - fi - fi -fi - -## Special case: Only reextract offmesh tiles -if [ "$USE_MMAPS_OFFMESH" = "1" ] -then - echo "Only extracting offmesh meshes" - only_extract_offmesh.sh offmesh $LOG_FILE $DETAIL_LOG_FILE - exit 0 -fi - -## Obtain numbe ob processes -if [ "$USE_MMAPS" = "1" ] -then - echo "How many CPUs should be used for extracting mmaps? (1-4)" - read line - if [ "$line" -ge "1" -a "$line" -le "4" ] - then - NUM_CPU=$line - else - echo "Only number between 1 and 4 supported!" - exit 1 - fi -fi - -## Give some status -echo "Current Settings: Extract DBCs/maps: $USE_AD, Extract vmaps: $USE_VMAPS, Extract mmaps: $USE_MMAPS on $NUM_CPU processes" -if [ "$1" != "a" ] -then - echo "If you don't like this settings, interrupt with CTRL+C" - read line -fi - -echo "`date`: Start extracting dataz for TrinityCore" | tee $LOG_FILE - -## Handle log messages -if [ "$USE_AD" = "1" ]; -then - echo "DBC and map files will be extracted" | tee -a $LOG_FILE -else - echo "DBC and map files won't be extracted!" | tee -a $LOG_FILE -fi -if [ "$USE_VMAPS" = "1" ] -then - echo "Vmaps will be extracted" | tee -a $LOG_FILE -else - echo "Vmaps won't be extracted!" | tee -a $LOG_FILE -fi -if [ "$USE_MMAPS" = "1" ] -then - echo "Mmaps will be extracted with $NUM_CPU processes" | tee -a $LOG_FILE -else - echo "Mmaps files won't be extracted!" | tee -a $LOG_FILE -fi -echo | tee -a $LOG_FILE - -echo "`date`: Start extracting dataz for TrinityCore, DBCs/maps $USE_AD, vmaps $USE_VMAPS, mmaps $USE_MMAPS on $NUM_CPU processes" | tee $DETAIL_LOG_FILE -echo | tee -a $DETAIL_LOG_FILE - -## Extract dbcs and maps -if [ "$USE_AD" = "1" ] -then - echo "`date`: Start extraction of DBCs and map files..." | tee -a $LOG_FILE - ad | tee -a $DETAIL_LOG_FILE - echo "`date`: Extracting of DBCs and map files finished" | tee -a $LOG_FILE - echo | tee -a $LOG_FILE - echo | tee -a $DETAIL_LOG_FILE -fi - -## Extract vmaps -if [ "$USE_VMAPS" = "1" ] -then - echo "`date`: Start extraction of vmaps..." | tee -a $LOG_FILE - vmap4extractor | tee -a $DETAIL_LOG_FILE - echo "`date`: Extracting of vmaps finished" | tee -a $LOG_FILE - mkdir vmaps - echo "`date`: Start assembling of vmaps..." | tee -a $LOG_FILE - vmap4assembler.exe buildings vmaps | tee -a $DETAIL_LOG_FILE - echo "`date`: Assembling of vmaps finished" | tee -a $LOG_FILE - - echo | tee -a $LOG_FILE - echo | tee -a $DETAIL_LOG_FILE -fi - -## Extract mmaps -if [ "$USE_MMAPS" = "1" ] -then - only_extract_offmesh.sh $NUM_CPU $LOG_FILE $DETAIL_LOG_FILE -fi diff --git a/contrib/extract/libmysql.dll b/contrib/extract/libmysql.dll deleted file mode 100644 index 36de6064f98..00000000000 Binary files a/contrib/extract/libmysql.dll and /dev/null differ diff --git a/contrib/extract/mapextractor.exe b/contrib/extract/mapextractor.exe deleted file mode 100644 index ae6d150ba0e..00000000000 Binary files a/contrib/extract/mapextractor.exe and /dev/null differ diff --git a/contrib/extract/mmaps_generator.exe b/contrib/extract/mmaps_generator.exe deleted file mode 100644 index 8cd9ff65c26..00000000000 Binary files a/contrib/extract/mmaps_generator.exe and /dev/null differ diff --git a/contrib/extract/offmesh.txt b/contrib/extract/offmesh.txt deleted file mode 100644 index 10299a2c696..00000000000 --- a/contrib/extract/offmesh.txt +++ /dev/null @@ -1,3 +0,0 @@ -0 31,59 (-14429.889648 450.344452 15.430828) (-14424.218750 444.332855 12.773965) 2.5 // booty bay dock -562 31,20 (6234.545898 256.902100 11.075373) (6230.961914 252.127274 11.180979) 2.5 // Blade's Edge Arena -562 31,20 (6243.081543 266.918854 11.059557) (6246.507324 271.623505 11.230524) 2.5 // Blade's Edge Arena \ No newline at end of file diff --git a/contrib/extract/only_extract_offmesh.sh b/contrib/extract/only_extract_offmesh.sh deleted file mode 100644 index 700626856ee..00000000000 --- a/contrib/extract/only_extract_offmesh.sh +++ /dev/null @@ -1,158 +0,0 @@ -#!/bin/sh - -# Copyright (C) 2005-2012 MaNGOS project -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -## Syntax of this helper -## First param must be number of to be used CPUs (only 1, 2, 3, 4 supported) or "offmesh" to recreate the special tiles from the OFFMESH_FILE -## Second param can be an additional filename for storing log -## Third param can be an addition filename for storing detailed log - -## Additional Parameters to be forwarded to MoveMapGen, see mmaps/readme for instructions -PARAMS="--silent" - -## Already a few map extracted, and don't care anymore -EXCLUDE_MAPS="" -#EXCLUDE_MAPS="0 1 530 571" # example to exclude the continents - -## Offmesh file -OFFMESH_FILE="offmesh.txt" - -## Normal log file (if not overwritten by second param -LOG_FILE="movemap.log" -## Detailed log file -DETAIL_LOG_FILE="movemap_detailed.log" - -## ! Use below only for finetuning or if you know what you are doing ! - -## All maps -MAP_LIST_A="1 37 543 595 289 572 529 562 531 269 47 649 650 599 548 559 429 230 573 349 13 25 409 229 43 48 546 553 547 604 545 90 576" -MAP_LIST_B="571 628 560 509 723 532 607 600 668 33 585 566 389 601 369 129 550 189 542 70 109 554 632 552 555 540 598 450 558 249 35 624 557" -MAP_LIST_C="0 631 609 534 533 619 469 602 329 580 615 578 36 556 44 565 544 34 617 608 618 449 616 42 451 582 584 586 587 588 589 590 591 592" -MAP_LIST_D="530 169 575 603 309 574 30 564 568 209 724 658 489 593 594 596 597 605 606 610 612 613 614 620 621 622 623 641 642 647 672 673 712 713 718" -MAP_LIST_D1="209 724 658 489 606 610 612 613 614 620 621" -MAP_LIST_D2="169 575 603 309 574 30 564 568 622 623 641 642 647 672 673 712 713 718" -MAP_LIST_D3="530 593 594 596 597 605" - -badParam() -{ - echo "ERROR! Bad arguments!" - echo "You can (re)extract mmaps with this helper script," - echo "or recreate only the tiles from the offmash file" - echo - echo "Call with number of processes (1 - 4) to create mmaps" - echo "Call with 'offmesh' to reextract the tiles from offmash file" - echo - echo "For further fine-tuning edit this helper script" - echo -} - -if [ "$#" = "3" ] -then - LOG_FILE=$2 - DETAIL_LOG_FILE=$3 -elif [ "$#" = "2" ] -then - LOG_FILE=$2 -fi - -# Offmesh file provided? -OFFMESH="" -if [ "$OFFMESH_FILE" != "" ] -then - if [ ! -f "$OFFMESH_FILE" ] - then - echo "ERROR! Offmesh file $OFFMESH_FILE could not be found." - echo "Provide valid file or none. You need to edit the script" - exit 1 - else - OFFMESH="--offMeshInput $OFFMESH_FILE" - fi -fi - -# Function to process a list -createMMaps() -{ - for i in $@ - do - for j in $EXCLUDE_MAPS - do - if [ "$i" = "$j" ] - then - continue 2 - fi - done - ./mmaps_generator $PARAMS $OFFMESH $i | tee -a $DETAIL_LOG_FILE - echo "`date`: (Re)created map $i" | tee -a $LOG_FILE - done -} - -createHeader() -{ - echo "`date`: Start creating mmaps_generator" | tee -a $LOG_FILE - echo "Used params: $PARAMS $OFFMESH" | tee -a $LOG_FILE - echo "Detailed log can be found in $DETAIL_LOG_FILE" | tee -a $LOG_FILE - echo "Start creating mmaps_generator" | tee -a $DETAIL_LOG_FILE - echo - echo "Be PATIENT - This will take a long time and might also have gaps between visible changes on the console." - echo "WAIT until you are informed that 'creating mmaps_generator' is 'finished'!" -} - -# Create mmaps directory if not exist -if [ ! -d mmaps ] -then - mkdir mmaps -fi - -# Param control -case "$1" in - "1" ) - createHeader $1 - createMMaps $MAP_LIST_A $MAP_LIST_B $MAP_LIST_C $MAP_LIST_D & - ;; - "2" ) - createHeader $1 - createMMaps $MAP_LIST_A $MAP_LIST_D & - createMMaps $MAP_LIST_B $MAP_LIST_C & - ;; - "3" ) - createHeader $1 - createMMaps $MAP_LIST_A $MAP_LIST_D1& - createMMaps $MAP_LIST_B $MAP_LIST_D2& - createMMaps $MAP_LIST_C $MAP_LIST_D3& - ;; - "4" ) - createHeader $1 - createMMaps $MAP_LIST_A & - createMMaps $MAP_LIST_B & - createMMaps $MAP_LIST_C & - createMMaps $MAP_LIST_D & - ;; - "offmesh" ) - echo "`date`: Recreate offmeshs from file $OFFMESH_FILE" | tee -a $LOG_FILE - echo "Recreate offmeshs from file $OFFMESH_FILE" | tee -a $DETAIL_LOG_FILE - while read map tile line - do - ./mmaps_generator $PARAMS $OFFMESH $map --tile $tile | tee -a $DETAIL_LOG_FILE - echo "`date`: Recreated $map $tile from $OFFMESH_FILE" | tee -a $LOG_FILE - done < $OFFMESH_FILE & - ;; - * ) - badParam - exit 1 - ;; -esac - -wait - -echo | tee -a $LOG_FILE -echo | tee -a $DETAIL_LOG_FILE -echo "`date`: Finished creating MoveMaps" | tee -a $LOG_FILE -echo "`date`: Finished creating MoveMaps" >> $DETAIL_LOG_FILE diff --git a/contrib/extract/vmap4assembler.exe b/contrib/extract/vmap4assembler.exe deleted file mode 100644 index e5331a5f70e..00000000000 Binary files a/contrib/extract/vmap4assembler.exe and /dev/null differ diff --git a/contrib/extract/vmap4extractor.exe b/contrib/extract/vmap4extractor.exe deleted file mode 100644 index 4866904d04f..00000000000 Binary files a/contrib/extract/vmap4extractor.exe and /dev/null differ diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index e47b2e5b44f..a0c40bc4392 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -158,13 +158,31 @@ namespace MMAP } /**************************************************************************/ - void MapBuilder::buildAllMaps() + void MapBuilder::buildAllMaps(int threads) { + int running = 0; for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) { uint32 mapID = (*it).first; if (!shouldSkipMap(mapID)) - buildMap(mapID); + { + if (threads > 1) + { + BuilderThread* thread = new BuilderThread(this, mapID); + thread->activate(); + ++running; + // Do not allow more than {threads} threads running at the same time + if (running == threads) + { + // Wait for previous threads to finish + ACE_Thread_Manager::instance()->wait(); + // Reset the number of running threads + running = 0; + } + } + else + buildMap(mapID); + } } } @@ -306,7 +324,7 @@ namespace MMAP } // now start building mmtiles for each tile - printf("We have %u tiles. \n", (unsigned int)tiles->size()); + printf("[Map %i] We have %u tiles. \n", mapID, (unsigned int)tiles->size()); for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) { uint32 tileX, tileY; @@ -415,10 +433,10 @@ namespace MMAP navMeshParams.maxPolys = maxPolysPerTile; navMesh = dtAllocNavMesh(); - printf("Creating navMesh... \r"); + printf("[Map %i] Creating navMesh...\n", mapID); if (!navMesh->init(&navMeshParams)) { - printf("Failed creating navmesh! \n"); + printf("[Map %i] Failed creating navmesh! \n", mapID); return; } @@ -430,7 +448,7 @@ namespace MMAP { dtFreeNavMesh(navMesh); char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", fileName); + sprintf(message, "[Map %i] Failed to open %s for writing!\n", mapID, fileName); perror(message); return; } @@ -446,9 +464,9 @@ namespace MMAP dtNavMesh* navMesh) { // console output - char tileString[10]; - sprintf(tileString, "[%02i,%02i]: ", tileX, tileY); - printf("%s Building movemap tiles... \r", tileString); + char tileString[20]; + sprintf(tileString, "[Map %03i] [%02i,%02i]: ", mapID, tileX, tileY); + printf("%s Building movemap tiles...\n", tileString); IntermediateValues iv; @@ -510,14 +528,14 @@ namespace MMAP rcPolyMesh** pmmerge = new rcPolyMesh*[TILES_PER_MAP * TILES_PER_MAP]; if (!pmmerge) { - printf("%s alloc pmmerge FIALED! \r", tileString); + printf("%s alloc pmmerge FIALED!\n", tileString); return; } rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP]; if (!dmmerge) { - printf("%s alloc dmmerge FIALED! \r", tileString); + printf("%s alloc dmmerge FIALED!\n", tileString); return; } @@ -539,7 +557,7 @@ namespace MMAP tile.solid = rcAllocHeightfield(); if (!tile.solid || !rcCreateHeightfield(m_rcContext, *tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch)) { - printf("%sFailed building heightfield! \n", tileString); + printf("%s Failed building heightfield! \n", tileString); continue; } @@ -560,33 +578,33 @@ namespace MMAP tile.chf = rcAllocCompactHeightfield(); if (!tile.chf || !rcBuildCompactHeightfield(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid, *tile.chf)) { - printf("%sFailed compacting heightfield! \n", tileString); + printf("%s Failed compacting heightfield! \n", tileString); continue; } // build polymesh intermediates if (!rcErodeWalkableArea(m_rcContext, config.walkableRadius, *tile.chf)) { - printf("%sFailed eroding area! \n", tileString); + printf("%s Failed eroding area! \n", tileString); continue; } if (!rcBuildDistanceField(m_rcContext, *tile.chf)) { - printf("%sFailed building distance field! \n", tileString); + printf("%s Failed building distance field! \n", tileString); continue; } if (!rcBuildRegions(m_rcContext, *tile.chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea)) { - printf("%sFailed building regions! \n", tileString); + printf("%s Failed building regions! \n", tileString); continue; } tile.cset = rcAllocContourSet(); if (!tile.cset || !rcBuildContours(m_rcContext, *tile.chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *tile.cset)) { - printf("%sFailed building contours! \n", tileString); + printf("%s Failed building contours! \n", tileString); continue; } @@ -594,14 +612,14 @@ namespace MMAP tile.pmesh = rcAllocPolyMesh(); if (!tile.pmesh || !rcBuildPolyMesh(m_rcContext, *tile.cset, tileCfg.maxVertsPerPoly, *tile.pmesh)) { - printf("%sFailed building polymesh! \n", tileString); + printf("%s Failed building polymesh! \n", tileString); continue; } tile.dmesh = rcAllocPolyMeshDetail(); if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg .detailSampleMaxError, *tile.dmesh)) { - printf("%sFailed building polymesh detail! \n", tileString); + printf("%s Failed building polymesh detail! \n", tileString); continue; } @@ -627,7 +645,7 @@ namespace MMAP iv.polyMesh = rcAllocPolyMesh(); if (!iv.polyMesh) { - printf("%s alloc iv.polyMesh FIALED! \r", tileString); + printf("%s alloc iv.polyMesh FIALED!\n", tileString); return; } rcMergePolyMeshes(m_rcContext, pmmerge, nmerge, *iv.polyMesh); @@ -635,16 +653,16 @@ namespace MMAP iv.polyMeshDetail = rcAllocPolyMeshDetail(); if (!iv.polyMeshDetail) { - printf("%s alloc m_dmesh FIALED! \r", tileString); + printf("%s alloc m_dmesh FIALED!\n", tileString); return; } rcMergePolyMeshDetails(m_rcContext, dmmerge, nmerge, *iv.polyMeshDetail); // free things up - delete [] pmmerge; - delete [] dmmerge; + delete[] pmmerge; + delete[] dmmerge; - delete [] tiles; + delete[] tiles; // remove padding for extraction for (int i = 0; i < iv.polyMesh->nverts; ++i) @@ -736,7 +754,7 @@ namespace MMAP continue; } - printf("%s Building navmesh tile... \r", tileString); + printf("%s Building navmesh tile...\n", tileString); if (!dtCreateNavMeshData(¶ms, &navData, &navDataSize)) { printf("%s Failed building navmesh tile! \n", tileString); @@ -744,7 +762,7 @@ namespace MMAP } dtTileRef tileRef = 0; - printf("%s Adding tile to navmesh... \r", tileString); + printf("%s Adding tile to navmesh...\n", 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); @@ -761,13 +779,13 @@ namespace MMAP if (!file) { char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", fileName); + sprintf(message, "[Map %i] Failed to open %s for writing!\n", mapID, fileName); perror(message); navMesh->removeTile(tileRef, NULL, NULL); continue; } - printf("%s Writing to file... \r", tileString); + printf("%s Writing to file...\n", tileString); // write header MmapTileHeader header; diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index 20789bf9bff..0c9dce05992 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -32,6 +32,8 @@ #include "Recast.h" #include "DetourNavMesh.h" +#include "ace/Task.h" + using namespace std; using namespace VMAP; @@ -80,7 +82,7 @@ namespace MMAP void buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY); // builds list of maps, then builds all of mmap tiles (based on the skip settings) - void buildAllMaps(); + void buildAllMaps(int threads); private: // detect maps and tiles @@ -125,6 +127,22 @@ namespace MMAP // build performance - not really used for now rcContext* m_rcContext; }; + + class BuilderThread : public ACE_Task + { + private: + MapBuilder* _builder; + uint32 _mapId; + public: + BuilderThread(MapBuilder* builder, uint32 mapId) : _builder(builder), _mapId(mapId) {} + + int svc() + { + if (_builder) + _builder->buildMap(_mapId); + return 0; + } + }; } #endif diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 7d9f59ed138..45d0aff958c 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -71,7 +71,8 @@ bool handleArgs(int argc, char** argv, bool &silent, bool &bigBaseUnit, char* &offMeshInputPath, - char* &file) + char* &file, + int& threads) { char* param = NULL; for (int i = 1; i < argc; ++i) @@ -88,6 +89,14 @@ bool handleArgs(int argc, char** argv, else printf("invalid option for '--maxAngle', using default\n"); } + else if (strcmp(argv[i], "--threads") == 0) + { + param = argv[++i]; + if (!param) + return false; + threads = atoi(param); + printf("Using %i threads to extract mmaps\n", threads); + } else if (strcmp(argv[i], "--file") == 0) { param = argv[++i]; @@ -232,7 +241,7 @@ int finish(const char* message, int returnValue) int main(int argc, char** argv) { - int mapnum = -1; + int threads = 3, mapnum = -1; float maxAngle = 60.0f; int tileX = -1, tileY = -1; bool skipLiquid = false, @@ -248,7 +257,7 @@ int main(int argc, char** argv) bool validParam = handleArgs(argc, argv, mapnum, tileX, tileY, maxAngle, skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, - debugOutput, silent, bigBaseUnit, offMeshInputPath, file); + debugOutput, silent, bigBaseUnit, offMeshInputPath, file, threads); if (!validParam) return silent ? -1 : finish("You have specified invalid parameters", -1); @@ -278,7 +287,7 @@ int main(int argc, char** argv) else if (mapnum >= 0) builder.buildMap(uint32(mapnum)); else - builder.buildAllMaps(); + builder.buildAllMaps(threads); return silent ? 1 : finish("Movemap build is complete!", 1); } -- cgit v1.2.3 From 35437149e210ed713b04e01bf7607aa1475e158f Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 25 Aug 2012 12:27:48 -0500 Subject: Core/Mmaps: Added some corrections to the logs in the mmaps_generator --- src/tools/mmaps_generator/MapBuilder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index a0c40bc4392..3b7a3e8d99d 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -294,7 +294,7 @@ namespace MMAP /**************************************************************************/ void MapBuilder::buildMap(uint32 mapID) { - printf("Building map %03u:\n", mapID); + printf("[Thread %i] Building map %03u:\n", ACE_Thread::self(), mapID); set* tiles = getTileList(mapID); @@ -340,7 +340,7 @@ namespace MMAP dtFreeNavMesh(navMesh); - printf("Complete! \n\n"); + printf("[Map %i] Complete!\n", mapID); } /**************************************************************************/ -- cgit v1.2.3 From c44601379179ad368bb2c80d371232c48f366f90 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 25 Aug 2012 12:40:04 -0500 Subject: Core/Mmaps: Added elapsed time to the mmaps_generator --- src/tools/mmaps_generator/PathGenerator.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 45d0aff958c..4da90fd153a 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -18,6 +18,7 @@ #include "PathCommon.h" #include "MapBuilder.h" +#include "Timer.h" using namespace MMAP; @@ -280,6 +281,7 @@ int main(int argc, char** argv) MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, debugOutput, bigBaseUnit, offMeshInputPath); + uint32 start = getMSTime(); if (file) builder.buildMeshFromFile(file); else if (tileX > -1 && tileY > -1 && mapnum >= 0) @@ -289,5 +291,7 @@ int main(int argc, char** argv) else builder.buildAllMaps(threads); - return silent ? 1 : finish("Movemap build is complete!", 1); + if (!silent) + printf("Finished. MMAPS were built in %u ms!", GetMSTimeDiffToNow(start)); + return 1; } -- cgit v1.2.3 From 92e72b2a5cd79c82625ceb6cc83125c546e7f1ab Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 25 Aug 2012 17:37:15 -0500 Subject: Core/Mmaps: Fixed a few mistakes in the mmaps_generator, should be somewhat faster now --- src/tools/mmaps_generator/MapBuilder.cpp | 82 +++++++++++++++++++------------- src/tools/mmaps_generator/MapBuilder.h | 8 +++- 2 files changed, 56 insertions(+), 34 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 3b7a3e8d99d..b04300994f9 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -160,30 +160,46 @@ namespace MMAP /**************************************************************************/ void MapBuilder::buildAllMaps(int threads) { - int running = 0; + std::vector _threads; + + for (int i = 0; i < threads; ++i) + _threads.push_back(new BuilderThread(this)); + for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) { - uint32 mapID = (*it).first; + uint32 mapID = it->first; if (!shouldSkipMap(mapID)) { if (threads > 1) { - BuilderThread* thread = new BuilderThread(this, mapID); - thread->activate(); - ++running; - // Do not allow more than {threads} threads running at the same time - if (running == threads) + bool next = false; + while (!next) { - // Wait for previous threads to finish - ACE_Thread_Manager::instance()->wait(); - // Reset the number of running threads - running = 0; + for (std::vector::iterator _th = _threads.begin(); _th != _threads.end(); ++_th) + { + if ((*_th)->Free) + { + printf("Thread is free for map %03i\n", mapID); + (*_th)->SetMapId(mapID); + (*_th)->activate(); + next = true; + break; + } + } + // Wait for 20 seconds + ACE_OS::sleep(ACE_Time_Value (0, 20000)); } } else buildMap(mapID); } } + // Wait for all threads to finish before closing down + ACE_Thread_Manager::instance()->wait(); + + // Free memory + for (std::vector::iterator _th = _threads.begin(); _th != _threads.end(); ++_th) + delete *_th; } /**************************************************************************/ @@ -311,34 +327,34 @@ namespace MMAP tiles->insert(StaticMapTree::packTileID(i, j)); } - if (!tiles->size()) - return; - - // build navMesh - dtNavMesh* navMesh = NULL; - buildNavMesh(mapID, navMesh); - if (!navMesh) + if (!tiles->empty()) { - printf("Failed creating navmesh! \n"); - return; - } + // build navMesh + dtNavMesh* navMesh = NULL; + buildNavMesh(mapID, navMesh); + if (!navMesh) + { + printf("Failed creating navmesh! \n"); + return; + } - // now start building mmtiles for each tile - printf("[Map %i] We have %u tiles. \n", mapID, (unsigned int)tiles->size()); - for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) - { - uint32 tileX, tileY; + // now start building mmtiles for each tile + printf("[Map %i] We have %u tiles. \n", mapID, (unsigned int)tiles->size()); + for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) + { + uint32 tileX, tileY; - // unpack tile coords - StaticMapTree::unpackTileID((*it), tileX, tileY); + // unpack tile coords + StaticMapTree::unpackTileID((*it), tileX, tileY); - if (shouldSkipTile(mapID, tileX, tileY)) - continue; + if (shouldSkipTile(mapID, tileX, tileY)) + continue; - buildTile(mapID, tileX, tileY, navMesh); - } + buildTile(mapID, tileX, tileY, navMesh); + } - dtFreeNavMesh(navMesh); + dtFreeNavMesh(navMesh); + } printf("[Map %i] Complete!\n", mapID); } diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index 0c9dce05992..61a71ff6d5b 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -134,14 +134,20 @@ namespace MMAP MapBuilder* _builder; uint32 _mapId; public: - BuilderThread(MapBuilder* builder, uint32 mapId) : _builder(builder), _mapId(mapId) {} + BuilderThread(MapBuilder* builder) : _builder(builder), Free(true) {} + + void SetMapId(uint32 mapId) { _mapId = mapId; } int svc() { + Free = false; if (_builder) _builder->buildMap(_mapId); + Free = true; return 0; } + + bool Free; }; } -- cgit v1.2.3 From a97cfbd2ebeaf8e39cef6802deb3139569505288 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 26 Aug 2012 18:14:58 -0500 Subject: Core/MMaps: Fixed infinite wait in the generator --- src/tools/mmaps_generator/MapBuilder.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index b04300994f9..8cdbdf61909 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -194,12 +194,13 @@ namespace MMAP buildMap(mapID); } } - // Wait for all threads to finish before closing down - ACE_Thread_Manager::instance()->wait(); // Free memory for (std::vector::iterator _th = _threads.begin(); _th != _threads.end(); ++_th) + { + _th->wait(); delete *_th; + } } /**************************************************************************/ -- cgit v1.2.3 From 02bbd1154eb3e119fb095850e60e3dc11ee937b1 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 27 Aug 2012 15:21:54 -0500 Subject: Core/Mmaps: Fixed build --- src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h | 2 +- src/tools/mmaps_generator/MapBuilder.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index 688d236c3f8..0ca688fb0df 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -84,7 +84,7 @@ class ChaseMovementGenerator : public TargetedMovementGeneratorMediumClearUnitState(UNIT_STATE_CHASE_MOVE); } static void _addUnitStateMove(T* u) { u->AddUnitState(UNIT_STATE_CHASE_MOVE); } bool EnableWalking() const { return false;} - bool _lostTarget(T* u) const { return u->getVictim() != GetTarget(); } + bool _lostTarget(T* u) const { return u->getVictim() != this->GetTarget(); } void _reachTarget(T*); }; diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 8cdbdf61909..03a77c01d27 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -198,7 +198,7 @@ namespace MMAP // Free memory for (std::vector::iterator _th = _threads.begin(); _th != _threads.end(); ++_th) { - _th->wait(); + (*_th)->wait(); delete *_th; } } -- cgit v1.2.3 From fa590d006e9026e95cd666223eee68fae8a33a68 Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 28 Aug 2012 20:09:04 -0500 Subject: Core/MMaps: Made some cosmetic improvements to the mmaps generator --- src/tools/mmaps_generator/MapBuilder.cpp | 5 ++--- src/tools/mmaps_generator/PathGenerator.cpp | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 03a77c01d27..2a74233a1a7 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -179,7 +179,6 @@ namespace MMAP { if ((*_th)->Free) { - printf("Thread is free for map %03i\n", mapID); (*_th)->SetMapId(mapID); (*_th)->activate(); next = true; @@ -335,7 +334,7 @@ namespace MMAP buildNavMesh(mapID, navMesh); if (!navMesh) { - printf("Failed creating navmesh! \n"); + printf("[Map %i] Failed creating navmesh!\n", mapID); return; } @@ -363,7 +362,7 @@ namespace MMAP /**************************************************************************/ void MapBuilder::buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh) { - printf("Building map %03u, tile [%02u,%02u]\n", mapID, tileX, tileY); + printf("[Map %i] Building tile [%02u,%02u]\n", mapID, tileX, tileY); MeshData meshData; diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 4da90fd153a..026bf957ec4 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -292,6 +292,6 @@ int main(int argc, char** argv) builder.buildAllMaps(threads); if (!silent) - printf("Finished. MMAPS were built in %u ms!", GetMSTimeDiffToNow(start)); + printf("Finished. MMAPS were built in %u ms!\n", GetMSTimeDiffToNow(start)); return 1; } -- cgit v1.2.3 From 69602df83388e89dc473936f08992c48022a73f0 Mon Sep 17 00:00:00 2001 From: kaelima Date: Tue, 4 Sep 2012 23:33:11 +0200 Subject: Core/MMaps: Fix some uninitialized variable complaints in PathGenerator --- src/server/game/Movement/PathGenerator.cpp | 19 ++++++++++--------- src/tools/mmaps_generator/PathGenerator.cpp | 4 ++-- 2 files changed, 12 insertions(+), 11 deletions(-) (limited to 'src/tools') diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index a02eb0a9a84..62ab0be4630 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -30,7 +30,7 @@ PathGenerator::PathGenerator(const Unit* owner) : m_polyLength(0), m_type(PATHFIND_BLANK), m_useStraightPath(false), m_forceDestination(false), m_pointPathLimit(MAX_POINT_PATH_LENGTH), - m_sourceUnit(owner), m_navMesh(NULL), m_navMeshQuery(NULL) + m_sourceUnit(owner), m_navMesh(NULL), m_navMeshQuery(NULL), m_endPosition(Vector3::zero()) { sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::PathGenerator for %u \n", m_sourceUnit->GetGUIDLow()); @@ -52,16 +52,16 @@ PathGenerator::~PathGenerator() bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool forceDest) { - if (!Trinity::IsValidMapCoord(destX, destY, destZ) || - !Trinity::IsValidMapCoord(m_sourceUnit->GetPositionX(), m_sourceUnit->GetPositionY(), m_sourceUnit->GetPositionZ())) + float x, y, z; + m_sourceUnit->GetPosition(x, y, z); + + if (!Trinity::IsValidMapCoord(destX, destY, destZ) || !Trinity::IsValidMapCoord(x, y, z)) return false; Vector3 oldDest = getEndPosition(); Vector3 dest(destX, destY, destZ); setEndPosition(dest); - float x, y, z; - m_sourceUnit->GetPosition(x, y, z); Vector3 start(x, y, z); setStartPosition(start); @@ -84,7 +84,7 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo // check if destination moved - if not we can optimize something here // we are following old, precalculated path? float dist = m_sourceUnit->GetObjectSize(); - if (inRange(oldDest, dest, dist, dist) && m_pathPoints.size() > 2) + if (oldDest != Vector3::zero() && inRange(oldDest, dest, dist, dist) && m_pathPoints.size() > 2) { // our target is not moving - we just coming closer // we are moving on precalculated path - enjoy the ride @@ -192,7 +192,7 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos if (waterPath) { // Check both start and end points, if they're both in water, then we can *safely* let the creature move - for (int i = 0; i < m_pathPoints.size(); ++i) + for (uint32 i = 0; i < m_pathPoints.size(); ++i) { LiquidData data; m_sourceUnit->GetBaseMap()->getLiquidStatus(m_pathPoints[i].x, m_pathPoints[i].y, m_pathPoints[i].z, MAP_ALL_LIQUIDS, &data); @@ -277,11 +277,12 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos // TODO: we can merge it with getPathPolyByPosition() loop bool startPolyFound = false; bool endPolyFound = false; - uint32 pathStartIndex, pathEndIndex; + uint32 pathStartIndex = 0; + uint32 pathEndIndex = 0; if (m_polyLength) { - for (pathStartIndex = 0; pathStartIndex < m_polyLength; ++pathStartIndex) + for (; pathStartIndex < m_polyLength; ++pathStartIndex) { // here to carch few bugs ASSERT(m_pathPolyRefs[pathStartIndex] != INVALID_POLYREF); diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 026bf957ec4..9707cb4160a 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -26,14 +26,14 @@ bool checkDirectories(bool debugOutput) { vector dirFiles; - if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size()) + if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty()) { printf("'maps' directory is empty or does not exist\n"); return false; } dirFiles.clear(); - if (getDirContents(dirFiles, "vmaps", "*.vmtree") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size()) + if (getDirContents(dirFiles, "vmaps", "*.vmtree") == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty()) { printf("'vmaps' directory is empty or does not exist\n"); return false; -- cgit v1.2.3 From c2f446ded917efed58c8054693858b3c4b4c4a8f Mon Sep 17 00:00:00 2001 From: kaelima Date: Wed, 5 Sep 2012 17:07:47 +0200 Subject: Core/MMaps: Minor warning fix --- src/server/game/Movement/PathGenerator.cpp | 13 ++++++------- src/tools/mmaps_generator/MapBuilder.cpp | 10 +++++----- 2 files changed, 11 insertions(+), 12 deletions(-) (limited to 'src/tools') diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 62ab0be4630..c9cfff08ede 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -591,8 +591,7 @@ bool PathGenerator::HaveTile(const Vector3 &p) const return (m_navMesh->getTileAt(tx, ty) != NULL); } -uint32 PathGenerator::fixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, - const dtPolyRef* visited, uint32 nvisited) +uint32 PathGenerator::fixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, dtPolyRef const* visited, uint32 nvisited) { int32 furthestPath = -1; int32 furthestVisited = -1; @@ -622,17 +621,17 @@ uint32 PathGenerator::fixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPat // Adjust beginning of the buffer to include the visited. uint32 req = nvisited - furthestVisited; - uint32 orig = uint32(furthestPath+1) < npath ? furthestPath+1 : npath; - uint32 size = npath-orig > 0 ? npath-orig : 0; - if (req+size > maxPath) + uint32 orig = uint32(furthestPath + 1) < npath ? furthestPath + 1 : npath; + uint32 size = npath > orig ? npath - orig : 0; + if (req + size > maxPath) size = maxPath-req; if (size) - memmove(path+req, path+orig, size*sizeof(dtPolyRef)); + memmove(path + req, path + orig, size * sizeof(dtPolyRef)); // Store visited for (uint32 i = 0; i < req; ++i) - path[i] = visited[(nvisited-1)-i]; + path[i] = visited[(nvisited - 1) - i]; return req+size; } diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 2a74233a1a7..69ffad94eb7 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -564,10 +564,10 @@ namespace MMAP Tile& tile = tiles[x + y * TILES_PER_MAP]; // Calculate the per tile bounding box. - tileCfg.bmin[0] = config.bmin[0] + (x*config.tileSize - config.borderSize)*config.cs; - tileCfg.bmin[2] = config.bmin[2] + (y*config.tileSize - config.borderSize)*config.cs; - tileCfg.bmax[0] = config.bmin[0] + ((x+1)*config.tileSize + config.borderSize)*config.cs; - tileCfg.bmax[2] = config.bmin[2] + ((y+1)*config.tileSize + config.borderSize)*config.cs; + tileCfg.bmin[0] = config.bmin[0] + float(x*config.tileSize - config.borderSize)*config.cs; + tileCfg.bmin[2] = config.bmin[2] + float(y*config.tileSize - config.borderSize)*config.cs; + tileCfg.bmax[0] = config.bmin[0] + float((x+1)*config.tileSize + config.borderSize)*config.cs; + tileCfg.bmax[2] = config.bmin[2] + float((y+1)*config.tileSize + config.borderSize)*config.cs; // build heightfield tile.solid = rcAllocHeightfield(); @@ -633,7 +633,7 @@ namespace MMAP } tile.dmesh = rcAllocPolyMeshDetail(); - if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg .detailSampleMaxError, *tile.dmesh)) + if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg.detailSampleMaxError, *tile.dmesh)) { printf("%s Failed building polymesh detail! \n", tileString); continue; -- cgit v1.2.3 From 50f833a0086c9f7f80152b907c77acb19d352896 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 06:59:31 -0500 Subject: Tools: Added an experimental tool (still WIP) to replace the current mmaps generator --- cmake/options.cmake | 2 +- src/tools/CMakeLists.txt | 1 + src/tools/mesh_extractor/ADT.h | 26 ++ src/tools/mesh_extractor/CMakeLists.txt | 62 +++ src/tools/mesh_extractor/Cache.h | 44 +++ src/tools/mesh_extractor/Chunk.cpp | 31 ++ src/tools/mesh_extractor/Chunk.h | 20 + src/tools/mesh_extractor/ChunkedData.cpp | 63 ++++ src/tools/mesh_extractor/ChunkedData.h | 20 + src/tools/mesh_extractor/Constants.h | 33 ++ src/tools/mesh_extractor/ContinentBuilder.cpp | 11 + src/tools/mesh_extractor/ContinentBuilder.h | 15 + src/tools/mesh_extractor/DoodadHandler.cpp | 99 +++++ src/tools/mesh_extractor/DoodadHandler.h | 51 +++ src/tools/mesh_extractor/Geometry.cpp | 102 +++++ src/tools/mesh_extractor/Geometry.h | 21 ++ src/tools/mesh_extractor/LiquidHandler.cpp | 1 + src/tools/mesh_extractor/LiquidHandler.h | 17 + src/tools/mesh_extractor/MPQ.cpp | 117 ++++++ src/tools/mesh_extractor/MPQ.h | 88 +++++ src/tools/mesh_extractor/MPQManager.cpp | 58 +++ src/tools/mesh_extractor/MPQManager.h | 24 ++ src/tools/mesh_extractor/MapChunk.cpp | 77 ++++ src/tools/mesh_extractor/MapChunk.h | 25 ++ src/tools/mesh_extractor/MeshExtractor.cpp | 34 ++ src/tools/mesh_extractor/Model.cpp | 49 +++ src/tools/mesh_extractor/Model.h | 21 ++ src/tools/mesh_extractor/ObjectDataHandler.cpp | 21 ++ src/tools/mesh_extractor/ObjectDataHandler.h | 15 + src/tools/mesh_extractor/TileBuilder.cpp | 37 ++ src/tools/mesh_extractor/TileBuilder.h | 22 ++ src/tools/mesh_extractor/Utils.cpp | 163 ++++++++ src/tools/mesh_extractor/Utils.h | 497 +++++++++++++++++++++++++ src/tools/mesh_extractor/WDT.cpp | 55 +++ src/tools/mesh_extractor/WDT.h | 27 ++ src/tools/mesh_extractor/WorldModelGroup.cpp | 122 ++++++ src/tools/mesh_extractor/WorldModelGroup.h | 33 ++ src/tools/mesh_extractor/WorldModelHandler.cpp | 190 ++++++++++ src/tools/mesh_extractor/WorldModelHandler.h | 42 +++ src/tools/mesh_extractor/WorldModelRoot.cpp | 74 ++++ src/tools/mesh_extractor/WorldModelRoot.h | 26 ++ src/tools/mesh_extractor/readme | 6 + 42 files changed, 2441 insertions(+), 1 deletion(-) create mode 100644 src/tools/mesh_extractor/ADT.h create mode 100644 src/tools/mesh_extractor/CMakeLists.txt create mode 100644 src/tools/mesh_extractor/Cache.h create mode 100644 src/tools/mesh_extractor/Chunk.cpp create mode 100644 src/tools/mesh_extractor/Chunk.h create mode 100644 src/tools/mesh_extractor/ChunkedData.cpp create mode 100644 src/tools/mesh_extractor/ChunkedData.h create mode 100644 src/tools/mesh_extractor/Constants.h create mode 100644 src/tools/mesh_extractor/ContinentBuilder.cpp create mode 100644 src/tools/mesh_extractor/ContinentBuilder.h create mode 100644 src/tools/mesh_extractor/DoodadHandler.cpp create mode 100644 src/tools/mesh_extractor/DoodadHandler.h create mode 100644 src/tools/mesh_extractor/Geometry.cpp create mode 100644 src/tools/mesh_extractor/Geometry.h create mode 100644 src/tools/mesh_extractor/LiquidHandler.cpp create mode 100644 src/tools/mesh_extractor/LiquidHandler.h create mode 100644 src/tools/mesh_extractor/MPQ.cpp create mode 100644 src/tools/mesh_extractor/MPQ.h create mode 100644 src/tools/mesh_extractor/MPQManager.cpp create mode 100644 src/tools/mesh_extractor/MPQManager.h create mode 100644 src/tools/mesh_extractor/MapChunk.cpp create mode 100644 src/tools/mesh_extractor/MapChunk.h create mode 100644 src/tools/mesh_extractor/MeshExtractor.cpp create mode 100644 src/tools/mesh_extractor/Model.cpp create mode 100644 src/tools/mesh_extractor/Model.h create mode 100644 src/tools/mesh_extractor/ObjectDataHandler.cpp create mode 100644 src/tools/mesh_extractor/ObjectDataHandler.h create mode 100644 src/tools/mesh_extractor/TileBuilder.cpp create mode 100644 src/tools/mesh_extractor/TileBuilder.h create mode 100644 src/tools/mesh_extractor/Utils.cpp create mode 100644 src/tools/mesh_extractor/Utils.h create mode 100644 src/tools/mesh_extractor/WDT.cpp create mode 100644 src/tools/mesh_extractor/WDT.h create mode 100644 src/tools/mesh_extractor/WorldModelGroup.cpp create mode 100644 src/tools/mesh_extractor/WorldModelGroup.h create mode 100644 src/tools/mesh_extractor/WorldModelHandler.cpp create mode 100644 src/tools/mesh_extractor/WorldModelHandler.h create mode 100644 src/tools/mesh_extractor/WorldModelRoot.cpp create mode 100644 src/tools/mesh_extractor/WorldModelRoot.h create mode 100644 src/tools/mesh_extractor/readme (limited to 'src/tools') diff --git a/cmake/options.cmake b/cmake/options.cmake index 11ebe6ddd12..5802ab86f43 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -10,7 +10,7 @@ option(SERVERS "Build worldserver and authserver" 1) option(SCRIPTS "Build core with scripts included" 1) -option(TOOLS "Build map/vmap extraction/assembler tools" 0) +option(TOOLS "Build map/vmap/mmap extraction/assembler tools" 0) option(USE_SCRIPTPCH "Use precompiled headers when compiling scripts" 1) option(USE_COREPCH "Use precompiled headers when compiling servers" 1) option(WITH_WARNINGS "Show all warnings during compile" 0) diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index 2d378966aff..bbff6f85751 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -12,3 +12,4 @@ add_subdirectory(map_extractor) add_subdirectory(vmap4_assembler) add_subdirectory(vmap4_extractor) add_subdirectory(mmaps_generator) +add_subdirectory(mesh_extractor) diff --git a/src/tools/mesh_extractor/ADT.h b/src/tools/mesh_extractor/ADT.h new file mode 100644 index 00000000000..18b811a4e4c --- /dev/null +++ b/src/tools/mesh_extractor/ADT.h @@ -0,0 +1,26 @@ +#ifndef ADT_H +#define ADT_H +#include "ChunkedData.h" +#include "MapChunk.h" +#include "DoodadHandler.h" +#include "WorldModelHandler.h" + +class ADT +{ +public: + ADT(); + ~ADT() { delete[] MapChunks; delete ObjectData; delete Data; } + + ChunkedData* ObjectData; + ChunkedData* Data; + // This here is not a pointer, is an array of objects ( made this way to allow the dynamic allocation ) + MapChunk* MapChunks; + MHDR Header; + // Can we dispose of this? + bool HasObjectData; + + DoodadHandler* _DoodadHandler; + WorldModelHandler* _WorldModelHandler; + LiquidHandler* _LiquidHandler; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt new file mode 100644 index 00000000000..3f5b5526dd4 --- /dev/null +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -0,0 +1,62 @@ +# Copyright (C) 2005-2009 MaNGOS project +# Copyright (C) 2008-2012 TrinityCore +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +file(GLOB_RECURSE sources *.cpp *.h) + +if( UNIX ) + include_directories ( + ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/dep/libmpq + ${CMAKE_SOURCE_DIR}/dep/g3dlite/include + ${CMAKE_CURRENT_SOURCE_DIR} + ) +elseif( WIN32 ) + include_directories ( + ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/src/server/shared/Database + ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation + ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Logging + ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/dep/libmpq + ${CMAKE_SOURCE_DIR}/dep/libmpq/win + ${CMAKE_SOURCE_DIR}/dep/g3dlite/include + ${ACE_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ) +endif() + +add_executable(MeshExtractor + ${sources} +) + +target_link_libraries(MeshExtractor + mpq + Recast + Detour + ${BZIP2_LIBRARIES} + ${ZLIB_LIBRARIES} + ${ACE_LIBRARY} +) + +add_dependencies(MeshExtractor mpq Recast Detour) + +if( UNIX ) + install(TARGETS MeshExtractor DESTINATION bin) +elseif( WIN32 ) + install(TARGETS MeshExtractor DESTINATION "${CMAKE_INSTALL_PREFIX}") +endif() \ No newline at end of file diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h new file mode 100644 index 00000000000..186a7870af1 --- /dev/null +++ b/src/tools/mesh_extractor/Cache.h @@ -0,0 +1,44 @@ +#ifndef CACHE_H +#define CACHE_H +#include +#include "Common.h" + +class WorldModelRoot; +class Model; + +template +class GenericCache +{ +public: + GenericCache() {} + const int32 FlushLimit = 1000; + + void Insert(std::string key, T* val) + { + if (_items.size() > FlushLimit) + Clear(); + _items.insert(key, val); + } + + T* Get(std::string key) + { + UNORDERED_MAP::iterator itr = _items.find(key); + if (itr != _items.end()) + return itr->second; + return NULL; + } + + void Clear() { _items.clear(); } +private: + UNORDERED_MAP _items; +}; + +class CacheClass +{ + CacheClass() {} + GenericCache ModelCache; + GenericCache WorldModelCache; +}; + +extern CacheClass* Cache; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/Chunk.cpp b/src/tools/mesh_extractor/Chunk.cpp new file mode 100644 index 00000000000..b41fa7d07d4 --- /dev/null +++ b/src/tools/mesh_extractor/Chunk.cpp @@ -0,0 +1,31 @@ +#include "Chunk.h" +#include "Utils.h" + +int32 Chunk::FindSubChunkOffset(std::string name) +{ + // Reverse the name + name = std::string(name.rbegin(), name.rend()); + if (name.size() != 4) + return -1; + + FILE* stream = GetStream(); + uint32 matched = 0; + while (ftell(stream) < Utils::Size(stream)) + { + char b; + fread(&b, sizeof(char), 1, stream); + if (b == name[matched]) + ++matched; + else + matched = 0; + if (matched == 4) + return ftell(stream) - 4; + } + return -1; +} + +FILE* Chunk::GetStream() +{ + fseek(Stream, Offset, SEEK_SET); + return Stream; +} diff --git a/src/tools/mesh_extractor/Chunk.h b/src/tools/mesh_extractor/Chunk.h new file mode 100644 index 00000000000..2eea36f69b6 --- /dev/null +++ b/src/tools/mesh_extractor/Chunk.h @@ -0,0 +1,20 @@ +#ifndef CHUNK_H +#define CHUNK_H +#include "Common.h" +#include +class ChunkedData; + +class Chunk +{ +public: + Chunk(const char* name, uint32 length, uint32 offset, FILE* stream) : Name(name), Length(length), Offset(offset), Stream(stream) {} + + int32 FindSubChunkOffset(std::string name); + FILE* GetStream(); + std::string Name; + uint32 Length; + uint32 Offset; + FILE* Stream; +}; + +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp new file mode 100644 index 00000000000..470b8b94f39 --- /dev/null +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -0,0 +1,63 @@ +#include "ChunkedData.h" +#include "MPQManager.h" +#include "Utils.h" + +#include + +ChunkedData::ChunkedData( FILE* stream, uint32 maxLength, uint32 chunksHint /*= 300*/ ) : +Stream(stream) +{ + if (!Stream) + return; + Load(maxLength, chunksHint); +} + +ChunkedData::ChunkedData( std::string file, uint32 chunksHint /*= 300*/ ) +{ + Stream = MPQHandler->GetFile(file); + if (!Stream) + return; + Load(0, chunksHint); +} + +void ChunkedData::Load( uint32 maxLength, uint32 chunksHint ) +{ + if (!maxLength) + maxLength = Utils::Size(Stream); + Chunks.reserve(chunksHint); + uint32 baseOffset = ftell(Stream); + uint32 calcOffset = 0; + while ((calcOffset + baseOffset) < Utils::Size(Stream) && (calcOffset < maxLength)) + { + char nameBytes[5]; + uint32 read = fread(&nameBytes, sizeof(char), 4, Stream); + nameBytes[read] = '\0'; + std::string name = std::string(nameBytes); + // Utils::Reverse(nameBytes); + name = std::string(name.rbegin(), name.rend()); + uint32 length; + fread(&length, sizeof(uint32), 1, Stream); + calcOffset += 8; + Chunks.push_back(new Chunk(name.c_str(), length, calcOffset + baseOffset, Stream)); + calcOffset += length; + // save an extra seek at the end + if ((calcOffset + baseOffset) < Utils::Size(Stream) && calcOffset < maxLength) + fseek(Stream, length, SEEK_CUR); + } +} + +int ChunkedData::GetFirstIndex( std::string name ) +{ + for (int i = 0; i < Chunks.size(); ++i) + if (Chunks[i]->Name == name) + return i; + return -1; +} + +Chunk* ChunkedData::GetChunkByName( std::string name ) +{ + for (int i = 0; i < Chunks.size(); ++i) + if (Chunks[i]->Name == name) + return Chunks[i]; + return NULL; +} diff --git a/src/tools/mesh_extractor/ChunkedData.h b/src/tools/mesh_extractor/ChunkedData.h new file mode 100644 index 00000000000..6e102828222 --- /dev/null +++ b/src/tools/mesh_extractor/ChunkedData.h @@ -0,0 +1,20 @@ +#ifndef CHNK_H +#define CHNK_H + +#include +#include "Chunk.h" + +class ChunkedData +{ +public: + ChunkedData(FILE* stream, uint32 maxLength, uint32 chunksHint = 300); + ChunkedData(std::string file, uint32 chunksHint = 300); + + int GetFirstIndex(std::string name); + Chunk* GetChunkByName(std::string name); + + void Load(uint32 maxLength, uint32 chunksHint); + std::vector Chunks; + FILE* Stream; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h new file mode 100644 index 00000000000..885761f1687 --- /dev/null +++ b/src/tools/mesh_extractor/Constants.h @@ -0,0 +1,33 @@ +#ifndef CONSTANTS_H +#define CONSTANTS_H + +#include "Common.h" + +class Constants +{ +public: + enum TriangleType + { + TRIANGLE_TYPE_UNKNOWN, + TRIANGLE_TYPE_TERRAIN, + TRIANGLE_TYPE_WATER, + TRIANGLE_TYPE_DOODAD, + TRIANGLE_TYPE_WMO + }; + + enum PolyArea + { + POLY_AREA_TERRAIN = 1, + POLY_AREA_WATER = 2, + POLY_AREA_ROAD = 3, + POLY_AREA_DANGER = 4, + }; + static const float TileSize; + static const float MaxXY; + static const float ChunkSize; + static const float UnitSize; + static const float Origin[]; + static const float PI; +}; + +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp new file mode 100644 index 00000000000..8af6f3a02e8 --- /dev/null +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -0,0 +1,11 @@ +#include "ContinentBuilder.h" +#include "WDT.h" +#include "Utils.h" + +void ContinentBuilder::Build() +{ + for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) + { + + } +} diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h new file mode 100644 index 00000000000..7db141ddcf1 --- /dev/null +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -0,0 +1,15 @@ +#ifndef CONT_BUILDER_H +#define CONT_BUILDER_H +#include +#include "WDT.h" + +class ContinentBuilder +{ +public: + ContinentBuilder(std::string continent, WDT* wdt) : Continent(continent), TileMap(wdt) {} + void Build(); +private: + std::string Continent; + WDT* TileMap; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp new file mode 100644 index 00000000000..4a7707753c4 --- /dev/null +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -0,0 +1,99 @@ +#include "DoodadHandler.h" +#include "Chunk.h" +#include "Cache.h" +#include "Model.h" +#include "g3d/Matrix4.h" + +DoodadHandler::DoodadHandler( ADT* adt ) : ObjectDataHandler(adt), _definitions(NULL), _paths(NULL) +{ + if (!adt->HasObjectData) + return; + Chunk* mddf = adt->ObjectData->GetChunkByName("MDDF"); + if (mddf) + ReadDoodadDefinitions(mddf); + + Chunk* mmid = adt->ObjectData->GetChunkByName("MMID"); + Chunk* mmdx = adt->ObjectData->GetChunkByName("MMDX"); + if (mmid && mmdx) + ReadDoodadPaths(mmid, mmdx); +} + +void DoodadHandler::ProcessInternal( ChunkedData* subChunks ) +{ + if (!IsSane()) + return; + Chunk* doodadReferencesChunk = subChunks->GetChunkByName("MCRD"); + if (!doodadReferencesChunk) + return; + FILE* stream = doodadReferencesChunk->GetStream(); + uint32 refCount = doodadReferencesChunk->Length / 4; + for (int i = 0; i < refCount; i++) + { + int32 index; + fread(&index, sizeof(int32), 1, stream); + if (index < 0 || index >= _definitions->size()) + continue; + DoodadDefinition doodad = (*_definitions)[index]; + if (_drawn.find(doodad.UniqueId) != _drawn.end()) + continue; + _drawn.insert(doodad.UniqueId); + if (doodad.MmidIndex >= _paths->size()) + continue; + + std::string path = (*_paths)[doodad.MmidIndex]; + Model* model = Cache.ModelCache.Get(path); + if (!model) + { + model = new Model(path); + Cache.ModelCache.Insert(path, model); + } + if (!model->IsCollidable) + continue; + + Vertices.reserve(refCount * model->Vertices.size() * 0.2); + Triangles.reserve(refCount * model->Triangles.size() * 0.2); + + InsertModelGeometry(doodad, model); + } +} + +void DoodadHandler::ReadDoodadDefinitions( Chunk* chunk ) +{ + int32 count = chunk->Length / 36; + _definitions = new std::vector; + _definitions->reserve(count); + FILE* stream = chunk->GetStream(); + for (int i = 0; i < count; i++) + { + DoodadDefinition def; + def.Read(stream); + _definitions->push_back(def); + } +} + +void DoodadHandler::ReadDoodadPaths( Chunk* id, Chunk* data ) +{ + int paths = id->Length / 4; + _paths = new std::vector(); + _paths->reserve(paths); + for (int i = 0; i < paths; i++) + { + FILE* idStream = id->GetStream(); + fseek(idStream, i * 4, SEEK_CUR); + uint32 offset; + fread(&offset, sizeof(uint32), 1, idStream); + FILE* dataStream = data->GetStream(); + fseek(dataStream, offset + data->Offset, SEEK_SET); + _paths->push_back(Utils::ReadString(dataStream)); + } +} + +void DoodadHandler::InsertModelGeometry(DoodadDefinition def, Model* model) +{ + G3D::Matrix4 transformation = Utils::GetTransformation(def); + uint32 vertOffset = Vertices.size(); + for (std::vector::iterator itr = model->Vertices.begin(); itr != model->Vertices.end(); ++itr) + Vertices.push_back(Utils::VectorTransform(*itr, transformation)); + for (std::vector >::iterator itr = model->Triangles.begin(); itr != model->Triangles.end(); ++itr) + Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_DOODAD, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); +} \ No newline at end of file diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h new file mode 100644 index 00000000000..c62584ca1f1 --- /dev/null +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -0,0 +1,51 @@ +#ifndef DOOADHNDL_H +#define DOOADHNDL_H +#include "ObjectDataHandler.h" +#include "Utils.h" +#include "Chunk.h" +#include "Model.h" +#include +#include + +class DoodadDefinition : IDefinition +{ +public: + uint32 MmidIndex; + uint32 UniqueId; + uint16 DecimalScale; + uint16 Flags; + + float Scale() { return DecimalScale / 1024.0f; } + + void Read(FILE* stream) + { + fread(&MmidIndex, sizeof(uint32), 1, stream); + fread(&UniqueId, sizeof(uint32), 1, stream); + Position = Vector3::Read(stream); + Rotation = Vector3::Read(stream); + fread(&DecimalScale, sizeof(uint16), 1, stream); + fread(&Flags, sizeof(uint16), 1, stream); + } +}; + +class DoodadHandler : public ObjectDataHandler +{ +public: + DoodadHandler(ADT* adt); + std::vector Vertices; + std::vector > Triangles; + bool IsSane() { return _definitions && _paths; } + + +protected: + void ProcessInternal(ChunkedData* chunk); + +private: + void ReadDoodadDefinitions(Chunk* chunk); + void ReadDoodadPaths(Chunk* id, Chunk* data); + void InsertModelGeometry(DoodadDefinition def, Model* model); + std::set _drawn; + std::vector* _definitions; + std::vector* _paths; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp new file mode 100644 index 00000000000..8e417af4c73 --- /dev/null +++ b/src/tools/mesh_extractor/Geometry.cpp @@ -0,0 +1,102 @@ +#include "Geometry.h" +#include "Constants.h" + +Geometry::Geometry() : Transform(false) +{ + Vertices.reserve(10000); + Triangles.reserve(10000); +} + +void Geometry::CalculateBoundingBox( float*& min, float*& max ) +{ + min = new float[3]; + max = new float[3]; + + for (std::vector::iterator itr = Vertices.begin(); itr != Vertices.end(); ++itr) + { + if (itr->x > max[0]) + max[0] = itr->x; + if (itr->x < min[0]) + min[0] = itr->x; + + if (itr->y > max[1]) + max[1] = itr->y; + if (itr->y < min[1]) + min[1] = itr->y; + + if (itr->z > max[2]) + max[2] = itr->z; + if (itr->z < min[2]) + min[2] = itr->z; + } +} + +void Geometry::CalculateMinMaxHeight( float& min, float& max ) +{ + min = 0.0f; + max = 0.0f; + + for (std::vector::iterator itr = Vertices.begin(); itr != Vertices.end(); ++itr) + { + if (Transform) + { + if (itr->y < min) + min = itr->y; + if (itr->y > max) + max = itr->y; + } + else + { + if (itr->z < min) + min = itr->z; + if (itr->z > max) + max = itr->z; + } + } +} + +void Geometry::AddData( std::vector& verts, std::vector >& tris ) +{ + uint32 vertOffset = Vertices.size(); + for (std::vector::iterator itr = verts.begin(); itr != verts.end(); ++itr) + Vertices.push_back(Transform ? Utils::ToRecast(*itr) : *itr); + + for (std::vector >::iterator itr = tris.begin(); itr != tris.end(); ++itr) + Triangles.push_back(Triangle(itr->Type, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); +} + +void Geometry::GetRawData( float*& verts, int*& tris, uint8*& areas ) +{ + verts = new float[Vertices.size() * 3]; + for (int i = 0; i < Vertices.size(); ++i) + { + Vector3& vert = Vertices[i]; + verts[(i * 3) + 0] = vert.x; + verts[(i * 3) + 1] = vert.y; + verts[(i * 3) + 2] = vert.z; + } + + tris = new int[Triangles.size() * 3]; + for (int i = 0; i < Triangles.size(); ++i) + { + Triangle& tri = Triangles[i]; + tris[(i * 3) + 0] = (int)tri.V0; + tris[(i * 3) + 1] = (int)tri.V1; + tris[(i * 3) + 2] = (int)tri.V2; + } + + areas = new uint8[Triangles.size()]; + for (int i = 0; i < Triangles.size(); i++) + { + switch (Triangles[i].Type) + { + case Constants::TRIANGLE_TYPE_WATER: + areas[i] = Constants::POLY_AREA_WATER; + break; + default: + areas[i] = Constants::POLY_AREA_TERRAIN; + break; + } + } +} + diff --git a/src/tools/mesh_extractor/Geometry.h b/src/tools/mesh_extractor/Geometry.h new file mode 100644 index 00000000000..048d9fde578 --- /dev/null +++ b/src/tools/mesh_extractor/Geometry.h @@ -0,0 +1,21 @@ +#ifndef GEOMETRY_H +#define GEOMETRY_H +#include + +#include "Utils.h" + +class Geometry +{ +public: + Geometry(); + + void CalculateBoundingBox(float*& min, float*& max); + void CalculateMinMaxHeight(float& min, float& max); + void AddData(std::vector& verts, std::vector >& tris); + void GetRawData(float*& verts, int*& tris, uint8*& areas); + + std::vector Vertices; + std::vector > Triangles; + bool Transform; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp new file mode 100644 index 00000000000..5924c693196 --- /dev/null +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -0,0 +1 @@ +#include "LiquidHandler.h" \ No newline at end of file diff --git a/src/tools/mesh_extractor/LiquidHandler.h b/src/tools/mesh_extractor/LiquidHandler.h new file mode 100644 index 00000000000..ba89be33e08 --- /dev/null +++ b/src/tools/mesh_extractor/LiquidHandler.h @@ -0,0 +1,17 @@ +#ifndef LIQUID_H +#define LIQUID_H +#include "ADT.h" +#include "Utils.h" +#include "Common.h" + +#include + +class LiquidHandler +{ +public: + ADT* Source; + std::vector Vertices; + std::vector > Triangles; + std::vector MCNKData; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/MPQ.cpp b/src/tools/mesh_extractor/MPQ.cpp new file mode 100644 index 00000000000..fbae56cd7a0 --- /dev/null +++ b/src/tools/mesh_extractor/MPQ.cpp @@ -0,0 +1,117 @@ +#include "MPQ.h" +#include "MPQManager.h" +#include +#include + +MPQArchive::MPQArchive(const char* filename) +{ + int result = libmpq__archive_open(&mpq_a, filename, -1); + printf("Opening %s\n", filename); + if (result) + { + switch (result) + { + case LIBMPQ_ERROR_OPEN : + printf("Error opening archive '%s': Does file really exist?\n", filename); + break; + case LIBMPQ_ERROR_FORMAT : /* bad file format */ + printf("Error opening archive '%s': Bad file format\n", filename); + break; + case LIBMPQ_ERROR_SEEK : /* seeking in file failed */ + printf("Error opening archive '%s': Seeking in file failed\n", filename); + break; + case LIBMPQ_ERROR_READ : /* Read error in archive */ + printf("Error opening archive '%s': Read error in archive\n", filename); + break; + case LIBMPQ_ERROR_MALLOC : /* maybe not enough memory? :) */ + printf("Error opening archive '%s': Maybe not enough memory\n", filename); + break; + default: + printf("Error opening archive '%s': Unknown error\n", filename); + break; + } + } +} + +void MPQArchive::close() +{ + libmpq__archive_close(mpq_a); +} + +MPQFile::MPQFile(const char* filename): +eof(false), buffer(0), pointer(0), size(0) +{ + for (std::deque::iterator i = MPQHandler->Archives.begin(); i != MPQHandler->Archives.end();++i) + { + mpq_archive* mpq_a = (*i)->mpq_a; + + uint32_t filenum; + if(libmpq__file_number(mpq_a, filename, &filenum)) + continue; + libmpq__off_t transferred; + libmpq__file_unpacked_size(mpq_a, filenum, &size); + + // HACK: in patch.mpq some files don't want to open and give 1 for filesize + if (size<=1) { + // printf("warning: file %s has size %d; cannot Read.\n", filename, size); + eof = true; + buffer = 0; + return; + } + buffer = new char[size]; + + //libmpq_file_getdata + libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); + /*libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);*/ + return; + + } + eof = true; + buffer = 0; +} + +size_t MPQFile::Read(void* dest, size_t bytes) +{ + if (eof) + return 0; + + size_t rpos = pointer + bytes; + if (rpos > size) { + bytes = size - pointer; + eof = true; + } + + memcpy(dest, &(buffer[pointer]), bytes); + + pointer = rpos; + + return bytes; +} + +void MPQFile::seek(int offset) +{ + pointer = offset; + eof = (pointer >= size); +} + +void MPQFile::seekRelative(int offset) +{ + pointer += offset; + eof = (pointer >= size); +} + +void MPQFile::close() +{ + if (buffer) + delete[] buffer; + buffer = 0; + eof = true; +} + +FILE* MPQFile::GetFileStream() +{ + FILE* file = tmpfile(); + fwrite(buffer, sizeof(char), size, file); + fseek(file, 0, SEEK_SET); + return file; +} diff --git a/src/tools/mesh_extractor/MPQ.h b/src/tools/mesh_extractor/MPQ.h new file mode 100644 index 00000000000..dd566bccff5 --- /dev/null +++ b/src/tools/mesh_extractor/MPQ.h @@ -0,0 +1,88 @@ +#ifndef MPQ_H +#define MPQ_H + +#include "libmpq/mpq.h" +#include "Common.h" +#include +#include +#include +#include +#include + +using namespace std; + +class MPQArchive +{ + +public: + mpq_archive_s *mpq_a; + + MPQArchive(const char* filename); + void close(); + + void GetFileListTo(vector& filelist) { + uint32_t filenum; + if(libmpq__file_number(mpq_a, "(listfile)", &filenum)) return; + libmpq__off_t size, transferred; + libmpq__file_unpacked_size(mpq_a, filenum, &size); + + char *buffer = new char[size]; + + libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); + + char seps[] = "\n"; + char* token; + + token = strtok( buffer, seps ); + uint32 counter = 0; + while ((token != NULL) && (counter < size)) { + //cout << token << endl; + token[strlen(token) - 1] = 0; + string s = token; + filelist.push_back(s); + counter += strlen(token) + 2; + token = strtok(NULL, seps); + } + + delete[] buffer; + } +}; + +class MPQFile +{ + //MPQHANDLE handle; + bool eof; + char *buffer; + libmpq__off_t pointer,size; + + // disable copying + MPQFile(const MPQFile& /*f*/) {} + void operator=(const MPQFile& /*f*/) {} + +public: + MPQFile(const char* filename); // filenames are not case sensitive + ~MPQFile() { close(); } + size_t Read(void* dest, size_t bytes); + FILE* GetFileStream(); + size_t getSize() { return size; } + size_t getPos() { return pointer; } + char* getBuffer() { return buffer; } + char* getPointer() { return buffer + pointer; } + bool isEof() { return eof; } + void seek(int offset); + void seekRelative(int offset); + void close(); +}; + +inline void flipcc(char *fcc) +{ + char t; + t=fcc[0]; + fcc[0]=fcc[3]; + fcc[3]=t; + t=fcc[1]; + fcc[1]=fcc[2]; + fcc[2]=t; +} + +#endif diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp new file mode 100644 index 00000000000..429b09ffe02 --- /dev/null +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -0,0 +1,58 @@ +#include "MPQManager.h" +#include "MPQ.h" + +char* MPQManager::Files[] = { + "common.MPQ", + "common-2.MPQ", + "expansion.MPQ", + "lichking.MPQ", + "patch.MPQ", + "patch-2.MPQ", + "patch-3.MPQ" +}; + +void MPQManager::Initialize() +{ + LoadMPQs(); +} + +void MPQManager::LoadMaps() +{ + +} + +void MPQManager::LoadMPQs() +{ + // Load the locale MPQ files first + char filename[512]; + + /*sprintf(filename,"Data/%s/locale-%s.MPQ", langs[locale], langs[locale]);*/ + Archives.push_front(new MPQArchive("Data/enUS/locale-enUS.MPQ")); + + for(int i = 0; i < 3; ++i) + { + char ext[3] = ""; + if (i) + sprintf(ext, "-%i", i + 1); + + sprintf(filename, "Data/enUS/patch-enUS%s.MPQ", ext); + Archives.push_front(new MPQArchive(filename)); + } + + // Now load the common MPQ files + int count = sizeof(Files) / sizeof(char*); + for (int i = 0; i < count; ++i) + { + sprintf(filename, "Data/%s", Files[i]); + Archives.push_front(new MPQArchive(filename)); + } + printf("Loaded %u MPQ files succesfully", Archives.size()); +} + +FILE* MPQManager::GetFile( std::string path ) +{ + MPQFile file(path.c_str()); + if (file.isEof()) + return NULL; + return file.GetFileStream(); +} diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h new file mode 100644 index 00000000000..e10066ae4a6 --- /dev/null +++ b/src/tools/mesh_extractor/MPQManager.h @@ -0,0 +1,24 @@ +#ifndef MPQ_MANAGER_H +#define MPQ_MANAGER_H + +#include "MPQ.h" + +class MPQManager +{ +public: + MPQManager() {} + ~MPQManager() {} + + void Initialize(); + void LoadMaps(); + FILE* GetFile(std::string path); + + std::deque Archives; + + static char* Files[]; +protected: + void LoadMPQs(); +}; + +extern MPQManager* MPQHandler; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp new file mode 100644 index 00000000000..95f8c2e56c0 --- /dev/null +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -0,0 +1,77 @@ +#include "MapChunk.h" +#include "ADT.h" + +MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : adt(_adt), Source(chunk), Vertices(NULL) +{ + FILE* stream = chunk->GetStream(); + Header.Read(stream); + fseek(stream, chunk->Offset, SEEK_SET); + GenerateVertices(stream); +} + +void MapChunk::GenerateTriangles() +{ + Triangles.reserve(256); + for (int y = 0; y < 8; y++) + { + for (int x = 0; x < 8; x++) + { + if (HasHole(Header.Holes, x / 2, y / 2)) + continue; + + uint32 topLeft = (17 * y) + x; + uint32 topRight = (17 * y) + x + 1; + uint32 bottomLeft = (17 * (y + 1)) + x; + uint32 bottomRight = (17 * (y + 1)) + x + 1; + uint32 center = (17 * y) + 9 + x; + + uint8 triangleType = Constants::TRIANGLE_TYPE_TERRAIN; + if (ADT.LiquidHandler && ADT.LiquidHandler.MCNKData) + { + var data = ADT.LiquidHandler.MCNKData[Index]; + uint32 maxHeight = std::max( + std::max( + std::max(std::max(Vertices[topLeft].z, Vertices[topRight].z), Vertices[bottomLeft].z), + Vertices[bottomRight].z), Vertices[center].z); + if (data && data->IsWater(x, y, maxHeight)) + triangleType = Constants::TRIANGLE_TYPE_WATER; + } + + Triangles.push_back(new Triangle(triangleType, topRight, topLeft, center)); + Triangles.push_back(new Triangle(triangleType, topLeft, bottomLeft, center)); + Triangles.push_back(new Triangle(triangleType, bottomLeft, bottomRight, center)); + Triangles.push_back(new Triangle(triangleType, bottomRight, topRight, center)); + } + } +} + +MapChunk::~MapChunk() +{ + delete[] Vertices; +} + +void MapChunk::GenerateVertices( FILE* stream ) +{ + fseek(stream, Header.OffsetMCVT, SEEK_CUR); + int32 vertIndex = 0; + Vertices = new Vector3[125]; + + for (int j = 0; j < 17; j++) + { + int values = j % 2 ? 8 : 9; + for (int i = 0; i < values; i++) + { + float tmp; + fread(&tmp, sizeof(float), 1, stream); + Vector3 vert(Header.Position.x - (j * (Constants::UnitSize * 0.5f)), Header.Position.y - (i * Constants::UnitSize), Header.Position.z + tmp); + if (values == 8) + vert.y -= Constants::UnitSize * 0.5f; + Vertices[vertIndex++] = vert; + } + } +} + +bool MapChunk::HasHole( uint32 map, int x, int y ) +{ + return (map & 0x0000FFFF) & ((1 << x) << (y << 2)); +} diff --git a/src/tools/mesh_extractor/MapChunk.h b/src/tools/mesh_extractor/MapChunk.h new file mode 100644 index 00000000000..034429a81ec --- /dev/null +++ b/src/tools/mesh_extractor/MapChunk.h @@ -0,0 +1,25 @@ +#ifndef MAPCHUNK_H +#define MAPCHUNK_H +#include "Chunk.h" +#include "Utils.h" +#include "Constants.h" +#include +class ADT; + +class MapChunk +{ +public: + MapChunk(ADT* _adt, Chunk* chunk); + ~MapChunk(); + + void GenerateTriangles(); + void GenerateVertices(FILE* stream); + static bool HasHole(uint32 map, int x, int y); + ADT* adt; + Chunk* Source; + MapChunkHeader Header; + Vector3* Vertices; + std::vector > Triangles; + int32 Index; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp new file mode 100644 index 00000000000..0220627cbcc --- /dev/null +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -0,0 +1,34 @@ +#include "MPQManager.h" +#include "WDT.h" +#include "ContinentBuilder.h" +#include "Cache.h" + +MPQManager* MPQHandler; +CacheClass* Cache; + +void ExtractAllMaps() +{ + WDT wdt("World\\maps\\DalaranPrison\\DalaranPrison.wdt"); + if (!wdt.IsValid) + return; + printf("Model valid!"); + if (wdt.IsGlobalModel) + { + printf("Unsupported"); + return; + } + ContinentBuilder builder("DalaranPrison", &wdt); + builder.Build(); +} + +int main(int argc, char* argv[]) +{ + system("pause"); + Cache = new CacheClass(); + MPQHandler = new MPQManager(); + MPQHandler->Initialize(); + MPQHandler->LoadMaps(); + ExtractAllMaps(); + return 0; +} + diff --git a/src/tools/mesh_extractor/Model.cpp b/src/tools/mesh_extractor/Model.cpp new file mode 100644 index 00000000000..a1c67d23f28 --- /dev/null +++ b/src/tools/mesh_extractor/Model.cpp @@ -0,0 +1,49 @@ +#include "Model.h" +#include "MPQManager.h" +#include "Utils.h" + +Model::Model( std::string path ) +{ + Stream = MPQHandler->GetFile(Utils::FixModelPath(path)); + Header.Read(Stream); + if (Header.OffsetBoundingNormals > 0 && Header.OffsetBoundingVertices > 0 && + Header.OffsetBoundingTriangles > 0 && Header.BoundingRadius > 0.0f) + { + IsCollidable = true; + ReadVertices(Stream); + ReadBoundingNormals(Stream); + ReadBoundingTriangles(Stream); + } +} + +void Model::ReadVertices( FILE* stream ) +{ + fseek(stream, Header.OffsetBoundingVertices, SEEK_SET); + Vertices.reserve(Header.CountBoundingVertices); + for (int i = 0; i < Header.CountBoundingVertices; ++i) + Vertices[i] = Vector3::Read(stream); +} + +void Model::ReadBoundingTriangles( FILE* stream ) +{ + fseek(stream, Header.OffsetBoundingTriangles, SEEK_SET); + Triangles.reserve(Header.CountBoundingTriangles / 3); + for (int i = 0; i < Header.CountBoundingTriangles / 3; i++) + { + Triangle tri; + tri.Type = Constants::TRIANGLE_TYPE_DOODAD; + fread(&tri.V0, sizeof(uint16), 1, stream); + fread(&tri.V1, sizeof(uint16), 1, stream); + fread(&tri.V2, sizeof(uint16), 1, stream); + Triangles[i] = tri; + } +} + +void Model::ReadBoundingNormals( FILE* stream ) +{ + fseek(stream, Header.OffsetBoundingNormals, SEEK_SET); + Normals.reserve(Header.CountBoundingNormals); + for (int i = 0; i < Header.CountBoundingNormals; i++) + Normals[i] = Vector3::Read(stream); +} + diff --git a/src/tools/mesh_extractor/Model.h b/src/tools/mesh_extractor/Model.h new file mode 100644 index 00000000000..a5b8338461d --- /dev/null +++ b/src/tools/mesh_extractor/Model.h @@ -0,0 +1,21 @@ +#ifndef MODEL_H +#define MODEL_H +#include +#include "Utils.h" + +class Model +{ +public: + Model(std::string path); + + void ReadVertices(FILE* stream); + void ReadBoundingTriangles(FILE* stream); + void ReadBoundingNormals(FILE* stream); + ModelHeader Header; + std::vector Vertices; + std::vector Normals; + std::vector > Triangles; + bool IsCollidable; + FILE* Stream; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/ObjectDataHandler.cpp b/src/tools/mesh_extractor/ObjectDataHandler.cpp new file mode 100644 index 00000000000..3ed2ee49604 --- /dev/null +++ b/src/tools/mesh_extractor/ObjectDataHandler.cpp @@ -0,0 +1,21 @@ +#include "ObjectDataHandler.h" +#include "Chunk.h" +#include "ADT.h" +#include "ChunkedData.h" + +void ObjectDataHandler::ProcessMapChunk( MapChunk* chunk ) +{ + if (!Source->HasObjectData) + return; + // fuck it blizzard, why is this crap necessary? + int32 firstIndex = Source->ObjectData->GetFirstIndex("MCNK"); + if (firstIndex == -1) + return; + if (firstIndex + chunk->Index > Source->ObjectData->Chunks.size()) + return; + Chunk* ourChunk = Source->ObjectData->Chunks[firstIndex + chunk->Index]; + if (ourChunk->Length == 0) + return; + ChunkedData* subChunks = new ChunkedData(ourChunk->GetStream(), ourChunk->Length, 2); + ProcessInternal(subChunks); +} diff --git a/src/tools/mesh_extractor/ObjectDataHandler.h b/src/tools/mesh_extractor/ObjectDataHandler.h new file mode 100644 index 00000000000..834bf66bcfb --- /dev/null +++ b/src/tools/mesh_extractor/ObjectDataHandler.h @@ -0,0 +1,15 @@ +#ifndef ODATA_HNDL_H +#define ODATA_HNDL_H +#include "ADT.h" +#include "MapChunk.h" + +class ObjectDataHandler +{ +public: + ObjectDataHandler(ADT* _adt) : Source(_adt) {} + + void ProcessMapChunk(MapChunk* chunk); + virtual void ProcessInternal(ChunkedData* data) = 0; + ADT* Source; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp new file mode 100644 index 00000000000..070b9d70050 --- /dev/null +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -0,0 +1,37 @@ +#include "TileBuilder.h" +#include "Constants.h" + +TileBuilder::TileBuilder(std::string world, int x, int y) : _Geometry(NULL), World(world), X(x), Y(y), MapId(608) +{ + // Cell Size = TileSize / TileVoxelSize + // 1800 = TileVoxelSize + Config.cs = Constants::TileSize / 1800; + // Cell Height + Config.ch = 0.3f; + // Min Region Area = 6^2 + Config.minRegionArea = 36; + // Merge Region Area = 12^2 + Config.mergeRegionArea = 144; + Config.walkableSlopeAngle = 50.0f; + Config.detailSampleDist = 3.0f; + Config.detailSampleMaxError = 1.25f; + Config.walkableClimb = 1.0f / Config.ch; + Config.walkableHeight = 2.1f / Config.ch; + Config.walkableRadius = 0.6f / Config.cs; + Config.maxEdgeLen = Config.walkableRadius * 8; + Config.borderSize = Config.walkableRadius + 8; + Config.width = 1800; + Config.maxVertsPerPoly = 6; + Config.maxSimplificationError = 1.3f; +} + +void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax ) +{ + float origin[3] = Constants::Origin; + bmin = new float[3]; + bmax = new float[3]; + bmin[0] = origin[0] + (Constants::TileSize * X); + bmin[2] = origin[2] + (Constants::TileSize * Y); + bmax[0] = origin[0] + (Constants::TileSize * (X + 1)); + bmax[2] = origin[2] + (Constants::TileSize * (Y + 1)); +} \ No newline at end of file diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h new file mode 100644 index 00000000000..badb05295e5 --- /dev/null +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -0,0 +1,22 @@ +#ifndef TILE_BUILD_H +#define TILE_BUILD_H +#include +#include "Recast.h" + +#include "Geometry.h" + +class TileBuilder +{ +public: + TileBuilder(std::string world, int x, int y); + void CalculateTileBounds(float*& bmin, float*& bmax); + uint8* Build(); + + std::string World; + int X; + int Y; + int MapId; + rcConfig Config; + Geometry* _Geometry; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp new file mode 100644 index 00000000000..03473eb0794 --- /dev/null +++ b/src/tools/mesh_extractor/Utils.cpp @@ -0,0 +1,163 @@ +#include "Utils.h" +#include "Constants.h" +#include +#include "g3d/Matrix4.h" + +const float Constants::TileSize = 533.0f + (1/3.0f); +const float Constants::MaxXY = 32.0f * Constants::TileSize; +const float Constants::ChunkSize = Constants::TileSize / 16.0f; +const float Constants::UnitSize = Constants::ChunkSize / 8.0f; +const float Constants::Origin[] = { -Constants::MaxXY, 0.0f, -Constants::MaxXY }; +const float Constants::PI = 3.1415926f; + +void Utils::Reverse(char word[]) +{ + int len = strlen(word); + for (int i = 0;i < len / 2; i++) + { + word[i] ^= word[len-i-1]; + word[len-i-1] ^= word[i]; + word[i] ^= word[len-i-1]; + } +} + +std::string Utils::ReadString( FILE* file ) +{ + std::string ret; + int i = 0; + while (true) + { + char b; + fread(&b, sizeof(char), 1, file); + if (b == 0) + break; + ret[i++] = b; + } + return ret; +} + +uint32 Utils::Size( FILE* file ) +{ + // store the old position + uint32 offset = ftell(file); + // Get file size + fseek(file, 0, SEEK_END); + uint32 size = ftell(file); + // reset back to the old position + fseek(file, offset, SEEK_SET); + return size; +} + +Vector3 Utils::ToRecast( Vector3 val ) +{ + return Vector3(-val.y, val.z, -val.x); +} + +std::string Utils::GetAdtPath( std::string world, int x, int y ) +{ + return "World\\Maps\\" + world + "\\" + world + "_" + Utils::ToString(x) + "_" + Utils::ToString(y) + ".adt"; +} + +std::string Utils::FixModelPath( std::string path ) +{ + std::string::size_type idx = path.rfind("."); + // Bizarre way of changing extension but... + if (idx != std::string::npos) + { + path[idx + 1] = "M"; + path[idx + 2] = "2"; + } + return path; +} + +G3D::Matrix4 Utils::RotationX(float angle) +{ + float _cos = cos(angle); + float _sin = sin(angle); + Matrix4 ret = G3D::Matrix4::identity(); + ret[2][2] = _cos; + ret[2][3] = _sin; + ret[3][2] = -_sin; + ret[3][3] = _cos; + return ret; +} + +G3D::Matrix4 Utils::GetTransformation( IDefinition def ) +{ + G3D::Matrix4 translation; + if (def.Position.x == 0.0f && def.Position.y == 0.0f && def.Position.z == 0.0f) + translation = G3D::Matrix4::identity(); + else + translation = G3D::Matrix4::translation(-(def.Position.z - Constants::MaxXY), + -(def.Position.x - Constants::MaxXY), def.Position.y); + + G3D::Matrix4 rotation = RotationX(ToRadians(def.Rotation.z)) * RotationY(ToRadians(def.Rotation.x)) * RotationZ(ToRadians(def.Rotation.y + 180)); + if (def.Scale() < 1.0f || def.Scale() > 1.0f) + return G3D::Matrix4::scale(def.Scale()) * rotation * translation; + return rotation * translation; +} + +G3D::Matrix4 Utils::RotationY( float angle ) +{ + float _cos = cos(angle); + float _sin = sin(angle); + Matrix4 ret = G3D::Matrix4::identity(); + ret[1][1] = _cos; + ret[1][3] = -_sin; + ret[3][1] = _sin; + ret[3][3] = _cos; + return ret; +} + +G3D::Matrix4 Utils::RotationZ( float angle ) +{ + float _cos = cos(angle); + float _sin = sin(angle); + Matrix4 ret = G3D::Matrix4::identity(); + ret[1][1] = _cos; + ret[1][2] = _sin; + ret[2][1] = -_sin; + ret[2][2] = _cos; + return ret; +} + +float Utils::ToRadians( float degrees ) +{ + return Constants::PI * degrees / 180.0f; +} + +Vector3 Utils::VectorTransform( Vector3 vec, G3D::Matrix matrix ) +{ + Vector3 ret; + ret.x = vec.x * matrix[1][1] + vec.y * matrix[2][1] + vec.z * matrix[3][1] + matrix[4][1]; + ret.y = vec.x * matrix[1][2] + vec.y * matrix[2][2] + vec.z * matrix[3][2] + matrix[4][2]; + ret.z = vec.x * matrix[1][3] + vec.y * matrix[2][3] + vec.z * matrix[3][3] + matrix[4][3]; + return ret; +} + +std::string Utils::GetPathBase( std::string path ) +{ + int lastIndex = path.find_last_of("."); + if (lastIndex != std::string::npos) + return path.substr(0, lastindex); + return path; +} + +Vector3 Vector3::Read( FILE* file ) +{ + Vector3 ret; + fread(&ret, sizeof(Vector3), 1, file); + return ret; +} + +Vector3 Utils::GetLiquidVert(G3D::Matrix4 transformation, Vector3 basePosition, float height, int x, int y) +{ + if (Utils::Distance(height, 0.0f) > 0.5f) + basePosition.z = 0.0f; + return Utils::VectorTransform(basePosition + Vector3(basePosition.x * Constants::UnitSize, basePosition.y * Constants::UnitSize, height), transformation); +} + +float Utils::Distance( float x, float y ) +{ + return sqrt(x*x + y*y); +} diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h new file mode 100644 index 00000000000..cda5f4c7cd8 --- /dev/null +++ b/src/tools/mesh_extractor/Utils.h @@ -0,0 +1,497 @@ +#ifndef UTILS_H +#define UTILS_H +#include +#include +#include + +#include "g3d/Matrix4.h" + +#include "Common.h" +#include "Constants.h" + +struct Vector3 +{ + Vector3() {} + Vector3(float X, float Y, float Z) : x(X), y(Y), z(Z) {} + float x; + float y; + float z; + Vector3 operator+(Vector3 right, Vector3 left) + { + return Vector3(right.x+left.x, right.y+left.y, right.z+left.z); + } + static Vector3 Read(FILE* file); +}; + +struct TilePos +{ + TilePos(int x, int y) : X(x), Y(y) {} + int X; + int Y; +}; + +template +struct Triangle +{ + Triangle(Constants::TriangleType type, T v0, T v1, T v2) : Type(type), V0(v0), V1(v1), V2(v2) {} + T V0; + T V1; + T V2; + Constants::TriangleType Type; +}; + +class MapChunkHeader +{ +public: + MapChunkHeader() {} + uint32 Flags; + uint32 IndexX; + uint32 IndexY; + uint32 Layers; + uint32 DoodadRefs; + uint32 OffsetMCVT; + uint32 OffsetMCNR; + uint32 OffsetMCLY; + uint32 OffsetMCRF; + uint32 OffsetMCAL; + uint32 SizeMCAL; + uint32 OffsetMCSH; + uint32 SizeMCSH; + uint32 AreaId; + uint32 MapObjectRefs; + uint32 Holes; + uint32* LowQualityTextureMap; + uint32 PredTex; + uint32 NumberEffectDoodad; + uint32 OffsetMCSE; + uint32 SoundEmitters; + uint32 OffsetMCLQ; + uint32 SizeMCLQ; + Vector3 Position; + uint32 OffsetMCCV; + + void Read(FILE* stream) + { + fread(&Flags, sizeof(uint32), 1, stream); + fread(&IndexX, sizeof(uint32), 1, stream); + fread(&IndexY, sizeof(uint32), 1, stream); + fread(&Layers, sizeof(uint32), 1, stream); + fread(&DoodadRefs, sizeof(uint32), 1, stream); + fread(&OffsetMCVT, sizeof(uint32), 1, stream); + fread(&OffsetMCNR, sizeof(uint32), 1, stream); + fread(&OffsetMCLY, sizeof(uint32), 1, stream); + fread(&OffsetMCRF, sizeof(uint32), 1, stream); + fread(&OffsetMCAL, sizeof(uint32), 1, stream); + fread(&SizeMCAL, sizeof(uint32), 1, stream); + fread(&OffsetMCSH, sizeof(uint32), 1, stream); + fread(&SizeMCSH, sizeof(uint32), 1, stream); + fread(&AreaId, sizeof(uint32), 1, stream); + fread(&MapObjectRefs, sizeof(uint32), 1, stream); + fread(&Holes, sizeof(uint32), 1, stream); + LowQualityTextureMap = new uint32[4]; + fread(LowQualityTextureMap, sizeof(uint32), 4, stream); + fread(&PredTex, sizeof(uint32), 1, stream); + fread(&NumberEffectDoodad, sizeof(uint32), 1, stream); + fread(&OffsetMCSE, sizeof(uint32), 1, stream); + fread(&SoundEmitters, sizeof(uint32), 1, stream); + fread(&OffsetMCLQ, sizeof(uint32), 1, stream); + fread(&SizeMCLQ, sizeof(uint32), 1, stream); + Position = Vector3::Read(stream); + fread(&OffsetMCCV, sizeof(uint32), 1, stream); + } +}; + +class MHDR +{ +public: + MHDR() {} + uint32 Flags; + uint32 OffsetMCIN; + uint32 OffsetMTEX; + uint32 OffsetMMDX; + uint32 OffsetMMID; + uint32 OffsetMWMO; + uint32 OffsetMWID; + uint32 OffsetMDDF; + uint32 OffsetMODF; + uint32 OffsetMFBO; + uint32 OffsetMH2O; + uint32 OffsetMTFX; + + void Read(FILE* stream) + { + fread(&Flags, sizeof(uint32), 1, stream); + fread(&OffsetMCIN, sizeof(uint32), 1, stream); + fread(&OffsetMTEX, sizeof(uint32), 1, stream); + fread(&OffsetMMDX, sizeof(uint32), 1, stream); + fread(&OffsetMMID, sizeof(uint32), 1, stream); + fread(&OffsetMWMO, sizeof(uint32), 1, stream); + fread(&OffsetMWID, sizeof(uint32), 1, stream); + fread(&OffsetMDDF, sizeof(uint32), 1, stream); + fread(&OffsetMODF, sizeof(uint32), 1, stream); + fread(&OffsetMFBO, sizeof(uint32), 1, stream); + fread(&OffsetMH2O, sizeof(uint32), 1, stream); + fread(&OffsetMTFX, sizeof(uint32), 1, stream); + } +}; + +class ModelHeader +{ +public: + char Magic[5]; + uint32 Version; + uint32 LengthModelName; + uint32 OffsetName; + uint32 ModelFlags; + uint32 CountGlobalSequences; + uint32 OffsetGlobalSequences; + uint32 CountAnimations; + uint32 OffsetAnimations; + uint32 CountAnimationLookup; + uint32 OffsetAnimationLookup; + uint32 CountBones; + uint32 OffsetBones; + uint32 CountKeyBoneLookup; + uint32 OffsetKeyBoneLookup; + uint32 CountVertices; + uint32 OffsetVertices; + uint32 CountViews; + uint32 CountColors; + uint32 OffsetColors; + uint32 CountTextures; + uint32 OffsetTextures; + uint32 CountTransparency; + uint32 OffsetTransparency; + uint32 CountUvAnimation; + uint32 OffsetUvAnimation; + uint32 CountTexReplace; + uint32 OffsetTexReplace; + uint32 CountRenderFlags; + uint32 OffsetRenderFlags; + uint32 CountBoneLookup; + uint32 OffsetBoneLookup; + uint32 CountTexLookup; + uint32 OffsetTexLookup; + uint32 CountTexUnits; + uint32 OffsetTexUnits; + uint32 CountTransLookup; + uint32 OffsetTransLookup; + uint32 CountUvAnimLookup; + uint32 OffsetUvAnimLookup; + Vector3 VertexBox[2]; + float VertexRadius; + Vector3 BoundingBox[2]; + float BoundingRadius; + uint32 CountBoundingTriangles; + uint32 OffsetBoundingTriangles; + uint32 CountBoundingVertices; + uint32 OffsetBoundingVertices; + uint32 CountBoundingNormals; + uint32 OffsetBoundingNormals; + + void Read(FILE* stream) + { + fread(&Magic, sizeof(char), 4, stream); + Magic[4] = '\0'; // null-terminate it. + fread(&Version, sizeof(uint32), 1, stream); + fread(&LengthModelName, sizeof(uint32), 1, stream); + fread(&OffsetName, sizeof(uint32), 1, stream); + fread(&ModelFlags, sizeof(uint32), 1, stream); + fread(&CountGlobalSequences, sizeof(uint32), 1, stream); + fread(&OffsetGlobalSequences, sizeof(uint32), 1, stream); + fread(&CountAnimations, sizeof(uint32), 1, stream); + fread(&OffsetAnimations, sizeof(uint32), 1, stream); + fread(&CountAnimationLookup, sizeof(uint32), 1, stream); + fread(&OffsetAnimationLookup, sizeof(uint32), 1, stream); + fread(&CountBones, sizeof(uint32), 1, stream); + fread(&OffsetBones, sizeof(uint32), 1, stream); + fread(&CountKeyBoneLookup, sizeof(uint32), 1, stream); + fread(&OffsetKeyBoneLookup, sizeof(uint32), 1, stream); + fread(&CountVertices, sizeof(uint32), 1, stream); + fread(&OffsetVertices, sizeof(uint32), 1, stream); + fread(&CountViews, sizeof(uint32), 1, stream); + fread(&CountColors, sizeof(uint32), 1, stream); + fread(&OffsetColors, sizeof(uint32), 1, stream); + fread(&CountTextures, sizeof(uint32), 1, stream); + fread(&OffsetTextures, sizeof(uint32), 1, stream); + fread(&CountTransparency, sizeof(uint32), 1, stream); + fread(&OffsetTransparency, sizeof(uint32), 1, stream); + fread(&CountUvAnimation, sizeof(uint32), 1, stream); + fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); + fread(&CountTexReplace, sizeof(uint32), 1, stream); + fread(&OffsetTexReplace, sizeof(uint32), 1, stream); + fread(&CountRenderFlags, sizeof(uint32), 1, stream); + fread(&OffsetRenderFlags, sizeof(uint32), 1, stream); + fread(&CountBoneLookup, sizeof(uint32), 1, stream); + fread(&OffsetBoneLookup, sizeof(uint32), 1, stream); + fread(&CountTexLookup, sizeof(uint32), 1, stream); + fread(&OffsetTexLookup, sizeof(uint32), 1, stream); + fread(&CountTexUnits, sizeof(uint32), 1, stream); + fread(&OffsetTexUnits, sizeof(uint32), 1, stream); + fread(&CountTransLookup, sizeof(uint32), 1, stream); + fread(&OffsetTransLookup, sizeof(uint32), 1, stream); + fread(&CountUvAnimLookup, sizeof(uint32), 1, stream); + fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream); + fread(&CountColors, sizeof(uint32), 1, stream); + fread(&OffsetColors, sizeof(uint32), 1, stream); + fread(&CountTextures, sizeof(uint32), 1, stream); + fread(&OffsetTextures, sizeof(uint32), 1, stream); + fread(&CountTransparency, sizeof(uint32), 1, stream); + fread(&OffsetTransparency, sizeof(uint32), 1, stream); + fread(&CountUvAnimation, sizeof(uint32), 1, stream); + fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); + fread(&CountTexReplace, sizeof(uint32), 1, stream); + fread(&OffsetTexReplace, sizeof(uint32), 1, stream); + VertexBox[0] = Vector3::Read(stream); + VertexBox[1] = Vector3::Read(stream); + fread(&VertexRadius, sizeof(float), 1, stream); + BoundingBox[0] = Vector3::Read(stream); + BoundingBox[1] = Vector3::Read(stream); + fread(&BoundingRadius, sizeof(float), 1, stream); + fread(&CountBoundingTriangles, sizeof(uint32), 1, stream); + fread(&OffsetBoundingTriangles, sizeof(uint32), 1, stream); + fread(&CountBoundingVertices, sizeof(uint32), 1, stream); + fread(&OffsetBoundingVertices, sizeof(uint32), 1, stream); + fread(&CountBoundingNormals, sizeof(uint32), 1, stream); + fread(&OffsetBoundingNormals, sizeof(uint32), 1, stream); + } +}; + +class WorldModelHeader +{ +public: + WorldModelHeader() {} + uint32 CountMaterials; + uint32 CountGroups; + uint32 CountPortals; + uint32 CountLights; + uint32 CountModels; + uint32 CountDoodads; + uint32 CountSets; + uint32 AmbientColorUnk; + uint32 WmoId; + Vector3 BoundingBox[2]; + uint32 LiquidTypeRelated; + + static WorldModelHeader Read(FILE* stream) + { + WorldModelHeader ret; + fread(&ret.CountMaterials, sizeof(uint32), 1, stream); + fread(&ret.CountGroups, sizeof(uint32), 1, stream); + fread(&ret.CountPortals, sizeof(uint32), 1, stream); + fread(&ret.CountLights, sizeof(uint32), 1, stream); + fread(&ret.CountModels, sizeof(uint32), 1, stream); + fread(&ret.CountDoodads, sizeof(uint32), 1, stream); + fread(&ret.CountSets, sizeof(uint32), 1, stream); + fread(&ret.AmbientColorUnk, sizeof(uint32), 1, stream); + fread(&ret.WmoId, sizeof(uint32), 1, stream); + ret.BoundingBox[0] = Vector3::Read(stream); + ret.BoundingBox[1] = Vector3::Read(stream); + fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); + return ret; + } +}; + +class DoodadInstance +{ +public: + DoodadInstance() {} + uint32 FileOffset; + std::string File; + Vector3 Position; + float QuatW; + float QuatX; + float QuatY; + float QuatZ; + float Scale; + uint32 LightColor; + + static DoodadInstance Read(FILE* stream) + { + DoodadInstance ret; + fread(&ret.FileOffset, sizeof(uint32), 1, stream); + ret.Position = Vector3::Read(stream); + fread(&ret.QuatW, sizeof(float), 1, stream); + fread(&ret.QuatX, sizeof(float), 1, stream); + fread(&ret.QuatY, sizeof(float), 1, stream); + fread(&ret.QuatZ, sizeof(float), 1, stream); + fread(&ret.Scale, sizeof(float), 1, stream); + fread(&ret.LightColor, sizeof(uint32), 1, stream); + return ret; + } +}; + +class DoodadSet +{ +public: + DoodadSet() {} + std::string Name; + uint32 FirstInstanceIndex; + uint32 CountInstances; + uint32 UnknownZero; + + static DoodadSet Read(FILE* stream) + { + DoodadSet ret; + char name[21]; + fread(&name, sizeof(char), 20, stream); + name[20] = '\0'; + ret.Name = name; + fread(&ret.FirstInstanceIndex, sizeof(uint32), 1, stream); + fread(&ret.CountInstances, sizeof(uint32), 1, stream); + fread(&ret.UnknownZero, sizeof(uint32), 1, stream); + return ret; + } +} + +class LiquidHeader +{ +public: + LiquidHeader() {} + uint32 CountXVertices; + uint32 CountYVertices; + uint32 Width; + uint32 Height; + Vector3 BaseLocation; + uint16 MaterialId; + + static LiquidHeader Read(FILE* stream) + { + LiquidHeader ret; + fread(&ret.CountXVertices, sizeof(uint32), 1, stream); + fread(&ret.CountYVertices, sizeof(uint32), 1, stream); + fread(&ret.Width, sizeof(uint32), 1, stream); + fread(&ret.Height, sizeof(uint32), 1, stream); + ret.BaseLocation = Vector3::Read(stream); + fread(&ret.MaterialId, sizeof(uint16), 1, stream); + return ret; + } +}; + +class LiquidData +{ +public: + LiquidData() {} + float** HeightMap; + uint8** RenderFlags; + + bool ShouldRender(int x, int y) + { + return RenderFlags[x][y] != 0x0F; + } + + public static LiquidData Read(FILE* stream, LiquidHeader header) + { + LiquidData ret; + ret.HeightMap = new float*[header.CountXVertices]; + for (int i = 0; i < header.CountXVertices; ++i) + ret.HeightMap[i] = new float[header.CountYVertices]; + + ret.RenderFlags = new uint8*[header.Width]; + for (int i = 0; i < header.Width; ++i) + ret.RenderFlags[i] = new uint8[header.Height]; + + for (int y = 0; y < header.CountYVertices; y++) + { + for (int x = 0; x < header.CountXVertices; x++) + { + uint32 discard; + fread(&discard, sizeof(uint32), 1, stream); + float tmp; + fread(&tmp, sizeof(float), 1, stream); + ret.HeightMap[x][y] = tmp; + } + } + + for (int y = 0; y < header.Height; y++) + { + for (int x = 0; x < header.Width; x++) + { + uint8 tmp; + fread(&tmp, sizeof(uint8), 1, stream); + ret.RenderFlags[x][y] = tmp; + } + } + + return ret; + } +}; + +class H2ORenderMask +{ +public: + H2ORenderMask() {} + uint8 Mask[8]; + + bool ShouldRender(int x, int y) + { + return (Mask[y] >> x & 1) != 0; + } + + static H2ORenderMask Read(FILE* stream) + { + H2ORenderMask ret; + fread(&ret.Mask, sizeof(uint8), 8, stream); + return ret; + } +}; + +class MCNKLiquidData +{ +public: + MCNKLiquidData() {} + const float MaxStandableHeight = 1.5f; + + float** Heights; + H2ORenderMask* Mask; + + bool IsWater(int x, int y, float height) + { + if (!Heights || !Mask) + return false; + if (!Mask->ShouldRender(x, y)) + return false; + float diff = Heights[x][y] - height; + if (diff > MaxStandableHeight) + return true; + return false; + } +}; + +// Dummy class to act as an interface. +class IDefinition +{ +public: + Vector3 Position; + Vector3 Rotation; + virtual float Scale() = 0; +}; + +class Utils +{ +public: + static void Reverse(char word[]); + static std::string ReadString(FILE* file); + static uint32 Size(FILE* file); + static Vector3 ToRecast( Vector3 val ); + static std::string GetAdtPath(std::string world, int x, int y); + static std::string FixModelPath(std::string path); + static G3D::Matrix4 GetTransformation(IDefinition def); + /// They say its better to declare template functions in the header files. + template + static std::string ToString(T val) + { + std::stringstream ss; + ss << val; + return ss.str(); + } + static G3D::Matrix4 RotationX(float angle); + static G3D::Matrix4 RotationY(float angle); + static G3D::Matrix4 RotationZ(float angle); + static float ToRadians(float degrees); + static Vector3 VectorTransform(Vector3 vec, G3D::Matrix matrix); + static std::string GetPathBase(std::string path); + static Vector3 GetLiquidVert(G3D::Matrix4 transformation, Vector3 basePosition, float height, int x, int y); + static float Distance(float x, float y); +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WDT.cpp b/src/tools/mesh_extractor/WDT.cpp new file mode 100644 index 00000000000..c06d8ac9677 --- /dev/null +++ b/src/tools/mesh_extractor/WDT.cpp @@ -0,0 +1,55 @@ +#include "WDT.h" +#include "Chunk.h" +#include "ChunkedData.h" +#include "Utils.h" +#include "WorldModelHandler.h" + +WDT::WDT(std::string file) : IsValid(false), IsGlobalModel(false) +{ + Data = new ChunkedData(file, 2); + ReadTileTable(); + ReadGlobalModel(); +} + +void WDT::ReadGlobalModel() +{ + Chunk* fileChunk = Data->GetChunkByName("MWMO"); + Chunk* defChunk = Data->GetChunkByName("MODF"); + if (!fileChunk || !defChunk) + return; + + IsGlobalModel = true; + ModelDefinition = WorldModelDefinition::Read(defChunk->GetStream()); + ModelFile = Utils::ReadString(fileChunk->GetStream()); +} + +void WDT::ReadTileTable() +{ + Chunk* chunk = Data->GetChunkByName("MAIN"); + if (!chunk) + return; + IsValid = true; + FILE* stream = chunk->GetStream(); + for (int y = 0; y < 64; ++y) + { + for (int x = 0; x < 64; ++x) + { + const uint32 hasTileFlag = 0x1; + uint32 flags; + uint32 discard; + fread(&flags, sizeof(uint32), 1, stream); + fread(&discard, sizeof(uint32), 1, stream); + if (flags & hasTileFlag) + TileTable.push_back(TilePos(x, y)); + + } + } +} + +bool WDT::HasTile( int x, int y ) +{ + for (std::vector::iterator itr = TileTable.begin(); itr != TileTable.end(); ++itr) + if (itr->X == x && itr->Y == y) + return true; + return false; +} diff --git a/src/tools/mesh_extractor/WDT.h b/src/tools/mesh_extractor/WDT.h new file mode 100644 index 00000000000..a12aa65218b --- /dev/null +++ b/src/tools/mesh_extractor/WDT.h @@ -0,0 +1,27 @@ +#ifndef WDT_H +#define WDT_H +#include +#include + +#include "ChunkedData.h" +#include "WorldModelHandler.h" +#include "Utils.h" + +class WDT +{ +public: + WDT(std::string file); + + ChunkedData* Data; + std::vector TileTable; + bool IsGlobalModel; + bool IsValid; + std::string ModelFile; + WorldModelDefinition ModelDefinition; + bool HasTile(int x, int y); +private: + void ReadGlobalModel(); + void ReadTileTable(); +}; + +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp new file mode 100644 index 00000000000..308c7ff7b86 --- /dev/null +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -0,0 +1,122 @@ +#include "WorldModelGroup.h" +#include "ChunkedData.h" +#include "Chunk.h" + +WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), IsBad(false) +{ + Data = new ChunkedData(path); + if (!Data->Stream) + { + IsBad = true; + return; + } + Chunk* mainChunk = Data->GetChunkByName("MOGP"); + int32 firstSub = mainChunk->FindSubChunkOffset("MOPY"); + if (firstSub == -1) + return; + FILE* stream = mainChunk->GetStream(); + fseek(stream, firstSub, SEEK_SET); + SubData = new ChunkedData(stream, mainChunk->Length - firstSub); + + ReadBoundingBox(); + ReadMaterials(); + ReadTriangles(); + ReadVertices(); + ReadNormals(); + ReadLiquid(); +} + +void WorldModelGroup::ReadNormals() +{ + Chunk* chunk = SubData->GetChunkByName("MONR"); + if (!chunk) + return; + + uint32 normalCount = chunk->Length / 12; + Assert(normalCount == Vertices.size(), "normalCount is different than the Vertices count"); + Normals.reserve(normalCount); + FILE* stream = chunk->GetStream(); + for (int i = 0; i < normalCount; i++) + Normals[i] = Vector3::Read(stream); +} + +void WorldModelGroup::ReadLiquid() +{ + Chunk* chunk = SubData->GetChunkByName("MLIQ"); + if (!chunk) + return; + + HasLiquidData = true; + FILE* stream = chunk->GetStream(); + LiquidDataHeader = LiquidHeader.Read(stream); + LiquidDataGeometry = LiquidData.Read(stream, LiquidDataHeader); +} + +void WorldModelGroup::ReadVertices() +{ + Chunk* chunk = SubData->GetChunkByName("MOVT"); + if (!chunk) + return; + + uint32 verticeCount = chunk.Length / 12; + Vertices.reserve(verticeCount); + FILE* stream = chunk->GetStream(); + for (int i = 0; i < verticeCount; i++) + Vertices.push_back(Vector3::Read(stream)); +} + +void WorldModelGroup::ReadTriangles() +{ + Chunk* chunk = SubData->GetChunkByName("MOVI"); + if (!chunk) + return; + + uint32 triangleCount = chunk.Length / 6; + Assert(triangleCount == TriangleFlags.size(), "triangleCount != TriangleFlags.size()"); + FILE* stream = chunk.GetStream(); + Triangles.reserve(triangleCount); + for (int i = 0; i < triangleCount; i++) + { + uint16 v0; + uint16 v1; + uint16 v2; + fread(&v0, sizeof(uint16), 1, stream); + fread(&v1, sizeof(uint16), 1, stream); + fread(&v2, sizeof(uint16), 1, stream); + Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, v0, v1, v2)); + } +} + +void WorldModelGroup::ReadMaterials() +{ + Chunk* chunk = SubData->GetChunkByName("MOPY"); + if (!chunk) + return; + + FILE* stream = chunk->GetStream(); + uint32 triangleCount = chunk.Length / 2; + TriangleFlags.reserve(triangleCount); + TriangleMaterials.reserve(triangleCount); + for (int i = 0; i < triangleCount; i++) + { + uint8 tmp; + fread(&tmp, sizeof(uint8), 1, stream); + TriangleFlags.push_back(tmp); + // Read again for material. + fread(&tmp, sizeof(uint8), 1, stream); + TriangleMaterials.push_back(tmp); + } +} + +void WorldModelGroup::ReadBoundingBox() +{ + Chunk* chunk = Data->GetChunkByName("MOGP"); + if (!chunk) + return; + + FILE* stream = chunk->GetStream(); + fseek(stream, 8, SEEK_CUR): + fread(&Flags, sizeof(uint32), 1, stream); + BoundingBox[0] = Vector3::Read(stream); + BoundingBox[1] = Vector3::Read(stream); +} diff --git a/src/tools/mesh_extractor/WorldModelGroup.h b/src/tools/mesh_extractor/WorldModelGroup.h new file mode 100644 index 00000000000..1dc754d0221 --- /dev/null +++ b/src/tools/mesh_extractor/WorldModelGroup.h @@ -0,0 +1,33 @@ +#ifndef WMOGROUP_H +#define WMOGROUP_H +#include "ChunkedData.h" +#include "Utils.h" + +class WorldModelGroup +{ +public: + WorldModelGroup(std::string path, int groupIndex); + ChunkedData* Data; + ChunkedData* SubData; + int GroupIndex; + Vector3 BoundingBox[2]; + uint32 Flags; + std::vector TriangleFlags; + std::vector TriangleMaterials; + std::vector > Triangles; + std::vector Vertices; + std::vector Normals; + + bool HasLiquidData; + bool IsBad; + LiquidHeader LiquidDataHeader; + LiquidData LiquidDataGeometry; +private: + void ReadNormals(); + void ReadLiquid(); + void ReadVertices(); + void ReadTriangles(); + void ReadMaterials(); + void ReadBoundingBox(); +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp new file mode 100644 index 00000000000..e895e2bfde8 --- /dev/null +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -0,0 +1,190 @@ +#include "WorldModelHandler.h" +#include "Chunk.h" +#include "Cache.h" +#include "Common.h" +#include "g3d/Matrix4.h" +#include + +WorldModelDefinition WorldModelDefinition::Read( FILE* file ) +{ + WorldModelDefinition ret; + fread(&ret.MwidIndex, sizeof(uint32), 1, file); + fread(&ret.UniqueId, sizeof(uint32), 1, file); + ret.Position = Vector3::Read(file); + ret.Rotation = Vector3::Read(file); + ret.UpperExtents = Vector3::Read(file); + ret.LowerExtents = Vector3::Read(file); + fread(&ret.Flags, sizeof(uint16), 1, file); + fread(&ret.DooadSet, sizeof(uint16), 1, file); + uint32 discard; + fread(&discard, sizeof(uint32), 1, file); + return ret; +} + + +WorldModelHandler::WorldModelHandler( ADT* adt ) : ObjectDataHandler(adt) +{ + if (!adt->HasObjectData) + return; + ReadModelPaths(); + ReadDefinitions(); +} + +void WorldModelHandler::ProcessInternal( ChunkedData* subChunks ) +{ + if (!IsSane()) + return; + Chunk* wmoReferencesChunk = subChunks->GetChunkByName("MCRW"); + if (!wmoReferencesChunk) + return; + FILE* stream = wmoReferencesChunk->GetStream(); + uint32 refCount = wmoReferencesChunk->Length / 4; + for (int i = 0; i < refCount; i++) + { + int32 index; + fread(&index, sizeof(int32), 1, stream); + + if (index < 0 || index >= _definitions->size()) + continue; + + WorldModelDefinition wmo = (*_definitions)[index]; + + if (_drawn.find(wmo.UniqueId) != _drawn.end()) + continue; + _drawn.insert(wmo.UniqueId); + + if (wmo.MwidIndex >= _paths->size()) + continue; + + std::string path = _paths[(int) wmo.MwidIndex]; + WorldModelRoot* model = Cache->WorldModelCache.Get(path); + if (!model) + { + model = new WorldModelRoot(path); + Cache->WorldModelCache.Insert(path, model); + } + + Vertices.reserve(1000); + Triangles.reserve(1000); + + InsertModelGeometry(Vertices, Triangles, wmo, model); + } +} + +void WorldModelHandler::InsertModelGeometry( std::vector verts, std::vector > tris, WorldModelDefinition& def, WorldModelRoot* root ) +{ + G3D::Matrix4 transformation = Utils::GetTransformation(); + for (std::vector::iterator group = root->Groups.begin(); group != root->Groups.end(); ++group) + { + uint32 vertOffset = verts.size(); + for (std::vector::iterator itr2 = group->Vertices.begin(); itr2 != group->Vertices.end(); ++itr2) + verts.push_back(Utils::VectorTransform(*itr2, transformation)); + + for (int i = 0; i < group->Triangles.size(); ++i) + { + // only include collidable tris + if ((group->TriangleFlags[i] & 0x04) != 0 && group->TriangleMaterials[i] != 0xFF) + continue; + Triangle tri = group->Triangles[i]; + tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, tri.V0 + vertOffset, tri.V1 + vertOffset, tri.V2 + vertOffset)); + } + } + + if (def.DoodadSet >= 0 && def.DoodadSet < root->DoodadSets.size()) + { + DoodadSet set = root->DoodadSets[def.DoodadSet]; + std::vector instances = new std::vector; + instances.reserve(set.CountInstances); + for (uint32 i = set.FirstInstanceIndex; i < (set.CountInstances + set.FirstInstanceIndex); i++) + { + if (i >= root->DoodadInstances.size()) + break; + instances.push_back(root->DoodadInstances[i]); + } + + for (std::vector::iterator instance = instances.begin(); instance != instances.end(); ++instance) + { + Model* model = Cache.ModelCache.Get(instance->File); + if (!model) + { + model = new Model(instance->File); + Cache.ModelCache.Insert(instance->File, model); + } + + if (!model.IsCollidable) + continue; + G3D::Matrix4 doodadTransformation = Utils::GetWmoDoodadTransformation(instance, def); + int vertOffset = verts.size(); + for (std::vector::iterator itr2 = model->Vertices.begin(); itr2 != model->Vertices.end(); ++itr2) + verts.push_back(Utils::VectorTransform(*itr2, doodadTransformation)); + for (std::vector >::iterator itr2 = model->Triangles.begin(); itr2 != model->Triangles.end(); ++itr2) + tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, itr2->V0 + vertOffset, itr2->V1 + vertOffset, itr2->V2 + vertOffset)); + } + + for (std::vector::iterator group = root->Groups.begin(); group != root->Groups.end(); ++group) + { + if (!group->HasLiquidData) + continue; + + for (int y = 0; y < group->LiquidDataHeader.Height; y++) + { + for (int x = 0; x < group->LiquidDataHeader.Width; x++) + { + if (!group->LiquidDataGeometry.ShouldRender(x, y)) + continue; + + uint32 vertOffset = verts.size(); + verts.push_back(Utils::GetLiquidVert(transformation, group->LiquidDataHeader.BaseLocation, + group->LiquidDataGeometry.HeightMap[x][y], x, y)); + verts.push_back(Utils::GetLiquidVert(transformation, group->LiquidDataHeader.BaseLocation, + group->LiquidDataGeometry.HeightMap[x + 1][y], x + 1, y)); + verts.push_back(Utils::GetLiquidVert(transformation, group->LiquidDataHeader.BaseLocation, + group->LiquidDataGeometry.HeightMap[x][y + 1], x, y + 1)); + verts.push_back(Utils::GetLiquidVert(transformation, group->LiquidDataHeader.BaseLocation, + group->LiquidDataGeometry.HeightMap[x + 1][y + 1], x + 1, y + 1)); + + tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset + 2, vertOffset + 1)); + tris.push_back(new Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1)); + + } + } + } + } +} + +void WorldModelHandler::ReadDefinitions() +{ + Chunk* chunk = Source->ObjectData->GetChunkByName("MODF"); + if (!chunk) + return; + + const int32 definitionSize = 64; + uint32 definitionCount = chunk.Length / definitionSize; + _definitions = new new std::vector; + _definitions->reserve(definitionCount); + FILE* stream = chunk->GetStream(); + for (int i = 0; i < definitionCount; i++) + _definitions->push_back(WorldModelDefinition::Read(stream)); +} + +void WorldModelHandler::ReadModelPaths() +{ + Chunk* mwid = Source->ObjectData->GetChunkByName("MWID"); + Chunk* mwmo = Source->ObjectData->GetChunkByName("MWMO"); + if (!mwid || !mwmo) + return; + + uint32 paths = mwid.Length / 4; + _paths = new std::vector; + _paths->reserve(paths); + for (int i = 0; i < paths; i++) + { + FILE* stream = mwid->GetStream(); + fseek(stream, i * 4, SEEK_CUR); + uint32 offset; + fread(&offset, sizeof(uint32), 1, stream); + FILE* dataStream = mwmo->GetStream(); + fseek(dataStream, offset + mwmo->Offset, SEEK_SET); + _paths->push_back(Utils::ReadString(dataStream)); + } +} diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h new file mode 100644 index 00000000000..2236339de9d --- /dev/null +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -0,0 +1,42 @@ +#ifndef WMODEL_HNDL_H +#define WMODEL_HNDL_H +#include "Common.h" +#include "Utils.h" +#include "ObjectDataHandler.h" +#include "ADT.h" + +#include +#include + +struct WorldModelDefinition : IDefinition +{ + WorldModelDefinition() {} + uint32 MwidIndex; + uint32 UniqueId; + Vector3 UpperExtents; + Vector3 LowerExtents; + uint16 Flags; + uint16 DoodadSet; + float Scale() { return 1.0f; } + static WorldModelDefinition Read(FILE* file); +}; + +class WorldModelHandler : public ObjectDataHandler +{ +public: + WorldModelHandler(ADT* adt); + + std::vector Vertices; + std::vector > Triangles; + bool IsSane() { return _definitions && _paths; } + void InsertModelGeometry(std::vector verts, std::vector > tris, WorldModelDefinition& def, WorldModelRoot* root); +protected: + void ProcessInternal(ChunkedData* data); +private: + void ReadDefinitions(); + void ReadModelPaths(); + std::set _drawn; + std::vector* _definitions; + std::vector* _paths; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp new file mode 100644 index 00000000000..9764e339242 --- /dev/null +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -0,0 +1,74 @@ +#include "WorldModelRoot.h" +#include "ChunkedData.h" +#include "Utils.h" + +WorldModelRoot::WorldModelRoot( std::string path ) +{ + Data = new ChunkedData(path); + Path = path; + ReadHeader(); + ReadGroups(); + ReadDoodadInstances(); + ReadDoodadSets(); +} + +void WorldModelRoot::ReadGroups() +{ + std::string pathBase = Utils::GetPathBase(Path); + Groups.reserve(Header.CountGroups); + for (int i = 0; i < Header.CountGroups; i++) + { + char name[200]; + sprintf(name, "%s_%03u.wmo", pathBase.c_str(), i); + WorldModelGroup group(name, i); + if (!group.IsBad) + Groups.push_back(group); + } +} + +void WorldModelRoot::ReadDoodadSets() +{ + Chunk* chunk = Data->GetChunkByName("MODS"); + if (!chunk) + return; + + FILE* stream = chunk->GetStream(); + Assert(chunk.Length / 32 == Header.CountSets, "chunk.Length / 32 == Header.CountSets"); + DoodadSets.reserve(Header.CountSets); + for (int i = 0; i < Header.CountSets; i++) + DoodadSets.push_back(DoodadSet::Read(stream)); +} + +void WorldModelRoot::ReadDoodadInstances() +{ + Chunk* chunk = Data->GetChunkByName("MODD"); + Chunk* nameChunk = Data->GetChunkByName("MODN"); + if (!chunk || !nameChunk) + return; + + const uint32 instanceSize = 40; + uint32 countInstances = chunk->Length / instanceSize; + DoodadInstances.reserve(countInstances); + for (int i = 0; i < countInstances; i++) + { + FILE* stream = chunk->GetStream(); + fseek(stream, instanceSize * i, SEEK_CUR); + DoodadInstance instance = DoodadInstance::Read(stream); + FILE* nameStream = nameChunk->GetStream(); + if (instance.FileOffset >= nameChunk->Length) + continue; + fseek(nameStream, instance.FileOffset, SEEK_CUR); + instance.File = Utils::ReadString(nameStream); + DoodadInstances.push_back(instance); + } +} + +void WorldModelRoot::ReadHeader() +{ + Chunk* chunk = Data->GetChunkByName("MOHD"); + if (!chunk) + return; + + FILE* stream = chunk->GetStream(); + Header = WorldModelHeader::Read(stream); +} diff --git a/src/tools/mesh_extractor/WorldModelRoot.h b/src/tools/mesh_extractor/WorldModelRoot.h new file mode 100644 index 00000000000..c06ff3d5d2b --- /dev/null +++ b/src/tools/mesh_extractor/WorldModelRoot.h @@ -0,0 +1,26 @@ +#ifndef WMOROOT_H +#define WMOROOT_H +#include +#include + +#include "ChunkedData.h" +#include "Utils.h" +#include "WorldModelGroup.h" + +class WorldModelRoot +{ +public: + WorldModelRoot(std::string path); + std::string Path; + ChunkedData* Data; + WorldModelHeader Header; + std::vector DoodadInstances; + std::vector DoodadSets; + std::vector Groups; +private: + void ReadGroups(); + void ReadDoodadSets(); + void ReadDoodadInstances(); + void ReadHeader(); +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/readme b/src/tools/mesh_extractor/readme new file mode 100644 index 00000000000..85cd7cfc975 --- /dev/null +++ b/src/tools/mesh_extractor/readme @@ -0,0 +1,6 @@ +Experimental mesh extractor. +Original work in C# by stschake +Thanks to: +Subv +~ +For helping in the porting to C++ \ No newline at end of file -- cgit v1.2.3 From ad0cd9f40acff1ff6d7571426b4acb1ea675d7a6 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 07:59:22 -0500 Subject: Tools: Made more updates to the MeshExtractor --- src/tools/mesh_extractor/ADT.h | 10 ++-- src/tools/mesh_extractor/LiquidHandler.cpp | 96 +++++++++++++++++++++++++++++- src/tools/mesh_extractor/LiquidHandler.h | 3 + src/tools/mesh_extractor/MapChunk.cpp | 8 +-- src/tools/mesh_extractor/MapChunk.h | 2 +- src/tools/mesh_extractor/Utils.cpp | 11 ++++ src/tools/mesh_extractor/Utils.h | 71 ++++++++++++++++++++-- 7 files changed, 186 insertions(+), 15 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ADT.h b/src/tools/mesh_extractor/ADT.h index 18b811a4e4c..43984d0902c 100644 --- a/src/tools/mesh_extractor/ADT.h +++ b/src/tools/mesh_extractor/ADT.h @@ -4,17 +4,19 @@ #include "MapChunk.h" #include "DoodadHandler.h" #include "WorldModelHandler.h" +#include "LiquidHandler.h" class ADT { public: - ADT(); - ~ADT() { delete[] MapChunks; delete ObjectData; delete Data; } + ADT(std::string file); + ~ADT(); + + void Read(); ChunkedData* ObjectData; ChunkedData* Data; - // This here is not a pointer, is an array of objects ( made this way to allow the dynamic allocation ) - MapChunk* MapChunks; + std::vector MapChunks; MHDR Header; // Can we dispose of this? bool HasObjectData; diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index 5924c693196..3217bb2cbc6 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -1 +1,95 @@ -#include "LiquidHandler.h" \ No newline at end of file +#include "LiquidHandler.h" +#include "Utils.h" + +LiquidHandler::LiquidHandler( ADT* adt ) : Source(adt) +{ + HandleNewLiquid(); +} + +void LiquidHandler::HandleNewLiquid() +{ + Chunk* chunk = Source->Data->GetChunkByName("MH2O"); + if (!chunk) + return; + + Vertices.reserve(1000); + Triangles.reserve(1000); + + FILE* stream = chunk->GetStream(); + H2OHeader header[256]; + MCNKData.reserve(256); + for (int i = 0; i < 256; i++) + header[i] = H2OHeader::Read(stream); + + for (int i = 0; i < 256; i++) + { + H2OHeader h = header[i]; + if (h.LayerCount == 0) + continue; + fseek(stream, chunk->Offset + h.OffsetInformation, SEEK_SET); + H2OInformation information = H2OInformation::Read(stream); + + float** heights = new float*[9]; + for (int i = 0; i < 9; ++i) + heights[i] = new float[9]; + + H2ORenderMask renderMask; + if (information.LiquidType != 2) + { + fseek(stream, chunk->Offset + h.OffsetRender, SEEK_SET); + renderMask = H2ORenderMask::Read(stream); + if ((Utils::IsAllZero(renderMask.Mask, 8) || (information.Width == 8 && information.Height == 8)) && information.OffsetMask2) + { + fseek(stream, chunk->Offset + information.OffsetMask2, SEEK_SET); + uint32 size = ceil(information.Width * information.Height / 8.0f); + uint8* altMask = new uint8[size]; + fread(altMax, sizeof(uint8), size, stream); + + for (int mi = 0; mi < size; mi++) + renderMask.Mask[mi + information.OffsetY] |= altMask[mi]; + delete[] altMask; + } + fseek(stream, chunk->Offset + information.OffsetHeightmap, SEEK_SET); + + for (int y = information.OffsetY; y < (information.OffsetY + information.Height); y++) + for (int x = information.OffsetX; x < (information.OffsetX + information.Width); x++) + fread(&heights[x][y], sizeof(float), 1, stream); + } + else + { + // Fill with ocean data + for (uint32 i = 0; i < 8; ++i) + renderMask.Mask[i] = 0xFF; + + for (uint32 y = 0; y < 9; ++y) + for (uint32 x = 0; x < 9; ++x) + heights[x][y] = information.HeightLevel1; + } + + MCNKData.push_back(MCNKLiquidData(heights, renderMask)); + + for (int y = information.OffsetY; y < (information.OffsetY + information.Height); y++) + { + for (int x = information.OffsetX; x < (information.OffsetX + information.Width); x++) + { + if (!renderMask.ShouldRender(x, y)) + continue; + + MapChunk* mapChunk = Source->MapChunks[i]; + Vector3 location = mapChunk->Header.Position; + location.y = location.y - (x * Constants::UnitSize); + location.x = location.x - (y * Constants::UnitSize); + location.z = heights[x][y]; + + uint32 vertOffset = Vertices.size(); + Vertices.push_back(location); + Vertices.push_back(Vector3(location.x - Constants::UnitSize, location.y, location.z)); + Vertices.push_back(new Vector3(location.x, location.y - Constants::UnitSize, location.z)); + Vertices.push_back(new Vector3(location.x - Constants::UnitSize, location.y - Constants::UnitSize, location.z)); + + Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset+2, vertOffset + 1)); + Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1)); + } + } + } +} diff --git a/src/tools/mesh_extractor/LiquidHandler.h b/src/tools/mesh_extractor/LiquidHandler.h index ba89be33e08..138b2da2ad9 100644 --- a/src/tools/mesh_extractor/LiquidHandler.h +++ b/src/tools/mesh_extractor/LiquidHandler.h @@ -9,9 +9,12 @@ class LiquidHandler { public: + LiquidHandler(ADT* adt); ADT* Source; std::vector Vertices; std::vector > Triangles; std::vector MCNKData; +private: + void HandleNewLiquid(); }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp index 95f8c2e56c0..4cb5dc04d2d 100644 --- a/src/tools/mesh_extractor/MapChunk.cpp +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -1,7 +1,7 @@ #include "MapChunk.h" #include "ADT.h" -MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : adt(_adt), Source(chunk), Vertices(NULL) +MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : Adt(_adt), Source(chunk), Vertices(NULL) { FILE* stream = chunk->GetStream(); Header.Read(stream); @@ -26,14 +26,14 @@ void MapChunk::GenerateTriangles() uint32 center = (17 * y) + 9 + x; uint8 triangleType = Constants::TRIANGLE_TYPE_TERRAIN; - if (ADT.LiquidHandler && ADT.LiquidHandler.MCNKData) + if (Adt->_LiquidHandler && !Adt->_LiquidHandler->MCNKData.empty()) { - var data = ADT.LiquidHandler.MCNKData[Index]; + MCNKLiquidData& data = Adt->_LiquidHandler->MCNKData[Index]; uint32 maxHeight = std::max( std::max( std::max(std::max(Vertices[topLeft].z, Vertices[topRight].z), Vertices[bottomLeft].z), Vertices[bottomRight].z), Vertices[center].z); - if (data && data->IsWater(x, y, maxHeight)) + if (data.IsWater(x, y, maxHeight)) triangleType = Constants::TRIANGLE_TYPE_WATER; } diff --git a/src/tools/mesh_extractor/MapChunk.h b/src/tools/mesh_extractor/MapChunk.h index 034429a81ec..9d7b02bbfe5 100644 --- a/src/tools/mesh_extractor/MapChunk.h +++ b/src/tools/mesh_extractor/MapChunk.h @@ -15,7 +15,7 @@ public: void GenerateTriangles(); void GenerateVertices(FILE* stream); static bool HasHole(uint32 map, int x, int y); - ADT* adt; + ADT* Adt; Chunk* Source; MapChunkHeader Header; Vector3* Vertices; diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 03473eb0794..0b92dab267f 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -161,3 +161,14 @@ float Utils::Distance( float x, float y ) { return sqrt(x*x + y*y); } + +std::string Utils::Replace( std::string str, const std::string& oldStr, const std::string& newStr ) +{ + size_t pos = 0; + while((pos = str.find(oldStr, pos)) != std::string::npos) + { + str.replace(pos, oldStr.length(), newStr); + pos += newStr.length(); + } + return str; +} diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index cda5f4c7cd8..aa73db173a7 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -16,9 +16,9 @@ struct Vector3 float x; float y; float z; - Vector3 operator+(Vector3 right, Vector3 left) + Vector3 operator +(Vector3 const& other) { - return Vector3(right.x+left.x, right.y+left.y, right.z+left.z); + return Vector3(x + other.x, y + other.y, z + other.z); } static Vector3 Read(FILE* file); }; @@ -380,7 +380,7 @@ public: return RenderFlags[x][y] != 0x0F; } - public static LiquidData Read(FILE* stream, LiquidHeader header) + static LiquidData Read(FILE* stream, LiquidHeader header) { LiquidData ret; ret.HeightMap = new float*[header.CountXVertices]; @@ -440,14 +440,15 @@ class MCNKLiquidData { public: MCNKLiquidData() {} + MCNKLiquidData(float** heights, H2ORenderMask mask) : Heights(heights), Mask(mask) {} const float MaxStandableHeight = 1.5f; float** Heights; - H2ORenderMask* Mask; + H2ORenderMask Mask; bool IsWater(int x, int y, float height) { - if (!Heights || !Mask) + if (!Heights) return false; if (!Mask->ShouldRender(x, y)) return false; @@ -458,6 +459,56 @@ public: } }; +class H2OHeader +{ +public: + H2OHeader() {} + uint32 OffsetInformation; + uint32 LayerCount; + uint32 OffsetRender; + + static H2OHeader Read(FILE* stream) + { + H2OHeader ret; + fread(&ret.OffsetInformation, sizeof(uint32), 1, stream); + fread(&ret.LayerCount, sizeof(uint32), 1, stream); + fread(&ret.OffsetRender, sizeof(uint32), 1, stream); + return ret; + } +}; + +class H2OInformation +{ +public: + H2OInformation() {} + uint16 LiquidType; + uint16 Flags; + float HeightLevel1; + float HeightLevel2; + uint8 OffsetX; + uint8 OffsetY; + uint8 Width; + uint8 Height; + uint32 OffsetMask2; + uint32 OffsetHeightmap; + + static H2OInformation Read(FILE* stream) + { + H2OInformation ret; + fread(&ret.LiquidType, sizeof(uint16), 1, stream); + fread(&ret.Flags, sizeof(uint16), 1, stream); + fread(&ret.HeightLevel1, sizeof(float), 1, stream); + fread(&ret.HeightLevel2, sizeof(float), 1, stream); + fread(&ret.OffsetX, sizeof(uint8), 1, stream); + fread(&ret.OffsetY, sizeof(uint8), 1, stream); + fread(&ret.Width, sizeof(uint8), 1, stream); + fread(&ret.Height, sizeof(uint8), 1, stream); + fread(&ret.OffsetMask2, sizeof(uint32), 1, stream); + fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream); + return ret; + } +}; + // Dummy class to act as an interface. class IDefinition { @@ -493,5 +544,15 @@ public: static std::string GetPathBase(std::string path); static Vector3 GetLiquidVert(G3D::Matrix4 transformation, Vector3 basePosition, float height, int x, int y); static float Distance(float x, float y); + template + static bool IsAllZero(T* arr, uint32 size) + { + for (uint32 i = 0; i < size; ++i) + if (arr[i]) + return false; + return true; + } + static std::string Utils::Replace( std::string str, const std::string& oldStr, const std::string& newStr ); + }; #endif \ No newline at end of file -- cgit v1.2.3 From 753f43718e59d4bf94b35e25a335e845e2277002 Mon Sep 17 00:00:00 2001 From: kaelima Date: Fri, 28 Sep 2012 15:04:47 +0200 Subject: Address a few compile errors. Correct spacing in HandleMmapPathCommand. --- src/server/scripts/Commands/cs_mmaps.cpp | 108 ++++++++++++------------- src/tools/mesh_extractor/Cache.h | 4 +- src/tools/mesh_extractor/DoodadHandler.cpp | 12 +-- src/tools/mesh_extractor/DoodadHandler.h | 2 +- src/tools/mesh_extractor/Geometry.cpp | 6 +- src/tools/mesh_extractor/TileBuilder.cpp | 2 +- src/tools/mesh_extractor/Utils.cpp | 10 +-- src/tools/mesh_extractor/Utils.h | 22 ++--- src/tools/mesh_extractor/WorldModelGroup.cpp | 14 ++-- src/tools/mesh_extractor/WorldModelHandler.cpp | 6 +- src/tools/mesh_extractor/WorldModelHandler.h | 6 +- src/tools/mesh_extractor/WorldModelRoot.cpp | 2 +- 12 files changed, 101 insertions(+), 93 deletions(-) (limited to 'src/tools') diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index c1fc4d1a5e9..e4a0ebf7f24 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -60,60 +60,58 @@ public: static bool HandleMmapPathCommand(ChatHandler* handler, char const* args) { - if (!MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId())) - { - handler->PSendSysMessage("NavMesh not loaded for current map."); - return true; - } - - handler->PSendSysMessage("mmap path:"); - - // units - Player* player = handler->GetSession()->GetPlayer(); - Unit* target = handler->getSelectedUnit(); - if (!player || !target) - { - handler->PSendSysMessage("Invalid target/source selection."); - return true; - } - - char* para = strtok((char*)args, " "); - - bool useStraightPath = false; - if (para && strcmp(para, "true") == 0) - useStraightPath = true; - - // unit locations - float x, y, z; - player->GetPosition(x, y, z); - - // path - PathGenerator path(target); - path.SetUseStraightPath(useStraightPath); - path.CalculatePath(x, y, z); - - PointsArray pointPath = path.GetPath(); - handler->PSendSysMessage("%s's path to %s:", target->GetName(), player->GetName()); - handler->PSendSysMessage("Building %s", useStraightPath ? "StraightPath" : "SmoothPath"); - handler->PSendSysMessage("length %i type %u", pointPath.size(), path.GetPathType()); - - Vector3 start = path.GetStartPosition(); - Vector3 end = path.GetEndPosition(); - Vector3 actualEnd = path.GetActualEndPosition(); - - handler->PSendSysMessage("start (%.3f, %.3f, %.3f)", start.x, start.y, start.z); - handler->PSendSysMessage("end (%.3f, %.3f, %.3f)", end.x, end.y, end.z); - handler->PSendSysMessage("actual end (%.3f, %.3f, %.3f)", actualEnd.x, actualEnd.y, actualEnd.z); - - if (!player->isGameMaster()) - handler->PSendSysMessage("Enable GM mode to see the path points."); - - // this entry visible only to GM's with "gm on" - static const uint32 WAYPOINT_NPC_ENTRY = 1; - for (uint32 i = 0; i < pointPath.size(); ++i) - player->SummonCreature(WAYPOINT_NPC_ENTRY, pointPath[i].x, pointPath[i].y, pointPath[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 9000); - - return true; + if (!MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId())) + { + handler->PSendSysMessage("NavMesh not loaded for current map."); + return true; + } + + handler->PSendSysMessage("mmap path:"); + + // units + Player* player = handler->GetSession()->GetPlayer(); + Unit* target = handler->getSelectedUnit(); + if (!player || !target) + { + handler->PSendSysMessage("Invalid target/source selection."); + return true; + } + + char* para = strtok((char*)args, " "); + + bool useStraightPath = false; + if (para && strcmp(para, "true") == 0) + useStraightPath = true; + + // unit locations + float x, y, z; + player->GetPosition(x, y, z); + + // path + PathGenerator path(target); + path.SetUseStraightPath(useStraightPath); + bool result = path.CalculatePath(x, y, z); + + PointsArray pointPath = path.GetPath(); + handler->PSendSysMessage("%s's path to %s:", target->GetName(), player->GetName()); + handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : "SmoothPath"); + handler->PSendSysMessage("Result: %s - Length: %i - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType()); + + Vector3 start = path.GetStartPosition(); + Vector3 end = path.GetEndPosition(); + Vector3 actualEnd = path.GetActualEndPosition(); + + handler->PSendSysMessage("StartPosition (%.3f, %.3f, %.3f)", start.x, start.y, start.z); + handler->PSendSysMessage("EndPosition (%.3f, %.3f, %.3f)", end.x, end.y, end.z); + handler->PSendSysMessage("ActualEndPosition (%.3f, %.3f, %.3f)", actualEnd.x, actualEnd.y, actualEnd.z); + + if (!player->isGameMaster()) + handler->PSendSysMessage("Enable GM mode to see the path points."); + + for (uint32 i = 0; i < pointPath.size(); ++i) + player->SummonCreature(VISUAL_WAYPOINT, pointPath[i].x, pointPath[i].y, pointPath[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 9000); + + return true; } static bool HandleMmapLocCommand(ChatHandler* handler, const char* args) @@ -290,4 +288,4 @@ public: void AddSC_mmaps_commandscript() { new mmaps_commandscript(); -} \ No newline at end of file +} diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 186a7870af1..bc2ea6a2883 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -11,7 +11,8 @@ class GenericCache { public: GenericCache() {} - const int32 FlushLimit = 1000; + + static const int32 FlushLimit = 1000; void Insert(std::string key, T* val) { @@ -35,6 +36,7 @@ private: class CacheClass { +public: CacheClass() {} GenericCache ModelCache; GenericCache WorldModelCache; diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 4a7707753c4..71ca1974b81 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -27,7 +27,7 @@ void DoodadHandler::ProcessInternal( ChunkedData* subChunks ) return; FILE* stream = doodadReferencesChunk->GetStream(); uint32 refCount = doodadReferencesChunk->Length / 4; - for (int i = 0; i < refCount; i++) + for (uint32 i = 0; i < refCount; i++) { int32 index; fread(&index, sizeof(int32), 1, stream); @@ -41,11 +41,11 @@ void DoodadHandler::ProcessInternal( ChunkedData* subChunks ) continue; std::string path = (*_paths)[doodad.MmidIndex]; - Model* model = Cache.ModelCache.Get(path); + Model* model = Cache->ModelCache.Get(path); if (!model) { model = new Model(path); - Cache.ModelCache.Insert(path, model); + Cache->ModelCache.Insert(path, model); } if (!model->IsCollidable) continue; @@ -92,8 +92,10 @@ void DoodadHandler::InsertModelGeometry(DoodadDefinition def, Model* model) { G3D::Matrix4 transformation = Utils::GetTransformation(def); uint32 vertOffset = Vertices.size(); + for (std::vector::iterator itr = model->Vertices.begin(); itr != model->Vertices.end(); ++itr) Vertices.push_back(Utils::VectorTransform(*itr, transformation)); + for (std::vector >::iterator itr = model->Triangles.begin(); itr != model->Triangles.end(); ++itr) - Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_DOODAD, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); -} \ No newline at end of file + Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_DOODAD, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); +} diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index c62584ca1f1..d38ee723bef 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -15,7 +15,7 @@ public: uint16 DecimalScale; uint16 Flags; - float Scale() { return DecimalScale / 1024.0f; } + virtual float Scale() const { return DecimalScale / 1024.0f; } void Read(FILE* stream) { diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp index 8e417af4c73..130258b6908 100644 --- a/src/tools/mesh_extractor/Geometry.cpp +++ b/src/tools/mesh_extractor/Geometry.cpp @@ -68,7 +68,7 @@ void Geometry::AddData( std::vector& verts, std::vector& tri = Triangles[i]; tris[(i * 3) + 0] = (int)tri.V0; @@ -86,7 +86,7 @@ void Geometry::GetRawData( float*& verts, int*& tris, uint8*& areas ) } areas = new uint8[Triangles.size()]; - for (int i = 0; i < Triangles.size(); i++) + for (uint32 i = 0; i < Triangles.size(); i++) { switch (Triangles[i].Type) { diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 070b9d70050..36e71730c34 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -34,4 +34,4 @@ void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax ) bmin[2] = origin[2] + (Constants::TileSize * Y); bmax[0] = origin[0] + (Constants::TileSize * (X + 1)); bmax[2] = origin[2] + (Constants::TileSize * (Y + 1)); -} \ No newline at end of file +} diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 0b92dab267f..ef24a8017bd 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -74,7 +74,7 @@ G3D::Matrix4 Utils::RotationX(float angle) { float _cos = cos(angle); float _sin = sin(angle); - Matrix4 ret = G3D::Matrix4::identity(); + G3D::Matrix4 ret = G3D::Matrix4::identity(); ret[2][2] = _cos; ret[2][3] = _sin; ret[3][2] = -_sin; @@ -82,7 +82,7 @@ G3D::Matrix4 Utils::RotationX(float angle) return ret; } -G3D::Matrix4 Utils::GetTransformation( IDefinition def ) +G3D::Matrix4 Utils::GetTransformation(IDefinition def) { G3D::Matrix4 translation; if (def.Position.x == 0.0f && def.Position.y == 0.0f && def.Position.z == 0.0f) @@ -101,7 +101,7 @@ G3D::Matrix4 Utils::RotationY( float angle ) { float _cos = cos(angle); float _sin = sin(angle); - Matrix4 ret = G3D::Matrix4::identity(); + G3D::Matrix4 ret = G3D::Matrix4::identity(); ret[1][1] = _cos; ret[1][3] = -_sin; ret[3][1] = _sin; @@ -113,7 +113,7 @@ G3D::Matrix4 Utils::RotationZ( float angle ) { float _cos = cos(angle); float _sin = sin(angle); - Matrix4 ret = G3D::Matrix4::identity(); + G3D::Matrix4 ret = G3D::Matrix4::identity(); ret[1][1] = _cos; ret[1][2] = _sin; ret[2][1] = -_sin; @@ -126,7 +126,7 @@ float Utils::ToRadians( float degrees ) return Constants::PI * degrees / 180.0f; } -Vector3 Utils::VectorTransform( Vector3 vec, G3D::Matrix matrix ) +Vector3 Utils::VectorTransform( Vector3 vec, G3D::Matrix4 matrix ) { Vector3 ret; ret.x = vec.x * matrix[1][1] + vec.y * matrix[2][1] + vec.z * matrix[3][1] + matrix[4][1]; diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index aa73db173a7..ec333d80f8c 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -16,10 +16,12 @@ struct Vector3 float x; float y; float z; + Vector3 operator +(Vector3 const& other) { return Vector3(x + other.x, y + other.y, z + other.z); } + static Vector3 Read(FILE* file); }; @@ -342,7 +344,7 @@ public: fread(&ret.UnknownZero, sizeof(uint32), 1, stream); return ret; } -} +}; class LiquidHeader { @@ -384,16 +386,16 @@ public: { LiquidData ret; ret.HeightMap = new float*[header.CountXVertices]; - for (int i = 0; i < header.CountXVertices; ++i) + for (uint32 i = 0; i < header.CountXVertices; ++i) ret.HeightMap[i] = new float[header.CountYVertices]; ret.RenderFlags = new uint8*[header.Width]; - for (int i = 0; i < header.Width; ++i) + for (uint32 i = 0; i < header.Width; ++i) ret.RenderFlags[i] = new uint8[header.Height]; - for (int y = 0; y < header.CountYVertices; y++) + for (uint32 y = 0; y < header.CountYVertices; y++) { - for (int x = 0; x < header.CountXVertices; x++) + for (uint32 x = 0; x < header.CountXVertices; x++) { uint32 discard; fread(&discard, sizeof(uint32), 1, stream); @@ -403,9 +405,9 @@ public: } } - for (int y = 0; y < header.Height; y++) + for (uint32 y = 0; y < header.Height; y++) { - for (int x = 0; x < header.Width; x++) + for (uint32 x = 0; x < header.Width; x++) { uint8 tmp; fread(&tmp, sizeof(uint8), 1, stream); @@ -441,8 +443,8 @@ class MCNKLiquidData public: MCNKLiquidData() {} MCNKLiquidData(float** heights, H2ORenderMask mask) : Heights(heights), Mask(mask) {} - const float MaxStandableHeight = 1.5f; + static const float MaxStandableHeight = 1.5f; float** Heights; H2ORenderMask Mask; @@ -515,7 +517,7 @@ class IDefinition public: Vector3 Position; Vector3 Rotation; - virtual float Scale() = 0; + virtual float Scale() const = 0; }; class Utils @@ -540,7 +542,7 @@ public: static G3D::Matrix4 RotationY(float angle); static G3D::Matrix4 RotationZ(float angle); static float ToRadians(float degrees); - static Vector3 VectorTransform(Vector3 vec, G3D::Matrix matrix); + static Vector3 VectorTransform(Vector3 vec, G3D::Matrix4 matrix); static std::string GetPathBase(std::string path); static Vector3 GetLiquidVert(G3D::Matrix4 transformation, Vector3 basePosition, float height, int x, int y); static float Distance(float x, float y); diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index 308c7ff7b86..5039eb56381 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -33,7 +33,7 @@ void WorldModelGroup::ReadNormals() return; uint32 normalCount = chunk->Length / 12; - Assert(normalCount == Vertices.size(), "normalCount is different than the Vertices count"); + ASSERT(normalCount == Vertices.size(), "normalCount is different than the Vertices count"); Normals.reserve(normalCount); FILE* stream = chunk->GetStream(); for (int i = 0; i < normalCount; i++) @@ -58,7 +58,7 @@ void WorldModelGroup::ReadVertices() if (!chunk) return; - uint32 verticeCount = chunk.Length / 12; + uint32 verticeCount = chunk->Length / 12; Vertices.reserve(verticeCount); FILE* stream = chunk->GetStream(); for (int i = 0; i < verticeCount; i++) @@ -71,9 +71,9 @@ void WorldModelGroup::ReadTriangles() if (!chunk) return; - uint32 triangleCount = chunk.Length / 6; - Assert(triangleCount == TriangleFlags.size(), "triangleCount != TriangleFlags.size()"); - FILE* stream = chunk.GetStream(); + uint32 triangleCount = chunk->Length / 6; + ASSERT(triangleCount == TriangleFlags.size(), "triangleCount != TriangleFlags.size()"); + FILE* stream = chunk->GetStream(); Triangles.reserve(triangleCount); for (int i = 0; i < triangleCount; i++) { @@ -94,7 +94,7 @@ void WorldModelGroup::ReadMaterials() return; FILE* stream = chunk->GetStream(); - uint32 triangleCount = chunk.Length / 2; + uint32 triangleCount = chunk->Length / 2; TriangleFlags.reserve(triangleCount); TriangleMaterials.reserve(triangleCount); for (int i = 0; i < triangleCount; i++) @@ -115,7 +115,7 @@ void WorldModelGroup::ReadBoundingBox() return; FILE* stream = chunk->GetStream(); - fseek(stream, 8, SEEK_CUR): + fseek(stream, 8, SEEK_CUR); fread(&Flags, sizeof(uint32), 1, stream); BoundingBox[0] = Vector3::Read(stream); BoundingBox[1] = Vector3::Read(stream); diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index e895e2bfde8..cb8ac6d8e5d 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -159,8 +159,8 @@ void WorldModelHandler::ReadDefinitions() return; const int32 definitionSize = 64; - uint32 definitionCount = chunk.Length / definitionSize; - _definitions = new new std::vector; + uint32 definitionCount = chunk->Length / definitionSize; + _definitions = new std::vector; _definitions->reserve(definitionCount); FILE* stream = chunk->GetStream(); for (int i = 0; i < definitionCount; i++) @@ -174,7 +174,7 @@ void WorldModelHandler::ReadModelPaths() if (!mwid || !mwmo) return; - uint32 paths = mwid.Length / 4; + uint32 paths = mwid->Length / 4; _paths = new std::vector; _paths->reserve(paths); for (int i = 0; i < paths; i++) diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h index 2236339de9d..81e6eab1c4b 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.h +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -10,14 +10,18 @@ struct WorldModelDefinition : IDefinition { +public: WorldModelDefinition() {} + uint32 MwidIndex; uint32 UniqueId; Vector3 UpperExtents; Vector3 LowerExtents; uint16 Flags; uint16 DoodadSet; - float Scale() { return 1.0f; } + + virtual float Scale() const { return 1.0f; } + static WorldModelDefinition Read(FILE* file); }; diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp index 9764e339242..18b3fd8586d 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.cpp +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -33,7 +33,7 @@ void WorldModelRoot::ReadDoodadSets() return; FILE* stream = chunk->GetStream(); - Assert(chunk.Length / 32 == Header.CountSets, "chunk.Length / 32 == Header.CountSets"); + ASSERT(chunk->Length / 32 == Header.CountSets, "chunk.Length / 32 == Header.CountSets"); DoodadSets.reserve(Header.CountSets); for (int i = 0; i < Header.CountSets; i++) DoodadSets.push_back(DoodadSet::Read(stream)); -- cgit v1.2.3 From e12f7ed3e89bc137ed8e893a6bbda8f3a5d9c63d Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 09:01:13 -0500 Subject: Tools: Fixed build in MeshExtractor (almost) --- dep/CMakeLists.txt | 2 +- src/server/CMakeLists.txt | 1 + src/tools/mesh_extractor/ADT.cpp | 53 ++++++++++++++++++++++++++ src/tools/mesh_extractor/ADT.h | 7 ++-- src/tools/mesh_extractor/CMakeLists.txt | 5 +++ src/tools/mesh_extractor/Cache.h | 2 +- src/tools/mesh_extractor/Constants.h | 1 + src/tools/mesh_extractor/DoodadHandler.cpp | 2 +- src/tools/mesh_extractor/DoodadHandler.h | 4 +- src/tools/mesh_extractor/LiquidHandler.cpp | 6 +-- src/tools/mesh_extractor/MapChunk.cpp | 11 +++--- src/tools/mesh_extractor/TileBuilder.cpp | 9 ++--- src/tools/mesh_extractor/Utils.cpp | 26 ++++++++----- src/tools/mesh_extractor/Utils.h | 13 ++++--- src/tools/mesh_extractor/WorldModelGroup.cpp | 8 ++-- src/tools/mesh_extractor/WorldModelHandler.cpp | 34 +++++++++-------- src/tools/mesh_extractor/WorldModelHandler.h | 10 ++--- src/tools/mesh_extractor/WorldModelRoot.cpp | 2 +- 18 files changed, 135 insertions(+), 61 deletions(-) create mode 100644 src/tools/mesh_extractor/ADT.cpp (limited to 'src/tools') diff --git a/dep/CMakeLists.txt b/dep/CMakeLists.txt index c01a1e3426a..f6db7ca22b7 100644 --- a/dep/CMakeLists.txt +++ b/dep/CMakeLists.txt @@ -22,7 +22,7 @@ endif() if(CMAKE_SYSTEM_NAME MATCHES "Windows") add_subdirectory(acelite) - if(SERVERS AND USE_MYSQL_SOURCES) + if(USE_MYSQL_SOURCES) add_subdirectory(mysqllite) endif() if(TOOLS) diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index 2b6c553e10b..e038f36fd47 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -30,5 +30,6 @@ if( SERVERS ) else() if( TOOLS ) add_subdirectory(collision) + add_subdirectory(shared) endif() endif() diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp new file mode 100644 index 00000000000..c564d7193cf --- /dev/null +++ b/src/tools/mesh_extractor/ADT.cpp @@ -0,0 +1,53 @@ +#include "ADT.h" +#include "DoodadHandler.h" +#include "LiquidHandler.h" +#include "WorldModelHandler.h" + +ADT::ADT( std::string file ) : ObjectData(NULL), Data(NULL), _DoodadHandler(NULL), _WorldModelHandler(NULL), _LiquidHandler(NULL), HasObjectData(false) +{ + Data = new ChunkedData(file); + ObjectData = new ChunkedData(Utils::Replace(file, ".adt", "_obj0.adt")); + if (ObjectData->Stream) + HasObjectData = true; + else + ObjectData = NULL; +} + +ADT::~ADT() +{ + delete ObjectData; + delete Data; + + for (std::vector::iterator itr = MapChunks.begin(); itr != MapChunks.end(); ++itr) + delete *itr; + + MapChunks.clear(); + delete _DoodadHandler; + delete _WorldModelHandler; + delete _LiquidHandler; +} + +void ADT::Read() +{ + Header.Read(Data->GetChunkByName("MHDR")->GetStream()); + MapChunks.reserve(16 * 16); + int mapChunkIndex = 0; + + for (std::vector::iterator itr = Data->Chunks.begin(); itr != Data->Chunks.end(); ++itr) + if ((*itr)->Name == "MCNK") + MapChunks.push_back(new MapChunk(this, *itr)); + + _LiquidHandler = new LiquidHandler(this); + + // do this separate from map chunk initialization to access liquid data + for (std::vector::iterator itr = MapChunks.begin(); itr != MapChunks.end(); ++itr) + (*itr)->GenerateTriangles(); + + _DoodadHandler = new DoodadHandler(this); + for (std::vector::iterator itr = MapChunks.begin(); itr != MapChunks.end(); ++itr) + _DoodadHandler->ProcessMapChunk(*itr); + + _WorldModelHandler = new WorldModelHandler(this); + for (std::vector::iterator itr = MapChunks.begin(); itr != MapChunks.end(); ++itr) + _WorldModelHandler->ProcessMapChunk(*itr); +} diff --git a/src/tools/mesh_extractor/ADT.h b/src/tools/mesh_extractor/ADT.h index 43984d0902c..096f491eed8 100644 --- a/src/tools/mesh_extractor/ADT.h +++ b/src/tools/mesh_extractor/ADT.h @@ -2,9 +2,10 @@ #define ADT_H #include "ChunkedData.h" #include "MapChunk.h" -#include "DoodadHandler.h" -#include "WorldModelHandler.h" -#include "LiquidHandler.h" + +class DoodadHandler; +class WorldModelHandler; +class LiquidHandler; class ADT { diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt index 3f5b5526dd4..0469590a201 100644 --- a/src/tools/mesh_extractor/CMakeLists.txt +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -45,9 +45,14 @@ add_executable(MeshExtractor ) target_link_libraries(MeshExtractor + shared + g3dlib mpq Recast Detour + ${MYSQL_LIBRARY} + ${OPENSSL_LIBRARIES} + ${OPENSSL_EXTRA_LIBRARIES} ${BZIP2_LIBRARIES} ${ZLIB_LIBRARIES} ${ACE_LIBRARY} diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index bc2ea6a2883..2693ce4e1e1 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -18,7 +18,7 @@ public: { if (_items.size() > FlushLimit) Clear(); - _items.insert(key, val); + _items[key] = val; } T* Get(std::string key) diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h index 885761f1687..38fa0b2e35b 100644 --- a/src/tools/mesh_extractor/Constants.h +++ b/src/tools/mesh_extractor/Constants.h @@ -28,6 +28,7 @@ public: static const float UnitSize; static const float Origin[]; static const float PI; + static const float MaxStandableHeight; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 71ca1974b81..89fcaba5601 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -88,7 +88,7 @@ void DoodadHandler::ReadDoodadPaths( Chunk* id, Chunk* data ) } } -void DoodadHandler::InsertModelGeometry(DoodadDefinition def, Model* model) +void DoodadHandler::InsertModelGeometry(const DoodadDefinition def, Model* model) { G3D::Matrix4 transformation = Utils::GetTransformation(def); uint32 vertOffset = Vertices.size(); diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index d38ee723bef..c426504da32 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -7,7 +7,7 @@ #include #include -class DoodadDefinition : IDefinition +class DoodadDefinition : public IDefinition { public: uint32 MmidIndex; @@ -43,7 +43,7 @@ protected: private: void ReadDoodadDefinitions(Chunk* chunk); void ReadDoodadPaths(Chunk* id, Chunk* data); - void InsertModelGeometry(DoodadDefinition def, Model* model); + void InsertModelGeometry(const DoodadDefinition def, Model* model); std::set _drawn; std::vector* _definitions; std::vector* _paths; diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index 3217bb2cbc6..3d0876aeb74 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -43,7 +43,7 @@ void LiquidHandler::HandleNewLiquid() fseek(stream, chunk->Offset + information.OffsetMask2, SEEK_SET); uint32 size = ceil(information.Width * information.Height / 8.0f); uint8* altMask = new uint8[size]; - fread(altMax, sizeof(uint8), size, stream); + fread(altMask, sizeof(uint8), size, stream); for (int mi = 0; mi < size; mi++) renderMask.Mask[mi + information.OffsetY] |= altMask[mi]; @@ -84,8 +84,8 @@ void LiquidHandler::HandleNewLiquid() uint32 vertOffset = Vertices.size(); Vertices.push_back(location); Vertices.push_back(Vector3(location.x - Constants::UnitSize, location.y, location.z)); - Vertices.push_back(new Vector3(location.x, location.y - Constants::UnitSize, location.z)); - Vertices.push_back(new Vector3(location.x - Constants::UnitSize, location.y - Constants::UnitSize, location.z)); + Vertices.push_back(Vector3(location.x, location.y - Constants::UnitSize, location.z)); + Vertices.push_back(Vector3(location.x - Constants::UnitSize, location.y - Constants::UnitSize, location.z)); Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset+2, vertOffset + 1)); Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1)); diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp index 4cb5dc04d2d..0b02a2a4a14 100644 --- a/src/tools/mesh_extractor/MapChunk.cpp +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -1,5 +1,6 @@ #include "MapChunk.h" #include "ADT.h" +#include "LiquidHandler.h" MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : Adt(_adt), Source(chunk), Vertices(NULL) { @@ -25,7 +26,7 @@ void MapChunk::GenerateTriangles() uint32 bottomRight = (17 * (y + 1)) + x + 1; uint32 center = (17 * y) + 9 + x; - uint8 triangleType = Constants::TRIANGLE_TYPE_TERRAIN; + Constants::TriangleType triangleType = Constants::TRIANGLE_TYPE_TERRAIN; if (Adt->_LiquidHandler && !Adt->_LiquidHandler->MCNKData.empty()) { MCNKLiquidData& data = Adt->_LiquidHandler->MCNKData[Index]; @@ -37,10 +38,10 @@ void MapChunk::GenerateTriangles() triangleType = Constants::TRIANGLE_TYPE_WATER; } - Triangles.push_back(new Triangle(triangleType, topRight, topLeft, center)); - Triangles.push_back(new Triangle(triangleType, topLeft, bottomLeft, center)); - Triangles.push_back(new Triangle(triangleType, bottomLeft, bottomRight, center)); - Triangles.push_back(new Triangle(triangleType, bottomRight, topRight, center)); + Triangles.push_back(Triangle(triangleType, topRight, topLeft, center)); + Triangles.push_back(Triangle(triangleType, topLeft, bottomLeft, center)); + Triangles.push_back(Triangle(triangleType, bottomLeft, bottomRight, center)); + Triangles.push_back(Triangle(triangleType, bottomRight, topRight, center)); } } } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 36e71730c34..190607493fa 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -27,11 +27,10 @@ TileBuilder::TileBuilder(std::string world, int x, int y) : _Geometry(NULL), Wor void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax ) { - float origin[3] = Constants::Origin; bmin = new float[3]; bmax = new float[3]; - bmin[0] = origin[0] + (Constants::TileSize * X); - bmin[2] = origin[2] + (Constants::TileSize * Y); - bmax[0] = origin[0] + (Constants::TileSize * (X + 1)); - bmax[2] = origin[2] + (Constants::TileSize * (Y + 1)); + bmin[0] = Constants::Origin[0] + (Constants::TileSize * X); + bmin[2] = Constants::Origin[2] + (Constants::TileSize * Y); + bmax[0] = Constants::Origin[0] + (Constants::TileSize * (X + 1)); + bmax[2] = Constants::Origin[2] + (Constants::TileSize * (Y + 1)); } diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index ef24a8017bd..c7c0cff0d42 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -1,7 +1,9 @@ #include "Utils.h" +#include "WorldModelHandler.h" #include "Constants.h" #include #include "g3d/Matrix4.h" +#include "g3d/Quat.h" const float Constants::TileSize = 533.0f + (1/3.0f); const float Constants::MaxXY = 32.0f * Constants::TileSize; @@ -9,6 +11,7 @@ const float Constants::ChunkSize = Constants::TileSize / 16.0f; const float Constants::UnitSize = Constants::ChunkSize / 8.0f; const float Constants::Origin[] = { -Constants::MaxXY, 0.0f, -Constants::MaxXY }; const float Constants::PI = 3.1415926f; +const float Constants::MaxStandableHeight = 1.5f; void Utils::Reverse(char word[]) { @@ -60,14 +63,7 @@ std::string Utils::GetAdtPath( std::string world, int x, int y ) std::string Utils::FixModelPath( std::string path ) { - std::string::size_type idx = path.rfind("."); - // Bizarre way of changing extension but... - if (idx != std::string::npos) - { - path[idx + 1] = "M"; - path[idx + 2] = "2"; - } - return path; + return Utils::GetPathBase(path) + ".M2"; } G3D::Matrix4 Utils::RotationX(float angle) @@ -139,7 +135,7 @@ std::string Utils::GetPathBase( std::string path ) { int lastIndex = path.find_last_of("."); if (lastIndex != std::string::npos) - return path.substr(0, lastindex); + return path.substr(0, lastIndex); return path; } @@ -172,3 +168,15 @@ std::string Utils::Replace( std::string str, const std::string& oldStr, const st } return str; } + +G3D::Matrix4 Utils::GetWmoDoodadTransformation( DoodadInstance inst, WorldModelDefinition root ) +{ + G3D::Matrix4 rootTransformation = Utils::GetTransformation(root); + G3D::Matrix4 translation = G3D::Matrix4::translation(inst.Position.x, inst.Position.y, inst.Position.z); + G3D::Matrix4 scale = G3D::Matrix4::scale(inst.Scale); + G3D::Matrix4 rotation = Utils::RotationY(Constants::PI); + G3D::Quat quat(-inst.QuatY, inst.QuatZ, -inst.QuatX, inst.QuatW); + G3D::Matrix4 quatRotation = quat.toRotationMatrix(); + + return scale * rotation * quatRotation ** translation * rootTransformation; +} diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index ec333d80f8c..ac14b9eca69 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -9,6 +9,9 @@ #include "Common.h" #include "Constants.h" +struct WorldModelDefinition; +class DoodadInstance; + struct Vector3 { Vector3() {} @@ -35,6 +38,7 @@ struct TilePos template struct Triangle { + Triangle() {} Triangle(Constants::TriangleType type, T v0, T v1, T v2) : Type(type), V0(v0), V1(v1), V2(v2) {} T V0; T V1; @@ -444,7 +448,6 @@ public: MCNKLiquidData() {} MCNKLiquidData(float** heights, H2ORenderMask mask) : Heights(heights), Mask(mask) {} - static const float MaxStandableHeight = 1.5f; float** Heights; H2ORenderMask Mask; @@ -452,10 +455,10 @@ public: { if (!Heights) return false; - if (!Mask->ShouldRender(x, y)) + if (!Mask.ShouldRender(x, y)) return false; float diff = Heights[x][y] - height; - if (diff > MaxStandableHeight) + if (diff > Constants::MaxStandableHeight) return true; return false; } @@ -517,7 +520,7 @@ class IDefinition public: Vector3 Position; Vector3 Rotation; - virtual float Scale() const = 0; + virtual float Scale() const { return 1.0f; }; }; class Utils @@ -555,6 +558,6 @@ public: return true; } static std::string Utils::Replace( std::string str, const std::string& oldStr, const std::string& newStr ); - + static G3D::Matrix4 GetWmoDoodadTransformation( DoodadInstance inst, WorldModelDefinition root ); }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index 5039eb56381..b4c963020c7 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -33,7 +33,7 @@ void WorldModelGroup::ReadNormals() return; uint32 normalCount = chunk->Length / 12; - ASSERT(normalCount == Vertices.size(), "normalCount is different than the Vertices count"); + ASSERT(normalCount == Vertices.size() && "normalCount is different than the Vertices count"); Normals.reserve(normalCount); FILE* stream = chunk->GetStream(); for (int i = 0; i < normalCount; i++) @@ -48,8 +48,8 @@ void WorldModelGroup::ReadLiquid() HasLiquidData = true; FILE* stream = chunk->GetStream(); - LiquidDataHeader = LiquidHeader.Read(stream); - LiquidDataGeometry = LiquidData.Read(stream, LiquidDataHeader); + LiquidDataHeader = LiquidHeader::Read(stream); + LiquidDataGeometry = LiquidData::Read(stream, LiquidDataHeader); } void WorldModelGroup::ReadVertices() @@ -72,7 +72,7 @@ void WorldModelGroup::ReadTriangles() return; uint32 triangleCount = chunk->Length / 6; - ASSERT(triangleCount == TriangleFlags.size(), "triangleCount != TriangleFlags.size()"); + ASSERT(triangleCount == TriangleFlags.size() && "triangleCount != TriangleFlags.size()"); FILE* stream = chunk->GetStream(); Triangles.reserve(triangleCount); for (int i = 0; i < triangleCount; i++) diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index cb8ac6d8e5d..e5a14d55c0c 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -1,6 +1,8 @@ #include "WorldModelHandler.h" +#include "WorldModelRoot.h" #include "Chunk.h" #include "Cache.h" +#include "Model.h" #include "Common.h" #include "g3d/Matrix4.h" #include @@ -15,7 +17,7 @@ WorldModelDefinition WorldModelDefinition::Read( FILE* file ) ret.UpperExtents = Vector3::Read(file); ret.LowerExtents = Vector3::Read(file); fread(&ret.Flags, sizeof(uint16), 1, file); - fread(&ret.DooadSet, sizeof(uint16), 1, file); + fread(&ret.DoodadSet, sizeof(uint16), 1, file); uint32 discard; fread(&discard, sizeof(uint32), 1, file); return ret; @@ -39,7 +41,7 @@ void WorldModelHandler::ProcessInternal( ChunkedData* subChunks ) return; FILE* stream = wmoReferencesChunk->GetStream(); uint32 refCount = wmoReferencesChunk->Length / 4; - for (int i = 0; i < refCount; i++) + for (uint32 i = 0; i < refCount; i++) { int32 index; fread(&index, sizeof(int32), 1, stream); @@ -56,7 +58,7 @@ void WorldModelHandler::ProcessInternal( ChunkedData* subChunks ) if (wmo.MwidIndex >= _paths->size()) continue; - std::string path = _paths[(int) wmo.MwidIndex]; + std::string path = (*_paths)[wmo.MwidIndex]; WorldModelRoot* model = Cache->WorldModelCache.Get(path); if (!model) { @@ -71,16 +73,16 @@ void WorldModelHandler::ProcessInternal( ChunkedData* subChunks ) } } -void WorldModelHandler::InsertModelGeometry( std::vector verts, std::vector > tris, WorldModelDefinition& def, WorldModelRoot* root ) +void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::vector >& tris, WorldModelDefinition& def, WorldModelRoot* root ) { - G3D::Matrix4 transformation = Utils::GetTransformation(); + G3D::Matrix4 transformation = Utils::GetTransformation(def); for (std::vector::iterator group = root->Groups.begin(); group != root->Groups.end(); ++group) { uint32 vertOffset = verts.size(); for (std::vector::iterator itr2 = group->Vertices.begin(); itr2 != group->Vertices.end(); ++itr2) verts.push_back(Utils::VectorTransform(*itr2, transformation)); - for (int i = 0; i < group->Triangles.size(); ++i) + for (uint32 i = 0; i < group->Triangles.size(); ++i) { // only include collidable tris if ((group->TriangleFlags[i] & 0x04) != 0 && group->TriangleMaterials[i] != 0xFF) @@ -93,7 +95,7 @@ void WorldModelHandler::InsertModelGeometry( std::vector verts, std::ve if (def.DoodadSet >= 0 && def.DoodadSet < root->DoodadSets.size()) { DoodadSet set = root->DoodadSets[def.DoodadSet]; - std::vector instances = new std::vector; + std::vector instances; instances.reserve(set.CountInstances); for (uint32 i = set.FirstInstanceIndex; i < (set.CountInstances + set.FirstInstanceIndex); i++) { @@ -104,16 +106,16 @@ void WorldModelHandler::InsertModelGeometry( std::vector verts, std::ve for (std::vector::iterator instance = instances.begin(); instance != instances.end(); ++instance) { - Model* model = Cache.ModelCache.Get(instance->File); + Model* model = Cache->ModelCache.Get(instance->File); if (!model) { model = new Model(instance->File); - Cache.ModelCache.Insert(instance->File, model); + Cache->ModelCache.Insert(instance->File, model); } - if (!model.IsCollidable) + if (!model->IsCollidable) continue; - G3D::Matrix4 doodadTransformation = Utils::GetWmoDoodadTransformation(instance, def); + G3D::Matrix4 doodadTransformation = Utils::GetWmoDoodadTransformation(*instance, def); int vertOffset = verts.size(); for (std::vector::iterator itr2 = model->Vertices.begin(); itr2 != model->Vertices.end(); ++itr2) verts.push_back(Utils::VectorTransform(*itr2, doodadTransformation)); @@ -126,9 +128,9 @@ void WorldModelHandler::InsertModelGeometry( std::vector verts, std::ve if (!group->HasLiquidData) continue; - for (int y = 0; y < group->LiquidDataHeader.Height; y++) + for (uint32 y = 0; y < group->LiquidDataHeader.Height; y++) { - for (int x = 0; x < group->LiquidDataHeader.Width; x++) + for (uint32 x = 0; x < group->LiquidDataHeader.Width; x++) { if (!group->LiquidDataGeometry.ShouldRender(x, y)) continue; @@ -144,7 +146,7 @@ void WorldModelHandler::InsertModelGeometry( std::vector verts, std::ve group->LiquidDataGeometry.HeightMap[x + 1][y + 1], x + 1, y + 1)); tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset + 2, vertOffset + 1)); - tris.push_back(new Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1)); + tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1)); } } @@ -163,7 +165,7 @@ void WorldModelHandler::ReadDefinitions() _definitions = new std::vector; _definitions->reserve(definitionCount); FILE* stream = chunk->GetStream(); - for (int i = 0; i < definitionCount; i++) + for (uint32 i = 0; i < definitionCount; i++) _definitions->push_back(WorldModelDefinition::Read(stream)); } @@ -177,7 +179,7 @@ void WorldModelHandler::ReadModelPaths() uint32 paths = mwid->Length / 4; _paths = new std::vector; _paths->reserve(paths); - for (int i = 0; i < paths; i++) + for (uint32 i = 0; i < paths; i++) { FILE* stream = mwid->GetStream(); fseek(stream, i * 4, SEEK_CUR); diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h index 81e6eab1c4b..daf0713ecd2 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.h +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -2,13 +2,15 @@ #define WMODEL_HNDL_H #include "Common.h" #include "Utils.h" +#include "WorldModelRoot.h" #include "ObjectDataHandler.h" -#include "ADT.h" #include #include -struct WorldModelDefinition : IDefinition +class ADT; + +struct WorldModelDefinition : public IDefinition { public: WorldModelDefinition() {} @@ -20,8 +22,6 @@ public: uint16 Flags; uint16 DoodadSet; - virtual float Scale() const { return 1.0f; } - static WorldModelDefinition Read(FILE* file); }; @@ -33,7 +33,7 @@ public: std::vector Vertices; std::vector > Triangles; bool IsSane() { return _definitions && _paths; } - void InsertModelGeometry(std::vector verts, std::vector > tris, WorldModelDefinition& def, WorldModelRoot* root); + void InsertModelGeometry(std::vector& verts, std::vector >& tris, WorldModelDefinition& def, WorldModelRoot* root); protected: void ProcessInternal(ChunkedData* data); private: diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp index 18b3fd8586d..3457a35f761 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.cpp +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -33,7 +33,7 @@ void WorldModelRoot::ReadDoodadSets() return; FILE* stream = chunk->GetStream(); - ASSERT(chunk->Length / 32 == Header.CountSets, "chunk.Length / 32 == Header.CountSets"); + ASSERT(chunk->Length / 32 == Header.CountSets && "chunk.Length / 32 == Header.CountSets"); DoodadSets.reserve(Header.CountSets); for (int i = 0; i < Header.CountSets; i++) DoodadSets.push_back(DoodadSet::Read(stream)); -- cgit v1.2.3 From 1c6a44e4c5516b5e81acf858733114e61d332e3f Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 09:30:23 -0500 Subject: Tools: Fixed build in MeshExtractor --- src/tools/mesh_extractor/CMakeLists.txt | 6 ++++++ src/tools/mesh_extractor/MeshExtractor.cpp | 4 ++++ 2 files changed, 10 insertions(+) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt index 0469590a201..09bd2982213 100644 --- a/src/tools/mesh_extractor/CMakeLists.txt +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -13,15 +13,19 @@ file(GLOB_RECURSE sources *.cpp *.h) if( UNIX ) include_directories ( + ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour ${CMAKE_SOURCE_DIR}/dep/libmpq ${CMAKE_SOURCE_DIR}/dep/g3dlite/include + ${MYSQL_INCLUDE_DIR} + ${OPENSSL_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ) elseif( WIN32 ) include_directories ( + ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/src/server/shared/Database ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation @@ -36,6 +40,8 @@ elseif( WIN32 ) ${CMAKE_SOURCE_DIR}/dep/libmpq/win ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${ACE_INCLUDE_DIR} + ${MYSQL_INCLUDE_DIR} + ${OPENSSL_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ) endif() diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 0220627cbcc..0611c9c2d58 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -3,6 +3,10 @@ #include "ContinentBuilder.h" #include "Cache.h" +#include "Common.h" +#include "LoginDatabase.h" +LoginDatabaseWorkerPool LoginDatabase; + MPQManager* MPQHandler; CacheClass* Cache; -- cgit v1.2.3 From 3eda479e2970a72a8fcf7731d94b962ff9874e38 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 13:30:43 -0500 Subject: Tools: MeshExtractor is working now. Please note that this is not yet finished --- src/tools/mesh_extractor/Cache.h | 28 +++- src/tools/mesh_extractor/Constants.h | 7 + src/tools/mesh_extractor/ContinentBuilder.cpp | 29 +++- src/tools/mesh_extractor/Geometry.cpp | 21 +++ src/tools/mesh_extractor/Geometry.h | 2 + src/tools/mesh_extractor/MPQManager.cpp | 2 +- src/tools/mesh_extractor/MapChunk.cpp | 12 +- src/tools/mesh_extractor/MapChunk.h | 3 +- src/tools/mesh_extractor/MeshExtractor.cpp | 4 +- src/tools/mesh_extractor/TileBuilder.cpp | 201 ++++++++++++++++++++++++- src/tools/mesh_extractor/TileBuilder.h | 7 +- src/tools/mesh_extractor/Utils.h | 16 ++ src/tools/mesh_extractor/WorldModelHandler.cpp | 2 +- 13 files changed, 308 insertions(+), 26 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 2693ce4e1e1..799878bdd3b 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -1,12 +1,14 @@ #ifndef CACHE_H #define CACHE_H #include +#include #include "Common.h" class WorldModelRoot; class Model; +class ADT; -template +template class GenericCache { public: @@ -14,32 +16,42 @@ public: static const int32 FlushLimit = 1000; - void Insert(std::string key, T* val) + void Insert(K key, T* val) { if (_items.size() > FlushLimit) Clear(); _items[key] = val; } - T* Get(std::string key) + T* Get(K key) { - UNORDERED_MAP::iterator itr = _items.find(key); + std::map::iterator itr = _items.find(key); if (itr != _items.end()) return itr->second; return NULL; } - void Clear() { _items.clear(); } + void Clear() + { + for (std::map::iterator itr = _items.begin(); itr != _items.end(); ++itr) + delete itr->second; + _items.clear(); + } private: - UNORDERED_MAP _items; + std::map _items; }; class CacheClass { public: CacheClass() {} - GenericCache ModelCache; - GenericCache WorldModelCache; + GenericCache ModelCache; + GenericCache WorldModelCache; + GenericCache, ADT> AdtCache; + void Clear() + { + AdtCache.Clear(); + } }; extern CacheClass* Cache; diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h index 38fa0b2e35b..f44d5f16797 100644 --- a/src/tools/mesh_extractor/Constants.h +++ b/src/tools/mesh_extractor/Constants.h @@ -22,6 +22,13 @@ public: POLY_AREA_ROAD = 3, POLY_AREA_DANGER = 4, }; + + enum PolyFlag + { + POLY_FLAG_WALK = 1, + POLY_FLAG_SWIM = 2, + POLY_FLAG_FLIGHTMASTER = 4 + }; static const float TileSize; static const float MaxXY; static const float ChunkSize; diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 8af6f3a02e8..f861dff1648 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -1,11 +1,38 @@ #include "ContinentBuilder.h" +#include "TileBuilder.h" #include "WDT.h" #include "Utils.h" +#include "DetourNavMesh.h" void ContinentBuilder::Build() { + FILE* mmap = fopen("608.mmap", "wb"); + dtNavMeshParams params; + params.maxPolys = 32768; + params.maxTiles = 4096; + params.orig[0] = -17066.666f; + params.orig[1] = 0.0f; + params.orig[2] = -17066.666f; + params.tileHeight = 533.33333f; + params.tileWidth = 533.33333f; + fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); + fclose(mmap); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { - + TileBuilder builder(Continent, itr->X, itr->Y, TileMap); + char buff[100]; + sprintf(buff, "%03u%02u%02u.mmtile", builder.MapId, itr->X, itr->Y); + FILE* f = fopen(buff, "wb"); + uint8* nav = builder.Build(); + if (nav) + { + MmapTileHeader header; + header.size = builder.DataSize; + fwrite(&header, sizeof(MmapTileHeader), 1, f); + fwrite(nav, sizeof(uint8), builder.DataSize, f); + } + fclose(f); + dtFree(nav); + printf("[%02u,%02u] Tile Built!\n", itr->X, itr->Y); } } diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp index 130258b6908..2fbe99e3211 100644 --- a/src/tools/mesh_extractor/Geometry.cpp +++ b/src/tools/mesh_extractor/Geometry.cpp @@ -1,5 +1,8 @@ #include "Geometry.h" #include "Constants.h" +#include "ADT.h" +#include "WorldModelHandler.h" +#include "DoodadHandler.h" Geometry::Geometry() : Transform(false) { @@ -100,3 +103,21 @@ void Geometry::GetRawData( float*& verts, int*& tris, uint8*& areas ) } } +void Geometry::AddAdt( ADT* adt ) +{ + for (std::vector::iterator itr = adt->MapChunks.begin(); itr != adt->MapChunks.end(); ++itr) + { + std::vector > tmp; + tmp.reserve((*itr)->Triangles.size()); + for (std::vector >::iterator itr2 = (*itr)->Triangles.begin(); itr2 != (*itr)->Triangles.end(); ++itr2) + tmp.push_back(Triangle(itr2->Type, itr2->V0, itr2->V1, itr2->V2)); + AddData((*itr)->Vertices, tmp); + } + + if (!adt->_DoodadHandler->Triangles.empty()) + AddData(adt->_DoodadHandler->Vertices, adt->_DoodadHandler->Triangles); + + if (!adt->_WorldModelHandler->Triangles.empty()) + AddData(adt->_WorldModelHandler->Vertices, adt->_WorldModelHandler->Triangles); +} + diff --git a/src/tools/mesh_extractor/Geometry.h b/src/tools/mesh_extractor/Geometry.h index 048d9fde578..9593c98044e 100644 --- a/src/tools/mesh_extractor/Geometry.h +++ b/src/tools/mesh_extractor/Geometry.h @@ -4,6 +4,7 @@ #include "Utils.h" +class ADT; class Geometry { public: @@ -12,6 +13,7 @@ public: void CalculateBoundingBox(float*& min, float*& max); void CalculateMinMaxHeight(float& min, float& max); void AddData(std::vector& verts, std::vector >& tris); + void AddAdt(ADT* adt); void GetRawData(float*& verts, int*& tris, uint8*& areas); std::vector Vertices; diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 429b09ffe02..35d4c91fc14 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -46,7 +46,7 @@ void MPQManager::LoadMPQs() sprintf(filename, "Data/%s", Files[i]); Archives.push_front(new MPQArchive(filename)); } - printf("Loaded %u MPQ files succesfully", Archives.size()); + printf("Loaded %u MPQ files succesfully\n", Archives.size()); } FILE* MPQManager::GetFile( std::string path ) diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp index 0b02a2a4a14..61c106f9766 100644 --- a/src/tools/mesh_extractor/MapChunk.cpp +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -2,7 +2,7 @@ #include "ADT.h" #include "LiquidHandler.h" -MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : Adt(_adt), Source(chunk), Vertices(NULL) +MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : Adt(_adt), Source(chunk) { FILE* stream = chunk->GetStream(); Header.Read(stream); @@ -46,16 +46,10 @@ void MapChunk::GenerateTriangles() } } -MapChunk::~MapChunk() -{ - delete[] Vertices; -} - void MapChunk::GenerateVertices( FILE* stream ) { fseek(stream, Header.OffsetMCVT, SEEK_CUR); - int32 vertIndex = 0; - Vertices = new Vector3[125]; + Vertices.reserve(125); for (int j = 0; j < 17; j++) { @@ -67,7 +61,7 @@ void MapChunk::GenerateVertices( FILE* stream ) Vector3 vert(Header.Position.x - (j * (Constants::UnitSize * 0.5f)), Header.Position.y - (i * Constants::UnitSize), Header.Position.z + tmp); if (values == 8) vert.y -= Constants::UnitSize * 0.5f; - Vertices[vertIndex++] = vert; + Vertices.push_back(vert); } } } diff --git a/src/tools/mesh_extractor/MapChunk.h b/src/tools/mesh_extractor/MapChunk.h index 9d7b02bbfe5..61dcabac9b0 100644 --- a/src/tools/mesh_extractor/MapChunk.h +++ b/src/tools/mesh_extractor/MapChunk.h @@ -10,7 +10,6 @@ class MapChunk { public: MapChunk(ADT* _adt, Chunk* chunk); - ~MapChunk(); void GenerateTriangles(); void GenerateVertices(FILE* stream); @@ -18,7 +17,7 @@ public: ADT* Adt; Chunk* Source; MapChunkHeader Header; - Vector3* Vertices; + std::vector Vertices; std::vector > Triangles; int32 Index; }; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 0611c9c2d58..38a120449bc 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -15,10 +15,10 @@ void ExtractAllMaps() WDT wdt("World\\maps\\DalaranPrison\\DalaranPrison.wdt"); if (!wdt.IsValid) return; - printf("Model valid!"); + printf("Model valid!\n"); if (wdt.IsGlobalModel) { - printf("Unsupported"); + printf("Unsupported\n"); return; } ContinentBuilder builder("DalaranPrison", &wdt); diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 190607493fa..4736274706d 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -1,7 +1,15 @@ #include "TileBuilder.h" +#include "Geometry.h" #include "Constants.h" +#include "Utils.h" +#include "Cache.h" +#include "ADT.h" +#include "WDT.h" +#include "Recast.h" +#include "RecastAlloc.h" +#include "DetourNavMeshBuilder.h" -TileBuilder::TileBuilder(std::string world, int x, int y) : _Geometry(NULL), World(world), X(x), Y(y), MapId(608) +TileBuilder::TileBuilder(std::string world, int x, int y, WDT* wdt) : _Geometry(NULL), World(world), X(x), Y(y), MapId(608), DataSize(0), Wdt(wdt) { // Cell Size = TileSize / TileVoxelSize // 1800 = TileVoxelSize @@ -23,6 +31,8 @@ TileBuilder::TileBuilder(std::string world, int x, int y) : _Geometry(NULL), Wor Config.width = 1800; Config.maxVertsPerPoly = 6; Config.maxSimplificationError = 1.3f; + + Context = new rcContext; } void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax ) @@ -34,3 +44,192 @@ void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax ) bmax[0] = Constants::Origin[0] + (Constants::TileSize * (X + 1)); bmax[2] = Constants::Origin[2] + (Constants::TileSize * (Y + 1)); } + +uint8* TileBuilder::Build() +{ + _Geometry = new Geometry(); + _Geometry->Transform = true; + ADT* adt = Cache->AdtCache.Get(std::make_pair(X, Y)); + if (!adt) + { + adt = new ADT(Utils::GetAdtPath(World, X, Y)); + adt->Read(); + Cache->AdtCache.Insert(std::make_pair(X, Y), adt); + } + _Geometry->AddAdt(adt); + + if (_Geometry->Vertices.empty() && _Geometry->Triangles.empty()) + return NULL; + + float* bbMin; + float* bbMax; + CalculateTileBounds(bbMin, bbMax); + _Geometry->CalculateMinMaxHeight(bbMin[1], bbMax[1]); + + // again, we load everything - wasteful but who cares + for (int ty = Y - 1; ty <= Y + 1; ty++) + { + for (int tx = X - 1; tx <= X + 1; tx++) + { + // don't load main tile again + if (tx == X && ty == Y) + continue; + + ADT* _adt = Cache->AdtCache.Get(std::make_pair(tx, ty)); + if (!_adt) + { + _adt = new ADT(Utils::GetAdtPath(World, tx, ty)); + // If this condition is met, it means that this wdt does not contain the ADT + if (!_adt->Data->Stream) + { + delete _adt; + continue; + } + _adt->Read(); + Cache->AdtCache.Insert(std::make_pair(tx, ty), _adt); + } + _Geometry->AddAdt(adt); + } + } + uint32 numVerts = _Geometry->Vertices.size(); + uint32 numTris = _Geometry->Triangles.size(); + float* vertices; + int* triangles; + uint8* areas; + _Geometry->GetRawData(vertices, triangles, areas); + _Geometry->Vertices.clear(); + _Geometry->Triangles.clear(); + + bbMin[0] -= Config.borderSize * Config.cs; + bbMin[2] -= Config.borderSize * Config.cs; + bbMax[0] += Config.borderSize * Config.cs; + bbMax[0] += Config.borderSize * Config.cs; + + rcHeightfield* hf = rcAllocHeightfield(); + int width = Config.width + (Config.borderSize * 2); + rcCreateHeightfield(Context, *hf, width, width, bbMin, bbMax, Config.cs, Config.ch); + rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); + rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); + + printf("[%02u,%02u] Triangles rasterized!\n", X, Y); + + // Once all geometry is rasterized, we do initial pass of filtering to + // remove unwanted overhangs caused by the conservative rasterization + // as well as filter spans where the character cannot possibly stand. + rcFilterLowHangingWalkableObstacles(Context, Config.walkableClimb, *hf); + rcFilterLedgeSpans(Context, Config.walkableHeight, Config.walkableClimb, *hf); + rcFilterWalkableLowHeightSpans(Context, Config.walkableHeight, *hf); + + printf("[%02u,%02u] Filtering done!\n", X, Y); + + // Compact the heightfield so that it is faster to handle from now on. + // This will result in more cache coherent data as well as the neighbours + // between walkable cells will be calculated. + rcCompactHeightfield* chf = rcAllocCompactHeightfield(); + rcBuildCompactHeightfield(Context, Config.walkableHeight, Config.walkableClimb, *hf, *chf); + + rcFreeHeightField(hf); + + printf("[%02u,%02u] Heightfield compressed!\n", X, Y); + + // Erode the walkable area by agent radius. + rcErodeWalkableArea(Context, Config.walkableRadius, *chf); + // Prepare for region partitioning, by calculating distance field along the walkable surface. + rcBuildDistanceField(Context, *chf); + // Partition the walkable surface into simple regions without holes. + rcBuildRegions(Context, *chf, Config.borderSize, Config.minRegionArea, Config.mergeRegionArea); + + printf("[%02u,%02u] Regions built!\n", X, Y); + + // Create contours. + rcContourSet* cset = rcAllocContourSet(); + rcBuildContours(Context, *chf, Config.maxSimplificationError, Config.maxEdgeLen, *cset); + + // Build polygon navmesh from the contours. + rcPolyMesh* pmesh = rcAllocPolyMesh(); + rcBuildPolyMesh(Context, *cset, Config.maxVertsPerPoly, *pmesh); + + printf("[%02u,%02u] Polymesh built!\n", X, Y); + + // Build detail mesh. + rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); + rcBuildPolyMeshDetail(Context, *pmesh, *chf, Config.detailSampleDist, Config.detailSampleMaxError, *dmesh); + + printf("[%02u,%02u] Polymesh detail built!\n", X, Y); + + rcFreeCompactHeightfield(chf); + rcFreeContourSet(cset); + + // Remove padding from the polymesh data. (Remove this odditity) + for (int i = 0; i < pmesh->nverts; ++i) + { + unsigned short* v = &pmesh->verts[i * 3]; + v[0] -= (unsigned short)Config.borderSize; + v[2] -= (unsigned short)Config.borderSize; + } + + // Set flags according to area types (e.g. Swim for Water) + for (int i = 0; i < pmesh->npolys; i++) + { + if (pmesh->areas[i] == Constants::POLY_AREA_ROAD || pmesh->areas[i] == Constants::POLY_AREA_TERRAIN) + pmesh->flags[i] = Constants::POLY_FLAG_WALK; + else if (pmesh->areas[i] == (int)Constants::POLY_AREA_WATER) + pmesh->flags[i] = Constants::POLY_FLAG_SWIM; + } + + // get original bounds + float* tilebMin; + float* tilebMax; + CalculateTileBounds(tilebMin, tilebMax); + tilebMin[1] = bbMin[1]; + tilebMax[1] = bbMax[1]; + + dtNavMeshCreateParams params; + // PolyMesh data + params.verts = pmesh->verts; + params.vertCount = pmesh->nverts; + params.polys = pmesh->polys; + params.polyAreas = pmesh->areas; + params.polyFlags = pmesh->flags; + params.polyCount = pmesh->npolys; + params.nvp = pmesh->nvp; + // PolyMeshDetail data + params.detailMeshes = dmesh->meshes; + params.detailVerts = dmesh->verts; + params.detailVertsCount = dmesh->nverts; + params.detailTris = dmesh->tris; + params.detailTriCount = dmesh->ntris; + // Copy bounding box + params.bmin[0] = tilebMin[0]; + params.bmin[1] = tilebMin[1]; + params.bmin[2] = tilebMin[2]; + params.bmax[0] = tilebMax[0]; + params.bmax[1] = tilebMax[1]; + params.bmax[2] = tilebMax[2]; + // General settings + params.ch = Config.ch; + params.cs = Config.cs; + params.walkableClimb = Config.walkableClimb; + params.walkableHeight = Config.walkableHeight; + params.walkableRadius = Config.walkableRadius; + params.tileX = X; + params.tileY = Y; + params.tileSize = Config.width; + int navDataSize; + uint8* navData; + printf("[%02u,%02u] Creating the navmesh!\n", X, Y); + bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); + if (result) + { + printf("[%02u,%02u] NavMesh created, size %u!\n", X, Y, navDataSize); + DataSize = navDataSize; + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + Cache->Clear(); + return navData; + } + + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + return NULL; +} diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index badb05295e5..7dff363cabe 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -5,10 +5,12 @@ #include "Geometry.h" +class WDT; + class TileBuilder { public: - TileBuilder(std::string world, int x, int y); + TileBuilder(std::string world, int x, int y, WDT* wdt); void CalculateTileBounds(float*& bmin, float*& bmax); uint8* Build(); @@ -17,6 +19,9 @@ public: int Y; int MapId; rcConfig Config; + rcContext* Context; Geometry* _Geometry; + uint32 DataSize; + WDT* Wdt; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index ac14b9eca69..4cf20a4cf9d 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -5,6 +5,7 @@ #include #include "g3d/Matrix4.h" +#include "DetourNavMesh.h" #include "Common.h" #include "Constants.h" @@ -523,6 +524,21 @@ public: virtual float Scale() const { return 1.0f; }; }; +#define MMAP_MAGIC 0x4d4d4150 // 'MMAP' +#define MMAP_VERSION 3 + +struct MmapTileHeader +{ + uint32 mmapMagic; + uint32 dtVersion; + uint32 mmapVersion; + uint32 size; + bool usesLiquids : 1; + + MmapTileHeader() : mmapMagic(MMAP_MAGIC), dtVersion(DT_NAVMESH_VERSION), + mmapVersion(MMAP_VERSION), size(0), usesLiquids(true) {} +}; + class Utils { public: diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index e5a14d55c0c..1a772a36558 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -92,7 +92,7 @@ void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::v } } - if (def.DoodadSet >= 0 && def.DoodadSet < root->DoodadSets.size()) + if (def.DoodadSet < root->DoodadSets.size()) { DoodadSet set = root->DoodadSets[def.DoodadSet]; std::vector instances; -- cgit v1.2.3 From 5725b068d22a22b3e77f8887b2a1736854d85027 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 14:28:50 -0500 Subject: Tools/MeshExtractor: Fixed an uninitialized variable error. --- src/tools/mesh_extractor/ContinentBuilder.cpp | 2 +- src/tools/mesh_extractor/DoodadHandler.cpp | 2 +- src/tools/mesh_extractor/DoodadHandler.h | 2 +- src/tools/mesh_extractor/TileBuilder.cpp | 20 ++++++++++++-------- src/tools/mesh_extractor/Utils.h | 2 +- 5 files changed, 16 insertions(+), 12 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index f861dff1648..c63445b2287 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -29,7 +29,7 @@ void ContinentBuilder::Build() MmapTileHeader header; header.size = builder.DataSize; fwrite(&header, sizeof(MmapTileHeader), 1, f); - fwrite(nav, sizeof(uint8), builder.DataSize, f); + fwrite(nav, sizeof(unsigned char), builder.DataSize, f); } fclose(f); dtFree(nav); diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 89fcaba5601..aa298cea698 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -88,7 +88,7 @@ void DoodadHandler::ReadDoodadPaths( Chunk* id, Chunk* data ) } } -void DoodadHandler::InsertModelGeometry(const DoodadDefinition def, Model* model) +void DoodadHandler::InsertModelGeometry(const DoodadDefinition& def, Model* model) { G3D::Matrix4 transformation = Utils::GetTransformation(def); uint32 vertOffset = Vertices.size(); diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index c426504da32..aa7e3cac20d 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -43,7 +43,7 @@ protected: private: void ReadDoodadDefinitions(Chunk* chunk); void ReadDoodadPaths(Chunk* id, Chunk* data); - void InsertModelGeometry(const DoodadDefinition def, Model* model); + void InsertModelGeometry(const DoodadDefinition& def, Model* model); std::set _drawn; std::vector* _definitions; std::vector* _paths; diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 4736274706d..445641fc009 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -111,7 +111,7 @@ uint8* TileBuilder::Build() rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); - printf("[%02u,%02u] Triangles rasterized!\n", X, Y); + printf("[%02i,%02i] Triangles rasterized!\n", X, Y); // Once all geometry is rasterized, we do initial pass of filtering to // remove unwanted overhangs caused by the conservative rasterization @@ -120,7 +120,7 @@ uint8* TileBuilder::Build() rcFilterLedgeSpans(Context, Config.walkableHeight, Config.walkableClimb, *hf); rcFilterWalkableLowHeightSpans(Context, Config.walkableHeight, *hf); - printf("[%02u,%02u] Filtering done!\n", X, Y); + printf("[%02i,%02i] Filtering done!\n", X, Y); // Compact the heightfield so that it is faster to handle from now on. // This will result in more cache coherent data as well as the neighbours @@ -130,7 +130,7 @@ uint8* TileBuilder::Build() rcFreeHeightField(hf); - printf("[%02u,%02u] Heightfield compressed!\n", X, Y); + printf("[%02i,%02i] Heightfield compressed!\n", X, Y); // Erode the walkable area by agent radius. rcErodeWalkableArea(Context, Config.walkableRadius, *chf); @@ -139,7 +139,7 @@ uint8* TileBuilder::Build() // Partition the walkable surface into simple regions without holes. rcBuildRegions(Context, *chf, Config.borderSize, Config.minRegionArea, Config.mergeRegionArea); - printf("[%02u,%02u] Regions built!\n", X, Y); + printf("[%02i,%02i] Regions built!\n", X, Y); // Create contours. rcContourSet* cset = rcAllocContourSet(); @@ -149,13 +149,13 @@ uint8* TileBuilder::Build() rcPolyMesh* pmesh = rcAllocPolyMesh(); rcBuildPolyMesh(Context, *cset, Config.maxVertsPerPoly, *pmesh); - printf("[%02u,%02u] Polymesh built!\n", X, Y); + printf("[%02i,%02i] Polymesh built!\n", X, Y); // Build detail mesh. rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); rcBuildPolyMeshDetail(Context, *pmesh, *chf, Config.detailSampleDist, Config.detailSampleMaxError, *dmesh); - printf("[%02u,%02u] Polymesh detail built!\n", X, Y); + printf("[%02i,%02i] Polymesh detail built!\n", X, Y); rcFreeCompactHeightfield(chf); rcFreeContourSet(cset); @@ -215,13 +215,17 @@ uint8* TileBuilder::Build() params.tileX = X; params.tileY = Y; params.tileSize = Config.width; + + // Offmesh-connection settings + params.offMeshConCount = 0; // none for now + int navDataSize; uint8* navData; - printf("[%02u,%02u] Creating the navmesh!\n", X, Y); + printf("[%02i,%02i] Creating the navmesh!\n", X, Y); bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); if (result) { - printf("[%02u,%02u] NavMesh created, size %u!\n", X, Y, navDataSize); + printf("[%02i,%02i] NavMesh created, size %i!\n", X, Y, navDataSize); DataSize = navDataSize; rcFreePolyMesh(pmesh); rcFreePolyMeshDetail(dmesh); diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 4cf20a4cf9d..188d47a88ce 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -533,7 +533,7 @@ struct MmapTileHeader uint32 dtVersion; uint32 mmapVersion; uint32 size; - bool usesLiquids : 1; + bool usesLiquids; MmapTileHeader() : mmapMagic(MMAP_MAGIC), dtVersion(DT_NAVMESH_VERSION), mmapVersion(MMAP_VERSION), size(0), usesLiquids(true) {} -- cgit v1.2.3 From 886f71df72a751abf1b742e67e7707cb623fd854 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 16:21:35 -0500 Subject: Tools/MeshExtract: Fixed linux build, thanks Dev[Acho]. Added a DBC class It will now autodetect your locale and start extracting mmaps as soon as started. --- src/tools/mesh_extractor/ADT.cpp | 9 +++- src/tools/mesh_extractor/CMakeLists.txt | 7 +++ src/tools/mesh_extractor/Cache.h | 4 +- src/tools/mesh_extractor/ContinentBuilder.cpp | 19 ++++++-- src/tools/mesh_extractor/ContinentBuilder.h | 4 +- src/tools/mesh_extractor/DBC.cpp | 64 ++++++++++++++++++++++++++ src/tools/mesh_extractor/DBC.h | 51 ++++++++++++++++++++ src/tools/mesh_extractor/DoodadHandler.cpp | 2 +- src/tools/mesh_extractor/MPQManager.cpp | 59 ++++++++++++++---------- src/tools/mesh_extractor/MPQManager.h | 6 ++- src/tools/mesh_extractor/MeshExtractor.cpp | 13 ++++++ src/tools/mesh_extractor/TileBuilder.cpp | 7 ++- src/tools/mesh_extractor/TileBuilder.h | 2 +- src/tools/mesh_extractor/Utils.cpp | 4 +- src/tools/mesh_extractor/Utils.h | 4 +- src/tools/mesh_extractor/WorldModelHandler.cpp | 2 +- 16 files changed, 214 insertions(+), 43 deletions(-) create mode 100644 src/tools/mesh_extractor/DBC.cpp create mode 100644 src/tools/mesh_extractor/DBC.h (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp index c564d7193cf..98bce8b2057 100644 --- a/src/tools/mesh_extractor/ADT.cpp +++ b/src/tools/mesh_extractor/ADT.cpp @@ -29,7 +29,14 @@ ADT::~ADT() void ADT::Read() { - Header.Read(Data->GetChunkByName("MHDR")->GetStream()); + Chunk* mhdr = Data->GetChunkByName("MHDR"); + if (!mhdr) + { + delete Data; + Data = NULL; + return; + } + Header.Read(mhdr->GetStream()); MapChunks.reserve(16 * 16); int mapChunkIndex = 0; diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt index 09bd2982213..8ef48a90742 100644 --- a/src/tools/mesh_extractor/CMakeLists.txt +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -15,6 +15,13 @@ if( UNIX ) include_directories ( ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/src/server/shared/Database + ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation + ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Logging + ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour ${CMAKE_SOURCE_DIR}/dep/libmpq diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 799878bdd3b..83b6ba6ca7a 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -25,7 +25,7 @@ public: T* Get(K key) { - std::map::iterator itr = _items.find(key); + typename std::map::iterator itr = _items.find(key); if (itr != _items.end()) return itr->second; return NULL; @@ -33,7 +33,7 @@ public: void Clear() { - for (std::map::iterator itr = _items.begin(); itr != _items.end(); ++itr) + for (typename std::map::iterator itr = _items.begin(); itr != _items.end(); ++itr) delete itr->second; _items.clear(); } diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index c63445b2287..7391ebb8767 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -6,7 +6,9 @@ void ContinentBuilder::Build() { - FILE* mmap = fopen("608.mmap", "wb"); + char buff[50]; + sprintf(buff, "%03u.mmap", MapId); + FILE* mmap = fopen(buff, "wb"); dtNavMeshParams params; params.maxPolys = 32768; params.maxTiles = 4096; @@ -19,19 +21,26 @@ void ContinentBuilder::Build() fclose(mmap); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { - TileBuilder builder(Continent, itr->X, itr->Y, TileMap); + TileBuilder builder(Continent, itr->X, itr->Y, TileMap, MapId); char buff[100]; - sprintf(buff, "%03u%02u%02u.mmtile", builder.MapId, itr->X, itr->Y); - FILE* f = fopen(buff, "wb"); + sprintf(buff, "%03u%02u%02u.mmtile", MapId, itr->X, itr->Y); + FILE* f = fopen(buff, "r"); + if (f) // Check if file already exists. + { + fclose(f); + continue; + } uint8* nav = builder.Build(); if (nav) { + fclose(f); + f = fopen(buff, "wb"); MmapTileHeader header; header.size = builder.DataSize; fwrite(&header, sizeof(MmapTileHeader), 1, f); fwrite(nav, sizeof(unsigned char), builder.DataSize, f); + fclose(f); } - fclose(f); dtFree(nav); printf("[%02u,%02u] Tile Built!\n", itr->X, itr->Y); } diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h index 7db141ddcf1..92c97c5f7e0 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -2,14 +2,16 @@ #define CONT_BUILDER_H #include #include "WDT.h" +#include "Common.h" class ContinentBuilder { public: - ContinentBuilder(std::string continent, WDT* wdt) : Continent(continent), TileMap(wdt) {} + ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt) : MapId(mapId), Continent(continent), TileMap(wdt) {} void Build(); private: std::string Continent; WDT* TileMap; + uint32 MapId; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/DBC.cpp b/src/tools/mesh_extractor/DBC.cpp new file mode 100644 index 00000000000..be04ce070ee --- /dev/null +++ b/src/tools/mesh_extractor/DBC.cpp @@ -0,0 +1,64 @@ +#include +#include "DBC.h" +#include "Common.h" + +DBC::DBC( FILE* stream ) : StringBlock(NULL), IsFaulty(true), StringBlockSize(0) +{ + char magic[5]; + fread(&magic, sizeof(char), 4, stream); + magic[4] = '\0'; + fread(&RecordCount, sizeof(uint32), 1, stream); + Records.reserve(RecordCount); + fread(&Fields, sizeof(uint32), 1, stream); + fread(&RecordSize, sizeof(uint32), 1, stream); + fread(&StringBlockSize, sizeof(uint32), 1, stream); + + for (int i = 0; i < RecordCount; i++) + { + Record* rec = new Record(this); + Records.push_back(rec); + int size = 0; + for (int f = 0; f < Fields; f++) + { + if (size + 4 > RecordSize) + { + IsFaulty = true; + break; + } + uint32 tmp; + fread(&tmp, sizeof(uint32), 1, stream); + rec->Values.push_back(tmp); + size += 4; + } + } + StringBlock = new uint8[StringBlockSize]; + fread(StringBlock, sizeof(uint8), StringBlockSize, stream); +} + +std::string DBC::GetStringByOffset( int offset ) +{ + int len = 0; + for (int i = offset; i < StringBlockSize; i++) + { + if (!StringBlock[i]) + { + len = (i - offset); + break; + } + } + char* d = new char[len+1]; + strcpy(d, (const char*)(StringBlock + offset)); + d[len] = '\0'; + std::string val = std::string(d); + delete d; + return val; +} + +Record* DBC::GetRecordById( int id ) +{ + // we assume Id is index 0 + for (std::vector::iterator itr = Records.begin(); itr != Records.end(); ++itr) + if ((*itr)->Values[0] == id) + return *itr; + return NULL; +} diff --git a/src/tools/mesh_extractor/DBC.h b/src/tools/mesh_extractor/DBC.h new file mode 100644 index 00000000000..6c86c1391dd --- /dev/null +++ b/src/tools/mesh_extractor/DBC.h @@ -0,0 +1,51 @@ +#ifndef DBC_H +#define DBC_H +#include +#include "Common.h" + +class Record; + +class DBC +{ +public: + DBC(FILE* stream); + + std::string GetStringByOffset(int offset); + + Record* GetRecordById(int id); + + std::string Name; + std::vector Records; + int RecordCount; + int Fields; + int RecordSize; + uint8* StringBlock; + uint32 StringBlockSize; + bool IsFaulty; +}; + +class Record +{ +public: + Record(DBC* dbc) : Source(dbc) {} + + DBC* Source; + std::vector Values; + + int operator[](int index) + { + return Values[index]; + } + + float GetFloat(int index) + { + return *(float*)(&Values[index]); + } + + std::string GetString(int index) + { + return Source->GetStringByOffset(Values[index]); + } +}; + +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index aa298cea698..28bb9da5f21 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -2,7 +2,7 @@ #include "Chunk.h" #include "Cache.h" #include "Model.h" -#include "g3d/Matrix4.h" +#include "G3D/Matrix4.h" DoodadHandler::DoodadHandler( ADT* adt ) : ObjectDataHandler(adt), _definitions(NULL), _paths(NULL) { diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 35d4c91fc14..24e7e827548 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -1,5 +1,7 @@ #include "MPQManager.h" #include "MPQ.h" +#include "DBC.h" +#include "Utils.h" char* MPQManager::Files[] = { "common.MPQ", @@ -11,42 +13,43 @@ char* MPQManager::Files[] = { "patch-3.MPQ" }; +char* MPQManager::Languages[] = { "esES", "enUS", "enGB", "esMX", "deDE" }; + void MPQManager::Initialize() { - LoadMPQs(); + InitializeDBC(); + uint32 size = sizeof(Files) / sizeof(char*); + for (uint32 i = 0; i < size; ++i) + { + MPQArchive* arc = new MPQArchive(std::string("Data/" + std::string(Files[i])).c_str()); + Archives.push_front(arc); + printf("Opened %s\n", Files[i]); + } } void MPQManager::LoadMaps() { - + DBC* file = GetDBC("Map"); + printf("NAME %s\n", file->GetRecordById(608)->GetString(1).c_str()); } -void MPQManager::LoadMPQs() +void MPQManager::InitializeDBC() { - // Load the locale MPQ files first - char filename[512]; - - /*sprintf(filename,"Data/%s/locale-%s.MPQ", langs[locale], langs[locale]);*/ - Archives.push_front(new MPQArchive("Data/enUS/locale-enUS.MPQ")); - - for(int i = 0; i < 3; ++i) + CurLocale = 0; + std::string fileName; + uint32 size = sizeof(Languages) / sizeof(char*); + for (uint32 i = 0; i < size; ++i) { - char ext[3] = ""; - if (i) - sprintf(ext, "-%i", i + 1); - - sprintf(filename, "Data/enUS/patch-enUS%s.MPQ", ext); - Archives.push_front(new MPQArchive(filename)); + fileName = "Data/" + std::string(Languages[i]) + "/locale-" + std::string(Languages[i]) + ".MPQ"; + FILE* file = fopen(fileName.c_str(), "rb"); + if (file) + { + CurLocale = i; + break; + } } - - // Now load the common MPQ files - int count = sizeof(Files) / sizeof(char*); - for (int i = 0; i < count; ++i) - { - sprintf(filename, "Data/%s", Files[i]); - Archives.push_front(new MPQArchive(filename)); - } - printf("Loaded %u MPQ files succesfully\n", Archives.size()); + Archives.push_front(new MPQArchive(fileName.c_str())); + printf("Using locale: %s\n", Languages[CurLocale]); } FILE* MPQManager::GetFile( std::string path ) @@ -56,3 +59,9 @@ FILE* MPQManager::GetFile( std::string path ) return NULL; return file.GetFileStream(); } + +DBC* MPQManager::GetDBC( std::string name ) +{ + std::string path = "DBFilesClient\\" + name + ".dbc"; + return new DBC(GetFile(path)); +} diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h index e10066ae4a6..725e0168237 100644 --- a/src/tools/mesh_extractor/MPQManager.h +++ b/src/tools/mesh_extractor/MPQManager.h @@ -3,6 +3,7 @@ #include "MPQ.h" +class DBC; class MPQManager { public: @@ -12,12 +13,15 @@ public: void Initialize(); void LoadMaps(); FILE* GetFile(std::string path); + DBC* GetDBC(std::string name); std::deque Archives; + uint32 CurLocale; static char* Files[]; + static char* Languages[]; protected: - void LoadMPQs(); + void InitializeDBC(); }; extern MPQManager* MPQHandler; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 38a120449bc..77b5a8e8c3d 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -2,6 +2,7 @@ #include "WDT.h" #include "ContinentBuilder.h" #include "Cache.h" +#include "DBC.h" #include "Common.h" #include "LoginDatabase.h" @@ -12,6 +13,17 @@ CacheClass* Cache; void ExtractAllMaps() { + DBC* dbc = MPQHandler->GetDBC("Map"); + for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) + { + std::string name = (*itr)->GetString(1); + WDT wdt("World\\maps\\" + name + "\\" + name + ".wdt"); + if (!wdt.IsValid || wdt.IsGlobalModel) + continue; + ContinentBuilder builder(name, (*itr)->Values[0], &wdt); + builder.Build(); + } + /* WDT wdt("World\\maps\\DalaranPrison\\DalaranPrison.wdt"); if (!wdt.IsValid) return; @@ -23,6 +35,7 @@ void ExtractAllMaps() } ContinentBuilder builder("DalaranPrison", &wdt); builder.Build(); + */ } int main(int argc, char* argv[]) diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 445641fc009..8bbfd5afb69 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -9,7 +9,7 @@ #include "RecastAlloc.h" #include "DetourNavMeshBuilder.h" -TileBuilder::TileBuilder(std::string world, int x, int y, WDT* wdt) : _Geometry(NULL), World(world), X(x), Y(y), MapId(608), DataSize(0), Wdt(wdt) +TileBuilder::TileBuilder(std::string world, int x, int y, WDT* wdt, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0), Wdt(wdt) { // Cell Size = TileSize / TileVoxelSize // 1800 = TileVoxelSize @@ -54,6 +54,11 @@ uint8* TileBuilder::Build() { adt = new ADT(Utils::GetAdtPath(World, X, Y)); adt->Read(); + if (!adt->Data) + { + delete adt; + return NULL; + } Cache->AdtCache.Insert(std::make_pair(X, Y), adt); } _Geometry->AddAdt(adt); diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index 7dff363cabe..261675af7e2 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -10,7 +10,7 @@ class WDT; class TileBuilder { public: - TileBuilder(std::string world, int x, int y, WDT* wdt); + TileBuilder(std::string world, int x, int y, WDT* wdt, uint32 mapId); void CalculateTileBounds(float*& bmin, float*& bmax); uint8* Build(); diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index c7c0cff0d42..2f07bd20080 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -2,8 +2,8 @@ #include "WorldModelHandler.h" #include "Constants.h" #include -#include "g3d/Matrix4.h" -#include "g3d/Quat.h" +#include "G3D/Matrix4.h" +#include "G3D/Quat.h" const float Constants::TileSize = 533.0f + (1/3.0f); const float Constants::MaxXY = 32.0f * Constants::TileSize; diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 188d47a88ce..c247169df73 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -4,7 +4,7 @@ #include #include -#include "g3d/Matrix4.h" +#include "G3D/Matrix4.h" #include "DetourNavMesh.h" #include "Common.h" @@ -573,7 +573,7 @@ public: return false; return true; } - static std::string Utils::Replace( std::string str, const std::string& oldStr, const std::string& newStr ); + static std::string Replace( std::string str, const std::string& oldStr, const std::string& newStr ); static G3D::Matrix4 GetWmoDoodadTransformation( DoodadInstance inst, WorldModelDefinition root ); }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index 1a772a36558..636b06f6f73 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -4,7 +4,7 @@ #include "Cache.h" #include "Model.h" #include "Common.h" -#include "g3d/Matrix4.h" +#include "G3D/Matrix4.h" #include WorldModelDefinition WorldModelDefinition::Read( FILE* file ) -- cgit v1.2.3 From eba6980b9a52f55859cb3bd93235e14866769514 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 16:26:43 -0500 Subject: Tools/MeshExtractor: Allow to extract only 1 map ( via command line ) --- src/tools/mesh_extractor/MeshExtractor.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 77b5a8e8c3d..a99cc4475a0 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -11,16 +11,20 @@ LoginDatabaseWorkerPool LoginDatabase; MPQManager* MPQHandler; CacheClass* Cache; -void ExtractAllMaps() +void ExtractAllMaps(uint32 onlyMap) { DBC* dbc = MPQHandler->GetDBC("Map"); for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) { + uint32 mapId = (*itr)->Values[0]; + if (onlyMap && mapId != onlyMap) + continue; std::string name = (*itr)->GetString(1); WDT wdt("World\\maps\\" + name + "\\" + name + ".wdt"); if (!wdt.IsValid || wdt.IsGlobalModel) continue; - ContinentBuilder builder(name, (*itr)->Values[0], &wdt); + printf("Building %s MapId %u\n", name, mapId); + ContinentBuilder builder(name, mapId, &wdt); builder.Build(); } /* @@ -45,7 +49,10 @@ int main(int argc, char* argv[]) MPQHandler = new MPQManager(); MPQHandler->Initialize(); MPQHandler->LoadMaps(); - ExtractAllMaps(); + uint32 onlyMap = 0; + if (argc == 2) + onlyMap = uint32(atoi(argv[1])); + ExtractAllMaps(onlyMap); return 0; } -- cgit v1.2.3 From 9b97a89ef8e1dd1694985d1fc8e88808da1550cd Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 17:09:44 -0500 Subject: Tools/MeshExtractor: Fixed a crash and some other mistakes. First glances of multithreading ( need to figure out a way around StormLib ) --- src/tools/mesh_extractor/ContinentBuilder.cpp | 88 +++++++++++++++++++++------ src/tools/mesh_extractor/MapChunk.cpp | 1 + src/tools/mesh_extractor/MeshExtractor.cpp | 2 +- src/tools/mesh_extractor/TileBuilder.cpp | 2 +- src/tools/mesh_extractor/TileBuilder.h | 3 +- 5 files changed, 73 insertions(+), 23 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 7391ebb8767..02a4d3626b7 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -3,32 +3,29 @@ #include "WDT.h" #include "Utils.h" #include "DetourNavMesh.h" +#include "ace/Task.h" -void ContinentBuilder::Build() +class BuilderThread : public ACE_Task { - char buff[50]; - sprintf(buff, "%03u.mmap", MapId); - FILE* mmap = fopen(buff, "wb"); - dtNavMeshParams params; - params.maxPolys = 32768; - params.maxTiles = 4096; - params.orig[0] = -17066.666f; - params.orig[1] = 0.0f; - params.orig[2] = -17066.666f; - params.tileHeight = 533.33333f; - params.tileWidth = 533.33333f; - fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); - fclose(mmap); - for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) +private: + int X, Y, MapId; + std::string Continent; +public: + BuilderThread() : Free(true) {} + void SetData(int x, int y, int map, std::string cont) { X = x; Y = y; MapId = map; Continent = cont; } + + int svc() { - TileBuilder builder(Continent, itr->X, itr->Y, TileMap, MapId); + Free = false; + TileBuilder builder(Continent, X, Y, MapId); char buff[100]; - sprintf(buff, "%03u%02u%02u.mmtile", MapId, itr->X, itr->Y); + sprintf(buff, "%03u%02u%02u.mmtile", MapId, X, Y); FILE* f = fopen(buff, "r"); if (f) // Check if file already exists. { fclose(f); - continue; + Free = true; + return 0; } uint8* nav = builder.Build(); if (nav) @@ -42,6 +39,59 @@ void ContinentBuilder::Build() fclose(f); } dtFree(nav); - printf("[%02u,%02u] Tile Built!\n", itr->X, itr->Y); + printf("[%02u,%02u] Tile Built!\n", X, Y); + Free = true; + return 0; } + + bool Free; +}; + +void ContinentBuilder::Build() +{ + char buff[50]; + sprintf(buff, "%03u.mmap", MapId); + FILE* mmap = fopen(buff, "wb"); + dtNavMeshParams params; + params.maxPolys = 32768; + params.maxTiles = 4096; + params.orig[0] = -17066.666f; + params.orig[1] = 0.0f; + params.orig[2] = -17066.666f; + params.tileHeight = 533.33333f; + params.tileWidth = 533.33333f; + fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); + fclose(mmap); + std::vector Threads; + /*for (uint32 i = 0; i < 1; ++i) + Threads.push_back(new BuilderThread());*/ + for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) + { + BuilderThread th; + th.SetData(itr->X, itr->Y, MapId, Continent); + th.svc(); + /*bool next = false; + while (!next) + { + for (std::vector::iterator _th = Threads.begin(); _th != Threads.end(); ++_th) + { + if ((*_th)->Free) + { + (*_th)->SetData(itr->X, itr->Y, MapId, Continent); + (*_th)->activate(); + next = true; + break; + } + } + // Wait for 20 seconds + ACE_OS::sleep(ACE_Time_Value (0, 20000)); + }*/ + } + + /*// Free memory + for (std::vector::iterator _th = Threads.begin(); _th != Threads.end(); ++_th) + { + (*_th)->wait(); + delete *_th; + }*/ } diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp index 61c106f9766..debde08cda8 100644 --- a/src/tools/mesh_extractor/MapChunk.cpp +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -7,6 +7,7 @@ MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : Adt(_adt), Source(chunk) FILE* stream = chunk->GetStream(); Header.Read(stream); fseek(stream, chunk->Offset, SEEK_SET); + Index = Header.IndexX + Header.IndexY * 16; GenerateVertices(stream); } diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index a99cc4475a0..7ae6afadb84 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -23,7 +23,7 @@ void ExtractAllMaps(uint32 onlyMap) WDT wdt("World\\maps\\" + name + "\\" + name + ".wdt"); if (!wdt.IsValid || wdt.IsGlobalModel) continue; - printf("Building %s MapId %u\n", name, mapId); + printf("Building %s MapId %u\n", name.c_str(), mapId); ContinentBuilder builder(name, mapId, &wdt); builder.Build(); } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 8bbfd5afb69..baf1fa0375c 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -9,7 +9,7 @@ #include "RecastAlloc.h" #include "DetourNavMeshBuilder.h" -TileBuilder::TileBuilder(std::string world, int x, int y, WDT* wdt, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0), Wdt(wdt) +TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0) { // Cell Size = TileSize / TileVoxelSize // 1800 = TileVoxelSize diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index 261675af7e2..f91a732f70c 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -10,7 +10,7 @@ class WDT; class TileBuilder { public: - TileBuilder(std::string world, int x, int y, WDT* wdt, uint32 mapId); + TileBuilder(std::string world, int x, int y, uint32 mapId); void CalculateTileBounds(float*& bmin, float*& bmax); uint8* Build(); @@ -22,6 +22,5 @@ public: rcContext* Context; Geometry* _Geometry; uint32 DataSize; - WDT* Wdt; }; #endif \ No newline at end of file -- cgit v1.2.3 From 95db9605ce227403eb4ea7fa46c91f47eb51a3ac Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 17:28:20 -0500 Subject: Tools/MeshExtractor: Removed extra fclose --- src/tools/mesh_extractor/ContinentBuilder.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 02a4d3626b7..29541da508c 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -30,7 +30,6 @@ public: uint8* nav = builder.Build(); if (nav) { - fclose(f); f = fopen(buff, "wb"); MmapTileHeader header; header.size = builder.DataSize; -- cgit v1.2.3 From 3bea28e62c00a5f73e4b58cd554db28666b1d54b Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 29 Sep 2012 06:24:35 -0500 Subject: Tools/MeshExtractor: Fixed a crash and bad data for liquids --- src/tools/mesh_extractor/ContinentBuilder.cpp | 1 + src/tools/mesh_extractor/LiquidHandler.cpp | 3 +++ src/tools/mesh_extractor/MapChunk.cpp | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 29541da508c..9d3b18491f1 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -17,6 +17,7 @@ public: int svc() { Free = false; + printf("[%02i,%02i] Building tile", X, Y); TileBuilder builder(Continent, X, Y, MapId); char buff[100]; sprintf(buff, "%03u%02u%02u.mmtile", MapId, X, Y); diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index 3d0876aeb74..f6f8e5678c6 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -31,7 +31,10 @@ void LiquidHandler::HandleNewLiquid() float** heights = new float*[9]; for (int i = 0; i < 9; ++i) + { heights[i] = new float[9]; + memset(heights[i], 0, sizeof(float) * 9); + } H2ORenderMask renderMask; if (information.LiquidType != 2) diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp index debde08cda8..67f4061035e 100644 --- a/src/tools/mesh_extractor/MapChunk.cpp +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -31,7 +31,7 @@ void MapChunk::GenerateTriangles() if (Adt->_LiquidHandler && !Adt->_LiquidHandler->MCNKData.empty()) { MCNKLiquidData& data = Adt->_LiquidHandler->MCNKData[Index]; - uint32 maxHeight = std::max( + float maxHeight = std::max( std::max( std::max(std::max(Vertices[topLeft].z, Vertices[topRight].z), Vertices[bottomLeft].z), Vertices[bottomRight].z), Vertices[center].z); -- cgit v1.2.3 From 1a7f0658b2a78a2c082b5f648548375b5d0f29e9 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 29 Sep 2012 12:49:14 -0500 Subject: Tools/MeshExtractor: * Fixed some crashes * Added multithreading support, default to 4 threads. * Added some command line arguments --- src/tools/mesh_extractor/ADT.cpp | 9 +--- src/tools/mesh_extractor/Cache.h | 3 ++ src/tools/mesh_extractor/ContinentBuilder.cpp | 19 ++++--- src/tools/mesh_extractor/ContinentBuilder.h | 3 +- src/tools/mesh_extractor/LiquidHandler.cpp | 4 ++ src/tools/mesh_extractor/MPQManager.cpp | 9 ++-- src/tools/mesh_extractor/MPQManager.h | 4 +- src/tools/mesh_extractor/MeshExtractor.cpp | 74 ++++++++++++++++++++------- src/tools/mesh_extractor/TileBuilder.cpp | 8 +-- 9 files changed, 82 insertions(+), 51 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp index 98bce8b2057..c564d7193cf 100644 --- a/src/tools/mesh_extractor/ADT.cpp +++ b/src/tools/mesh_extractor/ADT.cpp @@ -29,14 +29,7 @@ ADT::~ADT() void ADT::Read() { - Chunk* mhdr = Data->GetChunkByName("MHDR"); - if (!mhdr) - { - delete Data; - Data = NULL; - return; - } - Header.Read(mhdr->GetStream()); + Header.Read(Data->GetChunkByName("MHDR")->GetStream()); MapChunks.reserve(16 * 16); int mapChunkIndex = 0; diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 83b6ba6ca7a..49e268ec507 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -3,6 +3,7 @@ #include #include #include "Common.h" +#include "ace/Synch.h" class WorldModelRoot; class Model; @@ -20,6 +21,7 @@ public: { if (_items.size() > FlushLimit) Clear(); + ACE_GUARD(ACE_Thread_Mutex, g, mutex); _items[key] = val; } @@ -39,6 +41,7 @@ public: } private: std::map _items; + ACE_Thread_Mutex mutex; }; class CacheClass diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 9d3b18491f1..96f9085de8c 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -3,6 +3,7 @@ #include "WDT.h" #include "Utils.h" #include "DetourNavMesh.h" +#include "Cache.h" #include "ace/Task.h" class BuilderThread : public ACE_Task @@ -17,7 +18,7 @@ public: int svc() { Free = false; - printf("[%02i,%02i] Building tile", X, Y); + printf("[%02i,%02i] Building tile\n", X, Y); TileBuilder builder(Continent, X, Y, MapId); char buff[100]; sprintf(buff, "%03u%02u%02u.mmtile", MapId, X, Y); @@ -63,14 +64,11 @@ void ContinentBuilder::Build() fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); fclose(mmap); std::vector Threads; - /*for (uint32 i = 0; i < 1; ++i) - Threads.push_back(new BuilderThread());*/ + for (uint32 i = 0; i < NumberOfThreads; ++i) + Threads.push_back(new BuilderThread()); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { - BuilderThread th; - th.SetData(itr->X, itr->Y, MapId, Continent); - th.svc(); - /*bool next = false; + bool next = false; while (!next) { for (std::vector::iterator _th = Threads.begin(); _th != Threads.end(); ++_th) @@ -85,13 +83,14 @@ void ContinentBuilder::Build() } // Wait for 20 seconds ACE_OS::sleep(ACE_Time_Value (0, 20000)); - }*/ + } } + Cache->Clear(); - /*// Free memory + // Free memory for (std::vector::iterator _th = Threads.begin(); _th != Threads.end(); ++_th) { (*_th)->wait(); delete *_th; - }*/ + } } diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h index 92c97c5f7e0..d3da984595d 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -7,11 +7,12 @@ class ContinentBuilder { public: - ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt) : MapId(mapId), Continent(continent), TileMap(wdt) {} + ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : MapId(mapId), Continent(continent), TileMap(wdt), NumberOfThreads(tn) {} void Build(); private: std::string Continent; WDT* TileMap; uint32 MapId; + uint32 NumberOfThreads; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index f6f8e5678c6..9a40e08b73a 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -25,7 +25,11 @@ void LiquidHandler::HandleNewLiquid() { H2OHeader h = header[i]; if (h.LayerCount == 0) + { + // Need to fill in missing data with dummies. + MCNKData.push_back(MCNKLiquidData(NULL, H2ORenderMask())); continue; + } fseek(stream, chunk->Offset + h.OffsetInformation, SEEK_SET); H2OInformation information = H2OInformation::Read(stream); diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 24e7e827548..5ea6198e76d 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -3,6 +3,8 @@ #include "DBC.h" #include "Utils.h" +#include "ace/Synch.h" + char* MPQManager::Files[] = { "common.MPQ", "common-2.MPQ", @@ -27,12 +29,6 @@ void MPQManager::Initialize() } } -void MPQManager::LoadMaps() -{ - DBC* file = GetDBC("Map"); - printf("NAME %s\n", file->GetRecordById(608)->GetString(1).c_str()); -} - void MPQManager::InitializeDBC() { CurLocale = 0; @@ -54,6 +50,7 @@ void MPQManager::InitializeDBC() FILE* MPQManager::GetFile( std::string path ) { + ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL); MPQFile file(path.c_str()); if (file.isEof()) return NULL; diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h index 725e0168237..634c70cedeb 100644 --- a/src/tools/mesh_extractor/MPQManager.h +++ b/src/tools/mesh_extractor/MPQManager.h @@ -2,6 +2,7 @@ #define MPQ_MANAGER_H #include "MPQ.h" +#include "ace/Synch.h" class DBC; class MPQManager @@ -11,7 +12,6 @@ public: ~MPQManager() {} void Initialize(); - void LoadMaps(); FILE* GetFile(std::string path); DBC* GetDBC(std::string name); @@ -22,6 +22,8 @@ public: static char* Languages[]; protected: void InitializeDBC(); +private: + ACE_Thread_Mutex mutex; }; extern MPQManager* MPQHandler; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 7ae6afadb84..2884b998ac8 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -4,42 +4,73 @@ #include "Cache.h" #include "DBC.h" +#include + #include "Common.h" #include "LoginDatabase.h" +#include "Util.h" LoginDatabaseWorkerPool LoginDatabase; MPQManager* MPQHandler; CacheClass* Cache; -void ExtractAllMaps(uint32 onlyMap) +void ExtractAllMaps(std::set& mapIds, uint32 threads) { DBC* dbc = MPQHandler->GetDBC("Map"); for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) { uint32 mapId = (*itr)->Values[0]; - if (onlyMap && mapId != onlyMap) + + // Skip this map if a list of specific maps was provided and this one is not contained in it. + if (!mapIds.empty() && mapIds.find(mapId) == mapIds.end()) continue; + std::string name = (*itr)->GetString(1); WDT wdt("World\\maps\\" + name + "\\" + name + ".wdt"); if (!wdt.IsValid || wdt.IsGlobalModel) continue; printf("Building %s MapId %u\n", name.c_str(), mapId); - ContinentBuilder builder(name, mapId, &wdt); + ContinentBuilder builder(name, mapId, &wdt, threads); builder.Build(); } - /* - WDT wdt("World\\maps\\DalaranPrison\\DalaranPrison.wdt"); - if (!wdt.IsValid) - return; - printf("Model valid!\n"); - if (wdt.IsGlobalModel) +} + +bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapList) +{ + char* param = NULL; + for (int i = 1; i < argc; ++i) { - printf("Unsupported\n"); - return; + if (strcmp(argv[i], "--threads") == 0) + { + param = argv[++i]; + if (!param) + return false; + + threads = atoi(param); + printf("Using %i threads\n", threads); + } + if (strcmp(argv[i], "--maps") == 0) + { + param = argv[++i]; + if (!param) + return false; + std::string maps = std::string(param); + Tokens tokens(maps, ','); + + for (Tokens::iterator itr = tokens.begin(); itr != tokens.end(); ++itr) + mapList.insert(atoi(*itr)); + + printf("Extracting only provided list of maps (%u).\n", mapList.size()); + } } - ContinentBuilder builder("DalaranPrison", &wdt); - builder.Build(); - */ + return true; +} + +void PrintUsage() +{ + printf("MeshExtractor help.\n"); + printf("* Use \"--threads \" to specify threads, default to 4\n"); + printf("* Use \"--maps a,b,c,d,e\" to extract only the maps specified ( do not use spaces )\n"); } int main(int argc, char* argv[]) @@ -48,11 +79,16 @@ int main(int argc, char* argv[]) Cache = new CacheClass(); MPQHandler = new MPQManager(); MPQHandler->Initialize(); - MPQHandler->LoadMaps(); - uint32 onlyMap = 0; - if (argc == 2) - onlyMap = uint32(atoi(argv[1])); - ExtractAllMaps(onlyMap); + uint32 threads = 4; + std::set mapIds; + + if (!HandleArgs(argc, argv, threads, mapIds)) + { + PrintUsage(); + return -1; + } + + ExtractAllMaps(mapIds, threads); return 0; } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index baf1fa0375c..926d2591f1a 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -9,6 +9,8 @@ #include "RecastAlloc.h" #include "DetourNavMeshBuilder.h" +#include "ace/Synch.h" + TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0) { // Cell Size = TileSize / TileVoxelSize @@ -54,11 +56,6 @@ uint8* TileBuilder::Build() { adt = new ADT(Utils::GetAdtPath(World, X, Y)); adt->Read(); - if (!adt->Data) - { - delete adt; - return NULL; - } Cache->AdtCache.Insert(std::make_pair(X, Y), adt); } _Geometry->AddAdt(adt); @@ -234,7 +231,6 @@ uint8* TileBuilder::Build() DataSize = navDataSize; rcFreePolyMesh(pmesh); rcFreePolyMeshDetail(dmesh); - Cache->Clear(); return navData; } -- cgit v1.2.3 From 987436ceeac3c463a81d3b2cab05ff3c532dbbf8 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 29 Sep 2012 15:38:31 -0500 Subject: Tools/MeshExtractor: Get rid of some memory leaks --- src/tools/mesh_extractor/ChunkedData.cpp | 9 +++++++++ src/tools/mesh_extractor/ChunkedData.h | 1 + src/tools/mesh_extractor/DoodadHandler.cpp | 6 ++++++ src/tools/mesh_extractor/DoodadHandler.h | 2 ++ src/tools/mesh_extractor/LiquidHandler.h | 1 + src/tools/mesh_extractor/TileBuilder.cpp | 24 +++++++++++++++++++----- src/tools/mesh_extractor/TileBuilder.h | 2 ++ src/tools/mesh_extractor/WorldModelHandler.cpp | 8 +++++++- src/tools/mesh_extractor/WorldModelHandler.h | 1 + 9 files changed, 48 insertions(+), 6 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index 470b8b94f39..35b1bcd5af0 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -61,3 +61,12 @@ Chunk* ChunkedData::GetChunkByName( std::string name ) return Chunks[i]; return NULL; } + +ChunkedData::~ChunkedData() +{ + for (std::vector::iterator itr = Chunks.begin(); itr != Chunks.end(); ++itr) + delete *itr; + + Chunks.clear(); + fclose(Stream); +} diff --git a/src/tools/mesh_extractor/ChunkedData.h b/src/tools/mesh_extractor/ChunkedData.h index 6e102828222..d36d0868859 100644 --- a/src/tools/mesh_extractor/ChunkedData.h +++ b/src/tools/mesh_extractor/ChunkedData.h @@ -9,6 +9,7 @@ class ChunkedData public: ChunkedData(FILE* stream, uint32 maxLength, uint32 chunksHint = 300); ChunkedData(std::string file, uint32 chunksHint = 300); + ~ChunkedData(); int GetFirstIndex(std::string name); Chunk* GetChunkByName(std::string name); diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 28bb9da5f21..6604aebe73a 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -99,3 +99,9 @@ void DoodadHandler::InsertModelGeometry(const DoodadDefinition& def, Model* mode for (std::vector >::iterator itr = model->Triangles.begin(); itr != model->Triangles.end(); ++itr) Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_DOODAD, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); } + +DoodadHandler::~DoodadHandler() +{ + delete _definitions; + delete _paths; +} diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index aa7e3cac20d..2e00696f7e5 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -32,6 +32,8 @@ class DoodadHandler : public ObjectDataHandler { public: DoodadHandler(ADT* adt); + ~DoodadHandler(); + std::vector Vertices; std::vector > Triangles; bool IsSane() { return _definitions && _paths; } diff --git a/src/tools/mesh_extractor/LiquidHandler.h b/src/tools/mesh_extractor/LiquidHandler.h index 138b2da2ad9..6e8d0081adb 100644 --- a/src/tools/mesh_extractor/LiquidHandler.h +++ b/src/tools/mesh_extractor/LiquidHandler.h @@ -10,6 +10,7 @@ class LiquidHandler { public: LiquidHandler(ADT* adt); + ADT* Source; std::vector Vertices; std::vector > Triangles; diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 926d2591f1a..5c2c4faab80 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -225,16 +225,30 @@ uint8* TileBuilder::Build() uint8* navData; printf("[%02i,%02i] Creating the navmesh!\n", X, Y); bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); - if (result) + + // Free some memory + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + delete tilebMax; + delete tilebMin; + delete areas; + delete triangles; + delete vertices; + delete bbMax; + delete bbMin; + + if (result) { printf("[%02i,%02i] NavMesh created, size %i!\n", X, Y, navDataSize); DataSize = navDataSize; - rcFreePolyMesh(pmesh); - rcFreePolyMeshDetail(dmesh); return navData; } - rcFreePolyMesh(pmesh); - rcFreePolyMeshDetail(dmesh); return NULL; } + +TileBuilder::~TileBuilder() +{ + delete Context; + delete _Geometry; +} diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index f91a732f70c..e56b926e5a5 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -11,6 +11,8 @@ class TileBuilder { public: TileBuilder(std::string world, int x, int y, uint32 mapId); + ~TileBuilder(); + void CalculateTileBounds(float*& bmin, float*& bmax); uint8* Build(); diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index 636b06f6f73..edad6d1b6d8 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -24,7 +24,7 @@ WorldModelDefinition WorldModelDefinition::Read( FILE* file ) } -WorldModelHandler::WorldModelHandler( ADT* adt ) : ObjectDataHandler(adt) +WorldModelHandler::WorldModelHandler( ADT* adt ) : ObjectDataHandler(adt), _definitions(NULL), _paths(NULL) { if (!adt->HasObjectData) return; @@ -190,3 +190,9 @@ void WorldModelHandler::ReadModelPaths() _paths->push_back(Utils::ReadString(dataStream)); } } + +WorldModelHandler::~WorldModelHandler() +{ + delete _definitions; + delete _paths; +} diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h index daf0713ecd2..df5e3764eb5 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.h +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -29,6 +29,7 @@ class WorldModelHandler : public ObjectDataHandler { public: WorldModelHandler(ADT* adt); + ~WorldModelHandler(); std::vector Vertices; std::vector > Triangles; -- cgit v1.2.3 From 5c9e917e5e2a4c934aaa7d061624a46ff4269c8f Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 29 Sep 2012 16:19:33 -0500 Subject: Core/MMaps: Removed an incorrect call to GetHeight Tools/MeshExtractor: Fixed a crash caused by calling fclose in a NULL stream --- src/server/game/Movement/PathGenerator.cpp | 6 +----- src/tools/mesh_extractor/ChunkedData.cpp | 3 ++- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'src/tools') diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 9635399e71f..6e765b1ee27 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -58,12 +58,8 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo if (!Trinity::IsValidMapCoord(destX, destY, destZ) || !Trinity::IsValidMapCoord(x, y, z)) return false; - float newDestZ = _sourceUnit->GetBaseMap()->GetHeight(_sourceUnit->GetPhaseMask(), x, y, z, true, MAX_FALL_DISTANCE); - if (newDestZ <= INVALID_HEIGHT) - return false; - Vector3 oldDest = GetEndPosition(); - Vector3 dest(destX, destY, newDestZ); + Vector3 dest(destX, destY, destZ); SetEndPosition(dest); Vector3 start(x, y, z); diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index 35b1bcd5af0..4c59217ed33 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -68,5 +68,6 @@ ChunkedData::~ChunkedData() delete *itr; Chunks.clear(); - fclose(Stream); + if (Stream) + fclose(Stream); } -- cgit v1.2.3 From 14b304d4f726aeaf5f48fdac4cd9ce8aad66c5c9 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 30 Sep 2012 08:27:56 -0500 Subject: Tools/MeshExtractor: * Removed the cache of ADTs * Add the correct geometry for neighbor ADTs * Fixes more crashes * Calculate the correct bounds for the map tiles. --- src/tools/mesh_extractor/ADT.cpp | 1 + src/tools/mesh_extractor/Cache.h | 11 +++--- src/tools/mesh_extractor/ContinentBuilder.cpp | 57 +++++++++++++++++++++++---- src/tools/mesh_extractor/TileBuilder.cpp | 30 ++++++-------- 4 files changed, 68 insertions(+), 31 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp index c564d7193cf..1684d0636f4 100644 --- a/src/tools/mesh_extractor/ADT.cpp +++ b/src/tools/mesh_extractor/ADT.cpp @@ -2,6 +2,7 @@ #include "DoodadHandler.h" #include "LiquidHandler.h" #include "WorldModelHandler.h" +#include "Cache.h" ADT::ADT( std::string file ) : ObjectData(NULL), Data(NULL), _DoodadHandler(NULL), _WorldModelHandler(NULL), _LiquidHandler(NULL), HasObjectData(false) { diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 49e268ec507..36bf4a7a693 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -7,7 +7,6 @@ class WorldModelRoot; class Model; -class ADT; template class GenericCache @@ -19,21 +18,23 @@ public: void Insert(K key, T* val) { + ACE_GUARD(ACE_Thread_Mutex, g, mutex); + if (_items.size() > FlushLimit) Clear(); - ACE_GUARD(ACE_Thread_Mutex, g, mutex); _items[key] = val; } T* Get(K key) { + ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL); typename std::map::iterator itr = _items.find(key); if (itr != _items.end()) return itr->second; return NULL; } - void Clear() + void Clear() { for (typename std::map::iterator itr = _items.begin(); itr != _items.end(); ++itr) delete itr->second; @@ -50,10 +51,10 @@ public: CacheClass() {} GenericCache ModelCache; GenericCache WorldModelCache; - GenericCache, ADT> AdtCache; + void Clear() { - AdtCache.Clear(); + } }; diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 96f9085de8c..cdfe0ca050a 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -5,6 +5,7 @@ #include "DetourNavMesh.h" #include "Cache.h" #include "ace/Task.h" +#include "Recast.h" class BuilderThread : public ACE_Task { @@ -21,18 +22,24 @@ public: printf("[%02i,%02i] Building tile\n", X, Y); TileBuilder builder(Continent, X, Y, MapId); char buff[100]; - sprintf(buff, "%03u%02u%02u.mmtile", MapId, X, Y); + sprintf(buff, "mmaps/%03u%02u%02u.mmtile", MapId, X, Y); FILE* f = fopen(buff, "r"); if (f) // Check if file already exists. { + printf("[%02i,%02i] Tile skipped, file already exists\n", X, Y); fclose(f); Free = true; - return 0; + return 1; } uint8* nav = builder.Build(); if (nav) { f = fopen(buff, "wb"); + if (!f) + { + printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); + return -1; + } MmapTileHeader header; header.size = builder.DataSize; fwrite(&header, sizeof(MmapTileHeader), 1, f); @@ -48,17 +55,52 @@ public: bool Free; }; +void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) +{ + // this is for elevation + if (verts && vertCount) + rcCalcBounds(verts, vertCount, bmin, bmax); + else + { + bmin[1] = FLT_MIN; + bmax[1] = FLT_MAX; + } + + // this is for width and depth + bmax[0] = (32 - int(tileX)) * Constants::TileSize; + bmax[2] = (32 - int(tileY)) * Constants::TileSize; + bmin[0] = bmax[0] - Constants::TileSize; + bmin[2] = bmax[2] - Constants::TileSize; +} + void ContinentBuilder::Build() { char buff[50]; - sprintf(buff, "%03u.mmap", MapId); + sprintf(buff, "mmaps/%03u.mmap", MapId); FILE* mmap = fopen(buff, "wb"); + if (!mmap) + { + printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); + return; + } + + int tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0; + for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) + { + tileXMax = std::max(itr->X, tileXMax); + tileXMin = std::min(itr->X, tileXMin); + + tileYMax = std::max(itr->Y, tileYMax); + tileYMin = std::min(itr->Y, tileYMin); + } + + float bmin[3], bmax[3]; + getTileBounds(tileXMax, tileYMax, NULL, 0, bmin, bmax); + dtNavMeshParams params; params.maxPolys = 32768; - params.maxTiles = 4096; - params.orig[0] = -17066.666f; - params.orig[1] = 0.0f; - params.orig[2] = -17066.666f; + params.maxTiles = TileMap->TileTable.size(); + rcVcopy(params.orig, bmin); params.tileHeight = 533.33333f; params.tileWidth = 533.33333f; fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); @@ -66,6 +108,7 @@ void ContinentBuilder::Build() std::vector Threads; for (uint32 i = 0; i < NumberOfThreads; ++i) Threads.push_back(new BuilderThread()); + printf("Map %s ( %i ) has %i tiles. Building them with %i threads\n", Continent.c_str(), MapId, TileMap->TileTable.size(), NumberOfThreads); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { bool next = false; diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 5c2c4faab80..83137258710 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -51,14 +51,10 @@ uint8* TileBuilder::Build() { _Geometry = new Geometry(); _Geometry->Transform = true; - ADT* adt = Cache->AdtCache.Get(std::make_pair(X, Y)); - if (!adt) - { - adt = new ADT(Utils::GetAdtPath(World, X, Y)); - adt->Read(); - Cache->AdtCache.Insert(std::make_pair(X, Y), adt); - } + ADT* adt = new ADT(Utils::GetAdtPath(World, X, Y)); + adt->Read(); _Geometry->AddAdt(adt); + delete adt; if (_Geometry->Vertices.empty() && _Geometry->Triangles.empty()) return NULL; @@ -77,20 +73,16 @@ uint8* TileBuilder::Build() if (tx == X && ty == Y) continue; - ADT* _adt = Cache->AdtCache.Get(std::make_pair(tx, ty)); - if (!_adt) + ADT* _adt = new ADT(Utils::GetAdtPath(World, tx, ty)); + // If this condition is met, it means that this wdt does not contain the ADT + if (!_adt->Data->Stream) { - _adt = new ADT(Utils::GetAdtPath(World, tx, ty)); - // If this condition is met, it means that this wdt does not contain the ADT - if (!_adt->Data->Stream) - { - delete _adt; - continue; - } - _adt->Read(); - Cache->AdtCache.Insert(std::make_pair(tx, ty), _adt); + delete _adt; + continue; } - _Geometry->AddAdt(adt); + _adt->Read(); + _Geometry->AddAdt(_adt); + delete _adt; } } uint32 numVerts = _Geometry->Vertices.size(); -- cgit v1.2.3 From d63e1276d602b0172f2d32abe85ec718a7bc7912 Mon Sep 17 00:00:00 2001 From: Nay Date: Sun, 30 Sep 2012 15:38:03 +0100 Subject: Tools/MeshExtractor: tabs2spaces --- src/tools/mesh_extractor/ChunkedData.cpp | 12 +++++------ src/tools/mesh_extractor/ChunkedData.h | 2 +- src/tools/mesh_extractor/DoodadHandler.cpp | 4 ++-- src/tools/mesh_extractor/DoodadHandler.h | 2 +- src/tools/mesh_extractor/MeshExtractor.cpp | 2 +- src/tools/mesh_extractor/TileBuilder.cpp | 30 +++++++++++++------------- src/tools/mesh_extractor/TileBuilder.h | 2 +- src/tools/mesh_extractor/WorldModelHandler.cpp | 4 ++-- src/tools/mesh_extractor/WorldModelHandler.h | 2 +- 9 files changed, 30 insertions(+), 30 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index 4c59217ed33..725a6f45637 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -64,10 +64,10 @@ Chunk* ChunkedData::GetChunkByName( std::string name ) ChunkedData::~ChunkedData() { - for (std::vector::iterator itr = Chunks.begin(); itr != Chunks.end(); ++itr) - delete *itr; - - Chunks.clear(); - if (Stream) - fclose(Stream); + for (std::vector::iterator itr = Chunks.begin(); itr != Chunks.end(); ++itr) + delete *itr; + + Chunks.clear(); + if (Stream) + fclose(Stream); } diff --git a/src/tools/mesh_extractor/ChunkedData.h b/src/tools/mesh_extractor/ChunkedData.h index d36d0868859..e23648c845e 100644 --- a/src/tools/mesh_extractor/ChunkedData.h +++ b/src/tools/mesh_extractor/ChunkedData.h @@ -9,7 +9,7 @@ class ChunkedData public: ChunkedData(FILE* stream, uint32 maxLength, uint32 chunksHint = 300); ChunkedData(std::string file, uint32 chunksHint = 300); - ~ChunkedData(); + ~ChunkedData(); int GetFirstIndex(std::string name); Chunk* GetChunkByName(std::string name); diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 6604aebe73a..363f07b4578 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -102,6 +102,6 @@ void DoodadHandler::InsertModelGeometry(const DoodadDefinition& def, Model* mode DoodadHandler::~DoodadHandler() { - delete _definitions; - delete _paths; + delete _definitions; + delete _paths; } diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index 2e00696f7e5..a212b032d1d 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -32,7 +32,7 @@ class DoodadHandler : public ObjectDataHandler { public: DoodadHandler(ADT* adt); - ~DoodadHandler(); + ~DoodadHandler(); std::vector Vertices; std::vector > Triangles; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 2884b998ac8..3dde9ac36f5 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -89,6 +89,6 @@ int main(int argc, char* argv[]) } ExtractAllMaps(mapIds, threads); - return 0; + return 0; } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 83137258710..e3694541be8 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -217,19 +217,19 @@ uint8* TileBuilder::Build() uint8* navData; printf("[%02i,%02i] Creating the navmesh!\n", X, Y); bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); - - // Free some memory - rcFreePolyMesh(pmesh); - rcFreePolyMeshDetail(dmesh); - delete tilebMax; - delete tilebMin; - delete areas; - delete triangles; - delete vertices; - delete bbMax; - delete bbMin; - - if (result) + + // Free some memory + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + delete tilebMax; + delete tilebMin; + delete areas; + delete triangles; + delete vertices; + delete bbMax; + delete bbMin; + + if (result) { printf("[%02i,%02i] NavMesh created, size %i!\n", X, Y, navDataSize); DataSize = navDataSize; @@ -241,6 +241,6 @@ uint8* TileBuilder::Build() TileBuilder::~TileBuilder() { - delete Context; - delete _Geometry; + delete Context; + delete _Geometry; } diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index e56b926e5a5..2ec45811676 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -11,7 +11,7 @@ class TileBuilder { public: TileBuilder(std::string world, int x, int y, uint32 mapId); - ~TileBuilder(); + ~TileBuilder(); void CalculateTileBounds(float*& bmin, float*& bmax); uint8* Build(); diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index edad6d1b6d8..a0977c398c4 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -193,6 +193,6 @@ void WorldModelHandler::ReadModelPaths() WorldModelHandler::~WorldModelHandler() { - delete _definitions; - delete _paths; + delete _definitions; + delete _paths; } diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h index df5e3764eb5..cccedfa60fb 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.h +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -29,7 +29,7 @@ class WorldModelHandler : public ObjectDataHandler { public: WorldModelHandler(ADT* adt); - ~WorldModelHandler(); + ~WorldModelHandler(); std::vector Vertices; std::vector > Triangles; -- cgit v1.2.3 From 4c3266c7af5f5840a212d46bf068a793150b34fc Mon Sep 17 00:00:00 2001 From: Nay Date: Sun, 30 Sep 2012 15:52:10 +0100 Subject: Tools&Core: Whitespace cleanup No one likes whitespace, right? --- src/server/game/Maps/Map.cpp | 2 +- src/server/game/Movement/MotionMaster.cpp | 2 +- .../MovementGenerators/TargetedMovementGenerator.cpp | 2 +- src/server/game/Movement/PathGenerator.cpp | 4 ++-- src/server/scripts/Commands/cs_mmaps.cpp | 4 ++-- src/tools/map_extractor/System.cpp | 2 +- src/tools/mesh_extractor/ADT.cpp | 2 +- src/tools/mesh_extractor/ADT.h | 2 +- src/tools/mesh_extractor/Cache.h | 10 +++++----- src/tools/mesh_extractor/ChunkedData.cpp | 4 ++-- src/tools/mesh_extractor/Geometry.cpp | 4 ++-- src/tools/mesh_extractor/Geometry.h | 2 +- src/tools/mesh_extractor/LiquidHandler.cpp | 2 +- src/tools/mesh_extractor/MPQ.cpp | 10 +++++----- src/tools/mesh_extractor/MPQManager.cpp | 2 +- src/tools/mesh_extractor/MPQManager.h | 2 +- src/tools/mesh_extractor/MapChunk.h | 2 +- src/tools/mesh_extractor/MeshExtractor.cpp | 2 +- src/tools/mesh_extractor/ObjectDataHandler.h | 2 +- src/tools/mesh_extractor/TileBuilder.cpp | 14 +++++++------- src/tools/mesh_extractor/Utils.cpp | 2 +- src/tools/mesh_extractor/Utils.h | 4 ++-- src/tools/mesh_extractor/WDT.cpp | 2 +- src/tools/mesh_extractor/WorldModelHandler.cpp | 2 +- src/tools/mmaps_generator/MapBuilder.cpp | 10 +++++----- src/tools/mmaps_generator/TerrainBuilder.cpp | 2 +- 26 files changed, 49 insertions(+), 49 deletions(-) (limited to 'src/tools') diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index ae192f16080..25ffc1d19f2 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -123,7 +123,7 @@ bool Map::ExistVMap(uint32 mapid, int gx, int gy) void Map::LoadMMap(int gx, int gy) { bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gx, gy); - + if (mmapLoadResult) sLog->outInfo(LOG_FILTER_MAPS, "MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); else diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 34be779a8b7..386a95fa838 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -428,7 +428,7 @@ void MotionMaster::MoveCharge(PathGenerator path, float speed, uint32 id) Vector3 dest = path.GetActualEndPosition(); MoveCharge(dest.x, dest.y, dest.z); - + Movement::MoveSplineInit init(_owner); init.MovebyPath(path.GetPath()); init.SetVelocity(speed); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index c275c33032f..7a6611ed2ca 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -124,7 +124,7 @@ bool TargetedMovementGeneratorMedium::Update(T* owner, const uint32& time_d D::_clearUnitStateMove(owner); return true; } - + // prevent movement while casting spells with cast time or channel time if (owner->HasUnitState(UNIT_STATE_CASTING)) { diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 6e765b1ee27..3495c4d1218 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -469,7 +469,7 @@ void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoin _pathPoints[i] = Vector3(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]); NormalizePath(); - + // first point is always our current location - we need the next one SetActualEndPosition(_pathPoints[pointCount-1]); @@ -515,7 +515,7 @@ void PathGenerator::BuildShortcut() _pathPoints[1] = GetActualEndPosition(); NormalizePath(); - + _type = PATHFIND_SHORTCUT; } diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index be2d52b5925..c3f757614e2 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -152,7 +152,7 @@ public: // navmesh poly -> navmesh tile location dtQueryFilter filter = dtQueryFilter(); - dtPolyRef polyRef = INVALID_POLYREF; + dtPolyRef polyRef = INVALID_POLYREF; navmeshquery->findNearestPoly(location, extents, &filter, &polyRef, NULL); if (polyRef == INVALID_POLYREF) @@ -252,7 +252,7 @@ public: CellCoord pair(Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY()) ); Cell cell(pair); cell.SetNoCreate(); - + std::list creatureList; Trinity::AnyUnitInObjectRangeCheck go_check(object, radius); diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index 552bab30d50..2e117934679 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -852,7 +852,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, hasHoles = true; } } - + if (hasHoles) map.holesSize = sizeof(holes); else diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp index 1684d0636f4..a6c080cf0b0 100644 --- a/src/tools/mesh_extractor/ADT.cpp +++ b/src/tools/mesh_extractor/ADT.cpp @@ -18,7 +18,7 @@ ADT::~ADT() { delete ObjectData; delete Data; - + for (std::vector::iterator itr = MapChunks.begin(); itr != MapChunks.end(); ++itr) delete *itr; diff --git a/src/tools/mesh_extractor/ADT.h b/src/tools/mesh_extractor/ADT.h index 096f491eed8..133596eb024 100644 --- a/src/tools/mesh_extractor/ADT.h +++ b/src/tools/mesh_extractor/ADT.h @@ -12,7 +12,7 @@ class ADT public: ADT(std::string file); ~ADT(); - + void Read(); ChunkedData* ObjectData; diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 36bf4a7a693..90e2c138376 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -15,7 +15,7 @@ public: GenericCache() {} static const int32 FlushLimit = 1000; - + void Insert(K key, T* val) { ACE_GUARD(ACE_Thread_Mutex, g, mutex); @@ -35,10 +35,10 @@ public: } void Clear() - { - for (typename std::map::iterator itr = _items.begin(); itr != _items.end(); ++itr) + { + for (typename std::map::iterator itr = _items.begin(); itr != _items.end(); ++itr) delete itr->second; - _items.clear(); + _items.clear(); } private: std::map _items; @@ -54,7 +54,7 @@ public: void Clear() { - + } }; diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index 725a6f45637..4431993e3d1 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -4,7 +4,7 @@ #include -ChunkedData::ChunkedData( FILE* stream, uint32 maxLength, uint32 chunksHint /*= 300*/ ) : +ChunkedData::ChunkedData( FILE* stream, uint32 maxLength, uint32 chunksHint /*= 300*/ ) : Stream(stream) { if (!Stream) @@ -66,7 +66,7 @@ ChunkedData::~ChunkedData() { for (std::vector::iterator itr = Chunks.begin(); itr != Chunks.end(); ++itr) delete *itr; - + Chunks.clear(); if (Stream) fclose(Stream); diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp index 2fbe99e3211..2fc470e8e9f 100644 --- a/src/tools/mesh_extractor/Geometry.cpp +++ b/src/tools/mesh_extractor/Geometry.cpp @@ -63,7 +63,7 @@ void Geometry::AddData( std::vector& verts, std::vector::iterator itr = verts.begin(); itr != verts.end(); ++itr) Vertices.push_back(Transform ? Utils::ToRecast(*itr) : *itr); - + for (std::vector >::iterator itr = tris.begin(); itr != tris.end(); ++itr) Triangles.push_back(Triangle(itr->Type, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); } @@ -116,7 +116,7 @@ void Geometry::AddAdt( ADT* adt ) if (!adt->_DoodadHandler->Triangles.empty()) AddData(adt->_DoodadHandler->Vertices, adt->_DoodadHandler->Triangles); - + if (!adt->_WorldModelHandler->Triangles.empty()) AddData(adt->_WorldModelHandler->Vertices, adt->_WorldModelHandler->Triangles); } diff --git a/src/tools/mesh_extractor/Geometry.h b/src/tools/mesh_extractor/Geometry.h index 9593c98044e..e445234dd12 100644 --- a/src/tools/mesh_extractor/Geometry.h +++ b/src/tools/mesh_extractor/Geometry.h @@ -9,7 +9,7 @@ class Geometry { public: Geometry(); - + void CalculateBoundingBox(float*& min, float*& max); void CalculateMinMaxHeight(float& min, float& max); void AddData(std::vector& verts, std::vector >& tris); diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index 9a40e08b73a..5b998d75db9 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -20,7 +20,7 @@ void LiquidHandler::HandleNewLiquid() MCNKData.reserve(256); for (int i = 0; i < 256; i++) header[i] = H2OHeader::Read(stream); - + for (int i = 0; i < 256; i++) { H2OHeader h = header[i]; diff --git a/src/tools/mesh_extractor/MPQ.cpp b/src/tools/mesh_extractor/MPQ.cpp index fbae56cd7a0..699b0a5014c 100644 --- a/src/tools/mesh_extractor/MPQ.cpp +++ b/src/tools/mesh_extractor/MPQ.cpp @@ -7,9 +7,9 @@ MPQArchive::MPQArchive(const char* filename) { int result = libmpq__archive_open(&mpq_a, filename, -1); printf("Opening %s\n", filename); - if (result) + if (result) { - switch (result) + switch (result) { case LIBMPQ_ERROR_OPEN : printf("Error opening archive '%s': Does file really exist?\n", filename); @@ -46,7 +46,7 @@ eof(false), buffer(0), pointer(0), size(0) mpq_archive* mpq_a = (*i)->mpq_a; uint32_t filenum; - if(libmpq__file_number(mpq_a, filename, &filenum)) + if(libmpq__file_number(mpq_a, filename, &filenum)) continue; libmpq__off_t transferred; libmpq__file_unpacked_size(mpq_a, filenum, &size); @@ -72,7 +72,7 @@ eof(false), buffer(0), pointer(0), size(0) size_t MPQFile::Read(void* dest, size_t bytes) { - if (eof) + if (eof) return 0; size_t rpos = pointer + bytes; @@ -102,7 +102,7 @@ void MPQFile::seekRelative(int offset) void MPQFile::close() { - if (buffer) + if (buffer) delete[] buffer; buffer = 0; eof = true; diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 5ea6198e76d..608eef1547a 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -5,7 +5,7 @@ #include "ace/Synch.h" -char* MPQManager::Files[] = { +char* MPQManager::Files[] = { "common.MPQ", "common-2.MPQ", "expansion.MPQ", diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h index 634c70cedeb..0050dc5218a 100644 --- a/src/tools/mesh_extractor/MPQManager.h +++ b/src/tools/mesh_extractor/MPQManager.h @@ -10,7 +10,7 @@ class MPQManager public: MPQManager() {} ~MPQManager() {} - + void Initialize(); FILE* GetFile(std::string path); DBC* GetDBC(std::string name); diff --git a/src/tools/mesh_extractor/MapChunk.h b/src/tools/mesh_extractor/MapChunk.h index 61dcabac9b0..e7d835ae0e3 100644 --- a/src/tools/mesh_extractor/MapChunk.h +++ b/src/tools/mesh_extractor/MapChunk.h @@ -10,7 +10,7 @@ class MapChunk { public: MapChunk(ADT* _adt, Chunk* chunk); - + void GenerateTriangles(); void GenerateVertices(FILE* stream); static bool HasHole(uint32 map, int x, int y); diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 3dde9ac36f5..423095b22ca 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -56,7 +56,7 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis return false; std::string maps = std::string(param); Tokens tokens(maps, ','); - + for (Tokens::iterator itr = tokens.begin(); itr != tokens.end(); ++itr) mapList.insert(atoi(*itr)); diff --git a/src/tools/mesh_extractor/ObjectDataHandler.h b/src/tools/mesh_extractor/ObjectDataHandler.h index 834bf66bcfb..75b4e45700c 100644 --- a/src/tools/mesh_extractor/ObjectDataHandler.h +++ b/src/tools/mesh_extractor/ObjectDataHandler.h @@ -7,7 +7,7 @@ class ObjectDataHandler { public: ObjectDataHandler(ADT* _adt) : Source(_adt) {} - + void ProcessMapChunk(MapChunk* chunk); virtual void ProcessInternal(ChunkedData* data) = 0; ADT* Source; diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index e3694541be8..0c775b9b8c9 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -15,7 +15,7 @@ TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geome { // Cell Size = TileSize / TileVoxelSize // 1800 = TileVoxelSize - Config.cs = Constants::TileSize / 1800; + Config.cs = Constants::TileSize / 1800; // Cell Height Config.ch = 0.3f; // Min Region Area = 6^2 @@ -72,7 +72,7 @@ uint8* TileBuilder::Build() // don't load main tile again if (tx == X && ty == Y) continue; - + ADT* _adt = new ADT(Utils::GetAdtPath(World, tx, ty)); // If this condition is met, it means that this wdt does not contain the ADT if (!_adt->Data->Stream) @@ -104,7 +104,7 @@ uint8* TileBuilder::Build() rcCreateHeightfield(Context, *hf, width, width, bbMin, bbMax, Config.cs, Config.ch); rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); - + printf("[%02i,%02i] Triangles rasterized!\n", X, Y); // Once all geometry is rasterized, we do initial pass of filtering to @@ -113,7 +113,7 @@ uint8* TileBuilder::Build() rcFilterLowHangingWalkableObstacles(Context, Config.walkableClimb, *hf); rcFilterLedgeSpans(Context, Config.walkableHeight, Config.walkableClimb, *hf); rcFilterWalkableLowHeightSpans(Context, Config.walkableHeight, *hf); - + printf("[%02i,%02i] Filtering done!\n", X, Y); // Compact the heightfield so that it is faster to handle from now on. @@ -132,13 +132,13 @@ uint8* TileBuilder::Build() rcBuildDistanceField(Context, *chf); // Partition the walkable surface into simple regions without holes. rcBuildRegions(Context, *chf, Config.borderSize, Config.minRegionArea, Config.mergeRegionArea); - + printf("[%02i,%02i] Regions built!\n", X, Y); // Create contours. rcContourSet* cset = rcAllocContourSet(); rcBuildContours(Context, *chf, Config.maxSimplificationError, Config.maxEdgeLen, *cset); - + // Build polygon navmesh from the contours. rcPolyMesh* pmesh = rcAllocPolyMesh(); rcBuildPolyMesh(Context, *cset, Config.maxVertsPerPoly, *pmesh); @@ -217,7 +217,7 @@ uint8* TileBuilder::Build() uint8* navData; printf("[%02i,%02i] Creating the navmesh!\n", X, Y); bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); - + // Free some memory rcFreePolyMesh(pmesh); rcFreePolyMeshDetail(dmesh); diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 2f07bd20080..3db387bc81a 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -133,7 +133,7 @@ Vector3 Utils::VectorTransform( Vector3 vec, G3D::Matrix4 matrix ) std::string Utils::GetPathBase( std::string path ) { - int lastIndex = path.find_last_of("."); + int lastIndex = path.find_last_of("."); if (lastIndex != std::string::npos) return path.substr(0, lastIndex); return path; diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index c247169df73..c9d2746b7d8 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -551,8 +551,8 @@ public: static G3D::Matrix4 GetTransformation(IDefinition def); /// They say its better to declare template functions in the header files. template - static std::string ToString(T val) - { + static std::string ToString(T val) + { std::stringstream ss; ss << val; return ss.str(); diff --git a/src/tools/mesh_extractor/WDT.cpp b/src/tools/mesh_extractor/WDT.cpp index c06d8ac9677..f0c3091c04e 100644 --- a/src/tools/mesh_extractor/WDT.cpp +++ b/src/tools/mesh_extractor/WDT.cpp @@ -17,7 +17,7 @@ void WDT::ReadGlobalModel() Chunk* defChunk = Data->GetChunkByName("MODF"); if (!fileChunk || !defChunk) return; - + IsGlobalModel = true; ModelDefinition = WorldModelDefinition::Read(defChunk->GetStream()); ModelFile = Utils::ReadString(fileChunk->GetStream()); diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index a0977c398c4..b98a7aae826 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -103,7 +103,7 @@ void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::v break; instances.push_back(root->DoodadInstances[i]); } - + for (std::vector::iterator instance = instances.begin(); instance != instances.end(); ++instance) { Model* model = Cache->ModelCache.Get(instance->File); diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 69ffad94eb7..754bced903c 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -161,7 +161,7 @@ namespace MMAP void MapBuilder::buildAllMaps(int threads) { std::vector _threads; - + for (int i = 0; i < threads; ++i) _threads.push_back(new BuilderThread(this)); @@ -241,7 +241,7 @@ namespace MMAP minX = 32 - bmax[0] / GRID_SIZE; minY = 32 - bmax[2] / GRID_SIZE; } - + void MapBuilder::buildMeshFromFile(char* name) { FILE* file = fopen(name, "rb"); @@ -253,7 +253,7 @@ namespace MMAP fread(&mapId, sizeof(int), 1, file); fread(&tileX, sizeof(int), 1, file); fread(&tileY, sizeof(int), 1, file); - + dtNavMesh* navMesh = NULL; buildNavMesh(mapId, navMesh); if (!navMesh) @@ -270,7 +270,7 @@ namespace MMAP float* verts = new float[verticesCount]; int* inds = new int[indicesCount]; - + fread(verts, sizeof(float), verticesCount, file); fread(inds, sizeof(int), indicesCount, file); @@ -648,7 +648,7 @@ namespace MMAP tile.chf = NULL; rcFreeContourSet(tile.cset); tile.cset = NULL; - + if (tile.pmesh) { pmmerge[nmerge] = tile.pmesh; diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 7ee4dc7f46c..0159219c110 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -779,7 +779,7 @@ namespace MMAP continue; std::pair val; val.first = t[i]; - + index = val.first; val.second = count; -- cgit v1.2.3 From fa57ecddac2409307375a01c4214080c3ca1d44a Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 30 Sep 2012 15:47:39 -0500 Subject: Tools/MeshExtractor: * Added the option to output debug information on ADTs. * Tweaked rcConfig options and fixed some mistakes about it. * Generate 64 tiles per ADT, this should give us a more accurate mesh on large maps. * Speedup compilation time by moving function bodies from Utils.h to Utils.cpp --- src/tools/mesh_extractor/ADT.cpp | 1 - src/tools/mesh_extractor/ContinentBuilder.cpp | 17 +- src/tools/mesh_extractor/ContinentBuilder.h | 2 +- src/tools/mesh_extractor/MeshExtractor.cpp | 23 ++- src/tools/mesh_extractor/TileBuilder.cpp | 46 +++-- src/tools/mesh_extractor/TileBuilder.h | 2 +- src/tools/mesh_extractor/Utils.cpp | 250 ++++++++++++++++++++++++++ src/tools/mesh_extractor/Utils.h | 250 ++------------------------ 8 files changed, 319 insertions(+), 272 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp index a6c080cf0b0..8d7dce9ae11 100644 --- a/src/tools/mesh_extractor/ADT.cpp +++ b/src/tools/mesh_extractor/ADT.cpp @@ -2,7 +2,6 @@ #include "DoodadHandler.h" #include "LiquidHandler.h" #include "WorldModelHandler.h" -#include "Cache.h" ADT::ADT( std::string file ) : ObjectData(NULL), Data(NULL), _DoodadHandler(NULL), _WorldModelHandler(NULL), _LiquidHandler(NULL), HasObjectData(false) { diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index cdfe0ca050a..984f6170357 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -7,13 +7,14 @@ #include "ace/Task.h" #include "Recast.h" -class BuilderThread : public ACE_Task +class BuilderThread : public ACE_Task_Base { private: int X, Y, MapId; std::string Continent; + bool debug; public: - BuilderThread() : Free(true) {} + BuilderThread(bool deb) : Free(true), debug(deb) {} void SetData(int x, int y, int map, std::string cont) { X = x; Y = y; MapId = map; Continent = cont; } int svc() @@ -22,23 +23,23 @@ public: printf("[%02i,%02i] Building tile\n", X, Y); TileBuilder builder(Continent, X, Y, MapId); char buff[100]; - sprintf(buff, "mmaps/%03u%02u%02u.mmtile", MapId, X, Y); + sprintf(buff, "mmaps/%03u%02u%02u.mmtile", MapId, Y, X); FILE* f = fopen(buff, "r"); if (f) // Check if file already exists. { printf("[%02i,%02i] Tile skipped, file already exists\n", X, Y); fclose(f); Free = true; - return 1; + return 0; } - uint8* nav = builder.Build(); + uint8* nav = builder.Build(debug); if (nav) { f = fopen(buff, "wb"); if (!f) { printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); - return -1; + return 0; } MmapTileHeader header; header.size = builder.DataSize; @@ -73,7 +74,7 @@ void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, floa bmin[2] = bmax[2] - Constants::TileSize; } -void ContinentBuilder::Build() +void ContinentBuilder::Build(bool debug) { char buff[50]; sprintf(buff, "mmaps/%03u.mmap", MapId); @@ -107,7 +108,7 @@ void ContinentBuilder::Build() fclose(mmap); std::vector Threads; for (uint32 i = 0; i < NumberOfThreads; ++i) - Threads.push_back(new BuilderThread()); + Threads.push_back(new BuilderThread(debug)); printf("Map %s ( %i ) has %i tiles. Building them with %i threads\n", Continent.c_str(), MapId, TileMap->TileTable.size(), NumberOfThreads); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h index d3da984595d..c923498fc5e 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -8,7 +8,7 @@ class ContinentBuilder { public: ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : MapId(mapId), Continent(continent), TileMap(wdt), NumberOfThreads(tn) {} - void Build(); + void Build(bool debug); private: std::string Continent; WDT* TileMap; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 423095b22ca..9d88fcdcdfc 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -14,7 +14,7 @@ LoginDatabaseWorkerPool LoginDatabase; MPQManager* MPQHandler; CacheClass* Cache; -void ExtractAllMaps(std::set& mapIds, uint32 threads) +void ExtractAllMaps(std::set& mapIds, uint32 threads, bool debug) { DBC* dbc = MPQHandler->GetDBC("Map"); for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) @@ -31,11 +31,11 @@ void ExtractAllMaps(std::set& mapIds, uint32 threads) continue; printf("Building %s MapId %u\n", name.c_str(), mapId); ContinentBuilder builder(name, mapId, &wdt, threads); - builder.Build(); + builder.Build(debug); } } -bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapList) +bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapList, bool& debugOutput) { char* param = NULL; for (int i = 1; i < argc; ++i) @@ -62,6 +62,14 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis printf("Extracting only provided list of maps (%u).\n", mapList.size()); } + if (strcmp(argv[i], "--debug") == 0) + { + param = argv[++i]; + if (!param) + return false; + debugOutput = atoi(param); + printf("Output will contain debug information (.obj files)\n"); + } } return true; } @@ -71,6 +79,7 @@ void PrintUsage() printf("MeshExtractor help.\n"); printf("* Use \"--threads \" to specify threads, default to 4\n"); printf("* Use \"--maps a,b,c,d,e\" to extract only the maps specified ( do not use spaces )\n"); + printf("* Use \"--debug 1\" to generate debug information of the tiles.\n"); } int main(int argc, char* argv[]) @@ -81,14 +90,14 @@ int main(int argc, char* argv[]) MPQHandler->Initialize(); uint32 threads = 4; std::set mapIds; + bool debug = false; - if (!HandleArgs(argc, argv, threads, mapIds)) + if (!HandleArgs(argc, argv, threads, mapIds, debug)) { PrintUsage(); return -1; } - ExtractAllMaps(mapIds, threads); + ExtractAllMaps(mapIds, threads, debug); return 0; -} - +} \ No newline at end of file diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 0c775b9b8c9..54b9e4865cd 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -17,20 +17,22 @@ TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geome // 1800 = TileVoxelSize Config.cs = Constants::TileSize / 1800; // Cell Height - Config.ch = 0.3f; - // Min Region Area = 6^2 - Config.minRegionArea = 36; - // Merge Region Area = 12^2 - Config.mergeRegionArea = 144; + Config.ch = 0.4f; + // Min Region Area = 20^2 + Config.minRegionArea = 20*20; + // Merge Region Area = 40^2 + Config.mergeRegionArea = 40*40; + Config.tileSize = Constants::TileSize / 4; Config.walkableSlopeAngle = 50.0f; Config.detailSampleDist = 3.0f; Config.detailSampleMaxError = 1.25f; Config.walkableClimb = 1.0f / Config.ch; - Config.walkableHeight = 2.1f / Config.ch; - Config.walkableRadius = 0.6f / Config.cs; + Config.walkableHeight = 1.652778f / Config.ch; + Config.walkableRadius = 0.2951389f / Config.cs; Config.maxEdgeLen = Config.walkableRadius * 8; - Config.borderSize = Config.walkableRadius + 8; - Config.width = 1800; + Config.borderSize = Config.walkableRadius + 4; + Config.width = 1800 + Config.borderSize * 2; + Config.height = 1800 + Config.borderSize * 2; Config.maxVertsPerPoly = 6; Config.maxSimplificationError = 1.3f; @@ -47,7 +49,7 @@ void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax ) bmax[2] = Constants::Origin[2] + (Constants::TileSize * (Y + 1)); } -uint8* TileBuilder::Build() +uint8* TileBuilder::Build(bool dbg) { _Geometry = new Geometry(); _Geometry->Transform = true; @@ -65,9 +67,9 @@ uint8* TileBuilder::Build() _Geometry->CalculateMinMaxHeight(bbMin[1], bbMax[1]); // again, we load everything - wasteful but who cares - for (int ty = Y - 1; ty <= Y + 1; ty++) + for (int ty = Y - 4; ty <= Y + 4; ty++) { - for (int tx = X - 1; tx <= X + 1; tx++) + for (int tx = X - 4; tx <= X + 4; tx++) { // don't load main tile again if (tx == X && ty == Y) @@ -85,6 +87,19 @@ uint8* TileBuilder::Build() delete _adt; } } + + if (dbg) + { + char buff[100]; + sprintf(buff, "mmaps/%s_%02u%02u.obj", World.c_str(), Y, X); + FILE* debug = fopen(buff, "wb"); + for (int i = 0; i < _Geometry->Vertices.size(); ++i) + fprintf(debug, "v %f %f %f\n", _Geometry->Vertices[i].x, _Geometry->Vertices[i].y, _Geometry->Vertices[i].z); + for (int i = 0; i < _Geometry->Triangles.size(); ++i) + fprintf(debug, "f %i %i %i\n", _Geometry->Triangles[i].V0 + 1, _Geometry->Triangles[i].V1 + 1, _Geometry->Triangles[i].V2 + 1); + fclose(debug); + } + uint32 numVerts = _Geometry->Vertices.size(); uint32 numTris = _Geometry->Triangles.size(); float* vertices; @@ -100,8 +115,7 @@ uint8* TileBuilder::Build() bbMax[0] += Config.borderSize * Config.cs; rcHeightfield* hf = rcAllocHeightfield(); - int width = Config.width + (Config.borderSize * 2); - rcCreateHeightfield(Context, *hf, width, width, bbMin, bbMax, Config.cs, Config.ch); + rcCreateHeightfield(Context, *hf, Config.width, Config.height, bbMin, bbMax, Config.cs, Config.ch); rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); @@ -208,14 +222,14 @@ uint8* TileBuilder::Build() params.walkableRadius = Config.walkableRadius; params.tileX = X; params.tileY = Y; - params.tileSize = Config.width; + params.tileSize = 1800; // Offmesh-connection settings params.offMeshConCount = 0; // none for now int navDataSize; uint8* navData; - printf("[%02i,%02i] Creating the navmesh!\n", X, Y); + printf("[%02i,%02i] Creating the navmesh with %i vertices, %i polys, %i triangles!\n", X, Y, pmesh->nverts, pmesh->npolys, dmesh->ntris); bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); // Free some memory diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index 2ec45811676..72e275c75b7 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -14,7 +14,7 @@ public: ~TileBuilder(); void CalculateTileBounds(float*& bmin, float*& bmax); - uint8* Build(); + uint8* Build(bool dbg); std::string World; int X; diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 3db387bc81a..6389e0aa66e 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -180,3 +180,253 @@ G3D::Matrix4 Utils::GetWmoDoodadTransformation( DoodadInstance inst, WorldModelD return scale * rotation * quatRotation ** translation * rootTransformation; } + +void MapChunkHeader::Read(FILE* stream) +{ + fread(&Flags, sizeof(uint32), 1, stream); + fread(&IndexX, sizeof(uint32), 1, stream); + fread(&IndexY, sizeof(uint32), 1, stream); + fread(&Layers, sizeof(uint32), 1, stream); + fread(&DoodadRefs, sizeof(uint32), 1, stream); + fread(&OffsetMCVT, sizeof(uint32), 1, stream); + fread(&OffsetMCNR, sizeof(uint32), 1, stream); + fread(&OffsetMCLY, sizeof(uint32), 1, stream); + fread(&OffsetMCRF, sizeof(uint32), 1, stream); + fread(&OffsetMCAL, sizeof(uint32), 1, stream); + fread(&SizeMCAL, sizeof(uint32), 1, stream); + fread(&OffsetMCSH, sizeof(uint32), 1, stream); + fread(&SizeMCSH, sizeof(uint32), 1, stream); + fread(&AreaId, sizeof(uint32), 1, stream); + fread(&MapObjectRefs, sizeof(uint32), 1, stream); + fread(&Holes, sizeof(uint32), 1, stream); + LowQualityTextureMap = new uint32[4]; + fread(LowQualityTextureMap, sizeof(uint32), 4, stream); + fread(&PredTex, sizeof(uint32), 1, stream); + fread(&NumberEffectDoodad, sizeof(uint32), 1, stream); + fread(&OffsetMCSE, sizeof(uint32), 1, stream); + fread(&SoundEmitters, sizeof(uint32), 1, stream); + fread(&OffsetMCLQ, sizeof(uint32), 1, stream); + fread(&SizeMCLQ, sizeof(uint32), 1, stream); + Position = Vector3::Read(stream); + fread(&OffsetMCCV, sizeof(uint32), 1, stream); +} + +void MHDR::Read(FILE* stream) +{ + fread(&Flags, sizeof(uint32), 1, stream); + fread(&OffsetMCIN, sizeof(uint32), 1, stream); + fread(&OffsetMTEX, sizeof(uint32), 1, stream); + fread(&OffsetMMDX, sizeof(uint32), 1, stream); + fread(&OffsetMMID, sizeof(uint32), 1, stream); + fread(&OffsetMWMO, sizeof(uint32), 1, stream); + fread(&OffsetMWID, sizeof(uint32), 1, stream); + fread(&OffsetMDDF, sizeof(uint32), 1, stream); + fread(&OffsetMODF, sizeof(uint32), 1, stream); + fread(&OffsetMFBO, sizeof(uint32), 1, stream); + fread(&OffsetMH2O, sizeof(uint32), 1, stream); + fread(&OffsetMTFX, sizeof(uint32), 1, stream); +} + +void ModelHeader::Read(FILE* stream) +{ + fread(&Magic, sizeof(char), 4, stream); + Magic[4] = '\0'; // null-terminate it. + fread(&Version, sizeof(uint32), 1, stream); + fread(&LengthModelName, sizeof(uint32), 1, stream); + fread(&OffsetName, sizeof(uint32), 1, stream); + fread(&ModelFlags, sizeof(uint32), 1, stream); + fread(&CountGlobalSequences, sizeof(uint32), 1, stream); + fread(&OffsetGlobalSequences, sizeof(uint32), 1, stream); + fread(&CountAnimations, sizeof(uint32), 1, stream); + fread(&OffsetAnimations, sizeof(uint32), 1, stream); + fread(&CountAnimationLookup, sizeof(uint32), 1, stream); + fread(&OffsetAnimationLookup, sizeof(uint32), 1, stream); + fread(&CountBones, sizeof(uint32), 1, stream); + fread(&OffsetBones, sizeof(uint32), 1, stream); + fread(&CountKeyBoneLookup, sizeof(uint32), 1, stream); + fread(&OffsetKeyBoneLookup, sizeof(uint32), 1, stream); + fread(&CountVertices, sizeof(uint32), 1, stream); + fread(&OffsetVertices, sizeof(uint32), 1, stream); + fread(&CountViews, sizeof(uint32), 1, stream); + fread(&CountColors, sizeof(uint32), 1, stream); + fread(&OffsetColors, sizeof(uint32), 1, stream); + fread(&CountTextures, sizeof(uint32), 1, stream); + fread(&OffsetTextures, sizeof(uint32), 1, stream); + fread(&CountTransparency, sizeof(uint32), 1, stream); + fread(&OffsetTransparency, sizeof(uint32), 1, stream); + fread(&CountUvAnimation, sizeof(uint32), 1, stream); + fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); + fread(&CountTexReplace, sizeof(uint32), 1, stream); + fread(&OffsetTexReplace, sizeof(uint32), 1, stream); + fread(&CountRenderFlags, sizeof(uint32), 1, stream); + fread(&OffsetRenderFlags, sizeof(uint32), 1, stream); + fread(&CountBoneLookup, sizeof(uint32), 1, stream); + fread(&OffsetBoneLookup, sizeof(uint32), 1, stream); + fread(&CountTexLookup, sizeof(uint32), 1, stream); + fread(&OffsetTexLookup, sizeof(uint32), 1, stream); + fread(&CountTexUnits, sizeof(uint32), 1, stream); + fread(&OffsetTexUnits, sizeof(uint32), 1, stream); + fread(&CountTransLookup, sizeof(uint32), 1, stream); + fread(&OffsetTransLookup, sizeof(uint32), 1, stream); + fread(&CountUvAnimLookup, sizeof(uint32), 1, stream); + fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream); + fread(&CountColors, sizeof(uint32), 1, stream); + fread(&OffsetColors, sizeof(uint32), 1, stream); + fread(&CountTextures, sizeof(uint32), 1, stream); + fread(&OffsetTextures, sizeof(uint32), 1, stream); + fread(&CountTransparency, sizeof(uint32), 1, stream); + fread(&OffsetTransparency, sizeof(uint32), 1, stream); + fread(&CountUvAnimation, sizeof(uint32), 1, stream); + fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); + fread(&CountTexReplace, sizeof(uint32), 1, stream); + fread(&OffsetTexReplace, sizeof(uint32), 1, stream); + VertexBox[0] = Vector3::Read(stream); + VertexBox[1] = Vector3::Read(stream); + fread(&VertexRadius, sizeof(float), 1, stream); + BoundingBox[0] = Vector3::Read(stream); + BoundingBox[1] = Vector3::Read(stream); + fread(&BoundingRadius, sizeof(float), 1, stream); + fread(&CountBoundingTriangles, sizeof(uint32), 1, stream); + fread(&OffsetBoundingTriangles, sizeof(uint32), 1, stream); + fread(&CountBoundingVertices, sizeof(uint32), 1, stream); + fread(&OffsetBoundingVertices, sizeof(uint32), 1, stream); + fread(&CountBoundingNormals, sizeof(uint32), 1, stream); + fread(&OffsetBoundingNormals, sizeof(uint32), 1, stream); +} + +WorldModelHeader WorldModelHeader::Read(FILE* stream) +{ + WorldModelHeader ret; + fread(&ret.CountMaterials, sizeof(uint32), 1, stream); + fread(&ret.CountGroups, sizeof(uint32), 1, stream); + fread(&ret.CountPortals, sizeof(uint32), 1, stream); + fread(&ret.CountLights, sizeof(uint32), 1, stream); + fread(&ret.CountModels, sizeof(uint32), 1, stream); + fread(&ret.CountDoodads, sizeof(uint32), 1, stream); + fread(&ret.CountSets, sizeof(uint32), 1, stream); + fread(&ret.AmbientColorUnk, sizeof(uint32), 1, stream); + fread(&ret.WmoId, sizeof(uint32), 1, stream); + ret.BoundingBox[0] = Vector3::Read(stream); + ret.BoundingBox[1] = Vector3::Read(stream); + fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); + return ret; +} + +DoodadInstance DoodadInstance::Read(FILE* stream) +{ + DoodadInstance ret; + fread(&ret.FileOffset, sizeof(uint32), 1, stream); + ret.Position = Vector3::Read(stream); + fread(&ret.QuatW, sizeof(float), 1, stream); + fread(&ret.QuatX, sizeof(float), 1, stream); + fread(&ret.QuatY, sizeof(float), 1, stream); + fread(&ret.QuatZ, sizeof(float), 1, stream); + fread(&ret.Scale, sizeof(float), 1, stream); + fread(&ret.LightColor, sizeof(uint32), 1, stream); + return ret; +} + +DoodadSet DoodadSet::Read(FILE* stream) +{ + DoodadSet ret; + char name[21]; + fread(&name, sizeof(char), 20, stream); + name[20] = '\0'; + ret.Name = name; + fread(&ret.FirstInstanceIndex, sizeof(uint32), 1, stream); + fread(&ret.CountInstances, sizeof(uint32), 1, stream); + fread(&ret.UnknownZero, sizeof(uint32), 1, stream); + return ret; +} + +LiquidHeader LiquidHeader::Read(FILE* stream) +{ + LiquidHeader ret; + fread(&ret.CountXVertices, sizeof(uint32), 1, stream); + fread(&ret.CountYVertices, sizeof(uint32), 1, stream); + fread(&ret.Width, sizeof(uint32), 1, stream); + fread(&ret.Height, sizeof(uint32), 1, stream); + ret.BaseLocation = Vector3::Read(stream); + fread(&ret.MaterialId, sizeof(uint16), 1, stream); + return ret; +} + +LiquidData LiquidData::Read(FILE* stream, LiquidHeader& header) +{ + LiquidData ret; + ret.HeightMap = new float*[header.CountXVertices]; + for (uint32 i = 0; i < header.CountXVertices; ++i) + ret.HeightMap[i] = new float[header.CountYVertices]; + + ret.RenderFlags = new uint8*[header.Width]; + for (uint32 i = 0; i < header.Width; ++i) + ret.RenderFlags[i] = new uint8[header.Height]; + + for (uint32 y = 0; y < header.CountYVertices; y++) + { + for (uint32 x = 0; x < header.CountXVertices; x++) + { + uint32 discard; + fread(&discard, sizeof(uint32), 1, stream); + float tmp; + fread(&tmp, sizeof(float), 1, stream); + ret.HeightMap[x][y] = tmp; + } + } + + for (uint32 y = 0; y < header.Height; y++) + { + for (uint32 x = 0; x < header.Width; x++) + { + uint8 tmp; + fread(&tmp, sizeof(uint8), 1, stream); + ret.RenderFlags[x][y] = tmp; + } + } + + return ret; +} + +H2ORenderMask H2ORenderMask::Read(FILE* stream) +{ + H2ORenderMask ret; + fread(&ret.Mask, sizeof(uint8), 8, stream); + return ret; +} + +bool MCNKLiquidData::IsWater(int x, int y, float height) +{ + if (!Heights) + return false; + if (!Mask.ShouldRender(x, y)) + return false; + float diff = Heights[x][y] - height; + if (diff > Constants::MaxStandableHeight) + return true; + return false; +} + +H2OHeader H2OHeader::Read(FILE* stream) +{ + H2OHeader ret; + fread(&ret.OffsetInformation, sizeof(uint32), 1, stream); + fread(&ret.LayerCount, sizeof(uint32), 1, stream); + fread(&ret.OffsetRender, sizeof(uint32), 1, stream); + return ret; +} + +H2OInformation H2OInformation::Read(FILE* stream) +{ + H2OInformation ret; + fread(&ret.LiquidType, sizeof(uint16), 1, stream); + fread(&ret.Flags, sizeof(uint16), 1, stream); + fread(&ret.HeightLevel1, sizeof(float), 1, stream); + fread(&ret.HeightLevel2, sizeof(float), 1, stream); + fread(&ret.OffsetX, sizeof(uint8), 1, stream); + fread(&ret.OffsetY, sizeof(uint8), 1, stream); + fread(&ret.Width, sizeof(uint8), 1, stream); + fread(&ret.Height, sizeof(uint8), 1, stream); + fread(&ret.OffsetMask2, sizeof(uint32), 1, stream); + fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream); + return ret; +} diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index c9d2746b7d8..a45c3659240 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -77,35 +77,7 @@ public: Vector3 Position; uint32 OffsetMCCV; - void Read(FILE* stream) - { - fread(&Flags, sizeof(uint32), 1, stream); - fread(&IndexX, sizeof(uint32), 1, stream); - fread(&IndexY, sizeof(uint32), 1, stream); - fread(&Layers, sizeof(uint32), 1, stream); - fread(&DoodadRefs, sizeof(uint32), 1, stream); - fread(&OffsetMCVT, sizeof(uint32), 1, stream); - fread(&OffsetMCNR, sizeof(uint32), 1, stream); - fread(&OffsetMCLY, sizeof(uint32), 1, stream); - fread(&OffsetMCRF, sizeof(uint32), 1, stream); - fread(&OffsetMCAL, sizeof(uint32), 1, stream); - fread(&SizeMCAL, sizeof(uint32), 1, stream); - fread(&OffsetMCSH, sizeof(uint32), 1, stream); - fread(&SizeMCSH, sizeof(uint32), 1, stream); - fread(&AreaId, sizeof(uint32), 1, stream); - fread(&MapObjectRefs, sizeof(uint32), 1, stream); - fread(&Holes, sizeof(uint32), 1, stream); - LowQualityTextureMap = new uint32[4]; - fread(LowQualityTextureMap, sizeof(uint32), 4, stream); - fread(&PredTex, sizeof(uint32), 1, stream); - fread(&NumberEffectDoodad, sizeof(uint32), 1, stream); - fread(&OffsetMCSE, sizeof(uint32), 1, stream); - fread(&SoundEmitters, sizeof(uint32), 1, stream); - fread(&OffsetMCLQ, sizeof(uint32), 1, stream); - fread(&SizeMCLQ, sizeof(uint32), 1, stream); - Position = Vector3::Read(stream); - fread(&OffsetMCCV, sizeof(uint32), 1, stream); - } + void Read(FILE* stream); }; class MHDR @@ -125,21 +97,7 @@ public: uint32 OffsetMH2O; uint32 OffsetMTFX; - void Read(FILE* stream) - { - fread(&Flags, sizeof(uint32), 1, stream); - fread(&OffsetMCIN, sizeof(uint32), 1, stream); - fread(&OffsetMTEX, sizeof(uint32), 1, stream); - fread(&OffsetMMDX, sizeof(uint32), 1, stream); - fread(&OffsetMMID, sizeof(uint32), 1, stream); - fread(&OffsetMWMO, sizeof(uint32), 1, stream); - fread(&OffsetMWID, sizeof(uint32), 1, stream); - fread(&OffsetMDDF, sizeof(uint32), 1, stream); - fread(&OffsetMODF, sizeof(uint32), 1, stream); - fread(&OffsetMFBO, sizeof(uint32), 1, stream); - fread(&OffsetMH2O, sizeof(uint32), 1, stream); - fread(&OffsetMTFX, sizeof(uint32), 1, stream); - } + void Read(FILE* stream); }; class ModelHeader @@ -196,72 +154,7 @@ public: uint32 CountBoundingNormals; uint32 OffsetBoundingNormals; - void Read(FILE* stream) - { - fread(&Magic, sizeof(char), 4, stream); - Magic[4] = '\0'; // null-terminate it. - fread(&Version, sizeof(uint32), 1, stream); - fread(&LengthModelName, sizeof(uint32), 1, stream); - fread(&OffsetName, sizeof(uint32), 1, stream); - fread(&ModelFlags, sizeof(uint32), 1, stream); - fread(&CountGlobalSequences, sizeof(uint32), 1, stream); - fread(&OffsetGlobalSequences, sizeof(uint32), 1, stream); - fread(&CountAnimations, sizeof(uint32), 1, stream); - fread(&OffsetAnimations, sizeof(uint32), 1, stream); - fread(&CountAnimationLookup, sizeof(uint32), 1, stream); - fread(&OffsetAnimationLookup, sizeof(uint32), 1, stream); - fread(&CountBones, sizeof(uint32), 1, stream); - fread(&OffsetBones, sizeof(uint32), 1, stream); - fread(&CountKeyBoneLookup, sizeof(uint32), 1, stream); - fread(&OffsetKeyBoneLookup, sizeof(uint32), 1, stream); - fread(&CountVertices, sizeof(uint32), 1, stream); - fread(&OffsetVertices, sizeof(uint32), 1, stream); - fread(&CountViews, sizeof(uint32), 1, stream); - fread(&CountColors, sizeof(uint32), 1, stream); - fread(&OffsetColors, sizeof(uint32), 1, stream); - fread(&CountTextures, sizeof(uint32), 1, stream); - fread(&OffsetTextures, sizeof(uint32), 1, stream); - fread(&CountTransparency, sizeof(uint32), 1, stream); - fread(&OffsetTransparency, sizeof(uint32), 1, stream); - fread(&CountUvAnimation, sizeof(uint32), 1, stream); - fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); - fread(&CountTexReplace, sizeof(uint32), 1, stream); - fread(&OffsetTexReplace, sizeof(uint32), 1, stream); - fread(&CountRenderFlags, sizeof(uint32), 1, stream); - fread(&OffsetRenderFlags, sizeof(uint32), 1, stream); - fread(&CountBoneLookup, sizeof(uint32), 1, stream); - fread(&OffsetBoneLookup, sizeof(uint32), 1, stream); - fread(&CountTexLookup, sizeof(uint32), 1, stream); - fread(&OffsetTexLookup, sizeof(uint32), 1, stream); - fread(&CountTexUnits, sizeof(uint32), 1, stream); - fread(&OffsetTexUnits, sizeof(uint32), 1, stream); - fread(&CountTransLookup, sizeof(uint32), 1, stream); - fread(&OffsetTransLookup, sizeof(uint32), 1, stream); - fread(&CountUvAnimLookup, sizeof(uint32), 1, stream); - fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream); - fread(&CountColors, sizeof(uint32), 1, stream); - fread(&OffsetColors, sizeof(uint32), 1, stream); - fread(&CountTextures, sizeof(uint32), 1, stream); - fread(&OffsetTextures, sizeof(uint32), 1, stream); - fread(&CountTransparency, sizeof(uint32), 1, stream); - fread(&OffsetTransparency, sizeof(uint32), 1, stream); - fread(&CountUvAnimation, sizeof(uint32), 1, stream); - fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); - fread(&CountTexReplace, sizeof(uint32), 1, stream); - fread(&OffsetTexReplace, sizeof(uint32), 1, stream); - VertexBox[0] = Vector3::Read(stream); - VertexBox[1] = Vector3::Read(stream); - fread(&VertexRadius, sizeof(float), 1, stream); - BoundingBox[0] = Vector3::Read(stream); - BoundingBox[1] = Vector3::Read(stream); - fread(&BoundingRadius, sizeof(float), 1, stream); - fread(&CountBoundingTriangles, sizeof(uint32), 1, stream); - fread(&OffsetBoundingTriangles, sizeof(uint32), 1, stream); - fread(&CountBoundingVertices, sizeof(uint32), 1, stream); - fread(&OffsetBoundingVertices, sizeof(uint32), 1, stream); - fread(&CountBoundingNormals, sizeof(uint32), 1, stream); - fread(&OffsetBoundingNormals, sizeof(uint32), 1, stream); - } + void Read(FILE* stream); }; class WorldModelHeader @@ -280,23 +173,7 @@ public: Vector3 BoundingBox[2]; uint32 LiquidTypeRelated; - static WorldModelHeader Read(FILE* stream) - { - WorldModelHeader ret; - fread(&ret.CountMaterials, sizeof(uint32), 1, stream); - fread(&ret.CountGroups, sizeof(uint32), 1, stream); - fread(&ret.CountPortals, sizeof(uint32), 1, stream); - fread(&ret.CountLights, sizeof(uint32), 1, stream); - fread(&ret.CountModels, sizeof(uint32), 1, stream); - fread(&ret.CountDoodads, sizeof(uint32), 1, stream); - fread(&ret.CountSets, sizeof(uint32), 1, stream); - fread(&ret.AmbientColorUnk, sizeof(uint32), 1, stream); - fread(&ret.WmoId, sizeof(uint32), 1, stream); - ret.BoundingBox[0] = Vector3::Read(stream); - ret.BoundingBox[1] = Vector3::Read(stream); - fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); - return ret; - } + static WorldModelHeader Read(FILE* stream); }; class DoodadInstance @@ -313,19 +190,7 @@ public: float Scale; uint32 LightColor; - static DoodadInstance Read(FILE* stream) - { - DoodadInstance ret; - fread(&ret.FileOffset, sizeof(uint32), 1, stream); - ret.Position = Vector3::Read(stream); - fread(&ret.QuatW, sizeof(float), 1, stream); - fread(&ret.QuatX, sizeof(float), 1, stream); - fread(&ret.QuatY, sizeof(float), 1, stream); - fread(&ret.QuatZ, sizeof(float), 1, stream); - fread(&ret.Scale, sizeof(float), 1, stream); - fread(&ret.LightColor, sizeof(uint32), 1, stream); - return ret; - } + static DoodadInstance Read(FILE* stream); }; class DoodadSet @@ -337,18 +202,7 @@ public: uint32 CountInstances; uint32 UnknownZero; - static DoodadSet Read(FILE* stream) - { - DoodadSet ret; - char name[21]; - fread(&name, sizeof(char), 20, stream); - name[20] = '\0'; - ret.Name = name; - fread(&ret.FirstInstanceIndex, sizeof(uint32), 1, stream); - fread(&ret.CountInstances, sizeof(uint32), 1, stream); - fread(&ret.UnknownZero, sizeof(uint32), 1, stream); - return ret; - } + static DoodadSet Read(FILE* stream); }; class LiquidHeader @@ -362,17 +216,7 @@ public: Vector3 BaseLocation; uint16 MaterialId; - static LiquidHeader Read(FILE* stream) - { - LiquidHeader ret; - fread(&ret.CountXVertices, sizeof(uint32), 1, stream); - fread(&ret.CountYVertices, sizeof(uint32), 1, stream); - fread(&ret.Width, sizeof(uint32), 1, stream); - fread(&ret.Height, sizeof(uint32), 1, stream); - ret.BaseLocation = Vector3::Read(stream); - fread(&ret.MaterialId, sizeof(uint16), 1, stream); - return ret; - } + static LiquidHeader Read(FILE* stream); }; class LiquidData @@ -387,41 +231,7 @@ public: return RenderFlags[x][y] != 0x0F; } - static LiquidData Read(FILE* stream, LiquidHeader header) - { - LiquidData ret; - ret.HeightMap = new float*[header.CountXVertices]; - for (uint32 i = 0; i < header.CountXVertices; ++i) - ret.HeightMap[i] = new float[header.CountYVertices]; - - ret.RenderFlags = new uint8*[header.Width]; - for (uint32 i = 0; i < header.Width; ++i) - ret.RenderFlags[i] = new uint8[header.Height]; - - for (uint32 y = 0; y < header.CountYVertices; y++) - { - for (uint32 x = 0; x < header.CountXVertices; x++) - { - uint32 discard; - fread(&discard, sizeof(uint32), 1, stream); - float tmp; - fread(&tmp, sizeof(float), 1, stream); - ret.HeightMap[x][y] = tmp; - } - } - - for (uint32 y = 0; y < header.Height; y++) - { - for (uint32 x = 0; x < header.Width; x++) - { - uint8 tmp; - fread(&tmp, sizeof(uint8), 1, stream); - ret.RenderFlags[x][y] = tmp; - } - } - - return ret; - } + static LiquidData Read(FILE* stream, LiquidHeader& header); }; class H2ORenderMask @@ -435,12 +245,7 @@ public: return (Mask[y] >> x & 1) != 0; } - static H2ORenderMask Read(FILE* stream) - { - H2ORenderMask ret; - fread(&ret.Mask, sizeof(uint8), 8, stream); - return ret; - } + static H2ORenderMask Read(FILE* stream); }; class MCNKLiquidData @@ -452,17 +257,7 @@ public: float** Heights; H2ORenderMask Mask; - bool IsWater(int x, int y, float height) - { - if (!Heights) - return false; - if (!Mask.ShouldRender(x, y)) - return false; - float diff = Heights[x][y] - height; - if (diff > Constants::MaxStandableHeight) - return true; - return false; - } + bool IsWater(int x, int y, float height); }; class H2OHeader @@ -473,14 +268,7 @@ public: uint32 LayerCount; uint32 OffsetRender; - static H2OHeader Read(FILE* stream) - { - H2OHeader ret; - fread(&ret.OffsetInformation, sizeof(uint32), 1, stream); - fread(&ret.LayerCount, sizeof(uint32), 1, stream); - fread(&ret.OffsetRender, sizeof(uint32), 1, stream); - return ret; - } + static H2OHeader Read(FILE* stream); }; class H2OInformation @@ -498,21 +286,7 @@ public: uint32 OffsetMask2; uint32 OffsetHeightmap; - static H2OInformation Read(FILE* stream) - { - H2OInformation ret; - fread(&ret.LiquidType, sizeof(uint16), 1, stream); - fread(&ret.Flags, sizeof(uint16), 1, stream); - fread(&ret.HeightLevel1, sizeof(float), 1, stream); - fread(&ret.HeightLevel2, sizeof(float), 1, stream); - fread(&ret.OffsetX, sizeof(uint8), 1, stream); - fread(&ret.OffsetY, sizeof(uint8), 1, stream); - fread(&ret.Width, sizeof(uint8), 1, stream); - fread(&ret.Height, sizeof(uint8), 1, stream); - fread(&ret.OffsetMask2, sizeof(uint32), 1, stream); - fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream); - return ret; - } + static H2OInformation Read(FILE* stream); }; // Dummy class to act as an interface. -- cgit v1.2.3 From e32ddea96a017c7d5ad22eca16764d74501b90f3 Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 3 Oct 2012 18:02:18 -0500 Subject: Tools/MeshExtractor: * Added the capability of extracting DBCs. * Fixed most compile warnings * Some work on the navigation mesh generation process (still not ready) --- src/tools/mesh_extractor/ChunkedData.cpp | 4 +- src/tools/mesh_extractor/Constants.h | 11 +++ src/tools/mesh_extractor/ContinentBuilder.cpp | 16 +++-- src/tools/mesh_extractor/DoodadHandler.cpp | 2 +- src/tools/mesh_extractor/LiquidHandler.cpp | 8 +-- src/tools/mesh_extractor/MPQ.cpp | 1 + src/tools/mesh_extractor/MPQ.h | 2 + src/tools/mesh_extractor/MPQManager.cpp | 61 ++++++++++++++--- src/tools/mesh_extractor/MPQManager.h | 6 +- src/tools/mesh_extractor/MeshExtractor.cpp | 93 ++++++++++++++++++++++---- src/tools/mesh_extractor/TileBuilder.cpp | 75 ++++++++++++--------- src/tools/mesh_extractor/TileBuilder.h | 4 +- src/tools/mesh_extractor/Utils.cpp | 38 +++++++++++ src/tools/mesh_extractor/Utils.h | 2 + src/tools/mesh_extractor/WorldModelGroup.cpp | 8 +-- src/tools/mesh_extractor/WorldModelHandler.cpp | 2 +- src/tools/mesh_extractor/WorldModelRoot.cpp | 6 +- 17 files changed, 264 insertions(+), 75 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index 4431993e3d1..4d609d8f6b2 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -48,7 +48,7 @@ void ChunkedData::Load( uint32 maxLength, uint32 chunksHint ) int ChunkedData::GetFirstIndex( std::string name ) { - for (int i = 0; i < Chunks.size(); ++i) + for (uint32 i = 0; i < Chunks.size(); ++i) if (Chunks[i]->Name == name) return i; return -1; @@ -56,7 +56,7 @@ int ChunkedData::GetFirstIndex( std::string name ) Chunk* ChunkedData::GetChunkByName( std::string name ) { - for (int i = 0; i < Chunks.size(); ++i) + for (uint32 i = 0; i < Chunks.size(); ++i) if (Chunks[i]->Name == name) return Chunks[i]; return NULL; diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h index f44d5f16797..f3b71812155 100644 --- a/src/tools/mesh_extractor/Constants.h +++ b/src/tools/mesh_extractor/Constants.h @@ -29,6 +29,17 @@ public: POLY_FLAG_SWIM = 2, POLY_FLAG_FLIGHTMASTER = 4 }; + + enum ExtractFlags + { + EXTRACT_FLAG_DBC = 1, + EXTRACT_FLAG_MAPS = 2, + EXTRACT_FLAG_VMAPS = 4, + EXTRACT_FLAG_GOB_MODELS = 8, + EXTRACT_FLAG_MMAPS = 16, + EXTRACT_FLAG_ALLOWED = EXTRACT_FLAG_DBC | EXTRACT_FLAG_MAPS | EXTRACT_FLAG_VMAPS | EXTRACT_FLAG_GOB_MODELS | EXTRACT_FLAG_MMAPS + }; + static const float TileSize; static const float MaxXY; static const float ChunkSize; diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 984f6170357..e4a1d2ca9f4 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -13,8 +13,9 @@ private: int X, Y, MapId; std::string Continent; bool debug; + dtNavMeshParams Params; public: - BuilderThread(bool deb) : Free(true), debug(deb) {} + BuilderThread(bool deb, dtNavMeshParams& params) : Free(true), debug(deb), Params(params) {} void SetData(int x, int y, int map, std::string cont) { X = x; Y = y; MapId = map; Continent = cont; } int svc() @@ -32,7 +33,7 @@ public: Free = true; return 0; } - uint8* nav = builder.Build(debug); + uint8* nav = builder.Build(debug, Params); if (nav) { f = fopen(buff, "wb"); @@ -101,14 +102,17 @@ void ContinentBuilder::Build(bool debug) dtNavMeshParams params; params.maxPolys = 32768; params.maxTiles = TileMap->TileTable.size(); - rcVcopy(params.orig, bmin); - params.tileHeight = 533.33333f; - params.tileWidth = 533.33333f; + // rcVcopy(params.orig, bmin); + params.orig[0] = Constants::Origin[0]; + params.orig[1] = 0; + params.orig[2] = Constants::Origin[2]; + params.tileHeight = Constants::TileSize; + params.tileWidth = Constants::TileSize; fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); fclose(mmap); std::vector Threads; for (uint32 i = 0; i < NumberOfThreads; ++i) - Threads.push_back(new BuilderThread(debug)); + Threads.push_back(new BuilderThread(debug, params)); printf("Map %s ( %i ) has %i tiles. Building them with %i threads\n", Continent.c_str(), MapId, TileMap->TileTable.size(), NumberOfThreads); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 363f07b4578..4e8028b3dff 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -31,7 +31,7 @@ void DoodadHandler::ProcessInternal( ChunkedData* subChunks ) { int32 index; fread(&index, sizeof(int32), 1, stream); - if (index < 0 || index >= _definitions->size()) + if (index < 0 || uint32(index) >= _definitions->size()) continue; DoodadDefinition doodad = (*_definitions)[index]; if (_drawn.find(doodad.UniqueId) != _drawn.end()) diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index 5b998d75db9..7844130ab34 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -34,10 +34,10 @@ void LiquidHandler::HandleNewLiquid() H2OInformation information = H2OInformation::Read(stream); float** heights = new float*[9]; - for (int i = 0; i < 9; ++i) + for (int j = 0; j < 9; ++i) { - heights[i] = new float[9]; - memset(heights[i], 0, sizeof(float) * 9); + heights[j] = new float[9]; + memset(heights[j], 0, sizeof(float) * 9); } H2ORenderMask renderMask; @@ -52,7 +52,7 @@ void LiquidHandler::HandleNewLiquid() uint8* altMask = new uint8[size]; fread(altMask, sizeof(uint8), size, stream); - for (int mi = 0; mi < size; mi++) + for (uint32 mi = 0; mi < size; mi++) renderMask.Mask[mi + information.OffsetY] |= altMask[mi]; delete[] altMask; } diff --git a/src/tools/mesh_extractor/MPQ.cpp b/src/tools/mesh_extractor/MPQ.cpp index 699b0a5014c..b7be181594d 100644 --- a/src/tools/mesh_extractor/MPQ.cpp +++ b/src/tools/mesh_extractor/MPQ.cpp @@ -31,6 +31,7 @@ MPQArchive::MPQArchive(const char* filename) break; } } + GetFileListTo(Files); } void MPQArchive::close() diff --git a/src/tools/mesh_extractor/MPQ.h b/src/tools/mesh_extractor/MPQ.h index dd566bccff5..15fce452726 100644 --- a/src/tools/mesh_extractor/MPQ.h +++ b/src/tools/mesh_extractor/MPQ.h @@ -16,6 +16,8 @@ class MPQArchive public: mpq_archive_s *mpq_a; + + vector Files; MPQArchive(const char* filename); void close(); diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 608eef1547a..90491dfb945 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -15,7 +15,7 @@ char* MPQManager::Files[] = { "patch-3.MPQ" }; -char* MPQManager::Languages[] = { "esES", "enUS", "enGB", "esMX", "deDE" }; +char* MPQManager::Languages[] = { "enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }; void MPQManager::Initialize() { @@ -31,21 +31,38 @@ void MPQManager::Initialize() void MPQManager::InitializeDBC() { - CurLocale = 0; + BaseLocale = -1; std::string fileName; uint32 size = sizeof(Languages) / sizeof(char*); + MPQArchive* _baseLocale = NULL; for (uint32 i = 0; i < size; ++i) { - fileName = "Data/" + std::string(Languages[i]) + "/locale-" + std::string(Languages[i]) + ".MPQ"; - FILE* file = fopen(fileName.c_str(), "rb"); + std::string _fileName = "Data/" + std::string(Languages[i]) + "/locale-" + std::string(Languages[i]) + ".MPQ"; + FILE* file = fopen(_fileName.c_str(), "rb"); if (file) { - CurLocale = i; - break; + if (BaseLocale == -1) + { + BaseLocale = i; + _baseLocale = new MPQArchive(_fileName.c_str()); + fileName = _fileName; + LocaleFiles[i] = _baseLocale; + } + else + LocaleFiles[i] = new MPQArchive(_fileName.c_str()); + + AvailableLocales.insert(i); + printf("Detected locale: %s\n", Languages[i]); } } - Archives.push_front(new MPQArchive(fileName.c_str())); - printf("Using locale: %s\n", Languages[CurLocale]); + Archives.push_front(_baseLocale); + if (BaseLocale == -1) + { + printf("No locale data detected\n"); + ASSERT(false); + } + else + printf("Using default locale: %s\n", Languages[BaseLocale]); } FILE* MPQManager::GetFile( std::string path ) @@ -62,3 +79,31 @@ DBC* MPQManager::GetDBC( std::string name ) std::string path = "DBFilesClient\\" + name + ".dbc"; return new DBC(GetFile(path)); } + +FILE* MPQManager::GetFileFrom( std::string path, MPQArchive* file ) +{ + ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL); + mpq_archive* mpq_a = file->mpq_a; + + uint32_t filenum; + if(libmpq__file_number(mpq_a, path.c_str(), &filenum)) + return NULL; + + libmpq__off_t transferred; + libmpq__off_t size = 0; + libmpq__file_unpacked_size(mpq_a, filenum, &size); + + // HACK: in patch.mpq some files don't want to open and give 1 for filesize + if (size <= 1) + return NULL; + + uint8* buffer = new uint8[size]; + + //libmpq_file_getdata + libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); + + // Pack the return into a FILE stream + FILE* ret = tmpfile(); + fwrite(buffer, sizeof(uint8), size, ret); + return ret; +} diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h index 0050dc5218a..c23d7177825 100644 --- a/src/tools/mesh_extractor/MPQManager.h +++ b/src/tools/mesh_extractor/MPQManager.h @@ -13,10 +13,14 @@ public: void Initialize(); FILE* GetFile(std::string path); + FILE* GetFileFrom(std::string path, MPQArchive* file); DBC* GetDBC(std::string name); + std::vector GetAllFiles(std::string extension); std::deque Archives; - uint32 CurLocale; + int32 BaseLocale; + std::set AvailableLocales; + std::map LocaleFiles; static char* Files[]; static char* Languages[]; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 9d88fcdcdfc..d6b701607ba 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -3,6 +3,7 @@ #include "ContinentBuilder.h" #include "Cache.h" #include "DBC.h" +#include "Constants.h" #include @@ -14,7 +15,7 @@ LoginDatabaseWorkerPool LoginDatabase; MPQManager* MPQHandler; CacheClass* Cache; -void ExtractAllMaps(std::set& mapIds, uint32 threads, bool debug) +void ExtractMMaps(std::set& mapIds, uint32 threads, bool debug) { DBC* dbc = MPQHandler->GetDBC("Map"); for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) @@ -35,9 +36,45 @@ void ExtractAllMaps(std::set& mapIds, uint32 threads, bool debug) } } -bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapList, bool& debugOutput) +void ExtractDBCs() +{ + printf("Extracting DBCs\n"); + // Create the filesystem structure + std::string baseDBCPath = "dbc/"; + Utils::CreateDir(baseDBCPath); + + // Populate list of DBC files + std::set DBCFiles; + for (std::vector::iterator itr = MPQHandler->LocaleFiles[MPQHandler->BaseLocale]->Files.begin(); itr != MPQHandler->LocaleFiles[MPQHandler->BaseLocale]->Files.end(); ++itr) + if (itr->rfind(".dbc") == itr->length() - strlen(".dbc")) + DBCFiles.insert(*itr); + + // Iterate over all available locales + for (std::set::iterator itr = MPQHandler->AvailableLocales.begin(); itr != MPQHandler->AvailableLocales.end(); ++itr) + { + printf("Extracting DBCs for locale %s\n", MPQManager::Languages[*itr]); + std::string path = baseDBCPath; + if (*itr != MPQHandler->BaseLocale) + { + path += std::string(MPQManager::Languages[*itr]) + "/"; + Utils::CreateDir(path); + } + + std::string component = "component.wow-" + std::string(MPQManager::Languages[*itr]) + ".txt"; + // Extract the component file + Utils::SaveToDisk(MPQHandler->GetFile(component), path + component); + // Extract the DBC files for the given locale + for (std::set::iterator itr2 = DBCFiles.begin(); itr2 != DBCFiles.end(); ++itr2) + Utils::SaveToDisk(MPQHandler->GetFileFrom(*itr2, MPQHandler->LocaleFiles[*itr]), path + (itr2->c_str() + strlen("DBFilesClient\\"))); + } + printf("DBC extraction finished!\n"); +} + +bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapList, bool& debugOutput, uint32& extractFlags) { char* param = NULL; + extractFlags = 0; + for (int i = 1; i < argc; ++i) { if (strcmp(argv[i], "--threads") == 0) @@ -49,7 +86,7 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis threads = atoi(param); printf("Using %i threads\n", threads); } - if (strcmp(argv[i], "--maps") == 0) + else if (strcmp(argv[i], "--maps") == 0) { param = argv[++i]; if (!param) @@ -62,13 +99,32 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis printf("Extracting only provided list of maps (%u).\n", mapList.size()); } - if (strcmp(argv[i], "--debug") == 0) + else if (strcmp(argv[i], "--debug") == 0) { param = argv[++i]; if (!param) return false; debugOutput = atoi(param); - printf("Output will contain debug information (.obj files)\n"); + if (debugOutput) + printf("Output will contain debug information (.obj files)\n"); + } + else if (strcmp(argv[i], "--extract") == 0) + { + param = argv[++i]; + if (!param) + return false; + + extractFlags = atoi(param); + + if (!(extractFlags & Constants::EXTRACT_FLAG_ALLOWED)) // Tried to use an invalid flag + return false; + + printf("Detected flags: \n"); + printf("* Extract DBCs: %s\n", (extractFlags & Constants::EXTRACT_FLAG_DBC) ? "Yes" : "No"); + printf("* Extract Maps: %s\n", (extractFlags & Constants::EXTRACT_FLAG_MAPS) ? "Yes" : "No"); + printf("* Extract VMaps: %s\n", (extractFlags & Constants::EXTRACT_FLAG_VMAPS) ? "Yes" : "No"); + printf("* Extract GameObject Models: %s\n", (extractFlags & Constants::EXTRACT_FLAG_GOB_MODELS) ? "Yes" : "No"); + printf("* Extract MMaps: %s\n", (extractFlags & Constants::EXTRACT_FLAG_MMAPS) ? "Yes" : "No"); } } return true; @@ -77,9 +133,17 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis void PrintUsage() { printf("MeshExtractor help.\n"); - printf("* Use \"--threads \" to specify threads, default to 4\n"); - printf("* Use \"--maps a,b,c,d,e\" to extract only the maps specified ( do not use spaces )\n"); - printf("* Use \"--debug 1\" to generate debug information of the tiles.\n"); + printf("* Use \"--threads \" to specify threads, default to 4 (Only available when extracting MMaps)\n"); + printf("* Use \"--maps a,b,c,d,e\" to extract only the maps specified (Do not use spaces)\n"); + printf("* Use \"--debug 1\" to generate debug information of the tiles (Only available when extracting MMaps)\n"); + printf("* Use \"--extract X\" to extract the data specified by the flag X (Note: You can combine the flags with the bitwise OR operator |). Available flags are: \n"); + { + printf("- %u to extract DBCs\n", Constants::EXTRACT_FLAG_DBC); + printf("- %u to extract Maps (Not yet implemented)\n", Constants::EXTRACT_FLAG_MAPS); + printf("- %u to extract VMaps (Not yet implemented)\n", Constants::EXTRACT_FLAG_VMAPS); + printf("- %u to extract GameObject models (Not yet implemented)\n", Constants::EXTRACT_FLAG_GOB_MODELS); + printf("- %u to extract MMaps (Not yet finished)\n", Constants::EXTRACT_FLAG_MMAPS); + } } int main(int argc, char* argv[]) @@ -88,16 +152,21 @@ int main(int argc, char* argv[]) Cache = new CacheClass(); MPQHandler = new MPQManager(); MPQHandler->Initialize(); - uint32 threads = 4; + uint32 threads = 4, extractFlags = 0; std::set mapIds; bool debug = false; - - if (!HandleArgs(argc, argv, threads, mapIds, debug)) + + if (!HandleArgs(argc, argv, threads, mapIds, debug, extractFlags)) { PrintUsage(); return -1; } - ExtractAllMaps(mapIds, threads, debug); + if (extractFlags & Constants::EXTRACT_FLAG_DBC) + ExtractDBCs(); + + if (extractFlags & Constants::EXTRACT_FLAG_MMAPS) + ExtractMMaps(mapIds, threads, debug); + return 0; } \ No newline at end of file diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 54b9e4865cd..5b3e181713e 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -26,9 +26,9 @@ TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geome Config.walkableSlopeAngle = 50.0f; Config.detailSampleDist = 3.0f; Config.detailSampleMaxError = 1.25f; - Config.walkableClimb = 1.0f / Config.ch; - Config.walkableHeight = 1.652778f / Config.ch; - Config.walkableRadius = 0.2951389f / Config.cs; + Config.walkableClimb = floorf(1.0f / Config.ch); + Config.walkableHeight = ceilf(1.652778f / Config.ch); + Config.walkableRadius = ceilf(0.2951389f / Config.cs); Config.maxEdgeLen = Config.walkableRadius * 8; Config.borderSize = Config.walkableRadius + 4; Config.width = 1800 + Config.borderSize * 2; @@ -39,17 +39,17 @@ TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geome Context = new rcContext; } -void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax ) +void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams ) { bmin = new float[3]; bmax = new float[3]; - bmin[0] = Constants::Origin[0] + (Constants::TileSize * X); - bmin[2] = Constants::Origin[2] + (Constants::TileSize * Y); - bmax[0] = Constants::Origin[0] + (Constants::TileSize * (X + 1)); - bmax[2] = Constants::Origin[2] + (Constants::TileSize * (Y + 1)); + bmin[0] = Constants::Origin[0] /*navMeshParams.orig[0]*/ + (Constants::TileSize * X); + bmin[2] = Constants::Origin[2] /*navMeshParams.orig[2]*/ + (Constants::TileSize * Y); + bmax[0] = Constants::Origin[0] /*navMeshParams.orig[0]*/ + (Constants::TileSize * (X + 1)); + bmax[2] = Constants::Origin[2] /*navMeshParams.orig[2]*/ + (Constants::TileSize * (Y + 1)); } -uint8* TileBuilder::Build(bool dbg) +uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) { _Geometry = new Geometry(); _Geometry->Transform = true; @@ -61,15 +61,10 @@ uint8* TileBuilder::Build(bool dbg) if (_Geometry->Vertices.empty() && _Geometry->Triangles.empty()) return NULL; - float* bbMin; - float* bbMax; - CalculateTileBounds(bbMin, bbMax); - _Geometry->CalculateMinMaxHeight(bbMin[1], bbMax[1]); - // again, we load everything - wasteful but who cares - for (int ty = Y - 4; ty <= Y + 4; ty++) + for (int ty = Y - 2; ty <= Y + 2; ty++) { - for (int tx = X - 4; tx <= X + 4; tx++) + for (int tx = X - 2; tx <= X + 2; tx++) { // don't load main tile again if (tx == X && ty == Y) @@ -109,13 +104,23 @@ uint8* TileBuilder::Build(bool dbg) _Geometry->Vertices.clear(); _Geometry->Triangles.clear(); - bbMin[0] -= Config.borderSize * Config.cs; + float bbMin[3]; + float bbMax[3]; + // CalculateTileBounds(bbMin, bbMax, navMeshParams); + rcCalcBounds(vertices, numVerts, bbMin, bbMax); + // _Geometry->CalculateMinMaxHeight(bbMin[1], bbMax[1]); + + /*bbMin[0] -= Config.borderSize * Config.cs; bbMin[2] -= Config.borderSize * Config.cs; bbMax[0] += Config.borderSize * Config.cs; - bbMax[0] += Config.borderSize * Config.cs; + bbMax[0] += Config.borderSize * Config.cs;*/ + rcHeightfield* hf = rcAllocHeightfield(); - rcCreateHeightfield(Context, *hf, Config.width, Config.height, bbMin, bbMax, Config.cs, Config.ch); + int height, width; + rcCalcGridSize(bbMin, bbMax, Config.cs, &width, &height); + printf("Config values: Height: %i, Width: %i. Calculated values: Height: %i, Width: %i\n", Config.height, Config.width, height, width); + rcCreateHeightfield(Context, *hf, width, height, bbMin, bbMax, Config.cs, Config.ch); rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); @@ -168,29 +173,31 @@ uint8* TileBuilder::Build(bool dbg) rcFreeCompactHeightfield(chf); rcFreeContourSet(cset); + /* + * Removed with RecastNavigation v292 // Remove padding from the polymesh data. (Remove this odditity) for (int i = 0; i < pmesh->nverts; ++i) { unsigned short* v = &pmesh->verts[i * 3]; v[0] -= (unsigned short)Config.borderSize; v[2] -= (unsigned short)Config.borderSize; - } + }*/ // Set flags according to area types (e.g. Swim for Water) for (int i = 0; i < pmesh->npolys; i++) { if (pmesh->areas[i] == Constants::POLY_AREA_ROAD || pmesh->areas[i] == Constants::POLY_AREA_TERRAIN) pmesh->flags[i] = Constants::POLY_FLAG_WALK; - else if (pmesh->areas[i] == (int)Constants::POLY_AREA_WATER) + else if (pmesh->areas[i] == Constants::POLY_AREA_WATER) pmesh->flags[i] = Constants::POLY_FLAG_SWIM; } // get original bounds - float* tilebMin; + /*float* tilebMin; float* tilebMax; - CalculateTileBounds(tilebMin, tilebMax); + CalculateTileBounds(tilebMin, tilebMax, navMeshParams); tilebMin[1] = bbMin[1]; - tilebMax[1] = bbMax[1]; + tilebMax[1] = bbMax[1];*/ dtNavMeshCreateParams params; // PolyMesh data @@ -208,12 +215,14 @@ uint8* TileBuilder::Build(bool dbg) params.detailTris = dmesh->tris; params.detailTriCount = dmesh->ntris; // Copy bounding box - params.bmin[0] = tilebMin[0]; + /*params.bmin[0] = tilebMin[0]; params.bmin[1] = tilebMin[1]; params.bmin[2] = tilebMin[2]; params.bmax[0] = tilebMax[0]; params.bmax[1] = tilebMax[1]; - params.bmax[2] = tilebMax[2]; + params.bmax[2] = tilebMax[2];*/ + rcVcopy(params.bmin, pmesh->bmin); + rcVcopy(params.bmax, pmesh->bmax); // General settings params.ch = Config.ch; params.cs = Config.cs; @@ -222,7 +231,11 @@ uint8* TileBuilder::Build(bool dbg) params.walkableRadius = Config.walkableRadius; params.tileX = X; params.tileY = Y; - params.tileSize = 1800; + int _x = (((pmesh->bmin[0] + pmesh->bmax[0]) / 2) - Constants::Origin[0]) / Constants::TileSize; + int _y = (((pmesh->bmin[2] + pmesh->bmax[2]) / 2) - Constants::Origin[2]) / Constants::TileSize; + printf("[%02i,%02i] Generated with TileX: %i and TileY: %i\nbmin[0] %f bmin[1] %f bmin[2] %f bmax[0] %f bmax[1] %f bmax[2] %f\n", X, Y, _x, _y, params.bmin[0], params.bmin[1], params.bmin[2], params.bmax[0], params.bmax[1], params.bmax[2]); + params.buildBvTree = true; + params.tileLayer = 0; // Offmesh-connection settings params.offMeshConCount = 0; // none for now @@ -235,13 +248,13 @@ uint8* TileBuilder::Build(bool dbg) // Free some memory rcFreePolyMesh(pmesh); rcFreePolyMeshDetail(dmesh); - delete tilebMax; - delete tilebMin; + //delete tilebMax; + //delete tilebMin; delete areas; delete triangles; delete vertices; - delete bbMax; - delete bbMin; + //delete bbMax; + //delete bbMin; if (result) { diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index 72e275c75b7..17d6e48095a 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -13,8 +13,8 @@ public: TileBuilder(std::string world, int x, int y, uint32 mapId); ~TileBuilder(); - void CalculateTileBounds(float*& bmin, float*& bmax); - uint8* Build(bool dbg); + void CalculateTileBounds(float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams); + uint8* Build(bool dbg, dtNavMeshParams& navMeshParams); std::string World; int X; diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 6389e0aa66e..5b752885d17 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -5,6 +5,13 @@ #include "G3D/Matrix4.h" #include "G3D/Quat.h" +#ifdef _WIN32 + #include "direct.h" +#else + #include + #include +#endif + const float Constants::TileSize = 533.0f + (1/3.0f); const float Constants::MaxXY = 32.0f * Constants::TileSize; const float Constants::ChunkSize = Constants::TileSize / 16.0f; @@ -13,6 +20,15 @@ const float Constants::Origin[] = { -Constants::MaxXY, 0.0f, -Constants::MaxXY } const float Constants::PI = 3.1415926f; const float Constants::MaxStandableHeight = 1.5f; +void Utils::CreateDir( const std::string& Path ) +{ +#ifdef _WIN32 + _mkdir( Path.c_str()); +#else + mkdir( Path.c_str(), 0777 ); +#endif +} + void Utils::Reverse(char word[]) { int len = strlen(word); @@ -181,6 +197,28 @@ G3D::Matrix4 Utils::GetWmoDoodadTransformation( DoodadInstance inst, WorldModelD return scale * rotation * quatRotation ** translation * rootTransformation; } +void Utils::SaveToDisk( FILE* stream, std::string path ) +{ + FILE* disk = fopen(path.c_str(), "wb"); + if (!disk) + { + printf("Could not save file %s to disk, please verify that you have write permissions on that directory\n", path.c_str()); + return; + } + + uint32 size = Utils::Size(stream); + uint8* data = new uint8[size]; + // Read the data to an array + fread(data, 1, size, stream); + // And write it in the file + fwrite(data, 1, size, disk); + + // Close the filestream + fclose(disk); + // Free the used memory + delete data; +} + void MapChunkHeader::Read(FILE* stream) { fread(&Flags, sizeof(uint32), 1, stream); diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index a45c3659240..c19bc1bb29c 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -349,5 +349,7 @@ public: } static std::string Replace( std::string str, const std::string& oldStr, const std::string& newStr ); static G3D::Matrix4 GetWmoDoodadTransformation( DoodadInstance inst, WorldModelDefinition root ); + static void CreateDir( const std::string& Path ); + static void SaveToDisk(FILE* stream, std::string path); }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index b4c963020c7..bd0d106dabb 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -36,7 +36,7 @@ void WorldModelGroup::ReadNormals() ASSERT(normalCount == Vertices.size() && "normalCount is different than the Vertices count"); Normals.reserve(normalCount); FILE* stream = chunk->GetStream(); - for (int i = 0; i < normalCount; i++) + for (uint32 i = 0; i < normalCount; i++) Normals[i] = Vector3::Read(stream); } @@ -61,7 +61,7 @@ void WorldModelGroup::ReadVertices() uint32 verticeCount = chunk->Length / 12; Vertices.reserve(verticeCount); FILE* stream = chunk->GetStream(); - for (int i = 0; i < verticeCount; i++) + for (uint32 i = 0; i < verticeCount; i++) Vertices.push_back(Vector3::Read(stream)); } @@ -75,7 +75,7 @@ void WorldModelGroup::ReadTriangles() ASSERT(triangleCount == TriangleFlags.size() && "triangleCount != TriangleFlags.size()"); FILE* stream = chunk->GetStream(); Triangles.reserve(triangleCount); - for (int i = 0; i < triangleCount; i++) + for (uint32 i = 0; i < triangleCount; i++) { uint16 v0; uint16 v1; @@ -97,7 +97,7 @@ void WorldModelGroup::ReadMaterials() uint32 triangleCount = chunk->Length / 2; TriangleFlags.reserve(triangleCount); TriangleMaterials.reserve(triangleCount); - for (int i = 0; i < triangleCount; i++) + for (uint32 i = 0; i < triangleCount; i++) { uint8 tmp; fread(&tmp, sizeof(uint8), 1, stream); diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index b98a7aae826..7b60b9b2151 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -46,7 +46,7 @@ void WorldModelHandler::ProcessInternal( ChunkedData* subChunks ) int32 index; fread(&index, sizeof(int32), 1, stream); - if (index < 0 || index >= _definitions->size()) + if (index < 0 || uint32(index) >= _definitions->size()) continue; WorldModelDefinition wmo = (*_definitions)[index]; diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp index 3457a35f761..c34a77e4531 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.cpp +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -16,7 +16,7 @@ void WorldModelRoot::ReadGroups() { std::string pathBase = Utils::GetPathBase(Path); Groups.reserve(Header.CountGroups); - for (int i = 0; i < Header.CountGroups; i++) + for (uint32 i = 0; i < Header.CountGroups; i++) { char name[200]; sprintf(name, "%s_%03u.wmo", pathBase.c_str(), i); @@ -35,7 +35,7 @@ void WorldModelRoot::ReadDoodadSets() FILE* stream = chunk->GetStream(); ASSERT(chunk->Length / 32 == Header.CountSets && "chunk.Length / 32 == Header.CountSets"); DoodadSets.reserve(Header.CountSets); - for (int i = 0; i < Header.CountSets; i++) + for (uint32 i = 0; i < Header.CountSets; i++) DoodadSets.push_back(DoodadSet::Read(stream)); } @@ -49,7 +49,7 @@ void WorldModelRoot::ReadDoodadInstances() const uint32 instanceSize = 40; uint32 countInstances = chunk->Length / instanceSize; DoodadInstances.reserve(countInstances); - for (int i = 0; i < countInstances; i++) + for (uint32 i = 0; i < countInstances; i++) { FILE* stream = chunk->GetStream(); fseek(stream, instanceSize * i, SEEK_CUR); -- cgit v1.2.3 From d2437407f4f7ad1af3baeb351626b41bd700065c Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 3 Oct 2012 21:09:05 -0500 Subject: Tools/MeshExtractor: * Fixed a bunch of errors * Allow to extract m2 and mdx models, WMOs are still not being extracted. --- src/tools/mesh_extractor/Chunk.cpp | 2 +- src/tools/mesh_extractor/Constants.h | 2 + src/tools/mesh_extractor/DBC.cpp | 2 +- src/tools/mesh_extractor/DBC.h | 5 +- src/tools/mesh_extractor/MeshExtractor.cpp | 123 ++++++++++++++++++++++++- src/tools/mesh_extractor/Model.cpp | 29 ++++-- src/tools/mesh_extractor/Model.h | 2 + src/tools/mesh_extractor/ObjectDataHandler.cpp | 2 +- src/tools/mesh_extractor/TileBuilder.cpp | 4 +- src/tools/mesh_extractor/Utils.cpp | 36 ++++++-- src/tools/mesh_extractor/Utils.h | 3 + src/tools/mesh_extractor/WorldModelGroup.cpp | 2 +- 12 files changed, 183 insertions(+), 29 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/Chunk.cpp b/src/tools/mesh_extractor/Chunk.cpp index b41fa7d07d4..2f521f1badd 100644 --- a/src/tools/mesh_extractor/Chunk.cpp +++ b/src/tools/mesh_extractor/Chunk.cpp @@ -10,7 +10,7 @@ int32 Chunk::FindSubChunkOffset(std::string name) FILE* stream = GetStream(); uint32 matched = 0; - while (ftell(stream) < Utils::Size(stream)) + while (uint32(ftell(stream)) < Utils::Size(stream)) { char b; fread(&b, sizeof(char), 1, stream); diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h index f3b71812155..89cd6da20a2 100644 --- a/src/tools/mesh_extractor/Constants.h +++ b/src/tools/mesh_extractor/Constants.h @@ -47,6 +47,8 @@ public: static const float Origin[]; static const float PI; static const float MaxStandableHeight; + static bool ToWoWCoords; + static const char* VMAPMagic; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/DBC.cpp b/src/tools/mesh_extractor/DBC.cpp index be04ce070ee..c50e02014da 100644 --- a/src/tools/mesh_extractor/DBC.cpp +++ b/src/tools/mesh_extractor/DBC.cpp @@ -38,7 +38,7 @@ DBC::DBC( FILE* stream ) : StringBlock(NULL), IsFaulty(true), StringBlockSize(0) std::string DBC::GetStringByOffset( int offset ) { int len = 0; - for (int i = offset; i < StringBlockSize; i++) + for (uint32 i = offset; i < StringBlockSize; i++) { if (!StringBlock[i]) { diff --git a/src/tools/mesh_extractor/DBC.h b/src/tools/mesh_extractor/DBC.h index 6c86c1391dd..0c857bd40ed 100644 --- a/src/tools/mesh_extractor/DBC.h +++ b/src/tools/mesh_extractor/DBC.h @@ -37,9 +37,10 @@ public: return Values[index]; } - float GetFloat(int index) + template + T GetValue(int index) { - return *(float*)(&Values[index]); + return *(T*)(&Values[index]); } std::string GetString(int index) diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index d6b701607ba..8eb6ba5cb6e 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -4,6 +4,7 @@ #include "Cache.h" #include "DBC.h" #include "Constants.h" +#include "Model.h" #include @@ -70,6 +71,116 @@ void ExtractDBCs() printf("DBC extraction finished!\n"); } +void ExtractGameobjectModels() +{ + Constants::ToWoWCoords = true; + printf("Extracting GameObject models\n"); + + std::string baseBuildingsPath = "Buildings/"; + std::string baseVmapsPath = "vmaps/"; + Utils::CreateDir(baseVmapsPath); + Utils::CreateDir(baseBuildingsPath); + + FILE* modelList = fopen((baseVmapsPath + "GameObjectModels.list").c_str(), "wb"); + if (!modelList) + { + printf("Could not create file vmaps/GameObjectModels.list, please make sure that you have the write permissions in the folder\n"); + return; + } + + DBC* dbc = MPQHandler->GetDBC("GameObjectDisplayInfo"); + for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) + { + std::string path = (*itr)->GetString(1); + std::string fileName = Utils::GetPlainName(path.c_str()); + std::string extension = Utils::GetExtension(fileName); + // Convert the extension to lowercase + std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); + if (extension == "mdx" || extension == "m2") + { + fileName = Utils::FixModelPath(fileName); + Model model(path); + + if (model.IsBad) + continue; + + FILE* output = fopen((baseBuildingsPath + fileName).c_str(), "wb"); + if (!output) + { + printf("Could not create file %s, please check that you have write permissions\n", (baseBuildingsPath + fileName).c_str()); + continue; + } + // Placeholder for 0 values + int Nop[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + fwrite(Constants::VMAPMagic, 8, 1, output); + uint32 numVerts = model.Header.CountBoundingVertices; + fwrite(&numVerts, sizeof(uint32), 1, output); + uint32 numGroups = 1; + fwrite(&numGroups, sizeof(uint32), 1, output); + fwrite(Nop, 4 * 3 , 1, output); // rootwmoid, flags, groupid + fwrite(Nop, sizeof(float), 3 * 2, output);//bbox, only needed for WMO currently + fwrite(Nop, 4, 1, output);// liquidflags + fwrite("GRP ", 4, 1, output); + + uint32 branches = 1; + uint32 wsize = sizeof(branches) + sizeof(uint32) * branches; + fwrite(&wsize, sizeof(uint32), 1, output); + fwrite(&branches, sizeof(branches), 1, output); + uint32 numTris = model.Header.CountBoundingTriangles; + fwrite(&numTris, sizeof(uint32), 1, output); + fwrite("INDX", 4, 1, output); + wsize = sizeof(uint32) + sizeof(unsigned short) * numTris; + fwrite(&wsize, sizeof(int), 1, output); + fwrite(&numTris, sizeof(uint32), 1, output); + uint16* indices = new uint16[numTris]; + + if (numTris > 0) + { + uint32 i = 0; + for (std::vector >::iterator itr2 = model.Triangles.begin(); itr2 != model.Triangles.end(); ++itr2, ++i) + { + indices[i * 3 + 0] = itr2->V0; + indices[i * 3 + 1] = itr2->V1; + indices[i * 3 + 2] = itr2->V2; + } + fwrite(indices, sizeof(uint16), numTris, output); + } + + + fwrite("VERT", 4, 1, output); + wsize = sizeof(int) + sizeof(float) * 3 * numVerts; + fwrite(&wsize, sizeof(int), 1, output); + fwrite(&numVerts, sizeof(int), 1, output); + float* vertices = new float[numVerts*3]; + + if (numVerts > 0) + { + uint32 i = 0; + for (std::vector::iterator itr2 = model.Vertices.begin(); itr2 != model.Vertices.end(); ++itr2, ++i) + { + vertices[i * 3 + 0] = itr2->x; + vertices[i * 3 + 1] = itr2->y; + vertices[i * 3 + 2] = itr2->z; + } + + fwrite(vertices, sizeof(float), numVerts * 3, output); + } + + fclose(output); + delete[] indices; + delete[] vertices; + } + else if (extension == "wmo") + { + //WorldModelRoot model(path); + } + } + + printf("GameObject models extraction finished!"); + Constants::ToWoWCoords = false; +} + bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapList, bool& debugOutput, uint32& extractFlags) { char* param = NULL; @@ -141,7 +252,7 @@ void PrintUsage() printf("- %u to extract DBCs\n", Constants::EXTRACT_FLAG_DBC); printf("- %u to extract Maps (Not yet implemented)\n", Constants::EXTRACT_FLAG_MAPS); printf("- %u to extract VMaps (Not yet implemented)\n", Constants::EXTRACT_FLAG_VMAPS); - printf("- %u to extract GameObject models (Not yet implemented)\n", Constants::EXTRACT_FLAG_GOB_MODELS); + printf("- %u to extract GameObject models (Not yet finished)\n", Constants::EXTRACT_FLAG_GOB_MODELS); printf("- %u to extract MMaps (Not yet finished)\n", Constants::EXTRACT_FLAG_MMAPS); } } @@ -149,9 +260,6 @@ void PrintUsage() int main(int argc, char* argv[]) { system("pause"); - Cache = new CacheClass(); - MPQHandler = new MPQManager(); - MPQHandler->Initialize(); uint32 threads = 4, extractFlags = 0; std::set mapIds; bool debug = false; @@ -162,11 +270,18 @@ int main(int argc, char* argv[]) return -1; } + Cache = new CacheClass(); + MPQHandler = new MPQManager(); + MPQHandler->Initialize(); + if (extractFlags & Constants::EXTRACT_FLAG_DBC) ExtractDBCs(); if (extractFlags & Constants::EXTRACT_FLAG_MMAPS) ExtractMMaps(mapIds, threads, debug); + + if (extractFlags & Constants::EXTRACT_FLAG_GOB_MODELS) + ExtractGameobjectModels(); return 0; } \ No newline at end of file diff --git a/src/tools/mesh_extractor/Model.cpp b/src/tools/mesh_extractor/Model.cpp index a1c67d23f28..10fde0ebc2d 100644 --- a/src/tools/mesh_extractor/Model.cpp +++ b/src/tools/mesh_extractor/Model.cpp @@ -2,9 +2,14 @@ #include "MPQManager.h" #include "Utils.h" -Model::Model( std::string path ) +Model::Model( std::string path ) : IsCollidable(false), IsBad(false) { Stream = MPQHandler->GetFile(Utils::FixModelPath(path)); + if (!Stream) + { + IsBad = true; + return; + } Header.Read(Stream); if (Header.OffsetBoundingNormals > 0 && Header.OffsetBoundingVertices > 0 && Header.OffsetBoundingTriangles > 0 && Header.BoundingRadius > 0.0f) @@ -16,26 +21,36 @@ Model::Model( std::string path ) } } +Model::~Model() +{ + if (Stream) + fclose(Stream); +} + void Model::ReadVertices( FILE* stream ) { fseek(stream, Header.OffsetBoundingVertices, SEEK_SET); Vertices.reserve(Header.CountBoundingVertices); - for (int i = 0; i < Header.CountBoundingVertices; ++i) - Vertices[i] = Vector3::Read(stream); + for (uint32 i = 0; i < Header.CountBoundingVertices; ++i) + { + Vertices.push_back(Vector3::Read(stream)); + if (Constants::ToWoWCoords) + Vertices[i] = Utils::ToWoWCoords(Vertices[i]); + } } void Model::ReadBoundingTriangles( FILE* stream ) { fseek(stream, Header.OffsetBoundingTriangles, SEEK_SET); Triangles.reserve(Header.CountBoundingTriangles / 3); - for (int i = 0; i < Header.CountBoundingTriangles / 3; i++) + for (uint32 i = 0; i < Header.CountBoundingTriangles / 3; i++) { Triangle tri; tri.Type = Constants::TRIANGLE_TYPE_DOODAD; fread(&tri.V0, sizeof(uint16), 1, stream); fread(&tri.V1, sizeof(uint16), 1, stream); fread(&tri.V2, sizeof(uint16), 1, stream); - Triangles[i] = tri; + Triangles.push_back(tri); } } @@ -43,7 +58,7 @@ void Model::ReadBoundingNormals( FILE* stream ) { fseek(stream, Header.OffsetBoundingNormals, SEEK_SET); Normals.reserve(Header.CountBoundingNormals); - for (int i = 0; i < Header.CountBoundingNormals; i++) - Normals[i] = Vector3::Read(stream); + for (uint32 i = 0; i < Header.CountBoundingNormals; i++) + Normals.push_back(Vector3::Read(stream)); } diff --git a/src/tools/mesh_extractor/Model.h b/src/tools/mesh_extractor/Model.h index a5b8338461d..ea9331e7c30 100644 --- a/src/tools/mesh_extractor/Model.h +++ b/src/tools/mesh_extractor/Model.h @@ -7,6 +7,7 @@ class Model { public: Model(std::string path); + ~Model(); void ReadVertices(FILE* stream); void ReadBoundingTriangles(FILE* stream); @@ -17,5 +18,6 @@ public: std::vector > Triangles; bool IsCollidable; FILE* Stream; + bool IsBad; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/ObjectDataHandler.cpp b/src/tools/mesh_extractor/ObjectDataHandler.cpp index 3ed2ee49604..789efc6d62c 100644 --- a/src/tools/mesh_extractor/ObjectDataHandler.cpp +++ b/src/tools/mesh_extractor/ObjectDataHandler.cpp @@ -11,7 +11,7 @@ void ObjectDataHandler::ProcessMapChunk( MapChunk* chunk ) int32 firstIndex = Source->ObjectData->GetFirstIndex("MCNK"); if (firstIndex == -1) return; - if (firstIndex + chunk->Index > Source->ObjectData->Chunks.size()) + if (uint32(firstIndex + chunk->Index) > Source->ObjectData->Chunks.size()) return; Chunk* ourChunk = Source->ObjectData->Chunks[firstIndex + chunk->Index]; if (ourChunk->Length == 0) diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 5b3e181713e..12213b16373 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -88,9 +88,9 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) char buff[100]; sprintf(buff, "mmaps/%s_%02u%02u.obj", World.c_str(), Y, X); FILE* debug = fopen(buff, "wb"); - for (int i = 0; i < _Geometry->Vertices.size(); ++i) + for (uint32 i = 0; i < _Geometry->Vertices.size(); ++i) fprintf(debug, "v %f %f %f\n", _Geometry->Vertices[i].x, _Geometry->Vertices[i].y, _Geometry->Vertices[i].z); - for (int i = 0; i < _Geometry->Triangles.size(); ++i) + for (uint32 i = 0; i < _Geometry->Triangles.size(); ++i) fprintf(debug, "f %i %i %i\n", _Geometry->Triangles[i].V0 + 1, _Geometry->Triangles[i].V1 + 1, _Geometry->Triangles[i].V2 + 1); fclose(debug); } diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 5b752885d17..5fccd319554 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -19,6 +19,8 @@ const float Constants::UnitSize = Constants::ChunkSize / 8.0f; const float Constants::Origin[] = { -Constants::MaxXY, 0.0f, -Constants::MaxXY }; const float Constants::PI = 3.1415926f; const float Constants::MaxStandableHeight = 1.5f; +const char* Constants::VMAPMagic = "VMAP042"; +bool Constants::ToWoWCoords = false; void Utils::CreateDir( const std::string& Path ) { @@ -219,6 +221,21 @@ void Utils::SaveToDisk( FILE* stream, std::string path ) delete data; } +Vector3 Utils::ToWoWCoords( Vector3 vec ) +{ + return Vector3(vec.x, -vec.z, vec.y); +} + +std::string Utils::GetExtension( std::string path ) +{ + std::string::size_type idx = path.rfind('.'); + std::string extension = ""; + + if(idx != std::string::npos) + extension = path.substr(idx+1); + return extension; +} + void MapChunkHeader::Read(FILE* stream) { fread(&Flags, sizeof(uint32), 1, stream); @@ -308,16 +325,6 @@ void ModelHeader::Read(FILE* stream) fread(&OffsetTransLookup, sizeof(uint32), 1, stream); fread(&CountUvAnimLookup, sizeof(uint32), 1, stream); fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream); - fread(&CountColors, sizeof(uint32), 1, stream); - fread(&OffsetColors, sizeof(uint32), 1, stream); - fread(&CountTextures, sizeof(uint32), 1, stream); - fread(&OffsetTextures, sizeof(uint32), 1, stream); - fread(&CountTransparency, sizeof(uint32), 1, stream); - fread(&OffsetTransparency, sizeof(uint32), 1, stream); - fread(&CountUvAnimation, sizeof(uint32), 1, stream); - fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); - fread(&CountTexReplace, sizeof(uint32), 1, stream); - fread(&OffsetTexReplace, sizeof(uint32), 1, stream); VertexBox[0] = Vector3::Read(stream); VertexBox[1] = Vector3::Read(stream); fread(&VertexRadius, sizeof(float), 1, stream); @@ -468,3 +475,12 @@ H2OInformation H2OInformation::Read(FILE* stream) fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream); return ret; } + +char* Utils::GetPlainName(const char* FileName) +{ + char* temp; + + if((temp = (char*)strrchr(FileName, '\\')) != NULL) + FileName = temp + 1; + return (char*)FileName; +} \ No newline at end of file diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index c19bc1bb29c..47a6354d3b2 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -351,5 +351,8 @@ public: static G3D::Matrix4 GetWmoDoodadTransformation( DoodadInstance inst, WorldModelDefinition root ); static void CreateDir( const std::string& Path ); static void SaveToDisk(FILE* stream, std::string path); + static Vector3 ToWoWCoords( Vector3 vec ); + static std::string GetExtension( std::string path ); + static char* GetPlainName(const char* FileName); }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index bd0d106dabb..c7e6f0c525e 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -37,7 +37,7 @@ void WorldModelGroup::ReadNormals() Normals.reserve(normalCount); FILE* stream = chunk->GetStream(); for (uint32 i = 0; i < normalCount; i++) - Normals[i] = Vector3::Read(stream); + Normals.push_back(Vector3::Read(stream)); } void WorldModelGroup::ReadLiquid() -- cgit v1.2.3 From e31e251fda42f97844ad74892d364deb424a10b7 Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 4 Oct 2012 20:53:54 -0500 Subject: Tools/MeshExtractor: More progress on extracting GameObject models --- src/tools/mesh_extractor/MeshExtractor.cpp | 53 ++++++++++++++++++++++++++-- src/tools/mesh_extractor/Utils.cpp | 20 ++++++++++- src/tools/mesh_extractor/Utils.h | 19 ++++++++++ src/tools/mesh_extractor/WorldModelGroup.cpp | 27 ++++++++++---- src/tools/mesh_extractor/WorldModelGroup.h | 11 ++++-- 5 files changed, 117 insertions(+), 13 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 8eb6ba5cb6e..117a398d5cf 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -170,13 +170,62 @@ void ExtractGameobjectModels() fclose(output); delete[] indices; delete[] vertices; + + uint32 displayId = (*itr)->Values[0]; + uint32 pathLength = fileName.size(); + fwrite(&displayId, sizeof(uint32), 1, modelList); + fwrite(&pathLength, sizeof(uint32), 1, modelList); + fwrite(fileName.c_str(), sizeof(char), pathLength, modelList); } else if (extension == "wmo") { - //WorldModelRoot model(path); + WorldModelRoot model(path); + + FILE* output = fopen((baseBuildingsPath + fileName).c_str(), "wb"); + if (!output) + { + printf("Could not create file %s, please check that you have write permissions\n", (baseBuildingsPath + fileName).c_str()); + continue; + } + + fwrite(Constants::VMAPMagic, 1, 8, output); + uint32 numVertices = 0; + fwrite(&numVertices, sizeof(uint32), 1, output); // will be filled later + fwrite(&model.Header.CountGroups, sizeof(uint32), 1, output); + fwrite(&model.Header.WmoId, sizeof(uint32), 1, output); + + uint32 i = 0; + for (std::vector::iterator itr2 = model.Groups.begin(); itr2 != model.Groups.end(); ++itr2) + { + fwrite(&itr2->Header.Flags, sizeof(uint32), 1, output); + fwrite(&itr2->Header.WmoId, sizeof(uint32), 1, output); + fwrite(&itr2->Header.BoundingBox[0], sizeof(uint32), 1, output); + fwrite(&itr2->Header.BoundingBox[1], sizeof(uint32), 1, output); + uint32 LiquidFlags = itr2->HasLiquidData ? 1 : 0; + fwrite(&LiquidFlags, sizeof(uint32), 1, output); + + fwrite("GRP ", sizeof(char), 4, output); + uint32 k = 0; + uint32 mobaBatch = itr2->MOBALength / 12; + uint32* MobaEx = new uint32[mobaBatch*4]; + + for(uint32 i = 8; i < itr2->MOBALength; i += 12) + MobaEx[k++] = itr2->MOBA[i]; + + int mobaSizeGrp = mobaBatch * 4 + 4; + fwrite(&mobaSizeGrp, 4, 1, output); + fwrite(&mobaBatch, 4, 1, output); + fwrite(MobaEx, 4, k, output); + delete[] MobaEx; + + // Note: still not finished + } + + fclose(output); } } + fclose(modelList); printf("GameObject models extraction finished!"); Constants::ToWoWCoords = false; } @@ -252,7 +301,7 @@ void PrintUsage() printf("- %u to extract DBCs\n", Constants::EXTRACT_FLAG_DBC); printf("- %u to extract Maps (Not yet implemented)\n", Constants::EXTRACT_FLAG_MAPS); printf("- %u to extract VMaps (Not yet implemented)\n", Constants::EXTRACT_FLAG_VMAPS); - printf("- %u to extract GameObject models (Not yet finished)\n", Constants::EXTRACT_FLAG_GOB_MODELS); + printf("- %u to extract GameObject models (Not yet finished, you need to run VMapAssembler on the extracted files)\n", Constants::EXTRACT_FLAG_GOB_MODELS); printf("- %u to extract MMaps (Not yet finished)\n", Constants::EXTRACT_FLAG_MMAPS); } } diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 4414a02d681..b1b054e942e 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -483,4 +483,22 @@ char* Utils::GetPlainName(const char* FileName) if((temp = (char*)strrchr(FileName, '\\')) != NULL) FileName = temp + 1; return (char*)FileName; -} \ No newline at end of file +} + +WMOGroupHeader WMOGroupHeader::Read( FILE* stream ) +{ + WMOGroupHeader ret; + fread(&ret.OffsetGroupName, sizeof(uint32), 1, stream); + fread(&ret.OffsetDescriptiveName, sizeof(uint32), 1, stream); + fread(&ret.Flags, sizeof(uint32), 1, stream); + ret.BoundingBox[0] = Vector3::Read(stream); + ret.BoundingBox[1] = Vector3::Read(stream); + fread(&ret.OffsetPortals, sizeof(uint32), 1, stream); + fread(&ret.CountPortals, sizeof(uint32), 1, stream); + fread(&ret.CountBatches, sizeof(uint16), 4, stream); + fread(&ret.Fogs, sizeof(uint8), 4, stream); + fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); + fread(&ret.WmoId, sizeof(uint32), 1, stream); + + return ret; +} diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 47a6354d3b2..c5dd04fde06 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -289,6 +289,25 @@ public: static H2OInformation Read(FILE* stream); }; +class WMOGroupHeader +{ +public: + WMOGroupHeader() {} + + uint32 OffsetGroupName; + uint32 OffsetDescriptiveName; + uint32 Flags; + Vector3 BoundingBox[2]; + uint32 OffsetPortals; + uint32 CountPortals; + uint16 CountBatches[4]; + uint8 Fogs[4]; + uint32 LiquidTypeRelated; + uint32 WmoId; + + static WMOGroupHeader Read(FILE* stream); +}; + // Dummy class to act as an interface. class IDefinition { diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index c7e6f0c525e..35a5ba69782 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -1,8 +1,9 @@ #include "WorldModelGroup.h" #include "ChunkedData.h" #include "Chunk.h" +#include "Utils.h" -WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), IsBad(false) +WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), IsBad(false), MOBA(NULL) { Data = new ChunkedData(path); if (!Data->Stream) @@ -14,16 +15,20 @@ WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupInde int32 firstSub = mainChunk->FindSubChunkOffset("MOPY"); if (firstSub == -1) return; + + Name = Utils::GetPlainName(path.c_str()); + FILE* stream = mainChunk->GetStream(); fseek(stream, firstSub, SEEK_SET); SubData = new ChunkedData(stream, mainChunk->Length - firstSub); - ReadBoundingBox(); + ReadHeader(); ReadMaterials(); ReadTriangles(); ReadVertices(); ReadNormals(); ReadLiquid(); + ReadBatches(); } void WorldModelGroup::ReadNormals() @@ -108,15 +113,23 @@ void WorldModelGroup::ReadMaterials() } } -void WorldModelGroup::ReadBoundingBox() +void WorldModelGroup::ReadHeader() { Chunk* chunk = Data->GetChunkByName("MOGP"); if (!chunk) return; FILE* stream = chunk->GetStream(); - fseek(stream, 8, SEEK_CUR); - fread(&Flags, sizeof(uint32), 1, stream); - BoundingBox[0] = Vector3::Read(stream); - BoundingBox[1] = Vector3::Read(stream); + Header = WMOGroupHeader::Read(stream); +} + +void WorldModelGroup::ReadBatches() +{ + Chunk* chunk = Data->GetChunkByName("MOBA"); + if (!chunk) + return; + + MOBALength = chunk->Length / 2; + MOBA = new uint16[MOBALength]; + fread(MOBA, sizeof(uint16), MOBALength, chunk->GetStream()); } diff --git a/src/tools/mesh_extractor/WorldModelGroup.h b/src/tools/mesh_extractor/WorldModelGroup.h index 1dc754d0221..e4fe34cbc75 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.h +++ b/src/tools/mesh_extractor/WorldModelGroup.h @@ -10,13 +10,17 @@ public: ChunkedData* Data; ChunkedData* SubData; int GroupIndex; - Vector3 BoundingBox[2]; - uint32 Flags; + std::string Name; + WMOGroupHeader Header; + std::vector TriangleFlags; std::vector TriangleMaterials; std::vector > Triangles; std::vector Vertices; std::vector Normals; + // @ToDo: Research. + uint16* MOBA; + uint32 MOBALength; bool HasLiquidData; bool IsBad; @@ -28,6 +32,7 @@ private: void ReadVertices(); void ReadTriangles(); void ReadMaterials(); - void ReadBoundingBox(); + void ReadHeader(); + void ReadBatches(); }; #endif \ No newline at end of file -- cgit v1.2.3 From 509c8d0baefa7d8e0edbca5c9f1bb2c0d81149a4 Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 4 Oct 2012 20:59:59 -0500 Subject: Tools/MeshExtractor: Fixed build --- src/tools/mesh_extractor/MeshExtractor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 117a398d5cf..accccf4460f 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -252,9 +252,9 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis if (!param) return false; std::string maps = std::string(param); - Tokens tokens(maps, ','); + Tokenizer tokens(maps, ','); - for (Tokens::iterator itr = tokens.begin(); itr != tokens.end(); ++itr) + for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr) mapList.insert(atoi(*itr)); printf("Extracting only provided list of maps (%u).\n", mapList.size()); -- cgit v1.2.3 From 19d7f68592d653067c3b84c3d409e59b2724a85d Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 20 Oct 2012 07:17:11 -0500 Subject: Tools/MeshExtractor: Changed some things, lots of thanks to Faramir. --- src/tools/mesh_extractor/Constants.h | 17 +- src/tools/mesh_extractor/ContinentBuilder.cpp | 44 ++--- src/tools/mesh_extractor/ContinentBuilder.h | 10 +- src/tools/mesh_extractor/MeshExtractor.cpp | 82 +++++++++ src/tools/mesh_extractor/TileBuilder.cpp | 231 +++++++++++++++----------- src/tools/mesh_extractor/TileBuilder.h | 4 +- src/tools/mesh_extractor/Utils.cpp | 4 + 7 files changed, 265 insertions(+), 127 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h index 89cd6da20a2..54fa073fbef 100644 --- a/src/tools/mesh_extractor/Constants.h +++ b/src/tools/mesh_extractor/Constants.h @@ -32,12 +32,13 @@ public: enum ExtractFlags { - EXTRACT_FLAG_DBC = 1, - EXTRACT_FLAG_MAPS = 2, - EXTRACT_FLAG_VMAPS = 4, - EXTRACT_FLAG_GOB_MODELS = 8, - EXTRACT_FLAG_MMAPS = 16, - EXTRACT_FLAG_ALLOWED = EXTRACT_FLAG_DBC | EXTRACT_FLAG_MAPS | EXTRACT_FLAG_VMAPS | EXTRACT_FLAG_GOB_MODELS | EXTRACT_FLAG_MMAPS + EXTRACT_FLAG_DBC = 0x01, + EXTRACT_FLAG_MAPS = 0x02, + EXTRACT_FLAG_VMAPS = 0x04, + EXTRACT_FLAG_GOB_MODELS = 0x08, + EXTRACT_FLAG_MMAPS = 0x10, + EXTRACT_FLAG_TEST = 0x20, + EXTRACT_FLAG_ALLOWED = EXTRACT_FLAG_DBC | EXTRACT_FLAG_MAPS | EXTRACT_FLAG_VMAPS | EXTRACT_FLAG_GOB_MODELS | EXTRACT_FLAG_MMAPS | EXTRACT_FLAG_TEST }; static const float TileSize; @@ -49,6 +50,10 @@ public: static const float MaxStandableHeight; static bool ToWoWCoords; static const char* VMAPMagic; + static const float BaseUnitDim; + static const int VertexPerMap; + static const int VertexPerTile; + static const int TilesPerMap; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index e4a1d2ca9f4..013c0ff256a 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -14,15 +14,16 @@ private: std::string Continent; bool debug; dtNavMeshParams Params; + ContinentBuilder* cBuilder; public: - BuilderThread(bool deb, dtNavMeshParams& params) : Free(true), debug(deb), Params(params) {} + BuilderThread(ContinentBuilder* _cBuilder, bool deb, dtNavMeshParams& params) : Free(true), debug(deb), Params(params), cBuilder(_cBuilder) {} void SetData(int x, int y, int map, std::string cont) { X = x; Y = y; MapId = map; Continent = cont; } int svc() { Free = false; printf("[%02i,%02i] Building tile\n", X, Y); - TileBuilder builder(Continent, X, Y, MapId); + TileBuilder builder(cBuilder, Continent, X, Y, MapId); char buff[100]; sprintf(buff, "mmaps/%03u%02u%02u.mmtile", MapId, Y, X); FILE* f = fopen(buff, "r"); @@ -57,7 +58,7 @@ public: bool Free; }; -void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) +void ContinentBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) { // this is for elevation if (verts && vertCount) @@ -75,18 +76,8 @@ void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, floa bmin[2] = bmax[2] - Constants::TileSize; } -void ContinentBuilder::Build(bool debug) +void ContinentBuilder::CalculateTileBounds() { - char buff[50]; - sprintf(buff, "mmaps/%03u.mmap", MapId); - FILE* mmap = fopen(buff, "wb"); - if (!mmap) - { - printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); - return; - } - - int tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0; for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { tileXMax = std::max(itr->X, tileXMax); @@ -95,24 +86,33 @@ void ContinentBuilder::Build(bool debug) tileYMax = std::max(itr->Y, tileYMax); tileYMin = std::min(itr->Y, tileYMin); } - - float bmin[3], bmax[3]; getTileBounds(tileXMax, tileYMax, NULL, 0, bmin, bmax); +} + +void ContinentBuilder::Build(bool debug) +{ + char buff[50]; + sprintf(buff, "mmaps/%03u.mmap", MapId); + FILE* mmap = fopen(buff, "wb"); + if (!mmap) + { + printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); + return; + } + CalculateTileBounds(); + dtNavMeshParams params; - params.maxPolys = 32768; + params.maxPolys = 1 << STATIC_POLY_BITS; params.maxTiles = TileMap->TileTable.size(); - // rcVcopy(params.orig, bmin); - params.orig[0] = Constants::Origin[0]; - params.orig[1] = 0; - params.orig[2] = Constants::Origin[2]; + rcVcopy(params.orig, bmin); params.tileHeight = Constants::TileSize; params.tileWidth = Constants::TileSize; fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); fclose(mmap); std::vector Threads; for (uint32 i = 0; i < NumberOfThreads; ++i) - Threads.push_back(new BuilderThread(debug, params)); + Threads.push_back(new BuilderThread(this, debug, params)); printf("Map %s ( %i ) has %i tiles. Building them with %i threads\n", Continent.c_str(), MapId, TileMap->TileTable.size(), NumberOfThreads); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h index c923498fc5e..4c16fa0727e 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -7,12 +7,20 @@ class ContinentBuilder { public: - ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : MapId(mapId), Continent(continent), TileMap(wdt), NumberOfThreads(tn) {} + ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : MapId(mapId), Continent(continent), TileMap(wdt), NumberOfThreads(tn), tileXMin(64), tileYMin(64), tileXMax(0), tileYMax(0) {} void Build(bool debug); + void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax); + void CalculateTileBounds(); + float bmin[3]; + float bmax[3]; private: std::string Continent; WDT* TileMap; uint32 MapId; uint32 NumberOfThreads; + int tileXMin; + int tileYMin; + int tileXMax; + int tileYMax; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index accccf4460f..7379ba87117 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -6,6 +6,10 @@ #include "Constants.h" #include "Model.h" +#include "Recast.h" +#include "DetourNavMesh.h" +#include "DetourNavMeshQuery.h" + #include #include "Common.h" @@ -306,6 +310,19 @@ void PrintUsage() } } +void LoadTile(dtNavMesh*& navMesh, const char* tile) +{ + FILE* f = fopen(tile, "rb"); + MmapTileHeader header; + fread(&header, sizeof(MmapTileHeader), 1, f); + uint8* nav = new uint8[header.size]; + fread(nav, header.size, 1, f); + + dtStatus res = navMesh->addTile(nav, header.size, DT_TILE_FREE_DATA, 0, NULL); + + fclose(f); +} + int main(int argc, char* argv[]) { system("pause"); @@ -331,6 +348,71 @@ int main(int argc, char* argv[]) if (extractFlags & Constants::EXTRACT_FLAG_GOB_MODELS) ExtractGameobjectModels(); + + if (extractFlags & Constants::EXTRACT_FLAG_TEST) + { + float start[] = { 0.0f, 0.0f, 0.0f }; + float end[] = { 0.0f, 0.0f, 0.0f }; + + // + float m_spos[3]; + m_spos[0] = -1.0f * start[1]; + m_spos[1] = start[2]; + m_spos[2] = -1.0f * start[0]; + + // + float m_epos[3]; + m_epos[0] = -1.0f * end[1]; + m_epos[1] = end[2]; + m_epos[2] = -1.0f * end[0]; + + // + dtQueryFilter m_filter; + m_filter.setIncludeFlags(0xffff) ; + m_filter.setExcludeFlags(0); + + // + float m_polyPickExt[3]; + m_polyPickExt[0] = 2; + m_polyPickExt[1] = 4; + m_polyPickExt[2] = 2; + + // + dtPolyRef m_startRef; + dtPolyRef m_endRef; + + FILE* mmap = fopen(".mmap", "rb"); + dtNavMeshParams params; + fread(¶ms, sizeof(dtNavMeshParams), 1, mmap); + fclose(mmap); + + dtNavMesh* navMesh = new dtNavMesh(); + dtNavMeshQuery* navMeshQuery = new dtNavMeshQuery(); + + navMesh->init(¶ms); + LoadTile(navMesh, ".mmtile"); + LoadTile(navMesh, ".mmtile"); + LoadTile(navMesh, ".mmtile"); + LoadTile(navMesh, ".mmtile"); + LoadTile(navMesh, ".mmtile"); + LoadTile(navMesh, ".mmtile"); + + navMeshQuery->init(navMesh, 2048); + + float nearestPt[3]; + + dtStatus status = navMeshQuery->findNearestPoly(m_spos, m_polyPickExt, &m_filter, &m_startRef, nearestPt); + status = navMeshQuery->findNearestPoly(m_epos, m_polyPickExt, &m_filter, &m_endRef, nearestPt); + + // + if ( !m_startRef || !m_endRef ) + { + std::cerr << "Could not find any nearby poly's (" << m_startRef << "," << m_endRef << ")" << std::endl; + return 0; + } + + printf("Found!"); + } return 0; } \ No newline at end of file diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 12213b16373..2a02bc50cd4 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -1,3 +1,4 @@ +#include "ContinentBuilder.h" #include "TileBuilder.h" #include "Geometry.h" #include "Constants.h" @@ -11,8 +12,10 @@ #include "ace/Synch.h" -TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0) +TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0), cBuilder(_cBuilder) { + /* + Test, non-working values // Cell Size = TileSize / TileVoxelSize // 1800 = TileVoxelSize Config.cs = Constants::TileSize / 1800; @@ -35,6 +38,26 @@ TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geome Config.height = 1800 + Config.borderSize * 2; Config.maxVertsPerPoly = 6; Config.maxSimplificationError = 1.3f; + */ + + // All are in UNIT metrics! + memset(&Config, 0, sizeof(rcConfig)); + + Config.maxVertsPerPoly = DT_VERTS_PER_POLYGON; + Config.cs = Constants::BaseUnitDim; + Config.ch = Constants::BaseUnitDim; + Config.walkableSlopeAngle = 60.0f; + Config.tileSize = Constants::VertexPerTile; + Config.walkableRadius = 1; + Config.borderSize = Config.walkableRadius + 3; + Config.maxEdgeLen = Constants::VertexPerTile + 1; //anything bigger than tileSize + Config.walkableHeight = 3; + Config.walkableClimb = 2; // keep less than walkableHeight + Config.minRegionArea = rcSqr(60); + Config.mergeRegionArea = rcSqr(50); + Config.maxSimplificationError = 2.0f; // eliminates most jagged edges (tinny polygons) + Config.detailSampleDist = Config.cs * 64; + Config.detailSampleMaxError = Config.ch * 2; Context = new rcContext; } @@ -104,84 +127,101 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) _Geometry->Vertices.clear(); _Geometry->Triangles.clear(); - float bbMin[3]; - float bbMax[3]; - // CalculateTileBounds(bbMin, bbMax, navMeshParams); - rcCalcBounds(vertices, numVerts, bbMin, bbMax); - // _Geometry->CalculateMinMaxHeight(bbMin[1], bbMax[1]); - - /*bbMin[0] -= Config.borderSize * Config.cs; - bbMin[2] -= Config.borderSize * Config.cs; - bbMax[0] += Config.borderSize * Config.cs; - bbMax[0] += Config.borderSize * Config.cs;*/ - - - rcHeightfield* hf = rcAllocHeightfield(); - int height, width; - rcCalcGridSize(bbMin, bbMax, Config.cs, &width, &height); - printf("Config values: Height: %i, Width: %i. Calculated values: Height: %i, Width: %i\n", Config.height, Config.width, height, width); - rcCreateHeightfield(Context, *hf, width, height, bbMin, bbMax, Config.cs, Config.ch); - rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); - rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); - - printf("[%02i,%02i] Triangles rasterized!\n", X, Y); - - // Once all geometry is rasterized, we do initial pass of filtering to - // remove unwanted overhangs caused by the conservative rasterization - // as well as filter spans where the character cannot possibly stand. - rcFilterLowHangingWalkableObstacles(Context, Config.walkableClimb, *hf); - rcFilterLedgeSpans(Context, Config.walkableHeight, Config.walkableClimb, *hf); - rcFilterWalkableLowHeightSpans(Context, Config.walkableHeight, *hf); - - printf("[%02i,%02i] Filtering done!\n", X, Y); - - // Compact the heightfield so that it is faster to handle from now on. - // This will result in more cache coherent data as well as the neighbours - // between walkable cells will be calculated. - rcCompactHeightfield* chf = rcAllocCompactHeightfield(); - rcBuildCompactHeightfield(Context, Config.walkableHeight, Config.walkableClimb, *hf, *chf); - - rcFreeHeightField(hf); - - printf("[%02i,%02i] Heightfield compressed!\n", X, Y); - - // Erode the walkable area by agent radius. - rcErodeWalkableArea(Context, Config.walkableRadius, *chf); - // Prepare for region partitioning, by calculating distance field along the walkable surface. - rcBuildDistanceField(Context, *chf); - // Partition the walkable surface into simple regions without holes. - rcBuildRegions(Context, *chf, Config.borderSize, Config.minRegionArea, Config.mergeRegionArea); + + rcVcopy(Config.bmin, cBuilder->bmin); + rcVcopy(Config.bmax, cBuilder->bmax); + + // this sets the dimensions of the heightfield - should maybe happen before border padding + rcCalcGridSize(Config.bmin, Config.bmax, Config.cs, &Config.width, &Config.height); + + // Initialize per tile config. + rcConfig tileCfg = Config; + tileCfg.width = Config.tileSize + Config.borderSize * 2; + tileCfg.height = Config.tileSize + Config.borderSize * 2; - printf("[%02i,%02i] Regions built!\n", X, Y); + // merge per tile poly and detail meshes + rcPolyMesh** pmmerge = new rcPolyMesh*[Constants::TilesPerMap * Constants::TilesPerMap]; + rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[Constants::TilesPerMap * Constants::TilesPerMap]; - // Create contours. - rcContourSet* cset = rcAllocContourSet(); - rcBuildContours(Context, *chf, Config.maxSimplificationError, Config.maxEdgeLen, *cset); + int nmerge = 0; + for (int y = 0; y < Constants::TilesPerMap; ++y) + { + for (int x = 0; x < Constants::TilesPerMap; ++x) + { + // Calculate the per tile bounding box. + tileCfg.bmin[0] = Config.bmin[0] + float(x * Config.tileSize - Config.borderSize) * Config.cs; + tileCfg.bmin[2] = Config.bmin[2] + float(y * Config.tileSize - Config.borderSize) * Config.cs; + tileCfg.bmax[0] = Config.bmin[0] + float((x + 1) * Config.tileSize + Config.borderSize) * Config.cs; + tileCfg.bmax[2] = Config.bmin[2] + float((y + 1) * Config.tileSize + Config.borderSize) * Config.cs; + + + rcHeightfield* hf = rcAllocHeightfield(); + rcCreateHeightfield(Context, *hf, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch); + rcClearUnwalkableTriangles(Context, tileCfg.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); + rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); + + // Once all geometry is rasterized, we do initial pass of filtering to + // remove unwanted overhangs caused by the conservative rasterization + // as well as filter spans where the character cannot possibly stand. + rcFilterLowHangingWalkableObstacles(Context, Config.walkableClimb, *hf); + rcFilterLedgeSpans(Context, tileCfg.walkableHeight, tileCfg.walkableClimb, *hf); + rcFilterWalkableLowHeightSpans(Context, tileCfg.walkableHeight, *hf); + + // Compact the heightfield so that it is faster to handle from now on. + // This will result in more cache coherent data as well as the neighbours + // between walkable cells will be calculated. + rcCompactHeightfield* chf = rcAllocCompactHeightfield(); + rcBuildCompactHeightfield(Context, tileCfg.walkableHeight, tileCfg.walkableClimb, *hf, *chf); + + rcFreeHeightField(hf); + + // Erode the walkable area by agent radius. + rcErodeWalkableArea(Context, Config.walkableRadius, *chf); + // Prepare for region partitioning, by calculating distance field along the walkable surface. + rcBuildDistanceField(Context, *chf); + // Partition the walkable surface into simple regions without holes. + rcBuildRegions(Context, *chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea); + + // Create contours. + rcContourSet* cset = rcAllocContourSet(); + rcBuildContours(Context, *chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *cset); + + // Build polygon navmesh from the contours. + rcPolyMesh* pmesh = rcAllocPolyMesh(); + rcBuildPolyMesh(Context, *cset, tileCfg.maxVertsPerPoly, *pmesh); + + // Build detail mesh. + rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); + rcBuildPolyMeshDetail(Context, *pmesh, *chf, tileCfg.detailSampleDist, tileCfg.detailSampleMaxError, *dmesh); + + // Free memory + rcFreeCompactHeightfield(chf); + rcFreeContourSet(cset); + + pmmerge[nmerge] = pmesh; + dmmerge[nmerge] = dmesh; + ++nmerge; + } + } - // Build polygon navmesh from the contours. rcPolyMesh* pmesh = rcAllocPolyMesh(); - rcBuildPolyMesh(Context, *cset, Config.maxVertsPerPoly, *pmesh); - - printf("[%02i,%02i] Polymesh built!\n", X, Y); - - // Build detail mesh. + rcMergePolyMeshes(Context, pmmerge, nmerge, *pmesh); + rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); - rcBuildPolyMeshDetail(Context, *pmesh, *chf, Config.detailSampleDist, Config.detailSampleMaxError, *dmesh); - - printf("[%02i,%02i] Polymesh detail built!\n", X, Y); - - rcFreeCompactHeightfield(chf); - rcFreeContourSet(cset); - - /* - * Removed with RecastNavigation v292 + rcMergePolyMeshDetails(Context, dmmerge, nmerge, *dmesh); + + delete[] pmmerge; + delete[] dmmerge; + + printf("[%02i,%02i] Meshes merged!\n", X, Y); + // Remove padding from the polymesh data. (Remove this odditity) for (int i = 0; i < pmesh->nverts; ++i) { unsigned short* v = &pmesh->verts[i * 3]; v[0] -= (unsigned short)Config.borderSize; v[2] -= (unsigned short)Config.borderSize; - }*/ + } // Set flags according to area types (e.g. Swim for Water) for (int i = 0; i < pmesh->npolys; i++) @@ -192,14 +232,8 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) pmesh->flags[i] = Constants::POLY_FLAG_SWIM; } - // get original bounds - /*float* tilebMin; - float* tilebMax; - CalculateTileBounds(tilebMin, tilebMax, navMeshParams); - tilebMin[1] = bbMin[1]; - tilebMax[1] = bbMax[1];*/ - dtNavMeshCreateParams params; + memset(¶ms, 0, sizeof(params)); // PolyMesh data params.verts = pmesh->verts; params.vertCount = pmesh->nverts; @@ -214,32 +248,39 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) params.detailVertsCount = dmesh->nverts; params.detailTris = dmesh->tris; params.detailTriCount = dmesh->ntris; - // Copy bounding box - /*params.bmin[0] = tilebMin[0]; - params.bmin[1] = tilebMin[1]; - params.bmin[2] = tilebMin[2]; - params.bmax[0] = tilebMax[0]; - params.bmax[1] = tilebMax[1]; - params.bmax[2] = tilebMax[2];*/ rcVcopy(params.bmin, pmesh->bmin); rcVcopy(params.bmax, pmesh->bmax); // General settings params.ch = Config.ch; params.cs = Config.cs; - params.walkableClimb = Config.walkableClimb; - params.walkableHeight = Config.walkableHeight; - params.walkableRadius = Config.walkableRadius; - params.tileX = X; - params.tileY = Y; - int _x = (((pmesh->bmin[0] + pmesh->bmax[0]) / 2) - Constants::Origin[0]) / Constants::TileSize; - int _y = (((pmesh->bmin[2] + pmesh->bmax[2]) / 2) - Constants::Origin[2]) / Constants::TileSize; - printf("[%02i,%02i] Generated with TileX: %i and TileY: %i\nbmin[0] %f bmin[1] %f bmin[2] %f bmax[0] %f bmax[1] %f bmax[2] %f\n", X, Y, _x, _y, params.bmin[0], params.bmin[1], params.bmin[2], params.bmax[0], params.bmax[1], params.bmax[2]); - params.buildBvTree = true; - params.tileLayer = 0; - + params.walkableClimb = Constants::BaseUnitDim * Config.walkableClimb; + params.walkableHeight = Constants::BaseUnitDim * Config.walkableHeight; + params.walkableRadius = Constants::BaseUnitDim * Config.walkableRadius; + params.tileX = (((cBuilder->bmin[0] + cBuilder->bmax[0]) / 2) - navMeshParams.orig[0]) / Constants::TileSize; + params.tileY = (((cBuilder->bmin[2] + cBuilder->bmax[2]) / 2) - navMeshParams.orig[2]) / Constants::TileSize; + + rcVcopy(params.bmin, cBuilder->bmin); + rcVcopy(params.bmax, cBuilder->bmax); + // Offmesh-connection settings params.offMeshConCount = 0; // none for now + + params.tileSize = Constants::VertexPerMap; + if (!params.polyCount || !params.polys || Constants::TilesPerMap * Constants::TilesPerMap == params.polyCount) + { + // 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 + // drop tiles with only exact count - some tiles may have geometry while having less tiles + printf("[%02i,%02i] No polygons to build on tile, skipping.\n", X, Y); + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + delete areas; + delete triangles; + delete vertices; + return NULL; + } + int navDataSize; uint8* navData; printf("[%02i,%02i] Creating the navmesh with %i vertices, %i polys, %i triangles!\n", X, Y, pmesh->nverts, pmesh->npolys, dmesh->ntris); @@ -248,13 +289,9 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) // Free some memory rcFreePolyMesh(pmesh); rcFreePolyMeshDetail(dmesh); - //delete tilebMax; - //delete tilebMin; delete areas; delete triangles; delete vertices; - //delete bbMax; - //delete bbMin; if (result) { diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index 17d6e48095a..40c96f6ec42 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -5,12 +5,13 @@ #include "Geometry.h" +class ContinentBuilder; class WDT; class TileBuilder { public: - TileBuilder(std::string world, int x, int y, uint32 mapId); + TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId); ~TileBuilder(); void CalculateTileBounds(float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams); @@ -24,5 +25,6 @@ public: rcContext* Context; Geometry* _Geometry; uint32 DataSize; + ContinentBuilder* cBuilder; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index b1b054e942e..3639cb88acf 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -21,6 +21,10 @@ const float Constants::PI = 3.1415926f; const float Constants::MaxStandableHeight = 1.5f; const char* Constants::VMAPMagic = "VMAP041"; bool Constants::ToWoWCoords = false; +const float Constants::BaseUnitDim = 0.533333f; +const int Constants::VertexPerMap = (Constants::TileSize / Constants::BaseUnitDim) + 0.5f; +const int Constants::VertexPerTile = 40; +const int Constants::TilesPerMap = Constants::VertexPerMap / Constants::VertexPerTile; void Utils::CreateDir( const std::string& Path ) { -- cgit v1.2.3 From 5f15600e7a26170f0aacc77e9417df61db45a992 Mon Sep 17 00:00:00 2001 From: Spp Date: Wed, 9 Jan 2013 13:13:39 +0100 Subject: Core/Build: Fix linking and sooo many compile warnings --- src/server/collision/Management/MMapManager.cpp | 14 +- src/server/collision/Models/ModelInstance.h | 2 +- src/tools/map_extractor/adt.cpp | 21 +- src/tools/map_extractor/loadlib.cpp | 4 +- src/tools/map_extractor/loadlib/loadlib.h | 6 + src/tools/map_extractor/wdt.cpp | 12 +- src/tools/mesh_extractor/ADT.cpp | 4 +- src/tools/mesh_extractor/CMakeLists.txt | 3 +- src/tools/mesh_extractor/Cache.h | 4 +- src/tools/mesh_extractor/Chunk.cpp | 10 +- src/tools/mesh_extractor/ChunkedData.cpp | 3 +- src/tools/mesh_extractor/ContinentBuilder.cpp | 4 +- src/tools/mesh_extractor/ContinentBuilder.h | 8 +- src/tools/mesh_extractor/DBC.cpp | 22 +- src/tools/mesh_extractor/DoodadHandler.cpp | 6 +- src/tools/mesh_extractor/DoodadHandler.h | 14 +- src/tools/mesh_extractor/LiquidHandler.cpp | 10 +- src/tools/mesh_extractor/MapChunk.cpp | 3 +- src/tools/mesh_extractor/MeshExtractor.cpp | 36 ++- src/tools/mesh_extractor/Model.cpp | 9 +- src/tools/mesh_extractor/TileBuilder.cpp | 5 +- src/tools/mesh_extractor/Utils.cpp | 354 ++++++++++++++---------- src/tools/mesh_extractor/Utils.h | 4 +- src/tools/mesh_extractor/WDT.cpp | 11 +- src/tools/mesh_extractor/WorldModelGroup.cpp | 22 +- src/tools/mesh_extractor/WorldModelHandler.cpp | 20 +- src/tools/mmaps_generator/CMakeLists.txt | 2 +- src/tools/mmaps_generator/IntermediateValues.h | 2 +- src/tools/mmaps_generator/MapBuilder.cpp | 45 +-- src/tools/mmaps_generator/PathCommon.h | 2 +- src/tools/mmaps_generator/TerrainBuilder.cpp | 92 +++--- src/tools/mmaps_generator/TerrainBuilder.h | 1 - src/tools/mmaps_generator/VMapExtensions.cpp | 2 +- src/tools/vmap4_extractor/adtfile.cpp | 3 +- src/tools/vmap4_extractor/model.cpp | 4 +- src/tools/vmap4_extractor/vmapexport.cpp | 3 +- src/tools/vmap4_extractor/wmo.cpp | 4 +- 37 files changed, 468 insertions(+), 303 deletions(-) (limited to 'src/tools') diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp index c7dea358d92..1b6cf5c0260 100644 --- a/src/server/collision/Management/MMapManager.cpp +++ b/src/server/collision/Management/MMapManager.cpp @@ -52,8 +52,14 @@ namespace MMAP } dtNavMeshParams params; - fread(¶ms, sizeof(dtNavMeshParams), 1, file); + int count = fread(¶ms, sizeof(dtNavMeshParams), 1, file); fclose(file); + if (count != 1) + { + sLog->outDebug(LOG_FILTER_MAPS, "MMAP:loadMapData: Error: Could not read params from file '%s'", fileName); + delete [] fileName; + return false; + } dtNavMesh* mesh = dtAllocNavMesh(); ASSERT(mesh); @@ -82,7 +88,7 @@ namespace MMAP return uint32(x << 16 | y); } - bool MMapManager::loadMap(const std::string& basePath, uint32 mapId, int32 x, int32 y) + bool MMapManager::loadMap(const std::string& /*basePath*/, uint32 mapId, int32 x, int32 y) { // make sure the mmap is loaded and ready to load tiles if (!loadMapData(mapId)) @@ -114,9 +120,7 @@ namespace MMAP // read header MmapTileHeader fileHeader; - fread(&fileHeader, sizeof(MmapTileHeader), 1, file); - - if (fileHeader.mmapMagic != MMAP_MAGIC) + if (fread(&fileHeader, sizeof(MmapTileHeader), 1, file) != 1 || fileHeader.mmapMagic != MMAP_MAGIC) { sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Bad header in mmap %03u%02i%02i.mmtile", mapId, x, y); return false; diff --git a/src/server/collision/Models/ModelInstance.h b/src/server/collision/Models/ModelInstance.h index 6d1b7c68bd5..f26089bb46c 100644 --- a/src/server/collision/Models/ModelInstance.h +++ b/src/server/collision/Models/ModelInstance.h @@ -75,7 +75,7 @@ namespace VMAP float iInvScale; WorldModel* iModel; public: - WorldModel* const getWorldModel(); + WorldModel* getWorldModel(); }; } // namespace VMAP diff --git a/src/tools/map_extractor/adt.cpp b/src/tools/map_extractor/adt.cpp index fde70681113..505813c4bd0 100644 --- a/src/tools/map_extractor/adt.cpp +++ b/src/tools/map_extractor/adt.cpp @@ -6,6 +6,13 @@ int holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888}; int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; +u_map_fcc MHDRMagic = { {'M','H','D','R'} }; +u_map_fcc MCINMagic = { {'M','C','I','N'} }; +u_map_fcc MH20Magic = { {'M','H','2','0'} }; +u_map_fcc MCNKMagic = { {'M','C','N','K'} }; +u_map_fcc MCVTMagic = { {'M','C','V','T'} }; +u_map_fcc MCLQMagic = { {'M','C','L','Q'} }; + bool isHole(int holes, int i, int j) { int testi = i / 2; @@ -53,7 +60,7 @@ bool ADT_file::prepareLoadedData() bool adt_MHDR::prepareLoadedData() { - if (fcc != 'MHDR') + if (fcc != MHDRMagic.fcc) return false; if (size!=sizeof(adt_MHDR)-8) @@ -72,7 +79,7 @@ bool adt_MHDR::prepareLoadedData() bool adt_MCIN::prepareLoadedData() { - if (fcc != 'MCIN') + if (fcc != MCINMagic.fcc) return false; // Check cells data @@ -86,7 +93,7 @@ bool adt_MCIN::prepareLoadedData() bool adt_MH2O::prepareLoadedData() { - if (fcc != 'MH2O') + if (fcc != MH20Magic.fcc) return false; // Check liquid data @@ -98,7 +105,7 @@ bool adt_MH2O::prepareLoadedData() bool adt_MCNK::prepareLoadedData() { - if (fcc != 'MCNK') + if (fcc != MCNKMagic.fcc) return false; // Check height map @@ -113,7 +120,7 @@ bool adt_MCNK::prepareLoadedData() bool adt_MCVT::prepareLoadedData() { - if (fcc != 'MCVT') + if (fcc != MCVTMagic.fcc) return false; if (size != sizeof(adt_MCVT)-8) @@ -124,8 +131,8 @@ bool adt_MCVT::prepareLoadedData() bool adt_MCLQ::prepareLoadedData() { - if (fcc != 'MCLQ') + if (fcc != MCLQMagic.fcc) return false; return true; -} \ No newline at end of file +} diff --git a/src/tools/map_extractor/loadlib.cpp b/src/tools/map_extractor/loadlib.cpp index 465eb04083f..d1ea40110de 100644 --- a/src/tools/map_extractor/loadlib.cpp +++ b/src/tools/map_extractor/loadlib.cpp @@ -6,6 +6,8 @@ class MPQFile; +u_map_fcc MverMagic = { {'M','V','E','R'} }; + FileLoader::FileLoader() { data = 0; @@ -49,7 +51,7 @@ bool FileLoader::prepareLoadedData() { // Check version version = (file_MVER *) data; - if (version->fcc != 'MVER') + if (version->fcc != MverMagic.fcc) return false; if (version->ver != FILE_FORMAT_VERSION) return false; diff --git a/src/tools/map_extractor/loadlib/loadlib.h b/src/tools/map_extractor/loadlib/loadlib.h index bf6c0706d46..f32f46c63b9 100644 --- a/src/tools/map_extractor/loadlib/loadlib.h +++ b/src/tools/map_extractor/loadlib/loadlib.h @@ -29,6 +29,12 @@ typedef uint8_t uint8; #define FILE_FORMAT_VERSION 18 +union u_map_fcc +{ + char fcc_txt[4]; + uint32 fcc; +}; + // // File version chunk // diff --git a/src/tools/map_extractor/wdt.cpp b/src/tools/map_extractor/wdt.cpp index dedefbb64e5..90a07eafab3 100644 --- a/src/tools/map_extractor/wdt.cpp +++ b/src/tools/map_extractor/wdt.cpp @@ -2,23 +2,27 @@ #include "wdt.h" +u_map_fcc MWMOMagic = { {'M', 'W', 'M', 'O'} }; +u_map_fcc MPHDMagic = { {'M', 'P', 'H', 'D'} }; +u_map_fcc MAINMagic = { {'M', 'A', 'I', 'N'} }; + bool wdt_MWMO::prepareLoadedData() { - if (fcc != 'MWMO') + if (fcc != MWMOMagic.fcc) return false; return true; } bool wdt_MPHD::prepareLoadedData() { - if (fcc != 'MPHD') + if (fcc != MPHDMagic.fcc) return false; return true; } bool wdt_MAIN::prepareLoadedData() { - if (fcc != 'MAIN') + if (fcc != MAINMagic.fcc) return false; return true; } @@ -59,4 +63,4 @@ bool WDT_file::prepareLoadedData() if (!wmo->prepareLoadedData()) return false; return true; -} \ No newline at end of file +} diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp index 8d7dce9ae11..c2ac19d5be0 100644 --- a/src/tools/mesh_extractor/ADT.cpp +++ b/src/tools/mesh_extractor/ADT.cpp @@ -3,7 +3,8 @@ #include "LiquidHandler.h" #include "WorldModelHandler.h" -ADT::ADT( std::string file ) : ObjectData(NULL), Data(NULL), _DoodadHandler(NULL), _WorldModelHandler(NULL), _LiquidHandler(NULL), HasObjectData(false) +ADT::ADT( std::string file ) : ObjectData(NULL), Data(NULL), HasObjectData(false), + _DoodadHandler(NULL), _WorldModelHandler(NULL), _LiquidHandler(NULL) { Data = new ChunkedData(file); ObjectData = new ChunkedData(Utils::Replace(file, ".adt", "_obj0.adt")); @@ -31,7 +32,6 @@ void ADT::Read() { Header.Read(Data->GetChunkByName("MHDR")->GetStream()); MapChunks.reserve(16 * 16); - int mapChunkIndex = 0; for (std::vector::iterator itr = Data->Chunks.begin(); itr != Data->Chunks.end(); ++itr) if ((*itr)->Name == "MCNK") diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt index 8ef48a90742..29c571d9301 100644 --- a/src/tools/mesh_extractor/CMakeLists.txt +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -26,6 +26,7 @@ if( UNIX ) ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour ${CMAKE_SOURCE_DIR}/dep/libmpq ${CMAKE_SOURCE_DIR}/dep/g3dlite/include + ${ACE_INCLUDE_DIR} ${MYSQL_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} @@ -77,4 +78,4 @@ if( UNIX ) install(TARGETS MeshExtractor DESTINATION bin) elseif( WIN32 ) install(TARGETS MeshExtractor DESTINATION "${CMAKE_INSTALL_PREFIX}") -endif() \ No newline at end of file +endif() diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 90e2c138376..34293b14b54 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -14,7 +14,7 @@ class GenericCache public: GenericCache() {} - static const int32 FlushLimit = 1000; + static const uint32 FlushLimit = 1000; void Insert(K key, T* val) { @@ -59,4 +59,4 @@ public: }; extern CacheClass* Cache; -#endif \ No newline at end of file +#endif diff --git a/src/tools/mesh_extractor/Chunk.cpp b/src/tools/mesh_extractor/Chunk.cpp index 2f521f1badd..9f2898a46e0 100644 --- a/src/tools/mesh_extractor/Chunk.cpp +++ b/src/tools/mesh_extractor/Chunk.cpp @@ -12,12 +12,12 @@ int32 Chunk::FindSubChunkOffset(std::string name) uint32 matched = 0; while (uint32(ftell(stream)) < Utils::Size(stream)) { - char b; - fread(&b, sizeof(char), 1, stream); - if (b == name[matched]) - ++matched; - else + char b = 0; + if (fread(&b, sizeof(char), 1, stream) != 1 || b != name[matched]) matched = 0; + else + ++matched; + if (matched == 4) return ftell(stream) - 4; } diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index 4d609d8f6b2..e0db12a6be7 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -36,7 +36,8 @@ void ChunkedData::Load( uint32 maxLength, uint32 chunksHint ) // Utils::Reverse(nameBytes); name = std::string(name.rbegin(), name.rend()); uint32 length; - fread(&length, sizeof(uint32), 1, Stream); + if (fread(&length, sizeof(uint32), 1, Stream) != 1) + continue; calcOffset += 8; Chunks.push_back(new Chunk(name.c_str(), length, calcOffset + baseOffset, Stream)); calcOffset += length; diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 013c0ff256a..9b5c9f9c77b 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -16,7 +16,7 @@ private: dtNavMeshParams Params; ContinentBuilder* cBuilder; public: - BuilderThread(ContinentBuilder* _cBuilder, bool deb, dtNavMeshParams& params) : Free(true), debug(deb), Params(params), cBuilder(_cBuilder) {} + BuilderThread(ContinentBuilder* _cBuilder, bool deb, dtNavMeshParams& params) : debug(deb), Params(params), cBuilder(_cBuilder), Free(true) {} void SetData(int x, int y, int map, std::string cont) { X = x; Y = y; MapId = map; Continent = cont; } int svc() @@ -113,7 +113,7 @@ void ContinentBuilder::Build(bool debug) std::vector Threads; for (uint32 i = 0; i < NumberOfThreads; ++i) Threads.push_back(new BuilderThread(this, debug, params)); - printf("Map %s ( %i ) has %i tiles. Building them with %i threads\n", Continent.c_str(), MapId, TileMap->TileTable.size(), NumberOfThreads); + printf("Map %s ( %i ) has %u tiles. Building them with %i threads\n", Continent.c_str(), MapId, uint32(TileMap->TileTable.size()), NumberOfThreads); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { bool next = false; diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h index 4c16fa0727e..3d7b879879e 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -7,7 +7,11 @@ class ContinentBuilder { public: - ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : MapId(mapId), Continent(continent), TileMap(wdt), NumberOfThreads(tn), tileXMin(64), tileYMin(64), tileXMax(0), tileYMax(0) {} + ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : + Continent(continent), TileMap(wdt), MapId(mapId), + NumberOfThreads(tn), tileXMin(64), tileYMin(64), tileXMax(0), tileYMax(0) + {} + void Build(bool debug); void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax); void CalculateTileBounds(); @@ -23,4 +27,4 @@ private: int tileXMax; int tileYMax; }; -#endif \ No newline at end of file +#endif diff --git a/src/tools/mesh_extractor/DBC.cpp b/src/tools/mesh_extractor/DBC.cpp index c50e02014da..5c54d975487 100644 --- a/src/tools/mesh_extractor/DBC.cpp +++ b/src/tools/mesh_extractor/DBC.cpp @@ -2,16 +2,19 @@ #include "DBC.h" #include "Common.h" -DBC::DBC( FILE* stream ) : StringBlock(NULL), IsFaulty(true), StringBlockSize(0) +DBC::DBC( FILE* stream ) : StringBlock(NULL), StringBlockSize(0), IsFaulty(true) { char magic[5]; - fread(&magic, sizeof(char), 4, stream); + uint count = 0; + count += fread(&magic, sizeof(char), 4, stream); magic[4] = '\0'; - fread(&RecordCount, sizeof(uint32), 1, stream); + count += fread(&RecordCount, sizeof(uint32), 1, stream); Records.reserve(RecordCount); - fread(&Fields, sizeof(uint32), 1, stream); - fread(&RecordSize, sizeof(uint32), 1, stream); - fread(&StringBlockSize, sizeof(uint32), 1, stream); + count += fread(&Fields, sizeof(uint32), 1, stream); + count += fread(&RecordSize, sizeof(uint32), 1, stream); + count += fread(&StringBlockSize, sizeof(uint32), 1, stream); + if (count != 8) + printf("DBC::DBC: Failed to read some data expected 8, read %u\n", count); for (int i = 0; i < RecordCount; i++) { @@ -26,13 +29,16 @@ DBC::DBC( FILE* stream ) : StringBlock(NULL), IsFaulty(true), StringBlockSize(0) break; } uint32 tmp; - fread(&tmp, sizeof(uint32), 1, stream); + if (fread(&tmp, sizeof(uint32), 1, stream) != 1) + printf("DBC::DBC: Failed to read some data expected 1, read 0\n"); rec->Values.push_back(tmp); size += 4; } } StringBlock = new uint8[StringBlockSize]; - fread(StringBlock, sizeof(uint8), StringBlockSize, stream); + count = fread(StringBlock, sizeof(uint8), StringBlockSize, stream); + if (count != StringBlockSize) + printf("DBC::DBC: Failed to read some data expected %u, read %u\n", StringBlockSize, count); } std::string DBC::GetStringByOffset( int offset ) diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 4e8028b3dff..56c2a7986f8 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -30,7 +30,8 @@ void DoodadHandler::ProcessInternal( ChunkedData* subChunks ) for (uint32 i = 0; i < refCount; i++) { int32 index; - fread(&index, sizeof(int32), 1, stream); + if (int count = fread(&index, sizeof(int32), 1, stream) != 1) + printf("DoodadHandler::ProcessInternal: Failed to read some data expected 1, read %d\n", count); if (index < 0 || uint32(index) >= _definitions->size()) continue; DoodadDefinition doodad = (*_definitions)[index]; @@ -81,7 +82,8 @@ void DoodadHandler::ReadDoodadPaths( Chunk* id, Chunk* data ) FILE* idStream = id->GetStream(); fseek(idStream, i * 4, SEEK_CUR); uint32 offset; - fread(&offset, sizeof(uint32), 1, idStream); + if (fread(&offset, sizeof(uint32), 1, idStream) != 1) + printf("DoodadHandler::ReadDoodadPaths: Failed to read some data expected 1, read 0\n"); FILE* dataStream = data->GetStream(); fseek(dataStream, offset + data->Offset, SEEK_SET); _paths->push_back(Utils::ReadString(dataStream)); diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index a212b032d1d..981834ec7ac 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -19,12 +19,16 @@ public: void Read(FILE* stream) { - fread(&MmidIndex, sizeof(uint32), 1, stream); - fread(&UniqueId, sizeof(uint32), 1, stream); + int count = 0; + + count += fread(&MmidIndex, sizeof(uint32), 1, stream); + count += fread(&UniqueId, sizeof(uint32), 1, stream); Position = Vector3::Read(stream); Rotation = Vector3::Read(stream); - fread(&DecimalScale, sizeof(uint16), 1, stream); - fread(&Flags, sizeof(uint16), 1, stream); + count += fread(&DecimalScale, sizeof(uint16), 1, stream); + count += fread(&Flags, sizeof(uint16), 1, stream); + if (count != 4) + printf("DoodadDefinition::Read: Failed to read some data expected 4, read %d\n", count); } }; @@ -50,4 +54,4 @@ private: std::vector* _definitions; std::vector* _paths; }; -#endif \ No newline at end of file +#endif diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index 7844130ab34..285ea1a5b74 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -50,17 +50,17 @@ void LiquidHandler::HandleNewLiquid() fseek(stream, chunk->Offset + information.OffsetMask2, SEEK_SET); uint32 size = ceil(information.Width * information.Height / 8.0f); uint8* altMask = new uint8[size]; - fread(altMask, sizeof(uint8), size, stream); - - for (uint32 mi = 0; mi < size; mi++) - renderMask.Mask[mi + information.OffsetY] |= altMask[mi]; + if (fread(altMask, sizeof(uint8), size, stream) == size) + for (uint32 mi = 0; mi < size; mi++) + renderMask.Mask[mi + information.OffsetY] |= altMask[mi]; delete[] altMask; } fseek(stream, chunk->Offset + information.OffsetHeightmap, SEEK_SET); for (int y = information.OffsetY; y < (information.OffsetY + information.Height); y++) for (int x = information.OffsetX; x < (information.OffsetX + information.Width); x++) - fread(&heights[x][y], sizeof(float), 1, stream); + if (fread(&heights[x][y], sizeof(float), 1, stream) != 1) + return; } else { diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp index 67f4061035e..8fe40773d43 100644 --- a/src/tools/mesh_extractor/MapChunk.cpp +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -58,7 +58,8 @@ void MapChunk::GenerateVertices( FILE* stream ) for (int i = 0; i < values; i++) { float tmp; - fread(&tmp, sizeof(float), 1, stream); + if (fread(&tmp, sizeof(float), 1, stream) != 1) + printf("MapChunk::GenerateVertices: Failed to read some data expected 1, read 0\n"); Vector3 vert(Header.Position.x - (j * (Constants::UnitSize * 0.5f)), Header.Position.y - (i * Constants::UnitSize), Header.Position.z + tmp); if (values == 8) vert.y -= Constants::UnitSize * 0.5f; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 7379ba87117..b164ff5861d 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -59,7 +59,7 @@ void ExtractDBCs() { printf("Extracting DBCs for locale %s\n", MPQManager::Languages[*itr]); std::string path = baseDBCPath; - if (*itr != MPQHandler->BaseLocale) + if (*itr != uint32(MPQHandler->BaseLocale)) { path += std::string(MPQManager::Languages[*itr]) + "/"; Utils::CreateDir(path); @@ -198,7 +198,6 @@ void ExtractGameobjectModels() fwrite(&model.Header.CountGroups, sizeof(uint32), 1, output); fwrite(&model.Header.WmoId, sizeof(uint32), 1, output); - uint32 i = 0; for (std::vector::iterator itr2 = model.Groups.begin(); itr2 != model.Groups.end(); ++itr2) { fwrite(&itr2->Header.Flags, sizeof(uint32), 1, output); @@ -261,7 +260,7 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr) mapList.insert(atoi(*itr)); - printf("Extracting only provided list of maps (%u).\n", mapList.size()); + printf("Extracting only provided list of maps (%u).\n", uint32(mapList.size())); } else if (strcmp(argv[i], "--debug") == 0) { @@ -314,18 +313,27 @@ void LoadTile(dtNavMesh*& navMesh, const char* tile) { FILE* f = fopen(tile, "rb"); MmapTileHeader header; - fread(&header, sizeof(MmapTileHeader), 1, f); + + if (fread(&header, sizeof(MmapTileHeader), 1, f) != 1) + return; + uint8* nav = new uint8[header.size]; - fread(nav, header.size, 1, f); + if (fread(nav, header.size, 1, f) != 1) + return; - dtStatus res = navMesh->addTile(nav, header.size, DT_TILE_FREE_DATA, 0, NULL); + navMesh->addTile(nav, header.size, DT_TILE_FREE_DATA, 0, NULL); fclose(f); } int main(int argc, char* argv[]) { - system("pause"); + if (!system("pause")) + { + printf("main: Error in system call to pause\n"); + return -1; + } + uint32 threads = 4, extractFlags = 0; std::set mapIds; bool debug = false; @@ -383,8 +391,13 @@ int main(int argc, char* argv[]) FILE* mmap = fopen(".mmap", "rb"); dtNavMeshParams params; - fread(¶ms, sizeof(dtNavMeshParams), 1, mmap); + int count = fread(¶ms, sizeof(dtNavMeshParams), 1, mmap); fclose(mmap); + if (count != 1) + { + printf("main: Error reading from .mmap\n"); + return 0; + } dtNavMesh* navMesh = new dtNavMesh(); dtNavMeshQuery* navMeshQuery = new dtNavMeshQuery(); @@ -401,10 +414,9 @@ int main(int argc, char* argv[]) float nearestPt[3]; - dtStatus status = navMeshQuery->findNearestPoly(m_spos, m_polyPickExt, &m_filter, &m_startRef, nearestPt); - status = navMeshQuery->findNearestPoly(m_epos, m_polyPickExt, &m_filter, &m_endRef, nearestPt); + navMeshQuery->findNearestPoly(m_spos, m_polyPickExt, &m_filter, &m_startRef, nearestPt); + navMeshQuery->findNearestPoly(m_epos, m_polyPickExt, &m_filter, &m_endRef, nearestPt); - // if ( !m_startRef || !m_endRef ) { std::cerr << "Could not find any nearby poly's (" << m_startRef << "," << m_endRef << ")" << std::endl; @@ -415,4 +427,4 @@ int main(int argc, char* argv[]) } return 0; -} \ No newline at end of file +} diff --git a/src/tools/mesh_extractor/Model.cpp b/src/tools/mesh_extractor/Model.cpp index 10fde0ebc2d..77b1adbeaa0 100644 --- a/src/tools/mesh_extractor/Model.cpp +++ b/src/tools/mesh_extractor/Model.cpp @@ -47,9 +47,12 @@ void Model::ReadBoundingTriangles( FILE* stream ) { Triangle tri; tri.Type = Constants::TRIANGLE_TYPE_DOODAD; - fread(&tri.V0, sizeof(uint16), 1, stream); - fread(&tri.V1, sizeof(uint16), 1, stream); - fread(&tri.V2, sizeof(uint16), 1, stream); + int count = 0; + count += fread(&tri.V0, sizeof(uint16), 1, stream); + count += fread(&tri.V1, sizeof(uint16), 1, stream); + count += fread(&tri.V2, sizeof(uint16), 1, stream); + if (count != 3) + printf("Model::ReadBoundingTriangles: Error reading data, expected 3, read %d\n", count); Triangles.push_back(tri); } } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 2a02bc50cd4..4a14cbbd51d 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -12,7 +12,8 @@ #include "ace/Synch.h" -TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0), cBuilder(_cBuilder) +TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId) : + World(world), X(x), Y(y), MapId(mapId), _Geometry(NULL), DataSize(0), cBuilder(_cBuilder) { /* Test, non-working values @@ -62,7 +63,7 @@ TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, Context = new rcContext; } -void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams ) +void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshParams& /*navMeshParams*/ ) { bmin = new float[3]; bmax = new float[3]; diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 3639cb88acf..119ac94f94f 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -53,8 +53,7 @@ std::string Utils::ReadString( FILE* file ) while (true) { char b; - fread(&b, sizeof(char), 1, file); - if (b == 0) + if (fread(&b, sizeof(char), 1, file) != 1 || b == 0) break; ret[i++] = b; } @@ -155,7 +154,7 @@ Vector3 Utils::VectorTransform( Vector3 vec, G3D::Matrix4 matrix ) std::string Utils::GetPathBase( std::string path ) { - int lastIndex = path.find_last_of("."); + size_t lastIndex = path.find_last_of("."); if (lastIndex != std::string::npos) return path.substr(0, lastIndex); return path; @@ -164,11 +163,12 @@ std::string Utils::GetPathBase( std::string path ) Vector3 Vector3::Read( FILE* file ) { Vector3 ret; - fread(&ret, sizeof(Vector3), 1, file); + if (fread(&ret, sizeof(Vector3), 1, file) != 1) + printf("Vector3::Read: Failed to read some data expected 1, read 0\n"); return ret; } -Vector3 Utils::GetLiquidVert(G3D::Matrix4 transformation, Vector3 basePosition, float height, int x, int y) +Vector3 Utils::GetLiquidVert(G3D::Matrix4 transformation, Vector3 basePosition, float height, int /*x*/, int /*y*/) { if (Utils::Distance(height, 0.0f) > 0.5f) basePosition.z = 0.0f; @@ -208,14 +208,18 @@ void Utils::SaveToDisk( FILE* stream, std::string path ) FILE* disk = fopen(path.c_str(), "wb"); if (!disk) { - printf("Could not save file %s to disk, please verify that you have write permissions on that directory\n", path.c_str()); + printf("SaveToDisk: Could not save file %s to disk, please verify that you have write permissions on that directory\n", path.c_str()); return; } uint32 size = Utils::Size(stream); uint8* data = new uint8[size]; // Read the data to an array - fread(data, 1, size, stream); + if (fread(data, 1, size, stream) != 1) + { + printf("SaveToDisk: Error reading from Stream while trying to save file %s to disck.\n", path.c_str()); + return; + } // And write it in the file fwrite(data, 1, size, disk); @@ -242,136 +246,164 @@ std::string Utils::GetExtension( std::string path ) void MapChunkHeader::Read(FILE* stream) { - fread(&Flags, sizeof(uint32), 1, stream); - fread(&IndexX, sizeof(uint32), 1, stream); - fread(&IndexY, sizeof(uint32), 1, stream); - fread(&Layers, sizeof(uint32), 1, stream); - fread(&DoodadRefs, sizeof(uint32), 1, stream); - fread(&OffsetMCVT, sizeof(uint32), 1, stream); - fread(&OffsetMCNR, sizeof(uint32), 1, stream); - fread(&OffsetMCLY, sizeof(uint32), 1, stream); - fread(&OffsetMCRF, sizeof(uint32), 1, stream); - fread(&OffsetMCAL, sizeof(uint32), 1, stream); - fread(&SizeMCAL, sizeof(uint32), 1, stream); - fread(&OffsetMCSH, sizeof(uint32), 1, stream); - fread(&SizeMCSH, sizeof(uint32), 1, stream); - fread(&AreaId, sizeof(uint32), 1, stream); - fread(&MapObjectRefs, sizeof(uint32), 1, stream); - fread(&Holes, sizeof(uint32), 1, stream); + int count = 0; + + count += fread(&Flags, sizeof(uint32), 1, stream); + count += fread(&IndexX, sizeof(uint32), 1, stream); + count += fread(&IndexY, sizeof(uint32), 1, stream); + count += fread(&Layers, sizeof(uint32), 1, stream); + count += fread(&DoodadRefs, sizeof(uint32), 1, stream); + count += fread(&OffsetMCVT, sizeof(uint32), 1, stream); + count += fread(&OffsetMCNR, sizeof(uint32), 1, stream); + count += fread(&OffsetMCLY, sizeof(uint32), 1, stream); + count += fread(&OffsetMCRF, sizeof(uint32), 1, stream); + count += fread(&OffsetMCAL, sizeof(uint32), 1, stream); + count += fread(&SizeMCAL, sizeof(uint32), 1, stream); + count += fread(&OffsetMCSH, sizeof(uint32), 1, stream); + count += fread(&SizeMCSH, sizeof(uint32), 1, stream); + count += fread(&AreaId, sizeof(uint32), 1, stream); + count += fread(&MapObjectRefs, sizeof(uint32), 1, stream); + count += fread(&Holes, sizeof(uint32), 1, stream); LowQualityTextureMap = new uint32[4]; - fread(LowQualityTextureMap, sizeof(uint32), 4, stream); - fread(&PredTex, sizeof(uint32), 1, stream); - fread(&NumberEffectDoodad, sizeof(uint32), 1, stream); - fread(&OffsetMCSE, sizeof(uint32), 1, stream); - fread(&SoundEmitters, sizeof(uint32), 1, stream); - fread(&OffsetMCLQ, sizeof(uint32), 1, stream); - fread(&SizeMCLQ, sizeof(uint32), 1, stream); + count += fread(LowQualityTextureMap, sizeof(uint32), 4, stream); + count += fread(&PredTex, sizeof(uint32), 1, stream); + count += fread(&NumberEffectDoodad, sizeof(uint32), 1, stream); + count += fread(&OffsetMCSE, sizeof(uint32), 1, stream); + count += fread(&SoundEmitters, sizeof(uint32), 1, stream); + count += fread(&OffsetMCLQ, sizeof(uint32), 1, stream); + count += fread(&SizeMCLQ, sizeof(uint32), 1, stream); Position = Vector3::Read(stream); - fread(&OffsetMCCV, sizeof(uint32), 1, stream); + count += fread(&OffsetMCCV, sizeof(uint32), 1, stream); + + if (count != 27) + printf("MapChunkHeader::Read: Failed to read some data expected 27, read %d\n", count); } void MHDR::Read(FILE* stream) { - fread(&Flags, sizeof(uint32), 1, stream); - fread(&OffsetMCIN, sizeof(uint32), 1, stream); - fread(&OffsetMTEX, sizeof(uint32), 1, stream); - fread(&OffsetMMDX, sizeof(uint32), 1, stream); - fread(&OffsetMMID, sizeof(uint32), 1, stream); - fread(&OffsetMWMO, sizeof(uint32), 1, stream); - fread(&OffsetMWID, sizeof(uint32), 1, stream); - fread(&OffsetMDDF, sizeof(uint32), 1, stream); - fread(&OffsetMODF, sizeof(uint32), 1, stream); - fread(&OffsetMFBO, sizeof(uint32), 1, stream); - fread(&OffsetMH2O, sizeof(uint32), 1, stream); - fread(&OffsetMTFX, sizeof(uint32), 1, stream); + int count = 0; + + count += fread(&Flags, sizeof(uint32), 1, stream); + count += fread(&OffsetMCIN, sizeof(uint32), 1, stream); + count += fread(&OffsetMTEX, sizeof(uint32), 1, stream); + count += fread(&OffsetMMDX, sizeof(uint32), 1, stream); + count += fread(&OffsetMMID, sizeof(uint32), 1, stream); + count += fread(&OffsetMWMO, sizeof(uint32), 1, stream); + count += fread(&OffsetMWID, sizeof(uint32), 1, stream); + count += fread(&OffsetMDDF, sizeof(uint32), 1, stream); + count += fread(&OffsetMODF, sizeof(uint32), 1, stream); + count += fread(&OffsetMFBO, sizeof(uint32), 1, stream); + count += fread(&OffsetMH2O, sizeof(uint32), 1, stream); + count += fread(&OffsetMTFX, sizeof(uint32), 1, stream); + + if (count != 12) + printf("MHDR::Read: Failed to read some data expected 12, read %d\n", count); } void ModelHeader::Read(FILE* stream) { - fread(&Magic, sizeof(char), 4, stream); + int count = 0; + + count += fread(&Magic, sizeof(char), 4, stream); Magic[4] = '\0'; // null-terminate it. - fread(&Version, sizeof(uint32), 1, stream); - fread(&LengthModelName, sizeof(uint32), 1, stream); - fread(&OffsetName, sizeof(uint32), 1, stream); - fread(&ModelFlags, sizeof(uint32), 1, stream); - fread(&CountGlobalSequences, sizeof(uint32), 1, stream); - fread(&OffsetGlobalSequences, sizeof(uint32), 1, stream); - fread(&CountAnimations, sizeof(uint32), 1, stream); - fread(&OffsetAnimations, sizeof(uint32), 1, stream); - fread(&CountAnimationLookup, sizeof(uint32), 1, stream); - fread(&OffsetAnimationLookup, sizeof(uint32), 1, stream); - fread(&CountBones, sizeof(uint32), 1, stream); - fread(&OffsetBones, sizeof(uint32), 1, stream); - fread(&CountKeyBoneLookup, sizeof(uint32), 1, stream); - fread(&OffsetKeyBoneLookup, sizeof(uint32), 1, stream); - fread(&CountVertices, sizeof(uint32), 1, stream); - fread(&OffsetVertices, sizeof(uint32), 1, stream); - fread(&CountViews, sizeof(uint32), 1, stream); - fread(&CountColors, sizeof(uint32), 1, stream); - fread(&OffsetColors, sizeof(uint32), 1, stream); - fread(&CountTextures, sizeof(uint32), 1, stream); - fread(&OffsetTextures, sizeof(uint32), 1, stream); - fread(&CountTransparency, sizeof(uint32), 1, stream); - fread(&OffsetTransparency, sizeof(uint32), 1, stream); - fread(&CountUvAnimation, sizeof(uint32), 1, stream); - fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); - fread(&CountTexReplace, sizeof(uint32), 1, stream); - fread(&OffsetTexReplace, sizeof(uint32), 1, stream); - fread(&CountRenderFlags, sizeof(uint32), 1, stream); - fread(&OffsetRenderFlags, sizeof(uint32), 1, stream); - fread(&CountBoneLookup, sizeof(uint32), 1, stream); - fread(&OffsetBoneLookup, sizeof(uint32), 1, stream); - fread(&CountTexLookup, sizeof(uint32), 1, stream); - fread(&OffsetTexLookup, sizeof(uint32), 1, stream); - fread(&CountTexUnits, sizeof(uint32), 1, stream); - fread(&OffsetTexUnits, sizeof(uint32), 1, stream); - fread(&CountTransLookup, sizeof(uint32), 1, stream); - fread(&OffsetTransLookup, sizeof(uint32), 1, stream); - fread(&CountUvAnimLookup, sizeof(uint32), 1, stream); - fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream); + count += fread(&Version, sizeof(uint32), 1, stream); + count += fread(&LengthModelName, sizeof(uint32), 1, stream); + count += fread(&OffsetName, sizeof(uint32), 1, stream); + count += fread(&ModelFlags, sizeof(uint32), 1, stream); + count += fread(&CountGlobalSequences, sizeof(uint32), 1, stream); + count += fread(&OffsetGlobalSequences, sizeof(uint32), 1, stream); + count += fread(&CountAnimations, sizeof(uint32), 1, stream); + count += fread(&OffsetAnimations, sizeof(uint32), 1, stream); + count += fread(&CountAnimationLookup, sizeof(uint32), 1, stream); + count += fread(&OffsetAnimationLookup, sizeof(uint32), 1, stream); + count += fread(&CountBones, sizeof(uint32), 1, stream); + count += fread(&OffsetBones, sizeof(uint32), 1, stream); + count += fread(&CountKeyBoneLookup, sizeof(uint32), 1, stream); + count += fread(&OffsetKeyBoneLookup, sizeof(uint32), 1, stream); + count += fread(&CountVertices, sizeof(uint32), 1, stream); + count += fread(&OffsetVertices, sizeof(uint32), 1, stream); + count += fread(&CountViews, sizeof(uint32), 1, stream); + count += fread(&CountColors, sizeof(uint32), 1, stream); + count += fread(&OffsetColors, sizeof(uint32), 1, stream); + count += fread(&CountTextures, sizeof(uint32), 1, stream); + count += fread(&OffsetTextures, sizeof(uint32), 1, stream); + count += fread(&CountTransparency, sizeof(uint32), 1, stream); + count += fread(&OffsetTransparency, sizeof(uint32), 1, stream); + count += fread(&CountUvAnimation, sizeof(uint32), 1, stream); + count += fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); + count += fread(&CountTexReplace, sizeof(uint32), 1, stream); + count += fread(&OffsetTexReplace, sizeof(uint32), 1, stream); + count += fread(&CountRenderFlags, sizeof(uint32), 1, stream); + count += fread(&OffsetRenderFlags, sizeof(uint32), 1, stream); + count += fread(&CountBoneLookup, sizeof(uint32), 1, stream); + count += fread(&OffsetBoneLookup, sizeof(uint32), 1, stream); + count += fread(&CountTexLookup, sizeof(uint32), 1, stream); + count += fread(&OffsetTexLookup, sizeof(uint32), 1, stream); + count += fread(&CountTexUnits, sizeof(uint32), 1, stream); + count += fread(&OffsetTexUnits, sizeof(uint32), 1, stream); + count += fread(&CountTransLookup, sizeof(uint32), 1, stream); + count += fread(&OffsetTransLookup, sizeof(uint32), 1, stream); + count += fread(&CountUvAnimLookup, sizeof(uint32), 1, stream); + count += fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream); VertexBox[0] = Vector3::Read(stream); VertexBox[1] = Vector3::Read(stream); - fread(&VertexRadius, sizeof(float), 1, stream); + count += fread(&VertexRadius, sizeof(float), 1, stream); BoundingBox[0] = Vector3::Read(stream); BoundingBox[1] = Vector3::Read(stream); - fread(&BoundingRadius, sizeof(float), 1, stream); - fread(&CountBoundingTriangles, sizeof(uint32), 1, stream); - fread(&OffsetBoundingTriangles, sizeof(uint32), 1, stream); - fread(&CountBoundingVertices, sizeof(uint32), 1, stream); - fread(&OffsetBoundingVertices, sizeof(uint32), 1, stream); - fread(&CountBoundingNormals, sizeof(uint32), 1, stream); - fread(&OffsetBoundingNormals, sizeof(uint32), 1, stream); + count += fread(&BoundingRadius, sizeof(float), 1, stream); + count += fread(&CountBoundingTriangles, sizeof(uint32), 1, stream); + count += fread(&OffsetBoundingTriangles, sizeof(uint32), 1, stream); + count += fread(&CountBoundingVertices, sizeof(uint32), 1, stream); + count += fread(&OffsetBoundingVertices, sizeof(uint32), 1, stream); + count += fread(&CountBoundingNormals, sizeof(uint32), 1, stream); + count += fread(&OffsetBoundingNormals, sizeof(uint32), 1, stream); + + if (count != 51) + printf("ModelHeader::Read: Failed to read some data expected 51, read %d\n", count); + } WorldModelHeader WorldModelHeader::Read(FILE* stream) { WorldModelHeader ret; - fread(&ret.CountMaterials, sizeof(uint32), 1, stream); - fread(&ret.CountGroups, sizeof(uint32), 1, stream); - fread(&ret.CountPortals, sizeof(uint32), 1, stream); - fread(&ret.CountLights, sizeof(uint32), 1, stream); - fread(&ret.CountModels, sizeof(uint32), 1, stream); - fread(&ret.CountDoodads, sizeof(uint32), 1, stream); - fread(&ret.CountSets, sizeof(uint32), 1, stream); - fread(&ret.AmbientColorUnk, sizeof(uint32), 1, stream); - fread(&ret.WmoId, sizeof(uint32), 1, stream); + int count = 0; + + count += fread(&ret.CountMaterials, sizeof(uint32), 1, stream); + count += fread(&ret.CountGroups, sizeof(uint32), 1, stream); + count += fread(&ret.CountPortals, sizeof(uint32), 1, stream); + count += fread(&ret.CountLights, sizeof(uint32), 1, stream); + count += fread(&ret.CountModels, sizeof(uint32), 1, stream); + count += fread(&ret.CountDoodads, sizeof(uint32), 1, stream); + count += fread(&ret.CountSets, sizeof(uint32), 1, stream); + count += fread(&ret.AmbientColorUnk, sizeof(uint32), 1, stream); + count += fread(&ret.WmoId, sizeof(uint32), 1, stream); ret.BoundingBox[0] = Vector3::Read(stream); ret.BoundingBox[1] = Vector3::Read(stream); - fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); + count += fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); + + if (count != 10) + printf("WorldModelHeader::Read: Failed to read some data expected 10, read %d\n", count); + return ret; } DoodadInstance DoodadInstance::Read(FILE* stream) { DoodadInstance ret; - fread(&ret.FileOffset, sizeof(uint32), 1, stream); + int count = 0; + + count += fread(&ret.FileOffset, sizeof(uint32), 1, stream); ret.Position = Vector3::Read(stream); - fread(&ret.QuatW, sizeof(float), 1, stream); - fread(&ret.QuatX, sizeof(float), 1, stream); - fread(&ret.QuatY, sizeof(float), 1, stream); - fread(&ret.QuatZ, sizeof(float), 1, stream); - fread(&ret.Scale, sizeof(float), 1, stream); - fread(&ret.LightColor, sizeof(uint32), 1, stream); + count += fread(&ret.QuatW, sizeof(float), 1, stream); + count += fread(&ret.QuatX, sizeof(float), 1, stream); + count += fread(&ret.QuatY, sizeof(float), 1, stream); + count += fread(&ret.QuatZ, sizeof(float), 1, stream); + count += fread(&ret.Scale, sizeof(float), 1, stream); + count += fread(&ret.LightColor, sizeof(uint32), 1, stream); + + if (count != 7) + printf("DoodadInstance::Read: Failed to read some data expected 7, read %d\n", count); + return ret; } @@ -379,24 +411,35 @@ DoodadSet DoodadSet::Read(FILE* stream) { DoodadSet ret; char name[21]; - fread(&name, sizeof(char), 20, stream); + int count = 0; + + count += fread(&name, sizeof(char), 20, stream); name[20] = '\0'; ret.Name = name; - fread(&ret.FirstInstanceIndex, sizeof(uint32), 1, stream); - fread(&ret.CountInstances, sizeof(uint32), 1, stream); - fread(&ret.UnknownZero, sizeof(uint32), 1, stream); + count += fread(&ret.FirstInstanceIndex, sizeof(uint32), 1, stream); + count += fread(&ret.CountInstances, sizeof(uint32), 1, stream); + count += fread(&ret.UnknownZero, sizeof(uint32), 1, stream); + + if (count != 23) + printf("DoodadSet::Read: Failed to read some data expected 23, read %d\n", count); + return ret; } LiquidHeader LiquidHeader::Read(FILE* stream) { LiquidHeader ret; - fread(&ret.CountXVertices, sizeof(uint32), 1, stream); - fread(&ret.CountYVertices, sizeof(uint32), 1, stream); - fread(&ret.Width, sizeof(uint32), 1, stream); - fread(&ret.Height, sizeof(uint32), 1, stream); + int count = 0; + count += fread(&ret.CountXVertices, sizeof(uint32), 1, stream); + count += fread(&ret.CountYVertices, sizeof(uint32), 1, stream); + count += fread(&ret.Width, sizeof(uint32), 1, stream); + count += fread(&ret.Height, sizeof(uint32), 1, stream); ret.BaseLocation = Vector3::Read(stream); - fread(&ret.MaterialId, sizeof(uint16), 1, stream); + count += fread(&ret.MaterialId, sizeof(uint16), 1, stream); + + if (count != 5) + printf("LiquidHeader::Read: Failed to read some data expected 5, read %d\n", count); + return ret; } @@ -416,10 +459,12 @@ LiquidData LiquidData::Read(FILE* stream, LiquidHeader& header) for (uint32 x = 0; x < header.CountXVertices; x++) { uint32 discard; - fread(&discard, sizeof(uint32), 1, stream); float tmp; - fread(&tmp, sizeof(float), 1, stream); - ret.HeightMap[x][y] = tmp; + if (fread(&discard, sizeof(uint32), 1, stream) == 1 && + fread(&tmp, sizeof(float), 1, stream) == 1) + { + ret.HeightMap[x][y] = tmp; + } } } @@ -427,9 +472,9 @@ LiquidData LiquidData::Read(FILE* stream, LiquidHeader& header) { for (uint32 x = 0; x < header.Width; x++) { - uint8 tmp; - fread(&tmp, sizeof(uint8), 1, stream); - ret.RenderFlags[x][y] = tmp; + uint8 tmp = 0; + if (fread(&tmp, sizeof(uint8), 1, stream) == 1) + ret.RenderFlags[x][y] = tmp; } } @@ -439,7 +484,8 @@ LiquidData LiquidData::Read(FILE* stream, LiquidHeader& header) H2ORenderMask H2ORenderMask::Read(FILE* stream) { H2ORenderMask ret; - fread(&ret.Mask, sizeof(uint8), 8, stream); + if (int count = fread(&ret.Mask, sizeof(uint8), 8, stream) != 8) + printf("H2OHeader::Read: Failed to read some data expected 8, read %d\n", count); return ret; } @@ -458,25 +504,35 @@ bool MCNKLiquidData::IsWater(int x, int y, float height) H2OHeader H2OHeader::Read(FILE* stream) { H2OHeader ret; - fread(&ret.OffsetInformation, sizeof(uint32), 1, stream); - fread(&ret.LayerCount, sizeof(uint32), 1, stream); - fread(&ret.OffsetRender, sizeof(uint32), 1, stream); + int count = 0; + count += fread(&ret.OffsetInformation, sizeof(uint32), 1, stream); + count += fread(&ret.LayerCount, sizeof(uint32), 1, stream); + count += fread(&ret.OffsetRender, sizeof(uint32), 1, stream); + + if (count != 3) + printf("H2OHeader::Read: Failed to read some data expected 3, read %d\n", count); + return ret; } H2OInformation H2OInformation::Read(FILE* stream) { H2OInformation ret; - fread(&ret.LiquidType, sizeof(uint16), 1, stream); - fread(&ret.Flags, sizeof(uint16), 1, stream); - fread(&ret.HeightLevel1, sizeof(float), 1, stream); - fread(&ret.HeightLevel2, sizeof(float), 1, stream); - fread(&ret.OffsetX, sizeof(uint8), 1, stream); - fread(&ret.OffsetY, sizeof(uint8), 1, stream); - fread(&ret.Width, sizeof(uint8), 1, stream); - fread(&ret.Height, sizeof(uint8), 1, stream); - fread(&ret.OffsetMask2, sizeof(uint32), 1, stream); - fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream); + int count = 0; + count += fread(&ret.LiquidType, sizeof(uint16), 1, stream); + count += fread(&ret.Flags, sizeof(uint16), 1, stream); + count += fread(&ret.HeightLevel1, sizeof(float), 1, stream); + count += fread(&ret.HeightLevel2, sizeof(float), 1, stream); + count += fread(&ret.OffsetX, sizeof(uint8), 1, stream); + count += fread(&ret.OffsetY, sizeof(uint8), 1, stream); + count += fread(&ret.Width, sizeof(uint8), 1, stream); + count += fread(&ret.Height, sizeof(uint8), 1, stream); + count += fread(&ret.OffsetMask2, sizeof(uint32), 1, stream); + count += fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream); + + if (count != 10) + printf("H2OInformation::Read: Failed to read some data expected 10, read %d\n", count); + return ret; } @@ -492,17 +548,21 @@ char* Utils::GetPlainName(const char* FileName) WMOGroupHeader WMOGroupHeader::Read( FILE* stream ) { WMOGroupHeader ret; - fread(&ret.OffsetGroupName, sizeof(uint32), 1, stream); - fread(&ret.OffsetDescriptiveName, sizeof(uint32), 1, stream); - fread(&ret.Flags, sizeof(uint32), 1, stream); + int count = 0; + count += fread(&ret.OffsetGroupName, sizeof(uint32), 1, stream); + count += fread(&ret.OffsetDescriptiveName, sizeof(uint32), 1, stream); + count += fread(&ret.Flags, sizeof(uint32), 1, stream); ret.BoundingBox[0] = Vector3::Read(stream); ret.BoundingBox[1] = Vector3::Read(stream); - fread(&ret.OffsetPortals, sizeof(uint32), 1, stream); - fread(&ret.CountPortals, sizeof(uint32), 1, stream); - fread(&ret.CountBatches, sizeof(uint16), 4, stream); - fread(&ret.Fogs, sizeof(uint8), 4, stream); - fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); - fread(&ret.WmoId, sizeof(uint32), 1, stream); - + count += fread(&ret.OffsetPortals, sizeof(uint32), 1, stream); + count += fread(&ret.CountPortals, sizeof(uint32), 1, stream); + count += fread(&ret.CountBatches, sizeof(uint16), 4, stream); + count += fread(&ret.Fogs, sizeof(uint8), 4, stream); + count += fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); + count += fread(&ret.WmoId, sizeof(uint32), 1, stream); + + if (count != 15) + printf("WMOGroupHeader::Read: Failed to read some data expected 15, read %d\n", count); + return ret; } diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index c5dd04fde06..e7380ed8142 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -40,7 +40,7 @@ template struct Triangle { Triangle() {} - Triangle(Constants::TriangleType type, T v0, T v1, T v2) : Type(type), V0(v0), V1(v1), V2(v2) {} + Triangle(Constants::TriangleType type, T v0, T v1, T v2) : V0(v0), V1(v1), V2(v2), Type(type) {} T V0; T V1; T V2; @@ -374,4 +374,4 @@ public: static std::string GetExtension( std::string path ); static char* GetPlainName(const char* FileName); }; -#endif \ No newline at end of file +#endif diff --git a/src/tools/mesh_extractor/WDT.cpp b/src/tools/mesh_extractor/WDT.cpp index f0c3091c04e..70d140e79ed 100644 --- a/src/tools/mesh_extractor/WDT.cpp +++ b/src/tools/mesh_extractor/WDT.cpp @@ -4,7 +4,7 @@ #include "Utils.h" #include "WorldModelHandler.h" -WDT::WDT(std::string file) : IsValid(false), IsGlobalModel(false) +WDT::WDT(std::string file) : IsGlobalModel(false), IsValid(false) { Data = new ChunkedData(file, 2); ReadTileTable(); @@ -37,8 +37,13 @@ void WDT::ReadTileTable() const uint32 hasTileFlag = 0x1; uint32 flags; uint32 discard; - fread(&flags, sizeof(uint32), 1, stream); - fread(&discard, sizeof(uint32), 1, stream); + int count = 0; + count += fread(&flags, sizeof(uint32), 1, stream); + count += fread(&discard, sizeof(uint32), 1, stream); + + if (count != 2) + printf("WDT::ReadTileTable: Failed to read some data expected 2, read %d\n", count); + if (flags & hasTileFlag) TileTable.push_back(TilePos(x, y)); diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index 35a5ba69782..5eeef824b1a 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -3,7 +3,7 @@ #include "Chunk.h" #include "Utils.h" -WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), IsBad(false), MOBA(NULL) +WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), MOBA(NULL), IsBad(false) { Data = new ChunkedData(path); if (!Data->Stream) @@ -85,9 +85,13 @@ void WorldModelGroup::ReadTriangles() uint16 v0; uint16 v1; uint16 v2; - fread(&v0, sizeof(uint16), 1, stream); - fread(&v1, sizeof(uint16), 1, stream); - fread(&v2, sizeof(uint16), 1, stream); + int count = 0; + count += fread(&v0, sizeof(uint16), 1, stream); + count += fread(&v1, sizeof(uint16), 1, stream); + count += fread(&v2, sizeof(uint16), 1, stream); + if (count != 3) + printf("WorldModelGroup::ReadMaterials: Error reading data, expected 3, read %d\n", count); + Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, v0, v1, v2)); } } @@ -105,10 +109,12 @@ void WorldModelGroup::ReadMaterials() for (uint32 i = 0; i < triangleCount; i++) { uint8 tmp; - fread(&tmp, sizeof(uint8), 1, stream); + if (fread(&tmp, sizeof(uint8), 1, stream) != 1) + printf("WorldModelGroup::ReadMaterials: Error reading data, expected 1, read 0\n"); TriangleFlags.push_back(tmp); // Read again for material. - fread(&tmp, sizeof(uint8), 1, stream); + if (fread(&tmp, sizeof(uint8), 1, stream) != 1) + printf("WorldModelGroup::ReadMaterials: Error reading data, expected 1, read 0\n"); TriangleMaterials.push_back(tmp); } } @@ -131,5 +137,7 @@ void WorldModelGroup::ReadBatches() MOBALength = chunk->Length / 2; MOBA = new uint16[MOBALength]; - fread(MOBA, sizeof(uint16), MOBALength, chunk->GetStream()); + int count = fread(MOBA, sizeof(uint16), MOBALength, chunk->GetStream()); + if (count != MOBALength) + printf("WorldModelGroup::ReadBatches: Error reading data, expected %d, read %d\n", MOBALength, count); } diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index 7b60b9b2151..6ce41807492 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -10,16 +10,20 @@ WorldModelDefinition WorldModelDefinition::Read( FILE* file ) { WorldModelDefinition ret; - fread(&ret.MwidIndex, sizeof(uint32), 1, file); - fread(&ret.UniqueId, sizeof(uint32), 1, file); + int count = 0; + count += fread(&ret.MwidIndex, sizeof(uint32), 1, file); + count += fread(&ret.UniqueId, sizeof(uint32), 1, file); ret.Position = Vector3::Read(file); ret.Rotation = Vector3::Read(file); ret.UpperExtents = Vector3::Read(file); ret.LowerExtents = Vector3::Read(file); - fread(&ret.Flags, sizeof(uint16), 1, file); - fread(&ret.DoodadSet, sizeof(uint16), 1, file); + count += fread(&ret.Flags, sizeof(uint16), 1, file); + count += fread(&ret.DoodadSet, sizeof(uint16), 1, file); uint32 discard; - fread(&discard, sizeof(uint32), 1, file); + count += fread(&discard, sizeof(uint32), 1, file); + + if (count != 5) + printf("WorldModelDefinition::Read: Error reading data, expected 5, read %d\n", count); return ret; } @@ -44,7 +48,8 @@ void WorldModelHandler::ProcessInternal( ChunkedData* subChunks ) for (uint32 i = 0; i < refCount; i++) { int32 index; - fread(&index, sizeof(int32), 1, stream); + if (fread(&index, sizeof(int32), 1, stream) != 1) + printf("WorldModelDefinition::Read: Error reading data, expected 1, read 0\n"); if (index < 0 || uint32(index) >= _definitions->size()) continue; @@ -184,7 +189,8 @@ void WorldModelHandler::ReadModelPaths() FILE* stream = mwid->GetStream(); fseek(stream, i * 4, SEEK_CUR); uint32 offset; - fread(&offset, sizeof(uint32), 1, stream); + if (fread(&offset, sizeof(uint32), 1, stream) != 1) + printf("WorldModelDefinition::Read: Error reading data, expected 1, read 0\n"); FILE* dataStream = mwmo->GetStream(); fseek(dataStream, offset + mwmo->Offset, SEEK_SET); _paths->push_back(Utils::ReadString(dataStream)); diff --git a/src/tools/mmaps_generator/CMakeLists.txt b/src/tools/mmaps_generator/CMakeLists.txt index 46bf9d00d43..229a2cd808f 100644 --- a/src/tools/mmaps_generator/CMakeLists.txt +++ b/src/tools/mmaps_generator/CMakeLists.txt @@ -22,13 +22,13 @@ include_directories( ${CMAKE_SOURCE_DIR}/dep/libmpq ${CMAKE_SOURCE_DIR}/dep/zlib ${CMAKE_SOURCE_DIR}/dep/bzip2 - ${CMAKE_SOURCE_DIR}/dep/acelite ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/src/server/shared/Database ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation + ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging ${CMAKE_SOURCE_DIR}/src/server/shared/Threading ${CMAKE_SOURCE_DIR}/src/server/shared/Logging ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities diff --git a/src/tools/mmaps_generator/IntermediateValues.h b/src/tools/mmaps_generator/IntermediateValues.h index a267a0f6412..98042e1b917 100644 --- a/src/tools/mmaps_generator/IntermediateValues.h +++ b/src/tools/mmaps_generator/IntermediateValues.h @@ -35,7 +35,7 @@ namespace MMAP rcPolyMesh* polyMesh; rcPolyMeshDetail* polyMeshDetail; - IntermediateValues() : compactHeightfield(NULL), heightfield(NULL), + IntermediateValues() : heightfield(NULL), compactHeightfield(NULL), contours(NULL), polyMesh(NULL), polyMeshDetail(NULL) {} ~IntermediateValues(); diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 754bced903c..689ccdc906d 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -29,7 +29,7 @@ // These make the linker happy. LoginDatabaseWorkerPool LoginDatabase; -uint32 GetLiquidFlags(uint32 liquidType) +uint32 GetLiquidFlags(uint32 /*liquidType*/) { return 0; } @@ -37,7 +37,7 @@ uint32 GetLiquidFlags(uint32 liquidType) #include "DisableMgr.h" namespace DisableMgr { - bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags) + bool IsDisabledFor(DisableType /*type*/, uint32 /*entry*/, Unit const* /*unit*/, uint8 /*flags*/) { return 0; } @@ -50,15 +50,15 @@ namespace MMAP MapBuilder::MapBuilder(float maxWalkableAngle, bool skipLiquid, bool skipContinents, bool skipJunkMaps, bool skipBattlegrounds, bool debugOutput, bool bigBaseUnit, const char* offMeshFilePath) : - m_terrainBuilder(NULL), + m_terrainBuilder (NULL), m_debugOutput (debugOutput), + m_offMeshFilePath (offMeshFilePath), m_skipContinents (skipContinents), m_skipJunkMaps (skipJunkMaps), m_skipBattlegrounds (skipBattlegrounds), m_maxWalkableAngle (maxWalkableAngle), m_bigBaseUnit (bigBaseUnit), - m_rcContext (NULL), - m_offMeshFilePath (offMeshFilePath) + m_rcContext (NULL) { m_terrainBuilder = new TerrainBuilder(skipLiquid); @@ -250,9 +250,12 @@ namespace MMAP printf("Building mesh from file\n"); int tileX, tileY, mapId; - fread(&mapId, sizeof(int), 1, file); - fread(&tileX, sizeof(int), 1, file); - fread(&tileY, sizeof(int), 1, file); + if (fread(&mapId, sizeof(int), 1, file) != 1) + return; + if (fread(&tileX, sizeof(int), 1, file) != 1) + return; + if (fread(&tileY, sizeof(int), 1, file) != 1) + return; dtNavMesh* navMesh = NULL; buildNavMesh(mapId, navMesh); @@ -263,23 +266,26 @@ namespace MMAP return; } - - int verticesCount, indicesCount; - fread(&verticesCount, sizeof(int), 1, file); - fread(&indicesCount, sizeof(int), 1, file); + uint verticesCount, indicesCount; + if (fread(&verticesCount, sizeof(uint), 1, file) != 1) + return; + if (fread(&indicesCount, sizeof(uint), 1, file) != 1) + return; float* verts = new float[verticesCount]; int* inds = new int[indicesCount]; - fread(verts, sizeof(float), verticesCount, file); - fread(inds, sizeof(int), indicesCount, file); + if (fread(verts, sizeof(float), verticesCount, file) != verticesCount) + return; + if (fread(inds, sizeof(int), indicesCount, file) != indicesCount) + return; MeshData data; - for (int i = 0; i < verticesCount; ++i) + for (uint i = 0; i < verticesCount; ++i) data.solidVerts.append(verts[i]); - for (int i = 0; i < indicesCount; ++i) + for (uint i = 0; i < indicesCount; ++i) data.solidTris.append(inds[i]); TerrainBuilder::cleanVertices(data.solidVerts, data.solidTris); @@ -310,7 +316,7 @@ namespace MMAP /**************************************************************************/ void MapBuilder::buildMap(uint32 mapID) { - printf("[Thread %i] Building map %03u:\n", ACE_Thread::self(), mapID); + printf("[Thread %u] Building map %03u:\n", uint32(ACE_Thread::self()), mapID); set* tiles = getTileList(mapID); @@ -409,7 +415,6 @@ namespace MMAP //if (tileBits < 1) tileBits = 1; // need at least one bit! //int polyBits = sizeof(dtPolyRef)*8 - SALT_MIN_BITS - tileBits; - int tileBits = STATIC_TILE_BITS; int polyBits = STATIC_POLY_BITS; int maxTiles = tiles->size(); @@ -955,8 +960,10 @@ namespace MMAP return false; MmapTileHeader header; - fread(&header, sizeof(MmapTileHeader), 1, file); + int count = fread(&header, sizeof(MmapTileHeader), 1, file); fclose(file); + if (count != 1) + return false; if (header.mmapMagic != MMAP_MAGIC || header.dtVersion != DT_NAVMESH_VERSION) return false; diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index fd02ec02d50..966c12ec19e 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -75,7 +75,7 @@ namespace MMAP LISTFILE_OK = 1 }; - inline ListFilesResult getDirContents(vector &fileList, string dirpath = ".", string filter = "*", bool includeSubDirs = false) + inline ListFilesResult getDirContents(vector &fileList, string dirpath = ".", string filter = "*") { #ifdef WIN32 HANDLE hFind; diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 0159219c110..22946df478a 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -27,6 +27,9 @@ namespace MMAP { + + char const* MAP_VERSION_MAGIC = "v1.3"; + TerrainBuilder::TerrainBuilder(bool skipLiquid) : m_skipLiquid (skipLiquid){ } TerrainBuilder::~TerrainBuilder() { } @@ -86,9 +89,8 @@ namespace MMAP return false; map_fileheader fheader; - fread(&fheader, sizeof(map_fileheader), 1, mapFile); - - if (fheader.versionMagic != *((uint32 const*)(MAP_VERSION_MAGIC))) + if (fread(&fheader, sizeof(map_fileheader), 1, mapFile) != 1 || + fheader.versionMagic != *((uint32 const*)(MAP_VERSION_MAGIC))) { fclose(mapFile); printf("%s is the wrong version, please extract new .map files\n", mapFileName); @@ -97,10 +99,14 @@ namespace MMAP map_heightHeader hheader; fseek(mapFile, fheader.heightMapOffset, SEEK_SET); - fread(&hheader, sizeof(map_heightHeader), 1, mapFile); - bool haveTerrain = !(hheader.flags & MAP_HEIGHT_NO_HEIGHT); - bool haveLiquid = fheader.liquidMapOffset && !m_skipLiquid; + bool haveTerrain = false; + bool haveLiquid = false; + if (fread(&hheader, sizeof(map_heightHeader), 1, mapFile) == 1) + { + haveTerrain = !(hheader.flags & MAP_HEIGHT_NO_HEIGHT); + haveLiquid = fheader.liquidMapOffset && !m_skipLiquid; + } // no data in this map file if (!haveTerrain && !haveLiquid) @@ -120,42 +126,53 @@ namespace MMAP // terrain data if (haveTerrain) { - int i; float heightMultiplier; float V9[V9_SIZE_SQ], V8[V8_SIZE_SQ]; + int expected = V9_SIZE_SQ + V8_SIZE_SQ; if (hheader.flags & MAP_HEIGHT_AS_INT8) { uint8 v9[V9_SIZE_SQ]; uint8 v8[V8_SIZE_SQ]; - fread(v9, sizeof(uint8), V9_SIZE_SQ, mapFile); - fread(v8, sizeof(uint8), V8_SIZE_SQ, mapFile); + int count = 0; + count += fread(v9, sizeof(uint8), V9_SIZE_SQ, mapFile); + count += fread(v8, sizeof(uint8), V8_SIZE_SQ, mapFile); + if (count != expected) + printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count); + heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 255; - for (i = 0; i < V9_SIZE_SQ; ++i) + for (int i = 0; i < V9_SIZE_SQ; ++i) V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight; - for (i = 0; i < V8_SIZE_SQ; ++i) + for (int i = 0; i < V8_SIZE_SQ; ++i) V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight; } else if (hheader.flags & MAP_HEIGHT_AS_INT16) { uint16 v9[V9_SIZE_SQ]; uint16 v8[V8_SIZE_SQ]; - fread(v9, sizeof(uint16), V9_SIZE_SQ, mapFile); - fread(v8, sizeof(uint16), V8_SIZE_SQ, mapFile); + int count = 0; + count += fread(v9, sizeof(uint16), V9_SIZE_SQ, mapFile); + count += fread(v8, sizeof(uint16), V8_SIZE_SQ, mapFile); + if (count != expected) + printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count); + heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 65535; - for (i = 0; i < V9_SIZE_SQ; ++i) + for (int i = 0; i < V9_SIZE_SQ; ++i) V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight; - for (i = 0; i < V8_SIZE_SQ; ++i) + for (int i = 0; i < V8_SIZE_SQ; ++i) V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight; } else { - fread (V9, sizeof(float), V9_SIZE_SQ, mapFile); - fread(V8, sizeof(float), V8_SIZE_SQ, mapFile); + int count = 0; + count += fread(V9, sizeof(float), V9_SIZE_SQ, mapFile); + count += fread(V8, sizeof(float), V8_SIZE_SQ, mapFile); + if (count != expected) + printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count); } // hole data @@ -163,7 +180,8 @@ namespace MMAP { memset(holes, 0, fheader.holesSize); fseek(mapFile, fheader.holesOffset, SEEK_SET); - fread(holes, fheader.holesSize, 1, mapFile); + if (fread(holes, fheader.holesSize, 1, mapFile) != 1) + printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); } int count = meshData.solidVerts.size() / 3; @@ -172,7 +190,7 @@ namespace MMAP float coord[3]; - for (i = 0; i < V9_SIZE_SQ; ++i) + for (int i = 0; i < V9_SIZE_SQ; ++i) { getHeightCoord(i, GRID_V9, xoffset, yoffset, coord, V9); meshData.solidVerts.append(coord[0]); @@ -180,7 +198,7 @@ namespace MMAP meshData.solidVerts.append(coord[1]); } - for (i = 0; i < V8_SIZE_SQ; ++i) + for (int i = 0; i < V8_SIZE_SQ; ++i) { getHeightCoord(i, GRID_V8, xoffset, yoffset, coord, V8); meshData.solidVerts.append(coord[0]); @@ -188,10 +206,10 @@ namespace MMAP meshData.solidVerts.append(coord[1]); } - int j, indices[3], loopStart, loopEnd, loopInc; + int indices[3], loopStart = 0, loopEnd = 0, loopInc = 0; getLoopVars(portion, loopStart, loopEnd, loopInc); - for (i = loopStart; i < loopEnd; i+=loopInc) - for (j = TOP; j <= BOTTOM; j+=1) + for (int i = loopStart; i < loopEnd; i+=loopInc) + for (int j = TOP; j <= BOTTOM; j+=1) { getHeightTriangle(i, Spot(j), indices); ttriangles.append(indices[2] + count); @@ -205,19 +223,25 @@ namespace MMAP { map_liquidHeader lheader; fseek(mapFile, fheader.liquidMapOffset, SEEK_SET); - fread(&lheader, sizeof(map_liquidHeader), 1, mapFile); + if (fread(&lheader, sizeof(map_liquidHeader), 1, mapFile) != 1) + printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); + float* liquid_map = NULL; if (!(lheader.flags & MAP_LIQUID_NO_TYPE)) - fread(liquid_type, sizeof(liquid_type), 1, mapFile); + if (fread(liquid_type, sizeof(liquid_type), 1, mapFile) != 1) + printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) { - liquid_map = new float [lheader.width*lheader.height]; - fread(liquid_map, sizeof(float), lheader.width*lheader.height, mapFile); + uint toRead = lheader.width*lheader.height; + liquid_map = new float [toRead]; + if (fread(liquid_map, sizeof(float), toRead, mapFile) != toRead) + printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); } + // FIXME: "the address of ‘liquid_type’ will always evaluate as ‘true’" if (liquid_type && liquid_map) { int count = meshData.liquidVerts.size() / 3; @@ -263,9 +287,8 @@ namespace MMAP delete [] liquid_map; - int indices[3], loopStart, loopEnd, loopInc, triInc; + int indices[3], loopStart = 0, loopEnd = 0, loopInc = 0, triInc = BOTTOM-TOP; getLoopVars(portion, loopStart, loopEnd, loopInc); - triInc = BOTTOM-TOP; // generate triangles for (int i = loopStart; i < loopEnd; i+=loopInc) @@ -283,7 +306,7 @@ namespace MMAP // now that we have gathered the data, we can figure out which parts to keep: // liquid above ground, ground above liquid - int loopStart, loopEnd, loopInc, tTriCount = 4; + int loopStart = 0, loopEnd = 0, loopInc = 0, tTriCount = 4; bool useTerrain, useLiquid; float* lverts = meshData.liquidVerts.getCArray(); @@ -313,6 +336,7 @@ namespace MMAP useTerrain = true; useLiquid = true; uint8 liquidType = MAP_LIQUID_TYPE_NO_WATER; + // FIXME: "warning: the address of ‘liquid_type’ will always evaluate as ‘true’" // if there is no liquid, don't use liquid if (!liquid_type || !meshData.liquidVerts.size() || !ltriangles.size()) @@ -825,13 +849,13 @@ namespace MMAP while(fgets(buf, 512, fp)) { float p0[3], p1[3]; - int mid, tx, ty; + uint32 mid, tx, ty; float size; - if (10 != sscanf(buf, "%d %d,%d (%f %f %f) (%f %f %f) %f", &mid, &tx, &ty, - &p0[0], &p0[1], &p0[2], &p1[0], &p1[1], &p1[2], &size)) + if (sscanf(buf, "%d %d,%d (%f %f %f) (%f %f %f) %f", &mid, &tx, &ty, + &p0[0], &p0[1], &p0[2], &p1[0], &p1[1], &p1[2], &size) != 10) continue; - if (mapID == mid, tileX == tx, tileY == ty) + if (mapID == mid && tileX == tx && tileY == ty) { meshData.offMeshConnections.append(p0[1]); meshData.offMeshConnections.append(p0[2]); diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h index 6d478753279..7a24146946b 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.h +++ b/src/tools/mmaps_generator/TerrainBuilder.h @@ -62,7 +62,6 @@ namespace MMAP // see following files: // contrib/extractor/system.cpp // src/game/Map.cpp - static char const* MAP_VERSION_MAGIC = "v1.3"; struct MeshData { diff --git a/src/tools/mmaps_generator/VMapExtensions.cpp b/src/tools/mmaps_generator/VMapExtensions.cpp index 4f203e11c21..2b525fbf353 100644 --- a/src/tools/mmaps_generator/VMapExtensions.cpp +++ b/src/tools/mmaps_generator/VMapExtensions.cpp @@ -57,7 +57,7 @@ namespace VMAP } // declared in src/shared/vmap/ModelInstance.h - WorldModel* const ModelInstance::getWorldModel() + WorldModel* ModelInstance::getWorldModel() { return iModel; } diff --git a/src/tools/vmap4_extractor/adtfile.cpp b/src/tools/vmap4_extractor/adtfile.cpp index a605118eead..56e62d474d1 100644 --- a/src/tools/vmap4_extractor/adtfile.cpp +++ b/src/tools/vmap4_extractor/adtfile.cpp @@ -69,8 +69,7 @@ void fixname2(char* name, size_t len) char* GetExtension(char* FileName) { - char* szTemp; - if (szTemp = strrchr(FileName, '.')) + if (char* szTemp = strrchr(FileName, '.')) return szTemp; return NULL; } diff --git a/src/tools/vmap4_extractor/model.cpp b/src/tools/vmap4_extractor/model.cpp index c642f73ccae..b950db023fe 100644 --- a/src/tools/vmap4_extractor/model.cpp +++ b/src/tools/vmap4_extractor/model.cpp @@ -152,10 +152,10 @@ ModelInstance::ModelInstance(MPQFile& f, char const* ModelInstName, uint32 mapID fseek(input, 8, SEEK_SET); // get the correct no of vertices int nVertices; - fread(&nVertices, sizeof (int), 1, input); + int count = fread(&nVertices, sizeof (int), 1, input); fclose(input); - if(nVertices == 0) + if (count != 1 || nVertices == 0) return; uint16 adtId = 0;// not used for models diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp index 186f9c8606e..89e4b850dac 100644 --- a/src/tools/vmap4_extractor/vmapexport.cpp +++ b/src/tools/vmap4_extractor/vmapexport.cpp @@ -461,8 +461,7 @@ int main(int argc, char ** argv) printf("Your output directory seems to be polluted, please use an empty directory!\n"); printf(""); char garbage[2]; - scanf("%c", garbage); - return 1; + return scanf("%c", garbage); } } diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp index 0bc749b9bd5..7c9f23c5a95 100644 --- a/src/tools/vmap4_extractor/wmo.cpp +++ b/src/tools/vmap4_extractor/wmo.cpp @@ -521,10 +521,10 @@ WMOInstance::WMOInstance(MPQFile& f, char const* WmoInstName, uint32 mapID, uint fseek(input, 8, SEEK_SET); // get the correct no of vertices int nVertices; - fread(&nVertices, sizeof (int), 1, input); + int count = fread(&nVertices, sizeof (int), 1, input); fclose(input); - if(nVertices == 0) + if (count != 1 || nVertices == 0) return; float x,z; -- cgit v1.2.3 From cbf9324f61984727163150ed09a72288da45e3a4 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Wed, 9 Jan 2013 21:01:39 +0100 Subject: Core: Fix build --- src/tools/mesh_extractor/DBC.cpp | 2 +- src/tools/mmaps_generator/MapBuilder.cpp | 10 +++++----- src/tools/mmaps_generator/PathCommon.h | 2 +- src/tools/mmaps_generator/TerrainBuilder.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/DBC.cpp b/src/tools/mesh_extractor/DBC.cpp index 5c54d975487..3c846363d06 100644 --- a/src/tools/mesh_extractor/DBC.cpp +++ b/src/tools/mesh_extractor/DBC.cpp @@ -5,7 +5,7 @@ DBC::DBC( FILE* stream ) : StringBlock(NULL), StringBlockSize(0), IsFaulty(true) { char magic[5]; - uint count = 0; + uint32 count = 0; count += fread(&magic, sizeof(char), 4, stream); magic[4] = '\0'; count += fread(&RecordCount, sizeof(uint32), 1, stream); diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 689ccdc906d..29591a406df 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -266,10 +266,10 @@ namespace MMAP return; } - uint verticesCount, indicesCount; - if (fread(&verticesCount, sizeof(uint), 1, file) != 1) + uint32 verticesCount, indicesCount; + if (fread(&verticesCount, sizeof(uint32), 1, file) != 1) return; - if (fread(&indicesCount, sizeof(uint), 1, file) != 1) + if (fread(&indicesCount, sizeof(uint32), 1, file) != 1) return; float* verts = new float[verticesCount]; @@ -282,10 +282,10 @@ namespace MMAP MeshData data; - for (uint i = 0; i < verticesCount; ++i) + for (uint32 i = 0; i < verticesCount; ++i) data.solidVerts.append(verts[i]); - for (uint i = 0; i < indicesCount; ++i) + for (uint32 i = 0; i < indicesCount; ++i) data.solidTris.append(inds[i]); TerrainBuilder::cleanVertices(data.solidVerts, data.solidTris); diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index 966c12ec19e..8fad880212b 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -90,7 +90,7 @@ namespace MMAP return LISTFILE_DIRECTORY_NOT_FOUND; do { - if (includeSubDirs || (findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + if (findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == 0) fileList.push_back(string(findFileInfo.cFileName)); } while (FindNextFile(hFind, &findFileInfo)); diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 22946df478a..97e504d5160 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -235,7 +235,7 @@ namespace MMAP if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) { - uint toRead = lheader.width*lheader.height; + uint8 toRead = lheader.width*lheader.height; liquid_map = new float [toRead]; if (fread(liquid_map, sizeof(float), toRead, mapFile) != toRead) printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); -- cgit v1.2.3 From 7210ffe34d2052c1aee642ac3af40425c8ba137e Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Wed, 9 Jan 2013 21:14:12 +0100 Subject: Core: Fix warnings --- src/server/scripts/Commands/cs_mmaps.cpp | 10 +++++----- src/tools/mmaps_generator/PathCommon.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/tools') diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index c17c01adc33..09e777e4047 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -117,7 +117,7 @@ public: return true; } - static bool HandleMmapLocCommand(ChatHandler* handler, const char* args) + static bool HandleMmapLocCommand(ChatHandler* handler, char const* /*args*/) { handler->PSendSysMessage("mmap tileloc:"); @@ -171,7 +171,7 @@ public: return true; } - static bool HandleMmapLoadedTilesCommand(ChatHandler* handler, const char* args) + static bool HandleMmapLoadedTilesCommand(ChatHandler* handler, char const* /*args*/) { uint32 mapid = handler->GetSession()->GetPlayer()->GetMapId(); dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(mapid); @@ -196,7 +196,7 @@ public: return true; } - static bool HandleMmapStatsCommand(ChatHandler* handler, const char* args) + static bool HandleMmapStatsCommand(ChatHandler* handler, char const* /*args*/) { uint32 mapId = handler->GetSession()->GetPlayer()->GetMapId(); handler->PSendSysMessage("mmap stats:"); @@ -244,12 +244,12 @@ public: return true; } - static bool HandleMmapTestArea(ChatHandler* handler, const char* args) + static bool HandleMmapTestArea(ChatHandler* handler, char const* /*args*/) { float radius = 40.0f; WorldObject* object = handler->GetSession()->GetPlayer(); - CellCoord pair(Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY()) ); + CellCoord pair(Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY())); Cell cell(pair); cell.SetNoCreate(); diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index 8fad880212b..820ff34d425 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -90,7 +90,7 @@ namespace MMAP return LISTFILE_DIRECTORY_NOT_FOUND; do { - if (findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == 0) + if ((findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) fileList.push_back(string(findFileInfo.cFileName)); } while (FindNextFile(hFind, &findFileInfo)); -- cgit v1.2.3 From 1154c62b65af70e7801bb280aa90a98581d0c1ec Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Thu, 10 Jan 2013 12:40:26 +0100 Subject: Core/Tools: Fix logic fail for mmaps generator (thx armano2) --- src/tools/mmaps_generator/TerrainBuilder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 97e504d5160..d3c3772532d 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -235,7 +235,7 @@ namespace MMAP if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) { - uint8 toRead = lheader.width*lheader.height; + uint32 toRead = lheader.width * lheader.height; liquid_map = new float [toRead]; if (fread(liquid_map, sizeof(float), toRead, mapFile) != toRead) printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); -- cgit v1.2.3 From dfbf318a4feb48d412391d7da1df9381310858ab Mon Sep 17 00:00:00 2001 From: Spp Date: Thu, 10 Jan 2013 15:29:08 +0100 Subject: Typo fix --- src/tools/map_extractor/adt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/tools/map_extractor/adt.cpp b/src/tools/map_extractor/adt.cpp index 505813c4bd0..eeb69134fab 100644 --- a/src/tools/map_extractor/adt.cpp +++ b/src/tools/map_extractor/adt.cpp @@ -8,7 +8,7 @@ int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; u_map_fcc MHDRMagic = { {'M','H','D','R'} }; u_map_fcc MCINMagic = { {'M','C','I','N'} }; -u_map_fcc MH20Magic = { {'M','H','2','0'} }; +u_map_fcc MH2OMagic = { {'M','H','2','O'} }; u_map_fcc MCNKMagic = { {'M','C','N','K'} }; u_map_fcc MCVTMagic = { {'M','C','V','T'} }; u_map_fcc MCLQMagic = { {'M','C','L','Q'} }; @@ -93,7 +93,7 @@ bool adt_MCIN::prepareLoadedData() bool adt_MH2O::prepareLoadedData() { - if (fcc != MH20Magic.fcc) + if (fcc != MH2OMagic.fcc) return false; // Check liquid data -- cgit v1.2.3 From e783349803e64d0fd1879a97dcb4749435a87f05 Mon Sep 17 00:00:00 2001 From: Spp Date: Sat, 12 Jan 2013 02:15:10 +0100 Subject: Use correct initialization of some vars --- src/tools/map_extractor/adt.cpp | 12 ++++++------ src/tools/map_extractor/loadlib.cpp | 2 +- src/tools/map_extractor/wdt.cpp | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/tools') diff --git a/src/tools/map_extractor/adt.cpp b/src/tools/map_extractor/adt.cpp index eeb69134fab..a93ead838fe 100644 --- a/src/tools/map_extractor/adt.cpp +++ b/src/tools/map_extractor/adt.cpp @@ -6,12 +6,12 @@ int holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888}; int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; -u_map_fcc MHDRMagic = { {'M','H','D','R'} }; -u_map_fcc MCINMagic = { {'M','C','I','N'} }; -u_map_fcc MH2OMagic = { {'M','H','2','O'} }; -u_map_fcc MCNKMagic = { {'M','C','N','K'} }; -u_map_fcc MCVTMagic = { {'M','C','V','T'} }; -u_map_fcc MCLQMagic = { {'M','C','L','Q'} }; +u_map_fcc MHDRMagic = { {'R','D','H','M'} }; +u_map_fcc MCINMagic = { {'N','I','C','M'} }; +u_map_fcc MH2OMagic = { {'0','2','H','M'} }; +u_map_fcc MCNKMagic = { {'K','N','C','M'} }; +u_map_fcc MCVTMagic = { {'T','V','C','M'} }; +u_map_fcc MCLQMagic = { {'Q','L','C','M'} }; bool isHole(int holes, int i, int j) { diff --git a/src/tools/map_extractor/loadlib.cpp b/src/tools/map_extractor/loadlib.cpp index d1ea40110de..5dcb479a11c 100644 --- a/src/tools/map_extractor/loadlib.cpp +++ b/src/tools/map_extractor/loadlib.cpp @@ -6,7 +6,7 @@ class MPQFile; -u_map_fcc MverMagic = { {'M','V','E','R'} }; +u_map_fcc MverMagic = { {'R','E','V','M'} }; FileLoader::FileLoader() { diff --git a/src/tools/map_extractor/wdt.cpp b/src/tools/map_extractor/wdt.cpp index 90a07eafab3..ff255145583 100644 --- a/src/tools/map_extractor/wdt.cpp +++ b/src/tools/map_extractor/wdt.cpp @@ -2,9 +2,9 @@ #include "wdt.h" -u_map_fcc MWMOMagic = { {'M', 'W', 'M', 'O'} }; -u_map_fcc MPHDMagic = { {'M', 'P', 'H', 'D'} }; -u_map_fcc MAINMagic = { {'M', 'A', 'I', 'N'} }; +u_map_fcc MWMOMagic = { {'O', 'M', 'W', 'M'} }; +u_map_fcc MPHDMagic = { {'D', 'H', 'P', 'M'} }; +u_map_fcc MAINMagic = { {'N', 'I', 'A', 'M'} }; bool wdt_MWMO::prepareLoadedData() { -- cgit v1.2.3 From 32e08bcd122fce70ae33eed3f0ec44d35a60eff2 Mon Sep 17 00:00:00 2001 From: Nay Date: Sun, 13 Jan 2013 02:11:21 +0000 Subject: Tools/Extractor: Fix yet another typo in ADT. Fixes extracting. Closes #8900 --- src/tools/map_extractor/adt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/map_extractor/adt.cpp b/src/tools/map_extractor/adt.cpp index a93ead838fe..30524dbd640 100644 --- a/src/tools/map_extractor/adt.cpp +++ b/src/tools/map_extractor/adt.cpp @@ -8,7 +8,7 @@ int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; u_map_fcc MHDRMagic = { {'R','D','H','M'} }; u_map_fcc MCINMagic = { {'N','I','C','M'} }; -u_map_fcc MH2OMagic = { {'0','2','H','M'} }; +u_map_fcc MH2OMagic = { {'O','2','H','M'} }; u_map_fcc MCNKMagic = { {'K','N','C','M'} }; u_map_fcc MCVTMagic = { {'T','V','C','M'} }; u_map_fcc MCLQMagic = { {'Q','L','C','M'} }; -- cgit v1.2.3 From 65cd79dc779e1900cb82e862ffab9ef3a20771ac Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Mon, 14 Jan 2013 17:42:06 +0100 Subject: Core/Misc: Update headers to 2013 --- src/server/collision/Management/MMapFactory.cpp | 2 +- src/server/collision/Management/MMapFactory.h | 2 +- src/server/collision/Management/MMapManager.cpp | 2 +- src/server/collision/Management/MMapManager.h | 2 +- src/server/scripts/Commands/cs_mmaps.cpp | 2 +- src/tools/mesh_extractor/CMakeLists.txt | 2 +- src/tools/mmaps_generator/IntermediateValues.cpp | 2 +- src/tools/mmaps_generator/IntermediateValues.h | 2 +- src/tools/mmaps_generator/MapBuilder.cpp | 2 +- src/tools/mmaps_generator/MapBuilder.h | 2 +- src/tools/mmaps_generator/PathCommon.h | 2 +- src/tools/mmaps_generator/TerrainBuilder.cpp | 2 +- src/tools/mmaps_generator/TerrainBuilder.h | 2 +- src/tools/mmaps_generator/VMapExtensions.cpp | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src/tools') diff --git a/src/server/collision/Management/MMapFactory.cpp b/src/server/collision/Management/MMapFactory.cpp index 0b292b56dca..7adf7fbfa66 100644 --- a/src/server/collision/Management/MMapFactory.cpp +++ b/src/server/collision/Management/MMapFactory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2010 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/server/collision/Management/MMapFactory.h b/src/server/collision/Management/MMapFactory.h index a006aedfa6d..00f19a194d3 100644 --- a/src/server/collision/Management/MMapFactory.h +++ b/src/server/collision/Management/MMapFactory.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2010 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp index 1b6cf5c0260..e3ed8f3310a 100644 --- a/src/server/collision/Management/MMapManager.cpp +++ b/src/server/collision/Management/MMapManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2010 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/server/collision/Management/MMapManager.h b/src/server/collision/Management/MMapManager.h index 23b7d5fc6f8..56b1b856d65 100644 --- a/src/server/collision/Management/MMapManager.h +++ b/src/server/collision/Management/MMapManager.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2010 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index 09e777e4047..4649e13e1c4 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2012 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * * 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 diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt index 29c571d9301..b8bd9f54331 100644 --- a/src/tools/mesh_extractor/CMakeLists.txt +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (C) 2005-2009 MaNGOS project -# Copyright (C) 2008-2012 TrinityCore +# Copyright (C) 2008-2013 TrinityCore # # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without diff --git a/src/tools/mmaps_generator/IntermediateValues.cpp b/src/tools/mmaps_generator/IntermediateValues.cpp index b473d6472a0..6fad96887a2 100644 --- a/src/tools/mmaps_generator/IntermediateValues.cpp +++ b/src/tools/mmaps_generator/IntermediateValues.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/tools/mmaps_generator/IntermediateValues.h b/src/tools/mmaps_generator/IntermediateValues.h index 98042e1b917..89a5c3ae4c2 100644 --- a/src/tools/mmaps_generator/IntermediateValues.h +++ b/src/tools/mmaps_generator/IntermediateValues.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 29591a406df..9e6acd71a72 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index 61a71ff6d5b..c083e0b680a 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index 820ff34d425..413f2b8735d 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index d3c3772532d..f7cf76e9718 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h index 7a24146946b..6ad4284f416 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.h +++ b/src/tools/mmaps_generator/TerrainBuilder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/tools/mmaps_generator/VMapExtensions.cpp b/src/tools/mmaps_generator/VMapExtensions.cpp index 2b525fbf353..37b7d94af55 100644 --- a/src/tools/mmaps_generator/VMapExtensions.cpp +++ b/src/tools/mmaps_generator/VMapExtensions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify it -- cgit v1.2.3 From fcd258a8a97098c4392c216f9bd6f99424b5b4b9 Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 22 Jan 2013 15:40:12 +0100 Subject: Tools/MeshExtractor: Removed shared and MySQL dependencies. --- src/tools/mesh_extractor/CMakeLists.txt | 65 ++++++++------------------ src/tools/mesh_extractor/Cache.h | 5 +- src/tools/mesh_extractor/Chunk.h | 2 +- src/tools/mesh_extractor/Constants.h | 2 - src/tools/mesh_extractor/ContinentBuilder.h | 4 +- src/tools/mesh_extractor/DBC.cpp | 2 +- src/tools/mesh_extractor/DBC.h | 3 +- src/tools/mesh_extractor/LiquidHandler.h | 2 +- src/tools/mesh_extractor/MPQ.h | 14 +++--- src/tools/mesh_extractor/MPQManager.cpp | 3 +- src/tools/mesh_extractor/MPQManager.h | 4 +- src/tools/mesh_extractor/MeshExtractor.cpp | 28 ++++++----- src/tools/mesh_extractor/TileBuilder.cpp | 30 ++++++------ src/tools/mesh_extractor/Utils.h | 6 ++- src/tools/mesh_extractor/WorldModelHandler.cpp | 2 +- src/tools/mesh_extractor/WorldModelHandler.h | 2 +- 16 files changed, 74 insertions(+), 100 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt index b8bd9f54331..1b5d1564b71 100644 --- a/src/tools/mesh_extractor/CMakeLists.txt +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -11,69 +11,42 @@ file(GLOB_RECURSE sources *.cpp *.h) -if( UNIX ) - include_directories ( - ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/src/server/shared - ${CMAKE_SOURCE_DIR}/src/server/shared/Database - ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation - ${CMAKE_SOURCE_DIR}/src/server/shared/Threading - ${CMAKE_SOURCE_DIR}/src/server/shared/Logging - ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference - ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast - ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour - ${CMAKE_SOURCE_DIR}/dep/libmpq - ${CMAKE_SOURCE_DIR}/dep/g3dlite/include - ${ACE_INCLUDE_DIR} - ${MYSQL_INCLUDE_DIR} - ${OPENSSL_INCLUDE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ) -elseif( WIN32 ) - include_directories ( - ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/src/server/shared - ${CMAKE_SOURCE_DIR}/src/server/shared/Database - ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation - ${CMAKE_SOURCE_DIR}/src/server/shared/Threading - ${CMAKE_SOURCE_DIR}/src/server/shared/Logging - ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference - ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast - ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour - ${CMAKE_SOURCE_DIR}/dep/libmpq +add_definitions(-DNO_CORE_FUNCS) + +set(include_Base + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/dep/libmpq + ${CMAKE_SOURCE_DIR}/dep/g3dlite/include + ${ACE_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} +) + +if( WIN32 ) + set(include_Base + ${include_Base} ${CMAKE_SOURCE_DIR}/dep/libmpq/win - ${CMAKE_SOURCE_DIR}/dep/g3dlite/include - ${ACE_INCLUDE_DIR} - ${MYSQL_INCLUDE_DIR} - ${OPENSSL_INCLUDE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ) + ) endif() +include_directories(${include_Base}) + add_executable(MeshExtractor ${sources} ) target_link_libraries(MeshExtractor - shared g3dlib mpq Recast Detour - ${MYSQL_LIBRARY} - ${OPENSSL_LIBRARIES} - ${OPENSSL_EXTRA_LIBRARIES} ${BZIP2_LIBRARIES} ${ZLIB_LIBRARIES} ${ACE_LIBRARY} ) -add_dependencies(MeshExtractor mpq Recast Detour) - if( UNIX ) install(TARGETS MeshExtractor DESTINATION bin) elseif( WIN32 ) diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 34293b14b54..60e3d8434cf 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -2,8 +2,9 @@ #define CACHE_H #include #include -#include "Common.h" -#include "ace/Synch.h" +#include "Define.h" +#include +#include class WorldModelRoot; class Model; diff --git a/src/tools/mesh_extractor/Chunk.h b/src/tools/mesh_extractor/Chunk.h index 2eea36f69b6..f3681a9f576 100644 --- a/src/tools/mesh_extractor/Chunk.h +++ b/src/tools/mesh_extractor/Chunk.h @@ -1,6 +1,6 @@ #ifndef CHUNK_H #define CHUNK_H -#include "Common.h" +#include "Define.h" #include class ChunkedData; diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h index 54fa073fbef..02e2d25559f 100644 --- a/src/tools/mesh_extractor/Constants.h +++ b/src/tools/mesh_extractor/Constants.h @@ -1,8 +1,6 @@ #ifndef CONSTANTS_H #define CONSTANTS_H -#include "Common.h" - class Constants { public: diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h index 3d7b879879e..b36ca125b9e 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -2,7 +2,7 @@ #define CONT_BUILDER_H #include #include "WDT.h" -#include "Common.h" +#include "Define.h" class ContinentBuilder { @@ -22,7 +22,7 @@ private: WDT* TileMap; uint32 MapId; uint32 NumberOfThreads; - int tileXMin; + int tileXMin; int tileYMin; int tileXMax; int tileYMax; diff --git a/src/tools/mesh_extractor/DBC.cpp b/src/tools/mesh_extractor/DBC.cpp index 3c846363d06..9a55ff6d7ed 100644 --- a/src/tools/mesh_extractor/DBC.cpp +++ b/src/tools/mesh_extractor/DBC.cpp @@ -1,6 +1,6 @@ #include #include "DBC.h" -#include "Common.h" +#include "Define.h" DBC::DBC( FILE* stream ) : StringBlock(NULL), StringBlockSize(0), IsFaulty(true) { diff --git a/src/tools/mesh_extractor/DBC.h b/src/tools/mesh_extractor/DBC.h index 0c857bd40ed..5ed57754e73 100644 --- a/src/tools/mesh_extractor/DBC.h +++ b/src/tools/mesh_extractor/DBC.h @@ -1,7 +1,8 @@ #ifndef DBC_H #define DBC_H #include -#include "Common.h" +#include +#include "Define.h" class Record; diff --git a/src/tools/mesh_extractor/LiquidHandler.h b/src/tools/mesh_extractor/LiquidHandler.h index 6e8d0081adb..41e128ba20b 100644 --- a/src/tools/mesh_extractor/LiquidHandler.h +++ b/src/tools/mesh_extractor/LiquidHandler.h @@ -2,7 +2,7 @@ #define LIQUID_H #include "ADT.h" #include "Utils.h" -#include "Common.h" +#include "Define.h" #include diff --git a/src/tools/mesh_extractor/MPQ.h b/src/tools/mesh_extractor/MPQ.h index 15fce452726..2f8b082f526 100644 --- a/src/tools/mesh_extractor/MPQ.h +++ b/src/tools/mesh_extractor/MPQ.h @@ -2,27 +2,25 @@ #define MPQ_H #include "libmpq/mpq.h" -#include "Common.h" -#include +#include "Define.h" +#include #include #include #include #include -using namespace std; - class MPQArchive { public: mpq_archive_s *mpq_a; - - vector Files; + + std::vector Files; MPQArchive(const char* filename); void close(); - void GetFileListTo(vector& filelist) { + void GetFileListTo(std::vector& filelist) { uint32_t filenum; if(libmpq__file_number(mpq_a, "(listfile)", &filenum)) return; libmpq__off_t size, transferred; @@ -40,7 +38,7 @@ public: while ((token != NULL) && (counter < size)) { //cout << token << endl; token[strlen(token) - 1] = 0; - string s = token; + std::string s = token; filelist.push_back(s); counter += strlen(token) + 2; token = strtok(NULL, seps); diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 90491dfb945..0fe07cd8b85 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -2,8 +2,7 @@ #include "MPQ.h" #include "DBC.h" #include "Utils.h" - -#include "ace/Synch.h" +#include char* MPQManager::Files[] = { "common.MPQ", diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h index c23d7177825..788be7f5974 100644 --- a/src/tools/mesh_extractor/MPQManager.h +++ b/src/tools/mesh_extractor/MPQManager.h @@ -2,7 +2,9 @@ #define MPQ_MANAGER_H #include "MPQ.h" -#include "ace/Synch.h" +#include +#include +#include class DBC; class MPQManager diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index b164ff5861d..e06f44c7125 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -12,11 +12,6 @@ #include -#include "Common.h" -#include "LoginDatabase.h" -#include "Util.h" -LoginDatabaseWorkerPool LoginDatabase; - MPQManager* MPQHandler; CacheClass* Cache; @@ -64,7 +59,7 @@ void ExtractDBCs() path += std::string(MPQManager::Languages[*itr]) + "/"; Utils::CreateDir(path); } - + std::string component = "component.wow-" + std::string(MPQManager::Languages[*itr]) + ".txt"; // Extract the component file Utils::SaveToDisk(MPQHandler->GetFile(component), path + component); @@ -104,7 +99,7 @@ void ExtractGameobjectModels() { fileName = Utils::FixModelPath(fileName); Model model(path); - + if (model.IsBad) continue; @@ -151,7 +146,7 @@ void ExtractGameobjectModels() fwrite(indices, sizeof(uint16), numTris, output); } - + fwrite("VERT", 4, 1, output); wsize = sizeof(int) + sizeof(float) * 3 * numVerts; fwrite(&wsize, sizeof(int), 1, output); @@ -170,7 +165,7 @@ void ExtractGameobjectModels() fwrite(vertices, sizeof(float), numVerts * 3, output); } - + fclose(output); delete[] indices; delete[] vertices; @@ -254,11 +249,14 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis param = argv[++i]; if (!param) return false; - std::string maps = std::string(param); - Tokenizer tokens(maps, ','); - for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr) - mapList.insert(atoi(*itr)); + char* copy = strdup(param); + char* token = strtok(copy, ","); + while (token) + { + mapList.insert(atoi(token)); + token = strtok(NULL, ","); + } printf("Extracting only provided list of maps (%u).\n", uint32(mapList.size())); } @@ -337,7 +335,7 @@ int main(int argc, char* argv[]) uint32 threads = 4, extractFlags = 0; std::set mapIds; bool debug = false; - + if (!HandleArgs(argc, argv, threads, mapIds, debug, extractFlags)) { PrintUsage(); @@ -425,6 +423,6 @@ int main(int argc, char* argv[]) printf("Found!"); } - + return 0; } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 4a14cbbd51d..9bb9b11619f 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -10,7 +10,7 @@ #include "RecastAlloc.h" #include "DetourNavMeshBuilder.h" -#include "ace/Synch.h" +#include TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId) : World(world), X(x), Y(y), MapId(mapId), _Geometry(NULL), DataSize(0), cBuilder(_cBuilder) @@ -118,7 +118,7 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) fprintf(debug, "f %i %i %i\n", _Geometry->Triangles[i].V0 + 1, _Geometry->Triangles[i].V1 + 1, _Geometry->Triangles[i].V2 + 1); fclose(debug); } - + uint32 numVerts = _Geometry->Vertices.size(); uint32 numTris = _Geometry->Triangles.size(); float* vertices; @@ -128,13 +128,13 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) _Geometry->Vertices.clear(); _Geometry->Triangles.clear(); - + rcVcopy(Config.bmin, cBuilder->bmin); rcVcopy(Config.bmax, cBuilder->bmax); - + // this sets the dimensions of the heightfield - should maybe happen before border padding rcCalcGridSize(Config.bmin, Config.bmax, Config.cs, &Config.width, &Config.height); - + // Initialize per tile config. rcConfig tileCfg = Config; tileCfg.width = Config.tileSize + Config.borderSize * 2; @@ -154,8 +154,8 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) tileCfg.bmin[2] = Config.bmin[2] + float(y * Config.tileSize - Config.borderSize) * Config.cs; tileCfg.bmax[0] = Config.bmin[0] + float((x + 1) * Config.tileSize + Config.borderSize) * Config.cs; tileCfg.bmax[2] = Config.bmin[2] + float((y + 1) * Config.tileSize + Config.borderSize) * Config.cs; - - + + rcHeightfield* hf = rcAllocHeightfield(); rcCreateHeightfield(Context, *hf, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch); rcClearUnwalkableTriangles(Context, tileCfg.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); @@ -198,7 +198,7 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) // Free memory rcFreeCompactHeightfield(chf); rcFreeContourSet(cset); - + pmmerge[nmerge] = pmesh; dmmerge[nmerge] = dmesh; ++nmerge; @@ -207,15 +207,15 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) rcPolyMesh* pmesh = rcAllocPolyMesh(); rcMergePolyMeshes(Context, pmmerge, nmerge, *pmesh); - + rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); rcMergePolyMeshDetails(Context, dmmerge, nmerge, *dmesh); - + delete[] pmmerge; delete[] dmmerge; - + printf("[%02i,%02i] Meshes merged!\n", X, Y); - + // Remove padding from the polymesh data. (Remove this odditity) for (int i = 0; i < pmesh->nverts; ++i) { @@ -262,10 +262,10 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) rcVcopy(params.bmin, cBuilder->bmin); rcVcopy(params.bmax, cBuilder->bmax); - + // Offmesh-connection settings params.offMeshConCount = 0; // none for now - + params.tileSize = Constants::VertexPerMap; if (!params.polyCount || !params.polys || Constants::TilesPerMap * Constants::TilesPerMap == params.polyCount) @@ -281,7 +281,7 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) delete vertices; return NULL; } - + int navDataSize; uint8* navData; printf("[%02i,%02i] Creating the navmesh with %i vertices, %i polys, %i triangles!\n", X, Y, pmesh->nverts, pmesh->npolys, dmesh->ntris); diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index e7380ed8142..41ea33e6157 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -7,12 +7,16 @@ #include "G3D/Matrix4.h" #include "DetourNavMesh.h" -#include "Common.h" +#include "Define.h" #include "Constants.h" +#include + struct WorldModelDefinition; class DoodadInstance; +#define ASSERT(assertion) { if (!(assertion)) { ACE_Stack_Trace st; fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n", __FILE__, __LINE__, __FUNCTION__, #assertion, st.c_str()); *((volatile int*)NULL) = 0; } } + struct Vector3 { Vector3() {} diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index 6ce41807492..ecfff4e97d4 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -3,7 +3,7 @@ #include "Chunk.h" #include "Cache.h" #include "Model.h" -#include "Common.h" +#include "Define.h" #include "G3D/Matrix4.h" #include diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h index cccedfa60fb..29715ded696 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.h +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -1,6 +1,6 @@ #ifndef WMODEL_HNDL_H #define WMODEL_HNDL_H -#include "Common.h" +#include "Define.h" #include "Utils.h" #include "WorldModelRoot.h" #include "ObjectDataHandler.h" -- cgit v1.2.3 From 259a29c0935e566dd63d8c03360c5cd19b4ffe52 Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 22 Jan 2013 18:40:32 +0100 Subject: Tools/Extractors: Mmap extractors no longer depend on shared and MySQL libraries --- cmake/showoptions.cmake | 1 + src/server/collision/Management/VMapManager2.cpp | 12 ++-- src/server/collision/Maps/MapTree.cpp | 21 ++---- src/server/collision/Models/GameObjectModel.cpp | 13 ++-- src/server/collision/VMapDefinitions.h | 12 ++++ src/server/shared/Debugging/Errors.h | 2 +- src/tools/map_extractor/CMakeLists.txt | 19 +++-- src/tools/map_extractor/mpq_libmpq.cpp | 2 +- src/tools/map_extractor/mpq_libmpq04.h | 3 - src/tools/mesh_extractor/CMakeLists.txt | 8 +-- src/tools/mesh_extractor/MPQ.cpp | 2 +- src/tools/mmaps_generator/CMakeLists.txt | 45 +++++------- src/tools/mmaps_generator/IntermediateValues.cpp | 2 +- src/tools/mmaps_generator/MapBuilder.cpp | 55 +++++++------- src/tools/mmaps_generator/MapBuilder.h | 10 +-- src/tools/mmaps_generator/PathCommon.h | 43 +++++++++-- src/tools/mmaps_generator/PathGenerator.cpp | 3 +- src/tools/mmaps_generator/TerrainBuilder.cpp | 92 +++++++++++++++++++----- src/tools/mmaps_generator/TerrainBuilder.h | 11 +-- src/tools/mmaps_generator/VMapExtensions.cpp | 6 +- src/tools/vmap4_assembler/CMakeLists.txt | 2 - src/tools/vmap4_extractor/CMakeLists.txt | 25 +++---- src/tools/vmap4_extractor/mpq_libmpq.cpp | 2 +- src/tools/vmap4_extractor/mpq_libmpq04.h | 3 - src/tools/vmap4_extractor/wdtfile.cpp | 2 +- 25 files changed, 220 insertions(+), 176 deletions(-) (limited to 'src/tools') diff --git a/cmake/showoptions.cmake b/cmake/showoptions.cmake index 47ad7b0889b..d3415e4e204 100644 --- a/cmake/showoptions.cmake +++ b/cmake/showoptions.cmake @@ -34,6 +34,7 @@ endif() if( TOOLS ) message("* Build map/vmap tools : Yes") + add_definitions(-DNO_CORE_FUNCS) else() message("* Build map/vmap tools : No (default)") endif() diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp index 5e3741ca753..8a1bd346957 100644 --- a/src/server/collision/Management/VMapManager2.cpp +++ b/src/server/collision/Management/VMapManager2.cpp @@ -24,13 +24,13 @@ #include "MapTree.h" #include "ModelInstance.h" #include "WorldModel.h" -#include "VMapDefinitions.h" -#include "Log.h" #include #include #include #include "DisableMgr.h" #include "DBCStores.h" +#include "Log.h" +#include "VMapDefinitions.h" using G3D::Vector3; @@ -257,11 +257,11 @@ namespace VMAP WorldModel* worldmodel = new WorldModel(); if (!worldmodel->readFile(basepath + filename + ".vmo")) { - sLog->outError(LOG_FILTER_GENERAL, "VMapManager2: could not load '%s%s.vmo'", basepath.c_str(), filename.c_str()); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "VMapManager2: could not load '%s%s.vmo'", basepath.c_str(), filename.c_str()); delete worldmodel; return NULL; } - sLog->outDebug(LOG_FILTER_MAPS, "VMapManager2: loading file '%s%s'", basepath.c_str(), filename.c_str()); + VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "VMapManager2: loading file '%s%s'", basepath.c_str(), filename.c_str()); model = iLoadedModelFiles.insert(std::pair(filename, ManagedModel())).first; model->second.setModel(worldmodel); } @@ -277,12 +277,12 @@ namespace VMAP ModelFileMap::iterator model = iLoadedModelFiles.find(filename); if (model == iLoadedModelFiles.end()) { - sLog->outError(LOG_FILTER_GENERAL, "VMapManager2: trying to unload non-loaded file '%s'", filename.c_str()); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "VMapManager2: trying to unload non-loaded file '%s'", filename.c_str()); return; } if (model->second.decRefCount() == 0) { - sLog->outDebug(LOG_FILTER_MAPS, "VMapManager2: unloading file '%s'", filename.c_str()); + VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "VMapManager2: unloading file '%s'", filename.c_str()); delete model->second.getModel(); iLoadedModelFiles.erase(model); } diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index 5f4e2b6aa8b..e3cd158709c 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -27,12 +27,6 @@ #include #include -#ifndef NO_CORE_FUNCS - #include "Errors.h" -#else - #define ASSERT(x) -#endif - using G3D::Vector3; namespace VMAP @@ -277,7 +271,7 @@ namespace VMAP bool StaticMapTree::InitMap(const std::string &fname, VMapManager2* vm) { - sLog->outDebug(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : initializing StaticMapTree '%s'", fname.c_str()); + VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : initializing StaticMapTree '%s'", fname.c_str()); bool success = true; std::string fullname = iBasePath + fname; FILE* rf = fopen(fullname.c_str(), "rb"); @@ -310,7 +304,7 @@ namespace VMAP if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn)) { WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name); - sLog->outDebug(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : loading %s", spawn.name.c_str()); + VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : loading %s", spawn.name.c_str()); if (model) { // assume that global model always is the first and only tree value (could be improved...) @@ -320,7 +314,7 @@ namespace VMAP else { success = false; - sLog->outError(LOG_FILTER_GENERAL, "StaticMapTree::InitMap() : could not acquire WorldModel pointer for '%s'", spawn.name.c_str()); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::InitMap() : could not acquire WorldModel pointer for '%s'", spawn.name.c_str()); } } @@ -356,7 +350,7 @@ namespace VMAP } if (!iTreeValues) { - sLog->outError(LOG_FILTER_GENERAL, "StaticMapTree::LoadMapTile() : tree has not been initialized [%u, %u]", tileX, tileY); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::LoadMapTile() : tree has not been initialized [%u, %u]", tileX, tileY); return false; } bool result = true; @@ -382,7 +376,7 @@ namespace VMAP // acquire model instance WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name); if (!model) - sLog->outError(LOG_FILTER_GENERAL, "StaticMapTree::LoadMapTile() : could not acquire WorldModel pointer [%u, %u]", tileX, tileY); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::LoadMapTile() : could not acquire WorldModel pointer [%u, %u]", tileX, tileY); // update tree uint32 referencedVal; @@ -432,7 +426,7 @@ namespace VMAP loadedTileMap::iterator tile = iLoadedTiles.find(tileID); if (tile == iLoadedTiles.end()) { - sLog->outError(LOG_FILTER_GENERAL, "StaticMapTree::UnloadMapTile() : trying to unload non-loaded tile - Map:%u X:%u Y:%u", iMapID, tileX, tileY); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::UnloadMapTile() : trying to unload non-loaded tile - Map:%u X:%u Y:%u", iMapID, tileX, tileY); return; } if (tile->second) // file associated with tile @@ -466,7 +460,7 @@ namespace VMAP else { if (!iLoadedSpawns.count(referencedNode)) - sLog->outError(LOG_FILTER_GENERAL, "StaticMapTree::UnloadMapTile() : trying to unload non-referenced model '%s' (ID:%u)", spawn.name.c_str(), spawn.ID); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::UnloadMapTile() : trying to unload non-referenced model '%s' (ID:%u)", spawn.name.c_str(), spawn.ID); else if (--iLoadedSpawns[referencedNode] == 0) { iTreeValues[referencedNode].setUnloaded(); @@ -480,5 +474,4 @@ namespace VMAP } iLoadedTiles.erase(tile); } - } diff --git a/src/server/collision/Models/GameObjectModel.cpp b/src/server/collision/Models/GameObjectModel.cpp index 0ecf02648f9..54283389387 100644 --- a/src/server/collision/Models/GameObjectModel.cpp +++ b/src/server/collision/Models/GameObjectModel.cpp @@ -34,8 +34,6 @@ using G3D::Vector3; using G3D::Ray; using G3D::AABox; -#ifndef NO_CORE_FUNCS - struct GameobjectModelData { GameobjectModelData(const std::string& name_, const AABox& box) : @@ -54,7 +52,7 @@ void LoadGameObjectModelList() FILE* model_list_file = fopen((sWorld->GetDataPath() + "vmaps/" + VMAP::GAMEOBJECT_MODELS).c_str(), "rb"); if (!model_list_file) { - sLog->outError(LOG_FILTER_GENERAL, "Unable to open '%s' file.", VMAP::GAMEOBJECT_MODELS); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "Unable to open '%s' file.", VMAP::GAMEOBJECT_MODELS); return; } @@ -73,7 +71,7 @@ void LoadGameObjectModelList() || fread(&v1, sizeof(Vector3), 1, model_list_file) != 1 || fread(&v2, sizeof(Vector3), 1, model_list_file) != 1) { - sLog->outError(LOG_FILTER_GENERAL, "File '%s' seems to be corrupted!", VMAP::GAMEOBJECT_MODELS); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "File '%s' seems to be corrupted!", VMAP::GAMEOBJECT_MODELS); break; } @@ -84,8 +82,7 @@ void LoadGameObjectModelList() } fclose(model_list_file); - sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u GameObject models in %u ms", uint32(model_list.size()), GetMSTimeDiffToNow(oldMSTime)); - + VMAP_INFO_LOG(LOG_FILTER_SERVER_LOADING, ">> Loaded %u GameObject models in %u ms", uint32(model_list.size()), GetMSTimeDiffToNow(oldMSTime)); } GameObjectModel::~GameObjectModel() @@ -104,7 +101,7 @@ bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayIn // ignore models with no bounds if (mdl_box == G3D::AABox::zero()) { - sLog->outError(LOG_FILTER_GENERAL, "GameObject model %s has zero bounds, loading skipped", it->second.name.c_str()); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "GameObject model %s has zero bounds, loading skipped", it->second.name.c_str()); return false; } @@ -184,5 +181,3 @@ bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool Sto } return hit; } - -#endif diff --git a/src/server/collision/VMapDefinitions.h b/src/server/collision/VMapDefinitions.h index 609d00cd00f..56084389ad6 100644 --- a/src/server/collision/VMapDefinitions.h +++ b/src/server/collision/VMapDefinitions.h @@ -31,4 +31,16 @@ namespace VMAP // defined in TileAssembler.cpp currently... bool readChunk(FILE* rf, char *dest, const char *compare, uint32 len); } + +// Set of helper macros for extractors (VMAP and MMAP) +#ifndef NO_CORE_FUNCS +#define VMAP_ERROR_LOG(FILTER, ...) sLog->outError(FILTER, __VA_ARGS__) +#define VMAP_DEBUG_LOG(FILTER, ...) sLog->outDebug(FILTER, __VA_ARGS__) +#define VMAP_INFO_LOG(FILTER, ...) sLog->outInfo(FILTER, __VA_ARGS__) +#else +#define VMAP_ERROR_LOG(FILTER, ...) printf(__VA_ARGS__) +#define VMAP_DEBUG_LOG(FILTER, ...) printf(__VA_ARGS__) +#define VMAP_INFO_LOG(FILTER, ...) printf(__VA_ARGS__) +#endif + #endif diff --git a/src/server/shared/Debugging/Errors.h b/src/server/shared/Debugging/Errors.h index 3d10740f149..10e94634e9a 100644 --- a/src/server/shared/Debugging/Errors.h +++ b/src/server/shared/Debugging/Errors.h @@ -24,7 +24,7 @@ #include #include -#define WPAssert(assertion) { if (!(assertion)) { ACE_Stack_Trace st; sLog->outError(LOG_FILTER_GENERAL, "\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n", __FILE__, __LINE__, __FUNCTION__, #assertion, st.c_str()); *((volatile int*)NULL) = 0; } } +#define WPAssert(assertion) { if (!(assertion)) { ACE_Stack_Trace st; fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n", __FILE__, __LINE__, __FUNCTION__, #assertion, st.c_str()); *((volatile int*)NULL) = 0; } } #define WPError(assertion, errmsg) { if (!(assertion)) { sLog->outError(LOG_FILTER_GENERAL, "%\n%s:%i in %s ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg); *((volatile int*)NULL) = 0; } } #define WPWarning(assertion, errmsg) { if (!(assertion)) { sLog->outError(LOG_FILTER_GENERAL, "\n%s:%i in %s WARNING:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg); } } #define WPFatal(assertion, errmsg) { if (!(assertion)) { sLog->outError(LOG_FILTER_GENERAL, "\n%s:%i in %s FATAL ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg); ACE_OS::sleep(10); *((volatile int*)NULL) = 0; } } diff --git a/src/tools/map_extractor/CMakeLists.txt b/src/tools/map_extractor/CMakeLists.txt index 9fb8d5713d7..ea073456680 100644 --- a/src/tools/map_extractor/CMakeLists.txt +++ b/src/tools/map_extractor/CMakeLists.txt @@ -11,23 +11,22 @@ file(GLOB_RECURSE sources *.cpp *.h) -if( UNIX ) - include_directories ( +set(include_Dirs ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/dep/libmpq ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/loadlib - ) -elseif( WIN32 ) - include_directories ( - ${CMAKE_SOURCE_DIR}/src/server/shared - ${CMAKE_SOURCE_DIR}/dep/libmpq +) + +if( WIN32 ) + set(include_Dirs + ${include_Dirs} ${CMAKE_SOURCE_DIR}/dep/libmpq/win - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/loadlib ) endif() +include_directories(${include_Dirs}) + add_executable(mapextractor ${sources} ) @@ -38,8 +37,6 @@ target_link_libraries(mapextractor ${ZLIB_LIBRARIES} ) -add_dependencies(mapextractor mpq) - if( UNIX ) install(TARGETS mapextractor DESTINATION bin) elseif( WIN32 ) diff --git a/src/tools/map_extractor/mpq_libmpq.cpp b/src/tools/map_extractor/mpq_libmpq.cpp index 81aa8cc2894..1c1a12e7b85 100644 --- a/src/tools/map_extractor/mpq_libmpq.cpp +++ b/src/tools/map_extractor/mpq_libmpq.cpp @@ -79,7 +79,7 @@ size_t MPQFile::read(void* dest, size_t bytes) if (eof) return 0; size_t rpos = pointer + bytes; - if (rpos > size) { + if (rpos > size_t(size)) { bytes = size - pointer; eof = true; } diff --git a/src/tools/map_extractor/mpq_libmpq04.h b/src/tools/map_extractor/mpq_libmpq04.h index 89f715e9e87..9f0163067c4 100644 --- a/src/tools/map_extractor/mpq_libmpq04.h +++ b/src/tools/map_extractor/mpq_libmpq04.h @@ -1,6 +1,3 @@ -#define _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_WARNINGS - #ifndef MPQ_H #define MPQ_H diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt index 1b5d1564b71..9ed8472051d 100644 --- a/src/tools/mesh_extractor/CMakeLists.txt +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -9,9 +9,7 @@ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -file(GLOB_RECURSE sources *.cpp *.h) - -add_definitions(-DNO_CORE_FUNCS) +file(GLOB_RECURSE meshExtract_Sources *.cpp *.h) set(include_Base ${CMAKE_BINARY_DIR} @@ -33,9 +31,7 @@ endif() include_directories(${include_Base}) -add_executable(MeshExtractor - ${sources} -) +add_executable(MeshExtractor ${meshExtract_Sources}) target_link_libraries(MeshExtractor g3dlib diff --git a/src/tools/mesh_extractor/MPQ.cpp b/src/tools/mesh_extractor/MPQ.cpp index b7be181594d..18a9eb0f0e3 100644 --- a/src/tools/mesh_extractor/MPQ.cpp +++ b/src/tools/mesh_extractor/MPQ.cpp @@ -77,7 +77,7 @@ size_t MPQFile::Read(void* dest, size_t bytes) return 0; size_t rpos = pointer + bytes; - if (rpos > size) { + if (rpos > size_t(size)) { bytes = size - pointer; eof = true; } diff --git a/src/tools/mmaps_generator/CMakeLists.txt b/src/tools/mmaps_generator/CMakeLists.txt index 229a2cd808f..99492abf8ee 100644 --- a/src/tools/mmaps_generator/CMakeLists.txt +++ b/src/tools/mmaps_generator/CMakeLists.txt @@ -8,17 +8,11 @@ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -file(GLOB_RECURSE sources *.cpp *.h) +file(GLOB_RECURSE mmap_gen_sources *.cpp *.h) -# definitions -add_definitions(-DNO_CORE_FUNCS) -add_definitions(-DDEBUG) -add_definitions(-DNO_vsnprintf) - -include_directories( +set(mmap_gen_Includes ${CMAKE_BINARY_DIR} ${ACE_INCLUDE_DIR} - ${MYSQL_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/dep/libmpq ${CMAKE_SOURCE_DIR}/dep/zlib ${CMAKE_SOURCE_DIR}/dep/bzip2 @@ -26,20 +20,6 @@ include_directories( ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour ${CMAKE_SOURCE_DIR}/src/server/shared - ${CMAKE_SOURCE_DIR}/src/server/shared/Database - ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation - ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging - ${CMAKE_SOURCE_DIR}/src/server/shared/Threading - ${CMAKE_SOURCE_DIR}/src/server/shared/Logging - ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference - ${CMAKE_SOURCE_DIR}/src/server/game/Maps - ${CMAKE_SOURCE_DIR}/src/server/game/DataStores - ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints - ${CMAKE_SOURCE_DIR}/src/server/game/Grids - ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Cells - ${CMAKE_SOURCE_DIR}/src/server/game/Miscellaneous ${CMAKE_SOURCE_DIR}/src/server/game/Conditions ${CMAKE_SOURCE_DIR}/src/server/collision ${CMAKE_SOURCE_DIR}/src/server/collision/Management @@ -47,18 +27,25 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/collision/Models ) -add_executable(mmaps_generator ${sources}) +if( WIN32 ) + set(mmap_gen_Includes + ${mmap_gen_Includes} + ${CMAKE_SOURCE_DIR}/dep/libmpq/win + ) +endif() + +include_directories(${mmap_gen_Includes}) + +add_executable(mmaps_generator ${mmap_gen_sources}) target_link_libraries(mmaps_generator - ${MYSQL_LIBRARY} + collision + g3dlib + Recast + Detour ${ACE_LIBRARY} ${BZIP2_LIBRARIES} ${ZLIB_LIBRARIES} - Recast - Detour - collision - g3dlib - shared ) if( UNIX ) diff --git a/src/tools/mmaps_generator/IntermediateValues.cpp b/src/tools/mmaps_generator/IntermediateValues.cpp index 6fad96887a2..a490273ad80 100644 --- a/src/tools/mmaps_generator/IntermediateValues.cpp +++ b/src/tools/mmaps_generator/IntermediateValues.cpp @@ -37,7 +37,7 @@ namespace MMAP printf("%sWriting debug output... \r", tileString); - string name("meshes/%03u%02i%02i."); + std::string name("meshes/%03u%02i%02i."); #define DEBUG_WRITE(fileExtension,data) \ do { \ diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 9e6acd71a72..a62011ddfff 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -21,29 +21,34 @@ #include "MapTree.h" #include "ModelInstance.h" -#include "LoginDatabase.h" #include "DetourNavMeshBuilder.h" #include "DetourNavMesh.h" #include "DetourCommon.h" -// These make the linker happy. -LoginDatabaseWorkerPool LoginDatabase; -uint32 GetLiquidFlags(uint32 /*liquidType*/) -{ - return 0; -} - #include "DisableMgr.h" +#include + +uint32 GetLiquidFlags(uint32 /*liquidType*/) { return 0; } namespace DisableMgr { - bool IsDisabledFor(DisableType /*type*/, uint32 /*entry*/, Unit const* /*unit*/, uint8 /*flags*/) - { - return 0; - } + bool IsDisabledFor(DisableType /*type*/, uint32 /*entry*/, Unit const* /*unit*/, uint8 /*flags*/ /*= 0*/) { return false; } } -using namespace VMAP; +#define MMAP_MAGIC 0x4d4d4150 // 'MMAP' +#define MMAP_VERSION 3 + +struct MmapTileHeader +{ + uint32 mmapMagic; + uint32 dtVersion; + uint32 mmapVersion; + uint32 size; + bool usesLiquids : 1; + + MmapTileHeader() : mmapMagic(MMAP_MAGIC), dtVersion(DT_NAVMESH_VERSION), + mmapVersion(MMAP_VERSION), size(0), usesLiquids(true) {} +}; namespace MMAP { @@ -83,7 +88,7 @@ namespace MMAP /**************************************************************************/ void MapBuilder::discoverTiles() { - vector files; + std::vector files; uint32 mapID, tileX, tileY, tileID, count = 0; char filter[12]; @@ -94,7 +99,7 @@ namespace MMAP mapID = uint32(atoi(files[i].substr(0,3).c_str())); if (m_tiles.find(mapID) == m_tiles.end()) { - m_tiles.insert(pair*>(mapID, new set)); + m_tiles.insert(std::pair*>(mapID, new std::set)); count++; } } @@ -104,7 +109,7 @@ namespace MMAP for (uint32 i = 0; i < files.size(); ++i) { mapID = uint32(atoi(files[i].substr(0,3).c_str())); - m_tiles.insert(pair*>(mapID, new set)); + m_tiles.insert(std::pair*>(mapID, new std::set)); count++; } printf("found %u.\n", count); @@ -113,7 +118,7 @@ namespace MMAP printf("Discovering tiles... "); for (TileList::iterator itr = m_tiles.begin(); itr != m_tiles.end(); ++itr) { - set* tiles = (*itr).second; + std::set* tiles = (*itr).second; mapID = (*itr).first; sprintf(filter, "%03u*.vmtile", mapID); @@ -146,14 +151,14 @@ namespace MMAP } /**************************************************************************/ - set* MapBuilder::getTileList(uint32 mapID) + std::set* MapBuilder::getTileList(uint32 mapID) { TileList::iterator itr = m_tiles.find(mapID); if (itr != m_tiles.end()) return (*itr).second; - set* tiles = new set(); - m_tiles.insert(pair*>(mapID, tiles)); + std::set* tiles = new std::set(); + m_tiles.insert(std::pair*>(mapID, tiles)); return tiles; } @@ -318,7 +323,7 @@ namespace MMAP { printf("[Thread %u] Building map %03u:\n", uint32(ACE_Thread::self()), mapID); - set* tiles = getTileList(mapID); + std::set* tiles = getTileList(mapID); // make sure we process maps which don't have tiles if (!tiles->size()) @@ -346,7 +351,7 @@ namespace MMAP // now start building mmtiles for each tile printf("[Map %i] We have %u tiles. \n", mapID, (unsigned int)tiles->size()); - for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) + for (std::set::iterator it = tiles->begin(); it != tiles->end(); ++it) { uint32 tileX, tileY; @@ -407,7 +412,7 @@ namespace MMAP /**************************************************************************/ void MapBuilder::buildNavMesh(uint32 mapID, dtNavMesh* &navMesh) { - set* tiles = getTileList(mapID); + std::set* tiles = getTileList(mapID); // old code for non-statically assigned bitmask sizes: ///*** calculate number of bits needed to store tiles & polys ***/ @@ -423,9 +428,9 @@ namespace MMAP /*** calculate bounds of map ***/ uint32 tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0, tileX, tileY; - for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) + for (std::set::iterator it = tiles->begin(); it != tiles->end(); ++it) { - StaticMapTree::unpackTileID((*it), tileX, tileY); + StaticMapTree::unpackTileID(*it, tileX, tileY); if (tileX > tileXMax) tileXMax = tileX; diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index c083e0b680a..ea9636b3cc3 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -26,22 +26,18 @@ #include "TerrainBuilder.h" #include "IntermediateValues.h" -#include "IVMapManager.h" -#include "WorldModel.h" - #include "Recast.h" #include "DetourNavMesh.h" -#include "ace/Task.h" +#include -using namespace std; using namespace VMAP; // G3D namespace typedefs conflicts with ACE typedefs namespace MMAP { - typedef map*> TileList; + typedef std::map*> TileList; struct Tile { Tile() : chf(NULL), solid(NULL), cset(NULL), pmesh(NULL), dmesh(NULL) {} @@ -87,7 +83,7 @@ namespace MMAP private: // detect maps and tiles void discoverTiles(); - set* getTileList(uint32 mapID); + std::set* getTileList(uint32 mapID); void buildNavMesh(uint32 mapID, dtNavMesh* &navMesh); diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index 413f2b8735d..3e06ff58410 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -21,6 +21,7 @@ #include #include +#include #include "Define.h" @@ -33,7 +34,19 @@ #include #endif -using namespace std; +enum NavTerrain +{ + NAV_EMPTY = 0x00, + NAV_GROUND = 0x01, + NAV_MAGMA = 0x02, + NAV_SLIME = 0x04, + NAV_WATER = 0x08, + NAV_UNUSED1 = 0x10, + NAV_UNUSED2 = 0x20, + NAV_UNUSED3 = 0x40, + NAV_UNUSED4 = 0x80 + // we only have 8 bits +}; namespace MMAP { @@ -75,12 +88,12 @@ namespace MMAP LISTFILE_OK = 1 }; - inline ListFilesResult getDirContents(vector &fileList, string dirpath = ".", string filter = "*") + inline ListFilesResult getDirContents(std::vector &fileList, std::string dirpath = ".", std::string filter = "*") { #ifdef WIN32 HANDLE hFind; WIN32_FIND_DATA findFileInfo; - string directory; + std::string directory; directory = dirpath + "/" + filter; @@ -91,7 +104,7 @@ namespace MMAP do { if ((findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) - fileList.push_back(string(findFileInfo.cFileName)); + fileList.push_back(std::string(findFileInfo.cFileName)); } while (FindNextFile(hFind, &findFileInfo)); @@ -109,7 +122,7 @@ namespace MMAP if ((dp = readdir(dirp)) != NULL) { if (matchWildcardFilter(filter.c_str(), dp->d_name)) - fileList.push_back(string(dp->d_name)); + fileList.push_back(std::string(dp->d_name)); } else break; @@ -123,6 +136,26 @@ namespace MMAP return LISTFILE_OK; } + + inline uint32 getMSTime() + { + static const ACE_Time_Value ApplicationStartTime = ACE_OS::gettimeofday(); + return (ACE_OS::gettimeofday() - ApplicationStartTime).msec(); + } + + inline uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime) + { + // getMSTime() have limited data range and this is case when it overflow in this tick + if (oldMSTime > newMSTime) + return (0xFFFFFFFF - oldMSTime) + newMSTime; + else + return newMSTime - oldMSTime; + } + + inline uint32 GetMSTimeDiffToNow(uint32 oldMSTime) + { + return getMSTimeDiff(oldMSTime, getMSTime()); + } } #endif diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 9707cb4160a..01059099f98 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -18,13 +18,12 @@ #include "PathCommon.h" #include "MapBuilder.h" -#include "Timer.h" using namespace MMAP; bool checkDirectories(bool debugOutput) { - vector dirFiles; + std::vector dirFiles; if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty()) { diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index f7cf76e9718..c3d6541dfa3 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -24,6 +24,60 @@ #include "VMapManager2.h" #include "MapTree.h" #include "ModelInstance.h" +#include + +// ****************************************** +// Map file format defines +// ****************************************** +struct map_fileheader +{ + uint32 mapMagic; + uint32 versionMagic; + uint32 buildMagic; + uint32 areaMapOffset; + uint32 areaMapSize; + uint32 heightMapOffset; + uint32 heightMapSize; + uint32 liquidMapOffset; + uint32 liquidMapSize; + uint32 holesOffset; + uint32 holesSize; +}; + +#define MAP_HEIGHT_NO_HEIGHT 0x0001 +#define MAP_HEIGHT_AS_INT16 0x0002 +#define MAP_HEIGHT_AS_INT8 0x0004 + +struct map_heightHeader +{ + uint32 fourcc; + uint32 flags; + float gridHeight; + float gridMaxHeight; +}; + +#define MAP_LIQUID_NO_TYPE 0x0001 +#define MAP_LIQUID_NO_HEIGHT 0x0002 + +struct map_liquidHeader +{ + uint32 fourcc; + uint16 flags; + uint16 liquidType; + uint8 offsetX; + uint8 offsetY; + uint8 width; + uint8 height; + float liquidLevel; +}; + +#define MAP_LIQUID_TYPE_NO_WATER 0x00 +#define MAP_LIQUID_TYPE_WATER 0x01 +#define MAP_LIQUID_TYPE_OCEAN 0x02 +#define MAP_LIQUID_TYPE_MAGMA 0x04 +#define MAP_LIQUID_TYPE_SLIME 0x08 +#define MAP_LIQUID_TYPE_DARK_WATER 0x10 +#define MAP_LIQUID_TYPE_WMO_WATER 0x20 namespace MMAP { @@ -139,7 +193,7 @@ namespace MMAP count += fread(v8, sizeof(uint8), V8_SIZE_SQ, mapFile); if (count != expected) printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count); - + heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 255; for (int i = 0; i < V9_SIZE_SQ; ++i) @@ -612,11 +666,11 @@ namespace MMAP // now we have a model to add to the meshdata retval = true; - vector groupModels; + std::vector groupModels; worldModel->getGroupModels(groupModels); // all M2s need to have triangle indices reversed - bool isM2 = instance.name.find(".m2") != instance.name.npos || instance.name.find(".M2") != instance.name.npos; + bool isM2 = instance.name.find(".m2") != std::string::npos || instance.name.find(".M2") != std::string::npos; // transform data float scale = instance.iScale; @@ -625,14 +679,14 @@ namespace MMAP position.x -= 32*GRID_SIZE; position.y -= 32*GRID_SIZE; - for (vector::iterator it = groupModels.begin(); it != groupModels.end(); ++it) + for (std::vector::iterator it = groupModels.begin(); it != groupModels.end(); ++it) { - vector tempVertices; - vector transformedVertices; - vector tempTriangles; + std::vector tempVertices; + std::vector transformedVertices; + std::vector tempTriangles; WmoLiquid* liquid = NULL; - (*it).getMeshData(tempVertices, tempTriangles, liquid); + it->getMeshData(tempVertices, tempTriangles, liquid); // first handle collision mesh transform(tempVertices, transformedVertices, scale, rotation, position); @@ -645,8 +699,8 @@ namespace MMAP // now handle liquid data if (liquid) { - vector liqVerts; - vector liqTris; + std::vector liqVerts; + std::vector liqTris; uint32 tilesX, tilesY, vertsX, vertsY; Vector3 corner; liquid->getPosInfo(tilesX, tilesY, corner); @@ -732,9 +786,9 @@ namespace MMAP } /**************************************************************************/ - void TerrainBuilder::transform(vector &source, vector &transformedVertices, float scale, G3D::Matrix3 &rotation, Vector3 &position) + void TerrainBuilder::transform(std::vector &source, std::vector &transformedVertices, float scale, G3D::Matrix3 &rotation, Vector3 &position) { - for (vector::iterator it = source.begin(); it != source.end(); ++it) + for (std::vector::iterator it = source.begin(); it != source.end(); ++it) { // apply tranform, then mirror along the horizontal axes Vector3 v((*it) * rotation * scale + position); @@ -745,9 +799,9 @@ namespace MMAP } /**************************************************************************/ - void TerrainBuilder::copyVertices(vector &source, G3D::Array &dest) + void TerrainBuilder::copyVertices(std::vector &source, G3D::Array &dest) { - for (vector::iterator it = source.begin(); it != source.end(); ++it) + for (std::vector::iterator it = source.begin(); it != source.end(); ++it) { dest.push_back((*it).y); dest.push_back((*it).z); @@ -756,11 +810,11 @@ namespace MMAP } /**************************************************************************/ - void TerrainBuilder::copyIndices(vector &source, G3D::Array &dest, int offset, bool flip) + void TerrainBuilder::copyIndices(std::vector &source, G3D::Array &dest, int offset, bool flip) { if (flip) { - for (vector::iterator it = source.begin(); it != source.end(); ++it) + for (std::vector::iterator it = source.begin(); it != source.end(); ++it) { dest.push_back((*it).idx2+offset); dest.push_back((*it).idx1+offset); @@ -769,7 +823,7 @@ namespace MMAP } else { - for (vector::iterator it = source.begin(); it != source.end(); ++it) + for (std::vector::iterator it = source.begin(); it != source.end(); ++it) { dest.push_back((*it).idx0+offset); dest.push_back((*it).idx1+offset); @@ -789,7 +843,7 @@ namespace MMAP /**************************************************************************/ void TerrainBuilder::cleanVertices(G3D::Array &verts, G3D::Array &tris) { - map vertMap; + std::map vertMap; int* t = tris.getCArray(); float* v = verts.getCArray(); @@ -819,7 +873,7 @@ namespace MMAP // update triangles to use new indices for (int i = 0; i < tris.size(); ++i) { - map::iterator it; + std::map::iterator it; if ((it = vertMap.find(t[i])) == vertMap.end()) continue; diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h index 6ad4284f416..069a5a94c84 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.h +++ b/src/tools/mmaps_generator/TerrainBuilder.h @@ -20,17 +20,12 @@ #define _MMAP_TERRAIN_BUILDER_H #include "PathCommon.h" -#include "Map.h" -#include "SharedDefines.h" - #include "WorldModel.h" #include "G3D/Array.h" #include "G3D/Vector3.h" #include "G3D/Matrix3.h" -using namespace Trinity; - namespace MMAP { enum Spot @@ -93,10 +88,10 @@ namespace MMAP bool usesLiquids() { return !m_skipLiquid; } // vert and triangle methods - static void transform(vector &original, vector &transformed, + static void transform(std::vector &original, std::vector &transformed, float scale, G3D::Matrix3 &rotation, G3D::Vector3 &position); - static void copyVertices(vector &source, G3D::Array &dest); - static void copyIndices(vector &source, G3D::Array &dest, int offest, bool flip); + static void copyVertices(std::vector &source, G3D::Array &dest); + static void copyIndices(std::vector &source, G3D::Array &dest, int offest, bool flip); static void copyIndices(G3D::Array &src, G3D::Array &dest, int offset); static void cleanVertices(G3D::Array &verts, G3D::Array &tris); private: diff --git a/src/tools/mmaps_generator/VMapExtensions.cpp b/src/tools/mmaps_generator/VMapExtensions.cpp index 37b7d94af55..972f222bba6 100644 --- a/src/tools/mmaps_generator/VMapExtensions.cpp +++ b/src/tools/mmaps_generator/VMapExtensions.cpp @@ -22,8 +22,6 @@ #include "WorldModel.h" #include "ModelInstance.h" -using namespace std; - namespace VMAP { // Need direct access to encapsulated VMAP data, so we add functions for MMAP generator @@ -43,13 +41,13 @@ namespace VMAP } // declared in src/shared/vmap/WorldModel.h - void WorldModel::getGroupModels(vector &groupModels) + void WorldModel::getGroupModels(std::vector &groupModels) { groupModels = this->groupModels; } // declared in src/shared/vmap/WorldModel.h - void GroupModel::getMeshData(vector &vertices, vector &triangles, WmoLiquid* &liquid) + void GroupModel::getMeshData(std::vector &vertices, std::vector &triangles, WmoLiquid* &liquid) { vertices = this->vertices; triangles = this->triangles; diff --git a/src/tools/vmap4_assembler/CMakeLists.txt b/src/tools/vmap4_assembler/CMakeLists.txt index 55b6514d091..8d455eae6ee 100644 --- a/src/tools/vmap4_assembler/CMakeLists.txt +++ b/src/tools/vmap4_assembler/CMakeLists.txt @@ -20,9 +20,7 @@ include_directories( ${ZLIB_INCLUDE_DIR} ) -add_definitions(-DNO_CORE_FUNCS) add_executable(vmap4assembler VMapAssembler.cpp) -add_dependencies(vmap4assembler mpq) if(CMAKE_SYSTEM_NAME MATCHES "Darwin") set_target_properties(vmap4assembler PROPERTIES LINK_FLAGS "-framework Carbon") diff --git a/src/tools/vmap4_extractor/CMakeLists.txt b/src/tools/vmap4_extractor/CMakeLists.txt index 19798e46475..023f5447f85 100644 --- a/src/tools/vmap4_extractor/CMakeLists.txt +++ b/src/tools/vmap4_extractor/CMakeLists.txt @@ -11,26 +11,19 @@ file(GLOB_RECURSE sources *.cpp *.h) -# uncomment next line to disable debug mode -add_definitions("-DIOMAP_DEBUG") - -# build setup currently only supports libmpq 0.4.x -add_definitions("-DUSE_LIBMPQ04") -add_definitions("-Wall") -add_definitions("-ggdb") -add_definitions("-O3") - -if( UNIX ) - include_directories( - ${CMAKE_SOURCE_DIR}/dep/libmpq - ) -elseif( WIN32 ) - include_directories( +set(include_Dirs ${CMAKE_SOURCE_DIR}/dep/libmpq +) + +if( WIN32 ) + set(include_Dirs + ${include_Dirs} ${CMAKE_SOURCE_DIR}/dep/libmpq/win ) endif() +include_directories(${include_Dirs}) + add_executable(vmap4extractor ${sources}) target_link_libraries(vmap4extractor @@ -39,8 +32,6 @@ target_link_libraries(vmap4extractor ${ZLIB_LIBRARIES} ) -add_dependencies(vmap4extractor mpq) - if( UNIX ) install(TARGETS vmap4extractor DESTINATION bin) elseif( WIN32 ) diff --git a/src/tools/vmap4_extractor/mpq_libmpq.cpp b/src/tools/vmap4_extractor/mpq_libmpq.cpp index 528b9679a58..ffa097d9a22 100644 --- a/src/tools/vmap4_extractor/mpq_libmpq.cpp +++ b/src/tools/vmap4_extractor/mpq_libmpq.cpp @@ -79,7 +79,7 @@ size_t MPQFile::read(void* dest, size_t bytes) if (eof) return 0; size_t rpos = pointer + bytes; - if (rpos > size) { + if (rpos > size_t(size)) { bytes = size - pointer; eof = true; } diff --git a/src/tools/vmap4_extractor/mpq_libmpq04.h b/src/tools/vmap4_extractor/mpq_libmpq04.h index 89f715e9e87..9f0163067c4 100644 --- a/src/tools/vmap4_extractor/mpq_libmpq04.h +++ b/src/tools/vmap4_extractor/mpq_libmpq04.h @@ -1,6 +1,3 @@ -#define _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_WARNINGS - #ifndef MPQ_H #define MPQ_H diff --git a/src/tools/vmap4_extractor/wdtfile.cpp b/src/tools/vmap4_extractor/wdtfile.cpp index 7420edfee2e..d9216fd77eb 100644 --- a/src/tools/vmap4_extractor/wdtfile.cpp +++ b/src/tools/vmap4_extractor/wdtfile.cpp @@ -35,7 +35,7 @@ WDTFile::WDTFile(char* file_name, char* file_name1) : WDT(file_name), gWmoInstan filename.append(file_name1,strlen(file_name1)); } -bool WDTFile::init(char */*map_id*/, unsigned int mapID) +bool WDTFile::init(char* /*map_id*/, unsigned int mapID) { if (WDT.isEof()) { -- cgit v1.2.3 From 5b9159e165ea4bca3ab32317b180d9d543f99dbf Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 22 Jan 2013 19:07:40 +0100 Subject: Tools: Build fix --- src/tools/mesh_extractor/MPQManager.cpp | 2 +- src/tools/mesh_extractor/Utils.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 0fe07cd8b85..5ae8558d749 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -14,7 +14,7 @@ char* MPQManager::Files[] = { "patch-3.MPQ" }; -char* MPQManager::Languages[] = { "enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }; +char const* MPQManager::Languages[] = { "enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }; void MPQManager::Initialize() { diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 41ea33e6157..64fb1bb35ba 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -15,7 +15,7 @@ struct WorldModelDefinition; class DoodadInstance; -#define ASSERT(assertion) { if (!(assertion)) { ACE_Stack_Trace st; fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n", __FILE__, __LINE__, __FUNCTION__, #assertion, st.c_str()); *((volatile int*)NULL) = 0; } } +#define ASSERT(assertion) { if (!(assertion)) { ACE_Stack_Trace st; fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n", __FILE__, __LINE__, __FUNCTION__, #assertion, st.c_str()); *((volatile int*)NULL) = 0; } } struct Vector3 { -- cgit v1.2.3 From 7a74f68c0d974de5a1f885904fefa45db934da3d Mon Sep 17 00:00:00 2001 From: Nay Date: Tue, 22 Jan 2013 18:14:32 +0000 Subject: Tools/MapExtractor: Fix displaying of a few counts in Windows %zu works fine on GCC/Linux, but fails in MSVC/Windows --- src/tools/map_extractor/System.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/tools') diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index 2e117934679..bf88a92c32a 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -222,7 +222,7 @@ uint32 ReadMapDBC() map_ids[x].id = dbc.getRecord(x).getUInt(0); strcpy(map_ids[x].name, dbc.getRecord(x).getString(1)); } - printf("Done! (%zu maps loaded)\n", map_count); + printf("Done! (%u maps loaded)\n", (uint32)map_count); return map_count; } @@ -247,7 +247,7 @@ void ReadAreaTableDBC() maxAreaId = dbc.getMaxId(); - printf("Done! (%zu areas loaded)\n", area_count); + printf("Done! (%u areas loaded)\n", (uint32)area_count); } void ReadLiquidTypeTableDBC() @@ -268,7 +268,7 @@ void ReadLiquidTypeTableDBC() for(uint32 x = 0; x < liqTypeCount; ++x) LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3); - printf("Done! (%zu LiqTypes loaded)\n", liqTypeCount); + printf("Done! (%u LiqTypes loaded)\n", (uint32)liqTypeCount); } // -- cgit v1.2.3 From bd893b4516292de4d2b1244acbecb0f301977e3f Mon Sep 17 00:00:00 2001 From: Nay Date: Tue, 22 Jan 2013 18:41:26 +0000 Subject: Tools/MeshExtractor: Fix warnings --- src/tools/mesh_extractor/MPQManager.cpp | 2 +- src/tools/mesh_extractor/MPQManager.h | 4 ++-- src/tools/mesh_extractor/WorldModelGroup.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 5ae8558d749..91b9c121c89 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -4,7 +4,7 @@ #include "Utils.h" #include -char* MPQManager::Files[] = { +char const* MPQManager::Files[] = { "common.MPQ", "common-2.MPQ", "expansion.MPQ", diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h index 788be7f5974..2f49ad258a5 100644 --- a/src/tools/mesh_extractor/MPQManager.h +++ b/src/tools/mesh_extractor/MPQManager.h @@ -24,8 +24,8 @@ public: std::set AvailableLocales; std::map LocaleFiles; - static char* Files[]; - static char* Languages[]; + static char const* Files[]; + static char const* Languages[]; protected: void InitializeDBC(); private: diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index 5eeef824b1a..21e1c1e63e1 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -137,7 +137,7 @@ void WorldModelGroup::ReadBatches() MOBALength = chunk->Length / 2; MOBA = new uint16[MOBALength]; - int count = fread(MOBA, sizeof(uint16), MOBALength, chunk->GetStream()); + uint32 count = (uint32)fread(MOBA, sizeof(uint16), MOBALength, chunk->GetStream()); if (count != MOBALength) - printf("WorldModelGroup::ReadBatches: Error reading data, expected %d, read %d\n", MOBALength, count); + printf("WorldModelGroup::ReadBatches: Error reading data, expected %u, read %u\n", MOBALength, count); } -- cgit v1.2.3 From 7a76de93f83984a05bc38e321ca2f710cfd221d4 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Tue, 22 Jan 2013 20:24:00 +0100 Subject: Update more copyright note for 2013. --- dep/recastnavigation/Detour/CMakeLists.txt | 2 +- dep/recastnavigation/Recast/CMakeLists.txt | 2 +- src/tools/mmaps_generator/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/tools') diff --git a/dep/recastnavigation/Detour/CMakeLists.txt b/dep/recastnavigation/Detour/CMakeLists.txt index c09e0e35d42..303a003dee2 100644 --- a/dep/recastnavigation/Detour/CMakeLists.txt +++ b/dep/recastnavigation/Detour/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2010 Trinity +# Copyright (C) 2008-2013 TrinityCore # # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without diff --git a/dep/recastnavigation/Recast/CMakeLists.txt b/dep/recastnavigation/Recast/CMakeLists.txt index 7ced79c10b7..726aff72c0c 100644 --- a/dep/recastnavigation/Recast/CMakeLists.txt +++ b/dep/recastnavigation/Recast/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2010 Trinity +# Copyright (C) 2008-2013 TrinityCore # # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without diff --git a/src/tools/mmaps_generator/CMakeLists.txt b/src/tools/mmaps_generator/CMakeLists.txt index 99492abf8ee..b168691c994 100644 --- a/src/tools/mmaps_generator/CMakeLists.txt +++ b/src/tools/mmaps_generator/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2011 Trinity +# Copyright (C) 2008-2013 TrinityCore # # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without -- cgit v1.2.3 From 6fc17c6b1e0dadc3429ffa67b753ac492ddbd7a1 Mon Sep 17 00:00:00 2001 From: Nay Date: Tue, 22 Jan 2013 19:34:04 +0000 Subject: Core: Fix compile warnings --- src/server/game/Miscellaneous/SharedDefines.h | 2 +- .../game/Movement/MovementGenerators/PointMovementGenerator.h | 2 +- .../game/Movement/MovementGenerators/TargetedMovementGenerator.h | 6 +++--- src/server/game/Movement/PathGenerator.cpp | 2 +- src/server/scripts/Commands/cs_mmaps.cpp | 4 ++-- src/tools/mmaps_generator/TerrainBuilder.cpp | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/tools') diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index e5c4377d085..3d8ad37c92d 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -3534,7 +3534,7 @@ enum PartyResult ERR_PARTY_LFG_TELEPORT_IN_COMBAT = 30 }; -#define MMAP_MAGIC 0x4d4d4150 // 'MMAP' +const uint32 MMAP_MAGIC = 0x4d4d4150; // 'MMAP' #define MMAP_VERSION 3 struct MmapTileHeader diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h index 89f643283d6..421736ca4ec 100644 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h @@ -27,7 +27,7 @@ class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementG { public: PointMovementGenerator(uint32 _id, float _x, float _y, float _z, bool _generatePath, float _speed = 0.0f) : id(_id), - i_x(_x), i_y(_y), i_z(_z), m_generatePath(_generatePath), speed(_speed), i_recalculateSpeed(false) {} + i_x(_x), i_y(_y), i_z(_z), speed(_speed), m_generatePath(_generatePath), i_recalculateSpeed(false) {} void DoInitialize(T*); void DoFinalize(T*); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index 4f8cf658fde..3edeb348d54 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -39,8 +39,8 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, { protected: TargetedMovementGeneratorMedium(Unit* target, float offset, float angle) : - TargetedMovementGeneratorBase(target), i_recheckDistance(0), i_path(NULL), - i_offset(offset), i_angle(angle), + TargetedMovementGeneratorBase(target), i_path(NULL), + i_recheckDistance(0), i_offset(offset), i_angle(angle), i_recalculateTravel(false), i_targetReached(false) { } @@ -55,12 +55,12 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, protected: void _setTargetLocation(T* owner, bool updateDestination); + PathGenerator* i_path; TimeTrackerSmall i_recheckDistance; float i_offset; float i_angle; bool i_recalculateTravel : 1; bool i_targetReached : 1; - PathGenerator* i_path; }; template diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 71617f6a6ab..dbda4aa2411 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -30,7 +30,7 @@ PathGenerator::PathGenerator(const Unit* owner) : _polyLength(0), _type(PATHFIND_BLANK), _useStraightPath(false), _forceDestination(false), _pointPathLimit(MAX_POINT_PATH_LENGTH), - _sourceUnit(owner), _navMesh(NULL), _navMeshQuery(NULL), _endPosition(Vector3::zero()) + _endPosition(Vector3::zero()), _sourceUnit(owner), _navMesh(NULL), _navMeshQuery(NULL) { sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::PathGenerator for %u \n", _sourceUnit->GetGUIDLow()); diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index 4649e13e1c4..c4605e30991 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -98,7 +98,7 @@ public: PointsArray pointPath = path.GetPath(); handler->PSendSysMessage("%s's path to %s:", target->GetName().c_str(), player->GetName().c_str()); handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : "SmoothPath"); - handler->PSendSysMessage("Result: %s - Length: %i - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType()); + handler->PSendSysMessage("Result: %s - Length: "SIZEFMTD" - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType()); Vector3 start = path.GetStartPosition(); Vector3 end = path.GetEndPosition(); @@ -264,7 +264,7 @@ public: if (!creatureList.empty()) { - handler->PSendSysMessage("Found %i Creatures.", creatureList.size()); + handler->PSendSysMessage("Found "SIZEFTMD" Creatures.", creatureList.size()); uint32 paths = 0; uint32 uStartTime = getMSTime(); diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index c3d6541dfa3..6f26a43fa05 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -296,7 +296,7 @@ namespace MMAP } // FIXME: "the address of ‘liquid_type’ will always evaluate as ‘true’" - if (liquid_type && liquid_map) + if (liquid_map) { int count = meshData.liquidVerts.size() / 3; float xoffset = (float(tileX)-32)*GRID_SIZE; @@ -393,7 +393,7 @@ namespace MMAP // FIXME: "warning: the address of ‘liquid_type’ will always evaluate as ‘true’" // if there is no liquid, don't use liquid - if (!liquid_type || !meshData.liquidVerts.size() || !ltriangles.size()) + if (!meshData.liquidVerts.size() || !ltriangles.size()) useLiquid = false; else { -- cgit v1.2.3 From 4f3c6b139031116fe5074e9340bc53139a98ab57 Mon Sep 17 00:00:00 2001 From: Nay Date: Tue, 22 Jan 2013 20:47:52 +0000 Subject: Core: Yet another warning fix @Kaelima: could you verify MoveCharge? --- src/server/game/Movement/MotionMaster.cpp | 2 +- src/tools/mmaps_generator/TerrainBuilder.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src/tools') diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index f792aa959fb..c9ca7772186 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -428,7 +428,7 @@ void MotionMaster::MoveCharge(PathGenerator path, float speed, uint32 id) { Vector3 dest = path.GetActualEndPosition(); - MoveCharge(dest.x, dest.y, dest.z); + MoveCharge(dest.x, dest.y, dest.z, speed, id); Movement::MoveSplineInit init(_owner); init.MovebyPath(path.GetPath()); diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 6f26a43fa05..a42cd2b9bc6 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -295,7 +295,6 @@ namespace MMAP printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); } - // FIXME: "the address of ‘liquid_type’ will always evaluate as ‘true’" if (liquid_map) { int count = meshData.liquidVerts.size() / 3; @@ -369,7 +368,7 @@ namespace MMAP float* tverts = meshData.solidVerts.getCArray(); int* ttris = ttriangles.getCArray(); - if (ltriangles.size() + ttriangles.size() == 0) + if ((ltriangles.size() + ttriangles.size()) == 0) return false; // make a copy of liquid vertices -- cgit v1.2.3 From f4de181db00bf323793e2121aac496588c3b9b33 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Wed, 23 Jan 2013 20:29:40 +0100 Subject: SQL: Rename SQL merged in PR --- dep/SFMT/SFMT.h | 2 +- dep/SFMT/randomc.h | 2 +- .../2013_01_23_00_world_spell_script_names.sql | 77 ---------------------- .../2013_01_23_02_world_spell_script_names.sql | 77 ++++++++++++++++++++++ src/tools/mesh_extractor/Chunk.cpp | 2 +- src/tools/mesh_extractor/ContinentBuilder.cpp | 2 +- src/tools/mesh_extractor/DoodadHandler.h | 2 +- src/tools/mesh_extractor/Utils.cpp | 12 ++-- 8 files changed, 88 insertions(+), 88 deletions(-) delete mode 100644 sql/updates/world/2013_01_23_00_world_spell_script_names.sql create mode 100644 sql/updates/world/2013_01_23_02_world_spell_script_names.sql (limited to 'src/tools') diff --git a/dep/SFMT/SFMT.h b/dep/SFMT/SFMT.h index 08966e1831c..4004ae1db6e 100644 --- a/dep/SFMT/SFMT.h +++ b/dep/SFMT/SFMT.h @@ -7,7 +7,7 @@ * in effect in addition to the GNU General Public License. * Copyright (c) 2006, 2007 by Mutsuo Saito, Makoto Matsumoto and Hiroshima University. * Copyright (c) 2008 by Agner Fog. - * Copyright (c) 2012 Trinity Core + * Copyright (c) 2008-2013 Trinity Core * * BSD License: * Redistribution and use in source and binary forms, with or without diff --git a/dep/SFMT/randomc.h b/dep/SFMT/randomc.h index ee5ad9aa43b..eed2c81a205 100644 --- a/dep/SFMT/randomc.h +++ b/dep/SFMT/randomc.h @@ -7,7 +7,7 @@ * in effect in addition to the GNU General Public License. * Copyright (c) 2006, 2007 by Mutsuo Saito, Makoto Matsumoto and Hiroshima University. * Copyright (c) 2008 by Agner Fog. - * Copyright (c) 2012 Trinity Core + * Copyright (c) 2008-2013 Trinity Core * * BSD License: * Redistribution and use in source and binary forms, with or without diff --git a/sql/updates/world/2013_01_23_00_world_spell_script_names.sql b/sql/updates/world/2013_01_23_00_world_spell_script_names.sql deleted file mode 100644 index dd8b35ae420..00000000000 --- a/sql/updates/world/2013_01_23_00_world_spell_script_names.sql +++ /dev/null @@ -1,77 +0,0 @@ -DELETE FROM `spell_script_names` WHERE `spell_id` IN ( -70871, -- spell_blood_queen_essence_of_the_blood_queen -69383, -- spell_the_lich_king_dark_hunger -50453, -- spell_dk_blood_gorged --48496, -- spell_dru_living_seed -48504, -- spell_dru_living_seed_proc -28764, -- spell_gen_adaptive_warding -27539, -- spell_gen_obsidian_armor -34074, -- spell_hun_ascpect_of_the_viper -64411, -- spell_item_blessing_of_ancient_kings -71875, -- spell_item_necrotic_touch -71877, -- spell_item_necrotic_touch -71169, -- spell_item_shadows_fate -71903, -- spell_item_shadowmourne -71905, -- spell_item_shadowmourne_soul_fragment --44449, -- spell_mage_burnout -54646, -- spell_mage_focus_magic --11119, -- spell_mage_ignite --29074, -- spell_mage_master_of_elements --9799, -- spell_pal_eye_for_an_eye -20154, -- spell_pal_seal_of_righteousness -21084 -- spell_pal_seal_of_righteousness --47509, -- spell_pri_divine_aegis -55680, -- spell_pri_glyph_of_prayer_of_healing -28305, -- spell_pri_mana_leech -13877, -- spell_rog_blade_flurry -33735, -- spell_rog_blade_flurry -51211, -- spell_rog_blade_flurry -65956, -- spell_rog_blade_flurry -57934, -- spell_rog_tricks_of_the_trade -59628, -- spell_rog_tricks_of_the_trade_proc --974, -- spell_sha_earth_shield --47230, -- spell_warl_fel_synergy -63108, -- spell_warl_siphon_life --58872, -- spell_warr_damage_shield -12328, -- spell_warr_sweeping_strikes -18765, -- spell_warr_sweeping_strikes -35429 -- spell_warr_sweeping_strikes -); -INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES -(70871, 'spell_blood_queen_essence_of_the_blood_queen'), -(69383, 'spell_the_lich_king_dark_hunger'), -(50453, 'spell_dk_blood_gorged'), -(-48496, 'spell_dru_living_seed'), -(48504, 'spell_dru_living_seed_proc'), -(28764, 'spell_gen_adaptive_warding'), -(27539, 'spell_gen_obsidian_armor'), -(34074, 'spell_hun_ascpect_of_the_viper'), -(64411, 'spell_item_blessing_of_ancient_kings'), -(71875, 'spell_item_necrotic_touch'), -(71877, 'spell_item_necrotic_touch'), -(71169, 'spell_item_shadows_fate'), -(71903, 'spell_item_shadowmourne'), -(71905, 'spell_item_shadowmourne_soul_fragment'), -(-44449, 'spell_mage_burnout'), -(54646, 'spell_mage_focus_magic'), -(-11119, 'spell_mage_ignite'), -(-29074, 'spell_mage_master_of_elements'), -(-9799, 'spell_pal_eye_for_an_eye'), -(20154, 'spell_pal_seal_of_righteousness'), -(21084, 'spell_pal_seal_of_righteousness'), -(-47509, 'spell_pri_divine_aegis'), -(55680, 'spell_pri_glyph_of_prayer_of_healing'), -(28305, 'spell_pri_mana_leech'), -(13877, 'spell_rog_blade_flurry'), -(33735, 'spell_rog_blade_flurry'), -(51211, 'spell_rog_blade_flurry'), -(65956, 'spell_rog_blade_flurry'), -(57934, 'spell_rog_tricks_of_the_trade'), -(59628, 'spell_rog_tricks_of_the_trade_proc'), -(-974, 'spell_sha_earth_shield'), -(-47230, 'spell_warl_fel_synergy'), -(63108, 'spell_warl_siphon_life'), -(-58872, 'spell_warr_damage_shield'), -(12328, 'spell_warr_sweeping_strikes'), -(18765, 'spell_warr_sweeping_strikes'), -(35429, 'spell_warr_sweeping_strikes'); diff --git a/sql/updates/world/2013_01_23_02_world_spell_script_names.sql b/sql/updates/world/2013_01_23_02_world_spell_script_names.sql new file mode 100644 index 00000000000..dd8b35ae420 --- /dev/null +++ b/sql/updates/world/2013_01_23_02_world_spell_script_names.sql @@ -0,0 +1,77 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` IN ( +70871, -- spell_blood_queen_essence_of_the_blood_queen +69383, -- spell_the_lich_king_dark_hunger +50453, -- spell_dk_blood_gorged +-48496, -- spell_dru_living_seed +48504, -- spell_dru_living_seed_proc +28764, -- spell_gen_adaptive_warding +27539, -- spell_gen_obsidian_armor +34074, -- spell_hun_ascpect_of_the_viper +64411, -- spell_item_blessing_of_ancient_kings +71875, -- spell_item_necrotic_touch +71877, -- spell_item_necrotic_touch +71169, -- spell_item_shadows_fate +71903, -- spell_item_shadowmourne +71905, -- spell_item_shadowmourne_soul_fragment +-44449, -- spell_mage_burnout +54646, -- spell_mage_focus_magic +-11119, -- spell_mage_ignite +-29074, -- spell_mage_master_of_elements +-9799, -- spell_pal_eye_for_an_eye +20154, -- spell_pal_seal_of_righteousness +21084 -- spell_pal_seal_of_righteousness +-47509, -- spell_pri_divine_aegis +55680, -- spell_pri_glyph_of_prayer_of_healing +28305, -- spell_pri_mana_leech +13877, -- spell_rog_blade_flurry +33735, -- spell_rog_blade_flurry +51211, -- spell_rog_blade_flurry +65956, -- spell_rog_blade_flurry +57934, -- spell_rog_tricks_of_the_trade +59628, -- spell_rog_tricks_of_the_trade_proc +-974, -- spell_sha_earth_shield +-47230, -- spell_warl_fel_synergy +63108, -- spell_warl_siphon_life +-58872, -- spell_warr_damage_shield +12328, -- spell_warr_sweeping_strikes +18765, -- spell_warr_sweeping_strikes +35429 -- spell_warr_sweeping_strikes +); +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(70871, 'spell_blood_queen_essence_of_the_blood_queen'), +(69383, 'spell_the_lich_king_dark_hunger'), +(50453, 'spell_dk_blood_gorged'), +(-48496, 'spell_dru_living_seed'), +(48504, 'spell_dru_living_seed_proc'), +(28764, 'spell_gen_adaptive_warding'), +(27539, 'spell_gen_obsidian_armor'), +(34074, 'spell_hun_ascpect_of_the_viper'), +(64411, 'spell_item_blessing_of_ancient_kings'), +(71875, 'spell_item_necrotic_touch'), +(71877, 'spell_item_necrotic_touch'), +(71169, 'spell_item_shadows_fate'), +(71903, 'spell_item_shadowmourne'), +(71905, 'spell_item_shadowmourne_soul_fragment'), +(-44449, 'spell_mage_burnout'), +(54646, 'spell_mage_focus_magic'), +(-11119, 'spell_mage_ignite'), +(-29074, 'spell_mage_master_of_elements'), +(-9799, 'spell_pal_eye_for_an_eye'), +(20154, 'spell_pal_seal_of_righteousness'), +(21084, 'spell_pal_seal_of_righteousness'), +(-47509, 'spell_pri_divine_aegis'), +(55680, 'spell_pri_glyph_of_prayer_of_healing'), +(28305, 'spell_pri_mana_leech'), +(13877, 'spell_rog_blade_flurry'), +(33735, 'spell_rog_blade_flurry'), +(51211, 'spell_rog_blade_flurry'), +(65956, 'spell_rog_blade_flurry'), +(57934, 'spell_rog_tricks_of_the_trade'), +(59628, 'spell_rog_tricks_of_the_trade_proc'), +(-974, 'spell_sha_earth_shield'), +(-47230, 'spell_warl_fel_synergy'), +(63108, 'spell_warl_siphon_life'), +(-58872, 'spell_warr_damage_shield'), +(12328, 'spell_warr_sweeping_strikes'), +(18765, 'spell_warr_sweeping_strikes'), +(35429, 'spell_warr_sweeping_strikes'); diff --git a/src/tools/mesh_extractor/Chunk.cpp b/src/tools/mesh_extractor/Chunk.cpp index 9f2898a46e0..4605ae0f0dd 100644 --- a/src/tools/mesh_extractor/Chunk.cpp +++ b/src/tools/mesh_extractor/Chunk.cpp @@ -17,7 +17,7 @@ int32 Chunk::FindSubChunkOffset(std::string name) matched = 0; else ++matched; - + if (matched == 4) return ftell(stream) - 4; } diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 9b5c9f9c77b..d6125bdd8e2 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -101,7 +101,7 @@ void ContinentBuilder::Build(bool debug) } CalculateTileBounds(); - + dtNavMeshParams params; params.maxPolys = 1 << STATIC_POLY_BITS; params.maxTiles = TileMap->TileTable.size(); diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index 981834ec7ac..96aecbcce27 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -20,7 +20,7 @@ public: void Read(FILE* stream) { int count = 0; - + count += fread(&MmidIndex, sizeof(uint32), 1, stream); count += fread(&UniqueId, sizeof(uint32), 1, stream); Position = Vector3::Read(stream); diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 119ac94f94f..acb1ed38e27 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -218,7 +218,7 @@ void Utils::SaveToDisk( FILE* stream, std::string path ) if (fread(data, 1, size, stream) != 1) { printf("SaveToDisk: Error reading from Stream while trying to save file %s to disck.\n", path.c_str()); - return; + return; } // And write it in the file fwrite(data, 1, size, disk); @@ -274,7 +274,7 @@ void MapChunkHeader::Read(FILE* stream) count += fread(&SizeMCLQ, sizeof(uint32), 1, stream); Position = Vector3::Read(stream); count += fread(&OffsetMCCV, sizeof(uint32), 1, stream); - + if (count != 27) printf("MapChunkHeader::Read: Failed to read some data expected 27, read %d\n", count); } @@ -295,7 +295,7 @@ void MHDR::Read(FILE* stream) count += fread(&OffsetMFBO, sizeof(uint32), 1, stream); count += fread(&OffsetMH2O, sizeof(uint32), 1, stream); count += fread(&OffsetMTFX, sizeof(uint32), 1, stream); - + if (count != 12) printf("MHDR::Read: Failed to read some data expected 12, read %d\n", count); } @@ -357,7 +357,7 @@ void ModelHeader::Read(FILE* stream) count += fread(&OffsetBoundingVertices, sizeof(uint32), 1, stream); count += fread(&CountBoundingNormals, sizeof(uint32), 1, stream); count += fread(&OffsetBoundingNormals, sizeof(uint32), 1, stream); - + if (count != 51) printf("ModelHeader::Read: Failed to read some data expected 51, read %d\n", count); @@ -380,7 +380,7 @@ WorldModelHeader WorldModelHeader::Read(FILE* stream) ret.BoundingBox[0] = Vector3::Read(stream); ret.BoundingBox[1] = Vector3::Read(stream); count += fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); - + if (count != 10) printf("WorldModelHeader::Read: Failed to read some data expected 10, read %d\n", count); @@ -400,7 +400,7 @@ DoodadInstance DoodadInstance::Read(FILE* stream) count += fread(&ret.QuatZ, sizeof(float), 1, stream); count += fread(&ret.Scale, sizeof(float), 1, stream); count += fread(&ret.LightColor, sizeof(uint32), 1, stream); - + if (count != 7) printf("DoodadInstance::Read: Failed to read some data expected 7, read %d\n", count); -- cgit v1.2.3 From fd967ba4c64a71221397523440f2a3da0a9ec5f3 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Thu, 24 Jan 2013 01:20:25 +0100 Subject: Tools/mmaps_generator: Multithreading optimisations. Should save some time generating mmaps. --- src/server/shared/Database/DatabaseWorkerPool.h | 5 +-- src/tools/mmaps_generator/MapBuilder.cpp | 31 ++++---------- src/tools/mmaps_generator/MapBuilder.h | 55 ++++++++++++++++++++----- 3 files changed, 56 insertions(+), 35 deletions(-) (limited to 'src/tools') diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index 3df9436a4c4..edbc41be8f7 100644 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -56,9 +56,7 @@ class DatabaseWorkerPool _connections.resize(IDX_SIZE); WPFatal (mysql_thread_safe(), "Used MySQL library isn't thread-safe."); - WPFatal (mysql_get_server_version() >= MIN_MYSQL_SERVER_VERSION && - mysql_get_client_version() >= MIN_MYSQL_CLIENT_VERSION, - "TrinityCore does not support MySQL versions below 5.1"); + WPFatal (mysql_get_client_version() >= MIN_MYSQL_CLIENT_VERSION, "TrinityCore does not support MySQL versions below 5.1"); } ~DatabaseWorkerPool() @@ -79,6 +77,7 @@ class DatabaseWorkerPool { T* t = new T(_queue, _connectionInfo); res &= t->Open(); + WPFatal (mysql_get_server_version(t->GetHandle()) >= MIN_MYSQL_SERVER_VERSION, "TrinityCore does not support MySQL versions below 5.1"); _connections[IDX_ASYNC][i] = t; ++_connectionCount[IDX_ASYNC]; } diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index a62011ddfff..4707feb5857 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -166,45 +166,32 @@ namespace MMAP void MapBuilder::buildAllMaps(int threads) { std::vector _threads; - - for (int i = 0; i < threads; ++i) - _threads.push_back(new BuilderThread(this)); + + BuilderThreadPool* pool = new BuilderThreadPool(); for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) { uint32 mapID = it->first; if (!shouldSkipMap(mapID)) { - if (threads > 1) - { - bool next = false; - while (!next) - { - for (std::vector::iterator _th = _threads.begin(); _th != _threads.end(); ++_th) - { - if ((*_th)->Free) - { - (*_th)->SetMapId(mapID); - (*_th)->activate(); - next = true; - break; - } - } - // Wait for 20 seconds - ACE_OS::sleep(ACE_Time_Value (0, 20000)); - } - } + if (threads > 0) + pool->Enqueue(new BuildAMapPlz(mapID)); else buildMap(mapID); } } + for (int i = 0; i < threads; ++i) + _threads.push_back(new BuilderThread(this, pool->Queue())); + // Free memory for (std::vector::iterator _th = _threads.begin(); _th != _threads.end(); ++_th) { (*_th)->wait(); delete *_th; } + + delete pool; } /**************************************************************************/ diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index ea9636b3cc3..ea805fd9235 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -30,6 +30,8 @@ #include "DetourNavMesh.h" #include +#include +#include using namespace VMAP; @@ -123,27 +125,60 @@ namespace MMAP // build performance - not really used for now rcContext* m_rcContext; }; + + class BuildAMapPlz : public ACE_Method_Request + { + public: + BuildAMapPlz(uint32 mapId) : _mapId(mapId) {} + + virtual int call() + { + /// @ Actually a creative way of unabstracting the class and returning a member variable + return (int)_mapId; + } + + private: + uint32 _mapId; + }; class BuilderThread : public ACE_Task { private: MapBuilder* _builder; - uint32 _mapId; - public: - BuilderThread(MapBuilder* builder) : _builder(builder), Free(true) {} - - void SetMapId(uint32 mapId) { _mapId = mapId; } + ACE_Activation_Queue* _queue; + public: + BuilderThread(MapBuilder* builder, ACE_Activation_Queue* queue) : _builder(builder), _queue(queue) { activate(); } + int svc() { - Free = false; - if (_builder) - _builder->buildMap(_mapId); - Free = true; + BuildAMapPlz* request = NULL; + while (request = (BuildAMapPlz*)_queue->dequeue()) + { + _builder->buildMap(request->call()); + delete request; + request = NULL; + } return 0; } - bool Free; + }; + + class BuilderThreadPool + { + public: + BuilderThreadPool() : _queue(new ACE_Activation_Queue()) {} + ~BuilderThreadPool() { _queue->queue()->close(); delete _queue; } + + void Enqueue(BuildAMapPlz* request) + { + _queue->enqueue(request); + } + + ACE_Activation_Queue* Queue() { return _queue; } + + private: + ACE_Activation_Queue* _queue; }; } -- cgit v1.2.3 From 08866f377edae3c32d57195e2d9acabbd85fdd32 Mon Sep 17 00:00:00 2001 From: Shauren Date: Thu, 24 Jan 2013 16:40:35 +0100 Subject: Tools/mmap_generator: Fixed a deadlock at exit --- src/tools/mmaps_generator/MapBuilder.cpp | 8 ++++---- src/tools/mmaps_generator/MapBuilder.h | 20 +++++++++++--------- src/tools/mmaps_generator/PathGenerator.cpp | 2 +- 3 files changed, 16 insertions(+), 14 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 4707feb5857..4a016f267b4 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -166,8 +166,8 @@ namespace MMAP void MapBuilder::buildAllMaps(int threads) { std::vector _threads; - - BuilderThreadPool* pool = new BuilderThreadPool(); + + BuilderThreadPool* pool = threads > 0 ? new BuilderThreadPool() : NULL; for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) { @@ -175,13 +175,13 @@ namespace MMAP if (!shouldSkipMap(mapID)) { if (threads > 0) - pool->Enqueue(new BuildAMapPlz(mapID)); + pool->Enqueue(new MapBuildRequest(mapID)); else buildMap(mapID); } } - for (int i = 0; i < threads; ++i) + for (int i = 0; i < threads; ++i) _threads.push_back(new BuilderThread(this, pool->Queue())); // Free memory diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index ea805fd9235..3ffaea0ab66 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -125,11 +125,11 @@ namespace MMAP // build performance - not really used for now rcContext* m_rcContext; }; - - class BuildAMapPlz : public ACE_Method_Request + + class MapBuildRequest : public ACE_Method_Request { public: - BuildAMapPlz(uint32 mapId) : _mapId(mapId) {} + MapBuildRequest(uint32 mapId) : _mapId(mapId) {} virtual int call() { @@ -141,7 +141,7 @@ namespace MMAP uint32 _mapId; }; - class BuilderThread : public ACE_Task + class BuilderThread : public ACE_Task_Base { private: MapBuilder* _builder; @@ -149,19 +149,21 @@ namespace MMAP public: BuilderThread(MapBuilder* builder, ACE_Activation_Queue* queue) : _builder(builder), _queue(queue) { activate(); } - + int svc() { - BuildAMapPlz* request = NULL; - while (request = (BuildAMapPlz*)_queue->dequeue()) + /// @ Set a timeout for dequeue attempts (only used when the queue is empty) as it will never get populated after thread starts + ACE_Time_Value timeout(5); + ACE_Method_Request* request = NULL; + while ((request = _queue->dequeue(&timeout)) != NULL) { _builder->buildMap(request->call()); delete request; request = NULL; } + return 0; } - }; class BuilderThreadPool @@ -170,7 +172,7 @@ namespace MMAP BuilderThreadPool() : _queue(new ACE_Activation_Queue()) {} ~BuilderThreadPool() { _queue->queue()->close(); delete _queue; } - void Enqueue(BuildAMapPlz* request) + void Enqueue(MapBuildRequest* request) { _queue->enqueue(request); } diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 01059099f98..47d35b517d5 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -292,5 +292,5 @@ int main(int argc, char** argv) if (!silent) printf("Finished. MMAPS were built in %u ms!\n", GetMSTimeDiffToNow(start)); - return 1; + return 0; } -- cgit v1.2.3 From 98f01c2b12e6a2aeef8b2f9810e5a3cce9d5e475 Mon Sep 17 00:00:00 2001 From: Nay Date: Mon, 28 Jan 2013 02:54:27 +0000 Subject: Core/Misc: Fix compile errors introduced in previous merge There are probably other merge issues that got through, please report them --- src/server/game/Battlegrounds/Battleground.cpp | 6 ++- src/server/game/Handlers/BattleGroundHandler.cpp | 4 +- .../MovementGenerators/RandomMovementGenerator.cpp | 2 +- src/server/game/Movement/Spline/MoveSplineInit.cpp | 57 +++++++++++----------- .../scripts/Kalimdor/Firelands/boss_alysrazor.cpp | 2 +- src/server/scripts/Spells/spell_mage.cpp | 6 +-- src/server/scripts/Spells/spell_priest.cpp | 3 +- src/server/scripts/Spells/spell_warlock.cpp | 46 +++++++++++++---- src/server/scripts/Spells/spell_warrior.cpp | 41 ---------------- src/tools/CMakeLists.txt | 2 +- src/tools/map_extractor/System.cpp | 2 +- 11 files changed, 81 insertions(+), 90 deletions(-) (limited to 'src/tools') diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index e2ae9f50452..445d1295629 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -973,7 +973,7 @@ void Battleground::EndBattleground(uint32 winner) player->GetSession()->SendPacket(&pvpLogData); WorldPacket data; - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, player->GetBattlegroundQueueJoinTime(GetTypeID()), GetElapsedTime(), GetArenaType()); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, player->GetBattlegroundQueueJoinTime(GetTypeID()), GetElapsedTime(), GetArenaType()); player->GetSession()->SendPacket(&data); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1); @@ -1204,9 +1204,13 @@ void Battleground::AddPlayer(Player* player) sBattlegroundMgr->BuildPlayerJoinedBattlegroundPacket(&data, player->GetGUID()); SendPacketToTeam(team, &data, player, false); + // BG Status packet + BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(m_TypeID, GetArenaType()); + uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId); sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player, queueSlot, STATUS_IN_PROGRESS, player->GetBattlegroundQueueJoinTime(m_TypeID), GetElapsedTime(), GetArenaType()); player->GetSession()->SendPacket(&data); + player->RemoveAurasByType(SPELL_AURA_MOUNTED); // add arena specific auras diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index d28b67106c4..9955879d37a 100644 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -538,7 +538,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) _player->CleanupAfterTaxiFlight(); } - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), ginfo.Team); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_IN_PROGRESS, _player->GetBattlegroundQueueJoinTime(bgTypeId), bg->GetElapsedTime(), bg->GetArenaType()); _player->GetSession()->SendPacket(&data); // remove battleground queue status from BGmgr @@ -622,7 +622,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) { // this line is checked, i only don't know if GetElapsedTime() is changing itself after bg end! // send status in Battleground - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetBGTeam()); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, GetPlayer(), i, STATUS_IN_PROGRESS, _player->GetBattlegroundQueueJoinTime(bgTypeId), bg->GetElapsedTime(), arenaType); SendPacket(&data); continue; } diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp index 67136792fa6..723b0748494 100644 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp @@ -165,7 +165,7 @@ bool RandomMovementGenerator::GetResetPos(Creature* creature, float& x creature->GetRespawnPosition(x, y, z, NULL, &radius); // use current if in range - if (creature.IsWithinDist2d(x, y, radius)) + if (creature->IsWithinDist2d(x, y, radius)) creature->GetPosition(x, y, z); return true; diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index a8ae40926b8..f7d876d7aa3 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -60,23 +60,22 @@ namespace Movement int32 MoveSplineInit::Launch() { - MoveSpline& move_spline = *unit.movespline; + MoveSpline& move_spline = *unit->movespline; - Location real_position(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZMinusOffset(), unit.GetOrientation()); + Location real_position(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZMinusOffset(), unit->GetOrientation()); // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes - if (unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit.GetTransGUID()) + if (unit->GetTransGUID()) { - transport = true; - real_position.x = unit.GetTransOffsetX(); - real_position.y = unit.GetTransOffsetY(); - real_position.z = unit.GetTransOffsetZ(); - real_position.orientation = unit.GetTransOffsetO(); + real_position.x = unit->GetTransOffsetX(); + real_position.y = unit->GetTransOffsetY(); + real_position.z = unit->GetTransOffsetZ(); + real_position.orientation = unit->GetTransOffsetO(); } // there is a big chance that current position is unknown if current state is not finalized, need compute it - // this also allows CalculatePath spline position and update map position in much greater intervals + // this also allows calculate spline position and update map position in much greater intervals // Don't compute for transport movement if the unit is in a motion between two transports - if (!move_spline.Finalized() && move_spline.onTransport == (unit.GetTransGUID() != 0)) + if (!move_spline.Finalized() && move_spline.onTransport == (unit->GetTransGUID() != 0)) real_position = move_spline.ComputePosition(); // should i do the things that user should do? - no. @@ -86,7 +85,7 @@ namespace Movement // correct first vertex args.path[0] = real_position; args.initialOrientation = real_position.orientation; - move_spline.onTransport = (unit.GetTransGUID() != 0); + move_spline.onTransport = (unit->GetTransGUID() != 0); uint32 moveFlags = unit->m_movementInfo.GetMovementFlags(); if (args.flags.walkmode) @@ -105,27 +104,27 @@ namespace Movement if (moveFlags & MOVEMENTFLAG_ROOT) moveFlags &= ~MOVEMENTFLAG_MASK_MOVING; - unit.m_movementInfo.SetMovementFlags(moveFlags); + unit->m_movementInfo.SetMovementFlags(moveFlags); move_spline.Initialize(args); WorldPacket data(SMSG_MONSTER_MOVE, 64); data.append(unit->GetPackGUID()); - if (unit.GetTransGUID()) + if (unit->GetTransGUID()) { data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); - data.appendPackGUID(unit.GetTransGUID()); - data << int8(unit.GetTransSeat()); + data.appendPackGUID(unit->GetTransGUID()); + data << int8(unit->GetTransSeat()); } PacketBuilder::WriteMonsterMove(move_spline, data); - unit->SendMessageToSet(&data,true); - + unit->SendMessageToSet(&data, true); + return move_spline.Duration(); } void MoveSplineInit::Stop() { - MoveSpline& move_spline = *unit.movespline; + MoveSpline& move_spline = *unit->movespline; // No need to stop if we are not moving if (move_spline.Finalized()) @@ -133,30 +132,30 @@ namespace Movement Location loc = move_spline.ComputePosition(); args.flags = MoveSplineFlag::Done; - unit.m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_FORWARD); + unit->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_FORWARD); move_spline.Initialize(args); WorldPacket data(SMSG_MONSTER_MOVE, 64); - data.append(unit.GetPackGUID()); - if (unit.GetTransGUID()) + data.append(unit->GetPackGUID()); + if (unit->GetTransGUID()) { data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); - data.appendPackGUID(unit.GetTransGUID()); - data << int8(unit.GetTransSeat()); + data.appendPackGUID(unit->GetTransGUID()); + data << int8(unit->GetTransSeat()); } PacketBuilder::WriteStopMovement(loc, args.splineId, data); - unit.SendMessageToSet(&data, true); + unit->SendMessageToSet(&data, true); } - MoveSplineInit::MoveSplineInit(Unit& m) : unit(m) + MoveSplineInit::MoveSplineInit(Unit* m) : unit(m) { args.splineId = splineIdGen.NewId(); // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes - args.TransformForTransport = unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit->GetTransGUID(); + args.TransformForTransport = unit->GetTransGUID(); // mix existing state into new - args.flags.walkmode = unit.m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); - args.flags.flying = unit.m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY); + args.flags.walkmode = unit->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); + args.flags.flying = unit->m_movementInfo.HasMovementFlag(MovementFlags(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY)); args.flags.smoothGroundPath = true; // enabled by default, CatmullRom mode or client config "pathSmoothing" will disable this } @@ -202,7 +201,7 @@ namespace Movement void MoveSplineInit::SetFall() { args.flags.EnableFalling(); - args.flags.fallingSlow = unit.HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW); + args.flags.fallingSlow = unit->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW); } Vector3 TransportPathTransform::operator()(Vector3 input) diff --git a/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp b/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp index 1dc70c5e505..b7816242afc 100644 --- a/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp +++ b/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp @@ -298,7 +298,7 @@ class npc_blazing_monstrosity : public CreatureScript passenger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // Hack to relocate vehicle on vehicle so exiting players are not moved under map - Movement::MoveSplineInit init(*passenger); + Movement::MoveSplineInit init(passenger); init.DisableTransportPathTransformations(); init.MoveTo(0.6654003f, 0.0f, 1.9815f); init.SetFacing(0.0f); diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index e14327b0f36..7bd1753116b 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -688,7 +688,7 @@ class spell_mage_mage_ward : public SpellScriptLoader if (AuraEffect* aurEff = GetTarget()->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_GENERIC, ICON_MAGE_INCANTER_S_ABSORPTION, EFFECT_0)) { int32 bp = CalculatePct(absorbAmount, aurEff->GetAmount()); - GetTarget()->CastCustomSpell(GetTarget(), SPELL_MAGE_INCANTER_S_ABSORPTION_TRIGGERED, &bp, NULL, NULL, true); + GetTarget()->CastCustomSpell(GetTarget(), SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED, &bp, NULL, NULL, true); } } @@ -720,14 +720,14 @@ class spell_mage_mana_shield : public SpellScriptLoader if (AuraEffect* aurEff = GetTarget()->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_GENERIC, ICON_MAGE_INCANTER_S_ABSORPTION, EFFECT_0)) { int32 bp = CalculatePct(absorbAmount, aurEff->GetAmount()); - GetTarget()->CastCustomSpell(GetTarget(), SPELL_MAGE_INCANTER_S_ABSORPTION_TRIGGERED, &bp, NULL, NULL, true); + GetTarget()->CastCustomSpell(GetTarget(), SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED, &bp, NULL, NULL, true); } } void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL) - GetTarget()->CastSpell(GetTarget(), SPELL_MAGE_INCANTER_S_ABSORPTION_KNOCKBACK, true); + GetTarget()->CastSpell(GetTarget(), SPELL_MAGE_INCANTERS_ABSORBTION_R1, true); } void Register() diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 94b12818626..c2bfc913893 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -54,8 +54,9 @@ enum PriestSpells enum PriestSpellIcons { + PRIEST_ICON_ID_BORROWED_TIME = 2899, PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT = 3021, - PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874 + PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874, }; // -47509 - Divine Aegis diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 31833524861..df415a7bb08 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -29,28 +29,29 @@ enum WarlockSpells { SPELL_WARLOCK_BANE_OF_DOOM_EFFECT = 18662, + SPELL_WARLOCK_CURSE_OF_DOOM_EFFECT = 18662, + SPELL_WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST = 62388, SPELL_WARLOCK_DEMONIC_CIRCLE_SUMMON = 48018, SPELL_WARLOCK_DEMONIC_CIRCLE_TELEPORT = 48020, - SPELL_WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST = 62388, - SPELL_WARLOCK_DEMONIC_EMPOWERMENT_SUCCUBUS = 54435, - SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER = 54443, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_FELGUARD = 54508, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_FELHUNTER = 54509, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_IMP = 54444, + SPELL_WARLOCK_DEMONIC_EMPOWERMENT_SUCCUBUS = 54435, + SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER = 54443, SPELL_WARLOCK_FEL_SYNERGY_HEAL = 54181, SPELL_WARLOCK_GLYPH_OF_SIPHON_LIFE = 63106, + SPELL_WARLOCK_HAUNT = 48181, + SPELL_WARLOCK_HAUNT_HEAL = 48210, SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R1 = 18692, SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R2 = 18693, - SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R1 = 18703, - SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R2 = 18704, SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R1 = 60955, SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R2 = 60956, - SPELL_WARLOCK_HAUNT = 48181, - SPELL_WARLOCK_HAUNT_HEAL = 48210, + SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R1 = 18703, + SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R2 = 18704, SPELL_WARLOCK_LIFE_TAP_ENERGIZE = 31818, SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2 = 32553, - SPELL_WARLOCK_SOULSHATTER = 32835, SPELL_WARLOCK_SIPHON_LIFE_HEAL = 63106, + SPELL_WARLOCK_SOULSHATTER = 32835, SPELL_WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117 }; @@ -647,6 +648,34 @@ class spell_warl_life_tap : public SpellScriptLoader } }; +// 18541 - Ritual of Doom Effect +class spell_warl_ritual_of_doom_effect : public SpellScriptLoader +{ + public: + spell_warl_ritual_of_doom_effect() : SpellScriptLoader("spell_warl_ritual_of_doom_effect") { } + + class spell_warl_ritual_of_doom_effect_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_ritual_of_doom_effect_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + caster->CastSpell(caster, GetEffectValue(), true); + } + + void Register() + { + OnEffectHit += SpellEffectFn(spell_warl_ritual_of_doom_effect_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_warl_ritual_of_doom_effect_SpellScript(); + } +}; + // 27285 - Seed of Corruption /// Updated 4.3.4 class spell_warl_seed_of_corruption : public SpellScriptLoader @@ -846,7 +875,6 @@ void AddSC_warlock_spell_scripts() new spell_warl_bane_of_doom(); new spell_warl_banish(); new spell_warl_create_healthstone(); - new spell_warl_curse_of_doom(); new spell_warl_demonic_circle_summon(); new spell_warl_demonic_circle_teleport(); new spell_warl_demonic_empowerment(); diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index c155c39ffdb..9e2cb8aad71 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -31,7 +31,6 @@ enum WarriorSpells SPELL_WARRIOR_BLOODTHIRST = 23885, SPELL_WARRIOR_BLOODTHIRST_DAMAGE = 23881, SPELL_WARRIOR_CHARGE = 34846, - SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE = 59653, SPELL_WARRIOR_DEEP_WOUNDS_RANK_1 = 12162, SPELL_WARRIOR_DEEP_WOUNDS_RANK_2 = 12850, SPELL_WARRIOR_DEEP_WOUNDS_RANK_3 = 12868, @@ -43,7 +42,6 @@ enum WarriorSpells SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_TALENT = 64976, SPELL_WARRIOR_LAST_STAND_TRIGGERED = 12976, SPELL_WARRIOR_SLAM = 50782, - SPELL_WARRIOR_SLAM = 50783, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK = 26654, SPELL_WARRIOR_TAUNT = 355, SPELL_WARRIOR_UNRELENTING_ASSAULT_RANK_1 = 46859, @@ -201,44 +199,6 @@ class spell_warr_concussion_blow : public SpellScriptLoader } }; -// -58872 - Damage Shield -class spell_warr_damage_shield : public SpellScriptLoader -{ - public: - spell_warr_damage_shield() : SpellScriptLoader("spell_warr_damage_shield") { } - - class spell_warr_damage_shield_AuraScript : public AuraScript - { - PrepareAuraScript(spell_warr_damage_shield_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) - { - if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE)) - return false; - return true; - } - - void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - // % of amount blocked - int32 damage = CalculatePct(int32(GetTarget()->GetShieldBlockValue()), aurEff->GetAmount()); - GetTarget()->CastCustomSpell(SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE, SPELLVALUE_BASE_POINT0, damage, eventInfo.GetProcTarget(), true, NULL, aurEff); - } - - void Register() - { - OnEffectProc += AuraEffectProcFn(spell_warr_damage_shield_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; - - AuraScript* GetAuraScript() const - { - return new spell_warr_damage_shield_AuraScript(); - } -}; - /// Updated 4.3.4 class spell_warr_deep_wounds : public SpellScriptLoader { @@ -770,7 +730,6 @@ void AddSC_warrior_spell_scripts() new spell_warr_bloodthirst_heal(); new spell_warr_charge(); new spell_warr_concussion_blow(); - new spell_warr_damage_shield(); new spell_warr_deep_wounds(); new spell_warr_execute(); new spell_warr_improved_spell_reflection(); diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index 49c17913c64..671de25dfd3 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -12,4 +12,4 @@ add_subdirectory(map_extractor) add_subdirectory(vmap4_assembler) add_subdirectory(vmap4_extractor) add_subdirectory(mmaps_generator) -add_subdirectory(mesh_extractor) +# add_subdirectory(mesh_extractor) diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index 800328810a7..7b591ddfc85 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -901,7 +901,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, { for (int j = 0; j < ADT_CELLS_PER_GRID; ++j) { - adt_MCNK * cell = cells->getMCNK(i,j); + adt_MCNK * cell = adt.cells[i][j]; if (!cell) continue; holes[i][j] = cell->holes; -- cgit v1.2.3 From c4e4cb1b5c4b407c44da30fb254a6c248503451b Mon Sep 17 00:00:00 2001 From: Spp Date: Wed, 30 Jan 2013 09:06:19 +0100 Subject: Core/Misc: Remove using directive from header files (It will eventually lead to name collisions) --- src/server/collision/BoundingIntervalHierarchy.cpp | 12 +++-- src/server/collision/BoundingIntervalHierarchy.h | 33 ++++-------- .../collision/BoundingIntervalHierarchyWrapper.h | 8 +-- src/server/collision/DynamicTree.cpp | 61 ++++++++++++---------- src/server/collision/DynamicTree.h | 26 ++++----- src/server/collision/Maps/MapTree.h | 2 +- src/server/collision/Models/WorldModel.h | 28 +++++----- src/server/collision/RegularGrid.h | 16 ++---- src/server/game/Maps/Map.cpp | 6 +-- .../game/Movement/Spline/MovementPacketBuilder.cpp | 1 + .../game/Movement/Spline/MovementPacketBuilder.h | 1 + src/tools/mmaps_generator/TerrainBuilder.cpp | 24 ++++----- src/tools/mmaps_generator/VMapExtensions.cpp | 4 +- 13 files changed, 110 insertions(+), 112 deletions(-) (limited to 'src/tools') diff --git a/src/server/collision/BoundingIntervalHierarchy.cpp b/src/server/collision/BoundingIntervalHierarchy.cpp index ad3753ea3c9..bca738d1ff6 100644 --- a/src/server/collision/BoundingIntervalHierarchy.cpp +++ b/src/server/collision/BoundingIntervalHierarchy.cpp @@ -18,6 +18,12 @@ #include "BoundingIntervalHierarchy.h" +#if defined __APPLE__ + #define isnan std::isnan +#elif defined _MSC_VER + #define isnan _isnan +#endif + void BIH::buildHierarchy(std::vector &tempTree, buildData &dat, BuildStats &stats) { // create space for the first node @@ -51,7 +57,7 @@ void BIH::subdivide(int left, int right, std::vector &tempTree, buildDat prevAxis = axis; prevSplit = split; // perform quick consistency checks - Vector3 d( gridBox.hi - gridBox.lo ); + G3D::Vector3 d( gridBox.hi - gridBox.lo ); if (d.x < 0 || d.y < 0 || d.z < 0) throw std::logic_error("negative node extents"); for (int i = 0; i < 3; i++) @@ -255,11 +261,11 @@ bool BIH::writeToFile(FILE* wf) const bool BIH::readFromFile(FILE* rf) { uint32 treeSize; - Vector3 lo, hi; + G3D::Vector3 lo, hi; uint32 check=0, count=0; check += fread(&lo, sizeof(float), 3, rf); check += fread(&hi, sizeof(float), 3, rf); - bounds = AABox(lo, hi); + bounds = G3D::AABox(lo, hi); check += fread(&treeSize, sizeof(uint32), 1, rf); tree.resize(treeSize); check += fread(&tree[0], sizeof(uint32), treeSize, rf); diff --git a/src/server/collision/BoundingIntervalHierarchy.h b/src/server/collision/BoundingIntervalHierarchy.h index 7cbaedbfba6..997f9c99e5f 100644 --- a/src/server/collision/BoundingIntervalHierarchy.h +++ b/src/server/collision/BoundingIntervalHierarchy.h @@ -31,20 +31,8 @@ #include #include -#ifdef __APPLE__ - #define isnan(x) ( std::isnan(x) ) -#endif - #define MAX_STACK_SIZE 64 -#ifdef _MSC_VER - #define isnan(x) _isnan(x) -#endif - -using G3D::Vector3; -using G3D::AABox; -using G3D::Ray; - static inline uint32 floatToRawIntBits(float f) { union @@ -69,7 +57,7 @@ static inline float intBitsToFloat(uint32 i) struct AABound { - Vector3 lo, hi; + G3D::Vector3 lo, hi; }; /** Bounding Interval Hierarchy Class. @@ -105,12 +93,11 @@ class BIH dat.maxPrims = leafSize; dat.numPrims = primitives.size(); dat.indices = new uint32[dat.numPrims]; - dat.primBound = new AABox[dat.numPrims]; + dat.primBound = new G3D::AABox[dat.numPrims]; getBounds(primitives[0], bounds); for (uint32 i=0; i - void intersectRay(const Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirst=false) const + void intersectRay(const G3D::Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirst=false) const { float intervalMin = -1.f; float intervalMax = -1.f; - Vector3 org = r.origin(); - Vector3 dir = r.direction(); - Vector3 invDir; + G3D::Vector3 org = r.origin(); + G3D::Vector3 dir = r.direction(); + G3D::Vector3 invDir; for (int i=0; i<3; ++i) { invDir[i] = 1.f / dir[i]; @@ -270,7 +257,7 @@ class BIH } template - void intersectPoint(const Vector3 &p, IsectCallback& intersectCallback) const + void intersectPoint(const G3D::Vector3 &p, IsectCallback& intersectCallback) const { if (!bounds.contains(p)) return; @@ -353,12 +340,12 @@ class BIH protected: std::vector tree; std::vector objects; - AABox bounds; + G3D::AABox bounds; struct buildData { uint32 *indices; - AABox *primBound; + G3D::AABox *primBound; uint32 numPrims; int maxPrims; }; @@ -410,4 +397,4 @@ class BIH void subdivide(int left, int right, std::vector &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats); }; -#endif // _BIH_H \ No newline at end of file +#endif // _BIH_H diff --git a/src/server/collision/BoundingIntervalHierarchyWrapper.h b/src/server/collision/BoundingIntervalHierarchyWrapper.h index 315f3004306..305d57b0075 100644 --- a/src/server/collision/BoundingIntervalHierarchyWrapper.h +++ b/src/server/collision/BoundingIntervalHierarchyWrapper.h @@ -37,7 +37,7 @@ class BIHWrap MDLCallback(RayCallback& callback, const T* const* objects_array, uint32 objects_size ) : objects(objects_array), _callback(callback), objects_size(objects_size) {} - bool operator() (const Ray& ray, uint32 Idx, float& MaxDist, bool /*stopAtFirst*/) + bool operator() (const G3D::Ray& ray, uint32 Idx, float& MaxDist, bool /*stopAtFirst*/) { if (Idx >= objects_size) return false; @@ -46,7 +46,7 @@ class BIHWrap return false; } - void operator() (const Vector3& p, uint32 Idx) + void operator() (const G3D::Vector3& p, uint32 Idx) { if (Idx >= objects_size) return false; @@ -98,7 +98,7 @@ public: } template - void intersectRay(const Ray& ray, RayCallback& intersectCallback, float& maxDist) + void intersectRay(const G3D::Ray& ray, RayCallback& intersectCallback, float& maxDist) { balance(); MDLCallback temp_cb(intersectCallback, m_objects.getCArray(), m_objects.size()); @@ -106,7 +106,7 @@ public: } template - void intersectPoint(const Vector3& point, IsectCallback& intersectCallback) + void intersectPoint(const G3D::Vector3& point, IsectCallback& intersectCallback) { balance(); MDLCallback callback(intersectCallback, m_objects.getCArray(), m_objects.size()); diff --git a/src/server/collision/DynamicTree.cpp b/src/server/collision/DynamicTree.cpp index c6754278d17..c70a4b78a03 100644 --- a/src/server/collision/DynamicTree.cpp +++ b/src/server/collision/DynamicTree.cpp @@ -27,15 +27,24 @@ #include "GameObjectModel.h" #include "ModelInstance.h" +#include +#include +#include + using VMAP::ModelInstance; -using G3D::Ray; + +namespace { + +int CHECK_TREE_PERIOD = 200; + +} // namespace template<> struct HashTrait< GameObjectModel>{ static size_t hashCode(const GameObjectModel& g) { return (size_t)(void*)&g; } }; template<> struct PositionTrait< GameObjectModel> { - static void getPosition(const GameObjectModel& g, Vector3& p) { p = g.getPosition(); } + static void getPosition(const GameObjectModel& g, G3D::Vector3& p) { p = g.getPosition(); } }; template<> struct BoundsTrait< GameObjectModel> { @@ -49,11 +58,6 @@ static bool operator == (const GameObjectModel& mdl, const GameObjectModel& mdl2 } */ -int valuesPerNode = 5, numMeanSplits = 3; - -int UNBALANCED_TIMES_LIMIT = 5; -int CHECK_TREE_PERIOD = 200; - typedef RegularGrid2D > ParentTree; struct DynTreeImpl : public ParentTree/*, public Intersectable*/ @@ -103,43 +107,43 @@ struct DynTreeImpl : public ParentTree/*, public Intersectable*/ int unbalanced_times; }; -DynamicMapTree::DynamicMapTree() : impl(*new DynTreeImpl()) +DynamicMapTree::DynamicMapTree() : impl(new DynTreeImpl()) { } DynamicMapTree::~DynamicMapTree() { - delete &impl; + delete impl; } void DynamicMapTree::insert(const GameObjectModel& mdl) { - impl.insert(mdl); + impl->insert(mdl); } void DynamicMapTree::remove(const GameObjectModel& mdl) { - impl.remove(mdl); + impl->remove(mdl); } bool DynamicMapTree::contains(const GameObjectModel& mdl) const { - return impl.contains(mdl); + return impl->contains(mdl); } void DynamicMapTree::balance() { - impl.balance(); + impl->balance(); } int DynamicMapTree::size() const { - return impl.size(); + return impl->size(); } void DynamicMapTree::update(uint32 t_diff) { - impl.update(t_diff); + impl->update(t_diff); } struct DynamicTreeIntersectionCallback @@ -147,7 +151,7 @@ struct DynamicTreeIntersectionCallback bool did_hit; uint32 phase_mask; DynamicTreeIntersectionCallback(uint32 phasemask) : did_hit(false), phase_mask(phasemask) {} - bool operator()(const Ray& r, const GameObjectModel& obj, float& distance) + bool operator()(const G3D::Ray& r, const GameObjectModel& obj, float& distance) { did_hit = obj.intersectRay(r, distance, true, phase_mask); return did_hit; @@ -163,7 +167,7 @@ struct DynamicTreeIntersectionCallback_WithLogger { sLog->outDebug(LOG_FILTER_MAPS, "Dynamic Intersection log"); } - bool operator()(const Ray& r, const GameObjectModel& obj, float& distance) + bool operator()(const G3D::Ray& r, const GameObjectModel& obj, float& distance) { sLog->outDebug(LOG_FILTER_MAPS, "testing intersection with %s", obj.name.c_str()); bool hit = obj.intersectRay(r, distance, true, phase_mask); @@ -177,17 +181,20 @@ struct DynamicTreeIntersectionCallback_WithLogger bool didHit() const { return did_hit;} }; -bool DynamicMapTree::getIntersectionTime(const uint32 phasemask, const G3D::Ray& ray, const Vector3& endPos, float& maxDist) const +bool DynamicMapTree::getIntersectionTime(const uint32 phasemask, const G3D::Ray& ray, + const G3D::Vector3& endPos, float& maxDist) const { float distance = maxDist; DynamicTreeIntersectionCallback callback(phasemask); - impl.intersectRay(ray, callback, distance, endPos); + impl->intersectRay(ray, callback, distance, endPos); if (callback.didHit()) maxDist = distance; return callback.didHit(); } -bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const Vector3& startPos, const Vector3& endPos, Vector3& resultHit, float modifyDist) const +bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const G3D::Vector3& startPos, + const G3D::Vector3& endPos, G3D::Vector3& resultHit, + float modifyDist) const { bool result = false; float maxDist = (endPos - startPos).magnitude(); @@ -199,7 +206,7 @@ bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const Vector3& star resultHit = endPos; return false; } - Vector3 dir = (endPos - startPos)/maxDist; // direction with length of 1 + G3D::Vector3 dir = (endPos - startPos)/maxDist; // direction with length of 1 G3D::Ray ray(startPos, dir); float dist = maxDist; if (getIntersectionTime(phasemask, ray, endPos, dist)) @@ -227,26 +234,26 @@ bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const Vector3& star bool DynamicMapTree::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const { - Vector3 v1(x1, y1, z1), v2(x2, y2, z2); + G3D::Vector3 v1(x1, y1, z1), v2(x2, y2, z2); float maxDist = (v2 - v1).magnitude(); if (!G3D::fuzzyGt(maxDist, 0) ) return true; - Ray r(v1, (v2-v1) / maxDist); + G3D::Ray r(v1, (v2-v1) / maxDist); DynamicTreeIntersectionCallback callback(phasemask); - impl.intersectRay(r, callback, maxDist, v2); + impl->intersectRay(r, callback, maxDist, v2); return !callback.did_hit; } float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, uint32 phasemask) const { - Vector3 v(x, y, z); - Ray r(v, Vector3(0, 0, -1)); + G3D::Vector3 v(x, y, z); + G3D::Ray r(v, G3D::Vector3(0, 0, -1)); DynamicTreeIntersectionCallback callback(phasemask); - impl.intersectZAllignedRay(r, callback, maxSearchDist); + impl->intersectZAllignedRay(r, callback, maxSearchDist); if (callback.didHit()) return v.z - maxSearchDist; diff --git a/src/server/collision/DynamicTree.h b/src/server/collision/DynamicTree.h index ca199a9cd70..8e541fd453a 100644 --- a/src/server/collision/DynamicTree.h +++ b/src/server/collision/DynamicTree.h @@ -20,34 +20,36 @@ #ifndef _DYNTREE_H #define _DYNTREE_H -#include -#include -#include -#include - -//#include "ModelInstance.h" #include "Define.h" -//#include "GameObjectModel.h" namespace G3D { + class Ray; class Vector3; } -using G3D::Vector3; class GameObjectModel; +struct DynTreeImpl; class DynamicMapTree { - struct DynTreeImpl& impl; + DynTreeImpl *impl; + public: DynamicMapTree(); ~DynamicMapTree(); - bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const; - bool getIntersectionTime(uint32 phasemask, const G3D::Ray& ray, const Vector3& endPos, float& maxDist) const; - bool getObjectHitPos(uint32 phasemask, const Vector3& pPos1, const Vector3& pPos2, Vector3& pResultHitPos, float pModifyDist) const; + bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, + float z2, uint32 phasemask) const; + + bool getIntersectionTime(uint32 phasemask, const G3D::Ray& ray, + const G3D::Vector3& endPos, float& maxDist) const; + + bool getObjectHitPos(uint32 phasemask, const G3D::Vector3& pPos1, + const G3D::Vector3& pPos2, G3D::Vector3& pResultHitPos, + float pModifyDist) const; + float getHeight(float x, float y, float z, float maxSearchDist, uint32 phasemask) const; void insert(const GameObjectModel&); diff --git a/src/server/collision/Maps/MapTree.h b/src/server/collision/Maps/MapTree.h index c8e9628dff1..5de8e616d2b 100644 --- a/src/server/collision/Maps/MapTree.h +++ b/src/server/collision/Maps/MapTree.h @@ -72,7 +72,7 @@ namespace VMAP bool getObjectHitPos(const G3D::Vector3& pos1, const G3D::Vector3& pos2, G3D::Vector3& pResultHitPos, float pModifyDist) const; float getHeight(const G3D::Vector3& pPos, float maxSearchDist) const; bool getAreaInfo(G3D::Vector3 &pos, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const; - bool GetLocationInfo(const Vector3 &pos, LocationInfo &info) const; + bool GetLocationInfo(const G3D::Vector3 &pos, LocationInfo &info) const; bool InitMap(const std::string &fname, VMapManager2* vm); void UnloadMap(VMapManager2* vm); diff --git a/src/server/collision/Models/WorldModel.h b/src/server/collision/Models/WorldModel.h index ade9efbb040..cea32cfedfb 100644 --- a/src/server/collision/Models/WorldModel.h +++ b/src/server/collision/Models/WorldModel.h @@ -47,11 +47,11 @@ namespace VMAP class WmoLiquid { public: - WmoLiquid(uint32 width, uint32 height, const Vector3 &corner, uint32 type); + WmoLiquid(uint32 width, uint32 height, const G3D::Vector3 &corner, uint32 type); WmoLiquid(const WmoLiquid &other); ~WmoLiquid(); WmoLiquid& operator=(const WmoLiquid &other); - bool GetLiquidHeight(const Vector3 &pos, float &liqHeight) const; + bool GetLiquidHeight(const G3D::Vector3 &pos, float &liqHeight) const; uint32 GetType() const { return iType; } float *GetHeightStorage() { return iHeight; } uint8 *GetFlagsStorage() { return iFlags; } @@ -60,14 +60,14 @@ namespace VMAP static bool readFromFile(FILE* rf, WmoLiquid* &liquid); private: WmoLiquid(): iHeight(0), iFlags(0) {}; - uint32 iTilesX; //!< number of tiles in x direction, each + uint32 iTilesX; //!< number of tiles in x direction, each uint32 iTilesY; - Vector3 iCorner; //!< the lower corner - uint32 iType; //!< liquid type - float *iHeight; //!< (tilesX + 1)*(tilesY + 1) height values - uint8 *iFlags; //!< info if liquid tile is used + G3D::Vector3 iCorner; //!< the lower corner + uint32 iType; //!< liquid type + float *iHeight; //!< (tilesX + 1)*(tilesY + 1) height values + uint8 *iFlags; //!< info if liquid tile is used public: - void getPosInfo(uint32 &tilesX, uint32 &tilesY, Vector3 &corner) const; + void getPosInfo(uint32 &tilesX, uint32 &tilesY, G3D::Vector3 &corner) const; }; /*! holding additional info for WMO group files */ @@ -76,16 +76,16 @@ namespace VMAP public: GroupModel(): iLiquid(0) {} GroupModel(const GroupModel &other); - GroupModel(uint32 mogpFlags, uint32 groupWMOID, const AABox &bound): + GroupModel(uint32 mogpFlags, uint32 groupWMOID, const G3D::AABox &bound): iBound(bound), iMogpFlags(mogpFlags), iGroupWMOID(groupWMOID), iLiquid(0) {} ~GroupModel() { delete iLiquid; } //! pass mesh data to object and create BIH. Passed vectors get get swapped with old geometry! - void setMeshData(std::vector &vert, std::vector &tri); + void setMeshData(std::vector &vert, std::vector &tri); void setLiquidData(WmoLiquid*& liquid) { iLiquid = liquid; liquid = NULL; } bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const; - bool IsInsideObject(const Vector3 &pos, const Vector3 &down, float &z_dist) const; - bool GetLiquidLevel(const Vector3 &pos, float &liqHeight) const; + bool IsInsideObject(const G3D::Vector3 &pos, const G3D::Vector3 &down, float &z_dist) const; + bool GetLiquidLevel(const G3D::Vector3 &pos, float &liqHeight) const; uint32 GetLiquidType() const; bool writeToFile(FILE* wf); bool readFromFile(FILE* rf); @@ -96,12 +96,12 @@ namespace VMAP G3D::AABox iBound; uint32 iMogpFlags;// 0x8 outdor; 0x2000 indoor uint32 iGroupWMOID; - std::vector vertices; + std::vector vertices; std::vector triangles; BIH meshTree; WmoLiquid* iLiquid; public: - void getMeshData(std::vector &vertices, std::vector &triangles, WmoLiquid* &liquid); + void getMeshData(std::vector &vertices, std::vector &triangles, WmoLiquid* &liquid); }; /*! Holds a model (converted M2 or WMO) in its original coordinate space */ class WorldModel diff --git a/src/server/collision/RegularGrid.h b/src/server/collision/RegularGrid.h index f38bf357a19..d1832c1ea06 100644 --- a/src/server/collision/RegularGrid.h +++ b/src/server/collision/RegularGrid.h @@ -3,18 +3,12 @@ #include -#include #include #include #include #include "Errors.h" -using G3D::Vector2; -using G3D::Vector3; -using G3D::AABox; -using G3D::Ray; - template struct NodeCreator{ static Node * makeNode(int /*x*/, int /*y*/) { return new Node();} @@ -54,7 +48,7 @@ public: void insert(const T& value) { - Vector3 pos; + G3D::Vector3 pos; PositionFunc::getPosition(value, pos); Node& node = getGridFor(pos.x, pos.y); node.insert(value); @@ -109,13 +103,13 @@ public: } template - void intersectRay(const Ray& ray, RayCallback& intersectCallback, float max_dist) + void intersectRay(const G3D::Ray& ray, RayCallback& intersectCallback, float max_dist) { intersectRay(ray, intersectCallback, max_dist, ray.origin() + ray.direction() * max_dist); } template - void intersectRay(const Ray& ray, RayCallback& intersectCallback, float& max_dist, const Vector3& end) + void intersectRay(const G3D::Ray& ray, RayCallback& intersectCallback, float& max_dist, const G3D::Vector3& end) { Cell cell = Cell::ComputeCell(ray.origin().x, ray.origin().y); if (!cell.isValid()) @@ -191,7 +185,7 @@ public: } template - void intersectPoint(const Vector3& point, IsectCallback& intersectCallback) + void intersectPoint(const G3D::Vector3& point, IsectCallback& intersectCallback) { Cell cell = Cell::ComputeCell(point.x, point.y); if (!cell.isValid()) @@ -202,7 +196,7 @@ public: // Optimized verson of intersectRay function for rays with vertical directions template - void intersectZAllignedRay(const Ray& ray, RayCallback& intersectCallback, float& max_dist) + void intersectZAllignedRay(const G3D::Ray& ray, RayCallback& intersectCallback, float& max_dist) { Cell cell = Cell::ComputeCell(ray.origin().x, ray.origin().y); if (!cell.isValid()) diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 9e6735efc26..184450ef8d6 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -1920,10 +1920,10 @@ bool Map::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, floa bool Map::getObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist) { - Vector3 startPos = Vector3(x1, y1, z1); - Vector3 dstPos = Vector3(x2, y2, z2); + G3D::Vector3 startPos(x1, y1, z1); + G3D::Vector3 dstPos(x2, y2, z2); - Vector3 resultPos; + G3D::Vector3 resultPos; bool result = _dynamicTree.getObjectHitPos(phasemask, startPos, dstPos, resultPos, modifyDist); rx = resultPos.x; diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp index 7133fc50e9f..801219b2a5a 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp @@ -1,4 +1,5 @@ /* + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.h b/src/server/game/Movement/Spline/MovementPacketBuilder.h index 92a414e9b3b..b502e203656 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.h +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index a42cd2b9bc6..3a87da3d4f1 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -674,14 +674,14 @@ namespace MMAP // transform data float scale = instance.iScale; G3D::Matrix3 rotation = G3D::Matrix3::fromEulerAnglesXYZ(G3D::pi()*instance.iRot.z/-180.f, G3D::pi()*instance.iRot.x/-180.f, G3D::pi()*instance.iRot.y/-180.f); - Vector3 position = instance.iPos; + G3D::Vector3 position = instance.iPos; position.x -= 32*GRID_SIZE; position.y -= 32*GRID_SIZE; for (std::vector::iterator it = groupModels.begin(); it != groupModels.end(); ++it) { - std::vector tempVertices; - std::vector transformedVertices; + std::vector tempVertices; + std::vector transformedVertices; std::vector tempTriangles; WmoLiquid* liquid = NULL; @@ -698,10 +698,10 @@ namespace MMAP // now handle liquid data if (liquid) { - std::vector liqVerts; + std::vector liqVerts; std::vector liqTris; uint32 tilesX, tilesY, vertsX, vertsY; - Vector3 corner; + G3D::Vector3 corner; liquid->getPosInfo(tilesX, tilesY, corner); vertsX = tilesX + 1; vertsY = tilesY + 1; @@ -730,11 +730,11 @@ namespace MMAP // tile = x*tilesY+y // flag = y*tilesY+x - Vector3 vert; + G3D::Vector3 vert; for (uint32 x = 0; x < vertsX; ++x) for (uint32 y = 0; y < vertsY; ++y) { - vert = Vector3(corner.x + x * GRID_PART_SIZE, corner.y + y * GRID_PART_SIZE, data[y*vertsX + x]); + 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; @@ -785,12 +785,12 @@ namespace MMAP } /**************************************************************************/ - void TerrainBuilder::transform(std::vector &source, std::vector &transformedVertices, float scale, G3D::Matrix3 &rotation, Vector3 &position) + void TerrainBuilder::transform(std::vector &source, std::vector &transformedVertices, float scale, G3D::Matrix3 &rotation, G3D::Vector3 &position) { - for (std::vector::iterator it = source.begin(); it != source.end(); ++it) + for (std::vector::iterator it = source.begin(); it != source.end(); ++it) { // apply tranform, then mirror along the horizontal axes - Vector3 v((*it) * rotation * scale + position); + G3D::Vector3 v((*it) * rotation * scale + position); v.x *= -1.f; v.y *= -1.f; transformedVertices.push_back(v); @@ -798,9 +798,9 @@ namespace MMAP } /**************************************************************************/ - void TerrainBuilder::copyVertices(std::vector &source, G3D::Array &dest) + void TerrainBuilder::copyVertices(std::vector &source, G3D::Array &dest) { - for (std::vector::iterator it = source.begin(); it != source.end(); ++it) + for (std::vector::iterator it = source.begin(); it != source.end(); ++it) { dest.push_back((*it).y); dest.push_back((*it).z); diff --git a/src/tools/mmaps_generator/VMapExtensions.cpp b/src/tools/mmaps_generator/VMapExtensions.cpp index 972f222bba6..08929e5259d 100644 --- a/src/tools/mmaps_generator/VMapExtensions.cpp +++ b/src/tools/mmaps_generator/VMapExtensions.cpp @@ -47,7 +47,7 @@ namespace VMAP } // declared in src/shared/vmap/WorldModel.h - void GroupModel::getMeshData(std::vector &vertices, std::vector &triangles, WmoLiquid* &liquid) + void GroupModel::getMeshData(std::vector &vertices, std::vector &triangles, WmoLiquid* &liquid) { vertices = this->vertices; triangles = this->triangles; @@ -61,7 +61,7 @@ namespace VMAP } // declared in src/shared/vmap/WorldModel.h - void WmoLiquid::getPosInfo(uint32 &tilesX, uint32 &tilesY, Vector3 &corner) const + void WmoLiquid::getPosInfo(uint32 &tilesX, uint32 &tilesY, G3D::Vector3 &corner) const { tilesX = iTilesX; tilesY = iTilesY; -- cgit v1.2.3 From b346459ca88a4959c579e51607ef0b5eb8d75b98 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 3 Feb 2013 14:11:59 +0100 Subject: Core: Warning fixes --- src/server/collision/Models/GameObjectModel.cpp | 3 +++ src/server/game/Movement/Spline/MovementPacketBuilder.cpp | 2 +- src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp | 2 +- src/tools/mmaps_generator/MapBuilder.cpp | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/tools') diff --git a/src/server/collision/Models/GameObjectModel.cpp b/src/server/collision/Models/GameObjectModel.cpp index 54283389387..e166a860cd2 100644 --- a/src/server/collision/Models/GameObjectModel.cpp +++ b/src/server/collision/Models/GameObjectModel.cpp @@ -48,7 +48,10 @@ ModelList model_list; void LoadGameObjectModelList() { +#ifndef NO_CORE_FUNCS uint32 oldMSTime = getMSTime(); +#endif + FILE* model_list_file = fopen((sWorld->GetDataPath() + "vmaps/" + VMAP::GAMEOBJECT_MODELS).c_str(), "rb"); if (!model_list_file) { diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp index 801219b2a5a..29d1bb50a8f 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp @@ -146,7 +146,7 @@ namespace Movement //data.append(&mov.m_float_values[SpeedWalk], SpeedMaxCount); //if (mov.SplineEnabled()) { - MoveSplineFlag splineFlags = move_spline.splineflags; + MoveSplineFlag const& splineFlags = move_spline.splineflags; data << splineFlags.raw(); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index aa65cfda97e..1d340e61b61 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -298,7 +298,7 @@ class boss_lord_marrowgar : public CreatureScript case DATA_SPIKE_IMMUNE + 1: case DATA_SPIKE_IMMUNE + 2: { - int32 index = type - DATA_SPIKE_IMMUNE; + uint32 index = uint32(type - DATA_SPIKE_IMMUNE); if (index < _boneSpikeImmune.size()) return _boneSpikeImmune[index]; diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 4a016f267b4..cd85d926125 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -957,7 +957,7 @@ namespace MMAP if (count != 1) return false; - if (header.mmapMagic != MMAP_MAGIC || header.dtVersion != DT_NAVMESH_VERSION) + if (header.mmapMagic != MMAP_MAGIC || header.dtVersion != uint32(DT_NAVMESH_VERSION)) return false; if (header.mmapVersion != MMAP_VERSION) -- cgit v1.2.3