From bdcca4767c77ccd48b71fa6a5277d72171129da8 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Fri, 27 Jan 2012 01:40:57 +0200 Subject: [PATCH] Make mapgen generate stuff in chunks of 3^3 mapblocks --- src/map.cpp | 199 +++++++++++++++++++++++-------------------------- src/mapgen.cpp | 25 +++++-- src/mapgen.h | 4 +- 3 files changed, 114 insertions(+), 114 deletions(-) diff --git a/src/map.cpp b/src/map.cpp index b3954019..d6b33ed6 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -690,6 +690,9 @@ void Map::updateLighting(enum LightBank bank, core::map light_sources; core::map unlight_from; + + { + //TimeTaker t("first stuff"); core::map::Iterator i; i = a_blocks.getIterator(); @@ -704,6 +707,7 @@ void Map::updateLighting(enum LightBank bank, break; v3s16 pos = block->getPos(); + v3s16 posnodes = block->getPosRelative(); modified_blocks.insert(pos, block); blocks_to_update.insert(pos, block); @@ -718,20 +722,17 @@ void Map::updateLighting(enum LightBank bank, try{ v3s16 p(x,y,z); - MapNode n = block->getNode(v3s16(x,y,z)); + MapNode n = block->getNode(p); u8 oldlight = n.getLight(bank, nodemgr); n.setLight(bank, 0, nodemgr); - block->setNode(v3s16(x,y,z), n); + block->setNode(p, n); // Collect borders for unlighting if(x==0 || x == MAP_BLOCKSIZE-1 || y==0 || y == MAP_BLOCKSIZE-1 || z==0 || z == MAP_BLOCKSIZE-1) { - v3s16 p_map = p + v3s16( - MAP_BLOCKSIZE*pos.X, - MAP_BLOCKSIZE*pos.Y, - MAP_BLOCKSIZE*pos.Z); + v3s16 p_map = p + posnodes; unlight_from.insert(p_map, oldlight); } } @@ -783,6 +784,8 @@ void Map::updateLighting(enum LightBank bank, } } + + } /* Enable this to disable proper lighting for speeding up map @@ -2048,12 +2051,19 @@ void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos) { bool enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info"); if(enable_mapgen_debug_info) - infostream<<"initBlockMake(): ("<no_op = true; return; @@ -2061,7 +2071,9 @@ void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos) data->no_op = false; data->seed = m_seed; - data->blockpos = blockpos; + data->blockpos_min = blockpos_min; + data->blockpos_max = blockpos_max; + data->blockpos_requested = blockpos; data->nodedef = m_gamedef->ndef(); /* @@ -2070,17 +2082,17 @@ void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos) { //TimeTaker timer("initBlockMake() create area"); - for(s16 x=-1; x<=1; x++) - for(s16 z=-1; z<=1; z++) + for(s16 x=blockpos_min.X-1; x<=blockpos_max.X+1; x++) + for(s16 z=blockpos_min.Z-1; z<=blockpos_max.Z+1; z++) { - v2s16 sectorpos(blockpos.X+x, blockpos.Z+z); + v2s16 sectorpos(x, z); // Sector metadata is loaded from disk if not already loaded. ServerMapSector *sector = createSector(sectorpos); assert(sector); - for(s16 y=-1; y<=1; y++) + for(s16 y=blockpos_min.Y-1; y<=blockpos_max.Y+1; y++) { - v3s16 p(blockpos.X+x, blockpos.Y+y, blockpos.Z+z); + v3s16 p(x,y,z); //MapBlock *block = createBlock(p); // 1) get from memory, 2) load from disk MapBlock *block = emergeBlock(p, false); @@ -2114,8 +2126,8 @@ void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos) */ // The area that contains this block and it's neighbors - v3s16 bigarea_blocks_min = blockpos - v3s16(1,1,1); - v3s16 bigarea_blocks_max = blockpos + v3s16(1,1,1); + v3s16 bigarea_blocks_min = blockpos_min - v3s16(1,1,1); + v3s16 bigarea_blocks_max = blockpos_max + v3s16(1,1,1); data->vmanip = new ManualMapVoxelManipulator(this); //data->vmanip->setMap(this); @@ -2132,9 +2144,12 @@ void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos) MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data, core::map &changed_blocks) { - v3s16 blockpos = data->blockpos; - /*infostream<<"finishBlockMake(): ("<blockpos_min; + v3s16 blockpos_max = data->blockpos_max; + v3s16 blockpos_requested = data->blockpos_requested; + /*infostream<<"finishBlockMake(): ("<no_op) { @@ -2148,11 +2163,11 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data, data->vmanip.print(infostream);*/ // Make sure affected blocks are loaded - for(s16 x=-1; x<=1; x++) - for(s16 z=-1; z<=1; z++) - for(s16 y=-1; y<=1; y++) + for(s16 x=blockpos_min.X-1; x<=blockpos_max.X+1; x++) + for(s16 z=blockpos_min.Z-1; z<=blockpos_max.Z+1; z++) + for(s16 y=blockpos_min.Y-1; y<=blockpos_max.Y+1; y++) { - v3s16 p(blockpos.X+x, blockpos.Y+y, blockpos.Z+z); + v3s16 p(x, y, z); // Load from disk if not already in memory emergeBlock(p, false); } @@ -2179,83 +2194,30 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data, v3s16 p = data->transforming_liquid.pop_front(); m_transforming_liquid.push_back(p); } - - /* - Get central block - */ - MapBlock *block = getBlockNoCreateNoEx(data->blockpos); - assert(block); /* - Set is_underground flag for lighting with sunlight. - - Refer to map generator heuristics. - - NOTE: This is done in initChunkMake - */ - //block->setIsUnderground(mapgen::block_is_underground(data->seed, blockpos)); - - - /* - Add sunlight to central block. - This makes in-dark-spawning monsters to not flood the whole thing. - Do not spread the light, though. - */ - /*core::map light_sources; - bool black_air_left = false; - block->propagateSunlight(light_sources, true, &black_air_left);*/ - - /* - NOTE: Lighting and object adding shouldn't really be here, but - lighting is a bit tricky to move properly to makeBlock. - TODO: Do this the right way anyway, that is, move it to makeBlock. - - There needs to be some way for makeBlock to report back if - the lighting update is going further down because of the - new block blocking light + Do stuff in central blocks */ /* Update lighting - NOTE: This takes ~60ms, TODO: Investigate why */ { TimeTaker t("finishBlockMake lighting update"); core::map lighting_update_blocks; -#if 1 - // Center block - lighting_update_blocks.insert(block->getPos(), block); - - /*{ - s16 x = 0; - s16 z = 0; - v3s16 p = block->getPos()+v3s16(x,1,z); - lighting_update_blocks[p] = getBlockNoCreateNoEx(p); - }*/ -#endif -#if 0 - // All modified blocks - // NOTE: Should this be done? If this is not done, then the lighting - // of the others will be updated in a different place, one by one, i - // think... or they might not? Well, at least they are left marked as - // "lighting expired"; it seems that is not handled at all anywhere, - // so enabling this will slow it down A LOT because otherwise it - // would not do this at all. This causes the black trees. - for(core::map::Iterator - i = changed_blocks.getIterator(); - i.atEnd() == false; i++) + + // Center blocks + for(s16 x=blockpos_min.X; x<=blockpos_max.X; x++) + for(s16 z=blockpos_min.Z; z<=blockpos_max.Z; z++) + for(s16 y=blockpos_min.Y; y<=blockpos_max.Y; y++) { - lighting_update_blocks.insert(i.getNode()->getKey(), - i.getNode()->getValue()); + v3s16 p(x, y, z); + MapBlock *block = getBlockNoCreateNoEx(p); + assert(block); + lighting_update_blocks.insert(block->getPos(), block); } - /*// Also force-add all the upmost blocks for proper sunlight - for(s16 x=-1; x<=1; x++) - for(s16 z=-1; z<=1; z++) - { - v3s16 p = block->getPos()+v3s16(x,1,z); - lighting_update_blocks[p] = getBlockNoCreateNoEx(p); - }*/ -#endif + updateLighting(lighting_update_blocks, changed_blocks); /* @@ -2263,11 +2225,11 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data, This is cheating, but it is not fast enough if all of them would actually be updated. */ - for(s16 x=-1; x<=1; x++) - for(s16 y=-1; y<=1; y++) - for(s16 z=-1; z<=1; z++) + for(s16 x=blockpos_min.X-1; x<=blockpos_max.X+1; x++) + for(s16 z=blockpos_min.Z-1; z<=blockpos_max.Z+1; z++) + for(s16 y=blockpos_min.Y-1; y<=blockpos_max.Y+1; y++) { - v3s16 p = block->getPos()+v3s16(x,y,z); + v3s16 p(x, y, z); getBlockNoCreateNoEx(p)->setLightingExpired(false); } @@ -2275,11 +2237,21 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data, t.stop(true); // Hide output } - /* - Add random objects to block - */ - mapgen::add_random_objects(block); + // Center blocks + for(s16 x=blockpos_min.X; x<=blockpos_max.X; x++) + for(s16 z=blockpos_min.Z; z<=blockpos_max.Z; z++) + for(s16 y=blockpos_min.Y; y<=blockpos_max.Y; y++) + { + v3s16 p(x, y, z); + MapBlock *block = getBlockNoCreateNoEx(p); + assert(block); + /* + Add random objects to block + */ + mapgen::add_random_objects(block); + } + /* Go through changed blocks */ @@ -2300,9 +2272,17 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data, } /* - Set central block as generated + Set central blocks as generated */ - block->setGenerated(true); + for(s16 x=blockpos_min.X; x<=blockpos_max.X; x++) + for(s16 z=blockpos_min.Z; z<=blockpos_max.Z; z++) + for(s16 y=blockpos_min.Y; y<=blockpos_max.Y; y++) + { + v3s16 p(x, y, z); + MapBlock *block = getBlockNoCreateNoEx(p); + assert(block); + block->setGenerated(true); + } /* Save changed parts of map @@ -2310,19 +2290,23 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data, */ //save(MOD_STATE_WRITE_AT_UNLOAD); - /*infostream<<"finishBlockMake() done for ("<getPos()+v3s16(x,y,z); + /*for(s16 x=blockpos_min.X-1; x<=blockpos_max.X+1; x++) + for(s16 z=blockpos_min.Z-1; z<=blockpos_max.Z+1; z++) + for(s16 y=blockpos_min.Y-1; y<=blockpos_max.Y+1; y++)*/ + for(s16 x=blockpos_min.X-0; x<=blockpos_max.X+0; x++) + for(s16 z=blockpos_min.Z-0; z<=blockpos_max.Z+0; z++) + for(s16 y=blockpos_min.Y-0; y<=blockpos_max.Y+0; y++) + { + v3s16 p = v3s16(x,y,z); MapBlock *block = getBlockNoCreateNoEx(p); char spos[20]; snprintf(spos, 20, "(%2d,%2d,%2d)", x, y, z); @@ -2332,6 +2316,9 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data, } #endif + MapBlock *block = getBlockNoCreateNoEx(blockpos_requested); + assert(block); + return block; } diff --git a/src/mapgen.cpp b/src/mapgen.cpp index fe2ce13f..0b8781f5 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -1491,23 +1491,34 @@ void make_block(BlockMakeData *data) assert(data->vmanip); assert(data->nodedef); + assert(data->blockpos_requested.X >= data->blockpos_min.X && + data->blockpos_requested.Y >= data->blockpos_min.Y && + data->blockpos_requested.Z >= data->blockpos_min.Z); + assert(data->blockpos_requested.X <= data->blockpos_max.X && + data->blockpos_requested.Y <= data->blockpos_max.Y && + data->blockpos_requested.Z <= data->blockpos_max.Z); INodeDefManager *ndef = data->nodedef; - v3s16 blockpos = data->blockpos; + // Hack: use minimum block coordinates for old code that assumes + // a single block + v3s16 blockpos = data->blockpos_min; /*dstream<<"makeBlock(): ("<blockpos_min; + v3s16 blockpos_max = data->blockpos_max; + v3s16 blockpos_full_min = blockpos_min - v3s16(1,1,1); + v3s16 blockpos_full_max = blockpos_max + v3s16(1,1,1); + ManualMapVoxelManipulator &vmanip = *(data->vmanip); - v3s16 blockpos_min = blockpos - v3s16(1,1,1); - v3s16 blockpos_max = blockpos + v3s16(1,1,1); // Area of center block - v3s16 node_min = blockpos*MAP_BLOCKSIZE; - v3s16 node_max = (blockpos+v3s16(1,1,1))*MAP_BLOCKSIZE-v3s16(1,1,1); + v3s16 node_min = blockpos_min*MAP_BLOCKSIZE; + v3s16 node_max = (blockpos_max+v3s16(1,1,1))*MAP_BLOCKSIZE-v3s16(1,1,1); // Full allocated area - v3s16 full_node_min = (blockpos-1)*MAP_BLOCKSIZE; - v3s16 full_node_max = (blockpos+2)*MAP_BLOCKSIZE-v3s16(1,1,1); + v3s16 full_node_min = (blockpos_min-1)*MAP_BLOCKSIZE; + v3s16 full_node_max = (blockpos_max+2)*MAP_BLOCKSIZE-v3s16(1,1,1); // Area of a block double block_area_nodes = MAP_BLOCKSIZE*MAP_BLOCKSIZE; diff --git a/src/mapgen.h b/src/mapgen.h index 207dfdaf..20eefea2 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -58,7 +58,9 @@ namespace mapgen bool no_op; ManualMapVoxelManipulator *vmanip; // Destructor deletes u64 seed; - v3s16 blockpos; + v3s16 blockpos_min; + v3s16 blockpos_max; + v3s16 blockpos_requested; UniqueQueue transforming_liquid; INodeDefManager *nodedef; -- 2.30.2