mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 19:28:49 -04:00
Fix #244 and improve performance of light updates.
This commit is contained in:
parent
4330f33d36
commit
e8f62d5660
@ -49,6 +49,17 @@ pub const ChannelChunk = struct {
|
|||||||
value: u8,
|
value: u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const PositionEntry = struct {
|
||||||
|
x: u5,
|
||||||
|
y: u5,
|
||||||
|
z: u5,
|
||||||
|
};
|
||||||
|
|
||||||
|
const ChunkEntries = struct {
|
||||||
|
mesh: ?*chunk.meshing.ChunkMesh,
|
||||||
|
entries: std.ArrayListUnmanaged(PositionEntry),
|
||||||
|
};
|
||||||
|
|
||||||
fn propagateDirect(self: *ChannelChunk, lightQueue: *main.utils.CircularBufferQueue(Entry)) std.mem.Allocator.Error!void {
|
fn propagateDirect(self: *ChannelChunk, lightQueue: *main.utils.CircularBufferQueue(Entry)) std.mem.Allocator.Error!void {
|
||||||
var neighborLists: [6]std.ArrayListUnmanaged(Entry) = .{.{}} ** 6;
|
var neighborLists: [6]std.ArrayListUnmanaged(Entry) = .{.{}} ** 6;
|
||||||
defer {
|
defer {
|
||||||
@ -96,10 +107,9 @@ pub const ChannelChunk = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn propagateDestructive(self: *ChannelChunk, lightQueue: *main.utils.CircularBufferQueue(Entry)) std.mem.Allocator.Error!void {
|
fn propagateDestructive(self: *ChannelChunk, lightQueue: *main.utils.CircularBufferQueue(Entry), constructiveEntries: *std.ArrayListUnmanaged(ChunkEntries)) std.mem.Allocator.Error!std.ArrayListUnmanaged(PositionEntry) {
|
||||||
var neighborLists: [6]std.ArrayListUnmanaged(Entry) = .{.{}} ** 6;
|
var neighborLists: [6]std.ArrayListUnmanaged(Entry) = .{.{}} ** 6;
|
||||||
var constructiveList: std.ArrayListUnmanaged(Entry) = .{};
|
var constructiveList: std.ArrayListUnmanaged(PositionEntry) = .{};
|
||||||
defer constructiveList.deinit(main.globalAllocator);
|
|
||||||
defer {
|
defer {
|
||||||
for(&neighborLists) |*list| {
|
for(&neighborLists) |*list| {
|
||||||
list.deinit(main.globalAllocator);
|
list.deinit(main.globalAllocator);
|
||||||
@ -111,8 +121,9 @@ pub const ChannelChunk = struct {
|
|||||||
while(lightQueue.dequeue()) |entry| {
|
while(lightQueue.dequeue()) |entry| {
|
||||||
const index = chunk.getIndex(entry.x, entry.y, entry.z);
|
const index = chunk.getIndex(entry.x, entry.y, entry.z);
|
||||||
if(entry.value != self.data[index].load(.Unordered)) {
|
if(entry.value != self.data[index].load(.Unordered)) {
|
||||||
try constructiveList.append(main.globalAllocator, .{.x = entry.x, .y = entry.y, .z = entry.z, .value = self.data[index].load(.Unordered)});
|
if(self.data[index].load(.Unordered) != 0) {
|
||||||
self.data[index].store(0, .Unordered);
|
try constructiveList.append(main.globalAllocator, .{.x = entry.x, .y = entry.y, .z = entry.z});
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
self.data[index].store(0, .Unordered);
|
self.data[index].store(0, .Unordered);
|
||||||
@ -144,14 +155,13 @@ pub const ChannelChunk = struct {
|
|||||||
for(0..6) |neighbor| {
|
for(0..6) |neighbor| {
|
||||||
if(neighborLists[neighbor].items.len == 0) continue;
|
if(neighborLists[neighbor].items.len == 0) continue;
|
||||||
const neighborMesh = main.renderer.RenderStructure.getNeighborAndIncreaseRefCount(self.ch.pos, self.ch.pos.voxelSize, @intCast(neighbor)) orelse continue;
|
const neighborMesh = main.renderer.RenderStructure.getNeighborAndIncreaseRefCount(self.ch.pos, self.ch.pos.voxelSize, @intCast(neighbor)) orelse continue;
|
||||||
defer neighborMesh.decreaseRefCount();
|
try constructiveEntries.append(main.globalAllocator, .{
|
||||||
try neighborMesh.lightingData[@intFromEnum(self.channel)].propagateDestructiveFromNeighbor(neighborLists[neighbor].items);
|
.mesh = neighborMesh,
|
||||||
|
.entries = try neighborMesh.lightingData[@intFromEnum(self.channel)].propagateDestructiveFromNeighbor(neighborLists[neighbor].items, constructiveEntries),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for(constructiveList.items) |entry| {
|
return constructiveList;
|
||||||
try lightQueue.enqueue(entry);
|
|
||||||
}
|
|
||||||
try self.propagateDirect(lightQueue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn propagateFromNeighbor(self: *ChannelChunk, lights: []const Entry) std.mem.Allocator.Error!void {
|
fn propagateFromNeighbor(self: *ChannelChunk, lights: []const Entry) std.mem.Allocator.Error!void {
|
||||||
@ -168,7 +178,7 @@ pub const ChannelChunk = struct {
|
|||||||
try self.propagateDirect(&lightQueue);
|
try self.propagateDirect(&lightQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn propagateDestructiveFromNeighbor(self: *ChannelChunk, lights: []const Entry) std.mem.Allocator.Error!void {
|
fn propagateDestructiveFromNeighbor(self: *ChannelChunk, lights: []const Entry, constructiveEntries: *std.ArrayListUnmanaged(ChunkEntries)) std.mem.Allocator.Error!std.ArrayListUnmanaged(PositionEntry) {
|
||||||
var lightQueue = try main.utils.CircularBufferQueue(Entry).init(main.globalAllocator, 1 << 8);
|
var lightQueue = try main.utils.CircularBufferQueue(Entry).init(main.globalAllocator, 1 << 8);
|
||||||
defer lightQueue.deinit();
|
defer lightQueue.deinit();
|
||||||
for(lights) |entry| {
|
for(lights) |entry| {
|
||||||
@ -179,7 +189,7 @@ pub const ChannelChunk = struct {
|
|||||||
result.value -|= absorption;
|
result.value -|= absorption;
|
||||||
if(result.value != 0) try lightQueue.enqueue(result);
|
if(result.value != 0) try lightQueue.enqueue(result);
|
||||||
}
|
}
|
||||||
try self.propagateDestructive(&lightQueue);
|
return try self.propagateDestructive(&lightQueue, constructiveEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn propagateLights(self: *ChannelChunk, lights: []const [3]u8, comptime checkNeighbors: bool) std.mem.Allocator.Error!void {
|
pub fn propagateLights(self: *ChannelChunk, lights: []const [3]u8, comptime checkNeighbors: bool) std.mem.Allocator.Error!void {
|
||||||
@ -247,6 +257,26 @@ pub const ChannelChunk = struct {
|
|||||||
const index = chunk.getIndex(pos[0], pos[1], pos[2]);
|
const index = chunk.getIndex(pos[0], pos[1], pos[2]);
|
||||||
try lightQueue.enqueue(.{.x = @intCast(pos[0]), .y = @intCast(pos[1]), .z = @intCast(pos[2]), .value = self.data[index].load(.Unordered)});
|
try lightQueue.enqueue(.{.x = @intCast(pos[0]), .y = @intCast(pos[1]), .z = @intCast(pos[2]), .value = self.data[index].load(.Unordered)});
|
||||||
}
|
}
|
||||||
try self.propagateDestructive(&lightQueue);
|
var constructiveEntries: std.ArrayListUnmanaged(ChunkEntries) = .{};
|
||||||
|
defer constructiveEntries.deinit(main.globalAllocator);
|
||||||
|
try constructiveEntries.append(main.globalAllocator, .{
|
||||||
|
.mesh = null,
|
||||||
|
.entries = try self.propagateDestructive(&lightQueue, &constructiveEntries),
|
||||||
|
});
|
||||||
|
for(constructiveEntries.items) |entries| {
|
||||||
|
const mesh = entries.mesh;
|
||||||
|
defer if(mesh) |_mesh| _mesh.decreaseRefCount();
|
||||||
|
var entryList = entries.entries;
|
||||||
|
defer entryList.deinit(main.globalAllocator);
|
||||||
|
const channelChunk = if(mesh) |_mesh| &_mesh.lightingData[@intFromEnum(self.channel)] else self;
|
||||||
|
for(entryList.items) |entry| {
|
||||||
|
const index = chunk.getIndex(entry.x, entry.y, entry.z);
|
||||||
|
const value = channelChunk.data[index].load(.Unordered);
|
||||||
|
if(value == 0) continue;
|
||||||
|
channelChunk.data[index].store(0, .Unordered);
|
||||||
|
try lightQueue.enqueue(.{.x = entry.x, .y = entry.y, .z = entry.z, .value = value});
|
||||||
|
}
|
||||||
|
try channelChunk.propagateDirect(&lightQueue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user