diff --git a/src/lighting/LightSolver.cpp b/src/lighting/LightSolver.cpp index 04bf045d..d67df55a 100644 --- a/src/lighting/LightSolver.cpp +++ b/src/lighting/LightSolver.cpp @@ -9,22 +9,20 @@ #include "../voxels/Block.h" LightSolver::LightSolver(const ContentIndices* contentIds, Chunks* chunks, int channel) - : contentIds(contentIds), chunks(chunks), channel(channel) { + : contentIds(contentIds), + chunks(chunks), + channel(channel) { } void LightSolver::add(int x, int y, int z, int emission) { if (emission <= 1) return; - lightentry entry; - entry.x = x; - entry.y = y; - entry.z = z; - entry.light = emission; - addqueue.push(entry); - Chunk* chunk = chunks->getChunkByVoxel(entry.x, entry.y, entry.z); + addqueue.push(lightentry {x, y, z, ubyte(emission)}); + + Chunk* chunk = chunks->getChunkByVoxel(x, y, z); chunk->setModified(true); - chunk->lightmap->set(entry.x-chunk->x*CHUNK_W, entry.y, entry.z-chunk->z*CHUNK_D, channel, entry.light); + chunk->lightmap->set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, emission); } void LightSolver::add(int x, int y, int z) { @@ -37,19 +35,12 @@ void LightSolver::remove(int x, int y, int z) { if (chunk == nullptr) return; - int light = chunk->lightmap->get(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel); + ubyte light = chunk->lightmap->get(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel); if (light == 0){ return; } - - lightentry entry; - entry.x = x; - entry.y = y; - entry.z = z; - entry.light = light; - remqueue.push(entry); - - chunk->lightmap->set(entry.x-chunk->x*CHUNK_W, entry.y, entry.z-chunk->z*CHUNK_D, channel, 0); + remqueue.push(lightentry {x, y, z, light}); + chunk->lightmap->set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, 0); } void LightSolver::solve(){ @@ -66,30 +57,20 @@ void LightSolver::solve(){ const lightentry entry = remqueue.front(); remqueue.pop(); - for (size_t i = 0; i < 6; i++) { + for (int i = 0; i < 6; i++) { int x = entry.x+coords[i*3+0]; int y = entry.y+coords[i*3+1]; int z = entry.z+coords[i*3+2]; Chunk* chunk = chunks->getChunkByVoxel(x,y,z); if (chunk) { chunk->setModified(true); - int light = chunks->getLight(x,y,z, channel); + ubyte light = chunks->getLight(x,y,z, channel); if (light != 0 && light == entry.light-1){ - lightentry nentry; - nentry.x = x; - nentry.y = y; - nentry.z = z; - nentry.light = light; - remqueue.push(nentry); + remqueue.push(lightentry {x, y, z, light}); chunk->lightmap->set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, 0); } else if (light >= entry.light){ - lightentry nentry; - nentry.x = x; - nentry.y = y; - nentry.z = z; - nentry.light = light; - addqueue.push(nentry); + addqueue.push(lightentry {x, y, z, light}); } } } @@ -100,27 +81,22 @@ void LightSolver::solve(){ const lightentry entry = addqueue.front(); addqueue.pop(); - if (entry.light <= 1) - continue; - - for (size_t i = 0; i < 6; i++) { + for (int i = 0; i < 6; i++) { int x = entry.x+coords[i*3+0]; int y = entry.y+coords[i*3+1]; int z = entry.z+coords[i*3+2]; Chunk* chunk = chunks->getChunkByVoxel(x,y,z); if (chunk) { chunk->setModified(true); - int light = chunks->getLight(x,y,z, channel); + int light = chunk->lightmap->get( + x - chunk->x * CHUNK_W, y, + z - chunk->z * CHUNK_D, + channel); voxel* v = chunks->get(x,y,z); const Block* block = blockDefs[v->id]; if (block->lightPassing && light+2 <= entry.light){ chunk->lightmap->set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, entry.light-1); - lightentry nentry; - nentry.x = x; - nentry.y = y; - nentry.z = z; - nentry.light = entry.light-1; - addqueue.push(nentry); + addqueue.push(lightentry {x, y, z, ubyte(entry.light-1)}); } } } diff --git a/src/lighting/Lighting.cpp b/src/lighting/Lighting.cpp index e5ddd4c7..d4e4322e 100644 --- a/src/lighting/Lighting.cpp +++ b/src/lighting/Lighting.cpp @@ -114,18 +114,32 @@ void Lighting::onChunkLoaded(int cx, int cz, bool expand){ } if (expand) { - for (int y = -1; y <= CHUNK_H; y++){ - for (int z = -1; z <= CHUNK_D; z++){ - for (int x = -1; x <= CHUNK_W; x++){ - if (!(x == -1 || x == CHUNK_W || z == -1 || z == CHUNK_D)) - continue; + for (int x = 0; x < CHUNK_W; x += CHUNK_W-1) { + for (int y = 0; y < CHUNK_H; y++) { + for (int z = 0; z < CHUNK_D; z++) { int gx = x + cx * CHUNK_W; int gz = z + cz * CHUNK_D; - if (chunks->getLight(x,y,z)){ - solverR->add(gx,y,gz); - solverG->add(gx,y,gz); - solverB->add(gx,y,gz); - solverS->add(gx,y,gz); + int rgbs = chunk->lightmap->get(x, y, z); + if (rgbs){ + solverR->add(gx,y,gz, Lightmap::extract(rgbs, 0)); + solverG->add(gx,y,gz, Lightmap::extract(rgbs, 1)); + solverB->add(gx,y,gz, Lightmap::extract(rgbs, 2)); + solverS->add(gx,y,gz, Lightmap::extract(rgbs, 3)); + } + } + } + } + for (int z = 0; z < CHUNK_D; z += CHUNK_D-1) { + for (int y = 0; y < CHUNK_H; y++) { + for (int x = 0; x < CHUNK_W; x++) { + int gx = x + cx * CHUNK_W; + int gz = z + cz * CHUNK_D; + int rgbs = chunk->lightmap->get(x, y, z); + if (rgbs){ + solverR->add(gx,y,gz, Lightmap::extract(rgbs, 0)); + solverG->add(gx,y,gz, Lightmap::extract(rgbs, 1)); + solverB->add(gx,y,gz, Lightmap::extract(rgbs, 2)); + solverS->add(gx,y,gz, Lightmap::extract(rgbs, 3)); } } } diff --git a/src/logic/ChunksController.cpp b/src/logic/ChunksController.cpp index 8dbfa16e..da02dadc 100644 --- a/src/logic/ChunksController.cpp +++ b/src/logic/ChunksController.cpp @@ -30,7 +30,6 @@ ChunksController::ChunksController(Level* level, uint padding) } ChunksController::~ChunksController(){ - delete generator; } void ChunksController::update(int64_t maxDuration) { @@ -73,6 +72,7 @@ bool ChunksController::loadVisible(){ } chunk->surrounding = surrounding; if (surrounding == MIN_SURROUNDING && !chunk->isLighted()) { + timeutil::ScopeLogTimer log(555); bool lightsCache = chunk->isLoadedLights(); if (!lightsCache) { lighting->buildSkyLight(chunk->x, chunk->z); diff --git a/src/logic/ChunksController.h b/src/logic/ChunksController.h index a9fa0fa6..cf1e99df 100644 --- a/src/logic/ChunksController.h +++ b/src/logic/ChunksController.h @@ -1,6 +1,7 @@ #ifndef VOXELS_CHUNKSCONTROLLER_H_ #define VOXELS_CHUNKSCONTROLLER_H_ +#include #include "../typedefs.h" class Level; @@ -11,22 +12,22 @@ class WorldGenerator; /* ChunksController manages chunks dynamic loading/unloading */ class ChunksController { private: - Level* level; - Chunks* chunks; - Lighting* lighting; - uint padding; - WorldGenerator* generator; + Level* level; + Chunks* chunks; + Lighting* lighting; + uint padding; + std::unique_ptr generator; - /* Average measured microseconds duration of loadVisible call */ - int64_t avgDurationMcs = 1000; + /* Average measured microseconds duration of loadVisible call */ + int64_t avgDurationMcs = 1000; - /* Process one chunk: load it or calculate lights for it */ - bool loadVisible(); + /* Process one chunk: load it or calculate lights for it */ + bool loadVisible(); public: - ChunksController(Level* level, uint padding); - ~ChunksController(); + ChunksController(Level* level, uint padding); + ~ChunksController(); - /* @param maxDuration milliseconds reserved for chunks loading */ + /* @param maxDuration milliseconds reserved for chunks loading */ void update(int64_t maxDuration); };