Update light of neighboring blocks when they changed while placing/removing a block.

Also removes stair blocks when they are empty.

Fixes #339
This commit is contained in:
IntegratedQuantum 2024-04-30 23:22:13 +02:00
parent 3e0c666108
commit 711255a7e1
2 changed files with 16 additions and 9 deletions

View File

@ -748,10 +748,19 @@ pub const ChunkMesh = struct {
self.finishNeighbors(); self.finishNeighbors();
} }
fn updateBlockLight(self: *ChunkMesh, x: u5, y: u5, z: u5, newBlock: Block) void {
for(self.lightingData[0..]) |lightingData| {
lightingData.propagateLightsDestructive(&.{.{x, y, z}});
}
if(newBlock.light() != 0) {
self.lightingData[0].propagateLights(&.{.{x, y, z}}, false);
}
}
pub fn updateBlock(self: *ChunkMesh, _x: i32, _y: i32, _z: i32, _newBlock: Block) void { pub fn updateBlock(self: *ChunkMesh, _x: i32, _y: i32, _z: i32, _newBlock: Block) void {
const x = _x & chunk.chunkMask; const x: u5 = @intCast(_x & chunk.chunkMask);
const y = _y & chunk.chunkMask; const y: u5 = @intCast(_y & chunk.chunkMask);
const z = _z & chunk.chunkMask; const z: u5 = @intCast(_z & chunk.chunkMask);
var newBlock = _newBlock; var newBlock = _newBlock;
var neighborBlocks: [6]Block = undefined; var neighborBlocks: [6]Block = undefined;
@memset(&neighborBlocks, .{.typ = 0, .data = 0}); @memset(&neighborBlocks, .{.typ = 0, .data = 0});
@ -771,6 +780,7 @@ pub const ChunkMesh = struct {
neighborChunkMesh.opaqueMesh.coreFaces.clearRetainingCapacity(); neighborChunkMesh.opaqueMesh.coreFaces.clearRetainingCapacity();
neighborChunkMesh.transparentMesh.coreFaces.clearRetainingCapacity(); neighborChunkMesh.transparentMesh.coreFaces.clearRetainingCapacity();
neighborChunkMesh.mutex.unlock(); neighborChunkMesh.mutex.unlock();
neighborChunkMesh.updateBlockLight(@intCast(nx & chunk.chunkMask), @intCast(ny & chunk.chunkMask), @intCast(nz & chunk.chunkMask), neighborBlock);
neighborChunkMesh.generateMesh(); neighborChunkMesh.generateMesh();
neighborChunkMesh.mutex.lock(); neighborChunkMesh.mutex.lock();
} }
@ -784,6 +794,7 @@ pub const ChunkMesh = struct {
if(neighborBlock.mode().dependsOnNeighbors) { if(neighborBlock.mode().dependsOnNeighbors) {
if(neighborBlock.mode().updateData(&neighborBlock, neighbor ^ 1, newBlock)) { if(neighborBlock.mode().updateData(&neighborBlock, neighbor ^ 1, newBlock)) {
self.chunk.data.setValue(index, neighborBlock); self.chunk.data.setValue(index, neighborBlock);
self.updateBlockLight(@intCast(nx & chunk.chunkMask), @intCast(ny & chunk.chunkMask), @intCast(nz & chunk.chunkMask), neighborBlock);
} }
} }
self.mutex.unlock(); self.mutex.unlock();
@ -798,12 +809,7 @@ pub const ChunkMesh = struct {
self.mutex.lock(); self.mutex.lock();
self.chunk.data.setValue(chunk.getIndex(x, y, z), newBlock); self.chunk.data.setValue(chunk.getIndex(x, y, z), newBlock);
self.mutex.unlock(); self.mutex.unlock();
for(self.lightingData[0..]) |lightingData| { self.updateBlockLight(x, y, z, newBlock);
lightingData.propagateLightsDestructive(&.{.{@intCast(x), @intCast(y), @intCast(z)}});
}
if(newBlock.light() != 0) {
self.lightingData[0].propagateLights(&.{.{@intCast(x), @intCast(y), @intCast(z)}}, false);
}
self.mutex.lock(); self.mutex.lock();
defer self.mutex.unlock(); defer self.mutex.unlock();
// Update neighbor chunks: // Update neighbor chunks:

View File

@ -493,6 +493,7 @@ pub const RotationModes = struct {
pub fn chisel(_: *main.game.World, _: Vec3i, relativePlayerPos: Vec3f, playerDir: Vec3f, currentData: *Block) bool { pub fn chisel(_: *main.game.World, _: Vec3i, relativePlayerPos: Vec3f, playerDir: Vec3f, currentData: *Block) bool {
if(intersectionPos(currentData.*, relativePlayerPos, playerDir)) |intersection| { if(intersectionPos(currentData.*, relativePlayerPos, playerDir)) |intersection| {
currentData.data = currentData.data | subBlockMask(intersection.minPos[0], intersection.minPos[1], intersection.minPos[2]); currentData.data = currentData.data | subBlockMask(intersection.minPos[0], intersection.minPos[1], intersection.minPos[2]);
if(currentData.data == 255) currentData.* = .{.typ = 0, .data = 0};
return true; return true;
} }
return false; return false;