Loads a portion of a map's terrain.
136 {
137 char mapFileName[255];
138 sprintf(mapFileName, "maps/%03u%02u%02u.map", mapID, tileY, tileX);
139
140 FILE* mapFile = fopen(mapFileName, "rb");
141 if (!mapFile)
142 return false;
143
147 {
148 fclose(mapFile);
149 printf("%s is the wrong version, please extract new .map files\n", mapFileName);
150 return false;
151 }
152
155
156 bool haveTerrain = false;
157 bool haveLiquid = false;
159 {
162 }
163
164
165 if (!haveTerrain && !haveLiquid)
166 {
167 fclose(mapFile);
168 return false;
169 }
170
171
178 G3D::Array<int> ltriangles;
179 G3D::Array<int> ttriangles;
180
181
182 if (haveTerrain)
183 {
184 float heightMultiplier;
187
189 {
192 int count = 0;
195 if (count != expected)
196 printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
197
199
201 V9[i] = (
float)v9[i] * heightMultiplier + hheader.
gridHeight;
202
204 V8[i] = (
float)v8[i] * heightMultiplier + hheader.
gridHeight;
205 }
207 {
210 int count = 0;
213 if (count != expected)
214 printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
215
217
219 V9[i] = (
float)v9[i] * heightMultiplier + hheader.
gridHeight;
220
222 V8[i] = (
float)v8[i] * heightMultiplier + hheader.
gridHeight;
223 }
224 else
225 {
226 int count = 0;
229 if (count != expected)
230 printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
231 }
232
233
235 {
239 printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
240 }
241
242 int count = meshData.solidVerts.size() / 3;
243 float xoffset = (float(tileX) - 32) *
GRID_SIZE;
244 float yoffset = (float(tileY) - 32) *
GRID_SIZE;
245
246 float coord[3];
247
249 {
251 meshData.solidVerts.append(coord[0]);
252 meshData.solidVerts.append(coord[2]);
253 meshData.solidVerts.append(coord[1]);
254 }
255
257 {
259 meshData.solidVerts.append(coord[0]);
260 meshData.solidVerts.append(coord[2]);
261 meshData.solidVerts.append(coord[1]);
262 }
263
264 int indices[] = { 0, 0, 0 };
265 int loopStart = 0, loopEnd = 0, loopInc = 0;
267 for (int i = loopStart; i < loopEnd; i += loopInc)
269 {
271 ttriangles.append(indices[2] + count);
272 ttriangles.append(indices[1] + count);
273 ttriangles.append(indices[0] + count);
274 }
275 }
276
277
278 if (haveLiquid)
279 {
283 printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
284
285 float* liquid_map = nullptr;
286
288 {
290 printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
292 printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
293 }
294 else
295 {
298 }
299
301 {
303 liquid_map = new float [toRead];
304 if (fread(liquid_map, sizeof(float), toRead, mapFile) != toRead)
305 {
306 printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
307 delete[] liquid_map;
308 liquid_map = nullptr;
309 }
310 }
311
312 int count = meshData.liquidVerts.size() / 3;
313 float xoffset = (float(tileX)-32)*
GRID_SIZE;
314 float yoffset = (float(tileY)-32)*
GRID_SIZE;
315
316 float coord[3];
317 int row, col;
318
319
321 {
322 int j = 0;
324 {
327
328 if (row < lheader.offsetY || row >= lheader.
offsetY + lheader.
height ||
329 col < lheader.offsetX || col >= lheader.
offsetX + lheader.
width)
330 {
331
333 continue;
334 }
335
337 meshData.liquidVerts.append(coord[0]);
338 meshData.liquidVerts.append(coord[2]);
339 meshData.liquidVerts.append(coord[1]);
340 j++;
341 }
342 }
343 else
344 {
346 {
350 }
351 }
352
353 delete[] liquid_map;
354
355 int indices[] = { 0, 0, 0 };
356 int loopStart = 0, loopEnd = 0, loopInc = 0, triInc =
BOTTOM-
TOP;
358
359
360 for (int i = loopStart; i < loopEnd; i += loopInc)
361 {
362 for (
int j =
TOP; j <=
BOTTOM; j += triInc)
363 {
365 ltriangles.append(indices[2] + count);
366 ltriangles.append(indices[1] + count);
367 ltriangles.append(indices[0] + count);
368 }
369 }
370 }
371
372 fclose(mapFile);
373
374
375
376 int loopStart = 0, loopEnd = 0, loopInc = 0, tTriCount = 4;
377 bool useTerrain, useLiquid;
378
379 float* lverts = meshData.liquidVerts.getCArray();
380 int* ltris = ltriangles.getCArray();
381
382 float* tverts = meshData.solidVerts.getCArray();
383 int* ttris = ttriangles.getCArray();
384
385 if ((ltriangles.size() + ttriangles.size()) == 0)
386 return false;
387
388
389
390 float* lverts_copy = nullptr;
391 if (meshData.liquidVerts.size())
392 {
393 lverts_copy = new float[meshData.liquidVerts.size()];
394 memcpy(lverts_copy, lverts, sizeof(float)*meshData.liquidVerts.size());
395 }
396
398 for (int i = loopStart; i < loopEnd; i += loopInc)
399 {
400 for (int j = 0; j < 2; ++j)
401 {
402
403 useTerrain = true;
404 useLiquid = true;
406
407
408
409 if (!meshData.liquidVerts.size() || !ltriangles.size())
410 {
411 useLiquid = false;
412 }
413 else
414 {
416 switch (liquidType)
417 {
418 default:
419 useLiquid = false;
420 break;
423
425 break;
428 break;
431 break;
433
434 useTerrain = false;
435 useLiquid = false;
436 break;
437 }
438 }
439
440
441 if (!ttriangles.size())
442 useTerrain = false;
443
444
445
446 if (useLiquid)
447 {
448 float quadHeight = 0;
450 for (
uint32 idx = 0; idx < 3; idx++)
451 {
452 float h = lverts_copy[ltris[idx] * 3 + 1];
454 {
455 quadHeight += h;
456 validCount++;
457 }
458 }
459
460
461 if (validCount > 0 && validCount < 3)
462 {
463 quadHeight /= validCount;
464 for (
uint32 idx = 0; idx < 3; idx++)
465 {
466 float h = lverts[ltris[idx] * 3 + 1];
468 lverts[ltris[idx] * 3 + 1] = quadHeight;
469 }
470 }
471
472
473 if (validCount == 0)
474 useLiquid = false;
475 }
476
477
478 if (useTerrain && fheader.
holesSize != 0)
480
481
482 if (useTerrain && useLiquid)
483 {
486 for (
uint32 x = 0; x < 3; x++)
487 {
488 float h = lverts[ltris[x] * 3 + 1];
489 if (minLLevel > h)
490 minLLevel = h;
491
492 if (maxLLevel < h)
493 maxLLevel = h;
494 }
495
498 for (
uint32 x = 0; x < 6; x++)
499 {
500 float h = tverts[ttris[x] * 3 + 1];
501 if (maxTLevel < h)
502 maxTLevel = h;
503
504 if (minTLevel > h)
505 minTLevel = h;
506 }
507
508
509 if (minLLevel > maxTLevel)
510 useTerrain = false;
511
512
513 if (minTLevel > maxLLevel)
514 useLiquid = false;
515 }
516
517
518 if (useLiquid)
519 {
520 meshData.liquidType.append(liquidType);
521 for (int k = 0; k < 3; ++k)
522 meshData.liquidTris.append(ltris[k]);
523 }
524
525 if (useTerrain)
526 for (int k = 0; k < 3 * tTriCount / 2; ++k)
527 meshData.solidTris.append(ttris[k]);
528
529
530 ltris += 3;
531 ttris += 3 * tTriCount / 2;
532 }
533 }
534
535 if (lverts_copy)
536 delete [] lverts_copy;
537
538 return meshData.solidTris.size() || meshData.liquidTris.size();
539 }
@ NAV_MAGMA
Definition: MapDefines.h:55
@ NAV_SLIME
Definition: MapDefines.h:56
@ NAV_WATER
Definition: MapDefines.h:57
std::uint8_t uint8
Definition: Define.h:109
std::uint32_t uint32
Definition: Define.h:107
uint16 liquid_entry[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]
Definition: System.cpp:401
uint8 liquid_flags[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]
Definition: System.cpp:402
float V8[ADT_GRID_SIZE][ADT_GRID_SIZE]
Definition: System.cpp:394
float V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]
Definition: System.cpp:395
#define MAP_LIQUID_TYPE_MAGMA
Definition: Map.h:155
#define MAP_HEIGHT_AS_INT8
Definition: Map.h:113
#define MAP_LIQUID_TYPE_NO_WATER
Definition: Map.h:152
#define MAP_LIQUID_NO_TYPE
Definition: Map.h:124
#define MAP_LIQUID_NO_HEIGHT
Definition: Map.h:125
#define MAP_LIQUID_TYPE_WATER
Definition: Map.h:153
#define MAP_LIQUID_TYPE_DARK_WATER
Definition: Map.h:160
#define MAP_LIQUID_TYPE_OCEAN
Definition: Map.h:154
#define MAP_LIQUID_TYPE_SLIME
Definition: Map.h:156
#define MAP_HEIGHT_NO_HEIGHT
Definition: Map.h:111
#define MAP_HEIGHT_AS_INT16
Definition: Map.h:112
static const float GRID_SIZE
Definition: TerrainBuilder.h:48
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:84
uint32 holesSize
Definition: Map.h:99
uint32 heightMapOffset
Definition: Map.h:94
uint32 holesOffset
Definition: Map.h:98
uint32 versionMagic
Definition: Map.h:90
uint32 liquidMapOffset
Definition: Map.h:96
float gridMaxHeight
Definition: Map.h:121
uint32 flags
Definition: Map.h:119
float gridHeight
Definition: Map.h:120
uint8 offsetX
Definition: Map.h:133
uint8 liquidFlags
Definition: Map.h:131
uint8 width
Definition: Map.h:135
uint8 height
Definition: Map.h:136
uint8 flags
Definition: Map.h:130
uint16 liquidType
Definition: Map.h:132
uint8 offsetY
Definition: Map.h:134
float liquidLevel
Definition: Map.h:137
bool isHole(int square, const uint16 holes[16][16])
Determines if the specific position's triangles should be rendered.
Definition: TerrainBuilder.cpp:639
uint8 getLiquidType(int square, const uint8 liquid_type[16][16])
Get the liquid type for a specific position.
Definition: TerrainBuilder.cpp:654
void getHeightTriangle(int square, Spot triangle, int *indices, bool liquid=false)
Get the triangle's vector indices for a specific position.
Definition: TerrainBuilder.cpp:562
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:626
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:542
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:90