aboutsummaryrefslogtreecommitdiff
path: root/src/voxelalgorithms.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/voxelalgorithms.cpp')
-rw-r--r--src/voxelalgorithms.cpp229
1 files changed, 119 insertions, 110 deletions
diff --git a/src/voxelalgorithms.cpp b/src/voxelalgorithms.cpp
index 019ec1bc6..83c1dd4ca 100644
--- a/src/voxelalgorithms.cpp
+++ b/src/voxelalgorithms.cpp
@@ -583,144 +583,153 @@ bool isSunlightAbove(Map *map, v3s16 pos, INodeDefManager *ndef)
static const LightBank banks[] = { LIGHTBANK_DAY, LIGHTBANK_NIGHT };
-void update_lighting_node(Map *map, INodeDefManager *ndef, v3s16 p,
- MapNode oldnode, std::map<v3s16, MapBlock*> & modified_blocks)
+void update_lighting_nodes(Map *map, INodeDefManager *ndef,
+ std::vector<std::pair<v3s16, MapNode> > &oldnodes,
+ std::map<v3s16, MapBlock*> & modified_blocks)
{
// For node getter functions
bool is_valid_position;
- // Get position and block of the changed node
- relative_v3 rel_pos;
- mapblock_v3 block_pos;
- getNodeBlockPosWithOffset(p, block_pos, rel_pos);
- MapBlock *block = map->getBlockNoCreateNoEx(block_pos);
- if (block == NULL || block->isDummy()) {
- return;
- }
-
// Process each light bank separately
for (s32 i = 0; i < 2; i++) {
- // Get the new node
- MapNode n = block->getNodeNoCheck(rel_pos, &is_valid_position);
- if (!is_valid_position) {
- break;
- }
LightBank bank = banks[i];
+ UnlightQueue disappearing_lights(256);
+ ReLightQueue light_sources(256);
+ // For each changed node process sunlight and initialize
+ for (std::vector<std::pair<v3s16, MapNode> >::iterator it =
+ oldnodes.begin(); it < oldnodes.end(); it++) {
+ // Get position and block of the changed node
+ v3s16 p = it->first;
+ relative_v3 rel_pos;
+ mapblock_v3 block_pos;
+ getNodeBlockPosWithOffset(p, block_pos, rel_pos);
+ MapBlock *block = map->getBlockNoCreateNoEx(block_pos);
+ if (block == NULL || block->isDummy()) {
+ continue;
+ }
+ // Get the new node
+ MapNode n = block->getNodeNoCheck(rel_pos, &is_valid_position);
+ if (!is_valid_position) {
+ break;
+ }
- // Light of the old node
- u8 old_light = oldnode.getLight(bank, ndef);
+ // Light of the old node
+ u8 old_light = it->second.getLight(bank, ndef);
- // Add the block of the added node to modified_blocks
- modified_blocks[block_pos] = block;
+ // Add the block of the added node to modified_blocks
+ modified_blocks[block_pos] = block;
- // Get new light level of the node
- u8 new_light = 0;
- if (ndef->get(n).light_propagates) {
- if (bank == LIGHTBANK_DAY && ndef->get(n).sunlight_propagates
+ // Get new light level of the node
+ u8 new_light = 0;
+ if (ndef->get(n).light_propagates) {
+ if (bank == LIGHTBANK_DAY && ndef->get(n).sunlight_propagates
&& isSunlightAbove(map, p, ndef)) {
- new_light = LIGHT_SUN;
- } else {
- new_light = ndef->get(n).light_source;
- for (int i = 0; i < 6; i++) {
- v3s16 p2 = p + neighbor_dirs[i];
- bool is_valid;
- MapNode n2 = map->getNodeNoEx(p2, &is_valid);
- if (is_valid) {
- u8 spread = n2.getLight(bank, ndef);
- // If the neighbor is at least as bright as
- // this node then its light is not from
- // this node.
- // Its light can spread to this node.
- if (spread > new_light && spread >= old_light) {
- new_light = spread - 1;
+ new_light = LIGHT_SUN;
+ } else {
+ new_light = ndef->get(n).light_source;
+ for (int i = 0; i < 6; i++) {
+ v3s16 p2 = p + neighbor_dirs[i];
+ bool is_valid;
+ MapNode n2 = map->getNodeNoEx(p2, &is_valid);
+ if (is_valid) {
+ u8 spread = n2.getLight(bank, ndef);
+ // If the neighbor is at least as bright as
+ // this node then its light is not from
+ // this node.
+ // Its light can spread to this node.
+ if (spread > new_light && spread >= old_light) {
+ new_light = spread - 1;
+ }
}
}
}
+ } else {
+ // If this is an opaque node, it still can emit light.
+ new_light = ndef->get(n).light_source;
}
- } else {
- // If this is an opaque node, it still can emit light.
- new_light = ndef->get(n).light_source;
- }
-
- ReLightQueue light_sources(256);
- if (new_light > 0) {
- light_sources.push(new_light, rel_pos, block_pos, block, 6);
- }
+ if (new_light > 0) {
+ light_sources.push(new_light, rel_pos, block_pos, block, 6);
+ }
- if (new_light < old_light) {
- // The node became opaque or doesn't provide as much
- // light as the previous one, so it must be unlighted.
- LightQueue disappearing_lights(256);
+ if (new_light < old_light) {
+ // The node became opaque or doesn't provide as much
+ // light as the previous one, so it must be unlighted.
- // Add to unlight queue
- n.setLight(bank, 0, ndef);
- block->setNodeNoCheck(rel_pos, n);
- disappearing_lights.push(old_light, rel_pos, block_pos, block, 6);
+ // Add to unlight queue
+ n.setLight(bank, 0, ndef);
+ block->setNodeNoCheck(rel_pos, n);
+ disappearing_lights.push(old_light, rel_pos, block_pos, block,
+ 6);
- // Remove sunlight, if there was any
- if (bank == LIGHTBANK_DAY && old_light == LIGHT_SUN) {
- for (s16 y = p.Y - 1;; y--) {
- v3s16 n2pos(p.X, y, p.Z);
+ // Remove sunlight, if there was any
+ if (bank == LIGHTBANK_DAY && old_light == LIGHT_SUN) {
+ for (s16 y = p.Y - 1;; y--) {
+ v3s16 n2pos(p.X, y, p.Z);
- MapNode n2;
+ MapNode n2;
- n2 = map->getNodeNoEx(n2pos, &is_valid_position);
- if (!is_valid_position)
- break;
+ n2 = map->getNodeNoEx(n2pos, &is_valid_position);
+ if (!is_valid_position)
+ break;
- // If this node doesn't have sunlight, the nodes below
- // it don't have too.
- if (n2.getLight(LIGHTBANK_DAY, ndef) != LIGHT_SUN) {
- break;
+ // If this node doesn't have sunlight, the nodes below
+ // it don't have too.
+ if (n2.getLight(LIGHTBANK_DAY, ndef) != LIGHT_SUN) {
+ break;
+ }
+ // Remove sunlight and add to unlight queue.
+ n2.setLight(LIGHTBANK_DAY, 0, ndef);
+ map->setNode(n2pos, n2);
+ relative_v3 rel_pos2;
+ mapblock_v3 block_pos2;
+ getNodeBlockPosWithOffset(n2pos, block_pos2, rel_pos2);
+ MapBlock *block2 = map->getBlockNoCreateNoEx(
+ block_pos2);
+ disappearing_lights.push(LIGHT_SUN, rel_pos2,
+ block_pos2, block2,
+ 4 /* The node above caused the change */);
}
- // Remove sunlight and add to unlight queue.
- n2.setLight(LIGHTBANK_DAY, 0, ndef);
- map->setNode(n2pos, n2);
- relative_v3 rel_pos2;
- mapblock_v3 block_pos2;
- getNodeBlockPosWithOffset(n2pos, block_pos2, rel_pos2);
- MapBlock *block2 = map->getBlockNoCreateNoEx(block_pos2);
- disappearing_lights.push(LIGHT_SUN, rel_pos2, block_pos2,
- block2, 4 /* The node above caused the change */);
}
- }
- // Remove lights
- unspreadLight(map, ndef, bank, disappearing_lights, light_sources,
- modified_blocks);
- } else if (new_light > old_light) {
- // It is sure that the node provides more light than the previous
- // one, unlighting is not necessary.
- // Propagate sunlight
- if (bank == LIGHTBANK_DAY && new_light == LIGHT_SUN) {
- for (s16 y = p.Y - 1;; y--) {
- v3s16 n2pos(p.X, y, p.Z);
-
- MapNode n2;
-
- n2 = map->getNodeNoEx(n2pos, &is_valid_position);
- if (!is_valid_position)
- break;
-
- // This should not happen, but if the node has sunlight
- // then the iteration should stop.
- if (n2.getLight(LIGHTBANK_DAY, ndef) == LIGHT_SUN) {
- break;
- }
- // If the node terminates sunlight, stop.
- if (!ndef->get(n2).sunlight_propagates) {
- break;
+ } else if (new_light > old_light) {
+ // It is sure that the node provides more light than the previous
+ // one, unlighting is not necessary.
+ // Propagate sunlight
+ if (bank == LIGHTBANK_DAY && new_light == LIGHT_SUN) {
+ for (s16 y = p.Y - 1;; y--) {
+ v3s16 n2pos(p.X, y, p.Z);
+
+ MapNode n2;
+
+ n2 = map->getNodeNoEx(n2pos, &is_valid_position);
+ if (!is_valid_position)
+ break;
+
+ // This should not happen, but if the node has sunlight
+ // then the iteration should stop.
+ if (n2.getLight(LIGHTBANK_DAY, ndef) == LIGHT_SUN) {
+ break;
+ }
+ // If the node terminates sunlight, stop.
+ if (!ndef->get(n2).sunlight_propagates) {
+ break;
+ }
+ relative_v3 rel_pos2;
+ mapblock_v3 block_pos2;
+ getNodeBlockPosWithOffset(n2pos, block_pos2, rel_pos2);
+ MapBlock *block2 = map->getBlockNoCreateNoEx(
+ block_pos2);
+ // Mark node for lighting.
+ light_sources.push(LIGHT_SUN, rel_pos2, block_pos2,
+ block2, 4);
}
- relative_v3 rel_pos2;
- mapblock_v3 block_pos2;
- getNodeBlockPosWithOffset(n2pos, block_pos2, rel_pos2);
- MapBlock *block2 = map->getBlockNoCreateNoEx(block_pos2);
- // Mark node for lighting.
- light_sources.push(LIGHT_SUN, rel_pos2, block_pos2, block2,
- 4);
}
}
+
}
+ // Remove lights
+ unspreadLight(map, ndef, bank, disappearing_lights, light_sources,
+ modified_blocks);
// Initialize light values for light spreading.
for (u8 i = 0; i <= LIGHT_SUN; i++) {
const std::vector<ChangingLight> &lights = light_sources.lights[i];