Skip to content
Permalink
Browse files

Lighting: Update lighting at block loading

This commit updates mapblocks' light if necessary when they are loaded.
This removes ghost lighting.
  • Loading branch information...
juhdanad authored and paramat committed Oct 27, 2016
1 parent 2bd1002 commit f17c9c45dc30a388675d46418d278a4a029206e2
Showing with 273 additions and 121 deletions.
  1. +0 −6 src/clientiface.cpp
  2. +61 −70 src/map.cpp
  3. +11 −10 src/mapblock.cpp
  4. +39 −23 src/mapblock.h
  5. +3 −2 src/serialization.h
  6. +145 −7 src/voxelalgorithms.cpp
  7. +14 −3 src/voxelalgorithms.h
@@ -283,12 +283,6 @@ void RemoteClient::GetNextBlocks (
surely_not_found_on_disk = true;
}

// Block is valid if lighting is up-to-date and data exists
if(block->isValid() == false)
{
block_is_invalid = true;
}

if(block->isGenerated() == false)
block_is_invalid = true;

@@ -824,7 +824,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
// Update lighting
std::vector<std::pair<v3s16, MapNode> > oldnodes;
oldnodes.push_back(std::pair<v3s16, MapNode>(p, oldnode));
voxalgo::update_lighting_nodes(this, m_nodedef, oldnodes, modified_blocks);
voxalgo::update_lighting_nodes(this, oldnodes, modified_blocks);

for(std::map<v3s16, MapBlock*>::iterator
i = modified_blocks.begin();
@@ -1523,7 +1523,7 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks)
for (std::deque<v3s16>::iterator iter = must_reflow.begin(); iter != must_reflow.end(); ++iter)
m_transforming_liquid.push_back(*iter);

voxalgo::update_lighting_nodes(this, m_nodedef, changed_nodes, modified_blocks);
voxalgo::update_lighting_nodes(this, changed_nodes, modified_blocks);


/* ----------------------------------------------------------------------
@@ -1955,27 +1955,10 @@ void ServerMap::finishBlockMake(BlockMakeData *data,
v3s16 bpmax = data->blockpos_max;

v3s16 extra_borders(1, 1, 1);
v3s16 full_bpmin = bpmin - extra_borders;
v3s16 full_bpmax = bpmax + extra_borders;

bool enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
EMERGE_DBG_OUT("finishBlockMake(): " PP(bpmin) " - " PP(bpmax));

/*
Set lighting to non-expired state in all of them.
This is cheating, but it is not fast enough if all of them
would actually be updated.
*/
for (s16 x = full_bpmin.X; x <= full_bpmax.X; x++)
for (s16 z = full_bpmin.Z; z <= full_bpmax.Z; z++)
for (s16 y = full_bpmin.Y; y <= full_bpmax.Y; y++) {
MapBlock *block = emergeBlock(v3s16(x, y, z), false);
if (!block)
continue;

block->setLightingExpired(false);
}

/*
Blit generated stuff to map
NOTE: blitBackAll adds nearly everything to changed_blocks
@@ -2991,7 +2974,6 @@ void ServerMap::loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool

// We just loaded it from, so it's up-to-date.
block->resetModified();

}
catch(SerializationError &e)
{
@@ -3015,71 +2997,80 @@ MapBlock* ServerMap::loadBlock(v3s16 blockpos)
{
DSTACK(FUNCTION_NAME);

bool created_new = (getBlockNoCreateNoEx(blockpos) == NULL);

v2s16 p2d(blockpos.X, blockpos.Z);

std::string ret;
dbase->loadBlock(blockpos, &ret);
if (ret != "") {
loadBlock(&ret, blockpos, createSector(p2d), false);
return getBlockNoCreateNoEx(blockpos);
}
// Not found in database, try the files

// The directory layout we're going to load from.
// 1 - original sectors/xxxxzzzz/
// 2 - new sectors2/xxx/zzz/
// If we load from anything but the latest structure, we will
// immediately save to the new one, and remove the old.
int loadlayout = 1;
std::string sectordir1 = getSectorDir(p2d, 1);
std::string sectordir;
if(fs::PathExists(sectordir1))
{
sectordir = sectordir1;
}
else
{
loadlayout = 2;
sectordir = getSectorDir(p2d, 2);
}
} else {
// Not found in database, try the files

// The directory layout we're going to load from.
// 1 - original sectors/xxxxzzzz/
// 2 - new sectors2/xxx/zzz/
// If we load from anything but the latest structure, we will
// immediately save to the new one, and remove the old.
int loadlayout = 1;
std::string sectordir1 = getSectorDir(p2d, 1);
std::string sectordir;
if (fs::PathExists(sectordir1)) {
sectordir = sectordir1;
} else {
loadlayout = 2;
sectordir = getSectorDir(p2d, 2);
}

/*
/*
Make sure sector is loaded
*/
*/

MapSector *sector = getSectorNoGenerateNoEx(p2d);
if(sector == NULL)
{
try{
sector = loadSectorMeta(sectordir, loadlayout != 2);
}
catch(InvalidFilenameException &e)
{
return NULL;
}
catch(FileNotGoodException &e)
{
return NULL;
}
catch(std::exception &e)
{
return NULL;
MapSector *sector = getSectorNoGenerateNoEx(p2d);
if (sector == NULL) {
try {
sector = loadSectorMeta(sectordir, loadlayout != 2);
} catch(InvalidFilenameException &e) {
return NULL;
} catch(FileNotGoodException &e) {
return NULL;
} catch(std::exception &e) {
return NULL;
}
}
}

/*

/*
Make sure file exists
*/
*/

std::string blockfilename = getBlockFilename(blockpos);
if(fs::PathExists(sectordir + DIR_DELIM + blockfilename) == false)
return NULL;
std::string blockfilename = getBlockFilename(blockpos);
if (fs::PathExists(sectordir + DIR_DELIM + blockfilename) == false)
return NULL;

/*
/*
Load block and save it to the database
*/
loadBlock(sectordir, blockfilename, sector, true);
return getBlockNoCreateNoEx(blockpos);
*/
loadBlock(sectordir, blockfilename, sector, true);
}
MapBlock *block = getBlockNoCreateNoEx(blockpos);
if (created_new && (block != NULL)) {
std::map<v3s16, MapBlock*> modified_blocks;
// Fix lighting if necessary
voxalgo::update_block_border_lighting(this, block, modified_blocks);
if (!modified_blocks.empty()) {
//Modified lighting, send event
MapEditEvent event;
event.type = MEET_OTHER;
std::map<v3s16, MapBlock *>::iterator it;
for (it = modified_blocks.begin();
it != modified_blocks.end(); ++it)
event.modified_blocks.insert(it->first);
dispatchEvent(&event);
}
}
return block;
}

bool ServerMap::deleteBlock(v3s16 blockpos)
@@ -73,7 +73,7 @@ MapBlock::MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy):
m_modified(MOD_STATE_WRITE_NEEDED),
m_modified_reason(MOD_REASON_INITIAL),
is_underground(false),
m_lighting_expired(true),
m_lighting_complete(0xFFFF),
m_day_night_differs(false),
m_day_night_differs_expired(true),
m_generated(false),
@@ -571,11 +571,12 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk)
flags |= 0x01;
if(getDayNightDiff())
flags |= 0x02;
if(m_lighting_expired)
flags |= 0x04;
if(m_generated == false)
flags |= 0x08;
writeU8(os, flags);
if (version >= 27) {
writeU16(os, m_lighting_complete);
}

/*
Bulk node data
@@ -672,7 +673,11 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
u8 flags = readU8(is);
is_underground = (flags & 0x01) ? true : false;
m_day_night_differs = (flags & 0x02) ? true : false;
m_lighting_expired = (flags & 0x04) ? true : false;
if (version < 27) {
m_lighting_complete = 0xFFFF;
} else {
m_lighting_complete = readU16(is);
}
m_generated = (flags & 0x08) ? false : true;

/*
@@ -783,7 +788,7 @@ void MapBlock::deSerialize_pre22(std::istream &is, u8 version, bool disk)
// Initialize default flags
is_underground = false;
m_day_night_differs = false;
m_lighting_expired = false;
m_lighting_complete = 0xFFFF;
m_generated = true;

// Make a temporary buffer
@@ -849,7 +854,6 @@ void MapBlock::deSerialize_pre22(std::istream &is, u8 version, bool disk)
is.read((char*)&flags, 1);
is_underground = (flags & 0x01) ? true : false;
m_day_night_differs = (flags & 0x02) ? true : false;
m_lighting_expired = (flags & 0x04) ? true : false;
if(version >= 18)
m_generated = (flags & 0x08) ? false : true;

@@ -1027,10 +1031,7 @@ std::string analyze_block(MapBlock *block)
else
desc<<"is_ug [ ], ";

if(block->getLightingExpired())
desc<<"lighting_exp [X], ";
else
desc<<"lighting_exp [ ], ";
desc<<"lighting_complete: "<<block->getLightingComplete()<<", ";

if(block->isDummy())
{
@@ -105,7 +105,7 @@ class NodeContainer
#define MOD_REASON_INITIAL (1 << 0)
#define MOD_REASON_REALLOCATE (1 << 1)
#define MOD_REASON_SET_IS_UNDERGROUND (1 << 2)
#define MOD_REASON_SET_LIGHTING_EXPIRED (1 << 3)
#define MOD_REASON_SET_LIGHTING_COMPLETE (1 << 3)
#define MOD_REASON_SET_GENERATED (1 << 4)
#define MOD_REASON_SET_NODE (1 << 5)
#define MOD_REASON_SET_NODE_NO_CHECK (1 << 6)
@@ -213,17 +213,42 @@ class MapBlock /*: public NodeContainer*/
raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_SET_IS_UNDERGROUND);
}

inline void setLightingExpired(bool expired)
inline void setLightingComplete(u16 newflags)
{
if (expired != m_lighting_expired){
m_lighting_expired = expired;
raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_SET_LIGHTING_EXPIRED);
if (newflags != m_lighting_complete) {
m_lighting_complete = newflags;
raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_SET_LIGHTING_COMPLETE);
}
}

inline bool getLightingExpired()
inline u16 getLightingComplete()
{
return m_lighting_expired;
return m_lighting_complete;
}

inline void setLightingComplete(LightBank bank, u8 direction,
bool is_complete)
{
assert(direction >= 0 && direction <= 5);
if (bank == LIGHTBANK_NIGHT) {
direction += 6;
}
u16 newflags = m_lighting_complete;
if (is_complete) {
newflags |= 1 << direction;
} else {
newflags &= ~(1 << direction);
}
setLightingComplete(newflags);
}

inline bool isLightingComplete(LightBank bank, u8 direction)
{
assert(direction >= 0 && direction <= 5);
if (bank == LIGHTBANK_NIGHT) {
direction += 6;
}
return (m_lighting_complete & (1 << direction)) != 0;
}

inline bool isGenerated()
@@ -239,15 +264,6 @@ class MapBlock /*: public NodeContainer*/
}
}

inline bool isValid()
{
if (m_lighting_expired)
return false;
if (data == NULL)
return false;
return true;
}

////
//// Position stuff
////
@@ -613,14 +629,14 @@ class MapBlock /*: public NodeContainer*/
*/
bool is_underground;

/*
Set to true if changes has been made that make the old lighting
values wrong but the lighting hasn't been actually updated.
If this is false, lighting is exactly right.
If this is true, lighting might be wrong or right.
/*!
* Each bit indicates if light spreading was finished
* in a direction. (Because the neighbor could also be unloaded.)
* Bits: day X+, day Y+, day Z+, day Z-, day Y-, day X-,
* night X+, night Y+, night Z+, night Z-, night Y-, night X-,
* nothing, nothing, nothing, nothing.
*/
bool m_lighting_expired;
u16 m_lighting_complete;

// Whether day and night lighting differs
bool m_day_night_differs;
@@ -62,13 +62,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
24: 16-bit node ids and node timers (never released as stable)
25: Improved node timer format
26: Never written; read the same as 25
27: Added light spreading flags to blocks
*/
// This represents an uninitialized or invalid format
#define SER_FMT_VER_INVALID 255
// Highest supported serialization version
#define SER_FMT_VER_HIGHEST_READ 26
#define SER_FMT_VER_HIGHEST_READ 27
// Saved on disk version
#define SER_FMT_VER_HIGHEST_WRITE 25
#define SER_FMT_VER_HIGHEST_WRITE 27
// Lowest supported serialization version
#define SER_FMT_VER_LOWEST_READ 0
// Lowest serialization version for writing

0 comments on commit f17c9c4

Please sign in to comment.
You can’t perform that action at this time.