Make Mapgen::spreadLight use a queue (#8838)
authorDS <vorunbekannt75@web.de>
Fri, 23 Aug 2019 20:16:50 +0000 (22:16 +0200)
committersfan5 <sfan5@live.de>
Fri, 23 Aug 2019 20:16:50 +0000 (22:16 +0200)
src/mapgen/mapgen.cpp
src/mapgen/mapgen.h

index 29131d56e9d4170ba3204e6dc4267976db3640a0..9f17af866e2a44474130e6294dfc913aae4fb55c 100644 (file)
@@ -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<std::pair<v3s16, u8>> &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<std::pair<v3s16, u8>> 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 =
index b10aa7b9ed7fb4e4c89fce780028b8287914d0f4..0ac26d538d46f4e6590903ae7c6a324cb10db924 100644 (file)
@@ -190,11 +190,12 @@ public:
        void updateLiquid(UniqueQueue<v3s16> *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<std::pair<v3s16, u8>> &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; }