mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 19:28:49 -04:00
parent
d40da846a0
commit
04f9bae91c
@ -717,12 +717,8 @@ pub const ChunkMesh = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scheduleLightRefreshAndDecreaseRefCount(self: *ChunkMesh) void {
|
pub fn scheduleLightRefreshAndDecreaseRefCount1(self: *ChunkMesh) void {
|
||||||
if(!self.needsLightRefresh.swap(true, .acq_rel)) {
|
LightRefreshTask.scheduleAndDecreaseRefCount(self);
|
||||||
LightRefreshTask.scheduleAndDecreaseRefCount(self);
|
|
||||||
} else {
|
|
||||||
self.decreaseRefCount();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const LightRefreshTask = struct {
|
const LightRefreshTask = struct {
|
||||||
mesh: *ChunkMesh,
|
mesh: *ChunkMesh,
|
||||||
@ -783,7 +779,7 @@ pub const ChunkMesh = struct {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initLight(self: *ChunkMesh) void {
|
fn initLight(self: *ChunkMesh, lightRefreshList: *main.List(*ChunkMesh)) void {
|
||||||
self.mutex.lock();
|
self.mutex.lock();
|
||||||
var lightEmittingBlocks = main.List([3]u8).init(main.stackAllocator);
|
var lightEmittingBlocks = main.List([3]u8).init(main.stackAllocator);
|
||||||
defer lightEmittingBlocks.deinit();
|
defer lightEmittingBlocks.deinit();
|
||||||
@ -799,7 +795,7 @@ pub const ChunkMesh = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.mutex.unlock();
|
self.mutex.unlock();
|
||||||
self.lightingData[0].propagateLights(lightEmittingBlocks.items, true);
|
self.lightingData[0].propagateLights(lightEmittingBlocks.items, true, lightRefreshList);
|
||||||
sunLight: {
|
sunLight: {
|
||||||
var allSun: bool = self.chunk.data.paletteLength == 1 and self.chunk.data.palette[0].typ == 0;
|
var allSun: bool = self.chunk.data.paletteLength == 1 and self.chunk.data.palette[0].typ == 0;
|
||||||
var sunStarters: [chunk.chunkSize*chunk.chunkSize][3]u8 = undefined;
|
var sunStarters: [chunk.chunkSize*chunk.chunkSize][3]u8 = undefined;
|
||||||
@ -821,9 +817,9 @@ pub const ChunkMesh = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(allSun) {
|
if(allSun) {
|
||||||
self.lightingData[1].propagateUniformSun();
|
self.lightingData[1].propagateUniformSun(lightRefreshList);
|
||||||
} else {
|
} else {
|
||||||
self.lightingData[1].propagateLights(sunStarters[0..index], true);
|
self.lightingData[1].propagateLights(sunStarters[0..index], true, lightRefreshList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -835,7 +831,9 @@ pub const ChunkMesh = struct {
|
|||||||
self.mutex.unlock();
|
self.mutex.unlock();
|
||||||
try mesh_storage.addMeshToStorage(self);
|
try mesh_storage.addMeshToStorage(self);
|
||||||
|
|
||||||
self.initLight();
|
var lightRefreshList = main.List(*ChunkMesh).init(main.stackAllocator);
|
||||||
|
defer lightRefreshList.deinit();
|
||||||
|
self.initLight(&lightRefreshList);
|
||||||
|
|
||||||
self.mutex.lock();
|
self.mutex.lock();
|
||||||
self.finishedLighting = true;
|
self.finishedLighting = true;
|
||||||
@ -858,20 +856,28 @@ pub const ChunkMesh = struct {
|
|||||||
const shiftSelf: u5 = @intCast(((dx + 1)*3 + dy + 1)*3 + dz + 1);
|
const shiftSelf: u5 = @intCast(((dx + 1)*3 + dy + 1)*3 + dz + 1);
|
||||||
const shiftOther: u5 = @intCast(((-dx + 1)*3 + -dy + 1)*3 + -dz + 1);
|
const shiftOther: u5 = @intCast(((-dx + 1)*3 + -dy + 1)*3 + -dz + 1);
|
||||||
if(neighborMesh.litNeighbors.fetchOr(@as(u27, 1) << shiftOther, .monotonic) ^ @as(u27, 1) << shiftOther == ~@as(u27, 0)) { // Trigger mesh creation for neighbor
|
if(neighborMesh.litNeighbors.fetchOr(@as(u27, 1) << shiftOther, .monotonic) ^ @as(u27, 1) << shiftOther == ~@as(u27, 0)) { // Trigger mesh creation for neighbor
|
||||||
neighborMesh.generateMesh();
|
neighborMesh.generateMesh(&lightRefreshList);
|
||||||
}
|
}
|
||||||
neighborMesh.mutex.lock();
|
neighborMesh.mutex.lock();
|
||||||
const neighborFinishedLighting = neighborMesh.finishedLighting;
|
const neighborFinishedLighting = neighborMesh.finishedLighting;
|
||||||
neighborMesh.mutex.unlock();
|
neighborMesh.mutex.unlock();
|
||||||
if(neighborFinishedLighting and self.litNeighbors.fetchOr(@as(u27, 1) << shiftSelf, .monotonic) ^ @as(u27, 1) << shiftSelf == ~@as(u27, 0)) {
|
if(neighborFinishedLighting and self.litNeighbors.fetchOr(@as(u27, 1) << shiftSelf, .monotonic) ^ @as(u27, 1) << shiftSelf == ~@as(u27, 0)) {
|
||||||
self.generateMesh();
|
self.generateMesh(&lightRefreshList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(lightRefreshList.items) |other| {
|
||||||
|
if(other.needsLightRefresh.load(.unordered)) {
|
||||||
|
other.scheduleLightRefreshAndDecreaseRefCount1();
|
||||||
|
} else {
|
||||||
|
other.decreaseRefCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generateMesh(self: *ChunkMesh) void {
|
pub fn generateMesh(self: *ChunkMesh, lightRefreshList: *main.List(*ChunkMesh)) void {
|
||||||
var canSeeNeighbor: [6][chunk.chunkSize][chunk.chunkSize]u32 = undefined;
|
var canSeeNeighbor: [6][chunk.chunkSize][chunk.chunkSize]u32 = undefined;
|
||||||
@memset(std.mem.asBytes(&canSeeNeighbor), 0);
|
@memset(std.mem.asBytes(&canSeeNeighbor), 0);
|
||||||
var canSeeAllNeighbors: [chunk.chunkSize][chunk.chunkSize]u32 = undefined;
|
var canSeeAllNeighbors: [chunk.chunkSize][chunk.chunkSize]u32 = undefined;
|
||||||
@ -1108,23 +1114,32 @@ pub const ChunkMesh = struct {
|
|||||||
}
|
}
|
||||||
self.mutex.unlock();
|
self.mutex.unlock();
|
||||||
|
|
||||||
self.finishNeighbors();
|
self.finishNeighbors(lightRefreshList);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn updateBlockLight(self: *ChunkMesh, x: u5, y: u5, z: u5, newBlock: Block) void {
|
fn updateBlockLight(self: *ChunkMesh, x: u5, y: u5, z: u5, newBlock: Block, lightRefreshList: *main.List(*ChunkMesh)) void {
|
||||||
for(self.lightingData[0..]) |lightingData| {
|
for(self.lightingData[0..]) |lightingData| {
|
||||||
lightingData.propagateLightsDestructive(&.{.{x, y, z}});
|
lightingData.propagateLightsDestructive(&.{.{x, y, z}}, lightRefreshList);
|
||||||
}
|
}
|
||||||
if(newBlock.light() != 0) {
|
if(newBlock.light() != 0) {
|
||||||
self.lightingData[0].propagateLights(&.{.{x, y, z}}, false);
|
self.lightingData[0].propagateLights(&.{.{x, y, z}}, false, lightRefreshList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
std.log.err("Block: {} {} {}", .{_x, _y, _z});
|
||||||
|
var lightRefreshList = main.List(*ChunkMesh).init(main.stackAllocator);
|
||||||
|
defer lightRefreshList.deinit();
|
||||||
const x: u5 = @intCast(_x & chunk.chunkMask);
|
const x: u5 = @intCast(_x & chunk.chunkMask);
|
||||||
const y: u5 = @intCast(_y & chunk.chunkMask);
|
const y: u5 = @intCast(_y & chunk.chunkMask);
|
||||||
const z: u5 = @intCast(_z & chunk.chunkMask);
|
const z: u5 = @intCast(_z & chunk.chunkMask);
|
||||||
var newBlock = _newBlock;
|
var newBlock = _newBlock;
|
||||||
|
self.mutex.lock();
|
||||||
|
if(std.meta.eql(self.chunk.data.getValue(chunk.getIndex(x, y, z)), newBlock)) {
|
||||||
|
self.mutex.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.mutex.unlock();
|
||||||
var neighborBlocks: [6]Block = undefined;
|
var neighborBlocks: [6]Block = undefined;
|
||||||
@memset(&neighborBlocks, .{.typ = 0, .data = 0});
|
@memset(&neighborBlocks, .{.typ = 0, .data = 0});
|
||||||
for(chunk.Neighbors.iterable) |neighbor| {
|
for(chunk.Neighbors.iterable) |neighbor| {
|
||||||
@ -1143,8 +1158,8 @@ 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.updateBlockLight(@intCast(nx & chunk.chunkMask), @intCast(ny & chunk.chunkMask), @intCast(nz & chunk.chunkMask), neighborBlock, &lightRefreshList);
|
||||||
neighborChunkMesh.generateMesh();
|
neighborChunkMesh.generateMesh(&lightRefreshList);
|
||||||
neighborChunkMesh.mutex.lock();
|
neighborChunkMesh.mutex.lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1157,7 +1172,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.updateBlockLight(@intCast(nx & chunk.chunkMask), @intCast(ny & chunk.chunkMask), @intCast(nz & chunk.chunkMask), neighborBlock, &lightRefreshList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.mutex.unlock();
|
self.mutex.unlock();
|
||||||
@ -1172,7 +1187,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();
|
||||||
self.updateBlockLight(x, y, z, newBlock);
|
self.updateBlockLight(x, y, z, newBlock, &lightRefreshList);
|
||||||
self.mutex.lock();
|
self.mutex.lock();
|
||||||
defer self.mutex.unlock();
|
defer self.mutex.unlock();
|
||||||
// Update neighbor chunks:
|
// Update neighbor chunks:
|
||||||
@ -1200,8 +1215,15 @@ pub const ChunkMesh = struct {
|
|||||||
self.opaqueMesh.coreFaces.clearRetainingCapacity();
|
self.opaqueMesh.coreFaces.clearRetainingCapacity();
|
||||||
self.transparentMesh.coreFaces.clearRetainingCapacity();
|
self.transparentMesh.coreFaces.clearRetainingCapacity();
|
||||||
self.mutex.unlock();
|
self.mutex.unlock();
|
||||||
self.generateMesh(); // TODO: Batch mesh updates instead of applying them for each block changes.
|
self.generateMesh(&lightRefreshList); // TODO: Batch mesh updates instead of applying them for each block changes.
|
||||||
self.mutex.lock();
|
self.mutex.lock();
|
||||||
|
for(lightRefreshList.items) |other| {
|
||||||
|
if(other.needsLightRefresh.load(.unordered)) {
|
||||||
|
other.scheduleLightRefreshAndDecreaseRefCount1();
|
||||||
|
} else {
|
||||||
|
other.decreaseRefCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
self.uploadData();
|
self.uploadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1241,7 +1263,7 @@ pub const ChunkMesh = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finishNeighbors(self: *ChunkMesh) void {
|
fn finishNeighbors(self: *ChunkMesh, lightRefreshList: *main.List(*ChunkMesh)) void {
|
||||||
for(chunk.Neighbors.iterable) |neighbor| {
|
for(chunk.Neighbors.iterable) |neighbor| {
|
||||||
const nullNeighborMesh = mesh_storage.getNeighborAndIncreaseRefCount(self.pos, self.pos.voxelSize, neighbor);
|
const nullNeighborMesh = mesh_storage.getNeighborAndIncreaseRefCount(self.pos, self.pos.voxelSize, neighbor);
|
||||||
if(nullNeighborMesh) |neighborMesh| sameLodBlock: {
|
if(nullNeighborMesh) |neighborMesh| sameLodBlock: {
|
||||||
@ -1303,10 +1325,9 @@ pub const ChunkMesh = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ = neighborMesh.needsLightRefresh.swap(false, .acq_rel);
|
_ = neighborMesh.needsLightRefresh.store(true, .release);
|
||||||
neighborMesh.finishData();
|
|
||||||
neighborMesh.increaseRefCount();
|
neighborMesh.increaseRefCount();
|
||||||
mesh_storage.addToUpdateListAndDecreaseRefCount(neighborMesh);
|
lightRefreshList.append(neighborMesh);
|
||||||
} else {
|
} else {
|
||||||
self.mutex.lock();
|
self.mutex.lock();
|
||||||
defer self.mutex.unlock();
|
defer self.mutex.unlock();
|
||||||
|
@ -103,7 +103,7 @@ pub const ChannelChunk = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn propagateDirect(self: *ChannelChunk, lightQueue: *main.utils.CircularBufferQueue(Entry)) void {
|
fn propagateDirect(self: *ChannelChunk, lightQueue: *main.utils.CircularBufferQueue(Entry), lightRefreshList: *main.List(*chunk_meshing.ChunkMesh)) void {
|
||||||
var neighborLists: [6]main.ListUnmanaged(Entry) = .{.{}} ** 6;
|
var neighborLists: [6]main.ListUnmanaged(Entry) = .{.{}} ** 6;
|
||||||
defer {
|
defer {
|
||||||
for(&neighborLists) |*list| {
|
for(&neighborLists) |*list| {
|
||||||
@ -146,19 +146,26 @@ pub const ChannelChunk = struct {
|
|||||||
}
|
}
|
||||||
self.data.optimizeLayout();
|
self.data.optimizeLayout();
|
||||||
self.lock.unlockWrite();
|
self.lock.unlockWrite();
|
||||||
if(mesh_storage.getMeshAndIncreaseRefCount(self.ch.pos)) |mesh| {
|
if(mesh_storage.getMeshAndIncreaseRefCount(self.ch.pos)) |mesh| outer: {
|
||||||
mesh.scheduleLightRefreshAndDecreaseRefCount();
|
for(lightRefreshList.items) |other| {
|
||||||
|
if(mesh == other) {
|
||||||
|
mesh.decreaseRefCount();
|
||||||
|
break :outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mesh.needsLightRefresh.store(true, .release);
|
||||||
|
lightRefreshList.append(mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(0..6) |neighbor| {
|
for(0..6) |neighbor| {
|
||||||
if(neighborLists[neighbor].items.len == 0) continue;
|
if(neighborLists[neighbor].items.len == 0) continue;
|
||||||
const neighborMesh = mesh_storage.getNeighborAndIncreaseRefCount(self.ch.pos, self.ch.pos.voxelSize, @intCast(neighbor)) orelse continue;
|
const neighborMesh = mesh_storage.getNeighborAndIncreaseRefCount(self.ch.pos, self.ch.pos.voxelSize, @intCast(neighbor)) orelse continue;
|
||||||
defer neighborMesh.decreaseRefCount();
|
defer neighborMesh.decreaseRefCount();
|
||||||
neighborMesh.lightingData[@intFromBool(self.isSun)].propagateFromNeighbor(lightQueue, neighborLists[neighbor].items);
|
neighborMesh.lightingData[@intFromBool(self.isSun)].propagateFromNeighbor(lightQueue, neighborLists[neighbor].items, lightRefreshList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn propagateDestructive(self: *ChannelChunk, lightQueue: *main.utils.CircularBufferQueue(Entry), constructiveEntries: *main.ListUnmanaged(ChunkEntries), isFirstBlock: bool) main.ListUnmanaged(PositionEntry) {
|
fn propagateDestructive(self: *ChannelChunk, lightQueue: *main.utils.CircularBufferQueue(Entry), constructiveEntries: *main.ListUnmanaged(ChunkEntries), isFirstBlock: bool, lightRefreshList: *main.List(*chunk_meshing.ChunkMesh)) main.ListUnmanaged(PositionEntry) {
|
||||||
var neighborLists: [6]main.ListUnmanaged(Entry) = .{.{}} ** 6;
|
var neighborLists: [6]main.ListUnmanaged(Entry) = .{.{}} ** 6;
|
||||||
var constructiveList: main.ListUnmanaged(PositionEntry) = .{};
|
var constructiveList: main.ListUnmanaged(PositionEntry) = .{};
|
||||||
defer {
|
defer {
|
||||||
@ -224,8 +231,15 @@ pub const ChannelChunk = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.lock.unlockWrite();
|
self.lock.unlockWrite();
|
||||||
if(mesh_storage.getMeshAndIncreaseRefCount(self.ch.pos)) |mesh| {
|
if(mesh_storage.getMeshAndIncreaseRefCount(self.ch.pos)) |mesh| outer: {
|
||||||
mesh.scheduleLightRefreshAndDecreaseRefCount();
|
for(lightRefreshList.items) |other| {
|
||||||
|
if(mesh == other) {
|
||||||
|
mesh.decreaseRefCount();
|
||||||
|
break :outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mesh.needsLightRefresh.store(true, .release);
|
||||||
|
lightRefreshList.append(mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(0..6) |neighbor| {
|
for(0..6) |neighbor| {
|
||||||
@ -233,14 +247,14 @@ pub const ChannelChunk = struct {
|
|||||||
const neighborMesh = mesh_storage.getNeighborAndIncreaseRefCount(self.ch.pos, self.ch.pos.voxelSize, @intCast(neighbor)) orelse continue;
|
const neighborMesh = mesh_storage.getNeighborAndIncreaseRefCount(self.ch.pos, self.ch.pos.voxelSize, @intCast(neighbor)) orelse continue;
|
||||||
constructiveEntries.append(main.stackAllocator, .{
|
constructiveEntries.append(main.stackAllocator, .{
|
||||||
.mesh = neighborMesh,
|
.mesh = neighborMesh,
|
||||||
.entries = neighborMesh.lightingData[@intFromBool(self.isSun)].propagateDestructiveFromNeighbor(lightQueue, neighborLists[neighbor].items, constructiveEntries),
|
.entries = neighborMesh.lightingData[@intFromBool(self.isSun)].propagateDestructiveFromNeighbor(lightQueue, neighborLists[neighbor].items, constructiveEntries, lightRefreshList),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return constructiveList;
|
return constructiveList;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn propagateFromNeighbor(self: *ChannelChunk, lightQueue: *main.utils.CircularBufferQueue(Entry), lights: []const Entry) void {
|
fn propagateFromNeighbor(self: *ChannelChunk, lightQueue: *main.utils.CircularBufferQueue(Entry), lights: []const Entry, lightRefreshList: *main.List(*chunk_meshing.ChunkMesh)) void {
|
||||||
std.debug.assert(lightQueue.startIndex == lightQueue.endIndex);
|
std.debug.assert(lightQueue.startIndex == lightQueue.endIndex);
|
||||||
for(lights) |entry| {
|
for(lights) |entry| {
|
||||||
const index = chunk.getIndex(entry.x, entry.y, entry.z);
|
const index = chunk.getIndex(entry.x, entry.y, entry.z);
|
||||||
@ -248,10 +262,10 @@ pub const ChannelChunk = struct {
|
|||||||
calculateIncomingOcclusion(&result.value, self.ch.data.getValue(index), self.ch.pos.voxelSize, entry.sourceDir);
|
calculateIncomingOcclusion(&result.value, self.ch.data.getValue(index), self.ch.pos.voxelSize, entry.sourceDir);
|
||||||
if(result.value[0] != 0 or result.value[1] != 0 or result.value[2] != 0) lightQueue.enqueue(result);
|
if(result.value[0] != 0 or result.value[1] != 0 or result.value[2] != 0) lightQueue.enqueue(result);
|
||||||
}
|
}
|
||||||
self.propagateDirect(lightQueue);
|
self.propagateDirect(lightQueue, lightRefreshList);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn propagateDestructiveFromNeighbor(self: *ChannelChunk, lightQueue: *main.utils.CircularBufferQueue(Entry), lights: []const Entry, constructiveEntries: *main.ListUnmanaged(ChunkEntries)) main.ListUnmanaged(PositionEntry) {
|
fn propagateDestructiveFromNeighbor(self: *ChannelChunk, lightQueue: *main.utils.CircularBufferQueue(Entry), lights: []const Entry, constructiveEntries: *main.ListUnmanaged(ChunkEntries), lightRefreshList: *main.List(*chunk_meshing.ChunkMesh)) main.ListUnmanaged(PositionEntry) {
|
||||||
std.debug.assert(lightQueue.startIndex == lightQueue.endIndex);
|
std.debug.assert(lightQueue.startIndex == lightQueue.endIndex);
|
||||||
for(lights) |entry| {
|
for(lights) |entry| {
|
||||||
const index = chunk.getIndex(entry.x, entry.y, entry.z);
|
const index = chunk.getIndex(entry.x, entry.y, entry.z);
|
||||||
@ -259,10 +273,10 @@ pub const ChannelChunk = struct {
|
|||||||
calculateIncomingOcclusion(&result.value, self.ch.data.getValue(index), self.ch.pos.voxelSize, entry.sourceDir);
|
calculateIncomingOcclusion(&result.value, self.ch.data.getValue(index), self.ch.pos.voxelSize, entry.sourceDir);
|
||||||
lightQueue.enqueue(result);
|
lightQueue.enqueue(result);
|
||||||
}
|
}
|
||||||
return self.propagateDestructive(lightQueue, constructiveEntries, false);
|
return self.propagateDestructive(lightQueue, constructiveEntries, false, lightRefreshList);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn propagateLights(self: *ChannelChunk, lights: []const [3]u8, comptime checkNeighbors: bool) void {
|
pub fn propagateLights(self: *ChannelChunk, lights: []const [3]u8, comptime checkNeighbors: bool, lightRefreshList: *main.List(*chunk_meshing.ChunkMesh)) void {
|
||||||
var lightQueue = main.utils.CircularBufferQueue(Entry).init(main.stackAllocator, 1 << 12);
|
var lightQueue = main.utils.CircularBufferQueue(Entry).init(main.stackAllocator, 1 << 12);
|
||||||
defer lightQueue.deinit();
|
defer lightQueue.deinit();
|
||||||
for(lights) |pos| {
|
for(lights) |pos| {
|
||||||
@ -320,10 +334,10 @@ pub const ChannelChunk = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.propagateDirect(&lightQueue);
|
self.propagateDirect(&lightQueue, lightRefreshList);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn propagateUniformSun(self: *ChannelChunk) void {
|
pub fn propagateUniformSun(self: *ChannelChunk, lightRefreshList: *main.List(*chunk_meshing.ChunkMesh)) void {
|
||||||
std.debug.assert(self.isSun);
|
std.debug.assert(self.isSun);
|
||||||
self.lock.lockWrite();
|
self.lock.lockWrite();
|
||||||
if(self.data.paletteLength != 1) {
|
if(self.data.paletteLength != 1) {
|
||||||
@ -367,11 +381,11 @@ pub const ChannelChunk = struct {
|
|||||||
entry.sourceDir = neighbor ^ 1;
|
entry.sourceDir = neighbor ^ 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
neighborMesh.lightingData[1].propagateFromNeighbor(&lightQueue, &list);
|
neighborMesh.lightingData[1].propagateFromNeighbor(&lightQueue, &list, lightRefreshList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn propagateLightsDestructive(self: *ChannelChunk, lights: []const [3]u8) void {
|
pub fn propagateLightsDestructive(self: *ChannelChunk, lights: []const [3]u8, lightRefreshList: *main.List(*chunk_meshing.ChunkMesh)) void {
|
||||||
var lightQueue = main.utils.CircularBufferQueue(Entry).init(main.stackAllocator, 1 << 12);
|
var lightQueue = main.utils.CircularBufferQueue(Entry).init(main.stackAllocator, 1 << 12);
|
||||||
defer lightQueue.deinit();
|
defer lightQueue.deinit();
|
||||||
self.lock.lockRead();
|
self.lock.lockRead();
|
||||||
@ -384,7 +398,7 @@ pub const ChannelChunk = struct {
|
|||||||
defer constructiveEntries.deinit(main.stackAllocator);
|
defer constructiveEntries.deinit(main.stackAllocator);
|
||||||
constructiveEntries.append(main.stackAllocator, .{
|
constructiveEntries.append(main.stackAllocator, .{
|
||||||
.mesh = null,
|
.mesh = null,
|
||||||
.entries = self.propagateDestructive(&lightQueue, &constructiveEntries, true),
|
.entries = self.propagateDestructive(&lightQueue, &constructiveEntries, true, lightRefreshList),
|
||||||
});
|
});
|
||||||
for(constructiveEntries.items) |entries| {
|
for(constructiveEntries.items) |entries| {
|
||||||
const mesh = entries.mesh;
|
const mesh = entries.mesh;
|
||||||
@ -401,7 +415,7 @@ pub const ChannelChunk = struct {
|
|||||||
lightQueue.enqueue(.{.x = entry.x, .y = entry.y, .z = entry.z, .value = value, .sourceDir = 6, .activeValue = 0b111});
|
lightQueue.enqueue(.{.x = entry.x, .y = entry.y, .z = entry.z, .value = value, .sourceDir = 6, .activeValue = 0b111});
|
||||||
}
|
}
|
||||||
channelChunk.lock.unlockWrite();
|
channelChunk.lock.unlockWrite();
|
||||||
channelChunk.propagateDirect(&lightQueue);
|
channelChunk.propagateDirect(&lightQueue, lightRefreshList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user