46#define MAP_HEIGHT_NO_HEIGHT 0x0001
47#define MAP_HEIGHT_AS_INT16 0x0002
48#define MAP_HEIGHT_AS_INT8 0x0004
58#define MAP_LIQUID_NO_TYPE 0x0001
59#define MAP_LIQUID_NO_HEIGHT 0x0002
74#define MAP_LIQUID_TYPE_NO_WATER 0x00
75#define MAP_LIQUID_TYPE_WATER 0x01
76#define MAP_LIQUID_TYPE_OCEAN 0x02
77#define MAP_LIQUID_TYPE_MAGMA 0x04
78#define MAP_LIQUID_TYPE_SLIME 0x08
79#define MAP_LIQUID_TYPE_DARK_WATER 0x10
130 loadMap(mapID, tileX, tileY+1, meshData,
TOP);
138 char mapFileName[255];
139 sprintf(mapFileName,
"maps/%03u%02u%02u.map", mapID, tileY, tileX);
141 FILE* mapFile = fopen(mapFileName,
"rb");
150 printf(
"%s is the wrong version, please extract new .map files\n", mapFileName);
157 bool haveTerrain =
false;
158 bool haveLiquid =
false;
166 if (!haveTerrain && !haveLiquid)
179 G3D::Array<int> ltriangles;
180 G3D::Array<int> ttriangles;
185 float heightMultiplier;
196 if (count != expected)
197 printf(
"TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
202 V9[i] = (
float)v9[i]*heightMultiplier + hheader.
gridHeight;
205 V8[i] = (
float)v8[i]*heightMultiplier + hheader.
gridHeight;
214 if (count != expected)
215 printf(
"TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
220 V9[i] = (
float)v9[i]*heightMultiplier + hheader.
gridHeight;
223 V8[i] = (
float)v8[i]*heightMultiplier + hheader.
gridHeight;
230 if (count != expected)
231 printf(
"TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
240 printf(
"TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
244 float xoffset = (float(tileX)-32)*
GRID_SIZE;
245 float yoffset = (float(tileY)-32)*
GRID_SIZE;
265 int indices[] = { 0, 0, 0 };
266 int loopStart = 0, loopEnd = 0, loopInc = 0;
268 for (
int i = loopStart; i < loopEnd; i+=loopInc)
272 ttriangles.append(indices[2] + count);
273 ttriangles.append(indices[1] + count);
274 ttriangles.append(indices[0] + count);
284 printf(
"TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
286 float* liquid_map =
nullptr;
291 printf(
"TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
293 printf(
"TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
304 liquid_map =
new float [toRead];
305 if (fread(liquid_map,
sizeof(
float), toRead, mapFile) != toRead)
307 printf(
"TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
309 liquid_map =
nullptr;
314 float xoffset = (float(tileX)-32)*
GRID_SIZE;
315 float yoffset = (float(tileY)-32)*
GRID_SIZE;
329 if (row < lheader.offsetY || row >= lheader.
offsetY + lheader.
height ||
330 col < lheader.offsetX || col >= lheader.
offsetX + lheader.
width)
356 int indices[] = { 0, 0, 0 };
357 int loopStart = 0, loopEnd = 0, loopInc = 0, triInc =
BOTTOM-
TOP;
361 for (
int i = loopStart; i < loopEnd; i += loopInc)
363 for (
int j =
TOP; j <=
BOTTOM; j += triInc)
366 ltriangles.append(indices[2] + count);
367 ltriangles.append(indices[1] + count);
368 ltriangles.append(indices[0] + count);
377 int loopStart = 0, loopEnd = 0, loopInc = 0, tTriCount = 4;
378 bool useTerrain, useLiquid;
381 int* ltris = ltriangles.getCArray();
383 float* tverts = meshData.
solidVerts.getCArray();
384 int* ttris = ttriangles.getCArray();
386 if ((ltriangles.size() + ttriangles.size()) == 0)
391 float* lverts_copy =
nullptr;
394 lverts_copy =
new float[meshData.
liquidVerts.size()];
395 memcpy(lverts_copy, lverts,
sizeof(
float)*meshData.
liquidVerts.size());
399 for (
int i = loopStart; i < loopEnd; i+=loopInc)
401 for (
int j = 0; j < 2; ++j)
409 if (!meshData.
liquidVerts.size() || !ltriangles.size())
429 if (!ttriangles.size())
436 float quadHeight = 0;
438 for(
uint32 idx = 0; idx < 3; idx++)
440 float h = lverts_copy[ltris[idx]*3 + 1];
449 if (validCount > 0 && validCount < 3)
451 quadHeight /= validCount;
452 for(
uint32 idx = 0; idx < 3; idx++)
454 float h = lverts[ltris[idx]*3 + 1];
456 lverts[ltris[idx]*3 + 1] = quadHeight;
466 if (useTerrain && fheader.
holesSize != 0)
470 if (useTerrain && useLiquid)
474 for(
uint32 x = 0; x < 3; x++)
476 float h = lverts[ltris[x]*3 + 1];
486 for(
uint32 x = 0; x < 6; x++)
488 float h = tverts[ttris[x]*3 + 1];
497 if (minLLevel > maxTLevel)
501 if (minTLevel > maxLLevel)
509 for (
int k = 0; k < 3; ++k)
514 for (
int k = 0; k < 3*tTriCount/2; ++k)
519 ttris += 3*tTriCount/2;
524 delete [] lverts_copy;
557 indices[0] =
square+rowOffset;
558 indices[1] =
square+1+rowOffset;
562 indices[0] =
square+rowOffset;
567 indices[0] =
square+1+rowOffset;
582 indices[0] =
square+rowOffset;
583 indices[1] =
square+1+rowOffset;
587 indices[0] =
square+rowOffset;
603 coord[2] = v[index2];
614 int cellRow = row / 8;
615 int cellCol = col / 8;
616 int holeRow = row % 8 / 2;
617 int holeCol = (
square - (row * 128 + cellCol * 8)) / 2;
629 int cellRow = row / 8;
630 int cellCol = col / 8;
632 return liquid_type[cellRow][cellCol];
639 int result = vmapManager->
loadMap(
"vmaps", mapID, tileX, tileY);
648 ((
VMapManager2*)vmapManager)->getInstanceMapTree(instanceTrees);
650 if (!instanceTrees[mapID])
655 instanceTrees[mapID]->getModelInstances(models, count);
660 for (
uint32 i = 0; i < count; ++i)
672 std::vector<GroupModel> groupModels;
676 bool isM2 = instance.
name.find(
".m2") != std::string::npos || instance.
name.find(
".M2") != std::string::npos;
679 float scale = instance.
iScale;
680 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);
681 G3D::Vector3 position = instance.
iPos;
685 for (std::vector<GroupModel>::iterator it = groupModels.begin(); it != groupModels.end(); ++it)
687 std::vector<G3D::Vector3> tempVertices;
688 std::vector<G3D::Vector3> transformedVertices;
689 std::vector<MeshTriangle> tempTriangles;
692 it->getMeshData(tempVertices, tempTriangles, liquid);
695 transform(tempVertices, transformedVertices, scale, rotation, position);
705 std::vector<G3D::Vector3> liqVerts;
706 std::vector<int> liqTris;
707 uint32 tilesX, tilesY, vertsX, vertsY;
730 for (
uint32 x = 0; x < vertsX; ++x)
732 for (
uint32 y = 0; y < vertsY; ++y)
735 vert = vert * rotation * scale + position;
738 liqVerts.push_back(vert);
742 int idx1, idx2, idx3, idx4;
744 for (
uint32 x = 0; x < tilesX; ++x)
746 for (
uint32 y = 0; y < tilesY; ++y)
748 if ((
flags[x + y*tilesX] & 0x0f) != 0x0f)
753 idx3 =
square + tilesY + 1 + 1 + x;
754 idx4 =
square + tilesY + 1 + x;
757 liqTris.push_back(idx3);
758 liqTris.push_back(idx2);
759 liqTris.push_back(idx1);
761 liqTris.push_back(idx4);
762 liqTris.push_back(idx3);
763 liqTris.push_back(idx1);
769 for (
uint32 j = 0; j < liqVerts.size(); ++j)
770 meshData.
liquidVerts.append(liqVerts[j].y, liqVerts[j].z, liqVerts[j].x);
772 for (
uint32 j = 0; j < liqTris.size() / 3; ++j)
774 meshData.
liquidTris.append(liqTris[j * 3 + 1] + liqOffset, liqTris[j * 3 + 2] + liqOffset, liqTris[j * 3] + liqOffset);
783 vmapManager->
unloadMap(mapID, tileX, tileY);
790 void TerrainBuilder::transform(std::vector<G3D::Vector3> &source, std::vector<G3D::Vector3> &transformedVertices,
float scale, G3D::Matrix3 &rotation, G3D::Vector3 &position)
792 for (std::vector<G3D::Vector3>::iterator it = source.begin(); it != source.end(); ++it)
795 G3D::Vector3 v((*it) * rotation * scale + position);
798 transformedVertices.push_back(v);
805 for (std::vector<G3D::Vector3>::iterator it = source.begin(); it != source.end(); ++it)
807 dest.push_back((*it).y);
808 dest.push_back((*it).z);
809 dest.push_back((*it).x);
818 for (std::vector<MeshTriangle>::iterator it = source.begin(); it != source.end(); ++it)
820 dest.push_back((*it).idx2+offset);
821 dest.push_back((*it).idx1+offset);
822 dest.push_back((*it).idx0+offset);
827 for (std::vector<MeshTriangle>::iterator it = source.begin(); it != source.end(); ++it)
829 dest.push_back((*it).idx0+offset);
830 dest.push_back((*it).idx1+offset);
831 dest.push_back((*it).idx2+offset);
839 int* src = source.getCArray();
840 for (
int32 i = 0; i < source.size(); ++i)
841 dest.append(src[i] + offset);
847 std::map<int, int> vertMap;
849 int* t = tris.getCArray();
850 float* v = verts.getCArray();
852 G3D::Array<float> cleanVerts;
853 int index, count = 0;
855 for (
int i = 0; i < tris.size(); ++i)
857 if (vertMap.find(t[i]) != vertMap.end())
859 std::pair<int, int> val;
866 cleanVerts.append(v[index * 3], v[index * 3 + 1], v[index * 3 + 2]);
871 verts.append(cleanVerts);
875 for (
int i = 0; i < tris.size(); ++i)
877 std::map<int, int>::iterator it;
878 if ((it = vertMap.find(t[i])) == vertMap.end())
891 if (offMeshFilePath ==
nullptr)
894 FILE* fp = fopen(offMeshFilePath,
"rb");
897 printf(
" loadOffMeshConnections:: input file %s not found!\n", offMeshFilePath);
903 char* buf =
new char[512];
904 while(fgets(buf, 512, fp))
909 if (sscanf(buf,
"%u %u,%u (%f %f %f) (%f %f %f) %f", &mid, &tx, &ty,
910 &p0[0], &p0[1], &p0[2], &p1[0], &p1[1], &p1[2], &size) != 10)
913 if (mapID == mid && tileX == tx && tileY == ty)
uint16 holes[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]
uint16 liquid_entry[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]
uint8 liquid_flags[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]
#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
uint32 GetLiquidFlags(uint32 liquidId)
#define MAP_LIQUID_TYPE_SLIME
#define MAP_HEIGHT_NO_HEIGHT
#define MAP_HEIGHT_AS_INT16
void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, char const *offMeshFilePath)
bool isHole(int square, const uint16 holes[16][16])
Determines if the specific position's triangles should be rendered.
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.
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)
bool m_skipLiquid
Controls whether liquids are loaded.
TerrainBuilder(bool skipLiquid)
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.
WorldModel * getWorldModel()
void unloadMap(unsigned int mapId, int x, int y) override
int loadMap(char const *pBasePath, unsigned int mapId, int x, int y) override
void getPosInfo(uint32 &tilesX, uint32 &tilesY, G3D::Vector3 &corner) const
float * GetHeightStorage()
uint8 * GetFlagsStorage()
void getGroupModels(std::vector< GroupModel > &outGroupModels)
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
static const int V9_SIZE_SQ
static uint16 holetab_v[4]
static const int V8_SIZE_SQ
static uint16 holetab_h[4]
uint32 const MAP_VERSION_MAGIC
std::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