90 auto mapFile = Trinity::make_unique_ptr_with_deleter<&::fclose>(fopen(mapFileName.c_str(),
"rb"));
94 while (!mapFile && parentMapId != -1)
97 mapFile.reset(fopen(mapFileName.c_str(),
"rb"));
106 if (fread(&fheader,
sizeof(
map_fileheader), 1, mapFile.get()) != 1 ||
109 TC_LOG_ERROR(
"maps.mmapgen",
"{} is the wrong version, please extract new .map files", mapFileName);
116 bool haveTerrain =
false;
117 bool haveLiquid =
false;
125 if (!haveTerrain && !haveLiquid)
129 uint8 holes[16][16][8] = { };
130 uint16 liquid_entry[16][16] = { };
132 std::vector<int> ltriangles;
133 std::vector<int> ttriangles;
138 float heightMultiplier;
149 if (count != expected)
150 TC_LOG_ERROR(
"maps.mmapgen",
"TerrainBuilder::loadMap: Failed to read {} height data expected {}, read {}", mapFileName, expected, count);
155 V9[i] = (
float)v9[i]*heightMultiplier + hheader.
gridHeight;
158 V8[i] = (
float)v8[i]*heightMultiplier + hheader.
gridHeight;
167 if (count != expected)
168 TC_LOG_ERROR(
"maps.mmapgen",
"TerrainBuilder::loadMap: Failed to read {} height data expected {}, read {}", mapFileName, expected, count);
173 V9[i] = (
float)v9[i]*heightMultiplier + hheader.
gridHeight;
176 V8[i] = (
float)v8[i]*heightMultiplier + hheader.
gridHeight;
181 count += fread(V9,
sizeof(
float),
V9_SIZE_SQ, mapFile.get());
182 count += fread(V8,
sizeof(
float),
V8_SIZE_SQ, mapFile.get());
183 if (count != expected)
184 TC_LOG_ERROR(
"maps.mmapgen",
"TerrainBuilder::loadMap: Failed to read {} height data expected {}, read {}", mapFileName, expected, count);
191 fseek(mapFile.get(), fheader.
holesOffset, SEEK_SET);
192 if (fread(holes, fheader.
holesSize, 1, mapFile.get()) != 1)
193 TC_LOG_ERROR(
"maps.mmapgen",
"TerrainBuilder::loadMap: Failed to read {} holes data expected {}, read {}", mapFileName, 1, 0);
198 float* solidVerts = meshData.
solidVerts.data() + count * 3;
200 float xoffset = (float(tileX)-32)*
GRID_SIZE;
201 float yoffset = (float(tileY)-32)*
GRID_SIZE;
215 int loopStart = 0, loopEnd = 0, loopInc = 0;
217 for (
int i = loopStart; i < loopEnd; i+=loopInc)
219 std::size_t trianglesOffset = ttriangles.size();
220 ttriangles.resize(ttriangles.size() + 12);
234 TC_LOG_ERROR(
"maps.mmapgen",
"TerrainBuilder::loadMap: Failed to read {} liquid header expected {}, read {}", mapFileName, 1, 0);
236 std::unique_ptr<float[]> liquid_map;
240 if (fread(liquid_entry,
sizeof(liquid_entry), 1, mapFile.get()) != 1)
241 TC_LOG_ERROR(
"maps.mmapgen",
"TerrainBuilder::loadMap: Failed to read {} liquid id expected {}, read {}", mapFileName, 1, 0);
242 if (fread(liquid_flags,
sizeof(liquid_flags), 1, mapFile.get()) != 1)
243 TC_LOG_ERROR(
"maps.mmapgen",
"TerrainBuilder::loadMap: Failed to read {} liquid flags expected {}, read {}", mapFileName, 1, 0);
247 std::fill_n(&liquid_entry[0][0], 16 * 16, lheader.
liquidType);
248 std::fill_n(&liquid_flags[0][0], 16 * 16, lheader.
liquidFlags);
254 liquid_map = std::make_unique<float[]>(toRead);
255 if (fread(liquid_map.get(),
sizeof(
float), toRead, mapFile.get()) != toRead)
257 TC_LOG_ERROR(
"maps.mmapgen",
"TerrainBuilder::loadMap: Failed to read {} liquid header expected {}, read {}", mapFileName, toRead, 0);
258 liquid_map =
nullptr;
265 float xoffset = (float(tileX)-32)*
GRID_SIZE;
266 float yoffset = (float(tileY)-32)*
GRID_SIZE;
279 if (row < lheader.offsetY || row >= lheader.
offsetY + lheader.
height ||
280 col < lheader.offsetX || col >= lheader.
offsetX + lheader.
width)
283 liquidVerts[(count + i) * 3 + 0] = (yoffset + col *
GRID_PART_SIZE) * -1;
285 liquidVerts[(count + i) * 3 + 2] = (xoffset + row *
GRID_PART_SIZE) * -1;
289 getLiquidCoord(i, j, xoffset, yoffset, &liquidVerts[(count + i) * 3], liquid_map.get());
299 liquidVerts[(count + i) * 3 + 0] = (yoffset + col *
GRID_PART_SIZE) * -1;
300 liquidVerts[(count + i) * 3 + 1] = lheader.
liquidLevel;
301 liquidVerts[(count + i) * 3 + 2] = (xoffset + row *
GRID_PART_SIZE) * -1;
305 int loopStart = 0, loopEnd = 0, loopInc = 0;
309 for (
int i = loopStart; i < loopEnd; i += loopInc)
311 std::size_t trianglesOffset = ltriangles.size();
312 ltriangles.resize(ltriangles.size() + 6);
320 int loopStart = 0, loopEnd = 0, loopInc = 0, tTriCount = 4;
321 bool useTerrain, useLiquid;
324 int* ltris = ltriangles.data();
327 int* ttris = ttriangles.data();
329 if ((ltriangles.size() + ttriangles.size()) == 0)
334 std::unique_ptr<float[]> lverts_copy;
337 lverts_copy = std::make_unique<float[]>(meshData.
liquidVerts.size());
338 memcpy(lverts_copy.get(), lverts,
sizeof(
float)* meshData.
liquidVerts.size());
342 for (
int i = loopStart; i < loopEnd; i+=loopInc)
344 for (
int j = 0; j < 2; ++j)
353 if (meshData.
liquidVerts.empty() || ltriangles.empty())
373 if (ttriangles.empty())
380 float quadHeight = 0;
382 for(
uint32 idx = 0; idx < 3; idx++)
384 float h = lverts_copy[ltris[idx]*3 + 1];
393 if (validCount > 0 && validCount < 3)
395 quadHeight /= validCount;
396 for(
uint32 idx = 0; idx < 3; idx++)
398 float h = lverts[ltris[idx]*3 + 1];
400 lverts[ltris[idx]*3 + 1] = quadHeight;
410 if (useTerrain && fheader.
holesSize != 0)
411 useTerrain = !
isHole(i, holes);
414 if (useTerrain && useLiquid)
418 for(
uint32 x = 0; x < 3; x++)
420 float h = lverts[ltris[x]*3 + 1];
430 for(
uint32 x = 0; x < 6; x++)
432 float h = tverts[ttris[x]*3 + 1];
441 if (minLLevel > maxTLevel)
445 if (minTLevel > maxLLevel)
457 meshData.
solidTris.insert(meshData.
solidTris.end(), &ttris[0], &ttris[3 * tTriCount / 2]);
461 ttris += 3*tTriCount/2;
609 std::vector<VMAP::GroupModel>
const& groupModels = worldModel->
getGroupModels();
612 bool isM2 = worldModel->
IsM2();
615 for (std::vector<VMAP::GroupModel>::const_iterator it = groupModels.begin(); it != groupModels.end(); ++it)
629 uint32 vertsX = tilesX + 1;
630 uint32 vertsY = tilesY + 1;
651 for (
uint32 x = 0; x < vertsX; ++x)
653 for (
uint32 y = 0; y < vertsY; ++y)
656 vert = vert * rotation * scale + position;
659 liquidVerts[(liqOffset + x * vertsY + y) * 3 + 0] = vert.y;
660 liquidVerts[(liqOffset + x * vertsY + y) * 3 + 1] = vert.z;
661 liquidVerts[(liqOffset + x * vertsY + y) * 3 + 2] = vert.x;
665 std::size_t liquidSquares = 0;
666 for (
uint32 x = 0; x < tilesX; ++x)
668 for (
uint32 y = 0; y < tilesY; ++y)
670 if ((
flags[x + y * tilesX] & 0x0f) != 0x0f)
672 uint32 square = x * tilesY + y;
673 int idx1 = square + x;
674 int idx2 = square + 1 + x;
675 int idx3 = square + tilesY + 1 + 1 + x;
676 int idx4 = square + tilesY + 1 + x;
678 std::size_t liquidTriOffset = meshData.
liquidTris.size();
679 meshData.
liquidTris.resize(liquidTriOffset + 6);
680 int* liquidTris = meshData.
liquidTris.data() + liquidTriOffset;
683 liquidTris[0] = idx2 + liqOffset;
684 liquidTris[1] = idx1 + liqOffset;
685 liquidTris[2] = idx3 + liqOffset;
688 liquidTris[3] = idx3 + liqOffset;
689 liquidTris[4] = idx1 + liqOffset;
690 liquidTris[5] = idx4 + liqOffset;