diff --git a/src/mapgen/mapgen.cpp b/src/mapgen/mapgen.cpp index 29131d56e..9f17af866 100644 --- a/src/mapgen/mapgen.cpp +++ b/src/mapgen/mapgen.cpp @@ -39,6 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serialization.h" #include "util/serialize.h" #include "util/numeric.h" +#include "util/directiontables.h" #include "filesys.h" #include "log.h" #include "mapgen_carpathian.h" @@ -435,7 +436,8 @@ void Mapgen::setLighting(u8 light, v3s16 nmin, v3s16 nmax) } -void Mapgen::lightSpread(VoxelArea &a, v3s16 p, u8 light) +void Mapgen::lightSpread(VoxelArea &a, std::queue> &queue, + const v3s16 &p, u8 light) { if (light <= 1 || !a.contains(p)) return; @@ -455,8 +457,8 @@ void Mapgen::lightSpread(VoxelArea &a, v3s16 p, u8 light) // Bail out only if we have no more light from either bank to propogate, or // we hit a solid block that light cannot pass through. if ((light_day <= (n.param1 & 0x0F) && - light_night <= (n.param1 & 0xF0)) || - !ndef->get(n).light_propagates) + light_night <= (n.param1 & 0xF0)) || + !ndef->get(n).light_propagates) return; // Since this recursive function only terminates when there is no light from @@ -467,12 +469,8 @@ void Mapgen::lightSpread(VoxelArea &a, v3s16 p, u8 light) n.param1 = light; - lightSpread(a, p + v3s16(0, 0, 1), light); - lightSpread(a, p + v3s16(0, 1, 0), light); - lightSpread(a, p + v3s16(1, 0, 0), light); - lightSpread(a, p - v3s16(0, 0, 1), light); - lightSpread(a, p - v3s16(0, 1, 0), light); - lightSpread(a, p - v3s16(1, 0, 0), light); + // add to queue + queue.emplace(p, light); } @@ -525,9 +523,10 @@ void Mapgen::propagateSunlight(v3s16 nmin, v3s16 nmax, bool propagate_shadow) } -void Mapgen::spreadLight(v3s16 nmin, v3s16 nmax) +void Mapgen::spreadLight(const v3s16 &nmin, const v3s16 &nmax) { //TimeTaker t("spreadLight"); + std::queue> queue; VoxelArea a(nmin, nmax); for (int z = a.MinEdge.Z; z <= a.MaxEdge.Z; z++) { @@ -551,18 +550,24 @@ void Mapgen::spreadLight(v3s16 nmin, v3s16 nmax) u8 light = n.param1; if (light) { - lightSpread(a, v3s16(x, y, z + 1), light); - lightSpread(a, v3s16(x, y + 1, z ), light); - lightSpread(a, v3s16(x + 1, y, z ), light); - lightSpread(a, v3s16(x, y, z - 1), light); - lightSpread(a, v3s16(x, y - 1, z ), light); - lightSpread(a, v3s16(x - 1, y, z ), light); + const v3s16 p(x, y, z); + // spread to all 6 neighbor nodes + for (const auto &dir : g_6dirs) + lightSpread(a, queue, p + dir, light); } } } } - //printf("spreadLight: %dms\n", t.stop()); + while (!queue.empty()) { + const auto &i = queue.front(); + // spread to all 6 neighbor nodes + for (const auto &dir : g_6dirs) + lightSpread(a, queue, i.first + dir, i.second); + queue.pop(); + } + + //printf("spreadLight: %lums\n", t.stop()); } @@ -877,7 +882,7 @@ void MapgenBasic::generateDungeons(s16 max_stone_y) return; PseudoRandom ps(blockseed + 70033); - + DungeonParams dp; dp.np_alt_wall = diff --git a/src/mapgen/mapgen.h b/src/mapgen/mapgen.h index b10aa7b9e..0ac26d538 100644 --- a/src/mapgen/mapgen.h +++ b/src/mapgen/mapgen.h @@ -190,11 +190,12 @@ public: void updateLiquid(UniqueQueue *trans_liquid, v3s16 nmin, v3s16 nmax); void setLighting(u8 light, v3s16 nmin, v3s16 nmax); - void lightSpread(VoxelArea &a, v3s16 p, u8 light); + void lightSpread(VoxelArea &a, std::queue> &queue, + const v3s16 &p, u8 light); void calcLighting(v3s16 nmin, v3s16 nmax, v3s16 full_nmin, v3s16 full_nmax, bool propagate_shadow = true); void propagateSunlight(v3s16 nmin, v3s16 nmax, bool propagate_shadow); - void spreadLight(v3s16 nmin, v3s16 nmax); + void spreadLight(const v3s16 &nmin, const v3s16 &nmax); virtual void makeChunk(BlockMakeData *data) {} virtual int getGroundLevelAtPoint(v2s16 p) { return 0; }