84 std::vector<std::string> files;
85 uint32 mapID, tileX, tileY, tileID, count = 0;
87 printf(
"Discovering maps... ");
89 for (
uint32 i = 0; i < files.size(); ++i)
91 mapID =
uint32(atoi(files[i].substr(0, 4).c_str()));
94 m_tiles.insert(std::pair<
uint32, std::set<uint32>*>(mapID,
new std::set<uint32>));
101 for (
uint32 i = 0; i < files.size(); ++i)
103 mapID =
uint32(atoi(files[i].substr(0, 4).c_str()));
104 m_tiles.insert(std::pair<
uint32, std::set<uint32>*>(mapID,
new std::set<uint32>));
107 printf(
"found %u.\n", count);
110 printf(
"Discovering tiles... ");
111 for (TileList::iterator itr =
m_tiles.begin(); itr !=
m_tiles.end(); ++itr)
113 std::set<uint32>* tiles = (*itr).second;
114 mapID = (*itr).first;
118 snprintf(filter,
sizeof(filter),
"%04u*.vmtile", mapID);
120 for (
uint32 i = 0; i < files.size(); ++i)
122 tileX =
uint32(atoi(files[i].substr(8, 2).c_str()));
123 tileY =
uint32(atoi(files[i].substr(5, 2).c_str()));
126 tiles->insert(tileID);
131 snprintf(filter,
sizeof(filter),
"%04u*", mapID);
133 for (
uint32 i = 0; i < files.size(); ++i)
135 tileY =
uint32(atoi(files[i].substr(5, 2).c_str()));
136 tileX =
uint32(atoi(files[i].substr(8, 2).c_str()));
139 if (tiles->insert(tileID).second)
143 printf(
"found %u.\n", count);
409 int polyBits = STATIC_POLY_BITS;
411 int maxTiles = tiles->size();
412 int maxPolysPerTile = 1 << polyBits;
416 uint32 tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0, tileX, tileY;
417 for (std::set<uint32>::iterator it = tiles->begin(); it != tiles->end(); ++it)
421 if (tileX > tileXMax)
423 else if (tileX < tileXMin)
426 if (tileY > tileYMax)
428 else if (tileY < tileYMin)
433 float bmin[3], bmax[3];
439 dtNavMeshParams navMeshParams;
440 memset(&navMeshParams, 0,
sizeof(dtNavMeshParams));
443 rcVcopy(navMeshParams.orig, bmin);
444 navMeshParams.maxTiles = maxTiles;
445 navMeshParams.maxPolys = maxPolysPerTile;
447 navMesh = dtAllocNavMesh();
448 printf(
"[Map %04u] Creating navMesh...\n", mapID);
449 if (!navMesh->init(&navMeshParams))
451 printf(
"[Map %04u] Failed creating navmesh! \n", mapID);
456 snprintf(fileName,
sizeof(fileName),
"mmaps/%04u.mmap", mapID);
458 FILE* file = fopen(fileName,
"wb");
461 dtFreeNavMesh(navMesh);
463 snprintf(message,
sizeof(message),
"[Map %04u] Failed to open %s for writing!\n", mapID, fileName);
469 fwrite(&navMeshParams,
sizeof(dtNavMeshParams), 1, file);
475 MeshData &meshData,
float bmin[3],
float bmax[3],
480 snprintf(tileString,
sizeof(tileString),
"[Map %04u] [%02i,%02i]: ", mapID, tileX, tileY);
481 printf(
"%s Building movemap tiles...\n", tileString);
485 float* tVerts = meshData.
solidVerts.getCArray();
486 int tVertCount = meshData.
solidVerts.size() / 3;
487 int* tTris = meshData.
solidTris.getCArray();
488 int tTriCount = meshData.
solidTris.size() / 3;
493 int lTriCount = meshData.
liquidTris.size() / 3;
499 const static float BASE_UNIT_DIM =
m_bigBaseUnit ? 0.5333333f : 0.2666666f;
502 const static int VERTEX_PER_MAP = int(
GRID_SIZE/BASE_UNIT_DIM + 0.5f);
504 const static int TILES_PER_MAP = VERTEX_PER_MAP/VERTEX_PER_TILE;
507 memset(&config, 0,
sizeof(rcConfig));
509 rcVcopy(config.bmin, bmin);
510 rcVcopy(config.bmax, bmax);
512 config.maxVertsPerPoly = DT_VERTS_PER_POLYGON;
513 config.cs = BASE_UNIT_DIM;
514 config.ch = BASE_UNIT_DIM;
516 config.tileSize = VERTEX_PER_TILE;
518 config.borderSize = config.walkableRadius + 3;
519 config.maxEdgeLen = VERTEX_PER_TILE + 1;
522 config.minRegionArea = rcSqr(60);
523 config.mergeRegionArea = rcSqr(50);
524 config.maxSimplificationError = 1.8f;
525 config.detailSampleDist = config.cs * 64;
526 config.detailSampleMaxError = config.ch * 2;
529 rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height);
532 Tile* tiles =
new Tile[TILES_PER_MAP * TILES_PER_MAP];
535 rcConfig tileCfg = config;
536 tileCfg.width = config.tileSize + config.borderSize*2;
537 tileCfg.height = config.tileSize + config.borderSize*2;
540 rcPolyMesh** pmmerge =
new rcPolyMesh*[TILES_PER_MAP * TILES_PER_MAP];
543 printf(
"%s alloc pmmerge FAILED!\n", tileString);
547 rcPolyMeshDetail** dmmerge =
new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP];
550 printf(
"%s alloc dmmerge FAILED!\n", tileString);
557 for (
int y = 0; y < TILES_PER_MAP; ++y)
559 for (
int x = 0; x < TILES_PER_MAP; ++x)
561 Tile& tile = tiles[x + y * TILES_PER_MAP];
564 tileCfg.bmin[0] = config.bmin[0] + float(x*config.tileSize - config.borderSize)*config.cs;
565 tileCfg.bmin[2] = config.bmin[2] + float(y*config.tileSize - config.borderSize)*config.cs;
566 tileCfg.bmax[0] = config.bmin[0] + float((x+1)*config.tileSize + config.borderSize)*config.cs;
567 tileCfg.bmax[2] = config.bmin[2] + float((y+1)*config.tileSize + config.borderSize)*config.cs;
570 tile.
solid = rcAllocHeightfield();
571 if (!tile.
solid || !rcCreateHeightfield(
m_rcContext, *tile.
solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch))
573 printf(
"%s Failed building heightfield! \n", tileString);
578 unsigned char* triFlags =
new unsigned char[tTriCount];
579 memset(triFlags,
NAV_GROUND, tTriCount*
sizeof(
unsigned char));
580 rcClearUnwalkableTriangles(
m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags);
581 rcRasterizeTriangles(
m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.
solid, config.walkableClimb);
584 rcFilterLowHangingWalkableObstacles(
m_rcContext, config.walkableClimb, *tile.
solid);
585 rcFilterLedgeSpans(
m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.
solid);
586 rcFilterWalkableLowHeightSpans(
m_rcContext, tileCfg.walkableHeight, *tile.
solid);
588 rcRasterizeTriangles(
m_rcContext, lVerts, lVertCount, lTris, lTriFlags, lTriCount, *tile.
solid, config.walkableClimb);
591 tile.
chf = rcAllocCompactHeightfield();
592 if (!tile.
chf || !rcBuildCompactHeightfield(
m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.
solid, *tile.
chf))
594 printf(
"%s Failed compacting heightfield! \n", tileString);
599 if (!rcErodeWalkableArea(
m_rcContext, config.walkableRadius, *tile.
chf))
601 printf(
"%s Failed eroding area! \n", tileString);
607 printf(
"%s Failed building distance field! \n", tileString);
611 if (!rcBuildRegions(
m_rcContext, *tile.
chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea))
613 printf(
"%s Failed building regions! \n", tileString);
617 tile.
cset = rcAllocContourSet();
618 if (!tile.
cset || !rcBuildContours(
m_rcContext, *tile.
chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *tile.
cset))
620 printf(
"%s Failed building contours! \n", tileString);
625 tile.
pmesh = rcAllocPolyMesh();
628 printf(
"%s Failed building polymesh! \n", tileString);
632 tile.
dmesh = rcAllocPolyMeshDetail();
633 if (!tile.
dmesh || !rcBuildPolyMeshDetail(
m_rcContext, *tile.
pmesh, *tile.
chf, tileCfg.detailSampleDist, tileCfg.detailSampleMaxError, *tile.
dmesh))
635 printf(
"%s Failed building polymesh detail!\n", tileString);
642 rcFreeHeightField(tile.
solid);
644 rcFreeCompactHeightfield(tile.
chf);
646 rcFreeContourSet(tile.
cset);
651 pmmerge[nmerge] = tile.
pmesh;
652 dmmerge[nmerge] = tile.
dmesh;
661 printf(
"%s alloc iv.polyMesh FAILED!\n", tileString);
669 printf(
"%s alloc m_dmesh FAILED!\n", tileString);
682 for (
int i = 0; i < iv.
polyMesh->npolys; ++i)
683 if (iv.
polyMesh->areas[i] & RC_WALKABLE_AREA)
687 dtNavMeshCreateParams params;
688 memset(¶ms, 0,
sizeof(params));
690 params.vertCount = iv.
polyMesh->nverts;
692 params.polyAreas = iv.
polyMesh->areas;
693 params.polyFlags = iv.
polyMesh->flags;
694 params.polyCount = iv.
polyMesh->npolys;
709 params.walkableHeight = BASE_UNIT_DIM*config.walkableHeight;
710 params.walkableRadius = BASE_UNIT_DIM*config.walkableRadius;
711 params.walkableClimb = BASE_UNIT_DIM*config.walkableClimb;
712 params.tileX = (((bmin[0] + bmax[0]) / 2) - navMesh->getParams()->orig[0]) /
GRID_SIZE;
713 params.tileY = (((bmin[2] + bmax[2]) / 2) - navMesh->getParams()->orig[2]) /
GRID_SIZE;
714 rcVcopy(params.bmin, bmin);
715 rcVcopy(params.bmax, bmax);
716 params.cs = config.cs;
717 params.ch = config.ch;
718 params.tileLayer = 0;
719 params.buildBvTree =
true;
722 unsigned char* navData = NULL;
729 if (params.nvp > DT_VERTS_PER_POLYGON)
731 printf(
"%s Invalid verts-per-polygon value!\n", tileString);
734 if (params.vertCount >= 0xffff)
736 printf(
"%s Too many vertices!\n", tileString);
739 if (!params.vertCount || !params.verts)
748 if (!params.polyCount || !params.polys ||
749 TILES_PER_MAP*TILES_PER_MAP == params.polyCount)
754 printf(
"%s No polygons to build on tile!\n", tileString);
757 if (!params.detailMeshes || !params.detailVerts || !params.detailTris)
759 printf(
"%s No detail mesh to build tile!\n", tileString);
763 printf(
"%s Building navmesh tile...\n", tileString);
764 if (!dtCreateNavMeshData(¶ms, &navData, &navDataSize))
766 printf(
"%s Failed building navmesh tile!\n", tileString);
770 dtTileRef tileRef = 0;
771 printf(
"%s Adding tile to navmesh...\n", tileString);
774 dtStatus dtResult = navMesh->addTile(navData, navDataSize, DT_TILE_FREE_DATA, 0, &tileRef);
775 if (!tileRef || dtResult != DT_SUCCESS)
777 printf(
"%s Failed adding tile to navmesh!\n", tileString);
783 snprintf(fileName,
sizeof(fileName),
"mmaps/%04u_%02i_%02i.mmtile", mapID, tileY, tileX);
784 FILE* file = fopen(fileName,
"wb");
788 snprintf(message,
sizeof(message),
"[Map %04u] Failed to open %s for writing!\n", mapID, fileName);
790 navMesh->removeTile(tileRef, NULL, NULL);
794 printf(
"%s Writing to file...\n", tileString);
803 fwrite(navData,
sizeof(
unsigned char), navDataSize, file);
807 navMesh->removeTile(tileRef, NULL, NULL);
814 for (
int i = 0; i < iv.
polyMesh->nverts; ++i)
816 unsigned short* v = &iv.
polyMesh->verts[i*3];
817 v[0] += (
unsigned short)config.borderSize;
818 v[2] += (
unsigned short)config.borderSize;
822 iv.
writeIV(mapID, tileX, tileY);