Loads a portion of a map's terrain.
145 {
149 mapID, tileY, tileX
150 );
151
152 FILE* mapFile = fopen(mapFileName.c_str(), "rb");
153 if (!mapFile)
154 return false;
155
159 {
160 fclose(mapFile);
161 printf("%s is the wrong version, please extract new .map files\n", mapFileName.c_str());
162 return false;
163 }
164
167
168 bool haveTerrain = false;
169 bool haveLiquid = false;
171 {
174 }
175
176
177 if (!haveTerrain && !haveLiquid)
178 {
179 fclose(mapFile);
180 return false;
181 }
182
183
190 G3D::Array<int> ltriangles;
191 G3D::Array<int> ttriangles;
192
193
194 if (haveTerrain)
195 {
196 float heightMultiplier;
199
201 {
204 int count = 0;
207 if (count != expected)
208 printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
209
211
213 V9[i] = (
float)v9[i] * heightMultiplier + hheader.
gridHeight;
214
216 V8[i] = (
float)v8[i] * heightMultiplier + hheader.
gridHeight;
217 }
219 {
222 int count = 0;
225 if (count != expected)
226 printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
227
229
231 V9[i] = (
float)v9[i] * heightMultiplier + hheader.
gridHeight;
232
234 V8[i] = (
float)v8[i] * heightMultiplier + hheader.
gridHeight;
235 }
236 else
237 {
238 int count = 0;
241 if (count != expected)
242 printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
243 }
244
245
247 {
251 printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
252 }
253
254 int count = meshData.solidVerts.size() / 3;
255 float xoffset = (float(tileX) - 32) *
GRID_SIZE;
256 float yoffset = (float(tileY) - 32) *
GRID_SIZE;
257
258 float coord[3];
259
261 {
263 meshData.solidVerts.append(coord[0]);
264 meshData.solidVerts.append(coord[2]);
265 meshData.solidVerts.append(coord[1]);
266 }
267
269 {
271 meshData.solidVerts.append(coord[0]);
272 meshData.solidVerts.append(coord[2]);
273 meshData.solidVerts.append(coord[1]);
274 }
275
276 int indices[] = { 0, 0, 0 };
277 int loopStart = 0, loopEnd = 0, loopInc = 0;
279 for (int i = loopStart; i < loopEnd; i += loopInc)
281 {
283 ttriangles.append(indices[2] + count);
284 ttriangles.append(indices[1] + count);
285 ttriangles.append(indices[0] + count);
286 }
287 }
288
289
290 if (haveLiquid)
291 {
295 printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
296
297 float* liquid_map = nullptr;
298
300 {
302 printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
304 printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
305 }
306 else
307 {
310 }
311
313 {
315 liquid_map = new float [toRead];
316 if (fread(liquid_map, sizeof(float), toRead, mapFile) != toRead)
317 {
318 printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
319 delete[] liquid_map;
320 liquid_map = nullptr;
321 }
322 }
323
324 int count = meshData.liquidVerts.size() / 3;
325 float xoffset = (float(tileX)-32)*
GRID_SIZE;
326 float yoffset = (float(tileY)-32)*
GRID_SIZE;
327
328 float coord[3];
329 int row, col;
330
331
333 {
334 int j = 0;
336 {
339
340 if (row < lheader.offsetY || row >= lheader.
offsetY + lheader.
height ||
341 col < lheader.offsetX || col >= lheader.
offsetX + lheader.
width)
342 {
343
345 continue;
346 }
347
349 meshData.liquidVerts.append(coord[0]);
350 meshData.liquidVerts.append(coord[2]);
351 meshData.liquidVerts.append(coord[1]);
352 j++;
353 }
354 }
355 else
356 {
358 {
362 }
363 }
364
365 delete[] liquid_map;
366
367 int indices[] = { 0, 0, 0 };
368 int loopStart = 0, loopEnd = 0, loopInc = 0, triInc =
BOTTOM-
TOP;
370
371
372 for (int i = loopStart; i < loopEnd; i += loopInc)
373 {
374 for (
int j =
TOP; j <=
BOTTOM; j += triInc)
375 {
377 ltriangles.append(indices[2] + count);
378 ltriangles.append(indices[1] + count);
379 ltriangles.append(indices[0] + count);
380 }
381 }
382 }
383
384 fclose(mapFile);
385
386
387
388 int loopStart = 0, loopEnd = 0, loopInc = 0, tTriCount = 4;
389 bool useTerrain, useLiquid;
390
391 float* lverts = meshData.liquidVerts.getCArray();
392 int* ltris = ltriangles.getCArray();
393
394 float* tverts = meshData.solidVerts.getCArray();
395 int* ttris = ttriangles.getCArray();
396
397 if ((ltriangles.size() + ttriangles.size()) == 0)
398 return false;
399
400
401
402 float* lverts_copy = nullptr;
403 if (meshData.liquidVerts.size())
404 {
405 lverts_copy = new float[meshData.liquidVerts.size()];
406 memcpy(lverts_copy, lverts, sizeof(float)*meshData.liquidVerts.size());
407 }
408
410 for (int i = loopStart; i < loopEnd; i += loopInc)
411 {
412 for (int j = 0; j < 2; ++j)
413 {
414
415 useTerrain = true;
416 useLiquid = true;
418
419
420
421 if (!meshData.liquidVerts.size() || !ltriangles.size())
422 {
423 useLiquid = false;
424 }
425 else
426 {
428 switch (liquidType)
429 {
430 default:
431 useLiquid = false;
432 break;
435
437 break;
440 break;
443 break;
445
446 useTerrain = false;
447 useLiquid = false;
448 break;
449 }
450 }
451
452
453 if (!ttriangles.size())
454 useTerrain = false;
455
456
457
458 if (useLiquid)
459 {
460 float quadHeight = 0;
462 for (
uint32 idx = 0; idx < 3; idx++)
463 {
464 float h = lverts_copy[ltris[idx] * 3 + 1];
466 {
467 quadHeight += h;
468 validCount++;
469 }
470 }
471
472
473 if (validCount > 0 && validCount < 3)
474 {
475 quadHeight /= validCount;
476 for (
uint32 idx = 0; idx < 3; idx++)
477 {
478 float h = lverts[ltris[idx] * 3 + 1];
480 lverts[ltris[idx] * 3 + 1] = quadHeight;
481 }
482 }
483
484
485 if (validCount == 0)
486 useLiquid = false;
487 }
488
489
490 if (useTerrain && fheader.
holesSize != 0)
492
493
494 if (useTerrain && useLiquid)
495 {
498 for (
uint32 x = 0; x < 3; x++)
499 {
500 float h = lverts[ltris[x] * 3 + 1];
501 if (minLLevel > h)
502 minLLevel = h;
503
504 if (maxLLevel < h)
505 maxLLevel = h;
506 }
507
510 for (
uint32 x = 0; x < 6; x++)
511 {
512 float h = tverts[ttris[x] * 3 + 1];
513 if (maxTLevel < h)
514 maxTLevel = h;
515
516 if (minTLevel > h)
517 minTLevel = h;
518 }
519
520
521 if (minLLevel > maxTLevel)
522 useTerrain = false;
523
524
525 if (minTLevel > maxLLevel)
526 useLiquid = false;
527 }
528
529
530 if (useLiquid)
531 {
532 meshData.liquidType.append(liquidType);
533 for (int k = 0; k < 3; ++k)
534 meshData.liquidTris.append(ltris[k]);
535 }
536
537 if (useTerrain)
538 for (int k = 0; k < 3 * tTriCount / 2; ++k)
539 meshData.solidTris.append(ttris[k]);
540
541
542 ltris += 3;
543 ttris += 3 * tTriCount / 2;
544 }
545 }
546
547 if (lverts_copy)
548 delete [] lverts_copy;
549
550 return meshData.solidTris.size() || meshData.liquidTris.size();
551 }
std::uint8_t uint8
Definition Define.h:109
std::uint32_t uint32
Definition Define.h:107
#define MAP_LIQUID_TYPE_MAGMA
Definition GridTerrainData.h:37
#define MAP_HEIGHT_AS_INT8
Definition GridTerrainData.h:85
#define MAP_LIQUID_TYPE_NO_WATER
Definition GridTerrainData.h:34
#define MAP_LIQUID_NO_TYPE
Definition GridTerrainData.h:96
#define MAP_LIQUID_NO_HEIGHT
Definition GridTerrainData.h:97
#define MAP_LIQUID_TYPE_WATER
Definition GridTerrainData.h:35
#define MAP_LIQUID_TYPE_DARK_WATER
Definition GridTerrainData.h:42
#define MAP_LIQUID_TYPE_OCEAN
Definition GridTerrainData.h:36
#define MAP_LIQUID_TYPE_SLIME
Definition GridTerrainData.h:38
#define MAP_HEIGHT_NO_HEIGHT
Definition GridTerrainData.h:83
#define MAP_HEIGHT_AS_INT16
Definition GridTerrainData.h:84
@ NAV_MAGMA
Definition MapDefines.h:92
@ NAV_SLIME
Definition MapDefines.h:93
@ NAV_WATER
Definition MapDefines.h:94
uint16 liquid_entry[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]
Definition System.cpp:405
uint8 liquid_flags[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]
Definition System.cpp:406
float V8[ADT_GRID_SIZE][ADT_GRID_SIZE]
Definition System.cpp:398
float V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]
Definition System.cpp:399
bool isHole(int square, const uint16 holes[16][16])
Determines if the specific position's triangles should be rendered.
Definition TerrainBuilder.cpp:651
uint8 getLiquidType(int square, const uint8 liquid_type[16][16])
Get the liquid type for a specific position.
Definition TerrainBuilder.cpp:666
void getHeightTriangle(int square, Spot triangle, int *indices, bool liquid=false)
Get the triangle's vector indices for a specific position.
Definition TerrainBuilder.cpp:574
void getLiquidCoord(int index, int index2, float xOffset, float yOffset, float *coord, float *v)
Get the liquid vector coordinate for a specific position.
Definition TerrainBuilder.cpp:638
void getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float *coord, float *v)
Get the vector coordinate for a specific position.
Definition TerrainBuilder.cpp:554
void getLoopVars(Spot portion, int &loopStart, int &loopEnd, int &loopInc)
Sets loop variables for selecting only certain parts of a map's terrain.
Definition TerrainBuilder.cpp:99
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default AC string format function.
Definition StringFormat.h:34
static const float GRID_SIZE
Definition TerrainBuilder.h:48
static char const *const MAP_FILE_NAME_FORMAT
Definition MMapMgr.h:42
static const float INVALID_MAP_LIQ_HEIGHT_MAX
Definition TerrainBuilder.h:53
static const float INVALID_MAP_LIQ_HEIGHT
Definition TerrainBuilder.h:52
Spot
Definition TerrainBuilder.h:30
uint32 const MAP_VERSION_MAGIC
Definition TerrainBuilder.cpp:87