#pragma once #include #include #include "World.h" #include "Block.h" namespace vf { constexpr int maxLightLevel = 15; // Incremental sky + block light over a fixed world box. Sky light is seeded from // the open top of the box at full strength and travels straight down without loss // while unobstructed, attenuating one level per step in every other direction. // Block light radiates from emitters, attenuating one level per step. Editing a // block re-lights only the affected neighbourhood (flood-fill add plus removal // darkening) and yields the same field a full rebuild would produce. The box is // chunk-agnostic: it indexes by world coordinate, so light crosses chunk borders // seamlessly. class LightEngine { public: LightEngine(World& world, const Vec3i& origin, const Vec3i& dims); void rebuild(); // Sets a world block and incrementally updates both light channels. void setBlock(int gx, int gy, int gz, Block block); uint8_t sunAt(int gx, int gy, int gz) const; uint8_t blockAt(int gx, int gy, int gz) const; float combinedAt(int gx, int gy, int gz, float dayFactor = 1.0f) const; const Vec3i& regionOrigin() const { return origin; } const Vec3i& regionDims() const { return dims; } const std::vector& sunField() const { return sun; } const std::vector& blockField() const { return block; } void loadRaw(const std::vector& sunData, const std::vector& blockData) { if (sunData.size() == sun.size()) sun = sunData; if (blockData.size() == block.size()) block = blockData; } private: struct Node { int lx, ly, lz; uint8_t level; }; int index(int lx, int ly, int lz) const { return (ly * dims.z + lz) * dims.x + lx; } bool inBox(int lx, int ly, int lz) const; bool occludesLocal(int lx, int ly, int lz) const; // isSun selects the straight-down full-strength rule for the channel. void floodAdd(std::vector& field, std::vector& queue, bool isSun); void floodRemove(std::vector& field, std::vector& removals, std::vector& reAdd, bool isSun); void updateSun(int lx, int ly, int lz); void updateBlock(int lx, int ly, int lz, Block newBlock); World& world; Vec3i origin; Vec3i dims; std::vector sun; std::vector block; }; } // namespace vf