diff options
Diffstat (limited to 'src/voxelalgorithms.cpp')
-rw-r--r-- | src/voxelalgorithms.cpp | 847 |
1 files changed, 372 insertions, 475 deletions
diff --git a/src/voxelalgorithms.cpp b/src/voxelalgorithms.cpp index a773c90fd..62fd68890 100644 --- a/src/voxelalgorithms.cpp +++ b/src/voxelalgorithms.cpp @@ -50,8 +50,7 @@ typedef v3s16 relative_v3; typedef v3s16 mapblock_v3; //! Contains information about a node whose light is about to change. -struct ChangingLight -{ +struct ChangingLight { //! Relative position of the node in its map block. relative_v3 rel_position; //! Position of the node's block. @@ -67,11 +66,12 @@ struct ChangingLight ChangingLight() = default; ChangingLight(const relative_v3 &rel_pos, const mapblock_v3 &block_pos, - MapBlock *b, direction source_dir) : - rel_position(rel_pos), - block_position(block_pos), block(b), source_direction(source_dir) - { - } + MapBlock *b, direction source_dir) : + rel_position(rel_pos), + block_position(block_pos), + block(b), + source_direction(source_dir) + {} }; /*! @@ -79,8 +79,7 @@ struct ChangingLight * The ChangingLights are ordered by the given light levels. * The brightest ChangingLight is returned first. */ -struct LightQueue -{ +struct LightQueue { //! For each light level there is a vector. std::vector<ChangingLight> lights[LIGHT_SUN + 1]; //! Light of the brightest ChangingLight in the queue. @@ -127,8 +126,8 @@ struct LightQueue * \param light light level of the ChangingLight */ inline void push(u8 light, const relative_v3 &rel_pos, - const mapblock_v3 &block_pos, MapBlock *block, - direction source_dir) + const mapblock_v3 &block_pos, MapBlock *block, + direction source_dir) { assert(light <= LIGHT_SUN); lights[light].emplace_back(rel_pos, block_pos, block, source_dir); @@ -160,12 +159,12 @@ typedef LightQueue ReLightQueue; * See the definition of the type "direction" */ const static v3s16 neighbor_dirs[6] = { - v3s16(1, 0, 0), // right - v3s16(0, 1, 0), // top - v3s16(0, 0, 1), // back - v3s16(0, 0, -1), // front - v3s16(0, -1, 0), // bottom - v3s16(-1, 0, 0), // left + v3s16(1, 0, 0), // right + v3s16(0, 1, 0), // top + v3s16(0, 0, 1), // back + v3s16(0, 0, -1), // front + v3s16(0, -1, 0), // bottom + v3s16(-1, 0, 0), // left }; /*! @@ -175,7 +174,8 @@ const static v3s16 neighbor_dirs[6] = { * \param rel_pos the node's relative position in its map block * \param block_pos position of the node's block */ -bool step_rel_block_pos(direction dir, relative_v3 &rel_pos, mapblock_v3 &block_pos) +bool step_rel_block_pos(direction dir, relative_v3 &rel_pos, + mapblock_v3 &block_pos) { switch (dir) { case 0: @@ -247,8 +247,8 @@ bool step_rel_block_pos(direction dir, relative_v3 &rel_pos, mapblock_v3 &block_ * \param modified_blocks output, all modified map blocks are added to this */ void unspread_light(Map *map, const NodeDefManager *nodemgr, LightBank bank, - UnlightQueue &from_nodes, ReLightQueue &light_sources, - std::map<v3s16, MapBlock *> &modified_blocks) + UnlightQueue &from_nodes, ReLightQueue &light_sources, + std::map<v3s16, MapBlock*> &modified_blocks) { // Stores data popped from from_nodes u8 current_light; @@ -267,13 +267,13 @@ void unspread_light(Map *map, const NodeDefManager *nodemgr, LightBank bank, source_dir = 6; // The current node const MapNode &node = current.block->getNodeNoCheck( - current.rel_position, &is_valid_position); + current.rel_position, &is_valid_position); const ContentFeatures &f = nodemgr->get(node); // If the node emits light, it behaves like it had a // brighter neighbor. u8 brightest_neighbor_light = f.light_source + 1; for (direction i = 0; i < 6; i++) { - // For each neighbor + //For each neighbor // The node that changed this node has already zero light // and it can't give light to this node @@ -285,40 +285,34 @@ void unspread_light(Map *map, const NodeDefManager *nodemgr, LightBank bank, neighbor_block_pos = current.block_position; MapBlock *neighbor_block; if (step_rel_block_pos(i, neighbor_rel_pos, neighbor_block_pos)) { - neighbor_block = map->getBlockNoCreateNoEx( - neighbor_block_pos); + neighbor_block = map->getBlockNoCreateNoEx(neighbor_block_pos); if (neighbor_block == NULL) { - current.block->setLightingComplete( - bank, i, false); + current.block->setLightingComplete(bank, i, false); continue; } } else { neighbor_block = current.block; } // Get the neighbor itself - MapNode neighbor = neighbor_block->getNodeNoCheck( - neighbor_rel_pos, &is_valid_position); - const ContentFeatures &neighbor_f = - nodemgr->get(neighbor.getContent()); + MapNode neighbor = neighbor_block->getNodeNoCheck(neighbor_rel_pos, + &is_valid_position); + const ContentFeatures &neighbor_f = nodemgr->get( + neighbor.getContent()); u8 neighbor_light = neighbor.getLightRaw(bank, neighbor_f); // If the neighbor has at least as much light as this node, then // it won't lose its light, since it should have been added to // from_nodes earlier, so its light would be zero. - if (neighbor_f.light_propagates && - neighbor_light < current_light) { + if (neighbor_f.light_propagates && neighbor_light < current_light) { // Unlight, but only if the node has light. if (neighbor_light > 0) { neighbor.setLight(bank, 0, neighbor_f); - neighbor_block->setNodeNoCheck( - neighbor_rel_pos, neighbor); + neighbor_block->setNodeNoCheck(neighbor_rel_pos, neighbor); from_nodes.push(neighbor_light, neighbor_rel_pos, - neighbor_block_pos, - neighbor_block, i); - // The current node was modified earlier, so its - // block is in modified_blocks. + neighbor_block_pos, neighbor_block, i); + // The current node was modified earlier, so its block + // is in modified_blocks. if (current.block != neighbor_block) { - modified_blocks[neighbor_block_pos] = - neighbor_block; + modified_blocks[neighbor_block_pos] = neighbor_block; } } } else { @@ -337,9 +331,9 @@ void unspread_light(Map *map, const NodeDefManager *nodemgr, LightBank bank, if (brightest_neighbor_light > 1 && f.light_propagates) { brightest_neighbor_light--; light_sources.push(brightest_neighbor_light, current.rel_position, - current.block_position, current.block, - (source_dir == 6) ? 6 : 5 - source_dir - /* with opposite direction*/); + current.block_position, current.block, + (source_dir == 6) ? 6 : 5 - source_dir + /* with opposite direction*/); } } } @@ -357,7 +351,8 @@ void unspread_light(Map *map, const NodeDefManager *nodemgr, LightBank bank, * \param modified_blocks output, all modified map blocks are added to this */ void spread_light(Map *map, const NodeDefManager *nodemgr, LightBank bank, - LightQueue &light_sources, std::map<v3s16, MapBlock *> &modified_blocks) + LightQueue &light_sources, + std::map<v3s16, MapBlock*> &modified_blocks) { // The light the current node can provide to its neighbors. u8 spreading_light; @@ -380,37 +375,30 @@ void spread_light(Map *map, const NodeDefManager *nodemgr, LightBank bank, neighbor_block_pos = current.block_position; MapBlock *neighbor_block; if (step_rel_block_pos(i, neighbor_rel_pos, neighbor_block_pos)) { - neighbor_block = map->getBlockNoCreateNoEx( - neighbor_block_pos); + neighbor_block = map->getBlockNoCreateNoEx(neighbor_block_pos); if (neighbor_block == NULL) { - current.block->setLightingComplete( - bank, i, false); + current.block->setLightingComplete(bank, i, false); continue; } } else { neighbor_block = current.block; } // Get the neighbor itself - MapNode neighbor = neighbor_block->getNodeNoCheck( - neighbor_rel_pos, &is_valid_position); + MapNode neighbor = neighbor_block->getNodeNoCheck(neighbor_rel_pos, + &is_valid_position); const ContentFeatures &f = nodemgr->get(neighbor.getContent()); if (f.light_propagates) { - // Light up the neighbor, if it has less light than it - // should. + // Light up the neighbor, if it has less light than it should. u8 neighbor_light = neighbor.getLightRaw(bank, f); if (neighbor_light < spreading_light) { neighbor.setLight(bank, spreading_light, f); - neighbor_block->setNodeNoCheck( - neighbor_rel_pos, neighbor); - light_sources.push(spreading_light, - neighbor_rel_pos, - neighbor_block_pos, - neighbor_block, i); - // The current node was modified earlier, so its - // block is in modified_blocks. + neighbor_block->setNodeNoCheck(neighbor_rel_pos, neighbor); + light_sources.push(spreading_light, neighbor_rel_pos, + neighbor_block_pos, neighbor_block, i); + // The current node was modified earlier, so its block + // is in modified_blocks. if (current.block != neighbor_block) { - modified_blocks[neighbor_block_pos] = - neighbor_block; + modified_blocks[neighbor_block_pos] = neighbor_block; } } } @@ -418,19 +406,17 @@ void spread_light(Map *map, const NodeDefManager *nodemgr, LightBank bank, } } -struct SunlightPropagationUnit -{ +struct SunlightPropagationUnit{ v2s16 relative_pos; bool is_sunlit; - SunlightPropagationUnit(v2s16 relpos, bool sunlit) : - relative_pos(relpos), is_sunlit(sunlit) - { - } + SunlightPropagationUnit(v2s16 relpos, bool sunlit): + relative_pos(relpos), + is_sunlit(sunlit) + {} }; -struct SunlightPropagationData -{ +struct SunlightPropagationData{ std::vector<SunlightPropagationUnit> data; v3s16 target_block; }; @@ -446,7 +432,8 @@ bool is_sunlight_above(Map *map, v3s16 pos, const NodeDefManager *ndef) bool sunlight = true; mapblock_v3 source_block_pos; relative_v3 source_rel_pos; - getNodeBlockPosWithOffset(pos + v3s16(0, 1, 0), source_block_pos, source_rel_pos); + getNodeBlockPosWithOffset(pos + v3s16(0, 1, 0), source_block_pos, + source_rel_pos); // If the node above has sunlight, this node also can get it. MapBlock *source_block = map->getBlockNoCreateNoEx(source_block_pos); if (source_block == NULL) { @@ -459,8 +446,8 @@ bool is_sunlight_above(Map *map, v3s16 pos, const NodeDefManager *ndef) } } else { bool is_valid_position; - MapNode above = source_block->getNodeNoCheck( - source_rel_pos, &is_valid_position); + MapNode above = source_block->getNodeNoCheck(source_rel_pos, + &is_valid_position); if (is_valid_position) { if (above.getContent() == CONTENT_IGNORE) { // Trust heuristics @@ -477,10 +464,11 @@ bool is_sunlight_above(Map *map, v3s16 pos, const NodeDefManager *ndef) return sunlight; } -static const LightBank banks[] = {LIGHTBANK_DAY, LIGHTBANK_NIGHT}; +static const LightBank banks[] = { LIGHTBANK_DAY, LIGHTBANK_NIGHT }; -void update_lighting_nodes(Map *map, std::vector<std::pair<v3s16, MapNode>> &oldnodes, - std::map<v3s16, MapBlock *> &modified_blocks) +void update_lighting_nodes(Map *map, + std::vector<std::pair<v3s16, MapNode> > &oldnodes, + std::map<v3s16, MapBlock*> &modified_blocks) { const NodeDefManager *ndef = map->getNodeDefManager(); // For node getter functions @@ -494,9 +482,8 @@ void update_lighting_nodes(Map *map, std::vector<std::pair<v3s16, MapNode>> &old // won't change, since they didn't get their light from a // modified node. u8 min_safe_light = 0; - for (std::vector<std::pair<v3s16, MapNode>>::iterator it = - oldnodes.begin(); - it < oldnodes.end(); ++it) { + for (std::vector<std::pair<v3s16, MapNode> >::iterator it = + oldnodes.begin(); it < oldnodes.end(); ++it) { u8 old_light = it->second.getLight(bank, ndef); if (old_light > min_safe_light) { min_safe_light = old_light; @@ -508,9 +495,8 @@ void update_lighting_nodes(Map *map, std::vector<std::pair<v3s16, MapNode>> &old min_safe_light++; } // For each changed node process sunlight and initialize - for (std::vector<std::pair<v3s16, MapNode>>::iterator it = - oldnodes.begin(); - it < oldnodes.end(); ++it) { + 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; @@ -535,9 +521,8 @@ void update_lighting_nodes(Map *map, std::vector<std::pair<v3s16, MapNode>> &old // 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 && - is_sunlight_above(map, p, ndef)) { + if (bank == LIGHTBANK_DAY && ndef->get(n).sunlight_propagates + && is_sunlight_above(map, p, ndef)) { new_light = LIGHT_SUN; } else { new_light = ndef->get(n).light_source; @@ -546,13 +531,10 @@ void update_lighting_nodes(Map *map, std::vector<std::pair<v3s16, MapNode>> &old bool is_valid; MapNode n2 = map->getNode(p2, &is_valid); if (is_valid) { - u8 spread = n2.getLight( - bank, ndef); - // If it is sure that the neighbor - // won't be unlighted, its light - // can spread to this node. - if (spread > new_light && - spread >= min_safe_light) { + u8 spread = n2.getLight(bank, ndef); + // If it is sure that the neighbor won't be + // unlighted, its light can spread to this node. + if (spread > new_light && spread >= min_safe_light) { new_light = spread - 1; } } @@ -564,8 +546,7 @@ void update_lighting_nodes(Map *map, std::vector<std::pair<v3s16, MapNode>> &old } if (new_light > 0) { - light_sources.push( - new_light, rel_pos, block_pos, block, 6); + light_sources.push(new_light, rel_pos, block_pos, block, 6); } if (new_light < old_light) { @@ -575,8 +556,8 @@ void update_lighting_nodes(Map *map, std::vector<std::pair<v3s16, MapNode>> &old // 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); + 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) { @@ -585,54 +566,45 @@ void update_lighting_nodes(Map *map, std::vector<std::pair<v3s16, MapNode>> &old MapNode n2; - n2 = map->getNode(n2pos, - &is_valid_position); + n2 = map->getNode(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) { + // 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. + // 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 */); + 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 */); } } } 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 + // 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->getNode(n2pos, - &is_valid_position); + n2 = map->getNode(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) { + // 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. @@ -641,30 +613,27 @@ void update_lighting_nodes(Map *map, std::vector<std::pair<v3s16, MapNode>> &old } relative_v3 rel_pos2; mapblock_v3 block_pos2; - getNodeBlockPosWithOffset(n2pos, - block_pos2, rel_pos2); - MapBlock *block2 = - map->getBlockNoCreateNoEx( - 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); + light_sources.push(LIGHT_SUN, rel_pos2, block_pos2, + block2, 4); } } } + } // Remove lights unspread_light(map, ndef, bank, disappearing_lights, light_sources, - modified_blocks); + 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]; - for (std::vector<ChangingLight>::const_iterator it = - lights.begin(); + const std::vector<ChangingLight> &lights = light_sources.lights[i]; + for (std::vector<ChangingLight>::const_iterator it = lights.begin(); it < lights.end(); ++it) { - MapNode n = it->block->getNodeNoCheck( - it->rel_position, &is_valid_position); + MapNode n = it->block->getNodeNoCheck(it->rel_position, + &is_valid_position); n.setLight(bank, i, ndef); it->block->setNodeNoCheck(it->rel_position, n); } @@ -679,12 +648,12 @@ void update_lighting_nodes(Map *map, std::vector<std::pair<v3s16, MapNode>> &old * Compatible with type 'direction'. */ const VoxelArea block_borders[] = { - VoxelArea(v3s16(15, 0, 0), v3s16(15, 15, 15)), // X+ - VoxelArea(v3s16(0, 15, 0), v3s16(15, 15, 15)), // Y+ - VoxelArea(v3s16(0, 0, 15), v3s16(15, 15, 15)), // Z+ - VoxelArea(v3s16(0, 0, 0), v3s16(15, 15, 0)), // Z- - VoxelArea(v3s16(0, 0, 0), v3s16(15, 0, 15)), // Y- - VoxelArea(v3s16(0, 0, 0), v3s16(0, 15, 15)) // X- + VoxelArea(v3s16(15, 0, 0), v3s16(15, 15, 15)), //X+ + VoxelArea(v3s16(0, 15, 0), v3s16(15, 15, 15)), //Y+ + VoxelArea(v3s16(0, 0, 15), v3s16(15, 15, 15)), //Z+ + VoxelArea(v3s16(0, 0, 0), v3s16(15, 15, 0)), //Z- + VoxelArea(v3s16(0, 0, 0), v3s16(15, 0, 15)), //Y- + VoxelArea(v3s16(0, 0, 0), v3s16(0, 15, 15)) //X- }; /*! @@ -695,8 +664,8 @@ const VoxelArea block_borders[] = { * its light source and its brightest neighbor minus one. * . */ -bool is_light_locally_correct( - Map *map, const NodeDefManager *ndef, LightBank bank, v3s16 pos) +bool is_light_locally_correct(Map *map, const NodeDefManager *ndef, + LightBank bank, v3s16 pos) { bool is_valid_position; MapNode n = map->getNode(pos, &is_valid_position); @@ -708,7 +677,8 @@ bool is_light_locally_correct( assert(f.light_source <= LIGHT_MAX); u8 brightest_neighbor = f.light_source + 1; for (const v3s16 &neighbor_dir : neighbor_dirs) { - MapNode n2 = map->getNode(pos + neighbor_dir, &is_valid_position); + MapNode n2 = map->getNode(pos + neighbor_dir, + &is_valid_position); u8 light2 = n2.getLight(bank, ndef); if (brightest_neighbor < light2) { brightest_neighbor = light2; @@ -718,8 +688,8 @@ bool is_light_locally_correct( return brightest_neighbor == light + 1; } -void update_block_border_lighting( - Map *map, MapBlock *block, std::map<v3s16, MapBlock *> &modified_blocks) +void update_block_border_lighting(Map *map, MapBlock *block, + std::map<v3s16, MapBlock*> &modified_blocks) { const NodeDefManager *ndef = map->getNodeDefManager(); bool is_valid_position; @@ -753,56 +723,38 @@ void update_block_border_lighting( VoxelArea a = areas[blocknum]; // For all nodes for (s32 x = a.MinEdge.X; x <= a.MaxEdge.X; x++) - for (s32 z = a.MinEdge.Z; z <= a.MaxEdge.Z; z++) - for (s32 y = a.MinEdge.Y; - y <= a.MaxEdge.Y; y++) { - MapNode n = b->getNodeNoCheck(x, - y, z, - &is_valid_position); - u8 light = n.getLight(bank, ndef); - // Sunlight is fixed - if (light < LIGHT_SUN) { - // Unlight if not correct - if (!is_light_locally_correct( - map, - ndef, - bank, - v3s16(x, y, z) + - b->getPosRelative())) { - // Initialize for - // unlighting - n.setLight(bank, - 0, - ndef); - b->setNodeNoCheck( - x, - y, - z, - n); - modified_blocks[b->getPos()] = - b; - disappearing_lights - .push(light, relative_v3(x, y, z), - b->getPos(), - b, - 6); - } - } + for (s32 z = a.MinEdge.Z; z <= a.MaxEdge.Z; z++) + for (s32 y = a.MinEdge.Y; y <= a.MaxEdge.Y; y++) { + MapNode n = b->getNodeNoCheck(x, y, z, + &is_valid_position); + u8 light = n.getLight(bank, ndef); + // Sunlight is fixed + if (light < LIGHT_SUN) { + // Unlight if not correct + if (!is_light_locally_correct(map, ndef, bank, + v3s16(x, y, z) + b->getPosRelative())) { + // Initialize for unlighting + n.setLight(bank, 0, ndef); + b->setNodeNoCheck(x, y, z, n); + modified_blocks[b->getPos()]=b; + disappearing_lights.push(light, + relative_v3(x, y, z), b->getPos(), b, + 6); } + } + } } } // Remove lights unspread_light(map, ndef, bank, disappearing_lights, light_sources, - modified_blocks); + 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]; - for (std::vector<ChangingLight>::const_iterator it = - lights.begin(); + const std::vector<ChangingLight> &lights = light_sources.lights[i]; + for (std::vector<ChangingLight>::const_iterator it = lights.begin(); it < lights.end(); ++it) { - MapNode n = it->block->getNodeNoCheck( - it->rel_position, &is_valid_position); + MapNode n = it->block->getNodeNoCheck(it->rel_position, + &is_valid_position); n.setLight(bank, i, ndef); it->block->setNodeNoCheck(it->rel_position, n); } @@ -826,7 +778,7 @@ void update_block_border_lighting( * the bottom of the voxel manipulator. */ void fill_with_sunlight(MMVManip *vm, const NodeDefManager *ndef, v2s16 offset, - bool light[MAP_BLOCKSIZE][MAP_BLOCKSIZE]) + bool light[MAP_BLOCKSIZE][MAP_BLOCKSIZE]) { // Distance in array between two nodes on top of each other. s16 ystride = vm->m_area.getExtent().X; @@ -834,37 +786,37 @@ void fill_with_sunlight(MMVManip *vm, const NodeDefManager *ndef, v2s16 offset, MapNode ignore = MapNode(CONTENT_IGNORE); // For each column of nodes: for (s16 z = 0; z < MAP_BLOCKSIZE; z++) - for (s16 x = 0; x < MAP_BLOCKSIZE; x++) { - // Position of the column on the map. - v2s16 realpos = offset + v2s16(x, z); - // Array indices in the voxel manipulator - s32 maxindex = vm->m_area.index( - realpos.X, vm->m_area.MaxEdge.Y, realpos.Y); - s32 minindex = vm->m_area.index( - realpos.X, vm->m_area.MinEdge.Y, realpos.Y); - // True if the current node has sunlight. - bool lig = light[z][x]; - // For each node, downwards: - for (s32 i = maxindex; i >= minindex; i -= ystride) { - MapNode *n; - if (vm->m_flags[i] & VOXELFLAG_NO_DATA) - n = &ignore; - else - n = &vm->m_data[i]; - // Ignore IGNORE nodes, these are not generated yet. - if (n->getContent() == CONTENT_IGNORE) - continue; - const ContentFeatures &f = ndef->get(n->getContent()); - if (lig && !f.sunlight_propagates) - // Sunlight is stopped. - lig = false; - // Reset light - n->setLight(LIGHTBANK_DAY, lig ? 15 : 0, f); - n->setLight(LIGHTBANK_NIGHT, 0, f); - } - // Output outgoing light. - light[z][x] = lig; + for (s16 x = 0; x < MAP_BLOCKSIZE; x++) { + // Position of the column on the map. + v2s16 realpos = offset + v2s16(x, z); + // Array indices in the voxel manipulator + s32 maxindex = vm->m_area.index(realpos.X, vm->m_area.MaxEdge.Y, + realpos.Y); + s32 minindex = vm->m_area.index(realpos.X, vm->m_area.MinEdge.Y, + realpos.Y); + // True if the current node has sunlight. + bool lig = light[z][x]; + // For each node, downwards: + for (s32 i = maxindex; i >= minindex; i -= ystride) { + MapNode *n; + if (vm->m_flags[i] & VOXELFLAG_NO_DATA) + n = &ignore; + else + n = &vm->m_data[i]; + // Ignore IGNORE nodes, these are not generated yet. + if(n->getContent() == CONTENT_IGNORE) + continue; + const ContentFeatures &f = ndef->get(n->getContent()); + if (lig && !f.sunlight_propagates) + // Sunlight is stopped. + lig = false; + // Reset light + n->setLight(LIGHTBANK_DAY, lig ? 15 : 0, f); + n->setLight(LIGHTBANK_NIGHT, 0, f); } + // Output outgoing light. + light[z][x] = lig; + } } /*! @@ -876,8 +828,8 @@ void fill_with_sunlight(MMVManip *vm, const NodeDefManager *ndef, v2s16 offset, * is sunlight above the block at the given z-x relative * node coordinates. */ -void is_sunlight_above_block(ServerMap *map, mapblock_v3 pos, const NodeDefManager *ndef, - bool light[MAP_BLOCKSIZE][MAP_BLOCKSIZE]) +void is_sunlight_above_block(ServerMap *map, mapblock_v3 pos, + const NodeDefManager *ndef, bool light[MAP_BLOCKSIZE][MAP_BLOCKSIZE]) { mapblock_v3 source_block_pos = pos + v3s16(0, 1, 0); // Get or load source block. @@ -885,8 +837,8 @@ void is_sunlight_above_block(ServerMap *map, mapblock_v3 pos, const NodeDefManag // sunlight may be even slower. MapBlock *source_block = map->emergeBlock(source_block_pos, false); // Trust only generated blocks. - if (source_block == NULL || source_block->isDummy() || - !source_block->isGenerated()) { + if (source_block == NULL || source_block->isDummy() + || !source_block->isGenerated()) { // But if there is no block above, then use heuristics bool sunlight = true; MapBlock *node_block = map->getBlockNoCreateNoEx(pos); @@ -896,20 +848,19 @@ void is_sunlight_above_block(ServerMap *map, mapblock_v3 pos, const NodeDefManag else sunlight = !node_block->getIsUnderground(); for (s16 z = 0; z < MAP_BLOCKSIZE; z++) - for (s16 x = 0; x < MAP_BLOCKSIZE; x++) - light[z][x] = sunlight; + for (s16 x = 0; x < MAP_BLOCKSIZE; x++) + light[z][x] = sunlight; } else { // Dummy boolean, the position is valid. bool is_valid_position; // For each column: for (s16 z = 0; z < MAP_BLOCKSIZE; z++) - for (s16 x = 0; x < MAP_BLOCKSIZE; x++) { - // Get the bottom block. - MapNode above = source_block->getNodeNoCheck( - x, 0, z, &is_valid_position); - light[z][x] = above.getLight(LIGHTBANK_DAY, ndef) == - LIGHT_SUN; - } + for (s16 x = 0; x < MAP_BLOCKSIZE; x++) { + // Get the bottom block. + MapNode above = source_block->getNodeNoCheck(x, 0, z, + &is_valid_position); + light[z][x] = above.getLight(LIGHTBANK_DAY, ndef) == LIGHT_SUN; + } } } @@ -924,8 +875,7 @@ void is_sunlight_above_block(ServerMap *map, mapblock_v3 pos, const NodeDefManag * \returns true if the block was modified, false otherwise. */ bool propagate_block_sunlight(Map *map, const NodeDefManager *ndef, - SunlightPropagationData *data, UnlightQueue *unlight, - ReLightQueue *relight) + SunlightPropagationData *data, UnlightQueue *unlight, ReLightQueue *relight) { bool modified = false; // Get the block. @@ -942,22 +892,22 @@ bool propagate_block_sunlight(Map *map, const NodeDefManager *ndef, for (index = 0; index < data->data.size(); index++) { SunlightPropagationUnit it = data->data[index]; // Relative position of the currently inspected node. - relative_v3 current_pos( - it.relative_pos.X, MAP_BLOCKSIZE - 1, it.relative_pos.Y); + relative_v3 current_pos(it.relative_pos.X, MAP_BLOCKSIZE - 1, + it.relative_pos.Y); if (it.is_sunlit) { // Propagate sunlight. // For each node downwards: for (; current_pos.Y >= 0; current_pos.Y--) { MapNode n = block->getNodeNoCheck(current_pos, &is_valid); const ContentFeatures &f = ndef->get(n); - if (n.getLightRaw(LIGHTBANK_DAY, f) < LIGHT_SUN && - f.sunlight_propagates) { + if (n.getLightRaw(LIGHTBANK_DAY, f) < LIGHT_SUN + && f.sunlight_propagates) { // This node gets sunlight. n.setLight(LIGHTBANK_DAY, LIGHT_SUN, f); block->setNodeNoCheck(current_pos, n); modified = true; - relight->push(LIGHT_SUN, current_pos, - data->target_block, block, 4); + relight->push(LIGHT_SUN, current_pos, data->target_block, + block, 4); } else { // Light already valid, propagation stopped. break; @@ -974,8 +924,8 @@ bool propagate_block_sunlight(Map *map, const NodeDefManager *ndef, n.setLight(LIGHTBANK_DAY, 0, f); block->setNodeNoCheck(current_pos, n); modified = true; - unlight->push(LIGHT_SUN, current_pos, - data->target_block, block, 4); + unlight->push(LIGHT_SUN, current_pos, data->target_block, + block, 4); } else { // Reached shadow, propagation stopped. break; @@ -998,12 +948,12 @@ bool propagate_block_sunlight(Map *map, const NodeDefManager *ndef, * Compatible with type 'direction'. */ const VoxelArea block_pad[] = { - VoxelArea(v3s16(15, 0, 0), v3s16(15, 15, 15)), // X+ - VoxelArea(v3s16(1, 15, 0), v3s16(14, 15, 15)), // Y+ - VoxelArea(v3s16(1, 1, 15), v3s16(14, 14, 15)), // Z+ - VoxelArea(v3s16(1, 1, 0), v3s16(14, 14, 0)), // Z- - VoxelArea(v3s16(1, 0, 0), v3s16(14, 0, 15)), // Y- - VoxelArea(v3s16(0, 0, 0), v3s16(0, 15, 15)) // X- + VoxelArea(v3s16(15, 0, 0), v3s16(15, 15, 15)), //X+ + VoxelArea(v3s16(1, 15, 0), v3s16(14, 15, 15)), //Y+ + VoxelArea(v3s16(1, 1, 15), v3s16(14, 14, 15)), //Z+ + VoxelArea(v3s16(1, 1, 0), v3s16(14, 14, 0)), //Z- + VoxelArea(v3s16(1, 0, 0), v3s16(14, 0, 15)), //Y- + VoxelArea(v3s16(0, 0, 0), v3s16(0, 15, 15)) //X- }; /*! @@ -1026,9 +976,9 @@ const VoxelArea block_pad[] = { * \param modified_blocks the procedure adds all modified blocks to * this map */ -void finish_bulk_light_update(Map *map, mapblock_v3 minblock, mapblock_v3 maxblock, - UnlightQueue unlight[2], ReLightQueue relight[2], - std::map<v3s16, MapBlock *> *modified_blocks) +void finish_bulk_light_update(Map *map, mapblock_v3 minblock, + mapblock_v3 maxblock, UnlightQueue unlight[2], ReLightQueue relight[2], + std::map<v3s16, MapBlock*> *modified_blocks) { const NodeDefManager *ndef = map->getNodeDefManager(); // dummy boolean @@ -1039,7 +989,7 @@ void finish_bulk_light_update(Map *map, mapblock_v3 minblock, mapblock_v3 maxblo for (size_t bank = 0; bank < 2; bank++) { LightBank b = banks[bank]; unspread_light(map, ndef, b, unlight[bank], relight[bank], - *modified_blocks); + *modified_blocks); } // --- STEP 2: Get all newly inserted light sources @@ -1048,45 +998,30 @@ void finish_bulk_light_update(Map *map, mapblock_v3 minblock, mapblock_v3 maxblo v3s16 blockpos; v3s16 relpos; for (blockpos.X = minblock.X; blockpos.X <= maxblock.X; blockpos.X++) - for (blockpos.Y = minblock.Y; blockpos.Y <= maxblock.Y; blockpos.Y++) - for (blockpos.Z = minblock.Z; blockpos.Z <= maxblock.Z; - blockpos.Z++) { - MapBlock *block = map->getBlockNoCreateNoEx(blockpos); - if (!block || block->isDummy()) - // Skip not existing blocks - continue; - // For each node in the block: - for (relpos.X = 0; relpos.X < MAP_BLOCKSIZE; relpos.X++) - for (relpos.Z = 0; relpos.Z < MAP_BLOCKSIZE; - relpos.Z++) - for (relpos.Y = 0; - relpos.Y < MAP_BLOCKSIZE; - relpos.Y++) { - MapNode node = block->getNodeNoCheck( - relpos.X, - relpos.Y, - relpos.Z, - &is_valid); - const ContentFeatures &f = - ndef->get(node); - - // For each light bank - for (size_t b = 0; b < 2; b++) { - LightBank bank = banks[b]; - u8 light = f.param_type == CPT_LIGHT - ? node.getLightNoChecks( - bank, - &f) - : f.light_source; - if (light > 1) - relight[b].push(light, - relpos, - blockpos, - block, - 6); - } // end of banks - } // end of nodes - } // end of blocks + for (blockpos.Y = minblock.Y; blockpos.Y <= maxblock.Y; blockpos.Y++) + for (blockpos.Z = minblock.Z; blockpos.Z <= maxblock.Z; blockpos.Z++) { + MapBlock *block = map->getBlockNoCreateNoEx(blockpos); + if (!block || block->isDummy()) + // Skip not existing blocks + continue; + // For each node in the block: + for (relpos.X = 0; relpos.X < MAP_BLOCKSIZE; relpos.X++) + for (relpos.Z = 0; relpos.Z < MAP_BLOCKSIZE; relpos.Z++) + for (relpos.Y = 0; relpos.Y < MAP_BLOCKSIZE; relpos.Y++) { + MapNode node = block->getNodeNoCheck(relpos.X, relpos.Y, relpos.Z, &is_valid); + const ContentFeatures &f = ndef->get(node); + + // For each light bank + for (size_t b = 0; b < 2; b++) { + LightBank bank = banks[b]; + u8 light = f.param_type == CPT_LIGHT ? + node.getLightNoChecks(bank, &f): + f.light_source; + if (light > 1) + relight[b].push(light, relpos, blockpos, block, 6); + } // end of banks + } // end of nodes + } // end of blocks // --- STEP 3: do light spreading @@ -1098,11 +1033,10 @@ void finish_bulk_light_update(Map *map, mapblock_v3 minblock, mapblock_v3 maxblo // Initialize light values for light spreading. for (u8 i = 0; i <= maxlight; i++) { const std::vector<ChangingLight> &lights = relight[b].lights[i]; - for (std::vector<ChangingLight>::const_iterator it = - lights.begin(); + for (std::vector<ChangingLight>::const_iterator it = lights.begin(); it < lights.end(); ++it) { - MapNode n = it->block->getNodeNoCheck( - it->rel_position, &is_valid); + MapNode n = it->block->getNodeNoCheck(it->rel_position, + &is_valid); n.setLight(bank, i, ndef); it->block->setNodeNoCheck(it->rel_position, n); } @@ -1113,14 +1047,14 @@ void finish_bulk_light_update(Map *map, mapblock_v3 minblock, mapblock_v3 maxblo } void blit_back_with_light(ServerMap *map, MMVManip *vm, - std::map<v3s16, MapBlock *> *modified_blocks) + std::map<v3s16, MapBlock*> *modified_blocks) { const NodeDefManager *ndef = map->getNodeDefManager(); mapblock_v3 minblock = getNodeBlockPos(vm->m_area.MinEdge); mapblock_v3 maxblock = getNodeBlockPos(vm->m_area.MaxEdge); // First queue is for day light, second is for night light. - UnlightQueue unlight[] = {UnlightQueue(256), UnlightQueue(256)}; - ReLightQueue relight[] = {ReLightQueue(256), ReLightQueue(256)}; + UnlightQueue unlight[] = { UnlightQueue(256), UnlightQueue(256) }; + ReLightQueue relight[] = { ReLightQueue(256), ReLightQueue(256) }; // Will hold sunlight data. bool lights[MAP_BLOCKSIZE][MAP_BLOCKSIZE]; SunlightPropagationData data; @@ -1131,30 +1065,28 @@ void blit_back_with_light(ServerMap *map, MMVManip *vm, // For each map block: for (s16 x = minblock.X; x <= maxblock.X; x++) - for (s16 z = minblock.Z; z <= maxblock.Z; z++) { - // Extract sunlight above. - is_sunlight_above_block( - map, v3s16(x, maxblock.Y, z), ndef, lights); - v2s16 offset(x, z); - offset *= MAP_BLOCKSIZE; - // Reset the voxel manipulator. - fill_with_sunlight(vm, ndef, offset, lights); - // Copy sunlight data - data.target_block = v3s16(x, minblock.Y - 1, z); - for (s16 z = 0; z < MAP_BLOCKSIZE; z++) - for (s16 x = 0; x < MAP_BLOCKSIZE; x++) - data.data.emplace_back(v2s16(x, z), lights[z][x]); - // Propagate sunlight and shadow below the voxel manipulator. - while (!data.data.empty()) { - if (propagate_block_sunlight(map, ndef, &data, - &unlight[0], &relight[0])) - (*modified_blocks)[data.target_block] = - map->getBlockNoCreateNoEx( - data.target_block); - // Step downwards. - data.target_block.Y--; - } + for (s16 z = minblock.Z; z <= maxblock.Z; z++) { + // Extract sunlight above. + is_sunlight_above_block(map, v3s16(x, maxblock.Y, z), ndef, lights); + v2s16 offset(x, z); + offset *= MAP_BLOCKSIZE; + // Reset the voxel manipulator. + fill_with_sunlight(vm, ndef, offset, lights); + // Copy sunlight data + data.target_block = v3s16(x, minblock.Y - 1, z); + for (s16 z = 0; z < MAP_BLOCKSIZE; z++) + for (s16 x = 0; x < MAP_BLOCKSIZE; x++) + data.data.emplace_back(v2s16(x, z), lights[z][x]); + // Propagate sunlight and shadow below the voxel manipulator. + while (!data.data.empty()) { + if (propagate_block_sunlight(map, ndef, &data, &unlight[0], + &relight[0])) + (*modified_blocks)[data.target_block] = + map->getBlockNoCreateNoEx(data.target_block); + // Step downwards. + data.target_block.Y--; } + } // --- STEP 2: Get nodes from borders to unlight v3s16 blockpos; @@ -1164,71 +1096,45 @@ void blit_back_with_light(ServerMap *map, MMVManip *vm, // unlight each block. // For each block: for (blockpos.X = minblock.X; blockpos.X <= maxblock.X; blockpos.X++) - for (blockpos.Y = minblock.Y; blockpos.Y <= maxblock.Y; blockpos.Y++) - for (blockpos.Z = minblock.Z; blockpos.Z <= maxblock.Z; - blockpos.Z++) { - MapBlock *block = map->getBlockNoCreateNoEx(blockpos); - if (!block || block->isDummy()) - // Skip not existing blocks. - continue; - v3s16 offset = block->getPosRelative(); - // For each border of the block: - for (const VoxelArea &a : block_pad) { - // For each node of the border: - for (relpos.X = a.MinEdge.X; - relpos.X <= a.MaxEdge.X; - relpos.X++) - for (relpos.Z = a.MinEdge.Z; - relpos.Z <= a.MaxEdge.Z; - relpos.Z++) - for (relpos.Y = a.MinEdge.Y; - relpos.Y <= - a.MaxEdge.Y; - relpos.Y++) { - - // Get old and new node - MapNode oldnode = block->getNodeNoCheck( - relpos, - &is_valid); - const ContentFeatures &oldf = - ndef->get(oldnode); - MapNode newnode = vm->getNodeNoExNoEmerge( - relpos + - offset); - const ContentFeatures &newf = - oldnode == newnode - ? oldf - : ndef->get(newnode); - - // For each light bank - for (size_t b = 0; b < 2; - b++) { - LightBank bank = banks - [b]; - u8 oldlight = oldf.param_type == CPT_LIGHT - ? oldnode.getLightNoChecks( - bank, - &oldf) - : LIGHT_SUN; // no light information, force unlighting - u8 newlight = newf.param_type == CPT_LIGHT - ? newnode.getLightNoChecks( - bank, - &newf) - : newf.light_source; - // If the new node - // is dimmer, - // unlight. - if (oldlight > newlight) { - unlight[b].push(oldlight, - relpos, - blockpos, - block, - 6); - } - } // end of banks - } // end of nodes - } // end of borders - } // end of blocks + for (blockpos.Y = minblock.Y; blockpos.Y <= maxblock.Y; blockpos.Y++) + for (blockpos.Z = minblock.Z; blockpos.Z <= maxblock.Z; blockpos.Z++) { + MapBlock *block = map->getBlockNoCreateNoEx(blockpos); + if (!block || block->isDummy()) + // Skip not existing blocks. + continue; + v3s16 offset = block->getPosRelative(); + // For each border of the block: + for (const VoxelArea &a : block_pad) { + // For each node of the border: + for (relpos.X = a.MinEdge.X; relpos.X <= a.MaxEdge.X; relpos.X++) + for (relpos.Z = a.MinEdge.Z; relpos.Z <= a.MaxEdge.Z; relpos.Z++) + for (relpos.Y = a.MinEdge.Y; relpos.Y <= a.MaxEdge.Y; relpos.Y++) { + + // Get old and new node + MapNode oldnode = block->getNodeNoCheck(relpos, &is_valid); + const ContentFeatures &oldf = ndef->get(oldnode); + MapNode newnode = vm->getNodeNoExNoEmerge(relpos + offset); + const ContentFeatures &newf = oldnode == newnode ? oldf : + ndef->get(newnode); + + // For each light bank + for (size_t b = 0; b < 2; b++) { + LightBank bank = banks[b]; + u8 oldlight = oldf.param_type == CPT_LIGHT ? + oldnode.getLightNoChecks(bank, &oldf): + LIGHT_SUN; // no light information, force unlighting + u8 newlight = newf.param_type == CPT_LIGHT ? + newnode.getLightNoChecks(bank, &newf): + newf.light_source; + // If the new node is dimmer, unlight. + if (oldlight > newlight) { + unlight[b].push( + oldlight, relpos, blockpos, block, 6); + } + } // end of banks + } // end of nodes + } // end of borders + } // end of blocks // --- STEP 3: All information extracted, overwrite @@ -1236,8 +1142,8 @@ void blit_back_with_light(ServerMap *map, MMVManip *vm, // --- STEP 4: Finish light update - finish_bulk_light_update( - map, minblock, maxblock, unlight, relight, modified_blocks); + finish_bulk_light_update(map, minblock, maxblock, unlight, relight, + modified_blocks); } /*! @@ -1251,7 +1157,7 @@ void blit_back_with_light(ServerMap *map, MMVManip *vm, * the bottom of the map block. */ void fill_with_sunlight(MapBlock *block, const NodeDefManager *ndef, - bool light[MAP_BLOCKSIZE][MAP_BLOCKSIZE]) + bool light[MAP_BLOCKSIZE][MAP_BLOCKSIZE]) { if (block->isDummy()) return; @@ -1259,39 +1165,39 @@ void fill_with_sunlight(MapBlock *block, const NodeDefManager *ndef, bool is_valid; // For each column of nodes: for (s16 z = 0; z < MAP_BLOCKSIZE; z++) - for (s16 x = 0; x < MAP_BLOCKSIZE; x++) { - // True if the current node has sunlight. - bool lig = light[z][x]; - // For each node, downwards: - for (s16 y = MAP_BLOCKSIZE - 1; y >= 0; y--) { - MapNode n = block->getNodeNoCheck(x, y, z, &is_valid); - // Ignore IGNORE nodes, these are not generated yet. - if (n.getContent() == CONTENT_IGNORE) - continue; - const ContentFeatures &f = ndef->get(n.getContent()); - if (lig && !f.sunlight_propagates) { - // Sunlight is stopped. - lig = false; - } - // Reset light - n.setLight(LIGHTBANK_DAY, lig ? 15 : 0, f); - n.setLight(LIGHTBANK_NIGHT, 0, f); - block->setNodeNoCheck(x, y, z, n); + for (s16 x = 0; x < MAP_BLOCKSIZE; x++) { + // True if the current node has sunlight. + bool lig = light[z][x]; + // For each node, downwards: + for (s16 y = MAP_BLOCKSIZE - 1; y >= 0; y--) { + MapNode n = block->getNodeNoCheck(x, y, z, &is_valid); + // Ignore IGNORE nodes, these are not generated yet. + if (n.getContent() == CONTENT_IGNORE) + continue; + const ContentFeatures &f = ndef->get(n.getContent()); + if (lig && !f.sunlight_propagates) { + // Sunlight is stopped. + lig = false; } - // Output outgoing light. - light[z][x] = lig; + // Reset light + n.setLight(LIGHTBANK_DAY, lig ? 15 : 0, f); + n.setLight(LIGHTBANK_NIGHT, 0, f); + block->setNodeNoCheck(x, y, z, n); } + // Output outgoing light. + light[z][x] = lig; + } } void repair_block_light(ServerMap *map, MapBlock *block, - std::map<v3s16, MapBlock *> *modified_blocks) + std::map<v3s16, MapBlock*> *modified_blocks) { if (!block || block->isDummy()) return; const NodeDefManager *ndef = map->getNodeDefManager(); // First queue is for day light, second is for night light. - UnlightQueue unlight[] = {UnlightQueue(256), UnlightQueue(256)}; - ReLightQueue relight[] = {ReLightQueue(256), ReLightQueue(256)}; + UnlightQueue unlight[] = { UnlightQueue(256), UnlightQueue(256) }; + ReLightQueue relight[] = { ReLightQueue(256), ReLightQueue(256) }; // Will hold sunlight data. bool lights[MAP_BLOCKSIZE][MAP_BLOCKSIZE]; SunlightPropagationData data; @@ -1310,14 +1216,15 @@ void repair_block_light(ServerMap *map, MapBlock *block, // Copy sunlight data data.target_block = v3s16(blockpos.X, blockpos.Y - 1, blockpos.Z); for (s16 z = 0; z < MAP_BLOCKSIZE; z++) - for (s16 x = 0; x < MAP_BLOCKSIZE; x++) { - data.data.emplace_back(v2s16(x, z), lights[z][x]); - } + for (s16 x = 0; x < MAP_BLOCKSIZE; x++) { + data.data.emplace_back(v2s16(x, z), lights[z][x]); + } // Propagate sunlight and shadow below the voxel manipulator. while (!data.data.empty()) { - if (propagate_block_sunlight(map, ndef, &data, &unlight[0], &relight[0])) + if (propagate_block_sunlight(map, ndef, &data, &unlight[0], + &relight[0])) (*modified_blocks)[data.target_block] = - map->getBlockNoCreateNoEx(data.target_block); + map->getBlockNoCreateNoEx(data.target_block); // Step downwards. data.target_block.Y--; } @@ -1329,84 +1236,72 @@ void repair_block_light(ServerMap *map, MapBlock *block, v3s16 relpos; // For each node of the border: for (relpos.X = a.MinEdge.X; relpos.X <= a.MaxEdge.X; relpos.X++) - for (relpos.Z = a.MinEdge.Z; relpos.Z <= a.MaxEdge.Z; relpos.Z++) - for (relpos.Y = a.MinEdge.Y; relpos.Y <= a.MaxEdge.Y; - relpos.Y++) { - - // Get node - MapNode node = block->getNodeNoCheck( - relpos, &is_valid); - const ContentFeatures &f = ndef->get(node); - // For each light bank - for (size_t b = 0; b < 2; b++) { - LightBank bank = banks[b]; - u8 light = f.param_type == CPT_LIGHT - ? node.getLightNoChecks( - bank, - &f) - : f.light_source; - // If the new node is dimmer than - // sunlight, unlight. (if it has maximal - // light, it is pointless to remove - // surrounding light, as it can only - // become brighter) - if (LIGHT_SUN > light) { - unlight[b].push(LIGHT_SUN, relpos, - blockpos, block, - 6); - } - } // end of banks - } // end of nodes - } // end of borders + for (relpos.Z = a.MinEdge.Z; relpos.Z <= a.MaxEdge.Z; relpos.Z++) + for (relpos.Y = a.MinEdge.Y; relpos.Y <= a.MaxEdge.Y; relpos.Y++) { + + // Get node + MapNode node = block->getNodeNoCheck(relpos, &is_valid); + const ContentFeatures &f = ndef->get(node); + // For each light bank + for (size_t b = 0; b < 2; b++) { + LightBank bank = banks[b]; + u8 light = f.param_type == CPT_LIGHT ? + node.getLightNoChecks(bank, &f): + f.light_source; + // If the new node is dimmer than sunlight, unlight. + // (if it has maximal light, it is pointless to remove + // surrounding light, as it can only become brighter) + if (LIGHT_SUN > light) { + unlight[b].push( + LIGHT_SUN, relpos, blockpos, block, 6); + } + } // end of banks + } // end of nodes + } // end of borders // STEP 3: Remove and spread light - finish_bulk_light_update( - map, blockpos, blockpos, unlight, relight, modified_blocks); + finish_bulk_light_update(map, blockpos, blockpos, unlight, relight, + modified_blocks); } VoxelLineIterator::VoxelLineIterator(const v3f &start_position, const v3f &line_vector) : - m_start_position(start_position), m_line_vector(line_vector) + m_start_position(start_position), + m_line_vector(line_vector) { m_current_node_pos = floatToInt(m_start_position, 1); m_start_node_pos = m_current_node_pos; m_last_index = getIndex(floatToInt(start_position + line_vector, 1)); if (m_line_vector.X > 0) { - m_next_intersection_multi.X = (floorf(m_start_position.X - 0.5) + 1.5 - - m_start_position.X) / - m_line_vector.X; + m_next_intersection_multi.X = (floorf(m_start_position.X - 0.5) + 1.5 + - m_start_position.X) / m_line_vector.X; m_intersection_multi_inc.X = 1 / m_line_vector.X; } else if (m_line_vector.X < 0) { - m_next_intersection_multi.X = (floorf(m_start_position.X - 0.5) - - m_start_position.X + 0.5) / - m_line_vector.X; + m_next_intersection_multi.X = (floorf(m_start_position.X - 0.5) + - m_start_position.X + 0.5) / m_line_vector.X; m_intersection_multi_inc.X = -1 / m_line_vector.X; m_step_directions.X = -1; } if (m_line_vector.Y > 0) { - m_next_intersection_multi.Y = (floorf(m_start_position.Y - 0.5) + 1.5 - - m_start_position.Y) / - m_line_vector.Y; + m_next_intersection_multi.Y = (floorf(m_start_position.Y - 0.5) + 1.5 + - m_start_position.Y) / m_line_vector.Y; m_intersection_multi_inc.Y = 1 / m_line_vector.Y; } else if (m_line_vector.Y < 0) { - m_next_intersection_multi.Y = (floorf(m_start_position.Y - 0.5) - - m_start_position.Y + 0.5) / - m_line_vector.Y; + m_next_intersection_multi.Y = (floorf(m_start_position.Y - 0.5) + - m_start_position.Y + 0.5) / m_line_vector.Y; m_intersection_multi_inc.Y = -1 / m_line_vector.Y; m_step_directions.Y = -1; } if (m_line_vector.Z > 0) { - m_next_intersection_multi.Z = (floorf(m_start_position.Z - 0.5) + 1.5 - - m_start_position.Z) / - m_line_vector.Z; + m_next_intersection_multi.Z = (floorf(m_start_position.Z - 0.5) + 1.5 + - m_start_position.Z) / m_line_vector.Z; m_intersection_multi_inc.Z = 1 / m_line_vector.Z; } else if (m_line_vector.Z < 0) { - m_next_intersection_multi.Z = (floorf(m_start_position.Z - 0.5) - - m_start_position.Z + 0.5) / - m_line_vector.Z; + m_next_intersection_multi.Z = (floorf(m_start_position.Z - 0.5) + - m_start_position.Z + 0.5) / m_line_vector.Z; m_intersection_multi_inc.Z = -1 / m_line_vector.Z; m_step_directions.Z = -1; } @@ -1415,8 +1310,8 @@ VoxelLineIterator::VoxelLineIterator(const v3f &start_position, const v3f &line_ void VoxelLineIterator::next() { m_current_index++; - if ((m_next_intersection_multi.X < m_next_intersection_multi.Y) && - (m_next_intersection_multi.X < m_next_intersection_multi.Z)) { + if ((m_next_intersection_multi.X < m_next_intersection_multi.Y) + && (m_next_intersection_multi.X < m_next_intersection_multi.Z)) { m_next_intersection_multi.X += m_intersection_multi_inc.X; m_current_node_pos.X += m_step_directions.X; } else if ((m_next_intersection_multi.Y < m_next_intersection_multi.Z)) { @@ -1428,10 +1323,12 @@ void VoxelLineIterator::next() } } -s16 VoxelLineIterator::getIndex(v3s16 voxel) -{ - return abs(voxel.X - m_start_node_pos.X) + abs(voxel.Y - m_start_node_pos.Y) + - abs(voxel.Z - m_start_node_pos.Z); +s16 VoxelLineIterator::getIndex(v3s16 voxel){ + return + abs(voxel.X - m_start_node_pos.X) + + abs(voxel.Y - m_start_node_pos.Y) + + abs(voxel.Z - m_start_node_pos.Z); } } // namespace voxalgo + |