namespace voxalgo
{
-void setLight(VoxelManipulator &v, VoxelArea a, u8 light,
- INodeDefManager *ndef)
-{
- 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++)
- {
- v3s16 p(x,y,z);
- MapNode &n = v.getNodeRefUnsafe(p);
- n.setLight(LIGHTBANK_DAY, light, ndef);
- n.setLight(LIGHTBANK_NIGHT, light, ndef);
- }
-}
-
-void clearLightAndCollectSources(VoxelManipulator &v, VoxelArea a,
- enum LightBank bank, INodeDefManager *ndef,
- std::set<v3s16> & light_sources,
- std::map<v3s16, u8> & unlight_from)
-{
- // The full area we shall touch
- VoxelArea required_a = a;
- required_a.pad(v3s16(0,0,0));
- // Make sure we have access to it
- v.addArea(a);
-
- 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++)
- {
- v3s16 p(x,y,z);
- MapNode &n = v.getNodeRefUnsafe(p);
- u8 oldlight = n.getLight(bank, ndef);
- n.setLight(bank, 0, ndef);
-
- // If node sources light, add to list
- u8 source = ndef->get(n).light_source;
- if(source != 0)
- light_sources.insert(p);
-
- // Collect borders for unlighting
- if((x==a.MinEdge.X || x == a.MaxEdge.X
- || y==a.MinEdge.Y || y == a.MaxEdge.Y
- || z==a.MinEdge.Z || z == a.MaxEdge.Z)
- && oldlight != 0)
- {
- unlight_from[p] = oldlight;
- }
- }
-}
-
-SunlightPropagateResult propagateSunlight(VoxelManipulator &v, VoxelArea a,
- bool inexistent_top_provides_sunlight,
- std::set<v3s16> & light_sources,
- INodeDefManager *ndef)
-{
- // Return values
- bool bottom_sunlight_valid = true;
-
- // The full area we shall touch extends one extra at top and bottom
- VoxelArea required_a = a;
- required_a.pad(v3s16(0,1,0));
- // Make sure we have access to it
- v.addArea(a);
-
- s16 max_y = a.MaxEdge.Y;
- s16 min_y = a.MinEdge.Y;
-
- for(s32 x=a.MinEdge.X; x<=a.MaxEdge.X; x++)
- for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++)
- {
- v3s16 p_overtop(x, max_y+1, z);
- bool overtop_has_sunlight = false;
- // If overtop node does not exist, trust heuristics
- if(!v.exists(p_overtop))
- overtop_has_sunlight = inexistent_top_provides_sunlight;
- else if(v.getNodeRefUnsafe(p_overtop).getContent() == CONTENT_IGNORE)
- overtop_has_sunlight = inexistent_top_provides_sunlight;
- // Otherwise refer to it's light value
- else
- overtop_has_sunlight = (v.getNodeRefUnsafe(p_overtop).getLight(
- LIGHTBANK_DAY, ndef) == LIGHT_SUN);
-
- // Copy overtop's sunlight all over the place
- u8 incoming_light = overtop_has_sunlight ? LIGHT_SUN : 0;
- for(s32 y=max_y; y>=min_y; y--)
- {
- v3s16 p(x,y,z);
- MapNode &n = v.getNodeRefUnsafe(p);
- if(incoming_light == 0){
- // Do nothing
- } else if(incoming_light == LIGHT_SUN &&
- ndef->get(n).sunlight_propagates){
- // Do nothing
- } else if(!ndef->get(n).sunlight_propagates){
- incoming_light = 0;
- } else {
- incoming_light = diminish_light(incoming_light);
- }
- u8 old_light = n.getLight(LIGHTBANK_DAY, ndef);
-
- if(incoming_light > old_light)
- n.setLight(LIGHTBANK_DAY, incoming_light, ndef);
-
- if(diminish_light(incoming_light) != 0)
- light_sources.insert(p);
- }
-
- // Check validity of sunlight at top of block below if it
- // hasn't already been proven invalid
- if(bottom_sunlight_valid)
- {
- bool sunlight_should_continue_down = (incoming_light == LIGHT_SUN);
- v3s16 p_overbottom(x, min_y-1, z);
- if(!v.exists(p_overbottom) ||
- v.getNodeRefUnsafe(p_overbottom
- ).getContent() == CONTENT_IGNORE){
- // Is not known, cannot compare
- } else {
- bool overbottom_has_sunlight = (v.getNodeRefUnsafe(p_overbottom
- ).getLight(LIGHTBANK_DAY, ndef) == LIGHT_SUN);
- if(sunlight_should_continue_down != overbottom_has_sunlight){
- bottom_sunlight_valid = false;
- }
- }
- }
- }
-
- return {bottom_sunlight_valid};
-}
-
/*!
* A direction.
* 0=X+
ChangingLight() = default;
- ChangingLight(const relative_v3 &rel_pos, const mapblock_v3 &block_pos,
+ ChangingLight(relative_v3 rel_pos, mapblock_v3 block_pos,
MapBlock *b, direction source_dir) :
rel_position(rel_pos),
block_position(block_pos),
* The parameters are the same as in ChangingLight's constructor.
* \param light light level of the ChangingLight
*/
- inline void push(u8 light, const relative_v3 &rel_pos,
- const mapblock_v3 &block_pos, MapBlock *block,
+ inline void push(u8 light, relative_v3 rel_pos,
+ mapblock_v3 block_pos, MapBlock *block,
direction source_dir)
{
assert(light <= LIGHT_SUN);
* \param light_sources nodes that should be re-lighted
* \param modified_blocks output, all modified map blocks are added to this
*/
-void unspread_light(Map *map, INodeDefManager *nodemgr, LightBank bank,
+void unspread_light(Map *map, const NodeDefManager *nodemgr, LightBank bank,
UnlightQueue &from_nodes, ReLightQueue &light_sources,
std::map<v3s16, MapBlock*> &modified_blocks)
{
* \param light_sources starting nodes
* \param modified_blocks output, all modified map blocks are added to this
*/
-void spread_light(Map *map, INodeDefManager *nodemgr, LightBank bank,
+void spread_light(Map *map, const NodeDefManager *nodemgr, LightBank bank,
LightQueue &light_sources,
std::map<v3s16, MapBlock*> &modified_blocks)
{
*
* \param pos position of the node.
*/
-bool is_sunlight_above(Map *map, v3s16 pos, INodeDefManager *ndef)
+bool is_sunlight_above(Map *map, v3s16 pos, const NodeDefManager *ndef)
{
bool sunlight = true;
mapblock_v3 source_block_pos;
static const LightBank banks[] = { LIGHTBANK_DAY, LIGHTBANK_NIGHT };
void update_lighting_nodes(Map *map,
- std::vector<std::pair<v3s16, MapNode> > &oldnodes,
+ const std::vector<std::pair<v3s16, MapNode>> &oldnodes,
std::map<v3s16, MapBlock*> &modified_blocks)
{
- INodeDefManager *ndef = map->getNodeDefManager();
+ const NodeDefManager *ndef = map->getNodeDefManager();
// For node getter functions
bool is_valid_position;
// 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 (auto it = oldnodes.cbegin(); it < oldnodes.cend(); ++it) {
u8 old_light = it->second.getLight(bank, ndef);
if (old_light > min_safe_light) {
min_safe_light = old_light;
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 (auto it = oldnodes.cbegin(); it < oldnodes.cend(); ++it) {
// Get position and block of the changed node
v3s16 p = it->first;
relative_v3 rel_pos;
for (const v3s16 &neighbor_dir : neighbor_dirs) {
v3s16 p2 = p + neighbor_dir;
bool is_valid;
- MapNode n2 = map->getNodeNoEx(p2, &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
MapNode n2;
- n2 = map->getNodeNoEx(n2pos, &is_valid_position);
+ n2 = map->getNode(n2pos, &is_valid_position);
if (!is_valid_position)
break;
MapNode n2;
- n2 = map->getNodeNoEx(n2pos, &is_valid_position);
+ n2 = map->getNode(n2pos, &is_valid_position);
if (!is_valid_position)
break;
* its light source and its brightest neighbor minus one.
* .
*/
-bool is_light_locally_correct(Map *map, INodeDefManager *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->getNodeNoEx(pos, &is_valid_position);
+ MapNode n = map->getNode(pos, &is_valid_position);
const ContentFeatures &f = ndef->get(n);
if (f.param_type != CPT_LIGHT) {
return true;
assert(f.light_source <= LIGHT_MAX);
u8 brightest_neighbor = f.light_source + 1;
for (const v3s16 &neighbor_dir : neighbor_dirs) {
- MapNode n2 = map->getNodeNoEx(pos + neighbor_dir,
+ MapNode n2 = map->getNode(pos + neighbor_dir,
&is_valid_position);
u8 light2 = n2.getLight(bank, ndef);
if (brightest_neighbor < light2) {
void update_block_border_lighting(Map *map, MapBlock *block,
std::map<v3s16, MapBlock*> &modified_blocks)
{
- INodeDefManager *ndef = map->getNodeDefManager();
+ const NodeDefManager *ndef = map->getNodeDefManager();
bool is_valid_position;
for (LightBank bank : banks) {
// Since invalid light is not common, do not allocate
* After the procedure returns, this contains outgoing light at
* the bottom of the voxel manipulator.
*/
-void fill_with_sunlight(MMVManip *vm, INodeDefManager *ndef, v2s16 offset,
+void fill_with_sunlight(MMVManip *vm, const NodeDefManager *ndef, v2s16 offset,
bool light[MAP_BLOCKSIZE][MAP_BLOCKSIZE])
{
// Distance in array between two nodes on top of each other.
* node coordinates.
*/
void is_sunlight_above_block(ServerMap *map, mapblock_v3 pos,
- INodeDefManager *ndef, bool light[MAP_BLOCKSIZE][MAP_BLOCKSIZE])
+ const NodeDefManager *ndef, bool light[MAP_BLOCKSIZE][MAP_BLOCKSIZE])
{
mapblock_v3 source_block_pos = pos + v3s16(0, 1, 0);
// Get or load source block.
*
* \returns true if the block was modified, false otherwise.
*/
-bool propagate_block_sunlight(Map *map, INodeDefManager *ndef,
+bool propagate_block_sunlight(Map *map, const NodeDefManager *ndef,
SunlightPropagationData *data, UnlightQueue *unlight, ReLightQueue *relight)
{
bool modified = false;
mapblock_v3 maxblock, UnlightQueue unlight[2], ReLightQueue relight[2],
std::map<v3s16, MapBlock*> *modified_blocks)
{
- INodeDefManager *ndef = map->getNodeDefManager();
+ const NodeDefManager *ndef = map->getNodeDefManager();
// dummy boolean
bool is_valid;
// --- STEP 2: Get all newly inserted light sources
// For each block:
- for (s16 b_x = minblock.X; b_x <= maxblock.X; b_x++)
- for (s16 b_y = minblock.Y; b_y <= maxblock.Y; b_y++)
- for (s16 b_z = minblock.Z; b_z <= maxblock.Z; b_z++) {
- const v3s16 blockpos(b_x, b_y, b_z);
+ 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 (s32 x = 0; x < MAP_BLOCKSIZE; x++)
- for (s32 z = 0; z < MAP_BLOCKSIZE; z++)
- for (s32 y = 0; y < MAP_BLOCKSIZE; y++) {
- v3s16 relpos(x, y, z);
- MapNode node = block->getNodeNoCheck(x, y, z, &is_valid);
+ 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];
void blit_back_with_light(ServerMap *map, MMVManip *vm,
std::map<v3s16, MapBlock*> *modified_blocks)
{
- INodeDefManager *ndef = map->getNodeDefManager();
+ 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.
}
// --- STEP 2: Get nodes from borders to unlight
+ v3s16 blockpos;
+ v3s16 relpos;
// In case there are unloaded holes in the voxel manipulator
// unlight each block.
// For each block:
- for (s16 b_x = minblock.X; b_x <= maxblock.X; b_x++)
- for (s16 b_y = minblock.Y; b_y <= maxblock.Y; b_y++)
- for (s16 b_z = minblock.Z; b_z <= maxblock.Z; b_z++) {
- v3s16 blockpos(b_x, b_y, b_z);
+ 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.
// For each border of the block:
for (const VoxelArea &a : block_pad) {
// For each node of the border:
- 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++) {
- v3s16 relpos(x, y, z);
+ 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(x, y, z, &is_valid);
+ MapNode oldnode = block->getNodeNoCheck(relpos, &is_valid);
const ContentFeatures &oldf = ndef->get(oldnode);
MapNode newnode = vm->getNodeNoExNoEmerge(relpos + offset);
- const ContentFeatures &newf = ndef->get(newnode);
+ 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];
* After the procedure returns, this contains outgoing light at
* the bottom of the map block.
*/
-void fill_with_sunlight(MapBlock *block, INodeDefManager *ndef,
+void fill_with_sunlight(MapBlock *block, const NodeDefManager *ndef,
bool light[MAP_BLOCKSIZE][MAP_BLOCKSIZE])
{
if (block->isDummy())
{
if (!block || block->isDummy())
return;
- INodeDefManager *ndef = map->getNodeDefManager();
+ 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) };
// For each border of the block:
for (const VoxelArea &a : block_pad) {
+ v3s16 relpos;
// For each node of the border:
- 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++) {
- v3s16 relpos(x, y, z);
+ 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(x, y, z, &is_valid);
+ 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++) {