diff --git a/src/chunk.zig b/src/chunk.zig index e41cef8c..e5a0232f 100644 --- a/src/chunk.zig +++ b/src/chunk.zig @@ -358,12 +358,6 @@ pub const Chunk = struct { // } // } } -}; - - - - - // TODO: Check if/how they are needed: // @@ -374,151 +368,8 @@ pub const Chunk = struct { // public Vector3d getMax() { // return new Vector3d(wx + width, wy + width, wz + width); // } -// -// @Override -// public byte[] saveToByteArray() { -// byte[] data = new byte[4*blocks.length]; -// for(int i = 0; i < blocks.length; i++) { -// Bits.putInt(data, i*4, blocks[i]); -// } -// return data; -// } -// -// @Override -// public boolean loadFromByteArray(byte[] data, int outputLength) { -// if(outputLength != 4*blocks.length) { -// Logger.error("Chunk is corrupted(invalid data length "+outputLength+") : " + this); -// return false; -// } -// for(int i = 0; i < blocks.length; i++) { -// blocks[i] = Bits.getInt(data, i*4); -// } -// generated = true; -// return true; -// } - -pub const VisibleBlock = struct { - block: Block, - x: u8, - y: u8, - z: u8, - neighbors: u8, }; -pub const ChunkVisibilityData = struct { - pos: ChunkPosition, - visibles: std.ArrayList(VisibleBlock), - voxelSizeShift: u5, - /// Finds a block in the surrounding 8 chunks using relative corrdinates. - fn getBlock(self: ChunkVisibilityData, chunks: *const [8]Chunk, _x: ChunkCoordinate, _y: ChunkCoordinate, _z: ChunkCoordinate) Block { - var x = _x + (self.pos.wx - chunks[0].pos.wx) >> self.voxelSizeShift; - var y = _y + (self.pos.wy - chunks[0].pos.wy) >> self.voxelSizeShift; - var z = _z + (self.pos.wz - chunks[0].pos.wz) >> self.voxelSizeShift; - var chunk = &chunks[@intCast(usize, (x >> chunkShift)*4 + (y >> chunkShift)*2 + (z >> chunkShift))]; - x &= chunkMask; - y &= chunkMask; - z &= chunkMask; - return chunk.blocks[getIndex(x, y, z)]; - } - - pub fn initEmpty(allocator: Allocator, pos: ChunkPosition, initialCapacity: usize) !ChunkVisibilityData { - return ChunkVisibilityData { - .pos = pos, - .visibles = try std.ArrayList(VisibleBlock).initCapacity(allocator, initialCapacity), - .voxelSizeShift = std.math.log2_int(UChunkCoordinate, pos.voxelSize), - }; - } - - pub fn init(allocator: Allocator, pos: ChunkPosition, initialCapacity: usize) !ChunkVisibilityData { - var self = ChunkVisibilityData { - .pos = pos, - .visibles = try std.ArrayList(VisibleBlock).initCapacity(allocator, initialCapacity), - .voxelSizeShift = std.math.log2_int(UChunkCoordinate, pos.voxelSize), - }; - - const width = pos.voxelSize*chunkSize; - const widthMask = width - 1; - - // Get or generate the 8 surrounding chunks: - var chunks: [8]Chunk = undefined; - var x: u8 = 0; - while(x <= 1): (x += 1) { - var y: u8 = 0; - while(y <= 1): (y += 1) { - var z: u8 = 0; - while(z <= 1): (z += 1) { - chunks[x*4 + y*2 + z] = Chunk.init((pos.wx & ~widthMask) + x*width, (pos.wy & ~widthMask) + y*width, (pos.wz & ~widthMask) + z*width, pos.voxelSize); - // TODO: world.chunkManager.getOrGenerateReducedChunk((wx & ~widthMask) + x*width, (wy & ~widthMask) + y*width, (wz & ~widthMask) + z*width, voxelSize); - } - } - } - - const halfMask = chunkMask >> 1; - x = 0; - while(x < chunkSize): (x += 1) { - var y: u8 = 0; - while(y < chunkSize): (y += 1) { - var z: u8 = 0; - while(z < chunkSize): (z += 1) { - const block = self.getBlock(&chunks, x, y, z); - if(block.typ == 0) continue; - // Check all neighbors: - var neighborVisibility: u8 = 0; - for(Neighbors.iterable) |i| { - const x2 = x + Neighbors.relX[i]; - const y2 = y + Neighbors.relY[i]; - const z2 = z + Neighbors.relZ[i]; - const neighborBlock = self.getBlock(&chunks, x2, y2, z2); - var isVisible = neighborBlock.typ == 0; - if(!isVisible) { - // If the chunk is at a border, more neighbors need to be checked to prevent cracks at LOD changes: - // TODO: Find a better way to do this. This method doesn't always work and adds a lot of additional triangles. - if(x & halfMask == (x2 & halfMask) ^ halfMask or y & halfMask == (y2 & halfMask) ^ halfMask or z & halfMask == (z2 & halfMask) ^ halfMask) { - for(Neighbors.iterable) |j| { - const x3 = x2 + Neighbors.relX[j]; - const y3 = y2 + Neighbors.relY[j]; - const z3 = z2 + Neighbors.relZ[j]; - if(self.getBlock(&chunks, x3, y3, z3).typ == 0) { - isVisible = true; - break; - } - } - } - } - - if(isVisible) { - neighborVisibility |= Neighbors.bitMask[i]; - } - } - if(neighborVisibility != 0) { - try self.visibles.append(VisibleBlock{ - .block = block, - .x = x, - .y = y, - .z = z, - .neighbors = neighborVisibility, - }); - } - } - } - } - return self; - } - -// TODO: Check how this constructor is actually needed. -// public ReducedChunkVisibilityData(int wx, int wy, int wz, int voxelSize, byte[] x, byte[] y, byte[] z, byte[] neighbors, int[] visibleBlocks) { -// super(wx, wy, wz, voxelSize); -// voxelSizeShift = 31 - Integer.numberOfLeadingZeros(voxelSize); // log2 -// assert x.length == y.length && y.length == z.length && z.length == neighbors.length && neighbors.length == visibleBlocks.length : "Size of input parameters doesn't match."; -// this.x = x; -// this.y = y; -// this.z = z; -// this.neighbors = neighbors; -// this.visibleBlocks = visibleBlocks; -// capacity = size = x.length; -// } -//} -}; pub const meshing = struct { var shader: Shader = undefined; diff --git a/src/network.zig b/src/network.zig index 3997ecd3..b7ae9f06 100644 --- a/src/network.zig +++ b/src/network.zig @@ -691,37 +691,15 @@ pub const Protocols = blk: { const _inflatedData = try utils.Compression.inflate(main.threadAllocator, data[16..]); data = _inflatedData; defer main.threadAllocator.free(_inflatedData); - if(pos.voxelSize != 0) { - var ch = try renderer.RenderStructure.allocator.create(chunk.Chunk); - ch.init(pos); - for(ch.blocks) |*block| { - var blockTypeAndData = std.mem.readIntBig(u32, data[0..4]); - block.typ = @intCast(u16, blockTypeAndData & 0xffff); - block.data = @intCast(u16, blockTypeAndData >> 16); - data = data[4..]; - } - try renderer.RenderStructure.updateChunkMesh(ch); - } else { - //var size = @divExact(data.len, 8); - //var x = data[0..size]; - //var y = data[size..2*size]; - //var z = data[2*size..3*size]; - //var neighbors = data[3*size..4*size]; - //var visibleBlocks = data[4*size..]; - //var result = try renderer.RenderStructure.allocator.create(chunk.ChunkVisibilityData); - //result.* = try chunk.ChunkVisibilityData.initEmpty(renderer.RenderStructure.allocator, pos, size); - //for(x) |_, i| { - // var block = result.visibles.addOneAssumeCapacity(); - // block.x = x[i]; - // block.y = y[i]; - // block.z = z[i]; - // block.neighbors = neighbors[i]; - // var blockTypeAndData = std.mem.readIntBig(u32, visibleBlocks[4*i..][0..4]); - // block.block.typ = @intCast(u16, blockTypeAndData & 0xffff); - // block.block.data = @intCast(u16, blockTypeAndData >> 16); - //} - // TODO: try renderer.RenderStructure.updateChunkMesh(result); + var ch = try renderer.RenderStructure.allocator.create(chunk.Chunk); + ch.init(pos); + for(ch.blocks) |*block| { + var blockTypeAndData = std.mem.readIntBig(u32, data[0..4]); + block.typ = @intCast(u16, blockTypeAndData & 0xffff); + block.data = @intCast(u16, blockTypeAndData >> 16); + data = data[4..]; } + try renderer.RenderStructure.updateChunkMesh(ch); } pub fn sendChunk(conn: *Connection, visData: chunk.ChunkVisibilityData) !void { var data = try main.threadAllocator.alloc(u8, 16 + 8*visData.visibles.items.len);