[Tools] Extraction Project Sync

This commit is contained in:
Antz 2016-10-12 00:19:27 +01:00 committed by Antz
parent 94916ef635
commit 95f98ca7a5
23 changed files with 1288 additions and 693 deletions

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -62,15 +62,15 @@ namespace MMAP
} while (false)
if (heightfield)
DEBUG_WRITE("hf", heightfield);
{ DEBUG_WRITE("hf", heightfield); }
if (compactHeightfield)
DEBUG_WRITE("chf", compactHeightfield);
{ DEBUG_WRITE("chf", compactHeightfield); }
if (contours)
DEBUG_WRITE("cs", contours);
{ DEBUG_WRITE("cs", contours); }
if (polyMesh)
DEBUG_WRITE("pmesh", polyMesh);
{ DEBUG_WRITE("pmesh", polyMesh); }
if (polyMeshDetail)
DEBUG_WRITE("dmesh", polyMeshDetail);
{ DEBUG_WRITE("dmesh", polyMeshDetail); }
#undef DEBUG_WRITE
}
@ -78,7 +78,7 @@ namespace MMAP
void IntermediateValues::debugWrite(FILE* file, const rcHeightfield* mesh)
{
if (!file || !mesh)
return;
{ return; }
fwrite(&(mesh->cs), sizeof(float), 1, file);
fwrite(&(mesh->ch), sizeof(float), 1, file);
@ -116,7 +116,7 @@ namespace MMAP
void IntermediateValues::debugWrite(FILE* file, const rcCompactHeightfield* chf)
{
if (!file | !chf)
return;
{ return; }
fwrite(&(chf->width), sizeof(chf->width), 1, file);
fwrite(&(chf->height), sizeof(chf->height), 1, file);
@ -135,27 +135,27 @@ namespace MMAP
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;
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);
{ fwrite(chf->cells, sizeof(rcCompactCell), chf->width * chf->height, file); }
if (chf->spans)
fwrite(chf->spans, sizeof(rcCompactSpan), chf->spanCount, file);
{ fwrite(chf->spans, sizeof(rcCompactSpan), chf->spanCount, file); }
if (chf->dist)
fwrite(chf->dist, sizeof(unsigned short), chf->spanCount, file);
{ fwrite(chf->dist, sizeof(unsigned short), chf->spanCount, file); }
if (chf->areas)
fwrite(chf->areas, sizeof(unsigned char), chf->spanCount, file);
{ fwrite(chf->areas, sizeof(unsigned char), chf->spanCount, file); }
}
void IntermediateValues::debugWrite(FILE* file, const rcContourSet* cs)
{
if (!file || !cs)
return;
{ return; }
fwrite(&(cs->cs), sizeof(float), 1, file);
fwrite(&(cs->ch), sizeof(float), 1, file);
@ -176,7 +176,7 @@ namespace MMAP
void IntermediateValues::debugWrite(FILE* file, const rcPolyMesh* mesh)
{
if (!file || !mesh)
return;
{ return; }
fwrite(&(mesh->cs), sizeof(float), 1, file);
fwrite(&(mesh->ch), sizeof(float), 1, file);
@ -195,7 +195,7 @@ namespace MMAP
void IntermediateValues::debugWrite(FILE* file, const rcPolyMeshDetail* mesh)
{
if (!file || !mesh)
return;
{ return; }
fwrite(&(mesh->nverts), sizeof(int), 1, file);
fwrite(mesh->verts, sizeof(float), mesh->nverts * 3, file);
@ -233,10 +233,10 @@ namespace MMAP
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]);
{ 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);
{ fprintf(objFile, "f %i %i %i\n", tris[i * 3] + 1, tris[i * 3 + 1] + 1, tris[i * 3 + 2] + 1); }
fclose(objFile);

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -22,38 +22,94 @@
* and lore are copyrighted by Blizzard Entertainment, Inc.
*/
#ifndef _INTERMEDIATE_VALUES_H
#define _INTERMEDIATE_VALUES_H
#ifndef MANGOS_H_INTERMEDIATE_VALUES
#define MANGOS_H_INTERMEDIATE_VALUES
#include <Recast.h>
#include <DetourNavMesh.h>
#include "MMapCommon.h"
#include "TerrainBuilder.h"
#include "Recast.h"
#include "DetourNavMesh.h"
namespace MMAP
{
// this class gathers all debug info holding and output
/**
* @brief this class gathers all debug info holding and output
*
*/
struct IntermediateValues
{
rcHeightfield* heightfield;
rcCompactHeightfield* compactHeightfield;
rcContourSet* contours;
rcPolyMesh* polyMesh;
rcPolyMeshDetail* polyMeshDetail;
rcHeightfield* heightfield; /**< TODO */
rcCompactHeightfield* compactHeightfield; /**< TODO */
rcContourSet* contours; /**< TODO */
rcPolyMesh* polyMesh; /**< TODO */
rcPolyMeshDetail* polyMeshDetail; /**< TODO */
/**
* @brief
*
*/
IntermediateValues() : compactHeightfield(NULL), heightfield(NULL),
contours(NULL), polyMesh(NULL), polyMeshDetail(NULL) {}
/**
* @brief
*
*/
~IntermediateValues();
/**
* @brief
*
* @param mapID
* @param tileX
* @param tileY
*/
void writeIV(uint32 mapID, uint32 tileX, uint32 tileY);
/**
* @brief
*
* @param file
* @param mesh
*/
void debugWrite(FILE* file, const rcHeightfield* mesh);
/**
* @brief
*
* @param file
* @param chf
*/
void debugWrite(FILE* file, const rcCompactHeightfield* chf);
/**
* @brief
*
* @param file
* @param cs
*/
void debugWrite(FILE* file, const rcContourSet* cs);
/**
* @brief
*
* @param file
* @param mesh
*/
void debugWrite(FILE* file, const rcPolyMesh* mesh);
/**
* @brief
*
* @param file
* @param mesh
*/
void debugWrite(FILE* file, const rcPolyMeshDetail* mesh);
/**
* @brief
*
* @param mapID
* @param tileX
* @param tileY
* @param meshData
*/
void generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData);
};
}

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -22,8 +22,8 @@
* and lore are copyrighted by Blizzard Entertainment, Inc.
*/
#ifndef _MMAP_COMMON_H
#define _MMAP_COMMON_H
#ifndef MANGOS_H_MMAP_COMMON
#define MANGOS_H_MMAP_COMMON
// stop warning spam from ACE includes
#ifdef WIN32
@ -44,10 +44,17 @@ using namespace std;
namespace MMAP
{
/**
* @brief
*
* @param filter
* @param str
* @return bool
*/
inline bool matchWildcardFilter(const char* filter, const char* str)
{
if (!filter || !str)
return false;
{ return false; }
// end on null character
while (*filter && *str)
@ -55,19 +62,19 @@ namespace MMAP
if (*filter == '*')
{
if (*++filter == '\0') // wildcard at end of filter means all remaing chars match
return true;
{ return true; }
while (true)
{
if (*filter == *str)
break;
{ break; }
if (*str == '\0')
return false; // reached end of string without matching next filter character
{ return false; } // reached end of string without matching next filter character
str++;
}
}
else if (*filter != *str)
return false; // mismatch
{ return false; } // mismatch
filter++;
str++;
@ -76,12 +83,25 @@ namespace MMAP
return ((*filter == '\0' || (*filter == '*' && *++filter == '\0')) && *str == '\0');
}
/**
* @brief
*
*/
enum ListFilesResult
{
LISTFILE_DIRECTORY_NOT_FOUND = 0,
LISTFILE_OK = 1
};
/**
* @brief
*
* @param fileList
* @param dirpath
* @param filter
* @param includeSubDirs
* @return ListFilesResult
*/
inline ListFilesResult getDirContents(vector<string>& fileList, string dirpath = ".", string filter = "*", bool includeSubDirs = false)
{
#ifdef WIN32
@ -94,12 +114,12 @@ namespace MMAP
hFind = FindFirstFile(directory.c_str(), &findFileInfo);
if (hFind == INVALID_HANDLE_VALUE)
return LISTFILE_DIRECTORY_NOT_FOUND;
{ return LISTFILE_DIRECTORY_NOT_FOUND; }
do
{
if (includeSubDirs || (findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
fileList.push_back(string(findFileInfo.cFileName));
{ fileList.push_back(string(findFileInfo.cFileName)); }
}
while (FindNextFile(hFind, &findFileInfo));
@ -116,16 +136,16 @@ 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(string(dp->d_name)); }
}
else
break;
{ break; }
}
if (dirp)
closedir(dirp);
{ closedir(dirp); }
else
return LISTFILE_DIRECTORY_NOT_FOUND;
{ return LISTFILE_DIRECTORY_NOT_FOUND; }
#endif
return LISTFILE_OK;

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -22,25 +22,29 @@
* and lore are copyrighted by Blizzard Entertainment, Inc.
*/
#ifndef _MMAP_MANGOS_MAP_H
#define _MMAP_MANGOS_MAP_H
#ifndef MANGOS_H_MMAP_MANGOS_MAP
#define MANGOS_H_MMAP_MANGOS_MAP
// following is copied from src/game/GridMap.h (too many useless includes there to use original file)
namespace MaNGOS
{
/**
* @brief
*
*/
struct GridMapFileHeader
{
uint32 mapMagic;
uint32 versionMagic;
uint32 mapMagic; /**< TODO */
uint32 versionMagic; /**< TODO */
uint32 buildMagic;
uint32 areaMapOffset;
uint32 areaMapSize;
uint32 heightMapOffset;
uint32 heightMapSize;
uint32 liquidMapOffset;
uint32 liquidMapSize;
uint32 holesOffset;
uint32 holesSize;
uint32 areaMapOffset; /**< TODO */
uint32 areaMapSize; /**< TODO */
uint32 heightMapOffset; /**< TODO */
uint32 heightMapSize; /**< TODO */
uint32 liquidMapOffset; /**< TODO */
uint32 liquidMapSize; /**< TODO */
uint32 holesOffset; /**< TODO */
uint32 holesSize; /**< TODO */
};
// ==============mmaps don't use area==============
@ -57,27 +61,35 @@ namespace MaNGOS
#define MAP_HEIGHT_AS_INT16 0x0002
#define MAP_HEIGHT_AS_INT8 0x0004
/**
* @brief
*
*/
struct GridMapHeightHeader
{
uint32 fourcc;
uint32 flags;
float gridHeight;
float gridMaxHeight;
uint32 fourcc; /**< TODO */
uint32 flags; /**< TODO */
float gridHeight; /**< TODO */
float gridMaxHeight; /**< TODO */
};
#define MAP_LIQUID_NO_TYPE 0x0001
#define MAP_LIQUID_NO_HEIGHT 0x0002
/**
* @brief
*
*/
struct GridMapLiquidHeader
{
uint32 fourcc;
uint16 flags;
uint16 liquidType;
uint8 offsetX;
uint8 offsetY;
uint8 width;
uint8 height;
float liquidLevel;
uint32 fourcc; /**< TODO */
uint16 flags; /**< TODO */
uint16 liquidType; /**< TODO */
uint8 offsetX; /**< TODO */
uint8 offsetY; /**< TODO */
uint8 width; /**< TODO */
uint8 height; /**< TODO */
float liquidLevel; /**< TODO */
};
//enum GridMapLiquidStatus

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -95,10 +95,10 @@ namespace MMAP
m_tiles.insert(pair<uint32, set<uint32>*>(mapID, new set<uint32>));
count++;
}
printf("found %u.\n", count);
printf(" found %u.\n", count);
count = 0;
printf("Discovering tiles... ");
printf(" Discovering tiles... ");
for (TileList::iterator itr = m_tiles.begin(); itr != m_tiles.end(); ++itr)
{
set<uint32>* tiles = (*itr).second;
@ -130,7 +130,7 @@ namespace MMAP
{ count++; }
}
}
printf("found %u.\n\n", count);
printf(" found %u.\n\n", count);
}
/**************************************************************************/
@ -156,49 +156,6 @@ namespace MMAP
}
}
/**************************************************************************/
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] = { 0 };
float bmax[3] = { 0 };
float lmin[3] = { 0 };
float lmax[3] = { 0 };
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)
{
@ -265,7 +222,6 @@ namespace MMAP
printf("Complete! \n\n");
}
/**************************************************************************/
void MapBuilder::buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh)
{
@ -305,6 +261,49 @@ namespace MMAP
buildMoveMapTile(mapID, tileX, tileY, meshData, bmin, bmax, navMesh);
}
/**************************************************************************/
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] = { 0 };
float bmax[3] = { 0 };
float lmin[3] = { 0 };
float lmax[3] = { 0 };
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::buildNavMesh(uint32 mapID, dtNavMesh*& navMesh)
{
@ -471,7 +470,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;
}
@ -492,33 +491,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;
}
@ -526,14 +525,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;
}
@ -553,7 +552,7 @@ 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 FAILED! \n", tileString);
delete [] tiles;
return;
}
@ -561,7 +560,7 @@ namespace MMAP
rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP];
if (!dmmerge)
{
printf("%s alloc dmmerge FIALED! \r", tileString);
printf("%s alloc dmmerge FAILED! \n", tileString);
delete [] tiles;
return;
}
@ -584,7 +583,7 @@ namespace MMAP
iv.polyMesh = rcAllocPolyMesh();
if (!iv.polyMesh)
{
printf("%s alloc iv.polyMesh FAILED! \r", tileString);
printf("%s alloc iv.polyMesh FAILED! \n", tileString);
delete [] tiles;
return;
}
@ -593,7 +592,7 @@ namespace MMAP
iv.polyMeshDetail = rcAllocPolyMeshDetail();
if (!iv.polyMeshDetail)
{
printf("%s alloc m_dmesh FAILED! \r", tileString);
printf("%s alloc m_dmesh FAILED! \n", tileString);
delete [] tiles;
return;
}
@ -687,30 +686,28 @@ namespace MMAP
// 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);
printf(" No polygons to build on tile - %s \n", tileString);
continue;
}
if (!params.detailMeshes || !params.detailVerts || !params.detailTris)
{
printf("%s No detail mesh to build tile! \n", tileString);
printf(" No detail mesh to build tile - %s \n", tileString);
continue;
}
printf("%s Building navmesh tile... \r", tileString);
if (!dtCreateNavMeshData(&params, &navData, &navDataSize))
{
printf("%s Failed building navmesh tile! \n", tileString);
printf(" Failed building navmesh tile - %s \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 || dtStatusFailed(dtResult))
{
printf("%s Failed adding tile to navmesh! \n", tileString);
printf(" Failed adding tile %s to navmesh ! \n", tileString);
continue;
}
@ -727,8 +724,6 @@ namespace MMAP
continue;
}
printf("%s Writing to file... \r", tileString);
// write header
MmapTileHeader header;
header.usesLiquids = m_terrainBuilder->usesLiquids();

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -22,21 +22,22 @@
* and lore are copyrighted by Blizzard Entertainment, Inc.
*/
#ifndef _MAP_BUILDER_H
#define _MAP_BUILDER_H
#ifndef MANGOS_H_MAP_BUILDER
#define MANGOS_H_MAP_BUILDER
#include <vector>
#include <set>
#include <map>
#include <Recast.h>
#include <DetourNavMesh.h>
#include "TerrainBuilder.h"
#include "IntermediateValues.h"
#include "IVMapManager.h"
#include "WorldModel.h"
#include "Recast.h"
#include "DetourNavMesh.h"
using namespace std;
using namespace VMAP;
@ -44,10 +45,26 @@ using namespace VMAP;
namespace MMAP
{
/**
* @brief
*
*/
typedef map<uint32, set<uint32>*> TileList;
/**
* @brief
*
*/
struct Tile
{
/**
* @brief
*
*/
Tile() : chf(NULL), solid(NULL), cset(NULL), pmesh(NULL), dmesh(NULL) {}
/**
* @brief
*
*/
~Tile()
{
rcFreeCompactHeightfield(chf);
@ -56,16 +73,32 @@ namespace MMAP
rcFreePolyMesh(pmesh);
rcFreePolyMeshDetail(dmesh);
}
rcCompactHeightfield* chf;
rcHeightfield* solid;
rcContourSet* cset;
rcPolyMesh* pmesh;
rcPolyMeshDetail* dmesh;
rcCompactHeightfield* chf; /**< TODO */
rcHeightfield* solid; /**< TODO */
rcContourSet* cset; /**< TODO */
rcPolyMesh* pmesh; /**< TODO */
rcPolyMeshDetail* dmesh; /**< TODO */
};
/**
* @brief
*
*/
class MapBuilder
{
public:
/**
* @brief
*
* @param maxWalkableAngle
* @param skipLiquid
* @param skipContinents
* @param skipJunkMaps
* @param skipBattlegrounds
* @param debugOutput
* @param bigBaseUnit
* @param offMeshFilePath
*/
MapBuilder(float maxWalkableAngle = 60.f,
bool skipLiquid = false,
bool skipContinents = false,
@ -75,27 +108,77 @@ namespace MMAP
bool bigBaseUnit = false,
const char* offMeshFilePath = NULL);
/**
* @brief
*
*/
~MapBuilder();
// builds all mmap tiles for the specified map id (ignores skip settings)
/**
* @brief builds all mmap tiles for the specified map id (ignores skip settings)
*
* @param mapID
*/
void buildMap(uint32 mapID);
// builds an mmap tile for the specified map and its mesh
/**
* @brief builds an mmap tile for the specified map and its mesh
*
* @param mapID
* @param tileX
* @param tileY
*/
void buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY);
// builds list of maps, then builds all of mmap tiles (based on the skip settings)
/**
* @brief 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<uint32>* getTileList(uint32 mapID);
void buildNavMesh(uint32 mapID, dtNavMesh*& navMesh);
/**
* @brief
*
* @param mapID
* @param tileX
* @param tileY
* @param navMesh
*/
void buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh);
// move map building
private:
/**
* @brief detect maps and tiles
*
*/
void discoverTiles();
/**
* @brief
*
* @param mapID
* @return set<uint32>
*/
set<uint32>* getTileList(uint32 mapID);
/**
* @brief
*
* @param mapID
* @param navMesh
*/
void buildNavMesh(uint32 mapID, dtNavMesh*& navMesh);
/**
* @brief move map building
*
* @param mapID
* @param tileX
* @param tileY
* @param meshData
* @param bmin[]
* @param bmax[]
* @param navMesh
*/
void buildMoveMapTile(uint32 mapID,
uint32 tileX,
uint32 tileY,
@ -104,30 +187,57 @@ namespace MMAP
float bmax[3],
dtNavMesh* navMesh);
/**
* @brief
*
* @param tileX
* @param tileY
* @param verts
* @param vertCount
* @param bmin
* @param bmax
*/
void getTileBounds(uint32 tileX, uint32 tileY,
float* verts, int vertCount,
float* bmin, float* bmax);
/**
* @brief
*
* @param mapID
* @param minX
* @param minY
* @param maxX
* @param maxY
*/
void getGridBounds(uint32 mapID, uint32& minX, uint32& minY, uint32& maxX, uint32& maxY);
bool shouldSkipMap(uint32 mapID);
bool isTransportMap(uint32 mapID);
/**
* @brief
*
* @param mapID
* @param tileX
* @param tileY
* @return bool
*/
bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY);
TerrainBuilder* m_terrainBuilder;
TileList m_tiles;
TerrainBuilder* m_terrainBuilder; /**< TODO */
TileList m_tiles; /**< TODO */
bool m_debugOutput;
bool m_debugOutput; /**< TODO */
const char* m_offMeshFilePath;
bool m_skipContinents;
bool m_skipJunkMaps;
bool m_skipBattlegrounds;
const char* m_offMeshFilePath; /**< TODO */
bool m_skipContinents; /**< TODO */
bool m_skipJunkMaps; /**< TODO */
bool m_skipBattlegrounds; /**< TODO */
float m_maxWalkableAngle;
bool m_bigBaseUnit;
float m_maxWalkableAngle; /**< TODO */
bool m_bigBaseUnit; /**< TODO */
// build performance - not really used for now
rcContext* m_rcContext;
rcContext* m_rcContext; /**< build performance - not really used for now */
};
}

View file

@ -90,7 +90,7 @@ namespace MMAP
FILE* mapFile = fopen(mapFileName, "rb");
if (!mapFile)
return false;
{ return false; }
GridMapFileHeader fheader;
fread(&fheader, sizeof(GridMapFileHeader), 1, mapFile);
@ -140,10 +140,10 @@ namespace MMAP
heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 255;
for (i = 0; i < V9_SIZE_SQ; ++i)
V9[i] = (float)v9[i] * heightMultiplier + hheader.gridHeight;
{ V9[i] = (float)v9[i] * heightMultiplier + hheader.gridHeight; }
for (i = 0; i < V8_SIZE_SQ; ++i)
V8[i] = (float)v8[i] * heightMultiplier + hheader.gridHeight;
{ V8[i] = (float)v8[i] * heightMultiplier + hheader.gridHeight; }
}
else if (hheader.flags & MAP_HEIGHT_AS_INT16)
{
@ -154,10 +154,10 @@ namespace MMAP
heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 65535;
for (i = 0; i < V9_SIZE_SQ; ++i)
V9[i] = (float)v9[i] * heightMultiplier + hheader.gridHeight;
{ V9[i] = (float)v9[i] * heightMultiplier + hheader.gridHeight; }
for (i = 0; i < V8_SIZE_SQ; ++i)
V8[i] = (float)v8[i] * heightMultiplier + hheader.gridHeight;
{ V8[i] = (float)v8[i] * heightMultiplier + hheader.gridHeight; }
}
else
{
@ -241,7 +241,7 @@ namespace MMAP
col = i % V9_SIZE;
if (row < lheader.offsetY || row >= lheader.offsetY + lheader.height ||
col < lheader.offsetX || col >= lheader.offsetX + lheader.width)
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);
@ -297,7 +297,7 @@ namespace MMAP
int* ttris = ttriangles.getCArray();
if (ltriangles.size() + ttriangles.size() == 0)
return false;
{ return false; }
// make a copy of liquid vertices
// used to pad right-bottom frame due to lost vertex data at extraction
@ -320,7 +320,7 @@ namespace MMAP
// if there is no liquid, don't use liquid
if (!liquid_type || !meshData.liquidVerts.size() || !ltriangles.size())
useLiquid = false;
{ useLiquid = false; }
else
{
liquidType = getLiquidType(i, liquid_type);
@ -350,7 +350,7 @@ namespace MMAP
// if there is no terrain, don't use terrain
if (!ttriangles.size())
useTerrain = false;
{ useTerrain = false; }
// while extracting ADT data we are losing right-bottom vertices
// this code adds fair approximation of lost data
@ -376,18 +376,18 @@ namespace MMAP
{
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;
{ lverts[ltris[idx] * 3 + 1] = quadHeight; }
}
}
// no valid vertexes - don't use this poly at all
if (validCount == 0)
useLiquid = false;
{ useLiquid = false; }
}
// if there is a hole here, don't use the terrain
if (useTerrain)
useTerrain = !isHole(i, holes);
{ useTerrain = !isHole(i, holes); }
// we use only one terrain kind per quad - pick higher one
if (useTerrain && useLiquid)
@ -398,10 +398,10 @@ namespace MMAP
{
float h = lverts[ltris[x] * 3 + 1];
if (minLLevel > h)
minLLevel = h;
{ minLLevel = h; }
if (maxLLevel < h)
maxLLevel = h;
{ maxLLevel = h; }
}
float maxTLevel = INVALID_MAP_LIQ_HEIGHT;
@ -410,19 +410,19 @@ namespace MMAP
{
float h = tverts[ttris[x] * 3 + 1];
if (maxTLevel < h)
maxTLevel = h;
{ maxTLevel = h; }
if (minTLevel > h)
minTLevel = h;
{ minTLevel = h; }
}
// terrain under the liquid?
if (minLLevel > maxTLevel)
useTerrain = false;
{ useTerrain = false; }
//liquid under the terrain?
if (minTLevel > maxLLevel)
useLiquid = false;
{ useLiquid = false; }
}
// store the result
@ -430,12 +430,12 @@ namespace MMAP
{
meshData.liquidType.append(liquidType);
for (int k = 0; k < 3; ++k)
meshData.liquidTris.append(ltris[k]);
{ meshData.liquidTris.append(ltris[k]); }
}
if (useTerrain)
for (int k = 0; k < 3 * tTriCount / 2; ++k)
meshData.solidTris.append(ttris[k]);
{ meshData.solidTris.append(ttris[k]); }
// advance to next set of triangles
ltris += 3;
@ -444,7 +444,7 @@ namespace MMAP
}
if (lverts_copy)
delete [] lverts_copy;
{ delete [] lverts_copy; }
return meshData.solidTris.size() || meshData.liquidTris.size();
}
@ -566,20 +566,20 @@ namespace MMAP
do
{
if (result == VMAP_LOAD_RESULT_ERROR)
break;
{ break; }
InstanceTreeMap instanceTrees;
((VMapManager2*)vmapManager)->getInstanceMapTree(instanceTrees);
if (!instanceTrees[mapID])
break;
{ break; }
ModelInstance* models = NULL;
uint32 count = 0;
instanceTrees[mapID]->getModelInstances(models, count);
if (!models)
break;
{ break; }
for (uint32 i = 0; i < count; ++i)
{
@ -588,7 +588,7 @@ namespace MMAP
// model instances exist in tree even though there are instances of that model in this tile
WorldModel* worldModel = instance.getWorldModel();
if (!worldModel)
continue;
{ continue; }
// now we have a model to add to the meshdata
retval = true;
@ -600,7 +600,7 @@ namespace MMAP
bool isM2 = instance.name.find(".m2") != instance.name.npos || instance.name.find(".M2") != instance.name.npos;
// transform data
float Scale = instance.iScale;
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;
@ -616,7 +616,7 @@ namespace MMAP
(*it).getMeshData(tempVertices, tempTriangles, liquid);
// first handle collision mesh
transform(tempVertices, transformedVertices, Scale, rotation, position);
transform(tempVertices, transformedVertices, scale, rotation, position);
int offset = meshData.solidVerts.size() / 3;
@ -663,7 +663,7 @@ namespace MMAP
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 = vert * rotation * scale + position;
vert.x *= -1.f;
vert.y *= -1.f;
liqVerts.push_back(vert);
@ -693,7 +693,7 @@ namespace MMAP
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);
{ meshData.liquidVerts.append(liqVerts[i].y, liqVerts[i].z, liqVerts[i].x); }
for (uint32 i = 0; i < liqTris.size() / 3; ++i)
{
@ -713,12 +713,12 @@ namespace MMAP
}
/**************************************************************************/
void TerrainBuilder::transform(vector<Vector3>& source, vector<Vector3>& transformedVertices, float Scale, G3D::Matrix3& rotation, Vector3& position)
void TerrainBuilder::transform(vector<Vector3>& source, vector<Vector3>& transformedVertices, float scale, G3D::Matrix3& rotation, Vector3& position)
{
for (vector<Vector3>::iterator it = source.begin(); it != source.end(); ++it)
{
// apply tranform, then mirror along the horizontal axes
Vector3 v((*it) * rotation * Scale + position);
Vector3 v((*it) * rotation * scale + position);
v.x *= -1.f;
v.y *= -1.f;
transformedVertices.push_back(v);
@ -764,7 +764,7 @@ namespace MMAP
{
int* src = source.getCArray();
for (int32 i = 0; i < source.size(); ++i)
dest.append(src[i] + offset);
{ dest.append(src[i] + offset); }
}
/**************************************************************************/
@ -779,7 +779,7 @@ namespace MMAP
for (int i = 0; i < tris.size(); ++i)
{
if (vertMap.find(t[i]) != vertMap.end())
continue;
{ continue; }
vertMap.insert(std::pair<int, int>(t[i], 0));
}
@ -803,7 +803,7 @@ namespace MMAP
{
map<int, int>::iterator it;
if ((it = vertMap.find(t[i])) == vertMap.end())
continue;
{ continue; }
t[i] = (*it).second;
}
@ -816,7 +816,7 @@ namespace MMAP
{
// no meshfile input given?
if (offMeshFilePath == NULL)
return;
{ return; }
FILE* fp = fopen(offMeshFilePath, "rb");
if (!fp)
@ -835,9 +835,9 @@ namespace MMAP
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;
{ 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]);

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -22,8 +22,8 @@
* and lore are copyrighted by Blizzard Entertainment, Inc.
*/
#ifndef _MMAP_TERRAIN_BUILDER_H
#define _MMAP_TERRAIN_BUILDER_H
#ifndef MANGOS_H_MMAP_TERRAIN_BUILDER
#define MANGOS_H_MMAP_TERRAIN_BUILDER
#include "MMapCommon.h"
#include "MangosMap.h"
@ -39,6 +39,10 @@ using namespace MaNGOS;
namespace MMAP
{
/**
* @brief
*
*/
enum Spot
{
TOP = 1,
@ -48,94 +52,250 @@ namespace MMAP
ENTIRE = 5
};
/**
* @brief
*
*/
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;
static const int V9_SIZE = 129; /**< TODO */
static const int V9_SIZE_SQ = V9_SIZE* V9_SIZE; /**< TODO */
static const int V8_SIZE = 128; /**< TODO */
static const int V8_SIZE_SQ = V8_SIZE* V8_SIZE; /**< TODO */
static const float GRID_SIZE = 533.33333f; /**< TODO */
static const float GRID_PART_SIZE = GRID_SIZE / V8_SIZE; /**< TODO */
// 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;
static const float INVALID_MAP_LIQ_HEIGHT = -500.f; /**< TODO */
static const float INVALID_MAP_LIQ_HEIGHT_MAX = 5000.0f; /**< TODO */
// see following files:
// contrib/extractor/system.cpp
// src/tools/map-extractor/system.cpp
// src/game/GridMap.cpp
static char const* MAP_VERSION_MAGIC = "c1.4";
/**
* @brief
*
*/
struct MeshData
{
G3D::Array<float> solidVerts;
G3D::Array<int> solidTris;
G3D::Array<float> solidVerts; /**< TODO */
G3D::Array<int> solidTris; /**< TODO */
G3D::Array<float> liquidVerts;
G3D::Array<int> liquidTris;
G3D::Array<uint8> liquidType;
G3D::Array<float> liquidVerts; /**< TODO */
G3D::Array<int> liquidTris; /**< TODO */
G3D::Array<uint8> liquidType; /**< TODO */
// offmesh connection data
G3D::Array<float> offMeshConnections; // [p0y,p0z,p0x,p1y,p1z,p1x] - per connection
G3D::Array<float> offMeshConnectionRads;
G3D::Array<unsigned char> offMeshConnectionDirs;
G3D::Array<unsigned char> offMeshConnectionsAreas;
G3D::Array<unsigned short> offMeshConnectionsFlags;
G3D::Array<float> offMeshConnections; // [p0y,p0z,p0x,p1y,p1z,p1x] - per connection /**< TODO */
G3D::Array<float> offMeshConnectionRads; /**< TODO */
G3D::Array<unsigned char> offMeshConnectionDirs; /**< TODO */
G3D::Array<unsigned char> offMeshConnectionsAreas; /**< TODO */
G3D::Array<unsigned short> offMeshConnectionsFlags; /**< TODO */
};
/**
* @brief
*
*/
class TerrainBuilder
{
public:
/**
* @brief
*
* @param skipLiquid
*/
TerrainBuilder(bool skipLiquid);
/**
* @brief
*
*/
~TerrainBuilder();
/**
* @brief
*
* @param mapID
* @param tileX
* @param tileY
* @param meshData
*/
void loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData);
/**
* @brief
*
* @param mapID
* @param tileX
* @param tileY
* @param meshData
* @return bool
*/
bool loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData);
/**
* @brief
*
* @param mapID
* @param tileX
* @param tileY
* @param meshData
* @param offMeshFilePath
*/
void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData, const char* offMeshFilePath);
/**
* @brief
*
* @return bool
*/
bool usesLiquids() { return !m_skipLiquid; }
// vert and triangle methods
/**
* @brief vert and triangle methods
*
* @param original
* @param transformed
* @param scale
* @param rotation
* @param position
*/
static void transform(vector<G3D::Vector3>& original, vector<G3D::Vector3>& transformed,
float Scale, G3D::Matrix3& rotation, G3D::Vector3& position);
float scale, G3D::Matrix3& rotation, G3D::Vector3& position);
/**
* @brief
*
* @param source
* @param dest
*/
static void copyVertices(vector<G3D::Vector3>& source, G3D::Array<float>& dest);
/**
* @brief
*
* @param source
* @param dest
* @param offest
* @param flip
*/
static void copyIndices(vector<VMAP::MeshTriangle>& source, G3D::Array<int>& dest, int offest, bool flip);
/**
* @brief
*
* @param src
* @param dest
* @param offset
*/
static void copyIndices(G3D::Array<int>& src, G3D::Array<int>& dest, int offset);
/**
* @brief
*
* @param verts
* @param tris
*/
static void cleanVertices(G3D::Array<float>& verts, G3D::Array<int>& tris);
private:
/// Loads a portion of a map's terrain
/**
* @brief Loads a portion of a map's terrain
*
* @param mapID
* @param tileX
* @param tileY
* @param meshData
* @param portion
* @return bool
*/
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
/**
* @brief Sets loop variables for selecting only certain parts of a map's terrain
*
* @param portion
* @param loopStart
* @param loopEnd
* @param loopInc
*/
void getLoopVars(Spot portion, int& loopStart, int& loopEnd, int& loopInc);
/// Controls whether liquids are loaded
bool m_skipLiquid;
bool m_skipLiquid; /**< Controls whether liquids are loaded */
/// Load the map terrain from file
/**
* @brief Load the map terrain from file
*
* @param mapID
* @param tileX
* @param tileY
* @param vertices
* @param triangles
* @param portion
* @return bool
*/
bool loadHeightMap(uint32 mapID, uint32 tileX, uint32 tileY, G3D::Array<float>& vertices, G3D::Array<int>& triangles, Spot portion);
/// Get the vector coordinate for a specific position
/**
* @brief Get the vector coordinate for a specific position
*
* @param index
* @param grid
* @param xOffset
* @param yOffset
* @param coord
* @param v
*/
void getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v);
/// Get the triangle's vector indices for a specific position
/**
* @brief Get the triangle's vector indices for a specific position
*
* @param square
* @param triangle
* @param indices
* @param liquid
*/
void getHeightTriangle(int square, Spot triangle, int* indices, bool liquid = false);
/// Determines if the specific position's triangles should be rendered
/**
* @brief Determines if the specific position's triangles should be rendered
*
* @param square
* @param holes[][]
* @return bool
*/
bool isHole(int square, const uint16 holes[16][16]);
/// Get the liquid vector coordinate for a specific position
/**
* @brief Get the liquid vector coordinate for a specific position
*
* @param index
* @param index2
* @param xOffset
* @param yOffset
* @param coord
* @param v
*/
void getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v);
/// Get the liquid type for a specific position
/**
* @brief Get the liquid type for a specific position
*
* @param square
* @param liquid_type[][]
* @return uint8
*/
uint8 getLiquidType(int square, const uint8 liquid_type[16][16]);
// hide parameterless and copy constructor
/**
* @brief hide parameterless constructor
*
*/
TerrainBuilder();
/**
* @brief hide copy constructor
*
* @param tb
*/
TerrainBuilder(const TerrainBuilder& tb);
};
}

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -33,14 +33,14 @@ bool checkDirectories(bool debugOutput)
if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size())
{
printf("'maps' directory is empty or does not exist\n");
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");
printf(" 'vmaps' directory is empty or does not exist\n");
return false;
}
@ -56,7 +56,7 @@ bool checkDirectories(bool debugOutput)
{
if (getDirContents(dirFiles, "meshes") == LISTFILE_DIRECTORY_NOT_FOUND)
{
printf("'meshes' directory does not exist (no place to put debugOutput files)\n");
printf(" 'meshes' directory does not exist (no place to put debugOutput files)\n");
return false;
}
}
@ -106,19 +106,19 @@ bool handleArgs(int argc, char** argv,
{
param = argv[++i];
if (!param)
return false;
{ return false; }
float maxangle = atof(param);
if (maxangle <= 90.f && maxangle >= 45.f)
maxAngle = maxangle;
{ maxAngle = maxangle; }
else
printf("invalid option for '--maxAngle', using default\n");
{ printf("invalid option for '--maxAngle', using default\n"); }
}
else if (strcmp(argv[i], "--tile") == 0)
{
param = argv[++i];
if (!param)
return false;
{ return false; }
char* stileX = strtok(param, ",");
char* stileY = strtok(NULL, ",");
@ -126,9 +126,9 @@ bool handleArgs(int argc, char** argv,
int tiley = atoi(stileY);
if ((tilex > 0 && tilex < 64) || (tilex == 0 && strcmp(stileX, "0") == 0))
tileX = tilex;
{ tileX = tilex; }
if ((tiley > 0 && tiley < 64) || (tiley == 0 && strcmp(stileY, "0") == 0))
tileY = tiley;
{ tileY = tiley; }
if (tileX < 0 || tileY < 0)
{
@ -140,66 +140,66 @@ bool handleArgs(int argc, char** argv,
{
param = argv[++i];
if (!param)
return false;
{ return false; }
if (strcmp(param, "true") == 0)
skipLiquid = true;
{ skipLiquid = true; }
else if (strcmp(param, "false") == 0)
skipLiquid = false;
{ skipLiquid = false; }
else
printf("invalid option for '--skipLiquid', using default\n");
{ printf("invalid option for '--skipLiquid', using default\n"); }
}
else if (strcmp(argv[i], "--skipContinents") == 0)
{
param = argv[++i];
if (!param)
return false;
{ return false; }
if (strcmp(param, "true") == 0)
skipContinents = true;
{ skipContinents = true; }
else if (strcmp(param, "false") == 0)
skipContinents = false;
{ skipContinents = false; }
else
printf("invalid option for '--skipContinents', using default\n");
{ printf("invalid option for '--skipContinents', using default\n"); }
}
else if (strcmp(argv[i], "--skipJunkMaps") == 0)
{
param = argv[++i];
if (!param)
return false;
{ return false; }
if (strcmp(param, "true") == 0)
skipJunkMaps = true;
{ skipJunkMaps = true; }
else if (strcmp(param, "false") == 0)
skipJunkMaps = false;
{ skipJunkMaps = false; }
else
printf("invalid option for '--skipJunkMaps', using default\n");
{ printf("invalid option for '--skipJunkMaps', using default\n"); }
}
else if (strcmp(argv[i], "--skipBattlegrounds") == 0)
{
param = argv[++i];
if (!param)
return false;
{ return false; }
if (strcmp(param, "true") == 0)
skipBattlegrounds = true;
{ skipBattlegrounds = true; }
else if (strcmp(param, "false") == 0)
skipBattlegrounds = false;
{ skipBattlegrounds = false; }
else
printf("invalid option for '--skipBattlegrounds', using default\n");
{ printf("invalid option for '--skipBattlegrounds', using default\n"); }
}
else if (strcmp(argv[i], "--debugOutput") == 0)
{
param = argv[++i];
if (!param)
return false;
{ return false; }
if (strcmp(param, "true") == 0)
debugOutput = true;
{ debugOutput = true; }
else if (strcmp(param, "false") == 0)
debugOutput = false;
{ debugOutput = false; }
else
printf("invalid option for '--debugOutput', using default true\n");
{ printf("invalid option for '--debugOutput', using default true\n"); }
}
else if (strcmp(argv[i], "--silent") == 0)
{
@ -209,20 +209,20 @@ bool handleArgs(int argc, char** argv,
{
param = argv[++i];
if (!param)
return false;
{ return false; }
if (strcmp(param, "true") == 0)
bigBaseUnit = true;
{ bigBaseUnit = true; }
else if (strcmp(param, "false") == 0)
bigBaseUnit = false;
{ bigBaseUnit = false; }
else
printf("invalid option for '--bigBaseUnit', using default false\n");
{ printf("invalid option for '--bigBaseUnit', using default false\n"); }
}
else if (strcmp(argv[i], "--offMeshInput") == 0)
{
param = argv[++i];
if (!param)
return false;
{ return false; }
offMeshInputPath = param;
}
@ -235,7 +235,7 @@ bool handleArgs(int argc, char** argv,
{
int map = atoi(argv[i]);
if (map > 0 || (map == 0 && (strcmp(argv[i], "0") == 0)))
mapnum = map;
{ mapnum = map; }
else
{
printf("invalid map id\n");
@ -279,27 +279,28 @@ int main(int argc, char** argv)
if (mapnum == -1 && debugOutput)
{
if (silent)
return -2;
{ 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) ");
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;
{ return 0; }
}
if (!checkDirectories(debugOutput))
return silent ? -3 : finish("Press any key to close...", -3);
{ 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);
{ 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);
return silent ? 1 : finish(" Movemap build is complete! Press enter to exit\n", 1);
}

View file

@ -1,68 +0,0 @@
#!/usr/bin/python
"""
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
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
"""
import os, sys, threading, time, subprocess
from multiprocessing import cpu_count
from collections import deque
mapList = deque([0,1,530,571,13,25,30,33,34,35,36,37,42,43,44,47,48,70,90,109,129,169,189,209,229,230,249,269,289,309,329,349,369,
389,409,429,449,450,451,469,489,509,529,531,532,533,534,540,542,543,544,545,546,547,548,550,552,553,554,555,556,557,558,559,
560,562,564,565,566,568,572,573,574,575,576,578,580,582,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,
601,602,603,604,605,606,607,608,609,610,612,613,614,615,616,617,618,619,620,621,622,623,624,627,628,631,632,637,638,641,642,
643,644,645,646,647,648,649,650,651,654,655,656,657,658,659,660,661,662,668,669,670,671,672,673,674,712,713,718,719,720,721,
723,724,725,726,727,728,730,731,732,734,736,738,739,740,741,742,743,746,747,748,749,750,751,752,753,754,755,757,759,760,761,
762,763,764,765,766,767,859,861,930,938,939,940,951,967,969,974,977,980])
class workerThread(threading.Thread):
def __init__(self, mapID):
threading.Thread.__init__(self)
self.mapID = mapID
def run(self):
name = "Worker for map %u" % (self.mapID)
print "++ %s" % (name)
if sys.platform == 'win32':
stInfo = subprocess.STARTUPINFO()
stInfo.dwFlags |= 0x00000001
stInfo.wShowWindow = 7
cFlags = subprocess.CREATE_NEW_CONSOLE
binName = "movemap-generator.exe"
else:
stInfo = None
cFlags = 0
binName = "./MoveMapGen"
if self.mapID == 0:
retcode = subprocess.call([binName, "%u" % (self.mapID), "--silent", "--offMeshInput", "offmesh.txt"], startupinfo=stInfo, creationflags=cFlags)
else:
retcode = subprocess.call([binName, "%u" % (self.mapID), "--silent"], startupinfo=stInfo, creationflags=cFlags)
print "-- %s" % (name)
if __name__ == "__main__":
cpu = cpu_count() - 0 # You can reduce the load by putting 1 instead of 0 if you need to free 1 core/cpu
if cpu < 1:
cpu = 1
print "I will always maintain %u MoveMapGen tasks running in //\n" % (cpu)
while (len(mapList) > 0):
if (threading.active_count() <= cpu):
workerThread(mapList.popleft()).start()
time.sleep(0.2)

View file

@ -1 +0,0 @@
0 31,59 (-14429.889648 450.344452 15.430828) (-14424.218750 444.332855 12.773965) 2.5 // booty bay dock

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -22,13 +22,10 @@
* and lore are copyrighted by Blizzard Entertainment, Inc.
*/
#define _CRT_SECURE_NO_WARNINGS
#include "vmapexport.h"
#include "adtfile.h"
#include <algorithm>
#include <cstdio>
#include "vmapexport.h"
#include "adtfile.h"
#ifdef WIN32
#define snprintf _snprintf
@ -91,30 +88,27 @@ extern HANDLE WorldMpq;
ADTFile::ADTFile(char* filename): ADT(WorldMpq, filename)
{
Adtfilename.append(filename);
AdtFilename.append(filename);
}
bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY, StringSet& failedPaths)
{
if (ADT.isEof())
return false;
if (ADT.isEof()) { return false; }
uint32 size;
string xMap;
string yMap;
std::string xMap;
std::string yMap;
Adtfilename.erase(Adtfilename.find(".adt"), 4);
string TempMapNumber;
TempMapNumber = Adtfilename.substr(Adtfilename.length() - 6, 6);
AdtFilename.erase(AdtFilename.find(".adt"), 4);
std::string TempMapNumber;
TempMapNumber = AdtFilename.substr(AdtFilename.length() - 6, 6);
xMap = TempMapNumber.substr(TempMapNumber.find("_") + 1, (TempMapNumber.find_last_of("_") - 1) - (TempMapNumber.find("_")));
yMap = TempMapNumber.substr(TempMapNumber.find_last_of("_") + 1, (TempMapNumber.length()) - (TempMapNumber.find_last_of("_")));
Adtfilename.erase((Adtfilename.length() - xMap.length() - yMap.length() - 2), (xMap.length() + yMap.length() + 2));
string AdtMapNumber = xMap + ' ' + yMap + ' ' + GetPlainName((char*)Adtfilename.c_str());
//printf("Processing map %s...\n", AdtMapNumber.c_str());
//printf("MapNumber = %s\n", TempMapNumber.c_str());
//printf("xMap = %s\n", xMap.c_str());
//printf("yMap = %s\n", yMap.c_str());
AdtFilename.erase((AdtFilename.length() - xMap.length() - yMap.length() - 2), (xMap.length() + yMap.length() + 2));
string AdtMapNumber = xMap + ' ' + yMap + ' ' + GetPlainName((char*)AdtFilename.c_str());
std::string dirname = std::string(szWorkDirWmo) + "/dir_bin";
FILE* dirfile;
@ -149,18 +143,16 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY, StringSet& failed
ADT.read(buf, size);
char* p = buf;
int t = 0;
ModelInstansName = new string[size];
ModelInstansName = new std::string[size];
while (p < buf + size)
{
fixnamen(p, strlen(p));
char* s = GetPlainName(p);
fixname2(s, strlen(s));
string path(p); // Store copy after name fixed
std::string fixedName;
ExtractSingleModel(path, fixedName, failedPaths);
ModelInstansName[t++] = fixedName;
std::string path(p); // Store copy after name fixed
std::string uName;
ExtractSingleModel(path, uName, failedPaths);
ModelInstansName[t++] = uName;
p = p + strlen(p) + 1;
}
delete[] buf;
@ -174,10 +166,10 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY, StringSet& failed
ADT.read(buf, size);
char* p = buf;
int q = 0;
WmoInstansName = new string[size];
WmoInstansName = new std::string[size];
while (p < buf + size)
{
string path(p);
std::string path(p);
char* s = GetPlainName(p);
fixnamen(s, strlen(s));
fixname2(s, strlen(s));

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -33,111 +33,148 @@
#define TILESIZE (533.33333f)
#define CHUNKSIZE ((TILESIZE) / 16.0f)
#define UNITSIZE (CHUNKSIZE / 8.0f)
class Liquid;
/**
* @brief
*
*/
typedef struct
{
float x;
float y;
float z;
float x; /**< TODO */
float y; /**< TODO */
float z; /**< TODO */
} svec;
/**
* @brief
*
*/
struct vec
{
double x;
double y;
double z;
double x; /**< TODO */
double y; /**< TODO */
double z; /**< TODO */
};
/**
* @brief
*
*/
struct triangle
{
vec v[3];
vec v[3]; /**< TODO */
};
/**
* @brief
*
*/
typedef struct
{
float v9[16 * 8 + 1][16 * 8 + 1];
float v8[16 * 8][16 * 8];
float v9[16 * 8 + 1][16 * 8 + 1]; /**< TODO */
float v8[16 * 8][16 * 8]; /**< TODO */
} Cell;
/**
* @brief
*
*/
typedef struct
{
double v9[9][9];
double v8[8][8];
uint16 area_id;
double v9[9][9]; /**< TODO */
double v8[8][8]; /**< TODO */
uint16 area_id; /**< TODO */
//Liquid *lq;
float waterlevel[9][9];
uint8 flag;
float waterlevel[9][9]; /**< TODO */
uint8 flag; /**< TODO */
} chunk;
/**
* @brief
*
*/
typedef struct
{
chunk ch[16][16];
chunk ch[16][16]; /**< TODO */
} mcell;
/**
* @brief
*
*/
struct MapChunkHeader
{
uint32 flags;
uint32 ix;
uint32 iy;
uint32 nLayers;
uint32 nDoodadRefs;
uint32 ofsHeight;
uint32 ofsNormal;
uint32 ofsLayer;
uint32 ofsRefs;
uint32 ofsAlpha;
uint32 sizeAlpha;
uint32 ofsShadow;
uint32 sizeShadow;
uint32 areaid;
uint32 nMapObjRefs;
uint32 holes;
uint16 s1;
uint16 s2;
uint32 d1;
uint32 d2;
uint32 d3;
uint32 predTex;
uint32 nEffectDoodad;
uint32 ofsSndEmitters;
uint32 nSndEmitters;
uint32 ofsLiquid;
uint32 sizeLiquid;
float zpos;
float xpos;
float ypos;
uint32 textureId;
uint32 props;
uint32 effectId;
uint32 flags; /**< TODO */
uint32 ix; /**< TODO */
uint32 iy; /**< TODO */
uint32 nLayers; /**< TODO */
uint32 nDoodadRefs; /**< TODO */
uint32 ofsHeight; /**< TODO */
uint32 ofsNormal; /**< TODO */
uint32 ofsLayer; /**< TODO */
uint32 ofsRefs; /**< TODO */
uint32 ofsAlpha; /**< TODO */
uint32 sizeAlpha; /**< TODO */
uint32 ofsShadow; /**< TODO */
uint32 sizeShadow; /**< TODO */
uint32 areaid; /**< TODO */
uint32 nMapObjRefs; /**< TODO */
uint32 holes; /**< TODO */
uint16 s1; /**< TODO */
uint16 s2; /**< TODO */
uint32 d1; /**< TODO */
uint32 d2; /**< TODO */
uint32 d3; /**< TODO */
uint32 predTex; /**< TODO */
uint32 nEffectDoodad; /**< TODO */
uint32 ofsSndEmitters; /**< TODO */
uint32 nSndEmitters; /**< TODO */
uint32 ofsLiquid; /**< TODO */
uint32 sizeLiquid; /**< TODO */
float zpos; /**< TODO */
float xpos; /**< TODO */
float ypos; /**< TODO */
uint32 textureId; /**< TODO */
uint32 props; /**< TODO */
uint32 effectId; /**< TODO */
};
/**
* @brief
*
*/
class ADTFile
{
public:
/**
* @brief
*
* @param filename
*/
ADTFile(char* filename);
/**
* @brief
*
*/
~ADTFile();
int nWMO;
int nMDX;
string* WmoInstansName;
string* ModelInstansName;
int nWMO; /**< TODO */
int nMDX; /**< TODO */
string* WmoInstansName; /**< TODO */
string* ModelInstansName; /**< TODO */
/**
* @brief
*
* @param map_num
* @param tileX
* @param tileY
* @param failedPaths
* @return bool
*/
bool init(uint32 map_num, uint32 tileX, uint32 tileY, StringSet& failedPaths);
//void LoadMapChunks();
//uint32 wmo_count;
/*
const mcell& Getmcell() const
{
return Mcell;
}
*/
private:
//size_t mcnk_offsets[256], mcnk_sizes[256];
MPQFile ADT;
//mcell Mcell;
string Adtfilename;
MPQFile ADT; /**< TODO */
string AdtFilename; /**< TODO */
};
const char* GetPlainName(const char* FileName);
@ -145,6 +182,4 @@ char* GetPlainName(char* FileName);
char const* GetExtension(char const* FileName);
void fixnamen(char* name, size_t len);
void fixname2(char* name, size_t len);
//void fixMapNamen(char *name, size_t len);
#endif

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -60,14 +60,17 @@ bool Model::open(StringSet& failedPaths)
f.seekRelative(header.ofsBoundingVertices);
vertices = new Vec3D[header.nBoundingVertices];
f.read(vertices, header.nBoundingVertices * 12);
for (uint32 i = 0; i < header.nBoundingVertices; i++)
{
vertices[i] = fixCoordSystem(vertices[i]);
}
f.seek(0);
f.seekRelative(header.ofsBoundingTriangles);
indices = new uint16[header.nBoundingTriangles];
f.read(indices, header.nBoundingTriangles * 2);
f.close();
}
else
@ -88,6 +91,7 @@ bool Model::ConvertToVMAPModel(const char* outfilename)
printf("Can't create the output file '%s'\n", outfilename);
return false;
}
fwrite(szRawVMAPMagic, 8, 1, output);
uint32 nVertices = 0;
nVertices = header.nBoundingVertices;
@ -172,11 +176,11 @@ ModelInstance::ModelInstance(MPQFile& f, const char* ModelInstName, uint32 mapID
fclose(input);
if (nVertices == 0)
return;
{ return; }
uint16 adtId = 0;// not used for models
uint32 flags = MOD_M2;
if (tileX == 65 && tileY == 65) flags |= MOD_WORLDSPAWN;
if (tileX == 65 && tileY == 65) { flags |= MOD_WORLDSPAWN; }
//write mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, name
fwrite(&mapID, sizeof(uint32), 1, pDirfile);
fwrite(&tileX, sizeof(uint32), 1, pDirfile);

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -26,7 +26,6 @@
#define MODEL_H
#include "vec3d.h"
//#include "mpq.h"
#include "modelheaders.h"
#include <vector>
#include "vmapexport.h"
@ -43,17 +42,42 @@ class Model
uint32 offsBB_vertices, offsBB_indices;
Vec3D* BB_vertices, *vertices;
uint16* BB_indices, *indices;
size_t nIndices;
size_t nIndices; /**< TODO */
/**
* @brief
*
* @param failedPaths
* @return bool
*/
bool open(StringSet& failedPaths);
/**
* @brief
*
* @param outfilename
* @return bool
*/
bool ConvertToVMAPModel(const char* outfilename);
bool ok;
bool ok; /**< TODO */
/**
* @brief
*
* @param filename
*/
Model(std::string& filename);
/**
* @brief
*
*/
~Model() {_unload();}
private:
/**
* @brief
*
*/
void _unload()
{
delete[] vertices;
@ -61,21 +85,39 @@ class Model
vertices = NULL;
indices = NULL;
}
std::string filename;
std::string filename; /**< TODO */
char outfilename;
};
/**
* @brief
*
*/
class ModelInstance
{
public:
Model* model;
Model* model; /**< TODO */
uint32 id;
Vec3D pos, rot;
uint32 id; /**< TODO */
Vec3D pos, rot; /**< TODO */
unsigned int d1, Scale;
float w, sc;
/**
* @brief
*
*/
ModelInstance() {}
/**
* @brief
*
* @param f
* @param ModelInstName
* @param mapID
* @param tileX
* @param tileY
* @param pDirfile
*/
ModelInstance(MPQFile& f, const char* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile);
};

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -31,69 +31,69 @@
struct ModelHeader
{
char id[4];
uint8 version[4];
uint32 nameLength;
uint32 nameOfs;
uint32 type;
uint32 nGlobalSequences;
uint32 ofsGlobalSequences;
uint32 nAnimations;
uint32 ofsAnimations;
uint32 nAnimationLookup;
uint32 ofsAnimationLookup;
uint32 nBones;
uint32 ofsBones;
uint32 nKeyBoneLookup;
uint32 ofsKeyBoneLookup;
uint32 nVertices;
uint32 ofsVertices;
uint32 nViews;
uint32 nColors;
uint32 ofsColors;
uint32 nTextures;
uint32 ofsTextures;
uint32 nTransparency;
uint32 ofsTransparency;
uint32 nTextureanimations;
uint32 ofsTextureanimations;
uint32 nTexReplace;
uint32 ofsTexReplace;
uint32 nRenderFlags;
uint32 ofsRenderFlags;
uint32 nBoneLookupTable;
uint32 ofsBoneLookupTable;
uint32 nTexLookup;
uint32 ofsTexLookup;
uint32 nTexUnits;
uint32 ofsTexUnits;
uint32 nTransLookup;
uint32 ofsTransLookup;
uint32 nTexAnimLookup;
uint32 ofsTexAnimLookup;
float floats[14];
uint32 nBoundingTriangles;
uint32 ofsBoundingTriangles;
uint32 nBoundingVertices;
uint32 ofsBoundingVertices;
uint32 nBoundingNormals;
uint32 ofsBoundingNormals;
uint32 nAttachments;
uint32 ofsAttachments;
uint32 nAttachLookup;
uint32 ofsAttachLookup;
uint32 nAttachments_2;
uint32 ofsAttachments_2;
uint32 nLights;
uint32 ofsLights;
uint32 nCameras;
uint32 ofsCameras;
uint32 nCameraLookup;
uint32 ofsCameraLookup;
uint32 nRibbonEmitters;
uint32 ofsRibbonEmitters;
uint32 nParticleEmitters;
uint32 ofsParticleEmitters;
char id[4]; /**< TODO */
uint8 version[4]; /**< TODO */
uint32 nameLength; /**< TODO */
uint32 nameOfs; /**< TODO */
uint32 type; /**< TODO */
uint32 nGlobalSequences; /**< TODO */
uint32 ofsGlobalSequences; /**< TODO */
uint32 nAnimations; /**< TODO */
uint32 ofsAnimations; /**< TODO */
uint32 nAnimationLookup; /**< TODO */
uint32 ofsAnimationLookup; /**< TODO */
uint32 nBones; /**< TODO */
uint32 ofsBones; /**< TODO */
uint32 nKeyBoneLookup; /**< TODO */
uint32 ofsKeyBoneLookup; /**< TODO */
uint32 nVertices; /**< TODO */
uint32 ofsVertices; /**< TODO */
uint32 nViews; /**< TODO */
uint32 nColors; /**< TODO */
uint32 ofsColors; /**< TODO */
uint32 nTextures; /**< TODO */
uint32 ofsTextures; /**< TODO */
uint32 nTransparency; /**< TODO */
uint32 ofsTransparency; /**< TODO */
uint32 nTextureanimations; /**< TODO */
uint32 ofsTextureanimations; /**< TODO */
uint32 nTexReplace; /**< TODO */
uint32 ofsTexReplace; /**< TODO */
uint32 nRenderFlags; /**< TODO */
uint32 ofsRenderFlags; /**< TODO */
uint32 nBoneLookupTable; /**< TODO */
uint32 ofsBoneLookupTable; /**< TODO */
uint32 nTexLookup; /**< TODO */
uint32 ofsTexLookup; /**< TODO */
uint32 nTexUnits; /**< TODO */
uint32 ofsTexUnits; /**< TODO */
uint32 nTransLookup; /**< TODO */
uint32 ofsTransLookup; /**< TODO */
uint32 nTexAnimLookup; /**< TODO */
uint32 ofsTexAnimLookup; /**< TODO */
float floats[14]; /**< TODO */
uint32 nBoundingTriangles; /**< TODO */
uint32 ofsBoundingTriangles; /**< TODO */
uint32 nBoundingVertices; /**< TODO */
uint32 ofsBoundingVertices; /**< TODO */
uint32 nBoundingNormals; /**< TODO */
uint32 ofsBoundingNormals; /**< TODO */
uint32 nAttachments; /**< TODO */
uint32 ofsAttachments; /**< TODO */
uint32 nAttachLookup; /**< TODO */
uint32 ofsAttachLookup; /**< TODO */
uint32 nAttachments_2; /**< TODO */
uint32 ofsAttachments_2; /**< TODO */
uint32 nLights; /**< TODO */
uint32 ofsLights; /**< TODO */
uint32 nCameras; /**< TODO */
uint32 ofsCameras; /**< TODO */
uint32 nCameraLookup; /**< TODO */
uint32 ofsCameraLookup; /**< TODO */
uint32 nRibbonEmitters; /**< TODO */
uint32 ofsRibbonEmitters; /**< TODO */
uint32 nParticleEmitters; /**< TODO */
uint32 ofsParticleEmitters; /**< TODO */
};
#pragma pack(pop)

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -28,15 +28,37 @@
#include <iostream>
#include <cmath>
/**
* @brief
*
*/
class Vec3D
{
public:
float x, y, z;
float x, y, z; /**< TODO */
/**
* @brief
*
* @param x0
* @param y0
* @param z0
*/
Vec3D(float x0 = 0.0f, float y0 = 0.0f, float z0 = 0.0f) : x(x0), y(y0), z(z0) {}
/**
* @brief
*
* @param v
*/
Vec3D(const Vec3D& v) : x(v.x), y(v.y), z(v.z) {}
/**
* @brief
*
* @param v
* @return Vec3D &operator
*/
Vec3D& operator= (const Vec3D& v)
{
x = v.x;
@ -45,40 +67,83 @@ class Vec3D
return *this;
}
/**
* @brief
*
* @param v
* @return Vec3D operator
*/
Vec3D operator+ (const Vec3D& v) const
{
Vec3D r(x + v.x, y + v.y, z + v.z);
return r;
}
/**
* @brief
*
* @param v
* @return Vec3D operator
*/
Vec3D operator- (const Vec3D& v) const
{
Vec3D r(x - v.x, y - v.y, z - v.z);
return r;
}
/**
* @brief
*
* @param v
* @return float operator
*/
float operator* (const Vec3D& v) const
{
return x * v.x + y * v.y + z * v.z;
}
/**
* @brief
*
* @param d
* @return Vec3D operator
*/
Vec3D operator* (float d) const
{
Vec3D r(x * d, y * d, z * d);
return r;
}
/**
* @brief
*
* @param d
* @param v
* @return Vec3D operator
*/
friend Vec3D operator* (float d, const Vec3D& v)
{
return v * d;
}
/**
* @brief
*
* @param v
* @return Vec3D operator
*/
Vec3D operator% (const Vec3D& v) const
{
Vec3D r(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
return r;
}
/**
* @brief
*
* @param v
* @return Vec3D &operator
*/
Vec3D& operator+= (const Vec3D& v)
{
x += v.x;
@ -87,6 +152,12 @@ class Vec3D
return *this;
}
/**
* @brief
*
* @param v
* @return Vec3D &operator
*/
Vec3D& operator-= (const Vec3D& v)
{
x -= v.x;
@ -95,6 +166,12 @@ class Vec3D
return *this;
}
/**
* @brief
*
* @param d
* @return Vec3D &operator
*/
Vec3D& operator*= (float d)
{
x *= d;
@ -103,22 +180,42 @@ class Vec3D
return *this;
}
/**
* @brief
*
* @return float
*/
float lengthSquared() const
{
return x * x + y * y + z * z;
}
/**
* @brief
*
* @return float
*/
float length() const
{
return sqrt(x * x + y * y + z * z);
}
/**
* @brief
*
* @return Vec3D
*/
Vec3D& normalize()
{
this->operator*= (1.0f / length());
return *this;
}
/**
* @brief
*
* @return Vec3D operator
*/
Vec3D operator~() const
{
Vec3D r(*this);
@ -126,18 +223,37 @@ class Vec3D
return r;
}
/**
* @brief
*
* @param in
* @param v
* @return std::istream &operator >>
*/
friend std::istream& operator>>(std::istream& in, Vec3D& v)
{
in >> v.x >> v.y >> v.z;
return in;
}
/**
* @brief
*
* @param out
* @param v
* @return std::ostream &operator
*/
friend std::ostream& operator<<(std::ostream& out, const Vec3D& v)
{
out << v.x << " " << v.y << " " << v.z;
return out;
}
/**
* @brief
*
* @return operator float
*/
operator float* ()
{
return (float*)this;
@ -246,6 +362,15 @@ class Vec2D
}
};
/**
* @brief
*
* @param x0
* @param y0
* @param x
* @param y
* @param angle
*/
inline void rotate(float x0, float y0, float* x, float* y, float angle)
{
float xa = *x - x0, ya = *y - y0;

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -22,7 +22,6 @@
* and lore are copyrighted by Blizzard Entertainment, Inc.
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <cstdio>
#include <iostream>
#include <vector>
@ -52,7 +51,6 @@
#include "dbcfile.h"
#include "wmo.h"
#include "mpqfile.h"
#include "vmapexport.h"
#include "../shared/ExtractorCommon.h"
@ -61,7 +59,6 @@
// Defines
#define MPQ_BLOCK_SIZE 0x1000
//-----------------------------------------------------------------------------
HANDLE WorldMpq = NULL;
@ -107,7 +104,7 @@ uint16* LiqType = 0;
uint32 map_count;
char output_path[128] = ".";
char input_path[1024] = ".";
bool preciseVectorData = false;
bool preciseVectorData = true;
// Constants
@ -115,6 +112,20 @@ bool preciseVectorData = false;
const char* szWorkDirWmo = "./Buildings";
const char* szRawVMAPMagic = "VMAPc06";
// Local testing functions
bool FileExists(const char* file)
{
if (FILE* n = fopen(file, "rb"))
{
fclose(n);
return true;
}
return false;
}
bool LoadLocaleMPQFile(int locale)
{
TCHAR buff[512];
@ -254,20 +265,6 @@ void LoadCommonMPQFiles(uint32 build)
}
}
}
// Local testing functions
bool FileExists(const char* file)
{
if (FILE* n = fopen(file, "rb"))
{
fclose(n);
return true;
}
return false;
}
void strToLower(char* str)
{
while (*str)
@ -280,12 +277,11 @@ void strToLower(char* str)
// copied from contrib/extractor/System.cpp
void ReadLiquidTypeTableDBC()
{
printf("Read LiquidType.dbc file...");
DBCFile dbc(LocaleMpq, "DBFilesClient/LiquidType.dbc");
printf(" Reading liquid types from LiquidType.dbc...");
DBCFile dbc(LocaleMpq, "DBFilesClient\\LiquidType.dbc");
if (!dbc.open())
{
printf("Fatal error: Invalid LiquidType.dbc file format!\n");
printf("Fatal error: Could not read LiquidType.dbc!\n");
exit(1);
}
@ -295,9 +291,53 @@ void ReadLiquidTypeTableDBC()
memset(LiqType, 0xff, (LiqType_maxid + 1) * sizeof(uint16));
for (uint32 x = 0; x < LiqType_count; ++x)
{
LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3);
}
printf("Done! (%u LiqTypes loaded)\n", (unsigned int)LiqType_count);
printf(" Success! (%u LiqTypes loaded)\n", (unsigned int)LiqType_count);
}
void ParsMapFiles()
{
char fn[512];
//char id_filename[64];
char id[10];
StringSet failedPaths;
printf("\n");
for (unsigned int i = 0; i < map_count; ++i)
{
sprintf(id, "%03u", map_ids[i].id);
sprintf(fn, "World\\Maps\\%s\\%s.wdt", map_ids[i].name, map_ids[i].name);
WDTFile WDT(fn, map_ids[i].name);
if (WDT.init(id, map_ids[i].id))
{
printf(" Processing Map %u (%s)\n[", map_ids[i].id, map_ids[i].name);
for (int x = 0; x < 64; ++x)
{
for (int y = 0; y < 64; ++y)
{
if (ADTFile* ADT = WDT.GetMap(x, y))
{
//sprintf(id_filename,"%02u %02u %03u",x,y,map_ids[i].id);//!!!!!!!!!
ADT->init(map_ids[i].id, x, y, failedPaths);
delete ADT;
}
}
printf("#");
fflush(stdout);
}
printf("]\n");
}
}
if (!failedPaths.empty())
{
printf(" Warning: Some models could not be extracted, see below\n");
for (StringSet::const_iterator itr = failedPaths.begin(); itr != failedPaths.end(); ++itr)
{ printf("Could not find file of model %s\n", itr->c_str()); }
printf(" A few not found models can be expected and are not alarming.\n");
}
}
bool ExtractWmo()
@ -407,47 +447,6 @@ bool ExtractSingleWmo(std::string& fname)
return true;
}
void ParsMapFiles()
{
char fn[512];
//char id_filename[64];
char id[10];
StringSet failedPaths;
for (unsigned int i = 0; i < map_count; ++i)
{
sprintf(id, "%03u", map_ids[i].id);
sprintf(fn, "World/Maps/%s/%s.wdt", map_ids[i].name, map_ids[i].name);
WDTFile WDT(fn, map_ids[i].name);
if (WDT.init(id, map_ids[i].id))
{
printf("Processing Map %u\n[", map_ids[i].id);
for (int x = 0; x < 64; ++x)
{
for (int y = 0; y < 64; ++y)
{
if (ADTFile* ADT = WDT.GetMap(x, y))
{
//sprintf(id_filename,"%02u %02u %03u",x,y,map_ids[i].id);//!!!!!!!!!
ADT->init(map_ids[i].id, x, y, failedPaths);
delete ADT;
}
}
printf("#");
fflush(stdout);
}
printf("]\n");
}
}
if (!failedPaths.empty())
{
printf("Warning: Some models could not be extracted, see below\n");
for (StringSet::const_iterator itr = failedPaths.begin(); itr != failedPaths.end(); ++itr)
printf("Could not find file of model %s\n", itr->c_str());
printf("A few not found models can be expected and are not alarming.\n");
}
}
void getGamePath()
{
#ifdef _WIN32
@ -491,7 +490,7 @@ bool processArgv(int argc, char** argv)
{
bool result = true;
bool hasInputPathParam = false;
bool preciseVectorData = false;
bool preciseVectorData = true;
for (int i = 1; i < argc; ++i)
{
@ -543,10 +542,10 @@ bool processArgv(int argc, char** argv)
printf(" -b : target build (default %u)", CONF_TargetBuild);
printf(" -? : This message.\n");
}
return result;
}
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// Main
//
@ -560,11 +559,11 @@ int main(int argc, char** argv)
{
bool bCreatedVmapsFolder = false;
bool bExtractedWMOfiles = false;
std::string outDir = std::string(output_path) + "/vmaps";
std::string outDir = std::string(output_path) + "/vmaps";
// Use command line arguments, when some
if (!processArgv(argc, argv))
return 1;
{ return 1; }
// some simple check if working dir is dirty
else
@ -595,10 +594,10 @@ int main(int argc, char** argv)
}
}
printf("Extract for %s. Beginning work ....\n", szRawVMAPMagic);
printf(" Beginning work ....\n");
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// Create the working directory
CreateDir(std::string(szWorkDirWmo));
// Create the working and ouput directories
CreateDir(std::string(szWorkDirWmo));
bCreatedVmapsFolder = CreateDir(outDir);
printf("Loading common MPQ files\n");
@ -645,7 +644,7 @@ int main(int argc, char** argv)
{
map_ids[x].id = dbc->getRecord(x).getUInt(0);
strcpy(map_ids[x].name, dbc->getRecord(x).getString(1));
printf("Map - %s\n", map_ids[x].name);
printf(" Map %d - %s\n", map_ids[x].id, map_ids[x].name);
}
@ -665,6 +664,7 @@ int main(int argc, char** argv)
{
printf("ERROR: Extract for %s. Work NOT complete.\n Precise vector data=%d.\nPress any key.\n", szRawVMAPMagic, preciseVectorData);
getchar();
return 1;
}
printf("Extract for %s. Work complete. ", szRawVMAPMagic);

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -28,8 +28,16 @@
#include <string>
#include <set>
/**
* @brief
*
*/
typedef std::set<std::string> StringSet;
/**
* @brief
*
*/
enum ModelFlags
{
MOD_M2 = 1,
@ -40,6 +48,12 @@ enum ModelFlags
extern const char* szWorkDirWmo;
extern const char* szRawVMAPMagic; // vmap magic string for extracted raw vmap data
/**
* @brief Test if the specified file exists in the building directory
*
* @param file
* @return bool
*/
bool FileExists(const char* file);
void strToLower(char* str);

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -22,11 +22,10 @@
* and lore are copyrighted by Blizzard Entertainment, Inc.
*/
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include "vmapexport.h"
#include "wdtfile.h"
#include "adtfile.h"
#include <cstdio>
char* wdtGetPlainName(char* FileName)
{
@ -134,7 +133,7 @@ WDTFile::~WDTFile(void)
ADTFile* WDTFile::GetMap(int x, int z)
{
if (!(x >= 0 && z >= 0 && x < 64 && z < 64))
return NULL;
{ return NULL; }
char name[512];

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -25,29 +25,57 @@
#ifndef WDTFILE_H
#define WDTFILE_H
#include <string>
#include "mpqfile.h"
#include "wmo.h"
#include <string>
#include "stdlib.h"
class ADTFile;
/**
* @brief
*
*/
class WDTFile
{
public:
/**
* @brief
*
* @param file_name
* @param file_name1
*/
WDTFile(char* file_name, char* file_name1);
/**
* @brief
*
*/
~WDTFile(void);
/**
* @brief
*
* @param map_id
* @param mapID
* @return bool
*/
bool init(char* map_id, unsigned int mapID);
string* gWmoInstansName;
int gnWMO, nMaps;
std::string* gWmoInstansName; /**< TODO */
int gnWMO, nMaps; /**< TODO */
/**
* @brief
*
* @param x
* @param z
* @return ADTFile
*/
ADTFile* GetMap(int x, int z);
private:
MPQFile WDT;
bool maps[64][64];
string filename;
MPQFile WDT; /**< TODO */
bool maps[64][64]; /**< TODO */
std::string filename; /**< TODO */
};
#endif

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -50,7 +50,7 @@ bool WMORoot::open()
MPQFile f(WorldMpq, filename.c_str());
if (f.isEof())
{
printf("No such file %s.\n", filename.c_str());
printf(" No such file %s.\n", filename.c_str());
return false;
}
@ -156,7 +156,7 @@ bool WMOGroup::open()
MPQFile f(WorldMpq, filename.c_str());
if (f.isEof())
{
printf("No such file.\n");
printf(" No such file.\n");
return false;
}
uint32 size;
@ -355,8 +355,8 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE* output, WMORoot* rootWMO, bool pPrecis
{
// Skip no collision triangles
if (MOPY[2 * i]&WMO_MATERIAL_NO_COLLISION ||
!(MOPY[2 * i] & (WMO_MATERIAL_HINT | WMO_MATERIAL_COLLIDE_HIT)))
continue;
!(MOPY[2 * i] & (WMO_MATERIAL_HINT | WMO_MATERIAL_COLLIDE_HIT)))
{ continue; }
// Use this triangle
for (int j = 0; j < 3; ++j)
{
@ -395,7 +395,7 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE* output, WMORoot* rootWMO, bool pPrecis
fwrite(VERT, 4, 3, output);
for (uint32 i = 0; i < nVertices; ++i)
if (IndexRenum[i] >= 0)
check -= fwrite(MOVT + 3 * i, sizeof(float), 3, output);
{ check -= fwrite(MOVT + 3 * i, sizeof(float), 3, output); }
assert(check == 0);
@ -412,11 +412,11 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE* output, WMORoot* rootWMO, bool pPrecis
// according to WoW.Dev Wiki:
uint32 liquidEntry;
if (rootWMO->liquidType & 4)
liquidEntry = liquidType;
{ liquidEntry = liquidType; }
else if (liquidType == 15)
liquidEntry = 0;
{ liquidEntry = 0; }
else
liquidEntry = liquidType + 1;
{ liquidEntry = liquidType + 1; }
if (!liquidEntry)
{
@ -431,11 +431,11 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE* output, WMORoot* rootWMO, bool pPrecis
{
++v2;
if (v2 >= v1)
break;
{ break; }
}
if (v2 < v1 && (LiquBytes[v2] & 0xF) != 15)
liquidEntry = (LiquBytes[v2] & 0xF) + 1;
{ liquidEntry = (LiquBytes[v2] & 0xF) + 1; }
}
}
@ -444,7 +444,9 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE* output, WMORoot* rootWMO, bool pPrecis
switch (((uint8)liquidEntry - 1) & 3)
{
case 0:
liquidEntry = ((mogpFlags & 0x80000) != 0) + 13;
{
liquidEntry = ((mogpFlags & 0x80000) != 0) + 13;
}
break;
case 1:
liquidEntry = 14;
@ -453,7 +455,9 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE* output, WMORoot* rootWMO, bool pPrecis
liquidEntry = 19;
break;
case 3:
{
liquidEntry = 20;
}
break;
default:
break;
@ -470,7 +474,7 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE* output, WMORoot* rootWMO, bool pPrecis
fwrite(hlq, sizeof(WMOLiquidHeader), 1, output);
// only need height values, the other values are unknown anyway
for (uint32 i = 0; i < LiquEx_size / sizeof(WMOLiquidVert); ++i)
fwrite(&LiquEx[i].height, sizeof(float), 1, output);
{ fwrite(&LiquEx[i].height, sizeof(float), 1, output); }
// todo: compress to bit field
fwrite(LiquBytes, 1, hlq->xtiles * hlq->ytiles, output);
}
@ -489,6 +493,7 @@ WMOGroup::~WMOGroup()
delete [] LiquBytes;
}
//WmoInstName is in the form MD5/name.wmo
WMOInstance::WMOInstance(MPQFile& f, const char* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile)
{
pos = Vec3D(0, 0, 0);
@ -528,7 +533,7 @@ WMOInstance::WMOInstance(MPQFile& f, const char* WmoInstName, uint32 mapID, uint
fclose(input);
if (nVertices == 0)
return;
{ return; }
float x, z;
x = pos.x;
@ -542,9 +547,9 @@ WMOInstance::WMOInstance(MPQFile& f, const char* WmoInstName, uint32 mapID, uint
pos2 = fixCoords(pos2);
pos3 = fixCoords(pos3);
float Scale = 1.0f;
float scale = 1.0f;
uint32 flags = MOD_HAS_BOUND;
if (tileX == 65 && tileY == 65) flags |= MOD_WORLDSPAWN;
if (tileX == 65 && tileY == 65) { flags |= MOD_WORLDSPAWN; }
//write mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
fwrite(&mapID, sizeof(uint32), 1, pDirfile);
fwrite(&tileX, sizeof(uint32), 1, pDirfile);
@ -554,22 +559,11 @@ WMOInstance::WMOInstance(MPQFile& f, const char* WmoInstName, uint32 mapID, uint
fwrite(&id, sizeof(uint32), 1, pDirfile);
fwrite(&pos, sizeof(float), 3, pDirfile);
fwrite(&rot, sizeof(float), 3, pDirfile);
fwrite(&Scale, sizeof(float), 1, pDirfile);
fwrite(&scale, sizeof(float), 1, pDirfile);
fwrite(&pos2, sizeof(float), 3, pDirfile);
fwrite(&pos3, sizeof(float), 3, pDirfile);
uint32 nlen = strlen(WmoInstName);
fwrite(&nlen, sizeof(uint32), 1, pDirfile);
fwrite(WmoInstName, sizeof(char), nlen, pDirfile);
/* fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f 1.0 %d %d %d,%d %d\n",
MapName,
WmoInstName,
(float) x, (float) pos.y, (float) z,
(float) rot.x, (float) rot.y, (float) rot.z,
nVertices,
realx1, realy1,
realx2, realy2
); */
// fclose(dirfile);
}

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
* Copyright (C) 2005-2016 MaNGOS project <http://getmangos.eu>
*
* 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
@ -24,6 +24,7 @@
#ifndef WMO_H
#define WMO_H
#define TILESIZE (533.33333f)
#define CHUNKSIZE ((TILESIZE) / 16.0f)
@ -48,94 +49,170 @@ class MPQFile;
/* for whatever reason a certain company just can't stick to one coordinate system... */
static inline Vec3D fixCoords(const Vec3D& v) { return Vec3D(v.z, v.x, v.y); }
/**
* @brief
*
*/
class WMORoot
{
public:
uint32 nTextures, nGroups, nP, nLights, nModels, nDoodads, nDoodadSets, RootWMOID, liquidType;
unsigned int col;
float bbcorn1[3];
float bbcorn2[3];
uint32 nTextures, nGroups, nP, nLights, nModels, nDoodads, nDoodadSets, RootWMOID, liquidType; /**< TODO */
unsigned int col; /**< TODO */
float bbcorn1[3]; /**< TODO */
float bbcorn2[3]; /**< TODO */
/**
* @brief
*
* @param filename
*/
WMORoot(std::string& filename);
/**
* @brief
*
*/
~WMORoot();
/**
* @brief
*
* @return bool
*/
bool open();
/**
* @brief
*
* @param output
* @return bool
*/
bool ConvertToVMAPRootWmo(FILE* output);
private:
std::string filename;
std::string filename; /**< TODO */
char outfilename;
};
/**
* @brief
*
*/
struct WMOLiquidHeader
{
int xverts, yverts, xtiles, ytiles;
float pos_x;
float pos_y;
float pos_z;
short type;
int xverts, yverts, xtiles, ytiles; /**< TODO */
float pos_x; /**< TODO */
float pos_y; /**< TODO */
float pos_z; /**< TODO */
short type; /**< TODO */
};
/**
* @brief
*
*/
struct WMOLiquidVert
{
uint16 unk1;
uint16 unk2;
float height;
uint16 unk1; /**< TODO */
uint16 unk2; /**< TODO */
float height; /**< TODO */
};
/**
* @brief
*
*/
class WMOGroup
{
public:
// MOGP
int groupName, descGroupName, mogpFlags;
float bbcorn1[3];
float bbcorn2[3];
uint16 moprIdx;
uint16 moprNItems;
uint16 nBatchA;
uint16 nBatchB;
uint32 nBatchC, fogIdx, liquidType, groupWMOID;
int groupName, descGroupName, mogpFlags; /**< TODO */
float bbcorn1[3]; /**< TODO */
float bbcorn2[3]; /**< TODO */
uint16 moprIdx; /**< TODO */
uint16 moprNItems; /**< TODO */
uint16 nBatchA; /**< TODO */
uint16 nBatchB; /**< TODO */
uint32 nBatchC, fogIdx, liquidType, groupWMOID; /**< TODO */
int mopy_size, moba_size;
int LiquEx_size;
unsigned int nVertices; // number when loaded
int nTriangles; // number when loaded
char* MOPY;
uint16* MOVI;
uint16* MoviEx;
float* MOVT;
uint16* MOBA;
int* MobaEx;
WMOLiquidHeader* hlq;
WMOLiquidVert* LiquEx;
char* LiquBytes;
uint32 liquflags;
int mopy_size, moba_size; /**< TODO */
int LiquEx_size; /**< TODO */
unsigned int nVertices; /**< number when loaded */
int nTriangles; /**< number when loaded */
char* MOPY; /**< TODO */
uint16* MOVI; /**< TODO */
uint16* MoviEx; /**< TODO */
float* MOVT; /**< TODO */
uint16* MOBA; /**< TODO */
int* MobaEx; /**< TODO */
WMOLiquidHeader* hlq; /**< TODO */
WMOLiquidVert* LiquEx; /**< TODO */
char* LiquBytes; /**< TODO */
uint32 liquflags; /**< TODO */
/**
* @brief
*
* @param filename
*/
WMOGroup(std::string& filename);
/**
* @brief
*
*/
~WMOGroup();
/**
* @brief
*
* @return bool
*/
bool open();
/**
* @brief
*
* @param output
* @param rootWMO
* @param pPreciseVectorData
* @return int
*/
int ConvertToVMAPGroupWmo(FILE* output, WMORoot* rootWMO, bool pPreciseVectorData);
private:
std::string filename;
std::string filename; /**< TODO */
char outfilename;
};
/**
* @brief
*
*/
class WMOInstance
{
static std::set<int> ids;
static std::set<int> ids; /**< TODO */
public:
std::string MapName;
int currx;
int curry;
WMOGroup* wmo;
Vec3D pos;
Vec3D pos2, pos3, rot;
uint32 indx, id, d2, d3;
int doodadset;
std::string MapName; /**< TODO */
int currx; /**< TODO */
int curry; /**< TODO */
WMOGroup* wmo; /**< TODO */
Vec3D pos; /**< TODO */
Vec3D pos2, pos3, rot; /**< TODO */
uint32 indx, id, d2, d3; /**< TODO */
int doodadset; /**< TODO */
/**
* @brief
*
* @param f
* @param WmoInstName
* @param mapID
* @param tileX
* @param tileY
* @param pDirfile
*/
WMOInstance(MPQFile& f, const char* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile);
/**
* @brief
*
*/
static void reset();
};