void MapBuilder::buildMap(uint32 mapID) { printf("Building map %03u:\n", mapID); set<uint32>* tiles = getTileList(mapID); // make sure we process maps which don't have tiles if (!tiles->size()) { // convert coord bounds to grid bounds uint32 minX, minY, maxX, maxY; getGridBounds(mapID, minX, minY, maxX, maxY); // add all tiles within bounds to tile list. for (uint32 i = minX; i <= maxX; ++i) for (uint32 j = minY; j <= maxY; ++j) tiles->insert(StaticMapTree::packTileID(i, j)); } if (!tiles->size()) return; // build navMesh dtNavMesh* navMesh = NULL; buildNavMesh(mapID, navMesh); if (!navMesh) { printf("Failed creating navmesh! \n"); return; } // now start building mmtiles for each tile printf("We have %u tiles. \n", (unsigned int)tiles->size()); for (set<uint32>::iterator it = tiles->begin(); it != tiles->end(); ++it) { uint32 tileX, tileY; // unpack tile coords StaticMapTree::unpackTileID((*it), tileX, tileY); if (shouldSkipTile(mapID, tileX, tileY)) continue; buildTile(mapID, tileX, tileY, navMesh); } dtFreeNavMesh(navMesh); printf("Complete! \n\n"); }
void MapBuilder::buildNavMesh(uint32 mapID, dtNavMesh* &navMesh) { std::set<uint32>* tiles = getTileList(mapID); // old code for non-statically assigned bitmask sizes: ///*** calculate number of bits needed to store tiles & polys ***/ //int tileBits = dtIlog2(dtNextPow2(tiles->size())); //if (tileBits < 1) tileBits = 1; // need at least one bit! //int polyBits = sizeof(dtPolyRef)*8 - SALT_MIN_BITS - tileBits; int polyBits = STATIC_POLY_BITS; int maxTiles = tiles->size(); int maxPolysPerTile = 1 << polyBits; /*** calculate bounds of map ***/ uint32 tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0, tileX, tileY; for (std::set<uint32>::iterator it = tiles->begin(); it != tiles->end(); ++it) { StaticMapTree::unpackTileID(*it, tileX, tileY); if (tileX > tileXMax) tileXMax = tileX; else if (tileX < tileXMin) tileXMin = tileX; if (tileY > tileYMax) tileYMax = tileY; else if (tileY < tileYMin) tileYMin = tileY; } // use Max because '32 - tileX' is negative for values over 32 float bmin[3], bmax[3]; getTileBounds(tileXMax, tileYMax, NULL, 0, bmin, bmax); /*** now create the navmesh ***/ // navmesh creation params dtNavMeshParams navMeshParams; memset(&navMeshParams, 0, sizeof(dtNavMeshParams)); navMeshParams.tileWidth = GRID_SIZE; navMeshParams.tileHeight = GRID_SIZE; rcVcopy(navMeshParams.orig, bmin); navMeshParams.maxTiles = maxTiles; navMeshParams.maxPolys = maxPolysPerTile; navMesh = dtAllocNavMesh(); printf("[Map %04u] Creating navMesh...\n", mapID); if (!navMesh->init(&navMeshParams)) { printf("[Map %04u] Failed creating navmesh! \n", mapID); return; } char fileName[25]; sprintf(fileName, "mmaps/%04u.mmap", mapID); FILE* file = fopen(fileName, "wb"); if (!file) { dtFreeNavMesh(navMesh); char message[1024]; sprintf(message, "[Map %04u] Failed to open %s for writing!\n", mapID, fileName); perror(message); return; } // now that we know navMesh params are valid, we can write them to file fwrite(&navMeshParams, sizeof(dtNavMeshParams), 1, file); fclose(file); }
void MapBuilder::buildNavMesh(int mapID, dtNavMesh*& navMesh, dtNavMeshParams*& navMeshParams) { bool isFirstNavMesh = navMeshParams ? false : true; if (isFirstNavMesh) { set<uint32>* tiles = getTileList(mapID); int polyBits = DT_POLY_BITS; int maxTiles = tiles->size(); int maxPolysPerTile = 1 << polyBits; /*** calculate bounds of map ***/ uint32 tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0, tileX, tileY; for (set<uint32>::iterator it = tiles->begin(); it != tiles->end(); ++it) { StaticMapTree::unpackTileID((*it), tileX, tileY); if (tileX > tileXMax) { tileXMax = tileX; } else if (tileX < tileXMin) { tileXMin = tileX; } if (tileY > tileYMax) { tileYMax = tileY; } else if (tileY < tileYMin) { tileYMin = tileY; } } // use Max because '32 - tileX' is negative for values over 32 float bmin[3], bmax[3]; getTileBounds(tileXMax, tileYMax, NULL, 0, bmin, bmax); /*** now create the navmesh ***/ // navmesh creation params navMeshParams = new dtNavMeshParams(); memset(navMeshParams, 0, sizeof(dtNavMeshParams)); navMeshParams->tileWidth = GRID_SIZE; navMeshParams->tileHeight = GRID_SIZE; rcVcopy(navMeshParams->orig, bmin); navMeshParams->maxTiles = maxTiles; navMeshParams->maxPolys = maxPolysPerTile; } navMesh = dtAllocNavMesh(); if (!navMesh->init(navMeshParams)) { printf("Failed creating navmesh! \n"); return; } if (isFirstNavMesh) { char fileName[25]; sprintf(fileName, "mmaps/%03u.mmap", mapID); FILE* file = fopen(fileName, "wb"); if (!file) { dtFreeNavMesh(navMesh); char message[1024]; sprintf(message, "Failed to open %s for writing!\n", fileName); perror(message); return; } // now that we know navMesh params are valid, we can write them to file fwrite(navMeshParams, sizeof(dtNavMeshParams), 1, file); fclose(file); } }
void MapBuilder::buildMap(int mapID, bool standAlone) { set<uint32>* tiles = getTileList(mapID); // make sure we process maps which don't have tiles if (!tiles->size()) { // convert coord bounds to grid bounds uint32 minX, minY, maxX, maxY; getGridBounds(mapID, minX, minY, maxX, maxY); // add all tiles within bounds to tile list. for (uint32 i = minX; i <= maxX; ++i) for (uint32 j = minY; j <= maxY; ++j) { tiles->insert(StaticMapTree::packTileID(i, j)); } } if (!tiles->size()) { return; } // build navMesh dtNavMesh* navMesh = NULL; dtNavMeshParams* meshParams = NULL; buildNavMesh(mapID, navMesh, meshParams); if (!navMesh) { printf("Failed creating navmesh for map %03u! \n", mapID); if (meshParams) { delete meshParams; } return; } if (activated()) { dtFreeNavMesh(navMesh); } // each tile will get it's own pointer to navMesh // now start building/scheduling mmtiles for each tile printf(" %s map %03u [%u tiles]\n", activated() ? "Scheduling" : "Building", mapID, (unsigned int)tiles->size()); for (set<uint32>::iterator it = tiles->begin(); it != tiles->end(); ++it) { uint32 tileX, tileY; // unpack tile coords StaticMapTree::unpackTileID((*it), tileX, tileY); if (shouldSkipTile(mapID, tileX, tileY)) { continue; } if (!activated()) { buildTile(mapID, tileX, tileY, navMesh); } else { dtNavMesh *mesh = NULL; buildNavMesh(mapID, mesh, meshParams); //meshParams is not null, so we get a new pointer to dtNavMesh if (mesh) { TileBuilder* tb = new TileBuilder(this, mapID, tileX, tileY, mesh); Tile_Message_Block *mb = new Tile_Message_Block(tb); if (m_threadPool->putq(mb) == -1) { break; } } } } if (activated() && standAlone) { Tile_Message_Block *finish_mb = new Tile_Message_Block(NULL); finish_mb->msg_type(ACE_Message_Block::MB_HANGUP); m_threadPool->putq(finish_mb); m_threadPool->wait(); } if (!activated()) { dtFreeNavMesh(navMesh); } if (meshParams) { delete meshParams; } if (!activated()) { printf(" Map %03u complete!\n\n", mapID); } }