summaryrefslogtreecommitdiff
path: root/src/World/Generation
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
parent23d88e5f1c8f0c8652a07050fcfa8ff126e85d4a (diff)
downloadmeowcraft-2eef7cf49b7a15559ee7bb6719411bcf67386213.tar.zst
meowcraft-2eef7cf49b7a15559ee7bb6719411bcf67386213.zip
Propagation in lighting system
Diffstat (limited to 'src/World/Generation')
-rw-r--r--src/World/Generation/Lighting.cpp54
-rw-r--r--src/World/Generation/Lighting.hpp30
2 files changed, 72 insertions, 12 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);
+ }
+ }
+}
+
}
diff --git a/src/World/Generation/Lighting.hpp b/src/World/Generation/Lighting.hpp
index 7bb8fcc..72af0e1 100644
--- a/src/World/Generation/Lighting.hpp
+++ b/src/World/Generation/Lighting.hpp
@@ -1,13 +1,33 @@
#pragma once
+#include <queue>
#include "../Chunk.hpp"
-#include "ChunkNeighbors.hpp"
+#include "../ChunkIndex.hpp"
+#include "../ChunkRegistry.hpp"
+#include "../Position.hpp"
-namespace MC::World::Generation::Lighting {
+namespace MC::World::Generation {
-constexpr U8 LightSun = 200;
-constexpr U8 LightTorch = 100;
+class Lighting {
+public:
+ void add_chunk(Chunk& chunk);
+ void add_block(Chunk& chunk, Position::BlockLocal position, U8 light);
-void light_chunk(Chunk& chunk, ChunkNeighbors& neighbors);
+ void illuminate(ChunkRegistry& chunks);
+private:
+ static constexpr U8 SunBrightness = 200;
+ static constexpr U8 DefaultFalloff = 10;
+
+ struct Operation {
+ ChunkIndex chunk;
+ Position::BlockLocal position;
+ U8 origin;
+ };
+
+ void enqueue(ChunkIndex chunk, Position::BlockLocal position, U8 origin);
+ void process(ChunkRegistry& chunks, Operation op);
+
+ std::queue<Operation> m_queue;
+};
}