Make mapgen generate stuff in chunks of 3^3 mapblocks

This commit is contained in:
Perttu Ahola 2012-01-27 01:40:57 +02:00
parent 38f4dbfb51
commit bdcca4767c
3 changed files with 113 additions and 113 deletions

@ -690,6 +690,9 @@ void Map::updateLighting(enum LightBank bank,
core::map<v3s16, bool> light_sources; core::map<v3s16, bool> light_sources;
core::map<v3s16, u8> unlight_from; core::map<v3s16, u8> unlight_from;
{
//TimeTaker t("first stuff");
core::map<v3s16, MapBlock*>::Iterator i; core::map<v3s16, MapBlock*>::Iterator i;
i = a_blocks.getIterator(); i = a_blocks.getIterator();
@ -704,6 +707,7 @@ void Map::updateLighting(enum LightBank bank,
break; break;
v3s16 pos = block->getPos(); v3s16 pos = block->getPos();
v3s16 posnodes = block->getPosRelative();
modified_blocks.insert(pos, block); modified_blocks.insert(pos, block);
blocks_to_update.insert(pos, block); blocks_to_update.insert(pos, block);
@ -718,20 +722,17 @@ void Map::updateLighting(enum LightBank bank,
try{ try{
v3s16 p(x,y,z); v3s16 p(x,y,z);
MapNode n = block->getNode(v3s16(x,y,z)); MapNode n = block->getNode(p);
u8 oldlight = n.getLight(bank, nodemgr); u8 oldlight = n.getLight(bank, nodemgr);
n.setLight(bank, 0, nodemgr); n.setLight(bank, 0, nodemgr);
block->setNode(v3s16(x,y,z), n); block->setNode(p, n);
// Collect borders for unlighting // Collect borders for unlighting
if(x==0 || x == MAP_BLOCKSIZE-1 if(x==0 || x == MAP_BLOCKSIZE-1
|| y==0 || y == MAP_BLOCKSIZE-1 || y==0 || y == MAP_BLOCKSIZE-1
|| z==0 || z == MAP_BLOCKSIZE-1) || z==0 || z == MAP_BLOCKSIZE-1)
{ {
v3s16 p_map = p + v3s16( v3s16 p_map = p + posnodes;
MAP_BLOCKSIZE*pos.X,
MAP_BLOCKSIZE*pos.Y,
MAP_BLOCKSIZE*pos.Z);
unlight_from.insert(p_map, oldlight); 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 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"); bool enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info");
if(enable_mapgen_debug_info) if(enable_mapgen_debug_info)
infostream<<"initBlockMake(): ("<<blockpos.X<<","<<blockpos.Y<<"," infostream<<"initBlockMake(): "
<<blockpos.Z<<")"<<std::endl; <<"("<<blockpos.X<<","<<blockpos.Y<<","<<blockpos.Z<<") - "
<<"("<<blockpos.X<<","<<blockpos.Y<<","<<blockpos.Z<<")"
<<std::endl;
s16 chunksize = 3;
v3s16 blockpos_div = getContainerPos(blockpos, chunksize);
v3s16 blockpos_min = blockpos_div * chunksize;
v3s16 blockpos_max = blockpos_div * chunksize + v3s16(1,1,1)*(chunksize-1);
// Do nothing if not inside limits (+-1 because of neighbors) // Do nothing if not inside limits (+-1 because of neighbors)
if(blockpos_over_limit(blockpos - v3s16(1,1,1)) || if(blockpos_over_limit(blockpos_min - v3s16(1,1,1)) ||
blockpos_over_limit(blockpos + v3s16(1,1,1))) blockpos_over_limit(blockpos_max + v3s16(1,1,1)))
{ {
data->no_op = true; data->no_op = true;
return; return;
@ -2061,7 +2071,9 @@ void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos)
data->no_op = false; data->no_op = false;
data->seed = m_seed; 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(); data->nodedef = m_gamedef->ndef();
/* /*
@ -2070,17 +2082,17 @@ void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos)
{ {
//TimeTaker timer("initBlockMake() create area"); //TimeTaker timer("initBlockMake() create area");
for(s16 x=-1; x<=1; x++) for(s16 x=blockpos_min.X-1; x<=blockpos_max.X+1; x++)
for(s16 z=-1; z<=1; z++) 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. // Sector metadata is loaded from disk if not already loaded.
ServerMapSector *sector = createSector(sectorpos); ServerMapSector *sector = createSector(sectorpos);
assert(sector); 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); //MapBlock *block = createBlock(p);
// 1) get from memory, 2) load from disk // 1) get from memory, 2) load from disk
MapBlock *block = emergeBlock(p, false); 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 // The area that contains this block and it's neighbors
v3s16 bigarea_blocks_min = blockpos - v3s16(1,1,1); v3s16 bigarea_blocks_min = blockpos_min - v3s16(1,1,1);
v3s16 bigarea_blocks_max = blockpos + v3s16(1,1,1); v3s16 bigarea_blocks_max = blockpos_max + v3s16(1,1,1);
data->vmanip = new ManualMapVoxelManipulator(this); data->vmanip = new ManualMapVoxelManipulator(this);
//data->vmanip->setMap(this); //data->vmanip->setMap(this);
@ -2132,9 +2144,12 @@ void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos)
MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data, MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
core::map<v3s16, MapBlock*> &changed_blocks) core::map<v3s16, MapBlock*> &changed_blocks)
{ {
v3s16 blockpos = data->blockpos; v3s16 blockpos_min = data->blockpos_min;
/*infostream<<"finishBlockMake(): ("<<blockpos.X<<","<<blockpos.Y<<"," v3s16 blockpos_max = data->blockpos_max;
<<blockpos.Z<<")"<<std::endl;*/ v3s16 blockpos_requested = data->blockpos_requested;
/*infostream<<"finishBlockMake(): ("<<blockpos_requested.X<<","
<<blockpos_requested.Y<<","
<<blockpos_requested.Z<<")"<<std::endl;*/
if(data->no_op) if(data->no_op)
{ {
@ -2148,11 +2163,11 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
data->vmanip.print(infostream);*/ data->vmanip.print(infostream);*/
// Make sure affected blocks are loaded // Make sure affected blocks are loaded
for(s16 x=-1; x<=1; x++) for(s16 x=blockpos_min.X-1; x<=blockpos_max.X+1; x++)
for(s16 z=-1; z<=1; z++) for(s16 z=blockpos_min.Z-1; z<=blockpos_max.Z+1; z++)
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);
// Load from disk if not already in memory // Load from disk if not already in memory
emergeBlock(p, false); emergeBlock(p, false);
} }
@ -2179,83 +2194,30 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
v3s16 p = data->transforming_liquid.pop_front(); v3s16 p = data->transforming_liquid.pop_front();
m_transforming_liquid.push_back(p); m_transforming_liquid.push_back(p);
} }
/*
Get central block
*/
MapBlock *block = getBlockNoCreateNoEx(data->blockpos);
assert(block);
/* /*
Set is_underground flag for lighting with sunlight. Do stuff in central blocks
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<v3s16, bool> 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
*/ */
/* /*
Update lighting Update lighting
NOTE: This takes ~60ms, TODO: Investigate why
*/ */
{ {
TimeTaker t("finishBlockMake lighting update"); TimeTaker t("finishBlockMake lighting update");
core::map<v3s16, MapBlock*> lighting_update_blocks; core::map<v3s16, MapBlock*> lighting_update_blocks;
#if 1
// Center block // Center blocks
lighting_update_blocks.insert(block->getPos(), block); 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++)
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<v3s16, MapBlock*>::Iterator
i = changed_blocks.getIterator();
i.atEnd() == false; i++)
{ {
lighting_update_blocks.insert(i.getNode()->getKey(), v3s16 p(x, y, z);
i.getNode()->getValue()); 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); 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 This is cheating, but it is not fast enough if all of them
would actually be updated. would actually be updated.
*/ */
for(s16 x=-1; x<=1; x++) for(s16 x=blockpos_min.X-1; x<=blockpos_max.X+1; x++)
for(s16 y=-1; y<=1; y++) for(s16 z=blockpos_min.Z-1; z<=blockpos_max.Z+1; z++)
for(s16 z=-1; 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); getBlockNoCreateNoEx(p)->setLightingExpired(false);
} }
@ -2275,11 +2237,21 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
t.stop(true); // Hide output t.stop(true); // Hide output
} }
/* // Center blocks
Add random objects to block for(s16 x=blockpos_min.X; x<=blockpos_max.X; x++)
*/ for(s16 z=blockpos_min.Z; z<=blockpos_max.Z; z++)
mapgen::add_random_objects(block); 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 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 Save changed parts of map
@ -2310,19 +2290,23 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
*/ */
//save(MOD_STATE_WRITE_AT_UNLOAD); //save(MOD_STATE_WRITE_AT_UNLOAD);
/*infostream<<"finishBlockMake() done for ("<<blockpos.X<<","<<blockpos.Y<<"," /*infostream<<"finishBlockMake() done for ("<<blockpos_requested.X
<<blockpos.Z<<")"<<std::endl;*/ <<","<<blockpos_requested.Y<<","
<<blockpos_requested.Z<<")"<<std::endl;*/
#if 0 #if 0
if(enable_mapgen_debug_info) if(enable_mapgen_debug_info)
{ {
/* /*
Analyze resulting blocks Analyze resulting blocks
*/ */
for(s16 x=-1; x<=1; x++) /*for(s16 x=blockpos_min.X-1; x<=blockpos_max.X+1; x++)
for(s16 y=-1; y<=1; y++) for(s16 z=blockpos_min.Z-1; z<=blockpos_max.Z+1; z++)
for(s16 z=-1; 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 = block->getPos()+v3s16(x,y,z); v3s16 p = v3s16(x,y,z);
MapBlock *block = getBlockNoCreateNoEx(p); MapBlock *block = getBlockNoCreateNoEx(p);
char spos[20]; char spos[20];
snprintf(spos, 20, "(%2d,%2d,%2d)", x, y, z); snprintf(spos, 20, "(%2d,%2d,%2d)", x, y, z);
@ -2332,6 +2316,9 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
} }
#endif #endif
MapBlock *block = getBlockNoCreateNoEx(blockpos_requested);
assert(block);
return block; return block;
} }

@ -1491,23 +1491,34 @@ void make_block(BlockMakeData *data)
assert(data->vmanip); assert(data->vmanip);
assert(data->nodedef); 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; 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.X<<","<<blockpos.Y<<"," /*dstream<<"makeBlock(): ("<<blockpos.X<<","<<blockpos.Y<<","
<<blockpos.Z<<")"<<std::endl;*/ <<blockpos.Z<<")"<<std::endl;*/
v3s16 blockpos_min = data->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); ManualMapVoxelManipulator &vmanip = *(data->vmanip);
v3s16 blockpos_min = blockpos - v3s16(1,1,1);
v3s16 blockpos_max = blockpos + v3s16(1,1,1);
// Area of center block // Area of center block
v3s16 node_min = blockpos*MAP_BLOCKSIZE; v3s16 node_min = blockpos_min*MAP_BLOCKSIZE;
v3s16 node_max = (blockpos+v3s16(1,1,1))*MAP_BLOCKSIZE-v3s16(1,1,1); v3s16 node_max = (blockpos_max+v3s16(1,1,1))*MAP_BLOCKSIZE-v3s16(1,1,1);
// Full allocated area // Full allocated area
v3s16 full_node_min = (blockpos-1)*MAP_BLOCKSIZE; v3s16 full_node_min = (blockpos_min-1)*MAP_BLOCKSIZE;
v3s16 full_node_max = (blockpos+2)*MAP_BLOCKSIZE-v3s16(1,1,1); v3s16 full_node_max = (blockpos_max+2)*MAP_BLOCKSIZE-v3s16(1,1,1);
// Area of a block // Area of a block
double block_area_nodes = MAP_BLOCKSIZE*MAP_BLOCKSIZE; double block_area_nodes = MAP_BLOCKSIZE*MAP_BLOCKSIZE;

@ -58,7 +58,9 @@ namespace mapgen
bool no_op; bool no_op;
ManualMapVoxelManipulator *vmanip; // Destructor deletes ManualMapVoxelManipulator *vmanip; // Destructor deletes
u64 seed; u64 seed;
v3s16 blockpos; v3s16 blockpos_min;
v3s16 blockpos_max;
v3s16 blockpos_requested;
UniqueQueue<v3s16> transforming_liquid; UniqueQueue<v3s16> transforming_liquid;
INodeDefManager *nodedef; INodeDefManager *nodedef;