reduce Chunks.getChunkByVoxel calls in LightSolver

This commit is contained in:
MihailRis 2026-01-29 19:52:47 +03:00
parent 117199a3ec
commit bf7732f68a
4 changed files with 47 additions and 27 deletions

View file

@ -1,6 +1,3 @@
#include <iostream>
#include <assert.h>
#include "LightSolver.hpp" #include "LightSolver.hpp"
#include "Lightmap.hpp" #include "Lightmap.hpp"
#include "content/Content.hpp" #include "content/Content.hpp"
@ -9,6 +6,8 @@
#include "voxels/voxel.hpp" #include "voxels/voxel.hpp"
#include "voxels/Block.hpp" #include "voxels/Block.hpp"
#include <assert.h>
LightSolver::LightSolver(const ContentIndices& contentIds, Chunks& chunks, int channel) LightSolver::LightSolver(const ContentIndices& contentIds, Chunks& chunks, int channel)
: blockDefs(contentIds.blocks.getDefs()), : blockDefs(contentIds.blocks.getDefs()),
chunks(chunks), chunks(chunks),
@ -55,7 +54,7 @@ void LightSolver::remove(int x, int y, int z) {
lightmap.set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, 0); lightmap.set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, 0);
} }
void LightSolver::solve() { void LightSolver::solve(Chunk* prevailingChunk) {
const int coords[] = { const int coords[] = {
0, 0, 1, 0, 0, 1,
0, 0,-1, 0, 0,-1,
@ -75,10 +74,16 @@ void LightSolver::solve() {
int y = entry.y+coords[imul3+1]; int y = entry.y+coords[imul3+1];
int z = entry.z+coords[imul3+2]; int z = entry.z+coords[imul3+2];
Chunk* chunk = chunks.getChunkByVoxel(x,y,z); Chunk* chunk = prevailingChunk;
if (chunk == nullptr) { if (chunk == nullptr || !chunk->isBlockInside(x, z)) {
chunk = chunks.getChunkByVoxel(x,y,z);
if (chunk == nullptr) {
continue;
}
} else if (y < 0 || y >= CHUNK_H) {
continue; continue;
} }
int lx = x - chunk->x * CHUNK_W; int lx = x - chunk->x * CHUNK_W;
int lz = z - chunk->z * CHUNK_D; int lz = z - chunk->z * CHUNK_D;
chunk->flags.modified = true; chunk->flags.modified = true;
@ -116,10 +121,16 @@ void LightSolver::solve() {
int y = entry.y+coords[imul3+1]; int y = entry.y+coords[imul3+1];
int z = entry.z+coords[imul3+2]; int z = entry.z+coords[imul3+2];
Chunk* chunk = chunks.getChunkByVoxel(x,y,z); Chunk* chunk = prevailingChunk;
if (chunk == nullptr) { if (chunk == nullptr || !chunk->isBlockInside(x, z)) {
chunk = chunks.getChunkByVoxel(x,y,z);
if (chunk == nullptr) {
continue;
}
} else if (y < 0 || y >= CHUNK_H) {
continue; continue;
} }
assert(chunk->lightmap != nullptr); assert(chunk->lightmap != nullptr);
auto& lightmap = *chunk->lightmap; auto& lightmap = *chunk->lightmap;
int lx = x - chunk->x * CHUNK_W; int lx = x - chunk->x * CHUNK_W;

View file

@ -2,6 +2,7 @@
#include "util/array_queue.hpp" #include "util/array_queue.hpp"
class Chunk;
class Chunks; class Chunks;
class ContentIndices; class ContentIndices;
class Block; class Block;
@ -25,5 +26,5 @@ public:
void add(int x, int y, int z); void add(int x, int y, int z);
void add(int x, int y, int z, int emission); void add(int x, int y, int z, int emission);
void remove(int x, int y, int z); void remove(int x, int y, int z);
void solve(); void solve(Chunk* prevailingChunk = nullptr);
}; };

View file

@ -167,10 +167,10 @@ void Lighting::onChunkLoaded(int cx, int cz, bool expand) {
} }
} }
} }
solverR.solve(); solverR.solve(chunk);
solverG.solve(); solverG.solve(chunk);
solverB.solve(); solverB.solve(chunk);
solverS.solve(); solverS.solve(chunk);
} }
void Lighting::onBlockSet(int x, int y, int z, blockid_t id){ void Lighting::onBlockSet(int x, int y, int z, blockid_t id){
@ -180,9 +180,10 @@ void Lighting::onBlockSet(int x, int y, int z, blockid_t id){
solverB->remove(x,y,z); solverB->remove(x,y,z);
if (id == 0){ if (id == 0){
solverR->solve(); auto chunk = chunks.getChunkByVoxel(glm::ivec3{x, y, z});
solverG->solve(); solverR->solve(chunk);
solverB->solve(); solverG->solve(chunk);
solverB->solve(chunk);
if (chunks.getLight(x,y+1,z, 3) == 0xF){ if (chunks.getLight(x,y+1,z, 3) == 0xF){
for (int i = y; i >= 0; i--){ for (int i = y; i >= 0; i--){
voxel* vox = chunks.get(x,i,z); voxel* vox = chunks.get(x,i,z);
@ -197,11 +198,12 @@ void Lighting::onBlockSet(int x, int y, int z, blockid_t id){
solverR->add(x-1,y,z); solverG->add(x-1,y,z); solverB->add(x-1,y,z); solverS->add(x-1,y,z); solverR->add(x-1,y,z); solverG->add(x-1,y,z); solverB->add(x-1,y,z); solverS->add(x-1,y,z);
solverR->add(x,y,z+1); solverG->add(x,y,z+1); solverB->add(x,y,z+1); solverS->add(x,y,z+1); solverR->add(x,y,z+1); solverG->add(x,y,z+1); solverB->add(x,y,z+1); solverS->add(x,y,z+1);
solverR->add(x,y,z-1); solverG->add(x,y,z-1); solverB->add(x,y,z-1); solverS->add(x,y,z-1); solverR->add(x,y,z-1); solverG->add(x,y,z-1); solverB->add(x,y,z-1); solverS->add(x,y,z-1);
solverR->solve(); solverR->solve(chunk);
solverG->solve(); solverG->solve(chunk);
solverB->solve(); solverB->solve(chunk);
solverS->solve(); solverS->solve(chunk);
} else { } else {
auto chunk = chunks.getChunkByVoxel(glm::ivec3{x, y, z});
if (!block.skyLightPassing){ if (!block.skyLightPassing){
solverS->remove(x,y,z); solverS->remove(x,y,z);
for (int i = y-1; i >= 0; i--){ for (int i = y-1; i >= 0; i--){
@ -210,19 +212,19 @@ void Lighting::onBlockSet(int x, int y, int z, blockid_t id){
break; break;
} }
} }
solverS->solve(); solverS->solve(chunk);
} }
solverR->solve(); solverR->solve(chunk);
solverG->solve(); solverG->solve(chunk);
solverB->solve(); solverB->solve(chunk);
if (block.emission[0] || block.emission[1] || block.emission[2]){ if (block.emission[0] || block.emission[1] || block.emission[2]){
solverR->add(x,y,z,block.emission[0]); solverR->add(x,y,z,block.emission[0]);
solverG->add(x,y,z,block.emission[1]); solverG->add(x,y,z,block.emission[1]);
solverB->add(x,y,z,block.emission[2]); solverB->add(x,y,z,block.emission[2]);
solverR->solve(); solverR->solve(chunk);
solverG->solve(); solverG->solve(chunk);
solverB->solve(); solverB->solve(chunk);
} }
} }
} }

View file

@ -83,4 +83,10 @@ public:
glm::vec3((x + 1) * CHUNK_W, INFINITY, (z + 1) * CHUNK_D) glm::vec3((x + 1) * CHUNK_W, INFINITY, (z + 1) * CHUNK_D)
); );
} }
bool isBlockInside(int x, int z) const {
x -= this->x * CHUNK_W;
z -= this->z * CHUNK_D;
return x >= 0 && z >= 0 && x < CHUNK_W && z < CHUNK_D;
}
}; };