mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-09-09 12:16:24 -04:00
Cleanup some code and fix a data race. Mesh generation should also be a bit faster now.
This commit is contained in:
parent
d37589397c
commit
62d4920869
@ -567,14 +567,10 @@ pub const ChunkMesh = struct {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn regenerateMainMesh(self: *ChunkMesh) !void {
|
fn initLight(self: *ChunkMesh) !void {
|
||||||
try mesh_storage.addMeshToStorage(self);
|
|
||||||
self.mutex.lock();
|
self.mutex.lock();
|
||||||
self.opaqueMesh.reset();
|
|
||||||
self.transparentMesh.reset();
|
|
||||||
var lightEmittingBlocks = std.ArrayList([3]u8).init(main.globalAllocator);
|
var lightEmittingBlocks = std.ArrayList([3]u8).init(main.globalAllocator);
|
||||||
defer lightEmittingBlocks.deinit();
|
defer lightEmittingBlocks.deinit();
|
||||||
var n: u32 = 0;
|
|
||||||
var x: u8 = 0;
|
var x: u8 = 0;
|
||||||
while(x < chunk.chunkSize): (x += 1) {
|
while(x < chunk.chunkSize): (x += 1) {
|
||||||
var y: u8 = 0;
|
var y: u8 = 0;
|
||||||
@ -583,6 +579,54 @@ pub const ChunkMesh = struct {
|
|||||||
while(z < chunk.chunkSize): (z += 1) {
|
while(z < chunk.chunkSize): (z += 1) {
|
||||||
const block = (&self.chunk.blocks)[chunk.getIndex(x, y, z)]; // ← a temporary fix to a compiler performance bug. TODO: check if this was fixed.
|
const block = (&self.chunk.blocks)[chunk.getIndex(x, y, z)]; // ← a temporary fix to a compiler performance bug. TODO: check if this was fixed.
|
||||||
if(block.light() != 0) try lightEmittingBlocks.append(.{x, y, z});
|
if(block.light() != 0) try lightEmittingBlocks.append(.{x, y, z});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.mutex.unlock();
|
||||||
|
for(self.lightingData[3..]) |*lightingData| {
|
||||||
|
try lightingData.propagateLights(lightEmittingBlocks.items, true);
|
||||||
|
}
|
||||||
|
sunLight: {
|
||||||
|
var sunStarters: [chunk.chunkSize*chunk.chunkSize][3]u8 = undefined;
|
||||||
|
var index: usize = 0;
|
||||||
|
const lightStartMap = mesh_storage.getLightMapPieceAndIncreaseRefCount(self.pos.wx, self.pos.wz, self.pos.voxelSize) orelse break :sunLight;
|
||||||
|
defer lightStartMap.decreaseRefCount();
|
||||||
|
x = 0;
|
||||||
|
while(x < chunk.chunkSize): (x += 1) {
|
||||||
|
var z: u8 = 0;
|
||||||
|
while(z < chunk.chunkSize): (z += 1) {
|
||||||
|
const startHeight: i32 = lightStartMap.getHeight(self.pos.wx + x*self.pos.voxelSize, self.pos.wz + z*self.pos.voxelSize);
|
||||||
|
const relHeight = startHeight -% self.pos.wy;
|
||||||
|
if(relHeight < chunk.chunkSize*self.pos.voxelSize) {
|
||||||
|
sunStarters[index] = .{x, chunk.chunkSize-1, z};
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(self.lightingData[0..3]) |*lightingData| {
|
||||||
|
try lightingData.propagateLights(sunStarters[0..index], true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn regenerateMainMesh(self: *ChunkMesh) !void {
|
||||||
|
self.mutex.lock();
|
||||||
|
self.opaqueMesh.reset();
|
||||||
|
self.transparentMesh.reset();
|
||||||
|
self.mutex.unlock();
|
||||||
|
try mesh_storage.addMeshToStorage(self);
|
||||||
|
|
||||||
|
try self.initLight();
|
||||||
|
|
||||||
|
self.mutex.lock();
|
||||||
|
var n: u32 = 0;
|
||||||
|
var x: u8 = 0;
|
||||||
|
while(x < chunk.chunkSize): (x += 1) {
|
||||||
|
var y: u8 = 0;
|
||||||
|
while(y < chunk.chunkSize): (y += 1) {
|
||||||
|
var z: u8 = 0;
|
||||||
|
while(z < chunk.chunkSize): (z += 1) {
|
||||||
|
const block = (&self.chunk.blocks)[chunk.getIndex(x, y, z)]; // ← a temporary fix to a compiler performance bug. TODO: check if this was fixed.
|
||||||
if(block.typ == 0) continue;
|
if(block.typ == 0) continue;
|
||||||
// Check all neighbors:
|
// Check all neighbors:
|
||||||
for(chunk.Neighbors.iterable) |i| {
|
for(chunk.Neighbors.iterable) |i| {
|
||||||
@ -620,33 +664,8 @@ pub const ChunkMesh = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.mutex.unlock();
|
self.mutex.unlock();
|
||||||
for(self.lightingData[3..]) |*lightingData| {
|
|
||||||
try lightingData.propagateLights(lightEmittingBlocks.items, true);
|
|
||||||
}
|
|
||||||
sunLight: {
|
|
||||||
var sunStarters: [chunk.chunkSize*chunk.chunkSize][3]u8 = undefined;
|
|
||||||
var index: usize = 0;
|
|
||||||
const lightStartMap = mesh_storage.getLightMapPieceAndIncreaseRefCount(self.pos.wx, self.pos.wz, self.pos.voxelSize) orelse break :sunLight;
|
|
||||||
defer lightStartMap.decreaseRefCount();
|
|
||||||
x = 0;
|
|
||||||
while(x < chunk.chunkSize): (x += 1) {
|
|
||||||
var z: u8 = 0;
|
|
||||||
while(z < chunk.chunkSize): (z += 1) {
|
|
||||||
const startHeight: i32 = lightStartMap.getHeight(self.pos.wx + x*self.pos.voxelSize, self.pos.wz + z*self.pos.voxelSize);
|
|
||||||
const relHeight = startHeight -% self.pos.wy;
|
|
||||||
if(relHeight < chunk.chunkSize*self.pos.voxelSize) {
|
|
||||||
sunStarters[index] = .{x, chunk.chunkSize-1, z};
|
|
||||||
index += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(self.lightingData[0..3]) |*lightingData| {
|
|
||||||
try lightingData.propagateLights(sunStarters[0..index], true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Sunlight propagation
|
try self.finishNeighbors();
|
||||||
try self.finishNeighbors(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn addFace(self: *ChunkMesh, faceData: FaceData, fromNeighborChunk: ?u3, transparent: bool) !void {
|
fn addFace(self: *ChunkMesh, faceData: FaceData, fromNeighborChunk: ?u3, transparent: bool) !void {
|
||||||
@ -826,12 +845,11 @@ pub const ChunkMesh = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finishNeighbors(self: *ChunkMesh, comptime inRenderThread: bool) !void {
|
fn finishNeighbors(self: *ChunkMesh) !void {
|
||||||
const getNeighborMesh: fn(chunk.ChunkPosition, u31, u3) ?*ChunkMesh = if(inRenderThread) mesh_storage.getNeighborFromRenderThread else mesh_storage.getNeighborAndIncreaseRefCount;
|
|
||||||
for(chunk.Neighbors.iterable) |neighbor| {
|
for(chunk.Neighbors.iterable) |neighbor| {
|
||||||
const nullNeighborMesh = getNeighborMesh(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: {
|
||||||
defer if(!inRenderThread) neighborMesh.decreaseRefCount();
|
defer neighborMesh.decreaseRefCount();
|
||||||
std.debug.assert(neighborMesh != self);
|
std.debug.assert(neighborMesh != self);
|
||||||
deadlockFreeDoubleLock(&self.mutex, &neighborMesh.mutex);
|
deadlockFreeDoubleLock(&self.mutex, &neighborMesh.mutex);
|
||||||
defer self.mutex.unlock();
|
defer self.mutex.unlock();
|
||||||
@ -891,12 +909,8 @@ pub const ChunkMesh = struct {
|
|||||||
}
|
}
|
||||||
_ = neighborMesh.needsLightRefresh.swap(false, .AcqRel);
|
_ = neighborMesh.needsLightRefresh.swap(false, .AcqRel);
|
||||||
try neighborMesh.finishData();
|
try neighborMesh.finishData();
|
||||||
if(inRenderThread) {
|
neighborMesh.increaseRefCount();
|
||||||
try neighborMesh.uploadData();
|
try mesh_storage.addToUpdateListAndDecreaseRefCount(neighborMesh);
|
||||||
} else {
|
|
||||||
neighborMesh.increaseRefCount();
|
|
||||||
try mesh_storage.addToUpdateListAndDecreaseRefCount(neighborMesh);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
self.mutex.lock();
|
self.mutex.lock();
|
||||||
defer self.mutex.unlock();
|
defer self.mutex.unlock();
|
||||||
@ -907,7 +921,7 @@ pub const ChunkMesh = struct {
|
|||||||
}
|
}
|
||||||
// lod border:
|
// lod border:
|
||||||
if(self.pos.voxelSize == 1 << settings.highestLOD) continue;
|
if(self.pos.voxelSize == 1 << settings.highestLOD) continue;
|
||||||
const neighborMesh = getNeighborMesh(self.pos, 2*self.pos.voxelSize, neighbor) orelse {
|
const neighborMesh = mesh_storage.getNeighborAndIncreaseRefCount(self.pos, 2*self.pos.voxelSize, neighbor) orelse {
|
||||||
self.mutex.lock();
|
self.mutex.lock();
|
||||||
defer self.mutex.unlock();
|
defer self.mutex.unlock();
|
||||||
if(self.lastNeighborsHigherLod[neighbor] != null) {
|
if(self.lastNeighborsHigherLod[neighbor] != null) {
|
||||||
@ -916,10 +930,10 @@ pub const ChunkMesh = struct {
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
defer neighborMesh.decreaseRefCount();
|
||||||
deadlockFreeDoubleLock(&self.mutex, &neighborMesh.mutex);
|
deadlockFreeDoubleLock(&self.mutex, &neighborMesh.mutex);
|
||||||
defer self.mutex.unlock();
|
defer self.mutex.unlock();
|
||||||
defer neighborMesh.mutex.unlock();
|
defer neighborMesh.mutex.unlock();
|
||||||
defer if(!inRenderThread) neighborMesh.decreaseRefCount();
|
|
||||||
if(self.lastNeighborsHigherLod[neighbor] == neighborMesh) continue;
|
if(self.lastNeighborsHigherLod[neighbor] == neighborMesh) continue;
|
||||||
self.lastNeighborsHigherLod[neighbor] = neighborMesh;
|
self.lastNeighborsHigherLod[neighbor] = neighborMesh;
|
||||||
self.clearNeighbor(neighbor, true);
|
self.clearNeighbor(neighbor, true);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user