summary refs log tree commit diff
path: root/src/World/Generation/Lighting.cpp
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2023-07-22 17:35:00 +0200
committerMel <einebeere@gmail.com>2023-07-22 17:35:00 +0200
commit2eef7cf49b7a15559ee7bb6719411bcf67386213 (patch)
tree11eb7a4f437da7bfdde620c10a043960fd423cfb /src/World/Generation/Lighting.cpp
parent23d88e5f1c8f0c8652a07050fcfa8ff126e85d4a (diff)
downloadmeowcraft-2eef7cf49b7a15559ee7bb6719411bcf67386213.tar.zst
meowcraft-2eef7cf49b7a15559ee7bb6719411bcf67386213.zip
Propagation in lighting system
Diffstat (limited to 'src/World/Generation/Lighting.cpp')
-rw-r--r--src/World/Generation/Lighting.cpp54
1 files changed, 47 insertions, 7 deletions
diff --git a/src/World/Generation/Lighting.cpp b/src/World/Generation/Lighting.cpp
index 8df6e2a..39d8320 100644
--- a/src/World/Generation/Lighting.cpp
+++ b/src/World/Generation/Lighting.cpp
@@ -1,20 +1,60 @@
 #include "Lighting.hpp"
 
-namespace MC::World::Generation::Lighting {
+namespace MC::World::Generation {
 
-void light_chunk(Chunk& chunk, ChunkNeighbors& _) {
-    for (UInt x = 0; x < Chunk::Width; x++) {
-        for (UInt z = 0; z < Chunk::Width; z++) {
-            U8 current_light_exposure = LightSun;
-            for (UInt y = Chunk::Height - 1; y != 0; y--) {
+void Lighting::add_chunk(Chunk& chunk) {
+    for (U8 x = 0; x < Chunk::Width; x++) {
+        for (U8 z = 0; z < Chunk::Width; z++) {
+            U8 current_light_exposure = SunBrightness;
+            for (U8 y = Chunk::Height - 1; y != 0; y--) {
                 auto& block = chunk.at(x, y, z);
                 if (!block.type.is_translucent()) break;
 
                 current_light_exposure = (Real)current_light_exposure * (1 - block.type.opacity());
-                block.light = current_light_exposure;
+                add_block(chunk, {x, y, z}, current_light_exposure);
             }
         }
     }
 }
 
+void Lighting::add_block(Chunk& chunk, Position::BlockLocal position, U8 light) {
+    auto& block = chunk.at(position);
+    block.light = light;
+    enqueue(chunk.index(), position, light);
+}
+
+void Lighting::illuminate(ChunkRegistry& chunks) {
+    while (!m_queue.empty()) {
+        auto op = m_queue.front();
+        m_queue.pop();
+
+        process(chunks, op);
+    }
+}
+
+void Lighting::enqueue(ChunkIndex chunk, Position::BlockLocal position, U8 origin) {
+    m_queue.push({chunk, position, origin});
+}
+
+void Lighting::process(ChunkRegistry& chunks, Operation op) {
+    auto& chunk_data = chunks.get(op.chunk);
+    auto& chunk = chunk_data.chunk.value();
+
+    for (auto direction : Position::axis_directions) {
+        auto neighbor_pos = op.position.offset(direction);
+        if (!neighbor_pos.fits_within_chunk()) continue;
+
+        auto& neighbor = chunk.at(neighbor_pos);
+        if (!neighbor.type.is_translucent()) continue;
+
+        U8 falloff = (neighbor.type.opacity() + 1) * DefaultFalloff;
+        U8 target = std::max(op.origin - falloff, 0);
+
+        if (neighbor.light < target) {
+            neighbor.light = target;
+            enqueue(op.chunk, neighbor_pos, target);
+        }
+    }
+}
+
 }