make chunk lightmap optional
This commit is contained in:
@@ -16,18 +16,23 @@ LightSolver::LightSolver(const ContentIndices& contentIds, Chunks& chunks, int c
|
||||
}
|
||||
|
||||
void LightSolver::add(int x, int y, int z, int emission) {
|
||||
if (emission <= 1)
|
||||
if (emission <= 1) {
|
||||
return;
|
||||
}
|
||||
Chunk* chunk = chunks.getChunkByVoxel(x, y, z);
|
||||
if (chunk == nullptr)
|
||||
if (chunk == nullptr) {
|
||||
return;
|
||||
ubyte light = chunk->lightmap.get(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel);
|
||||
}
|
||||
assert(chunk->lightmap != nullptr);
|
||||
auto& lightmap = *chunk->lightmap;
|
||||
|
||||
ubyte light = lightmap.get(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel);
|
||||
if (emission < light) return;
|
||||
|
||||
addqueue.push(lightentry {x, y, z, ubyte(emission)});
|
||||
|
||||
chunk->flags.modified = true;
|
||||
chunk->lightmap.set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, emission);
|
||||
lightmap.set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, emission);
|
||||
}
|
||||
|
||||
void LightSolver::add(int x, int y, int z) {
|
||||
@@ -36,15 +41,18 @@ void LightSolver::add(int x, int y, int z) {
|
||||
|
||||
void LightSolver::remove(int x, int y, int z) {
|
||||
Chunk* chunk = chunks.getChunkByVoxel(x, y, z);
|
||||
if (chunk == nullptr)
|
||||
if (chunk == nullptr) {
|
||||
return;
|
||||
}
|
||||
assert(chunk->lightmap != nullptr);
|
||||
auto& lightmap = *chunk->lightmap;
|
||||
|
||||
ubyte light = chunk->lightmap.get(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel);
|
||||
if (light == 0){
|
||||
ubyte light = lightmap.get(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel);
|
||||
if (light == 0) {
|
||||
return;
|
||||
}
|
||||
remqueue.push(lightentry {x, y, z, light});
|
||||
chunk->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(){
|
||||
@@ -73,18 +81,21 @@ void LightSolver::solve(){
|
||||
int lz = z - chunk->z * CHUNK_D;
|
||||
chunk->flags.modified = true;
|
||||
|
||||
ubyte light = chunk->lightmap.get(lx,y,lz, channel);
|
||||
assert(chunk->lightmap != nullptr);
|
||||
auto& lightmap = *chunk->lightmap;
|
||||
|
||||
ubyte light = lightmap.get(lx,y,lz, channel);
|
||||
if (light != 0 && light == entry.light-1){
|
||||
voxel* vox = chunks.get(x, y, z);
|
||||
if (vox && vox->id != 0) {
|
||||
const Block* block = blockDefs[vox->id];
|
||||
if (uint8_t emission = block->emission[channel]) {
|
||||
addqueue.push(lightentry {x, y, z, emission});
|
||||
chunk->lightmap.set(lx, y, lz, channel, emission);
|
||||
lightmap.set(lx, y, lz, channel, emission);
|
||||
}
|
||||
else chunk->lightmap.set(lx, y, lz, channel, 0);
|
||||
else lightmap.set(lx, y, lz, channel, 0);
|
||||
}
|
||||
else chunk->lightmap.set(lx, y, lz, channel, 0);
|
||||
else lightmap.set(lx, y, lz, channel, 0);
|
||||
remqueue.push(lightentry {x, y, z, light});
|
||||
}
|
||||
else if (light >= entry.light){
|
||||
@@ -105,21 +116,24 @@ void LightSolver::solve(){
|
||||
int z = entry.z+coords[imul3+2];
|
||||
|
||||
Chunk* chunk = chunks.getChunkByVoxel(x,y,z);
|
||||
if (chunk) {
|
||||
int lx = x - chunk->x * CHUNK_W;
|
||||
int lz = z - chunk->z * CHUNK_D;
|
||||
chunk->flags.modified = true;
|
||||
if (chunk == nullptr) {
|
||||
continue;
|
||||
}
|
||||
assert(chunk->lightmap != nullptr);
|
||||
auto& lightmap = *chunk->lightmap;
|
||||
int lx = x - chunk->x * CHUNK_W;
|
||||
int lz = z - chunk->z * CHUNK_D;
|
||||
chunk->flags.modified = true;
|
||||
|
||||
ubyte light = chunk->lightmap.get(lx, y, lz, channel);
|
||||
voxel& v = chunk->voxels[vox_index(lx, y, lz)];
|
||||
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);
|
||||
addqueue.push(lightentry {x, y, z, ubyte(entry.light-1)});
|
||||
}
|
||||
ubyte light = lightmap.get(lx, y, lz, channel);
|
||||
voxel& v = chunk->voxels[vox_index(lx, y, lz)];
|
||||
const Block* block = blockDefs[v.id];
|
||||
if (block->lightPassing && light+2 <= entry.light){
|
||||
lightmap.set(
|
||||
x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D,
|
||||
channel,
|
||||
entry.light-1);
|
||||
addqueue.push(lightentry {x, y, z, ubyte(entry.light-1)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+26
-13
@@ -29,16 +29,21 @@ void Lighting::clear(){
|
||||
const auto& chunks = this->chunks.getChunks();
|
||||
for (size_t index = 0; index < chunks.size(); index++){
|
||||
auto chunk = chunks[index];
|
||||
if (chunk == nullptr)
|
||||
if (chunk == nullptr) {
|
||||
continue;
|
||||
Lightmap& lightmap = chunk->lightmap;
|
||||
for (int i = 0; i < CHUNK_VOL; i++){
|
||||
lightmap.map[i] = 0;
|
||||
}
|
||||
auto& lightmap = chunk->lightmap;
|
||||
if (lightmap == nullptr) {
|
||||
continue;
|
||||
}
|
||||
std::memset(lightmap->map, 0, sizeof(Lightmap::map));
|
||||
}
|
||||
}
|
||||
|
||||
void Lighting::prebuildSkyLight(Chunk& chunk, const ContentIndices& indices){
|
||||
void Lighting::prebuildSkyLight(Chunk& chunk, const ContentIndices& indices) {
|
||||
assert(chunk.lightmap != nullptr);
|
||||
auto& lightmap = *chunk.lightmap;
|
||||
|
||||
const auto* blockDefs = indices.blocks.getDefs();
|
||||
|
||||
int highestPoint = 0;
|
||||
@@ -49,17 +54,19 @@ void Lighting::prebuildSkyLight(Chunk& chunk, const ContentIndices& indices){
|
||||
voxel& vox = chunk.voxels[index];
|
||||
const Block* block = blockDefs[vox.id];
|
||||
if (!block->skyLightPassing) {
|
||||
if (highestPoint < y)
|
||||
if (highestPoint < y) {
|
||||
highestPoint = y;
|
||||
}
|
||||
break;
|
||||
}
|
||||
chunk.lightmap.setS(x,y,z, 15);
|
||||
lightmap.setS(x, y, z, 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (highestPoint < CHUNK_H-1)
|
||||
if (highestPoint < CHUNK_H-1) {
|
||||
highestPoint++;
|
||||
chunk.lightmap.highestPoint = highestPoint;
|
||||
}
|
||||
lightmap.highestPoint = highestPoint;
|
||||
}
|
||||
|
||||
void Lighting::buildSkyLight(int cx, int cz){
|
||||
@@ -70,15 +77,18 @@ void Lighting::buildSkyLight(int cx, int cz){
|
||||
logger.error() << "attempted to build sky lights to chunk missing in local matrix";
|
||||
return;
|
||||
}
|
||||
assert(chunk->lightmap != nullptr);
|
||||
auto& lightmap = *chunk->lightmap;
|
||||
|
||||
for (int z = 0; z < CHUNK_D; z++){
|
||||
for (int x = 0; x < CHUNK_W; x++){
|
||||
int gx = x + cx * CHUNK_W;
|
||||
int gz = z + cz * CHUNK_D;
|
||||
for (int y = chunk->lightmap.highestPoint; y >= 0; y--){
|
||||
for (int y = lightmap.highestPoint; y >= 0; y--){
|
||||
while (y > 0 && !blockDefs[chunk->voxels[vox_index(x, y, z)].id]->lightPassing) {
|
||||
y--;
|
||||
}
|
||||
if (chunk->lightmap.getS(x, y, z) != 15) {
|
||||
if (lightmap.getS(x, y, z) != 15) {
|
||||
solverS->add(gx,y+1,gz);
|
||||
for (; y >= 0; y--){
|
||||
solverS->add(gx+1,y,gz);
|
||||
@@ -106,6 +116,9 @@ void Lighting::onChunkLoaded(int cx, int cz, bool expand) {
|
||||
logger.error() << "attempted to build lights to chunk missing in local matrix";
|
||||
return;
|
||||
}
|
||||
assert(chunk->lightmap != nullptr);
|
||||
auto& lightmap = *chunk->lightmap;
|
||||
|
||||
for (uint y = 0; y < CHUNK_H; y++){
|
||||
for (uint z = 0; z < CHUNK_D; z++){
|
||||
for (uint x = 0; x < CHUNK_W; x++){
|
||||
@@ -128,7 +141,7 @@ void Lighting::onChunkLoaded(int cx, int cz, bool expand) {
|
||||
for (int z = 0; z < CHUNK_D; z++) {
|
||||
int gx = x + cx * CHUNK_W;
|
||||
int gz = z + cz * CHUNK_D;
|
||||
int rgbs = chunk->lightmap.get(x, y, z);
|
||||
int rgbs = 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));
|
||||
@@ -143,7 +156,7 @@ void Lighting::onChunkLoaded(int cx, int cz, bool expand) {
|
||||
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);
|
||||
int rgbs = 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));
|
||||
|
||||
@@ -89,4 +89,6 @@ public:
|
||||
|
||||
std::unique_ptr<ubyte[]> encode() const;
|
||||
static std::unique_ptr<light_t[]> decode(const ubyte* buffer);
|
||||
|
||||
static inline light_t SUN_LIGHT_ONLY = combine(0U, 0U, 0U, 15U);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user