[11903] Add MoveMapGen tool to generate MMaps

Authorship also includes qsa, and thanks to others!
This commit is contained in:
faramir118 2012-01-29 21:49:34 +01:00 committed by Schmoozerd
parent 136c0ba618
commit deb97590a1
23 changed files with 3955 additions and 1 deletions

2
contrib/mmap/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
bin

177
contrib/mmap/CMakeLists.txt Normal file
View file

@ -0,0 +1,177 @@
# Copyright (C) 2005-2012 MaNGOS project <http://getmangos.com/>
#
# 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.
cmake_minimum_required (VERSION 2.6)
project( MoveMapGen )
ADD_DEFINITIONS(-DMMAP_GENERATOR -DNO_CORE_FUNCS -DDEBUG)
# zlib
ADD_DEFINITIONS( -DNO_vsnprintf )
ADD_DEFINITIONS("-ggdb")
ADD_DEFINITIONS("-O3")
include_directories(
../../src
../../src/shared
../../src/game
../../src/game/vmap
../../dep/include/g3dlite
../../src/framework
../../dep/ACE_wrappers
../../objdir/dep/ACE_wrappers
../../dep/recastnavigation/Detour/Include
../../dep/recastnavigation/Recast/Include
../../dep/src/zlib
)
add_library(zlib
../../dep/src/zlib/adler32.c
../../dep/src/zlib/compress.c
../../dep/src/zlib/crc32.c
../../dep/src/zlib/deflate.c
../../dep/src/zlib/example.c
../../dep/src/zlib/gzio.c
../../dep/src/zlib/infback.c
../../dep/src/zlib/inffast.c
../../dep/src/zlib/inflate.c
../../dep/src/zlib/inftrees.c
../../dep/src/zlib/trees.c
../../dep/src/zlib/uncompr.c
../../dep/src/zlib/zutil.c
)
add_library(g3dlite
../../dep/src/g3dlite/AABox.cpp
../../dep/src/g3dlite/Any.cpp
../../dep/src/g3dlite/AnyVal.cpp
../../dep/src/g3dlite/AreaMemoryManager.cpp
../../dep/src/g3dlite/BinaryFormat.cpp
../../dep/src/g3dlite/BinaryInput.cpp
../../dep/src/g3dlite/BinaryOutput.cpp
../../dep/src/g3dlite/Box.cpp
../../dep/src/g3dlite/Box2D.cpp
../../dep/src/g3dlite/BumpMapPreprocess.cpp
../../dep/src/g3dlite/Capsule.cpp
../../dep/src/g3dlite/CollisionDetection.cpp
../../dep/src/g3dlite/Color1.cpp
../../dep/src/g3dlite/Color1uint8.cpp
../../dep/src/g3dlite/Color3.cpp
../../dep/src/g3dlite/Color3uint8.cpp
../../dep/src/g3dlite/Color4.cpp
../../dep/src/g3dlite/Color4uint8.cpp
../../dep/src/g3dlite/Cone.cpp
../../dep/src/g3dlite/constants.cpp
../../dep/src/g3dlite/ConvexPolyhedron.cpp
../../dep/src/g3dlite/CoordinateFrame.cpp
../../dep/src/g3dlite/Crypto.cpp
../../dep/src/g3dlite/Crypto_md5.cpp
../../dep/src/g3dlite/Cylinder.cpp
../../dep/src/g3dlite/debugAssert.cpp
../../dep/src/g3dlite/fileutils.cpp
../../dep/src/g3dlite/filter.cpp
../../dep/src/g3dlite/format.cpp
../../dep/src/g3dlite/g3dfnmatch.cpp
../../dep/src/g3dlite/g3dmath.cpp
../../dep/src/g3dlite/GCamera.cpp
../../dep/src/g3dlite/GLight.cpp
../../dep/src/g3dlite/GThread.cpp
../../dep/src/g3dlite/GUniqueID.cpp
../../dep/src/g3dlite/Intersect.cpp
../../dep/src/g3dlite/license.cpp
../../dep/src/g3dlite/Line.cpp
../../dep/src/g3dlite/LineSegment.cpp
../../dep/src/g3dlite/Log.cpp
../../dep/src/g3dlite/Matrix.cpp
../../dep/src/g3dlite/Matrix3.cpp
../../dep/src/g3dlite/Matrix4.cpp
../../dep/src/g3dlite/MemoryManager.cpp
../../dep/src/g3dlite/MeshAlg.cpp
../../dep/src/g3dlite/MeshAlgAdjacency.cpp
../../dep/src/g3dlite/MeshAlgWeld.cpp
../../dep/src/g3dlite/MeshBuilder.cpp
../../dep/src/g3dlite/NetAddress.cpp
../../dep/src/g3dlite/NetworkDevice.cpp
../../dep/src/g3dlite/PhysicsFrame.cpp
../../dep/src/g3dlite/Plane.cpp
../../dep/src/g3dlite/PrecomputedRandom.cpp
../../dep/src/g3dlite/prompt.cpp
../../dep/src/g3dlite/Quat.cpp
../../dep/src/g3dlite/Random.cpp
../../dep/src/g3dlite/Ray.cpp
../../dep/src/g3dlite/Rect2D.cpp
../../dep/src/g3dlite/ReferenceCount.cpp
../../dep/src/g3dlite/RegistryUtil.cpp
../../dep/src/g3dlite/Sphere.cpp
../../dep/src/g3dlite/SplineBase.cpp
../../dep/src/g3dlite/stringutils.cpp
../../dep/src/g3dlite/System.cpp
../../dep/src/g3dlite/TextInput.cpp
../../dep/src/g3dlite/TextOutput.cpp
../../dep/src/g3dlite/ThreadSet.cpp
../../dep/src/g3dlite/Triangle.cpp
../../dep/src/g3dlite/uint128.cpp
../../dep/src/g3dlite/UprightFrame.cpp
../../dep/src/g3dlite/Vector2.cpp
../../dep/src/g3dlite/Vector2int16.cpp
../../dep/src/g3dlite/Vector3.cpp
../../dep/src/g3dlite/Vector3int16.cpp
../../dep/src/g3dlite/Vector3int32.cpp
../../dep/src/g3dlite/Vector4.cpp
../../dep/src/g3dlite/Vector4int8.cpp
../../dep/src/g3dlite/Welder.cpp
../../dep/src/g3dlite/WinMain.cpp
)
add_library(vmap
../../src/game/vmap/BIH.cpp
../../src/game/vmap/VMapManager2.cpp
../../src/game/vmap/MapTree.cpp
../../src/game/vmap/TileAssembler.cpp
../../src/game/vmap/WorldModel.cpp
../../src/game/vmap/ModelInstance.cpp
)
target_link_libraries(vmap g3dlite zlib)
add_library(Detour
../../dep/recastnavigation/Detour/Source/DetourAlloc.cpp
../../dep/recastnavigation/Detour/Source/DetourCommon.cpp
../../dep/recastnavigation/Detour/Source/DetourNavMesh.cpp
../../dep/recastnavigation/Detour/Source/DetourNavMeshBuilder.cpp
../../dep/recastnavigation/Detour/Source/DetourNavMeshQuery.cpp
../../dep/recastnavigation/Detour/Source/DetourNode.cpp
)
add_library(Recast
../../dep/recastnavigation/Recast/Source/Recast.cpp
../../dep/recastnavigation/Recast/Source/RecastAlloc.cpp
../../dep/recastnavigation/Recast/Source/RecastArea.cpp
../../dep/recastnavigation/Recast/Source/RecastContour.cpp
../../dep/recastnavigation/Recast/Source/RecastFilter.cpp
../../dep/recastnavigation/Recast/Source/RecastMesh.cpp
../../dep/recastnavigation/Recast/Source/RecastMeshDetail.cpp
../../dep/recastnavigation/Recast/Source/RecastRasterization.cpp
../../dep/recastnavigation/Recast/Source/RecastRegion.cpp
)
set(SOURCES
./src/IntermediateValues.cpp
./src/generator.cpp
./src/MapBuilder.cpp
./src/TerrainBuilder.cpp
./src/VMapExtensions.cpp
)
add_executable( MoveMapGen ${SOURCES} )
target_link_libraries( MoveMapGen g3dlite vmap Detour Recast zlib )

View file

@ -0,0 +1,60 @@
#!/usr/bin/python
"""
Copyright (C) 2005-2012 MaNGOS <http://getmangos.com/>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, 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,628,631,632,641,642,647,649,650,
658,668,672,673,712,713,718,723,724])
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 = "MoveMapGen.exe"
else:
stInfo = None
cFlags = 0
binName = "./MoveMapGen"
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.1)

View file

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

66
contrib/mmap/readme Normal file
View file

@ -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:
movemapgen
builds maps using the default settings (see above for defaults)
movemapgen --skipContinents true
builds the default maps, except continents
movemapgen 0
builds all tiles of map 0
movemapgen 0 --tile 34,46
builds only tile 34,46 of map 0 (this is the southern face of blackrock mountain)

View file

@ -0,0 +1,277 @@
/*
* Copyright (C) 2005-2012 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#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<float> allVerts;
G3D::Array<int> 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);
}
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (C) 2005-2012 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _INTERMEDIATE_VALUES_H
#define _INTERMEDIATE_VALUES_H
#include "MMapCommon.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

View file

@ -0,0 +1,129 @@
/*
* Copyright (C) 2005-2012 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _MMAP_COMMON_H
#define _MMAP_COMMON_H
// stop warning spam from ACE includes
#ifdef WIN32
# pragma warning( disable : 4996 )
#endif
#include <string>
#include <vector>
#include "Platform/Define.h"
#ifndef WIN32
#include <stddef.h>
#include <dirent.h>
#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<string> &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;
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

View file

@ -0,0 +1,105 @@
/*
* Copyright (C) 2005-2012 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _MMAP_MANGOS_MAP_H
#define _MMAP_MANGOS_MAP_H
// following is copied from src/game/GridMap.h (too many useless includes there to use original file)
namespace MaNGOS
{
struct GridMapFileHeader
{
uint32 mapMagic;
uint32 versionMagic;
uint32 buildMagic;
uint32 areaMapOffset;
uint32 areaMapSize;
uint32 heightMapOffset;
uint32 heightMapSize;
uint32 liquidMapOffset;
uint32 liquidMapSize;
uint32 holesOffset;
uint32 holesSize;
};
// ==============mmaps don't use area==============
//#define MAP_AREA_NO_AREA 0x0001
//struct GridMapAreaHeader
//{
// uint32 fourcc;
// uint16 flags;
// uint16 gridArea;
//};
#define MAP_HEIGHT_NO_HEIGHT 0x0001
#define MAP_HEIGHT_AS_INT16 0x0002
#define MAP_HEIGHT_AS_INT8 0x0004
struct GridMapHeightHeader
{
uint32 fourcc;
uint32 flags;
float gridHeight;
float gridMaxHeight;
};
#define MAP_LIQUID_NO_TYPE 0x0001
#define MAP_LIQUID_NO_HEIGHT 0x0002
struct GridMapLiquidHeader
{
uint32 fourcc;
uint16 flags;
uint16 liquidType;
uint8 offsetX;
uint8 offsetY;
uint8 width;
uint8 height;
float liquidLevel;
};
//enum GridMapLiquidStatus
//{
// LIQUID_MAP_NO_WATER = 0x00000000,
// LIQUID_MAP_ABOVE_WATER = 0x00000001,
// LIQUID_MAP_WATER_WALK = 0x00000002,
// LIQUID_MAP_IN_WATER = 0x00000004,
// LIQUID_MAP_UNDER_WATER = 0x00000008
//};
#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_ALL_LIQUIDS (MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN | MAP_LIQUID_TYPE_MAGMA | MAP_LIQUID_TYPE_SLIME)
#define MAP_LIQUID_TYPE_DARK_WATER 0x10
#define MAP_LIQUID_TYPE_WMO_WATER 0x20
//struct GridMapLiquidData
//{
// uint32 type;
// float level;
// float depth_level;
//};
}
#endif

View file

@ -0,0 +1,882 @@
/*
* Copyright (C) 2005-2012 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "MMapCommon.h"
#include "MapBuilder.h"
#include "MapTree.h"
#include "ModelInstance.h"
#include "DetourNavMeshBuilder.h"
#include "DetourCommon.h"
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<string> 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<uint32,set<uint32>*>(mapID, new set<uint32>));
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<uint32,set<uint32>*>(mapID, new set<uint32>));
count++;
}
printf("found %u.\n", count);
count = 0;
printf("Discovering tiles... ");
for (TileList::iterator itr = m_tiles.begin(); itr != m_tiles.end(); ++itr)
{
set<uint32>* 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<uint32>* MapBuilder::getTileList(uint32 mapID)
{
TileList::iterator itr = m_tiles.find(mapID);
if (itr != m_tiles.end())
return (*itr).second;
set<uint32>* tiles = new set<uint32>();
m_tiles.insert(pair<uint32, set<uint32>*>(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<uint32>* 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<uint32>::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<float> 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<uint32>* 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<uint32>::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(&params, 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(&params, &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;
}
}

View file

@ -0,0 +1,128 @@
/*
* Copyright (C) 2005-2012 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _MAP_BUILDER_H
#define _MAP_BUILDER_H
#include <vector>
#include <set>
#include <map>
#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<uint32,set<uint32>*> 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<uint32>* 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

View file

@ -0,0 +1,855 @@
/*
* Copyright (C) 2005-2012 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "TerrainBuilder.h"
#include "MMapCommon.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;
GridMapFileHeader fheader;
fread(&fheader, sizeof(GridMapFileHeader), 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;
}
GridMapHeightHeader hheader;
fseek(mapFile, fheader.heightMapOffset, SEEK_SET);
fread(&hheader, sizeof(GridMapHeightHeader), 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<int> ltriangles;
G3D::Array<int> 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)
{
GridMapLiquidHeader lheader;
fseek(mapFile, fheader.liquidMapOffset, SEEK_SET);
fread(&lheader, sizeof(GridMapLiquidHeader), 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();
VMAPLoadResult 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<GroupModel> 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<GroupModel>::iterator it = groupModels.begin(); it != groupModels.end(); ++it)
{
vector<Vector3> tempVertices;
vector<Vector3> transformedVertices;
vector<MeshTriangle> 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<Vector3> liqVerts;
vector<int> 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<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);
v.x *= -1.f;
v.y *= -1.f;
transformedVertices.push_back(v);
}
}
/**************************************************************************/
void TerrainBuilder::copyVertices(vector<Vector3> &source, G3D::Array<float> &dest)
{
for (vector<Vector3>::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<MeshTriangle> &source, G3D::Array<int> &dest, int offset, bool flip)
{
if (flip)
{
for (vector<MeshTriangle>::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<MeshTriangle>::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<int> &source, G3D::Array<int> &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<float> &verts, G3D::Array<int> &tris)
{
map<int, int> 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<int, int>(t[i], 0));
}
// collect the vertices
G3D::Array<float> cleanVerts;
int index, count = 0;
for (map<int, int>::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<int, int>::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);
}
}

View file

@ -0,0 +1,137 @@
/*
* Copyright (C) 2005-2012 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _MMAP_TERRAIN_BUILDER_H
#define _MMAP_TERRAIN_BUILDER_H
#include "MMapCommon.h"
#include "MangosMap.h"
#include "../../src/game/MoveMapSharedDefines.h"
#include "WorldModel.h"
#include "G3D/Array.h"
#include "G3D/Vector3.h"
#include "G3D/Matrix3.h"
using namespace MaNGOS;
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/GridMap.cpp
static char const* MAP_VERSION_MAGIC = "v1.1";
struct MeshData
{
G3D::Array<float> solidVerts;
G3D::Array<int> solidTris;
G3D::Array<float> liquidVerts;
G3D::Array<int> liquidTris;
G3D::Array<uint8> liquidType;
// 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;
};
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<G3D::Vector3> &original, vector<G3D::Vector3> &transformed,
float scale, G3D::Matrix3 &rotation, G3D::Vector3 &position);
static void copyVertices(vector<G3D::Vector3> &source, G3D::Array<float> &dest);
static void copyIndices(vector<VMAP::MeshTriangle> &source, G3D::Array<int> &dest, int offest, bool flip);
static void copyIndices(G3D::Array<int> &src, G3D::Array<int> &dest, int offset);
static void cleanVertices(G3D::Array<float> &verts, G3D::Array<int> &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<float> &vertices, G3D::Array<int> &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

View file

@ -0,0 +1,73 @@
/*
* Copyright (C) 2005-2012 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <vector>
#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<GroupModel> &groupModels)
{
groupModels = this->groupModels;
}
// declared in src/shared/vmap/WorldModel.h
void GroupModel::getMeshData(vector<Vector3> &vertices, vector<MeshTriangle> &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;
}
}

View file

@ -0,0 +1,273 @@
/*
* Copyright (C) 2005-2012 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "MMapCommon.h"
#include "MapBuilder.h"
using namespace MMAP;
bool checkDirectories(bool debugOutput)
{
vector<string> 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);
}

View file

@ -0,0 +1,87 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MoveMapGen", "VC100\MoveMapGen_VC100.vcxproj", "{8028C1F8-4C3E-44D4-96D7-1D6F51B7AB47}"
ProjectSection(ProjectDependencies) = postProject
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2} = {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64} = {00B9DC66-96A6-465D-A6C1-5DFF94E48A64}
{8072769E-CF10-48BF-B9E1-12752A5DAC6E} = {8072769E-CF10-48BF-B9E1-12752A5DAC6E}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "g3dlite", "..\..\..\win\VC100\g3dlite.vcxproj", "{8072769E-CF10-48BF-B9E1-12752A5DAC6E}"
ProjectSection(ProjectDependencies) = postProject
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2} = {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\..\win\VC100\zlib.vcxproj", "{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Recast", "..\..\..\dep\recastnavigation\Recast\win\VC100\Recast.vcxproj", "{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Detour", "..\..\..\dep\recastnavigation\Detour\win\VC100\Detour.vcxproj", "{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug_NoPCH|Win32 = Debug_NoPCH|Win32
Debug_NoPCH|x64 = Debug_NoPCH|x64
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8028C1F8-4C3E-44D4-96D7-1D6F51B7AB47}.Debug_NoPCH|Win32.ActiveCfg = Debug|Win32
{8028C1F8-4C3E-44D4-96D7-1D6F51B7AB47}.Debug_NoPCH|Win32.Build.0 = Debug|Win32
{8028C1F8-4C3E-44D4-96D7-1D6F51B7AB47}.Debug_NoPCH|x64.ActiveCfg = Debug|Win32
{8028C1F8-4C3E-44D4-96D7-1D6F51B7AB47}.Debug|Win32.ActiveCfg = Debug|Win32
{8028C1F8-4C3E-44D4-96D7-1D6F51B7AB47}.Debug|Win32.Build.0 = Debug|Win32
{8028C1F8-4C3E-44D4-96D7-1D6F51B7AB47}.Debug|x64.ActiveCfg = Debug|Win32
{8028C1F8-4C3E-44D4-96D7-1D6F51B7AB47}.Release|Win32.ActiveCfg = Release|Win32
{8028C1F8-4C3E-44D4-96D7-1D6F51B7AB47}.Release|Win32.Build.0 = Release|Win32
{8028C1F8-4C3E-44D4-96D7-1D6F51B7AB47}.Release|x64.ActiveCfg = Release|Win32
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug_NoPCH|Win32.ActiveCfg = Debug_NoPCH|Win32
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug_NoPCH|Win32.Build.0 = Debug_NoPCH|Win32
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug_NoPCH|x64.ActiveCfg = Debug_NoPCH|x64
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug_NoPCH|x64.Build.0 = Debug_NoPCH|x64
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|Win32.ActiveCfg = Debug|Win32
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|Win32.Build.0 = Debug|Win32
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|x64.ActiveCfg = Debug|x64
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|x64.Build.0 = Debug|x64
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|Win32.ActiveCfg = Release|Win32
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|Win32.Build.0 = Release|Win32
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|x64.ActiveCfg = Release|x64
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|x64.Build.0 = Release|x64
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug_NoPCH|Win32.ActiveCfg = Debug_NoPCH|Win32
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug_NoPCH|Win32.Build.0 = Debug_NoPCH|Win32
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug_NoPCH|x64.ActiveCfg = Debug_NoPCH|x64
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug_NoPCH|x64.Build.0 = Debug_NoPCH|x64
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|Win32.ActiveCfg = Debug|Win32
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|Win32.Build.0 = Debug|Win32
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|x64.ActiveCfg = Debug|x64
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|x64.Build.0 = Debug|x64
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|Win32.ActiveCfg = Release|Win32
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|Win32.Build.0 = Release|Win32
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|x64.ActiveCfg = Release|x64
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|x64.Build.0 = Release|x64
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Debug_NoPCH|Win32.ActiveCfg = Debug|Win32
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Debug_NoPCH|Win32.Build.0 = Debug|Win32
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Debug_NoPCH|x64.ActiveCfg = Debug|Win32
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Debug|Win32.ActiveCfg = Debug|Win32
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Debug|Win32.Build.0 = Debug|Win32
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Debug|x64.ActiveCfg = Debug|Win32
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Release|Win32.ActiveCfg = Release|Win32
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Release|Win32.Build.0 = Release|Win32
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Release|x64.ActiveCfg = Release|Win32
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Debug_NoPCH|Win32.ActiveCfg = Debug|Win32
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Debug_NoPCH|Win32.Build.0 = Debug|Win32
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Debug_NoPCH|x64.ActiveCfg = Debug|Win32
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Debug|Win32.ActiveCfg = Debug|Win32
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Debug|Win32.Build.0 = Debug|Win32
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Debug|x64.ActiveCfg = Debug|Win32
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Release|Win32.ActiveCfg = Release|Win32
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Release|Win32.Build.0 = Release|Win32
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,85 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MoveMapGen", "VC90\MoveMapGen.vcproj", "{97193524-E639-4CBD-AFE4-0CFF84D9656E}"
ProjectSection(ProjectDependencies) = postProject
{B6137343-A2F6-4AE7-BA47-484EC0EF369C} = {B6137343-A2F6-4AE7-BA47-484EC0EF369C}
{5FDC0EBC-3F80-4518-A5DF-1CD5BBEB64F7} = {5FDC0EBC-3F80-4518-A5DF-1CD5BBEB64F7}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "g3dlite", "..\..\..\win\VC90\g3dlite.vcproj", "{8072769E-CF10-48BF-B9E1-12752A5DAC6E}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\..\win\VC90\zlib.vcproj", "{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Recast", "..\..\..\dep\recastnavigation\Recast\win\VC90\Recast.vcproj", "{B6137343-A2F6-4AE7-BA47-484EC0EF369C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Detour", "..\..\..\dep\recastnavigation\Detour\win\VC90\Detour.vcproj", "{5FDC0EBC-3F80-4518-A5DF-1CD5BBEB64F7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug_NoPCH|Win32 = Debug_NoPCH|Win32
Debug_NoPCH|x64 = Debug_NoPCH|x64
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{97193524-E639-4CBD-AFE4-0CFF84D9656E}.Debug_NoPCH|Win32.ActiveCfg = Debug|Win32
{97193524-E639-4CBD-AFE4-0CFF84D9656E}.Debug_NoPCH|Win32.Build.0 = Debug|Win32
{97193524-E639-4CBD-AFE4-0CFF84D9656E}.Debug_NoPCH|x64.ActiveCfg = Debug|Win32
{97193524-E639-4CBD-AFE4-0CFF84D9656E}.Debug|Win32.ActiveCfg = Debug|Win32
{97193524-E639-4CBD-AFE4-0CFF84D9656E}.Debug|Win32.Build.0 = Debug|Win32
{97193524-E639-4CBD-AFE4-0CFF84D9656E}.Debug|x64.ActiveCfg = Debug|Win32
{97193524-E639-4CBD-AFE4-0CFF84D9656E}.Release|Win32.ActiveCfg = Release|Win32
{97193524-E639-4CBD-AFE4-0CFF84D9656E}.Release|Win32.Build.0 = Release|Win32
{97193524-E639-4CBD-AFE4-0CFF84D9656E}.Release|x64.ActiveCfg = Release|Win32
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug_NoPCH|Win32.ActiveCfg = Debug_NoPCH|Win32
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug_NoPCH|Win32.Build.0 = Debug_NoPCH|Win32
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug_NoPCH|x64.ActiveCfg = Debug_NoPCH|x64
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug_NoPCH|x64.Build.0 = Debug_NoPCH|x64
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|Win32.ActiveCfg = Debug|Win32
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|Win32.Build.0 = Debug|Win32
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|x64.ActiveCfg = Debug|x64
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|x64.Build.0 = Debug|x64
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|Win32.ActiveCfg = Release|Win32
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|Win32.Build.0 = Release|Win32
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|x64.ActiveCfg = Release|x64
{8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|x64.Build.0 = Release|x64
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug_NoPCH|Win32.ActiveCfg = Debug_NoPCH|Win32
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug_NoPCH|Win32.Build.0 = Debug_NoPCH|Win32
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug_NoPCH|x64.ActiveCfg = Debug_NoPCH|x64
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug_NoPCH|x64.Build.0 = Debug_NoPCH|x64
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|Win32.ActiveCfg = Debug|Win32
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|Win32.Build.0 = Debug|Win32
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|x64.ActiveCfg = Debug|x64
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|x64.Build.0 = Debug|x64
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|Win32.ActiveCfg = Release|Win32
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|Win32.Build.0 = Release|Win32
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|x64.ActiveCfg = Release|x64
{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|x64.Build.0 = Release|x64
{B6137343-A2F6-4AE7-BA47-484EC0EF369C}.Debug_NoPCH|Win32.ActiveCfg = Debug|Win32
{B6137343-A2F6-4AE7-BA47-484EC0EF369C}.Debug_NoPCH|Win32.Build.0 = Debug|Win32
{B6137343-A2F6-4AE7-BA47-484EC0EF369C}.Debug_NoPCH|x64.ActiveCfg = Debug|Win32
{B6137343-A2F6-4AE7-BA47-484EC0EF369C}.Debug|Win32.ActiveCfg = Debug|Win32
{B6137343-A2F6-4AE7-BA47-484EC0EF369C}.Debug|Win32.Build.0 = Debug|Win32
{B6137343-A2F6-4AE7-BA47-484EC0EF369C}.Debug|x64.ActiveCfg = Debug|Win32
{B6137343-A2F6-4AE7-BA47-484EC0EF369C}.Release|Win32.ActiveCfg = Release|Win32
{B6137343-A2F6-4AE7-BA47-484EC0EF369C}.Release|Win32.Build.0 = Release|Win32
{B6137343-A2F6-4AE7-BA47-484EC0EF369C}.Release|x64.ActiveCfg = Release|Win32
{5FDC0EBC-3F80-4518-A5DF-1CD5BBEB64F7}.Debug_NoPCH|Win32.ActiveCfg = Debug|x64
{5FDC0EBC-3F80-4518-A5DF-1CD5BBEB64F7}.Debug_NoPCH|x64.ActiveCfg = Debug|x64
{5FDC0EBC-3F80-4518-A5DF-1CD5BBEB64F7}.Debug_NoPCH|x64.Build.0 = Debug|x64
{5FDC0EBC-3F80-4518-A5DF-1CD5BBEB64F7}.Debug|Win32.ActiveCfg = Debug|Win32
{5FDC0EBC-3F80-4518-A5DF-1CD5BBEB64F7}.Debug|Win32.Build.0 = Debug|Win32
{5FDC0EBC-3F80-4518-A5DF-1CD5BBEB64F7}.Debug|x64.ActiveCfg = Debug|x64
{5FDC0EBC-3F80-4518-A5DF-1CD5BBEB64F7}.Debug|x64.Build.0 = Debug|x64
{5FDC0EBC-3F80-4518-A5DF-1CD5BBEB64F7}.Release|Win32.ActiveCfg = Release|Win32
{5FDC0EBC-3F80-4518-A5DF-1CD5BBEB64F7}.Release|Win32.Build.0 = Release|Win32
{5FDC0EBC-3F80-4518-A5DF-1CD5BBEB64F7}.Release|x64.ActiveCfg = Release|x64
{5FDC0EBC-3F80-4518-A5DF-1CD5BBEB64F7}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

6
contrib/mmap/win/VC100/.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
*Win32_Debug
*Win32_Release
*x64_Debug
*x64_Release
*.user

View file

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{8028C1F8-4C3E-44D4-96D7-1D6F51B7AB47}</ProjectGuid>
<RootNamespace>MoveMapGen_VC100</RootNamespace>
<ProjectName>MoveMapGen</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>..\..\bin\$(Platform)_$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>..\..\bin\$(Platform)_$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\src\;..\..\..\..\dep\recastnavigation\Detour\Include\;..\..\..\..\dep\recastnavigation\Recast\Include\;..\..\..\..\src\game\vmap;..\..\..\..\dep\include\g3dlite;..\..\..\..\src\framework\;..\..\..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;DEBUG;MMAP_GENERATOR;NO_CORE_FUNCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>
</AdditionalLibraryDirectories>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<AdditionalDependencies>msvcrtd.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<LargeAddressAware>true</LargeAddressAware>
</Link>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..\src\;..\..\..\..\dep\recastnavigation\Detour\Include\;..\..\..\..\dep\recastnavigation\Recast\Include\;..\..\..\..\src\game\vmap;..\..\..\..\dep\include\g3dlite;..\..\..\..\src\framework\;..\..\..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<PreprocessorDefinitions>WIN32;NDEBUG;MMAP_GENERATOR;_CRT_SECURE_NO_WARNINGS;NO_CORE_FUNCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<AdditionalDependencies>msvcrt.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>
</AdditionalLibraryDirectories>
<GenerateMapFile>true</GenerateMapFile>
<LargeAddressAware>true</LargeAddressAware>
</Link>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
<ProjectReference>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
</ProjectReference>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\..\src\game\vmap\BIH.cpp" />
<ClCompile Include="..\..\..\..\src\game\vmap\MapTree.cpp" />
<ClCompile Include="..\..\..\..\src\game\vmap\ModelInstance.cpp" />
<ClCompile Include="..\..\..\..\src\game\vmap\TileAssembler.cpp" />
<ClCompile Include="..\..\..\..\src\game\vmap\VMapFactory.cpp" />
<ClCompile Include="..\..\..\..\src\game\vmap\VMapManager2.cpp" />
<ClCompile Include="..\..\..\..\src\game\vmap\WorldModel.cpp" />
<ClCompile Include="..\..\src\generator.cpp" />
<ClCompile Include="..\..\src\MapBuilder.cpp" />
<ClCompile Include="..\..\src\TerrainBuilder.cpp" />
<ClCompile Include="..\..\src\VMapExtensions.cpp" />
<ClCompile Include="..\..\src\IntermediateValues.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\..\src\game\vmap\BIH.h" />
<ClInclude Include="..\..\..\..\src\game\vmap\IVMapManager.h" />
<ClInclude Include="..\..\..\..\src\game\vmap\MapTree.h" />
<ClInclude Include="..\..\..\..\src\game\vmap\ModelInstance.h" />
<ClInclude Include="..\..\..\..\src\game\vmap\TileAssembler.h" />
<ClInclude Include="..\..\..\..\src\game\vmap\VMapDefinitions.h" />
<ClInclude Include="..\..\..\..\src\game\vmap\VMapFactory.h" />
<ClInclude Include="..\..\..\..\src\game\vmap\VMapManager2.h" />
<ClInclude Include="..\..\..\..\src\game\vmap\VMapTools.h" />
<ClInclude Include="..\..\..\..\src\game\vmap\WorldModel.h" />
<ClInclude Include="..\..\..\..\src\game\MoveMapSharedDefines.h" />
<ClInclude Include="..\..\src\MangosMap.h" />
<ClInclude Include="..\..\src\MapBuilder.h" />
<ClInclude Include="..\..\src\MMapCommon.h" />
<ClInclude Include="..\..\src\TerrainBuilder.h" />
<ClInclude Include="..\..\src\IntermediateValues.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\dep\recastnavigation\Detour\win\VC100\Detour.vcxproj">
<Project>{72bdf975-4d4a-42c7-b2c4-f9ed90a2abb6}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\dep\recastnavigation\Recast\win\VC100\Recast.vcxproj">
<Project>{00b9dc66-96a6-465d-a6c1-5dff94e48a64}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\win\VC100\g3dlite.vcxproj">
<Project>{8072769e-cf10-48bf-b9e1-12752a5dac6e}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\win\VC100\zlib.vcxproj">
<Project>{8f1dea42-6a5b-4b62-839d-c141a7bfacf2}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="generator">
<UniqueIdentifier>{dcfc8b46-b41f-4c19-9f6b-257a463f6c67}</UniqueIdentifier>
</Filter>
<Filter Include="vmap">
<UniqueIdentifier>{8c2c5f18-4147-4fdb-bd45-aa9664476e6c}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\generator.cpp">
<Filter>generator</Filter>
</ClCompile>
<ClCompile Include="..\..\src\VMapExtensions.cpp">
<Filter>generator</Filter>
</ClCompile>
<ClCompile Include="..\..\src\MapBuilder.cpp">
<Filter>generator</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\game\vmap\BIH.cpp">
<Filter>vmap</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\game\vmap\MapTree.cpp">
<Filter>vmap</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\game\vmap\ModelInstance.cpp">
<Filter>vmap</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\game\vmap\TileAssembler.cpp">
<Filter>vmap</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\game\vmap\VMapFactory.cpp">
<Filter>vmap</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\game\vmap\VMapManager2.cpp">
<Filter>vmap</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\game\vmap\WorldModel.cpp">
<Filter>vmap</Filter>
</ClCompile>
<ClCompile Include="..\..\src\TerrainBuilder.cpp">
<Filter>generator</Filter>
</ClCompile>
<ClCompile Include="..\..\src\IntermediateValues.cpp">
<Filter>generator</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\MMapCommon.h">
<Filter>generator</Filter>
</ClInclude>
<ClInclude Include="..\..\src\IntermediateValues.h">
<Filter>generator</Filter>
</ClInclude>
<ClInclude Include="..\..\src\MangosMap.h">
<Filter>generator</Filter>
</ClInclude>
<ClInclude Include="..\..\src\MapBuilder.h">
<Filter>generator</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\src\game\MoveMapSharedDefines.h">
<Filter>generator</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\src\game\vmap\BIH.h">
<Filter>vmap</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\src\game\vmap\IVMapManager.h">
<Filter>vmap</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\src\game\vmap\MapTree.h">
<Filter>vmap</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\src\game\vmap\ModelInstance.h">
<Filter>vmap</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\src\game\vmap\TileAssembler.h">
<Filter>vmap</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\src\game\vmap\VMapDefinitions.h">
<Filter>vmap</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\src\game\vmap\VMapFactory.h">
<Filter>vmap</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\src\game\vmap\VMapManager2.h">
<Filter>vmap</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\src\game\vmap\VMapTools.h">
<Filter>vmap</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\src\game\vmap\WorldModel.h">
<Filter>vmap</Filter>
</ClInclude>
<ClInclude Include="..\..\src\TerrainBuilder.h">
<Filter>generator</Filter>
</ClInclude>
</ItemGroup>
</Project>

6
contrib/mmap/win/VC90/.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
*Win32_Release
*Win32_Debug
*x64_Release
*x64_Debug
*.user

View file

@ -0,0 +1,297 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="MoveMapGen"
ProjectGUID="{97193524-E639-4CBD-AFE4-0CFF84D9656E}"
RootNamespace="MoveMapGen"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\..\bin\$(PlatformName)_$(ConfigurationName)\"
IntermediateDirectory=".\$(ProjectName)__$(PlatformName)_$(ConfigurationName)\"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
FavorSizeOrSpeed="1"
WholeProgramOptimization="false"
AdditionalIncludeDirectories="..\..\src\;..\..\..\..\src\game\vmap;..\..\..\..\dep\include\g3dlite\;..\..\..\..\src\framework\;..\..\..\..\dep\ACE_wrappers\;..\..\..\..\dep\recastnavigation\Detour\Include\;..\..\..\..\dep\recastnavigation\Recast\Include\;"
PreprocessorDefinitions="WIN32;DEBUG;MMAP_GENERATOR;NO_CORE_FUNCS;"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="Detour.lib Recast.lib g3dlite.lib zlib.lib"
AdditionalLibraryDirectories="..\..\..\..\dep\lib\$(PlatformName)_$(ConfigurationName)\;..\..\..\..\win\VC90\g3dlite__$(PlatformName)_$(ConfigurationName)\;..\..\..\..\win\VC90\zlib__$(PlatformName)_$(ConfigurationName)\"
GenerateDebugInformation="true"
LargeAddressAware="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\..\bin\$(PlatformName)_$(ConfigurationName)\"
IntermediateDirectory=".\$(ProjectName)__$(PlatformName)_$(ConfigurationName)\"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
AdditionalIncludeDirectories="..\..\src\;..\..\..\..\src\game\vmap;..\..\..\..\dep\include\g3dlite\;..\..\..\..\src\framework\;..\..\..\..\dep\ACE_wrappers\;..\..\..\..\dep\recastnavigation\Detour\Include\;..\..\..\..\dep\recastnavigation\Recast\Include\;"
PreprocessorDefinitions="WIN32;NDEBUG;MMAP_GENERATOR;NO_CORE_FUNCS;"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="Detour.lib Recast.lib g3dlite.lib zlib.lib"
AdditionalLibraryDirectories="..\..\..\..\dep\lib\$(PlatformName)_$(ConfigurationName)\;..\..\..\..\win\VC90\g3dlite__$(PlatformName)_$(ConfigurationName)\;..\..\..\..\win\VC90\zlib__$(PlatformName)_$(ConfigurationName)\"
GenerateDebugInformation="true"
LargeAddressAware="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="generator"
>
<File
RelativePath="..\..\src\generator.cpp"
>
</File>
<File
RelativePath="..\..\src\MangosMap.h"
>
</File>
<File
RelativePath="..\..\..\..\src\game\MoveMapSharedDefines.h"
>
</File>
<File
RelativePath="..\..\src\MapBuilder.cpp"
>
</File>
<File
RelativePath="..\..\src\MapBuilder.h"
>
</File>
<File
RelativePath="..\..\src\MMapCommon.h"
>
</File>
<File
RelativePath="..\..\src\TerrainBuilder.cpp"
>
</File>
<File
RelativePath="..\..\src\TerrainBuilder.h"
>
</File>
<File
RelativePath="..\..\src\VMapExtensions.cpp"
>
</File>
<File
RelativePath="..\..\src\IntermediateValues.h"
>
</File>
<File
RelativePath="..\..\src\IntermediateValues.cpp"
>
</File>
</Filter>
<Filter
Name="vmap"
>
<File
RelativePath="..\..\..\..\src\game\vmap\BIH.cpp"
>
</File>
<File
RelativePath="..\..\..\..\src\game\vmap\BIH.h"
>
</File>
<File
RelativePath="..\..\..\..\src\game\vmap\IVMapManager.h"
>
</File>
<File
RelativePath="..\..\..\..\src\game\vmap\MapTree.cpp"
>
</File>
<File
RelativePath="..\..\..\..\src\game\vmap\MapTree.h"
>
</File>
<File
RelativePath="..\..\..\..\src\game\vmap\ModelInstance.cpp"
>
</File>
<File
RelativePath="..\..\..\..\src\game\vmap\ModelInstance.h"
>
</File>
<File
RelativePath="..\..\..\..\src\game\vmap\TileAssembler.cpp"
>
</File>
<File
RelativePath="..\..\..\..\src\game\vmap\TileAssembler.h"
>
</File>
<File
RelativePath="..\..\..\..\src\game\vmap\VMapDefinitions.h"
>
</File>
<File
RelativePath="..\..\..\..\src\game\vmap\VMapFactory.cpp"
>
</File>
<File
RelativePath="..\..\..\..\src\game\vmap\VMapFactory.h"
>
</File>
<File
RelativePath="..\..\..\..\src\game\vmap\VMapManager2.cpp"
>
</File>
<File
RelativePath="..\..\..\..\src\game\vmap\VMapManager2.h"
>
</File>
<File
RelativePath="..\..\..\..\src\game\vmap\VMapTools.h"
>
</File>
<File
RelativePath="..\..\..\..\src\game\vmap\WorldModel.cpp"
>
</File>
<File
RelativePath="..\..\..\..\src\game\vmap\WorldModel.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "11902"
#define REVISION_NR "11903"
#endif // __REVISION_NR_H__