34#define MAP_HEIGHT_NO_HEIGHT 0x0001
35#define MAP_HEIGHT_AS_INT16 0x0002
36#define MAP_HEIGHT_AS_INT8 0x0004
46#define MAP_LIQUID_NO_TYPE 0x0001
47#define MAP_LIQUID_NO_HEIGHT 0x0002
61#define MAP_LIQUID_TYPE_NO_WATER 0x00
62#define MAP_LIQUID_TYPE_WATER 0x01
63#define MAP_LIQUID_TYPE_OCEAN 0x02
64#define MAP_LIQUID_TYPE_MAGMA 0x04
65#define MAP_LIQUID_TYPE_SLIME 0x08
66#define MAP_LIQUID_TYPE_DARK_WATER 0x10
67#define MAP_LIQUID_TYPE_WMO_WATER 0x20
117 loadMap(mapID, tileX, tileY+1, meshData,
TOP);
125 char mapFileName[255];
126 snprintf(mapFileName,
sizeof(mapFileName),
"maps/%04u_%02u_%02u.map", mapID, tileY, tileX);
128 FILE* mapFile = fopen(mapFileName,
"rb");
137 printf(
"%s is the wrong version, please extract new .map files\n", mapFileName);
144 bool haveTerrain =
false;
145 bool haveLiquid =
false;
153 if (!haveTerrain && !haveLiquid)
162 uint8 liquid_type[16][16];
163 memset(liquid_type, 0,
sizeof(liquid_type));
164 G3D::Array<int> ltriangles;
165 G3D::Array<int> ttriangles;
170 float heightMultiplier;
181 if (count != expected)
182 printf(
"TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
187 V9[i] = (
float)v9[i]*heightMultiplier + hheader.
gridHeight;
190 V8[i] = (
float)v8[i]*heightMultiplier + hheader.
gridHeight;
199 if (count != expected)
200 printf(
"TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
205 V9[i] = (
float)v9[i]*heightMultiplier + hheader.
gridHeight;
208 V8[i] = (
float)v8[i]*heightMultiplier + hheader.
gridHeight;
215 if (count != expected)
216 printf(
"TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
225 printf(
"TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
229 float xoffset = (float(tileX)-32)*
GRID_SIZE;
230 float yoffset = (float(tileY)-32)*
GRID_SIZE;
250 int indices[3], loopStart = 0, loopEnd = 0, loopInc = 0;
252 for (
int i = loopStart; i < loopEnd; i+=loopInc)
256 ttriangles.append(indices[2] + count);
257 ttriangles.append(indices[1] + count);
258 ttriangles.append(indices[0] + count);
268 printf(
"TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
270 float* liquid_map = NULL;
273 if (fread(liquid_type,
sizeof(liquid_type), 1, mapFile) != 1)
274 printf(
"TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
279 liquid_map =
new float [toRead];
280 if (fread(liquid_map,
sizeof(
float), toRead, mapFile) != toRead)
281 printf(
"TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
287 float xoffset = (float(tileX)-32)*
GRID_SIZE;
288 float yoffset = (float(tileY)-32)*
GRID_SIZE;
302 if (row < lheader.offsetY || row >= lheader.
offsetY + lheader.
height ||
303 col < lheader.offsetX || col >= lheader.
offsetX + lheader.
width)
327 delete [] liquid_map;
329 int indices[3], loopStart = 0, loopEnd = 0, loopInc = 0, triInc =
BOTTOM-
TOP;
333 for (
int i = loopStart; i < loopEnd; i+=loopInc)
334 for (
int j =
TOP; j <=
BOTTOM; j+= triInc)
337 ltriangles.append(indices[2] + count);
338 ltriangles.append(indices[1] + count);
339 ltriangles.append(indices[0] + count);
348 int loopStart = 0, loopEnd = 0, loopInc = 0, tTriCount = 4;
349 bool useTerrain, useLiquid;
352 int* ltris = ltriangles.getCArray();
354 float* tverts = meshData.
solidVerts.getCArray();
355 int* ttris = ttriangles.getCArray();
357 if ((ltriangles.size() + ttriangles.size()) == 0)
362 float* lverts_copy = NULL;
365 lverts_copy =
new float[meshData.
liquidVerts.size()];
366 memcpy(lverts_copy, lverts,
sizeof(
float)*meshData.
liquidVerts.size());
370 for (
int i = loopStart; i < loopEnd; i+=loopInc)
372 for (
int j = 0; j < 2; ++j)
381 if (!meshData.
liquidVerts.size() || !ltriangles.size())
411 if (!ttriangles.size())
418 float quadHeight = 0;
420 for(
uint32 idx = 0; idx < 3; idx++)
422 float h = lverts_copy[ltris[idx]*3 + 1];
431 if (validCount > 0 && validCount < 3)
433 quadHeight /= validCount;
434 for(
uint32 idx = 0; idx < 3; idx++)
436 float h = lverts[ltris[idx]*3 + 1];
438 lverts[ltris[idx]*3 + 1] = quadHeight;
448 if (useTerrain && fheader.
holesSize != 0)
452 if (useTerrain && useLiquid)
456 for(
uint32 x = 0; x < 3; x++)
458 float h = lverts[ltris[x]*3 + 1];
468 for(
uint32 x = 0; x < 6; x++)
470 float h = tverts[ttris[x]*3 + 1];
479 if (minLLevel > maxTLevel)
483 if (minTLevel > maxLLevel)
491 for (
int k = 0; k < 3; ++k)
496 for (
int k = 0; k < 3*tTriCount/2; ++k)
501 ttris += 3*tTriCount/2;
506 delete [] lverts_copy;
534 int rowOffset = square/
V8_SIZE;
539 indices[0] = square+rowOffset;
540 indices[1] = square+1+rowOffset;
544 indices[0] = square+rowOffset;
546 indices[2] = square+
V9_SIZE+rowOffset;
549 indices[0] = square+1+rowOffset;
550 indices[1] = square+
V9_SIZE+1+rowOffset;
555 indices[1] = square+
V9_SIZE+1+rowOffset;
556 indices[2] = square+
V9_SIZE+rowOffset;
564 indices[0] = square+rowOffset;
565 indices[1] = square+1+rowOffset;
566 indices[2] = square+
V9_SIZE+1+rowOffset;
569 indices[0] = square+rowOffset;
570 indices[1] = square+
V9_SIZE+1+rowOffset;
571 indices[2] = square+
V9_SIZE+rowOffset;
584 coord[2] = v[index2];
589 int row = square / 128;
590 int col = square % 128;
591 int cellRow = row / 8;
592 int cellCol = col / 8;
593 int holeRow = row % 8;
594 int holeCol = (square - (row * 128 + cellCol * 8));
595 return holes[cellRow][cellCol][holeRow] & (1 << holeCol);
601 int row = square / 128;
602 int col = square % 128;
603 int cellRow = row / 8;
604 int cellCol = col / 8;
606 return liquid_type[cellRow][cellCol];
613 int result = vmapManager->
loadMap(
"vmaps", mapID, tileX, tileY);
622 ((
VMapManager2*)vmapManager)->getInstanceMapTree(instanceTrees);
624 if (!instanceTrees[mapID])
629 instanceTrees[mapID]->getModelInstances(models, count);
634 for (
uint32 i = 0; i < count; ++i)
646 std::vector<GroupModel> groupModels;
650 bool isM2 = instance.
name.find(
".m2") != std::string::npos || instance.
name.find(
".M2") != std::string::npos;
653 float scale = instance.
iScale;
654 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);
655 G3D::Vector3 position = instance.
iPos;
659 for (std::vector<GroupModel>::iterator it = groupModels.begin(); it != groupModels.end(); ++it)
661 std::vector<G3D::Vector3> tempVertices;
662 std::vector<G3D::Vector3> transformedVertices;
663 std::vector<MeshTriangle> tempTriangles;
666 it->getMeshData(tempVertices, tempTriangles, liquid);
669 transform(tempVertices, transformedVertices, scale, rotation, position);
679 std::vector<G3D::Vector3> liqVerts;
680 std::vector<int> liqTris;
681 uint32 tilesX, tilesY, vertsX, vertsY;
712 for (
uint32 x = 0; x < vertsX; ++x)
713 for (
uint32 y = 0; y < vertsY; ++y)
716 vert = vert * rotation * scale + position;
719 liqVerts.push_back(vert);
722 int idx1, idx2, idx3, idx4;
724 for (
uint32 x = 0; x < tilesX; ++x)
725 for (
uint32 y = 0; y < tilesY; ++y)
726 if ((flags[x+y*tilesX] & 0x0f) != 0x0f)
728 square = x * tilesY + y;
731 idx3 = square+tilesY+1+1+x;
732 idx4 = square+tilesY+1+x;
735 liqTris.push_back(idx3);
736 liqTris.push_back(idx2);
737 liqTris.push_back(idx1);
739 liqTris.push_back(idx4);
740 liqTris.push_back(idx3);
741 liqTris.push_back(idx1);
745 for (
uint32 i = 0; i < liqVerts.size(); ++i)
746 meshData.
liquidVerts.append(liqVerts[i].y, liqVerts[i].z, liqVerts[i].x);
748 for (
uint32 i = 0; i < liqTris.size() / 3; ++i)
750 meshData.
liquidTris.append(liqTris[i*3+1] + liqOffset, liqTris[i*3+2] + liqOffset, liqTris[i*3] + liqOffset);
759 vmapManager->
unloadMap(mapID, tileX, tileY);
766 void TerrainBuilder::transform(std::vector<G3D::Vector3> &source, std::vector<G3D::Vector3> &transformedVertices,
float scale, G3D::Matrix3 &rotation, G3D::Vector3 &position)
768 for (std::vector<G3D::Vector3>::iterator it = source.begin(); it != source.end(); ++it)
771 G3D::Vector3 v((*it) * rotation * scale + position);
774 transformedVertices.push_back(v);
781 for (std::vector<G3D::Vector3>::iterator it = source.begin(); it != source.end(); ++it)
783 dest.push_back((*it).y);
784 dest.push_back((*it).z);
785 dest.push_back((*it).x);
794 for (std::vector<MeshTriangle>::iterator it = source.begin(); it != source.end(); ++it)
796 dest.push_back((*it).idx2+offset);
797 dest.push_back((*it).idx1+offset);
798 dest.push_back((*it).idx0+offset);
803 for (std::vector<MeshTriangle>::iterator it = source.begin(); it != source.end(); ++it)
805 dest.push_back((*it).idx0+offset);
806 dest.push_back((*it).idx1+offset);
807 dest.push_back((*it).idx2+offset);
815 int* src = source.getCArray();
816 for (
int32 i = 0; i < source.size(); ++i)
817 dest.append(src[i] + offset);
823 std::map<int, int> vertMap;
825 int* t = tris.getCArray();
826 float* v = verts.getCArray();
828 G3D::Array<float> cleanVerts;
829 int index, count = 0;
831 for (
int i = 0; i < tris.size(); ++i)
833 if (vertMap.find(t[i]) != vertMap.end())
836 std::pair<int, int> val;
843 cleanVerts.append(v[index * 3], v[index * 3 + 1], v[index * 3 + 2]);
848 verts.append(cleanVerts);
852 for (
int i = 0; i < tris.size(); ++i)
854 std::map<int, int>::iterator it;
855 if ((it = vertMap.find(t[i])) == vertMap.end())
868 if (offMeshFilePath == NULL)
871 FILE* fp = fopen(offMeshFilePath,
"rb");
874 printf(
" loadOffMeshConnections:: input file %s not found!\n", offMeshFilePath);
880 char* buf =
new char[512];
881 while(fgets(buf, 512, fp))
886 if (sscanf(buf,
"%d %d,%d (%f %f %f) (%f %f %f) %f", &mid, &tx, &ty,
887 &p0[0], &p0[1], &p0[2], &p1[0], &p1[1], &p1[2], &size) != 10)
890 if (mapID == mid && tileX == tx && tileY == ty)
#define MAP_LIQUID_TYPE_MAGMA
#define MAP_HEIGHT_AS_INT8
#define MAP_LIQUID_TYPE_NO_WATER
#define MAP_LIQUID_NO_TYPE
#define MAP_LIQUID_NO_HEIGHT
#define MAP_LIQUID_TYPE_WATER
#define MAP_LIQUID_TYPE_DARK_WATER
#define MAP_LIQUID_TYPE_OCEAN
#define MAP_LIQUID_TYPE_SLIME
#define MAP_HEIGHT_NO_HEIGHT
#define MAP_HEIGHT_AS_INT16
uint16 holes[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]
float V8[ADT_GRID_SIZE][ADT_GRID_SIZE]
float V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]
static void copyVertices(std::vector< G3D::Vector3 > &source, G3D::Array< float > &dest)
uint8 getLiquidType(int square, const uint8 liquid_type[16][16])
Get the liquid type for a specific position.
bool isHole(int square, uint8 const holes[16][16][8])
Determines if the specific position's triangles should be rendered.
static void transform(std::vector< G3D::Vector3 > &original, std::vector< G3D::Vector3 > &transformed, float scale, G3D::Matrix3 &rotation, G3D::Vector3 &position)
static void cleanVertices(G3D::Array< float > &verts, G3D::Array< int > &tris)
static void copyIndices(std::vector< VMAP::MeshTriangle > &source, G3D::Array< int > &dest, int offest, bool flip)
void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char *offMeshFilePath)
bool m_skipLiquid
Controls whether liquids are loaded.
void getHeightTriangle(int square, Spot triangle, int *indices, bool liquid=false)
Get the triangle's vector indices for a specific position.
void loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData)
void getLiquidCoord(int index, int index2, float xOffset, float yOffset, float *coord, float *v)
Get the liquid vector coordinate for a specific position.
bool loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData)
void getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float *coord, float *v)
Get the vector coordinate for a specific position.
void getLoopVars(Spot portion, int &loopStart, int &loopEnd, int &loopInc)
Sets loop variables for selecting only certain parts of a map's terrain.
virtual int loadMap(const char *pBasePath, unsigned int pMapId, int x, int y)=0
virtual void unloadMap(unsigned int pMapId, int x, int y)=0
WorldModel * getWorldModel()
void getPosInfo(uint32 &tilesX, uint32 &tilesY, G3D::Vector3 &corner) const
float * GetHeightStorage()
uint8 * GetFlagsStorage()
void getGroupModels(std::vector< GroupModel > &groupModels)
static const float GRID_SIZE
static const float INVALID_MAP_LIQ_HEIGHT_MAX
static const float GRID_PART_SIZE
static const float INVALID_MAP_LIQ_HEIGHT
char const * MAP_VERSION_MAGIC
static const int V9_SIZE_SQ
static const int V8_SIZE_SQ
UNORDERED_MAP< uint32, StaticMapTree * > InstanceTreeMap
G3D::Array< float > liquidVerts
G3D::Array< float > offMeshConnectionRads
G3D::Array< unsigned char > offMeshConnectionDirs
G3D::Array< float > offMeshConnections
G3D::Array< unsigned short > offMeshConnectionsFlags
G3D::Array< float > solidVerts
G3D::Array< int > liquidTris
G3D::Array< int > solidTris
G3D::Array< unsigned char > offMeshConnectionsAreas
G3D::Array< uint8 > liquidType