Loads a portion of a map's terrain.
135 {
136 char mapFileName[255];
137 sprintf(mapFileName, "maps/%03u%02u%02u.map", mapID, tileY, tileX);
138
139 FILE* mapFile = fopen(mapFileName, "rb");
140 if (!mapFile)
141 return false;
142
146 {
147 fclose(mapFile);
148 printf("%s is the wrong version, please extract new .map files\n", mapFileName);
149 return false;
150 }
151
154
155 bool haveTerrain = false;
156 bool haveLiquid = false;
158 {
161 }
162
163
164 if (!haveTerrain && !haveLiquid)
165 {
166 fclose(mapFile);
167 return false;
168 }
169
170
177 G3D::Array<int> ltriangles;
178 G3D::Array<int> ttriangles;
179
180
181 if (haveTerrain)
182 {
183 float heightMultiplier;
186
188 {
191 int count = 0;
194 if (count != expected)
195 printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
196
198
200 V9[i] = (
float)v9[i] * heightMultiplier + hheader.
gridHeight;
201
203 V8[i] = (
float)v8[i] * heightMultiplier + hheader.
gridHeight;
204 }
206 {
209 int count = 0;
212 if (count != expected)
213 printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
214
216
218 V9[i] = (
float)v9[i] * heightMultiplier + hheader.
gridHeight;
219
221 V8[i] = (
float)v8[i] * heightMultiplier + hheader.
gridHeight;
222 }
223 else
224 {
225 int count = 0;
228 if (count != expected)
229 printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
230 }
231
232
234 {
238 printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
239 }
240
241 int count = meshData.solidVerts.size() / 3;
242 float xoffset = (float(tileX) - 32) *
GRID_SIZE;
243 float yoffset = (float(tileY) - 32) *
GRID_SIZE;
244
245 float coord[3];
246
248 {
250 meshData.solidVerts.append(coord[0]);
251 meshData.solidVerts.append(coord[2]);
252 meshData.solidVerts.append(coord[1]);
253 }
254
256 {
258 meshData.solidVerts.append(coord[0]);
259 meshData.solidVerts.append(coord[2]);
260 meshData.solidVerts.append(coord[1]);
261 }
262
263 int indices[] = { 0, 0, 0 };
264 int loopStart = 0, loopEnd = 0, loopInc = 0;
266 for (int i = loopStart; i < loopEnd; i += loopInc)
268 {
270 ttriangles.append(indices[2] + count);
271 ttriangles.append(indices[1] + count);
272 ttriangles.append(indices[0] + count);
273 }
274 }
275
276
277 if (haveLiquid)
278 {
282 printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
283
284 float* liquid_map = nullptr;
285
287 {
289 printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
291 printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
292 }
293 else
294 {
297 }
298
300 {
302 liquid_map = new float [toRead];
303 if (fread(liquid_map, sizeof(float), toRead, mapFile) != toRead)
304 {
305 printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
306 delete[] liquid_map;
307 liquid_map = nullptr;
308 }
309 }
310
311 int count = meshData.liquidVerts.size() / 3;
312 float xoffset = (float(tileX)-32)*
GRID_SIZE;
313 float yoffset = (float(tileY)-32)*
GRID_SIZE;
314
315 float coord[3];
316 int row, col;
317
318
320 {
321 int j = 0;
323 {
326
327 if (row < lheader.offsetY || row >= lheader.
offsetY + lheader.
height ||
328 col < lheader.offsetX || col >= lheader.
offsetX + lheader.
width)
329 {
330
332 continue;
333 }
334
336 meshData.liquidVerts.append(coord[0]);
337 meshData.liquidVerts.append(coord[2]);
338 meshData.liquidVerts.append(coord[1]);
339 j++;
340 }
341 }
342 else
343 {
345 {
349 }
350 }
351
352 delete[] liquid_map;
353
354 int indices[] = { 0, 0, 0 };
355 int loopStart = 0, loopEnd = 0, loopInc = 0, triInc =
BOTTOM-
TOP;
357
358
359 for (int i = loopStart; i < loopEnd; i += loopInc)
360 {
361 for (
int j =
TOP; j <=
BOTTOM; j += triInc)
362 {
364 ltriangles.append(indices[2] + count);
365 ltriangles.append(indices[1] + count);
366 ltriangles.append(indices[0] + count);
367 }
368 }
369 }
370
371 fclose(mapFile);
372
373
374
375 int loopStart = 0, loopEnd = 0, loopInc = 0, tTriCount = 4;
376 bool useTerrain, useLiquid;
377
378 float* lverts = meshData.liquidVerts.getCArray();
379 int* ltris = ltriangles.getCArray();
380
381 float* tverts = meshData.solidVerts.getCArray();
382 int* ttris = ttriangles.getCArray();
383
384 if ((ltriangles.size() + ttriangles.size()) == 0)
385 return false;
386
387
388
389 float* lverts_copy = nullptr;
390 if (meshData.liquidVerts.size())
391 {
392 lverts_copy = new float[meshData.liquidVerts.size()];
393 memcpy(lverts_copy, lverts, sizeof(float)*meshData.liquidVerts.size());
394 }
395
397 for (int i = loopStart; i < loopEnd; i += loopInc)
398 {
399 for (int j = 0; j < 2; ++j)
400 {
401
402 useTerrain = true;
403 useLiquid = true;
405
406
407
408 if (!meshData.liquidVerts.size() || !ltriangles.size())
409 {
410 useLiquid = false;
411 }
412 else
413 {
415 switch (liquidType)
416 {
417 default:
418 useLiquid = false;
419 break;
422
424 break;
427 break;
430 break;
432
433 useTerrain = false;
434 useLiquid = false;
435 break;
436 }
437 }
438
439
440 if (!ttriangles.size())
441 useTerrain = false;
442
443
444
445 if (useLiquid)
446 {
447 float quadHeight = 0;
449 for (
uint32 idx = 0; idx < 3; idx++)
450 {
451 float h = lverts_copy[ltris[idx] * 3 + 1];
453 {
454 quadHeight += h;
455 validCount++;
456 }
457 }
458
459
460 if (validCount > 0 && validCount < 3)
461 {
462 quadHeight /= validCount;
463 for (
uint32 idx = 0; idx < 3; idx++)
464 {
465 float h = lverts[ltris[idx] * 3 + 1];
467 lverts[ltris[idx] * 3 + 1] = quadHeight;
468 }
469 }
470
471
472 if (validCount == 0)
473 useLiquid = false;
474 }
475
476
477 if (useTerrain && fheader.
holesSize != 0)
479
480
481 if (useTerrain && useLiquid)
482 {
485 for (
uint32 x = 0; x < 3; x++)
486 {
487 float h = lverts[ltris[x] * 3 + 1];
488 if (minLLevel > h)
489 minLLevel = h;
490
491 if (maxLLevel < h)
492 maxLLevel = h;
493 }
494
497 for (
uint32 x = 0; x < 6; x++)
498 {
499 float h = tverts[ttris[x] * 3 + 1];
500 if (maxTLevel < h)
501 maxTLevel = h;
502
503 if (minTLevel > h)
504 minTLevel = h;
505 }
506
507
508 if (minLLevel > maxTLevel)
509 useTerrain = false;
510
511
512 if (minTLevel > maxLLevel)
513 useLiquid = false;
514 }
515
516
517 if (useLiquid)
518 {
519 meshData.liquidType.append(liquidType);
520 for (int k = 0; k < 3; ++k)
521 meshData.liquidTris.append(ltris[k]);
522 }
523
524 if (useTerrain)
525 for (int k = 0; k < 3 * tTriCount / 2; ++k)
526 meshData.solidTris.append(ttris[k]);
527
528
529 ltris += 3;
530 ttris += 3 * tTriCount / 2;
531 }
532 }
533
534 if (lverts_copy)
535 delete [] lverts_copy;
536
537 return meshData.solidTris.size() || meshData.liquidTris.size();
538 }
@ 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:110
std::uint32_t uint32
Definition: Define.h:108
#define MAP_LIQUID_TYPE_MAGMA
Definition: Map.h:157
#define MAP_HEIGHT_AS_INT8
Definition: Map.h:115
#define MAP_LIQUID_TYPE_NO_WATER
Definition: Map.h:154
#define MAP_LIQUID_NO_TYPE
Definition: Map.h:126
#define MAP_LIQUID_NO_HEIGHT
Definition: Map.h:127
#define MAP_LIQUID_TYPE_WATER
Definition: Map.h:155
#define MAP_LIQUID_TYPE_DARK_WATER
Definition: Map.h:162
#define MAP_LIQUID_TYPE_OCEAN
Definition: Map.h:156
#define MAP_LIQUID_TYPE_SLIME
Definition: Map.h:158
#define MAP_HEIGHT_NO_HEIGHT
Definition: Map.h:113
#define MAP_HEIGHT_AS_INT16
Definition: Map.h:114
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
static const float GRID_SIZE
Definition: TerrainBuilder.h:49
static const float INVALID_MAP_LIQ_HEIGHT_MAX
Definition: TerrainBuilder.h:54
static const float INVALID_MAP_LIQ_HEIGHT
Definition: TerrainBuilder.h:53
Spot
Definition: TerrainBuilder.h:31
uint32 const MAP_VERSION_MAGIC
Definition: TerrainBuilder.cpp:83
uint32 holesSize
Definition: Map.h:101
uint32 heightMapOffset
Definition: Map.h:96
uint32 holesOffset
Definition: Map.h:100
uint32 versionMagic
Definition: Map.h:92
uint32 liquidMapOffset
Definition: Map.h:98
float gridMaxHeight
Definition: Map.h:123
uint32 flags
Definition: Map.h:121
float gridHeight
Definition: Map.h:122
uint8 offsetX
Definition: Map.h:135
uint8 liquidFlags
Definition: Map.h:133
uint8 width
Definition: Map.h:137
uint8 height
Definition: Map.h:138
uint8 flags
Definition: Map.h:132
uint16 liquidType
Definition: Map.h:134
uint8 offsetY
Definition: Map.h:136
float liquidLevel
Definition: Map.h:139
bool isHole(int square, const uint16 holes[16][16])
Determines if the specific position's triangles should be rendered.
Definition: TerrainBuilder.cpp:638
uint8 getLiquidType(int square, const uint8 liquid_type[16][16])
Get the liquid type for a specific position.
Definition: TerrainBuilder.cpp:653
void getHeightTriangle(int square, Spot triangle, int *indices, bool liquid=false)
Get the triangle's vector indices for a specific position.
Definition: TerrainBuilder.cpp:561
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:625
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:541
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:89