From 51e0d55a0c8d5f99d0f059ae567005cb9a10ca54 Mon Sep 17 00:00:00 2001 From: Zachary Hall Date: Thu, 12 Sep 2024 11:20:11 -0700 Subject: [PATCH 01/10] Don't trigger window drag when trying to click on a window button (#695) * Refactor getting X positions of buttons in preparation for not moving the window when clicking the buttons * Prevent moving the window by the buttons * Use tabs instead of spaces for indentation, done using sed. * Fix formatting actually now with sed in while loop * Attempt to fix indentation * Add minimum width and change return type of getButtonPositions * Include window ID in size error * Fix orientation lines showing when clicking button and incorrect scaling for button press detection on windows * Don't include windows without titlebar in window size requirement * Take into account closability of windows when calculating min width * Add single quotes around window ID in the width error message for clarity * Fix chat window automatic sizing, refactoring the minimum window size check in the process --- src/gui/GuiWindow.zig | 33 ++++++++++++++++++++++++++------- src/gui/windows/chat.zig | 3 ++- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/gui/GuiWindow.zig b/src/gui/GuiWindow.zig index cdb28721..a4c0254f 100644 --- a/src/gui/GuiWindow.zig +++ b/src/gui/GuiWindow.zig @@ -77,6 +77,7 @@ onOpenFn: *const fn()void = &defaultFunction, onCloseFn: *const fn()void = &defaultFunction, var grabbedWindow: *const GuiWindow = undefined; +var windowMoving: bool = false; var grabPosition: ?Vec2f = null; var selfPositionWhenGrabbed: Vec2f = undefined; @@ -130,10 +131,13 @@ pub fn defaultFunction() void {} pub fn mainButtonPressed(self: *const GuiWindow, mousePosition: Vec2f) void { const scaledMousePos = (mousePosition - self.pos)/@as(Vec2f, @splat(self.scale)); + const btnPos = self.getButtonPositions(); + const zoomInPos = btnPos[2]/self.scale; if(scaledMousePos[1] < titleBarHeight and (self.showTitleBar or gui.reorderWindows)) { grabbedWindow = self; grabPosition = mousePosition; selfPositionWhenGrabbed = self.pos; + windowMoving = scaledMousePos[0] <= zoomInPos; } else { if(self.rootComponent) |*component| { if(GuiComponent.contains(component.pos(), component.size(), scaledMousePos)) { @@ -143,12 +147,19 @@ pub fn mainButtonPressed(self: *const GuiWindow, mousePosition: Vec2f) void { } } +pub fn getButtonPositions(self: *const GuiWindow) [3]f32 { + const closePos = if(self.closeable) self.size[0] - iconWidth*self.scale else self.size[0]; + const zoomOutPos = closePos - iconWidth*self.scale; + const zoomInPos = zoomOutPos - iconWidth*self.scale; + return .{closePos, zoomOutPos, zoomInPos}; +} pub fn mainButtonReleased(self: *GuiWindow, mousePosition: Vec2f) void { if(grabPosition != null and @reduce(.And, grabPosition.? == mousePosition) and grabbedWindow == self) { if(self.showTitleBar or gui.reorderWindows) { - const closePos = if(self.closeable) self.size[0] - iconWidth*self.scale else self.size[0]; - const zoomOutPos = closePos - iconWidth*self.scale; - const zoomInPos = zoomOutPos - iconWidth*self.scale; + const btnPos = self.getButtonPositions(); + const closePos = btnPos[0]; + const zoomOutPos = btnPos[1]; + const zoomInPos = btnPos[2]; if(mousePosition[0] - self.pos[0] > zoomInPos) { if(mousePosition[0] - self.pos[0] > zoomOutPos) { if(mousePosition[0] - self.pos[0] > closePos) { @@ -324,7 +335,7 @@ pub fn update(self: *GuiWindow) void { pub fn updateSelected(self: *GuiWindow, mousePosition: Vec2f) void { self.updateSelectedFn(); const windowSize = main.Window.getWindowSize()/@as(Vec2f, @splat(gui.scale)); - if(self == grabbedWindow and (gui.reorderWindows or self.showTitleBar)) if(grabPosition) |_grabPosition| { + if(self == grabbedWindow and windowMoving and (gui.reorderWindows or self.showTitleBar)) if(grabPosition) |_grabPosition| { self.relativePosition[0] = .{.ratio = undefined}; self.relativePosition[1] = .{.ratio = undefined}; self.pos = (mousePosition - _grabPosition) + selfPositionWhenGrabbed; @@ -354,8 +365,16 @@ pub fn updateHovered(self: *GuiWindow, mousePosition: Vec2f) void { } } } - +pub fn getMinWindowWidth(self: *GuiWindow) f32 { + return iconWidth * @as(f32, (if (self.closeable) 4 else 3)); +} pub fn updateWindowPosition(self: *GuiWindow) void { + const minSize = self.getMinWindowWidth(); + if(self.contentSize[0] < minSize) { + std.log.err("Window '{s}' width is too small: {d}px before scaling", .{self.id, self.contentSize[0]}); + self.contentSize[0] = minSize; + std.log.debug("Resized width to {d}px unscaled", .{self.contentSize[0]}); + } self.size = self.contentSize*@as(Vec2f, @splat(self.scale)); const windowSize = main.Window.getWindowSize()/@as(Vec2f, @splat(gui.scale)); for(self.relativePosition, 0..) |relPos, i| { @@ -483,7 +502,7 @@ pub fn render(self: *const GuiWindow, mousePosition: Vec2f) void { } draw.restoreTranslation(oldTranslation); draw.restoreScale(oldScale); - if(self == grabbedWindow and (gui.reorderWindows or self.showTitleBar) and grabPosition != null) { + if(self == grabbedWindow and windowMoving and (gui.reorderWindows or self.showTitleBar) and grabPosition != null) { self.drawOrientationLines(); } -} \ No newline at end of file +} diff --git a/src/gui/windows/chat.zig b/src/gui/windows/chat.zig index 56585d9d..c49fb8d1 100644 --- a/src/gui/windows/chat.zig +++ b/src/gui/windows/chat.zig @@ -57,6 +57,7 @@ fn refresh() void { list.scrollBar.currentState = 1; window.rootComponent = list.toComponent(); window.contentSize = window.rootComponent.?.pos() + window.rootComponent.?.size() + @as(Vec2f, @splat(padding)); + window.contentSize[0] = @max(window.contentSize[0], window.getMinWindowWidth()); gui.updateWindowPositions(); if(!hideInput) { for(history.items) |label| { @@ -148,4 +149,4 @@ pub fn sendMessage(_: usize) void { main.network.Protocols.chat.send(main.game.world.?.conn, input.currentString.items); input.clear(); } -} \ No newline at end of file +} From cf6e9df663face9ee7e29d5e5f265bcaf6258ce1 Mon Sep 17 00:00:00 2001 From: Zachary Hall Date: Fri, 13 Sep 2024 13:04:15 -0700 Subject: [PATCH 02/10] Fix Zig download url (#718) * Update debug_linux.sh * Update debug_windows.bat --- debug_linux.sh | 2 +- debug_windows.bat | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/debug_linux.sh b/debug_linux.sh index 9f51d4fc..61a0e898 100755 --- a/debug_linux.sh +++ b/debug_linux.sh @@ -48,7 +48,7 @@ if [[ "$CURRENT_VERSION" != "$VERSION" ]]; then rm -r compiler/zig mkdir compiler/zig echo "Downloading $VERSION..." - wget -O compiler/archive.tar.xz https://ziglang.org/builds/"$VERSION".tar.xz + wget -O compiler/archive.tar.xz https://ziglang.org/download/$BASE_VERSION/"$VERSION".tar.xz if [ $? != 0 ] then echo "Failed to download the Zig compiler." diff --git a/debug_windows.bat b/debug_windows.bat index 28302074..02ce4f29 100644 --- a/debug_windows.bat +++ b/debug_windows.bat @@ -29,7 +29,7 @@ if not "%version%" == "%currVersion%" ( echo Deleting current Zig installation ... if exist compiler\zig rmdir /s /q compiler\zig echo Downloading %version% ... - powershell -Command $ProgressPreference = 'SilentlyContinue'; "Invoke-WebRequest -uri https://ziglang.org/builds/%version%.zip -OutFile compiler\archive.zip" + powershell -Command $ProgressPreference = 'SilentlyContinue'; "Invoke-WebRequest -uri https://ziglang.org/download/%baseVersion%/%version%.zip -OutFile compiler\archive.zip" if errorlevel 1 ( echo Failed to download the Zig compiler. exit /b 1 From 8987dc4eb05697aaa1a813821b36f625fadac91b Mon Sep 17 00:00:00 2001 From: IntegratedQuantum Date: Fri, 13 Sep 2024 23:43:25 +0200 Subject: [PATCH 03/10] Pull zig from a github repo instead of relying on ziglang.org, this should be more stable. fixes #719 --- debug_linux.sh | 2 +- debug_windows.bat | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/debug_linux.sh b/debug_linux.sh index 61a0e898..fe3e7c3c 100755 --- a/debug_linux.sh +++ b/debug_linux.sh @@ -48,7 +48,7 @@ if [[ "$CURRENT_VERSION" != "$VERSION" ]]; then rm -r compiler/zig mkdir compiler/zig echo "Downloading $VERSION..." - wget -O compiler/archive.tar.xz https://ziglang.org/download/$BASE_VERSION/"$VERSION".tar.xz + wget -O compiler/archive.tar.xz https://github.com/PixelGuys/Cubyz-zig-versions/releases/download/$BASE_VERSION/"$VERSION".tar.xz if [ $? != 0 ] then echo "Failed to download the Zig compiler." diff --git a/debug_windows.bat b/debug_windows.bat index 02ce4f29..ee4f9e12 100644 --- a/debug_windows.bat +++ b/debug_windows.bat @@ -29,7 +29,7 @@ if not "%version%" == "%currVersion%" ( echo Deleting current Zig installation ... if exist compiler\zig rmdir /s /q compiler\zig echo Downloading %version% ... - powershell -Command $ProgressPreference = 'SilentlyContinue'; "Invoke-WebRequest -uri https://ziglang.org/download/%baseVersion%/%version%.zip -OutFile compiler\archive.zip" + powershell -Command $ProgressPreference = 'SilentlyContinue'; "Invoke-WebRequest -uri https://github.com/PixelGuys/Cubyz-zig-versions/releases/download/%baseVersion%/%version%.zip -OutFile compiler\archive.zip" if errorlevel 1 ( echo Failed to download the Zig compiler. exit /b 1 From 330187b9aeac4892a637e1abcbb4599bb4cd8d67 Mon Sep 17 00:00:00 2001 From: IntegratedQuantum Date: Sat, 14 Sep 2024 13:42:25 +0200 Subject: [PATCH 04/10] Update zig version --- .zig-version | 2 +- src/chunk.zig | 4 +- src/graphics.zig | 4 +- src/gui/gui.zig | 4 +- src/gui/windows/debug_network.zig | 2 +- src/gui/windows/gpu_performance_measuring.zig | 2 +- src/json.zig | 38 +++++++++---------- src/main.zig | 8 ++-- src/models.zig | 12 +++--- src/network.zig | 2 +- src/random.zig | 4 +- src/rotation.zig | 6 +-- src/server/command/_command.zig | 2 +- src/server/terrain/CaveBiomeMap.zig | 2 +- src/server/terrain/CaveMap.zig | 2 +- src/server/terrain/ClimateMap.zig | 2 +- src/server/terrain/StructureMap.zig | 2 +- src/server/terrain/SurfaceMap.zig | 2 +- src/server/terrain/biomes.zig | 28 +++++++------- src/server/terrain/terrain.zig | 2 +- src/settings.zig | 28 +++++++------- src/utils.zig | 4 +- src/vec.zig | 28 +++++++------- 23 files changed, 95 insertions(+), 95 deletions(-) diff --git a/.zig-version b/.zig-version index 51de3305..d1e624e2 100644 --- a/.zig-version +++ b/.zig-version @@ -1 +1 @@ -0.13.0 \ No newline at end of file +0.14.0-dev.1550+4fba7336a \ No newline at end of file diff --git a/src/chunk.zig b/src/chunk.zig index f7f7d4db..6c13a98b 100644 --- a/src/chunk.zig +++ b/src/chunk.zig @@ -151,14 +151,14 @@ pub const ChunkPosition = struct { // MARK: ChunkPosition } pub fn equals(self: ChunkPosition, other: anytype) bool { - if(@typeInfo(@TypeOf(other)) == .Optional) { + if(@typeInfo(@TypeOf(other)) == .optional) { if(other) |notNull| { return self.equals(notNull); } return false; } else if(@TypeOf(other.*) == ServerChunk) { return self.wx == other.super.pos.wx and self.wy == other.super.pos.wy and self.wz == other.super.pos.wz and self.voxelSize == other.super.pos.voxelSize; - } else if(@typeInfo(@TypeOf(other)) == .Pointer) { + } else if(@typeInfo(@TypeOf(other)) == .pointer) { return self.wx == other.pos.wx and self.wy == other.pos.wy and self.wz == other.pos.wz and self.voxelSize == other.pos.voxelSize; } else @compileError("Unsupported"); } diff --git a/src/graphics.zig b/src/graphics.zig index 6a5bb586..51ca0038 100644 --- a/src/graphics.zig +++ b/src/graphics.zig @@ -1220,7 +1220,7 @@ pub const Shader = struct { // MARK: Shader pub fn initAndGetUniforms(vertex: []const u8, fragment: []const u8, defines: []const u8, ptrToUniformStruct: anytype) Shader { const self = Shader.init(vertex, fragment, defines); - inline for(@typeInfo(@TypeOf(ptrToUniformStruct.*)).Struct.fields) |field| { + inline for(@typeInfo(@TypeOf(ptrToUniformStruct.*)).@"struct".fields) |field| { if(field.type == c_int) { @field(ptrToUniformStruct, field.name) = c.glGetUniformLocation(self.id, field.name[0..]); } @@ -1237,7 +1237,7 @@ pub const Shader = struct { // MARK: Shader pub fn initComputeAndGetUniforms(compute: []const u8, defines: []const u8, ptrToUniformStruct: anytype) Shader { const self = Shader.initCompute(compute, defines); - inline for(@typeInfo(@TypeOf(ptrToUniformStruct.*)).Struct.fields) |field| { + inline for(@typeInfo(@TypeOf(ptrToUniformStruct.*)).@"struct".fields) |field| { if(field.type == c_int) { @field(ptrToUniformStruct, field.name) = c.glGetUniformLocation(self.id, field.name[0..]); } diff --git a/src/gui/gui.zig b/src/gui/gui.zig index 001d3fc4..6c388c2b 100644 --- a/src/gui/gui.zig +++ b/src/gui/gui.zig @@ -131,7 +131,7 @@ pub fn init() void { // MARK: init() windowList = List(*GuiWindow).init(main.globalAllocator); hudWindows = List(*GuiWindow).init(main.globalAllocator); openWindows = List(*GuiWindow).init(main.globalAllocator); - inline for(@typeInfo(windowlist).Struct.decls) |decl| { + inline for(@typeInfo(windowlist).@"struct".decls) |decl| { const windowStruct = @field(windowlist, decl.name); windowStruct.window.id = decl.name; addWindow(&windowStruct.window); @@ -173,7 +173,7 @@ pub fn deinit() void { ContinuousSlider.__deinit(); DiscreteSlider.__deinit(); TextInput.__deinit(); - inline for(@typeInfo(windowlist).Struct.decls) |decl| { + inline for(@typeInfo(windowlist).@"struct".decls) |decl| { const WindowStruct = @field(windowlist, decl.name); if(@hasDecl(WindowStruct, "deinit")) { WindowStruct.deinit(); diff --git a/src/gui/windows/debug_network.zig b/src/gui/windows/debug_network.zig index 75405be0..98522633 100644 --- a/src/gui/windows/debug_network.zig +++ b/src/gui/windows/debug_network.zig @@ -36,7 +36,7 @@ pub fn render() void { const loss = @as(f64, @floatFromInt(resent))/@as(f64, @floatFromInt(sent))*100; draw.print("Packet loss: {d:.1}% ({}/{})", .{loss, resent, sent}, 0, y, 8, .left); y += 8; - inline for(@typeInfo(network.Protocols).Struct.decls) |decl| { + inline for(@typeInfo(network.Protocols).@"struct".decls) |decl| { if(@TypeOf(@field(network.Protocols, decl.name)) == type) { const id = @field(network.Protocols, decl.name).id; draw.print("{s}: {}kiB in {} packets", .{decl.name, network.bytesReceived[id].load(.monotonic) >> 10, network.packetsReceived[id].load(.monotonic)}, 0, y, 8, .left); diff --git a/src/gui/windows/gpu_performance_measuring.zig b/src/gui/windows/gpu_performance_measuring.zig index 995fd857..1860b565 100644 --- a/src/gui/windows/gpu_performance_measuring.zig +++ b/src/gui/windows/gpu_performance_measuring.zig @@ -51,7 +51,7 @@ const names = [_][]const u8 { const buffers = 4; var curBuffer: u2 = 0; -var queryObjects: [buffers][@typeInfo(Samples).Enum.fields.len]c_uint = undefined; +var queryObjects: [buffers][@typeInfo(Samples).@"enum".fields.len]c_uint = undefined; var activeSample: ?Samples = null; diff --git a/src/json.zig b/src/json.zig index f7c08410..858be88a 100644 --- a/src/json.zig +++ b/src/json.zig @@ -87,36 +87,36 @@ pub const JsonElement = union(JsonType) { // MARK: JsonElement pub fn as(self: *const JsonElement, comptime T: type, replacement: T) T { comptime var typeInfo : std.builtin.Type = @typeInfo(T); comptime var innerType = T; - inline while(typeInfo == .Optional) { - innerType = typeInfo.Optional.child; + inline while(typeInfo == .optional) { + innerType = typeInfo.optional.child; typeInfo = @typeInfo(innerType); } switch(typeInfo) { - .Int => { + .int => { switch(self.*) { .JsonInt => return std.math.cast(innerType, self.JsonInt) orelse replacement, .JsonFloat => return std.math.lossyCast(innerType, std.math.round(self.JsonFloat)), else => return replacement, } }, - .Float => { + .float => { switch(self.*) { .JsonInt => return @floatFromInt(self.JsonInt), .JsonFloat => return @floatCast(self.JsonFloat), else => return replacement, } }, - .Vector => { - const len = typeInfo.Vector.len; + .vector => { + const len = typeInfo.vector.len; const elems = self.toSlice(); if(elems.len != len) return replacement; var result: innerType = undefined; if(innerType == T) result = replacement; inline for(0..len) |i| { if(innerType == T) { - result[i] = elems[i].as(typeInfo.Vector.child, result[i]); + result[i] = elems[i].as(typeInfo.vector.child, result[i]); } else { - result[i] = elems[i].as(?typeInfo.Vector.child, null) orelse return replacement; + result[i] = elems[i].as(?typeInfo.vector.child, null) orelse return replacement; } } return result; @@ -146,39 +146,39 @@ pub const JsonElement = union(JsonType) { // MARK: JsonElement fn createElementFromRandomType(value: anytype, allocator: std.mem.Allocator) JsonElement { switch(@typeInfo(@TypeOf(value))) { - .Void => return JsonElement{.JsonNull={}}, - .Null => return JsonElement{.JsonNull={}}, - .Bool => return JsonElement{.JsonBool=value}, - .Int, .ComptimeInt => return JsonElement{.JsonInt=@intCast(value)}, - .Float, .ComptimeFloat => return JsonElement{.JsonFloat=@floatCast(value)}, - .Union => { + .void => return JsonElement{.JsonNull={}}, + .null => return JsonElement{.JsonNull={}}, + .bool => return JsonElement{.JsonBool=value}, + .int, .comptime_int => return JsonElement{.JsonInt=@intCast(value)}, + .float, .comptime_float => return JsonElement{.JsonFloat=@floatCast(value)}, + .@"union" => { if(@TypeOf(value) == JsonElement) { return value; } else { @compileError("Unknown value type."); } }, - .Pointer => |ptr| { + .pointer => |ptr| { if(ptr.child == u8 and ptr.size == .Slice) { return JsonElement{.JsonString=value}; } else { const childInfo = @typeInfo(ptr.child); - if(ptr.size == .One and childInfo == .Array and childInfo.Array.child == u8) { + if(ptr.size == .One and childInfo == .array and childInfo.array.child == u8) { return JsonElement{.JsonString=value}; } else { @compileError("Unknown value type."); } } }, - .Optional => { + .optional => { if(value) |val| { return createElementFromRandomType(val, allocator); } else { return JsonElement{.JsonNull={}}; } }, - .Vector => { - const len = @typeInfo(@TypeOf(value)).Vector.len; + .vector => { + const len = @typeInfo(@TypeOf(value)).vector.len; const result = initArray(main.utils.NeverFailingAllocator{.allocator = allocator, .IAssertThatTheProvidedAllocatorCantFail = {}}); result.JsonArray.ensureCapacity(len); inline for(0..len) |i| { diff --git a/src/main.zig b/src/main.zig index bce8039b..fa6decf3 100644 --- a/src/main.zig +++ b/src/main.zig @@ -56,7 +56,7 @@ pub const std_options: std.Options = .{ // MARK: std_options .log_level = .debug, .logFn = struct {pub fn logFn( comptime level: std.log.Level, - comptime _: @Type(.EnumLiteral), + comptime _: @Type(.enum_literal), comptime format: []const u8, args: anytype, ) void { @@ -125,10 +125,10 @@ pub const std_options: std.Options = .{ // MARK: std_options types = types ++ &[_]type{i64}; } else if(@TypeOf(args[i_1]) == comptime_float) { types = types ++ &[_]type{f64}; - } else if(TI == .Pointer and TI.Pointer.size == .Slice and TI.Pointer.child == u8) { + } else if(TI == .pointer and TI.pointer.size == .Slice and TI.pointer.child == u8) { types = types ++ &[_]type{[]const u8}; - } else if(TI == .Int and TI.Int.bits <= 64) { - if(TI.Int.signedness == .signed) { + } else if(TI == .int and TI.int.bits <= 64) { + if(TI.int.signedness == .signed) { types = types ++ &[_]type{i64}; } else { types = types ++ &[_]type{u64}; diff --git a/src/models.zig b/src/models.zig index 87d32a50..cafe5da0 100644 --- a/src/models.zig +++ b/src/models.zig @@ -32,7 +32,7 @@ const gridSize = 4096; fn snapToGrid(x: anytype) @TypeOf(x) { const T = @TypeOf(x); - const int = @as(@Vector(@typeInfo(T).Vector.len, i32), @intFromFloat(std.math.round(x*@as(T, @splat(gridSize))))); + const int = @as(@Vector(@typeInfo(T).vector.len, i32), @intFromFloat(std.math.round(x*@as(T, @splat(gridSize))))); return @as(T, @floatFromInt(int))/@as(T, @splat(gridSize)); } @@ -212,7 +212,7 @@ pub const Model = struct { continue; if (std.mem.eql(u8, line[0..2], "v ")) { - var coordsIter = std.mem.split(u8, line[2..], " "); + var coordsIter = std.mem.splitScalar(u8, line[2..], ' '); var coords: Vec3f = undefined; var i: usize = 0; while (coordsIter.next()) |coord| : (i += 1) { @@ -221,7 +221,7 @@ pub const Model = struct { const coordsCorrect: Vec3f = .{coords[0], coords[1], coords[2]}; vertices.append(coordsCorrect); } else if (std.mem.eql(u8, line[0..3], "vn ")) { - var coordsIter = std.mem.split(u8, line[3..], " "); + var coordsIter = std.mem.splitScalar(u8, line[3..], ' '); var norm: Vec3f = undefined; var i: usize = 0; while (coordsIter.next()) |coord| : (i += 1) { @@ -230,7 +230,7 @@ pub const Model = struct { const normCorrect: Vec3f = .{norm[0], norm[1], norm[2]}; normals.append(normCorrect); } else if (std.mem.eql(u8, line[0..3], "vt ")) { - var coordsIter = std.mem.split(u8, line[3..], " "); + var coordsIter = std.mem.splitScalar(u8, line[3..], ' '); var uv: Vec2f = undefined; var i: usize = 0; while (coordsIter.next()) |coord| : (i += 1) { @@ -240,7 +240,7 @@ pub const Model = struct { uv[1] *= 4; uvs.append(.{uv[0], uv[1]}); } else if (std.mem.eql(u8, line[0..2], "f ")) { - var coordsIter = std.mem.split(u8, line[2..], " "); + var coordsIter = std.mem.splitScalar(u8, line[2..], ' '); var faceData: [3][4]usize = undefined; var i: usize = 0; var failed = false; @@ -250,7 +250,7 @@ pub const Model = struct { std.log.err("More than 4 verticies in a face", .{}); break; } - var d = std.mem.split(u8, vertex, "/"); + var d = std.mem.splitScalar(u8, vertex, '/'); var j: usize = 0; if (std.mem.count(u8, vertex, "/") != 2 or std.mem.count(u8, vertex, "//") != 0) { failed = true; diff --git a/src/network.zig b/src/network.zig index 1fde8e6c..448a056c 100644 --- a/src/network.zig +++ b/src/network.zig @@ -113,7 +113,7 @@ const Socket = struct { pub fn init() void { Socket.startup(); - inline for(@typeInfo(Protocols).Struct.decls) |decl| { + inline for(@typeInfo(Protocols).@"struct".decls) |decl| { if(@TypeOf(@field(Protocols, decl.name)) == type) { const id = @field(Protocols, decl.name).id; if(id != Protocols.keepAlive and id != Protocols.important and Protocols.list[id] == null) { diff --git a/src/random.zig b/src/random.zig index 99dbe4fc..b127304b 100644 --- a/src/random.zig +++ b/src/random.zig @@ -35,8 +35,8 @@ pub fn nextInt(comptime T: type, seed: *u64) T { } pub fn nextIntBounded(comptime T: type, seed: *u64, bound: T) T { - if(@typeInfo(T) != .Int) @compileError("Type must be integer."); - if(@typeInfo(T).Int.signedness == .signed) return nextIntBounded(std.meta.Int(.unsigned, @bitSizeOf(T) - 1), seed, @intCast(bound)); + if(@typeInfo(T) != .int) @compileError("Type must be integer."); + if(@typeInfo(T).int.signedness == .signed) return nextIntBounded(std.meta.Int(.unsigned, @bitSizeOf(T) - 1), seed, @intCast(bound)); const bitSize = std.math.log2_int_ceil(T, bound); var result = nextWithBitSize(T, seed, bitSize); while(result >= bound) { diff --git a/src/rotation.zig b/src/rotation.zig index ba43fcc8..e4814dc3 100644 --- a/src/rotation.zig +++ b/src/rotation.zig @@ -669,14 +669,14 @@ pub const RotationModes = struct { pub fn init() void { rotationModes = std.StringHashMap(RotationMode).init(main.globalAllocator.allocator); - inline for(@typeInfo(RotationModes).Struct.decls) |declaration| { + inline for(@typeInfo(RotationModes).@"struct".decls) |declaration| { register(@field(RotationModes, declaration.name)); } } pub fn deinit() void { rotationModes.deinit(); - inline for(@typeInfo(RotationModes).Struct.decls) |declaration| { + inline for(@typeInfo(RotationModes).@"struct".decls) |declaration| { @field(RotationModes, declaration.name).deinit(); } } @@ -690,7 +690,7 @@ pub fn getByID(id: []const u8) *RotationMode { pub fn register(comptime Mode: type) void { Mode.init(); var result: RotationMode = RotationMode{}; - inline for(@typeInfo(RotationMode).Struct.fields) |field| { + inline for(@typeInfo(RotationMode).@"struct".fields) |field| { if(@hasDecl(Mode, field.name)) { if(field.type == @TypeOf(@field(Mode, field.name))) { @field(result, field.name) = @field(Mode, field.name); diff --git a/src/server/command/_command.zig b/src/server/command/_command.zig index 6c6da2a6..6b87e6c0 100644 --- a/src/server/command/_command.zig +++ b/src/server/command/_command.zig @@ -15,7 +15,7 @@ pub var commands: std.StringHashMap(Command) = undefined; pub fn init() void { commands = std.StringHashMap(Command).init(main.globalAllocator.allocator); const commandList = @import("_list.zig"); - inline for(@typeInfo(commandList).Struct.decls) |decl| { + inline for(@typeInfo(commandList).@"struct".decls) |decl| { commands.put(decl.name, .{ .name = decl.name, .description = @field(commandList, decl.name).description, diff --git a/src/server/terrain/CaveBiomeMap.zig b/src/server/terrain/CaveBiomeMap.zig index f1c4a57c..28491ec7 100644 --- a/src/server/terrain/CaveBiomeMap.zig +++ b/src/server/terrain/CaveBiomeMap.zig @@ -575,7 +575,7 @@ var profile: TerrainGenerationProfile = undefined; pub fn initGenerators() void { const list = @import("cavebiomegen/_list.zig"); - inline for(@typeInfo(list).Struct.decls) |decl| { + inline for(@typeInfo(list).@"struct".decls) |decl| { CaveBiomeGenerator.registerGenerator(@field(list, decl.name)); } } diff --git a/src/server/terrain/CaveMap.zig b/src/server/terrain/CaveMap.zig index 440f9735..05023120 100644 --- a/src/server/terrain/CaveMap.zig +++ b/src/server/terrain/CaveMap.zig @@ -316,7 +316,7 @@ fn cacheInit(pos: ChunkPosition) *CaveMapFragment { pub fn initGenerators() void { const list = @import("cavegen/_list.zig"); - inline for(@typeInfo(list).Struct.decls) |decl| { + inline for(@typeInfo(list).@"struct".decls) |decl| { CaveGenerator.registerGenerator(@field(list, decl.name)); } } diff --git a/src/server/terrain/ClimateMap.zig b/src/server/terrain/ClimateMap.zig index c5a4e8fd..e1207497 100644 --- a/src/server/terrain/ClimateMap.zig +++ b/src/server/terrain/ClimateMap.zig @@ -109,7 +109,7 @@ var profile: TerrainGenerationProfile = undefined; pub fn initGenerators() void { const list = @import("climategen/_list.zig"); - inline for(@typeInfo(list).Struct.decls) |decl| { + inline for(@typeInfo(list).@"struct".decls) |decl| { ClimateMapGenerator.registerGenerator(@field(list, decl.name)); } } diff --git a/src/server/terrain/StructureMap.zig b/src/server/terrain/StructureMap.zig index 1abd231a..d7e7b47f 100644 --- a/src/server/terrain/StructureMap.zig +++ b/src/server/terrain/StructureMap.zig @@ -157,7 +157,7 @@ fn cacheInit(pos: ChunkPosition) *StructureMapFragment { pub fn initGenerators() void { const list = @import("structuremapgen/_list.zig"); - inline for(@typeInfo(list).Struct.decls) |decl| { + inline for(@typeInfo(list).@"struct".decls) |decl| { StructureMapGenerator.registerGenerator(@field(list, decl.name)); } } diff --git a/src/server/terrain/SurfaceMap.zig b/src/server/terrain/SurfaceMap.zig index e3210b01..9c50e55e 100644 --- a/src/server/terrain/SurfaceMap.zig +++ b/src/server/terrain/SurfaceMap.zig @@ -251,7 +251,7 @@ var profile: TerrainGenerationProfile = undefined; pub fn initGenerators() void { const list = @import("mapgen/_list.zig"); - inline for(@typeInfo(list).Struct.decls) |decl| { + inline for(@typeInfo(list).@"struct".decls) |decl| { MapGenerator.registerGenerator(@field(list, decl.name)); } } diff --git a/src/server/terrain/biomes.zig b/src/server/terrain/biomes.zig index 9f600cde..5084aa4c 100644 --- a/src/server/terrain/biomes.zig +++ b/src/server/terrain/biomes.zig @@ -141,24 +141,24 @@ const Stripe = struct { // MARK: Stripe fn hashGeneric(input: anytype) u64 { const T = @TypeOf(input); return switch(@typeInfo(T)) { - .Bool => @intFromBool(input), - .Enum => @intFromEnum(input), - .Int, .Float => @as(std.meta.Int(.unsigned, @bitSizeOf(T)), @bitCast(input)), - .Struct => blk: { + .bool => @intFromBool(input), + .@"enum" => @intFromEnum(input), + .int, .float => @as(std.meta.Int(.unsigned, @bitSizeOf(T)), @bitCast(input)), + .@"struct" => blk: { if(@hasDecl(T, "getHash")) { break :blk input.getHash(); } var result: u64 = 0; - inline for(@typeInfo(T).Struct.fields) |field| { + inline for(@typeInfo(T).@"struct".fields) |field| { result ^= hashGeneric(@field(input, field.name))*%hashGeneric(@as([]const u8, field.name)); } break :blk result; }, - .Optional => if(input) |_input| hashGeneric(_input) else 0, - .Pointer => switch(@typeInfo(T).Pointer.size) { + .optional => if(input) |_input| hashGeneric(_input) else 0, + .pointer => switch(@typeInfo(T).pointer.size) { .One => blk: { - if(@typeInfo(@typeInfo(T).Pointer.child) == .Fn) break :blk 0; - if(@typeInfo(T).Pointer.child == anyopaque) break :blk 0; + if(@typeInfo(@typeInfo(T).pointer.child) == .@"fn") break :blk 0; + if(@typeInfo(T).pointer.child == anyopaque) break :blk 0; break :blk hashGeneric(input.*); }, .Slice => blk: { @@ -170,16 +170,16 @@ fn hashGeneric(input: anytype) u64 { }, else => @compileError("Unsupported type " ++ @typeName(T)), }, - .Array => blk: { + .array => blk: { var result: u64 = 0; for(input) |val| { result = result*%33 +% hashGeneric(val); } break :blk result; }, - .Vector => blk: { + .vector => blk: { var result: u64 = 0; - inline for(0..@typeInfo(T).Vector.len) |i| { + inline for(0..@typeInfo(T).vector.len) |i| { result = result*%33 +% hashGeneric(input[i]); } break :blk result; @@ -222,7 +222,7 @@ pub const Biome = struct { // MARK: Biome var result: GenerationProperties = .{}; for(json.toSlice()) |child| { const property = child.as([]const u8, ""); - inline for(@typeInfo(GenerationProperties).Struct.fields) |field| { + inline for(@typeInfo(GenerationProperties).@"struct".fields) |field| { if(std.mem.eql(u8, field.name, property)) { @field(result, field.name) = true; } @@ -546,7 +546,7 @@ pub fn init() void { caveBiomes = main.List(Biome).init(main.globalAllocator); biomesById = std.StringHashMap(*Biome).init(main.globalAllocator.allocator); const list = @import("simple_structures/_list.zig"); - inline for(@typeInfo(list).Struct.decls) |decl| { + inline for(@typeInfo(list).@"struct".decls) |decl| { SimpleStructureModel.registerGenerator(@field(list, decl.name)); } } diff --git a/src/server/terrain/terrain.zig b/src/server/terrain/terrain.zig index cf73edc6..b7d85608 100644 --- a/src/server/terrain/terrain.zig +++ b/src/server/terrain/terrain.zig @@ -131,7 +131,7 @@ pub fn initGenerators() void { CaveMap.initGenerators(); StructureMap.initGenerators(); const list = @import("chunkgen/_list.zig"); - inline for(@typeInfo(list).Struct.decls) |decl| { + inline for(@typeInfo(list).@"struct".decls) |decl| { BlockGenerator.registerGenerator(@field(list, decl.name)); } const t1 = std.time.milliTimestamp(); diff --git a/src/settings.zig b/src/settings.zig index d95bea44..4a15c194 100644 --- a/src/settings.zig +++ b/src/settings.zig @@ -66,17 +66,17 @@ pub fn init() void { }; defer json.free(main.stackAllocator); - inline for(@typeInfo(@This()).Struct.decls) |decl| { - const is_const = @typeInfo(@TypeOf(&@field(@This(), decl.name))).Pointer.is_const; // Sadly there is no direct way to check if a declaration is const. + inline for(@typeInfo(@This()).@"struct".decls) |decl| { + const is_const = @typeInfo(@TypeOf(&@field(@This(), decl.name))).pointer.is_const; // Sadly there is no direct way to check if a declaration is const. if(!is_const) { const declType = @TypeOf(@field(@This(), decl.name)); - if(@typeInfo(declType) == .Struct) { + if(@typeInfo(declType) == .@"struct") { @compileError("Not implemented yet."); } @field(@This(), decl.name) = json.get(declType, decl.name, @field(@This(), decl.name)); - if(@typeInfo(declType) == .Pointer) { - if(@typeInfo(declType).Pointer.size == .Slice) { - @field(@This(), decl.name) = main.globalAllocator.dupe(@typeInfo(declType).Pointer.child, @field(@This(), decl.name)); + if(@typeInfo(declType) == .pointer) { + if(@typeInfo(declType).pointer.size == .Slice) { + @field(@This(), decl.name) = main.globalAllocator.dupe(@typeInfo(declType).pointer.child, @field(@This(), decl.name)); } else { @compileError("Not implemented yet."); } @@ -98,15 +98,15 @@ pub fn init() void { pub fn deinit() void { save(); - inline for(@typeInfo(@This()).Struct.decls) |decl| { - const is_const = @typeInfo(@TypeOf(&@field(@This(), decl.name))).Pointer.is_const; // Sadly there is no direct way to check if a declaration is const. + inline for(@typeInfo(@This()).@"struct".decls) |decl| { + const is_const = @typeInfo(@TypeOf(&@field(@This(), decl.name))).pointer.is_const; // Sadly there is no direct way to check if a declaration is const. if(!is_const) { const declType = @TypeOf(@field(@This(), decl.name)); - if(@typeInfo(declType) == .Struct) { + if(@typeInfo(declType) == .@"struct") { @compileError("Not implemented yet."); } - if(@typeInfo(declType) == .Pointer) { - if(@typeInfo(declType).Pointer.size == .Slice) { + if(@typeInfo(declType) == .pointer) { + if(@typeInfo(declType).pointer.size == .Slice) { main.globalAllocator.free(@field(@This(), decl.name)); } else { @compileError("Not implemented yet."); @@ -120,11 +120,11 @@ pub fn save() void { const jsonObject = JsonElement.initObject(main.stackAllocator); defer jsonObject.free(main.stackAllocator); - inline for(@typeInfo(@This()).Struct.decls) |decl| { - const is_const = @typeInfo(@TypeOf(&@field(@This(), decl.name))).Pointer.is_const; // Sadly there is no direct way to check if a declaration is const. + inline for(@typeInfo(@This()).@"struct".decls) |decl| { + const is_const = @typeInfo(@TypeOf(&@field(@This(), decl.name))).pointer.is_const; // Sadly there is no direct way to check if a declaration is const. if(!is_const) { const declType = @TypeOf(@field(@This(), decl.name)); - if(@typeInfo(declType) == .Struct) { + if(@typeInfo(declType) == .@"struct") { @compileError("Not implemented yet."); } if(declType == []const u8) { diff --git a/src/utils.zig b/src/utils.zig index ecb5ddf5..c7734b79 100644 --- a/src/utils.zig +++ b/src/utils.zig @@ -725,7 +725,7 @@ pub const NeverFailingAllocator = struct { // MARK: NeverFailingAllocator /// can be larger, smaller, or the same size as the old memory allocation. /// If `new_n` is 0, this is the same as `free` and it always succeeds. pub fn realloc(self: NeverFailingAllocator, old_mem: anytype, new_n: usize) t: { - const Slice = @typeInfo(@TypeOf(old_mem)).Pointer; + const Slice = @typeInfo(@TypeOf(old_mem)).pointer; break :t []align(Slice.alignment) Slice.child; } { return self.allocator.realloc(old_mem, new_n) catch unreachable; @@ -737,7 +737,7 @@ pub const NeverFailingAllocator = struct { // MARK: NeverFailingAllocator new_n: usize, return_address: usize, ) t: { - const Slice = @typeInfo(@TypeOf(old_mem)).Pointer; + const Slice = @typeInfo(@TypeOf(old_mem)).pointer; break :t []align(Slice.alignment) Slice.child; } { return self.allocator.reallocAdvanced(old_mem, new_n, return_address) catch unreachable; diff --git a/src/vec.zig b/src/vec.zig index 6ac29b85..616d0561 100644 --- a/src/vec.zig +++ b/src/vec.zig @@ -14,23 +14,23 @@ pub inline fn combine(pos: Vec3f, w: f32) Vec4f { return .{pos[0], pos[1], pos[2], w}; } -pub fn xyz(self: anytype) @Vector(3, @typeInfo(@TypeOf(self)).Vector.child) { - return @Vector(3, @typeInfo(@TypeOf(self)).Vector.child){self[0], self[1], self[2]}; +pub fn xyz(self: anytype) @Vector(3, @typeInfo(@TypeOf(self)).vector.child) { + return @Vector(3, @typeInfo(@TypeOf(self)).vector.child){self[0], self[1], self[2]}; } -pub fn xy(self: anytype) @Vector(2, @typeInfo(@TypeOf(self)).Vector.child) { - return @Vector(2, @typeInfo(@TypeOf(self)).Vector.child){self[0], self[1]}; +pub fn xy(self: anytype) @Vector(2, @typeInfo(@TypeOf(self)).vector.child) { + return @Vector(2, @typeInfo(@TypeOf(self)).vector.child){self[0], self[1]}; } -pub fn dot(self: anytype, other: @TypeOf(self)) @typeInfo(@TypeOf(self)).Vector.child { +pub fn dot(self: anytype, other: @TypeOf(self)) @typeInfo(@TypeOf(self)).vector.child { return @reduce(.Add, self*other); } -pub fn lengthSquare(self: anytype) @typeInfo(@TypeOf(self)).Vector.child { +pub fn lengthSquare(self: anytype) @typeInfo(@TypeOf(self)).vector.child { return @reduce(.Add, self*self); } -pub fn length(self: anytype) @typeInfo(@TypeOf(self)).Vector.child { +pub fn length(self: anytype) @typeInfo(@TypeOf(self)).vector.child { return @sqrt(@reduce(.Add, self*self)); } @@ -39,7 +39,7 @@ pub fn normalize(self: anytype) @TypeOf(self) { } pub fn cross(self: anytype, other: @TypeOf(self)) @TypeOf(self) { - if(@typeInfo(@TypeOf(self)).Vector.len != 3) @compileError("Only available for vectors of length 3."); + if(@typeInfo(@TypeOf(self)).vector.len != 3) @compileError("Only available for vectors of length 3."); return @TypeOf(self) { self[1]*other[2] - self[2]*other[1], self[2]*other[0] - self[0]*other[2], @@ -47,8 +47,8 @@ pub fn cross(self: anytype, other: @TypeOf(self)) @TypeOf(self) { }; } -pub fn rotateX(self: anytype, angle: @typeInfo(@TypeOf(self)).Vector.child) @TypeOf(self) { - if(@typeInfo(@TypeOf(self)).Vector.len != 3) @compileError("Only available for vectors of length 3."); +pub fn rotateX(self: anytype, angle: @typeInfo(@TypeOf(self)).vector.child) @TypeOf(self) { + if(@typeInfo(@TypeOf(self)).vector.len != 3) @compileError("Only available for vectors of length 3."); const sin = @sin(angle); const cos = @cos(angle); return @TypeOf(self){ @@ -58,8 +58,8 @@ pub fn rotateX(self: anytype, angle: @typeInfo(@TypeOf(self)).Vector.child) @Typ }; } -pub fn rotateY(self: anytype, angle: @typeInfo(@TypeOf(self)).Vector.child) @TypeOf(self) { - if(@typeInfo(@TypeOf(self)).Vector.len != 3) @compileError("Only available for vectors of length 3."); +pub fn rotateY(self: anytype, angle: @typeInfo(@TypeOf(self)).vector.child) @TypeOf(self) { + if(@typeInfo(@TypeOf(self)).vector.len != 3) @compileError("Only available for vectors of length 3."); const sin = @sin(angle); const cos = @cos(angle); return @TypeOf(self){ @@ -69,8 +69,8 @@ pub fn rotateY(self: anytype, angle: @typeInfo(@TypeOf(self)).Vector.child) @Typ }; } -pub fn rotateZ(self: anytype, angle: @typeInfo(@TypeOf(self)).Vector.child) @TypeOf(self) { - if(@typeInfo(@TypeOf(self)).Vector.len != 3) @compileError("Only available for vectors of length 3."); +pub fn rotateZ(self: anytype, angle: @typeInfo(@TypeOf(self)).vector.child) @TypeOf(self) { + if(@typeInfo(@TypeOf(self)).vector.len != 3) @compileError("Only available for vectors of length 3."); const sin = @sin(angle); const cos = @cos(angle); return @TypeOf(self){ From 72207c973e6639618babd6a78a7adfbe707e7f38 Mon Sep 17 00:00:00 2001 From: IntegratedQuantum Date: Sat, 14 Sep 2024 14:54:09 +0200 Subject: [PATCH 05/10] Refactor: Use decl literals, a recent addition to Zig. --- src/assets.zig | 14 +++---- src/blocks.zig | 28 +++++++------- src/chunk.zig | 6 +-- src/entity.zig | 2 +- src/game.zig | 10 ++--- src/graphics.zig | 22 +++++------ src/gui/components/HorizontalList.zig | 2 +- src/gui/components/TextInput.zig | 2 +- src/gui/components/VerticalList.zig | 2 +- src/gui/gui.zig | 14 +++---- src/gui/windows/chat.zig | 6 +-- src/gui/windows/creative_inventory.zig | 2 +- src/gui/windows/inventory_crafting.zig | 4 +- src/gui/windows/invite.zig | 2 +- src/gui/windows/multiplayer.zig | 2 +- src/itemdrop.zig | 8 ++-- src/items.zig | 8 ++-- src/json.zig | 18 ++++----- src/models.zig | 10 ++--- src/network.zig | 38 +++++++++---------- src/renderer.zig | 4 +- src/renderer/chunk_meshing.zig | 6 +-- src/renderer/lighting.zig | 2 +- src/renderer/mesh_storage.zig | 2 +- src/rotation.zig | 10 ++--- src/server/command/_command.zig | 2 +- src/server/server.zig | 10 ++--- src/server/storage.zig | 2 +- src/server/terrain/CaveBiomeMap.zig | 2 +- src/server/terrain/CaveMap.zig | 2 +- src/server/terrain/ClimateMap.zig | 2 +- src/server/terrain/LightMap.zig | 2 +- src/server/terrain/StructureMap.zig | 4 +- src/server/terrain/SurfaceMap.zig | 4 +- src/server/terrain/biomes.zig | 18 ++++----- .../terrain/noise/CachedFractalNoise.zig | 2 +- src/server/world.zig | 16 ++++---- src/utils.zig | 12 +++--- src/utils/file_monitor.zig | 10 ++--- 39 files changed, 156 insertions(+), 156 deletions(-) diff --git a/src/assets.zig b/src/assets.zig index f048e0ba..549708b8 100644 --- a/src/assets.zig +++ b/src/assets.zig @@ -174,13 +174,13 @@ pub fn readAssets(externalAllocator: NeverFailingAllocator, assetPath: []const u pub fn init() void { biomes_zig.init(); blocks_zig.init(); - arena = main.utils.NeverFailingArenaAllocator.init(main.globalAllocator); + arena = .init(main.globalAllocator); arenaAllocator = arena.allocator(); - commonBlocks = std.StringHashMap(JsonElement).init(arenaAllocator.allocator); - commonItems = std.StringHashMap(JsonElement).init(arenaAllocator.allocator); - commonBiomes = std.StringHashMap(JsonElement).init(arenaAllocator.allocator); - commonRecipes = main.List([]const u8).init(arenaAllocator); - commonModels = std.StringHashMap([]const u8).init(arenaAllocator.allocator); + commonBlocks = .init(arenaAllocator.allocator); + commonItems = .init(arenaAllocator.allocator); + commonBiomes = .init(arenaAllocator.allocator); + commonRecipes = .init(arenaAllocator); + commonModels = .init(arenaAllocator.allocator); readAssets(arenaAllocator, "assets/", &commonBlocks, &commonItems, &commonBiomes, &commonRecipes, &commonModels); } @@ -218,7 +218,7 @@ pub const Palette = struct { // MARK: Palette pub fn init(allocator: NeverFailingAllocator, json: JsonElement, firstElement: ?[]const u8) !*Palette { const self = allocator.create(Palette); self.* = Palette { - .palette = main.List([]const u8).init(allocator), + .palette = .init(allocator), }; errdefer self.deinit(); if(json != .JsonObject or json.JsonObject.count() == 0) { diff --git a/src/blocks.zig b/src/blocks.zig index e3e29fd7..a1edb745 100644 --- a/src/blocks.zig +++ b/src/blocks.zig @@ -87,12 +87,12 @@ var reverseIndices = std.StringHashMap(u16).init(allocator.allocator); var size: u32 = 0; -pub var ores: main.List(Ore) = main.List(Ore).init(allocator); +pub var ores: main.List(Ore) = .init(allocator); var unfinishedOreSourceBlockIds: main.List([][]const u8) = undefined; pub fn init() void { - unfinishedOreSourceBlockIds = main.List([][]const u8).init(main.globalAllocator); + unfinishedOreSourceBlockIds = .init(main.globalAllocator); } pub fn deinit() void { @@ -218,7 +218,7 @@ pub fn reset() void { ores.clearAndFree(); meshes.reset(); _ = arena.reset(.free_all); - reverseIndices = std.StringHashMap(u16).init(arena.allocator().allocator); + reverseIndices = .init(arena.allocator().allocator); std.debug.assert(unfinishedOreSourceBlockIds.items.len == 0); } @@ -394,17 +394,17 @@ pub const meshes = struct { // MARK: meshes pub fn init() void { animationShader = Shader.initComputeAndGetUniforms("assets/cubyz/shaders/animation_pre_processing.glsl", "", &animationUniforms); - blockTextureArray = TextureArray.init(); - emissionTextureArray = TextureArray.init(); - reflectivityAndAbsorptionTextureArray = TextureArray.init(); - textureIDs = main.List([]const u8).init(main.globalAllocator); - animation = main.List(AnimationData).init(main.globalAllocator); - blockTextures = main.List(Image).init(main.globalAllocator); - emissionTextures = main.List(Image).init(main.globalAllocator); - reflectivityTextures = main.List(Image).init(main.globalAllocator); - absorptionTextures = main.List(Image).init(main.globalAllocator); - textureFogData = main.List(FogData).init(main.globalAllocator); - arenaForWorld = main.utils.NeverFailingArenaAllocator.init(main.globalAllocator); + blockTextureArray = .init(); + emissionTextureArray = .init(); + reflectivityAndAbsorptionTextureArray = .init(); + textureIDs = .init(main.globalAllocator); + animation = .init(main.globalAllocator); + blockTextures = .init(main.globalAllocator); + emissionTextures = .init(main.globalAllocator); + reflectivityTextures = .init(main.globalAllocator); + absorptionTextures = .init(main.globalAllocator); + textureFogData = .init(main.globalAllocator); + arenaForWorld = .init(main.globalAllocator); } pub fn deinit() void { diff --git a/src/chunk.zig b/src/chunk.zig index 6c13a98b..1b086a94 100644 --- a/src/chunk.zig +++ b/src/chunk.zig @@ -130,8 +130,8 @@ var serverPool: std.heap.MemoryPoolAligned(ServerChunk, @alignOf(ServerChunk)) = var serverPoolMutex: std.Thread.Mutex = .{}; pub fn init() void { - memoryPool = std.heap.MemoryPoolAligned(Chunk, @alignOf(Chunk)).init(main.globalAllocator.allocator); - serverPool = std.heap.MemoryPoolAligned(ServerChunk, @alignOf(ServerChunk)).init(main.globalAllocator.allocator); + memoryPool = .init(main.globalAllocator.allocator); + serverPool = .init(main.globalAllocator.allocator); } pub fn deinit() void { @@ -281,7 +281,7 @@ pub const ServerChunk = struct { // MARK: ServerChunk .voxelSizeMask = pos.voxelSize - 1, .widthShift = voxelSizeShift + chunkShift, }, - .refCount = std.atomic.Value(u16).init(1), + .refCount = .init(1), }; self.super.data.init(); return self; diff --git a/src/entity.zig b/src/entity.zig index 2b196e65..52bc8690 100644 --- a/src/entity.zig +++ b/src/entity.zig @@ -89,7 +89,7 @@ pub const ClientEntityManager = struct { pub var mutex: std.Thread.Mutex = std.Thread.Mutex{}; pub fn init() void { - entities = main.VirtualList(ClientEntity, 1 << 20).init(); + entities = .init(); shader = graphics.Shader.initAndGetUniforms("assets/cubyz/shaders/entity_vertex.vs", "assets/cubyz/shaders/entity_fragment.fs", "", &uniforms); } diff --git a/src/game.zig b/src/game.zig index 0596cb44..0ec524a5 100644 --- a/src/game.zig +++ b/src/game.zig @@ -330,9 +330,9 @@ pub const Player = struct { // MARK: Player pub var eyeCoyote: f64 = 0; pub var eyeStep: @Vector(3, bool) = .{false, false, false}; pub var id: u32 = 0; - pub var isFlying: Atomic(bool) = Atomic(bool).init(false); - pub var isGhost: Atomic(bool) = Atomic(bool).init(false); - pub var hyperSpeed: Atomic(bool) = Atomic(bool).init(false); + pub var isFlying: Atomic(bool) = .init(false); + pub var isGhost: Atomic(bool) = .init(false); + pub var hyperSpeed: Atomic(bool) = .init(false); pub var mutex: std.Thread.Mutex = std.Thread.Mutex{}; pub var inventory__SEND_CHANGES_TO_SERVER: Inventory = undefined; pub var selectedSlot: u32 = 0; @@ -477,7 +477,7 @@ pub const World = struct { // MARK: World gravity: f64 = 9.81*1.5, // TODO: Balance name: []const u8, milliTime: i64, - gameTime: Atomic(i64) = Atomic(i64).init(0), + gameTime: Atomic(i64) = .init(0), spawn: Vec3f = undefined, blockPalette: *assets.Palette = undefined, biomePalette: *assets.Palette = undefined, @@ -499,7 +499,7 @@ pub const World = struct { // MARK: World main.blocks.meshes.generateTextureArray(); main.models.uploadModels(); - self.playerBiome = Atomic(*const main.server.terrain.biomes.Biome).init(main.server.terrain.biomes.getById("")); + self.playerBiome = .init(main.server.terrain.biomes.getById("")); main.audio.setMusic(self.playerBiome.raw.preferredMusic); } diff --git a/src/graphics.zig b/src/graphics.zig index 51ca0038..70a82c48 100644 --- a/src/graphics.zig +++ b/src/graphics.zig @@ -654,16 +654,16 @@ pub const TextBuffer = struct { // MARK: TextBuffer var parser = Parser { .unicodeIterator = std.unicode.Utf8Iterator{.bytes = text, .i = 0}, .currentFontEffect = initialFontEffect, - .parsedText = main.List(u32).init(main.stackAllocator), - .fontEffects = main.List(FontEffect).init(allocator), - .characterIndex = main.List(u32).init(allocator), + .parsedText = .init(main.stackAllocator), + .fontEffects = .init(allocator), + .characterIndex = .init(allocator), .showControlCharacters = showControlCharacters }; defer parser.fontEffects.deinit(); defer parser.parsedText.deinit(); defer parser.characterIndex.deinit(); - self.lines = main.List(Line).init(allocator); - self.lineBreaks = main.List(LineBreak).init(allocator); + self.lines = .init(allocator); + self.lineBreaks = .init(allocator); parser.parse(); if(parser.parsedText.items.len == 0) { self.lineBreaks.append(.{.index = 0, .width = 0}); @@ -1027,8 +1027,8 @@ const TextRendering = struct { // MARK: TextRendering harfbuzzFace = hbft.hb_ft_face_create_referenced(freetypeFace); harfbuzzFont = hbft.hb_font_create(harfbuzzFace); - glyphMapping = main.List(u31).init(main.globalAllocator); - glyphData = main.List(Glyph).init(main.globalAllocator); + glyphMapping = .init(main.globalAllocator); + glyphData = .init(main.globalAllocator); glyphData.append(undefined); // 0 is a reserved value. c.glGenTextures(2, &glyphTexture); c.glBindTexture(c.GL_TEXTURE_2D, glyphTexture[0]); @@ -1319,7 +1319,7 @@ pub fn LargeBuffer(comptime Entry: type) type { // MARK: LargerBuffer const Self = @This(); fn createBuffer(self: *Self, size: u31) void { - self.ssbo = SSBO.init(); + self.ssbo = .init(); c.glBindBuffer(c.GL_SHADER_STORAGE_BUFFER, self.ssbo.bufferID); const flags = c.GL_MAP_WRITE_BIT | c.GL_DYNAMIC_STORAGE_BIT; const bytes = @as(c.GLsizeiptr, size)*@sizeOf(Entry); @@ -1336,10 +1336,10 @@ pub fn LargeBuffer(comptime Entry: type) type { // MARK: LargerBuffer fence.* = c.glFenceSync(c.GL_SYNC_GPU_COMMANDS_COMPLETE, 0); } for(&self.fencedFreeLists) |*list| { - list.* = main.List(SubAllocation).init(allocator); + list.* = .init(allocator); } - self.freeBlocks = main.List(SubAllocation).init(allocator); + self.freeBlocks = .init(allocator); self.freeBlocks.append(.{.start = 0, .len = size}); } @@ -1935,7 +1935,7 @@ const block_texture = struct { // MARK: block_texture fn init() void { shader = Shader.initAndGetUniforms("assets/cubyz/shaders/item_texture_post.vs", "assets/cubyz/shaders/item_texture_post.fs", "", &uniforms); - depthTexture = Texture.init(); + depthTexture = .init(); depthTexture.bind(); var data: [128*128]f32 = undefined; diff --git a/src/gui/components/HorizontalList.zig b/src/gui/components/HorizontalList.zig index 6bc24f7d..b791b364 100644 --- a/src/gui/components/HorizontalList.zig +++ b/src/gui/components/HorizontalList.zig @@ -19,7 +19,7 @@ children: main.List(GuiComponent), pub fn init() *HorizontalList { const self = main.globalAllocator.create(HorizontalList); self.* = HorizontalList { - .children = main.List(GuiComponent).init(main.globalAllocator), + .children = .init(main.globalAllocator), .pos = .{0, 0}, .size = .{0, 0}, }; diff --git a/src/gui/components/TextInput.zig b/src/gui/components/TextInput.zig index ec619560..fb6d7eef 100644 --- a/src/gui/components/TextInput.zig +++ b/src/gui/components/TextInput.zig @@ -48,7 +48,7 @@ pub fn init(pos: Vec2f, maxWidth: f32, maxHeight: f32, text: []const u8, onNewli self.* = TextInput { .pos = pos, .size = .{maxWidth, maxHeight}, - .currentString = main.List(u8).init(main.globalAllocator), + .currentString = .init(main.globalAllocator), .textBuffer = TextBuffer.init(main.globalAllocator, text, .{}, true, .left), .maxWidth = maxWidth, .maxHeight = maxHeight, diff --git a/src/gui/components/VerticalList.zig b/src/gui/components/VerticalList.zig index 1a17ebcc..703ba55c 100644 --- a/src/gui/components/VerticalList.zig +++ b/src/gui/components/VerticalList.zig @@ -29,7 +29,7 @@ pub fn init(pos: Vec2f, maxHeight: f32, padding: f32) *VerticalList { const scrollBar = ScrollBar.init(undefined, scrollBarWidth, maxHeight - 2*border, 0); const self = main.globalAllocator.create(VerticalList); self.* = VerticalList { - .children = main.List(GuiComponent).init(main.globalAllocator), + .children = .init(main.globalAllocator), .pos = pos, .size = .{0, 0}, .padding = padding, diff --git a/src/gui/gui.zig b/src/gui/gui.zig index 6c388c2b..f651605f 100644 --- a/src/gui/gui.zig +++ b/src/gui/gui.zig @@ -52,7 +52,7 @@ const GuiCommandQueue = struct { // MARK: GuiCommandQueue fn init() void { mutex.lock(); defer mutex.unlock(); - commands = List(Command).init(main.globalAllocator); + commands = .init(main.globalAllocator); } fn deinit() void { @@ -128,9 +128,9 @@ pub const Callback = struct { pub fn init() void { // MARK: init() GuiCommandQueue.init(); - windowList = List(*GuiWindow).init(main.globalAllocator); - hudWindows = List(*GuiWindow).init(main.globalAllocator); - openWindows = List(*GuiWindow).init(main.globalAllocator); + windowList = .init(main.globalAllocator); + hudWindows = .init(main.globalAllocator); + openWindows = .init(main.globalAllocator); inline for(@typeInfo(windowlist).@"struct".decls) |decl| { const windowStruct = @field(windowlist, decl.name); windowStruct.window.id = decl.name; @@ -596,8 +596,8 @@ pub const inventory = struct { // MARK: inventory var initialAmount: u16 = 0; pub fn init() void { - deliveredItemSlots = List(*ItemSlot).init(main.globalAllocator); - deliveredItemStacksAmountAdded = List(u16).init(main.globalAllocator); + deliveredItemSlots = .init(main.globalAllocator); + deliveredItemStacksAmountAdded = .init(main.globalAllocator); carriedItemSlot = ItemSlot.init(.{0, 0}, carriedItemStack, undefined, undefined, .default, .normal); carriedItemSlot.renderFrame = false; } @@ -695,7 +695,7 @@ pub const inventory = struct { // MARK: inventory if(carriedItemStack.amount == 0) if(hoveredItemSlot) |hovered| { if(hovered.itemStack.item) |item| { const tooltip = item.getTooltip(); - var textBuffer: graphics.TextBuffer = graphics.TextBuffer.init(main.stackAllocator, tooltip, .{}, false, .left); + var textBuffer = graphics.TextBuffer.init(main.stackAllocator, tooltip, .{}, false, .left); defer textBuffer.deinit(); var size = textBuffer.calculateLineBreaks(16, 256); size[0] = 0; diff --git a/src/gui/windows/chat.zig b/src/gui/windows/chat.zig index c49fb8d1..7b4a9aa9 100644 --- a/src/gui/windows/chat.zig +++ b/src/gui/windows/chat.zig @@ -70,9 +70,9 @@ fn refresh() void { } pub fn onOpen() void { - history = main.List(*Label).init(main.globalAllocator); - expirationTime = main.List(i32).init(main.globalAllocator); - messageQueue = main.List([]const u8).init(main.globalAllocator); + history = .init(main.globalAllocator); + expirationTime = .init(main.globalAllocator); + messageQueue = .init(main.globalAllocator); historyStart = 0; fadeOutEnd = 0; input = TextInput.init(.{0, 0}, 256, 32, "", .{.callback = &sendMessage}); diff --git a/src/gui/windows/creative_inventory.zig b/src/gui/windows/creative_inventory.zig index 7857a7cf..fa15ab1a 100644 --- a/src/gui/windows/creative_inventory.zig +++ b/src/gui/windows/creative_inventory.zig @@ -48,7 +48,7 @@ fn lessThan(_: void, lhs: Item, rhs: Item) bool { } pub fn onOpen() void { - items = main.List(Item).init(main.globalAllocator); + items = .init(main.globalAllocator); var itemIterator = main.items.iterator(); while(itemIterator.next()) |item| { items.append(Item{.baseItem = item.*}); diff --git a/src/gui/windows/inventory_crafting.zig b/src/gui/windows/inventory_crafting.zig index c5082875..0f4e436a 100644 --- a/src/gui/windows/inventory_crafting.zig +++ b/src/gui/windows/inventory_crafting.zig @@ -159,8 +159,8 @@ fn refresh() void { } pub fn onOpen() void { - availableItems = main.List(*BaseItem).init(main.globalAllocator); - itemAmount = main.List(u32).init(main.globalAllocator); + availableItems = .init(main.globalAllocator); + itemAmount = .init(main.globalAllocator); refresh(); } diff --git a/src/gui/windows/invite.zig b/src/gui/windows/invite.zig index 361c3277..d49a3f72 100644 --- a/src/gui/windows/invite.zig +++ b/src/gui/windows/invite.zig @@ -23,7 +23,7 @@ var ipAddressEntry: *TextInput = undefined; const padding: f32 = 8; var ipAddress: []const u8 = ""; -var gotIpAddress: std.atomic.Value(bool) = std.atomic.Value(bool).init(false); +var gotIpAddress: std.atomic.Value(bool) = .init(false); var thread: ?std.Thread = null; const width: f32 = 420; diff --git a/src/gui/windows/multiplayer.zig b/src/gui/windows/multiplayer.zig index 4aab320e..2d401bfd 100644 --- a/src/gui/windows/multiplayer.zig +++ b/src/gui/windows/multiplayer.zig @@ -24,7 +24,7 @@ const padding: f32 = 8; var connection: ?*ConnectionManager = null; var ipAddress: []const u8 = ""; -var gotIpAddress: std.atomic.Value(bool) = std.atomic.Value(bool).init(false); +var gotIpAddress: std.atomic.Value(bool) = .init(false); var thread: ?std.Thread = null; const width: f32 = 420; diff --git a/src/itemdrop.zig b/src/itemdrop.zig index be76f640..69c86f84 100644 --- a/src/itemdrop.zig +++ b/src/itemdrop.zig @@ -71,7 +71,7 @@ pub const ItemDropManager = struct { // MARK: ItemDropManager .allocator = allocator, .list = std.MultiArrayList(ItemDrop){}, .lastUpdates = JsonElement.initArray(allocator), - .isEmpty = std.bit_set.ArrayBitSet(usize, maxCapacity).initFull(), + .isEmpty = .initFull(), .world = world, .gravity = gravity, .airDragFactor = gravity/maxSpeed, @@ -590,12 +590,12 @@ pub const ItemDropRenderer = struct { // MARK: ItemDropRenderer pub fn init() void { itemShader = graphics.Shader.initAndGetUniforms("assets/cubyz/shaders/item_drop.vs", "assets/cubyz/shaders/item_drop.fs", "", &itemUniforms); - itemModelSSBO = graphics.SSBO.init(); + itemModelSSBO = .init(); itemModelSSBO.bufferData(i32, &[3]i32{1, 1, 1}); itemModelSSBO.bind(2); - modelData = main.List(u32).init(main.globalAllocator); - freeSlots = main.List(*ItemVoxelModel).init(main.globalAllocator); + modelData = .init(main.globalAllocator); + freeSlots = .init(main.globalAllocator); } pub fn deinit() void { diff --git a/src/items.zig b/src/items.zig index c32178d3..d9b84d1a 100644 --- a/src/items.zig +++ b/src/items.zig @@ -173,7 +173,7 @@ const TextureGenerator = struct { // MARK: TextureGenerator items: main.List(*const BaseItem), pub fn init(allocator: NeverFailingAllocator) PixelData { return PixelData { - .items = main.List(*const BaseItem).init(allocator), + .items = .init(allocator), }; } pub fn deinit(self: *PixelData) void { @@ -1299,9 +1299,9 @@ pub fn recipes() []Recipe { } pub fn globalInit() void { - arena = main.utils.NeverFailingArenaAllocator.init(main.globalAllocator); - reverseIndices = std.StringHashMap(*BaseItem).init(arena.allocator().allocator); - recipeList = main.List(Recipe).init(arena.allocator()); + arena = .init(main.globalAllocator); + reverseIndices = .init(arena.allocator().allocator); + recipeList = .init(arena.allocator()); itemListSize = 0; } diff --git a/src/json.zig b/src/json.zig index 858be88a..7145cc04 100644 --- a/src/json.zig +++ b/src/json.zig @@ -25,14 +25,14 @@ pub const JsonElement = union(JsonType) { // MARK: JsonElement JsonObject: *std.StringHashMap(JsonElement), pub fn initObject(allocator: NeverFailingAllocator) JsonElement { - const map: *std.StringHashMap(JsonElement) = allocator.create(std.StringHashMap(JsonElement)); - map.* = std.StringHashMap(JsonElement).init(allocator.allocator); + const map = allocator.create(std.StringHashMap(JsonElement)); + map.* = .init(allocator.allocator); return JsonElement{.JsonObject=map}; } pub fn initArray(allocator: NeverFailingAllocator) JsonElement { - const list: *List(JsonElement) = allocator.create(List(JsonElement)); - list.* = List(JsonElement).init(allocator); + const list = allocator.create(List(JsonElement)); + list.* = .init(allocator); return JsonElement{.JsonArray=list}; } @@ -456,7 +456,7 @@ const Parser = struct { // MARK: Parser } fn parseString(allocator: NeverFailingAllocator, chars: []const u8, index: *u32) []const u8 { - var builder: List(u8) = List(u8).init(allocator); + var builder = List(u8).init(allocator); while(index.* < chars.len): (index.* += 1) { if(chars[index.*] == '\"') { index.* += 1; @@ -487,8 +487,8 @@ const Parser = struct { // MARK: Parser } fn parseArray(allocator: NeverFailingAllocator, chars: []const u8, index: *u32) JsonElement { - const list: *List(JsonElement) = allocator.create(List(JsonElement)); - list.* = List(JsonElement).init(allocator); + const list = allocator.create(List(JsonElement)); + list.* = .init(allocator); while(index.* < chars.len) { skipWhitespaces(chars, index); if(index.* >= chars.len) break; @@ -507,8 +507,8 @@ const Parser = struct { // MARK: Parser } fn parseObject(allocator: NeverFailingAllocator, chars: []const u8, index: *u32) JsonElement { - const map: *std.StringHashMap(JsonElement) = allocator.create(std.StringHashMap(JsonElement)); - map.* = std.StringHashMap(JsonElement).init(allocator.allocator); + const map = allocator.create(std.StringHashMap(JsonElement)); + map.* = .init(allocator.allocator); while(index.* < chars.len) { skipWhitespaces(chars, index); if(index.* >= chars.len) break; diff --git a/src/models.zig b/src/models.zig index cafe5da0..0cdc1f3a 100644 --- a/src/models.zig +++ b/src/models.zig @@ -529,12 +529,12 @@ pub fn registerModel(id: []const u8, data: []const u8) u16 { // TODO: Entity models. pub fn init() void { - models = main.List(Model).init(main.globalAllocator); - quads = main.List(QuadInfo).init(main.globalAllocator); - extraQuadInfos = main.List(ExtraQuadInfo).init(main.globalAllocator); - quadDeduplication = std.AutoHashMap([@sizeOf(QuadInfo)]u8, u16).init(main.globalAllocator.allocator); + models = .init(main.globalAllocator); + quads = .init(main.globalAllocator); + extraQuadInfos = .init(main.globalAllocator); + quadDeduplication = .init(main.globalAllocator.allocator); - nameToIndex = std.StringHashMap(u16).init(main.globalAllocator.allocator); + nameToIndex = .init(main.globalAllocator.allocator); nameToIndex.put("none", Model.init(&.{})) catch unreachable; } diff --git a/src/network.zig b/src/network.zig index 448a056c..a9b0355c 100644 --- a/src/network.zig +++ b/src/network.zig @@ -390,8 +390,8 @@ pub const ConnectionManager = struct { // MARK: ConnectionManager thread: std.Thread = undefined, threadId: std.Thread.Id = undefined, externalAddress: Address = undefined, - online: Atomic(bool) = Atomic(bool).init(false), - running: Atomic(bool) = Atomic(bool).init(true), + online: Atomic(bool) = .init(false), + running: Atomic(bool) = .init(true), connections: main.List(*Connection) = undefined, requests: main.List(*Request) = undefined, @@ -421,9 +421,9 @@ pub const ConnectionManager = struct { // MARK: ConnectionManager const result: *ConnectionManager = main.globalAllocator.create(ConnectionManager); errdefer main.globalAllocator.destroy(result); result.* = .{}; - result.connections = main.List(*Connection).init(main.globalAllocator); - result.requests = main.List(*Request).init(main.globalAllocator); - result.packetSendRequests = std.PriorityQueue(PacketSendRequest, void, PacketSendRequest.compare).init(main.globalAllocator.allocator, {}); + result.connections = .init(main.globalAllocator); + result.requests = .init(main.globalAllocator); + result.packetSendRequests = .init(main.globalAllocator.allocator, {}); result.localPort = localPort; result.socket = Socket.init(localPort) catch |err| blk: { @@ -650,8 +650,8 @@ const UnconfirmedPacket = struct { }; // MARK: Protocols -pub var bytesReceived: [256]Atomic(usize) = [_]Atomic(usize) {Atomic(usize).init(0)} ** 256; -pub var packetsReceived: [256]Atomic(usize) = [_]Atomic(usize) {Atomic(usize).init(0)} ** 256; +pub var bytesReceived: [256]Atomic(usize) = .{Atomic(usize).init(0)} ** 256; +pub var packetsReceived: [256]Atomic(usize) = .{Atomic(usize).init(0)} ** 256; pub const Protocols = struct { pub var list: [256]?*const fn(*Connection, []const u8) anyerror!void = [_]?*const fn(*Connection, []const u8) anyerror!void {null} ** 256; pub var isAsynchronous: [256]bool = .{false} ** 256; @@ -1282,8 +1282,8 @@ pub const Connection = struct { // MARK: Connection const timeUnit = 100_000_000; // Statistics: - pub var packetsSent: Atomic(u32) = Atomic(u32).init(0); - pub var packetsResent: Atomic(u32) = Atomic(u32).init(0); + pub var packetsSent: Atomic(u32) = .init(0); + pub var packetsResent: Atomic(u32) = .init(0); manager: *ConnectionManager, user: ?*main.server.User, @@ -1318,8 +1318,8 @@ pub const Connection = struct { // MARK: Connection congestionControl_bandWidthUsed: usize = 0, congestionControl_curPosition: usize = 0, - disconnected: Atomic(bool) = Atomic(bool).init(false), - handShakeState: Atomic(u8) = Atomic(u8).init(Protocols.handShake.stepStart), + disconnected: Atomic(bool) = .init(false), + handShakeState: Atomic(u8) = .init(Protocols.handShake.stepStart), handShakeWaiting: std.Thread.Condition = std.Thread.Condition{}, lastConnection: i64, @@ -1339,14 +1339,14 @@ pub const Connection = struct { // MARK: Connection .congestionControl_sendTimeLimit = @as(i64, @truncate(std.time.nanoTimestamp())) +% timeUnit*21/20, }; errdefer main.globalAllocator.free(result.packetMemory); - result.unconfirmedPackets = main.List(UnconfirmedPacket).init(main.globalAllocator); + result.unconfirmedPackets = .init(main.globalAllocator); errdefer result.unconfirmedPackets.deinit(); - result.packetQueue = main.utils.CircularBufferQueue(UnconfirmedPacket).init(main.globalAllocator, 1024); + result.packetQueue = .init(main.globalAllocator, 1024); errdefer result.packetQueue.deinit(); result.receivedPackets = [3]main.List(u32){ - main.List(u32).init(main.globalAllocator), - main.List(u32).init(main.globalAllocator), - main.List(u32).init(main.globalAllocator), + .init(main.globalAllocator), + .init(main.globalAllocator), + .init(main.globalAllocator), }; errdefer for(&result.receivedPackets) |*list| { list.deinit(); @@ -1385,7 +1385,7 @@ pub const Connection = struct { // MARK: Connection self.receivedPackets[2].clearRetainingCapacity(); self.lastIndex = 0; self.lastIncompletePacket = 0; - self.handShakeState = Atomic(u8).init(Protocols.handShake.stepStart); + self.handShakeState = .init(Protocols.handShake.stepStart); } pub fn deinit(self: *Connection) void { @@ -1524,9 +1524,9 @@ pub const Connection = struct { // MARK: Connection self.mutex.lock(); defer self.mutex.unlock(); - var runLengthEncodingStarts: main.List(u32) = main.List(u32).init(main.stackAllocator); + var runLengthEncodingStarts = main.List(u32).init(main.stackAllocator); defer runLengthEncodingStarts.deinit(); - var runLengthEncodingLengths: main.List(u32) = main.List(u32).init(main.stackAllocator); + var runLengthEncodingLengths = main.List(u32).init(main.stackAllocator); defer runLengthEncodingLengths.deinit(); for(self.receivedPackets) |list| { diff --git a/src/renderer.zig b/src/renderer.zig index faa7e572..ce5eae8f 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -69,7 +69,7 @@ pub fn init() void { }; chunk_meshing.init(); mesh_storage.init(); - reflectionCubeMap = graphics.CubeMapTexture.init(); + reflectionCubeMap = .init(); reflectionCubeMap.generate(reflectionCubeMapSize, reflectionCubeMapSize); initReflectionCubeMap(); } @@ -312,7 +312,7 @@ const Bloom = struct { // MARK: Bloom pub fn init() void { buffer1.init(false, c.GL_LINEAR, c.GL_CLAMP_TO_EDGE); buffer2.init(false, c.GL_LINEAR, c.GL_CLAMP_TO_EDGE); - emptyBuffer = graphics.Texture.init(); + emptyBuffer = .init(); emptyBuffer.generate(graphics.Image.emptyImage); firstPassShader = graphics.Shader.init("assets/cubyz/shaders/bloom/first_pass.vs", "assets/cubyz/shaders/bloom/first_pass.fs", ""); secondPassShader = graphics.Shader.init("assets/cubyz/shaders/bloom/second_pass.vs", "assets/cubyz/shaders/bloom/second_pass.fs", ""); diff --git a/src/renderer/chunk_meshing.zig b/src/renderer/chunk_meshing.zig index 73c33367..9a76c6d7 100644 --- a/src/renderer/chunk_meshing.zig +++ b/src/renderer/chunk_meshing.zig @@ -684,12 +684,12 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh sortingOutputBuffer: []FaceData = &.{}, culledSortingCount: u31 = 0, lastTransparentUpdatePos: Vec3i = Vec3i{0, 0, 0}, - refCount: std.atomic.Value(u32) = std.atomic.Value(u32).init(1), - needsLightRefresh: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + refCount: std.atomic.Value(u32) = .init(1), + needsLightRefresh: std.atomic.Value(bool) = .init(false), needsMeshUpdate: bool = false, finishedMeshing: bool = false, finishedLighting: bool = false, - litNeighbors: Atomic(u32) = Atomic(u32).init(0), + litNeighbors: Atomic(u32) = .init(0), mutex: std.Thread.Mutex = .{}, chunkAllocation: graphics.SubAllocation = .{.start = 0, .len = 0}, min: Vec3f = undefined, diff --git a/src/renderer/lighting.zig b/src/renderer/lighting.zig index 1c789407..09ce5df9 100644 --- a/src/renderer/lighting.zig +++ b/src/renderer/lighting.zig @@ -11,7 +11,7 @@ var memoryPool: std.heap.MemoryPool(ChannelChunk) = undefined; var memoryPoolMutex: std.Thread.Mutex = .{}; pub fn init() void { - memoryPool = std.heap.MemoryPool(ChannelChunk).init(main.globalAllocator.allocator); + memoryPool = .init(main.globalAllocator.allocator); } pub fn deinit() void { diff --git a/src/renderer/mesh_storage.zig b/src/renderer/mesh_storage.zig index 2dbd7b39..66ba1802 100644 --- a/src/renderer/mesh_storage.zig +++ b/src/renderer/mesh_storage.zig @@ -55,7 +55,7 @@ var blockUpdateList: main.List(BlockUpdate) = undefined; pub fn init() void { // MARK: init() lastRD = 0; - blockUpdateList = main.List(BlockUpdate).init(main.globalAllocator); + blockUpdateList = .init(main.globalAllocator); for(&storageLists) |*storageList| { storageList.* = main.globalAllocator.create([storageSize*storageSize*storageSize]ChunkMeshNode); for(storageList.*) |*val| { diff --git a/src/rotation.zig b/src/rotation.zig index e4814dc3..29b431c2 100644 --- a/src/rotation.zig +++ b/src/rotation.zig @@ -93,7 +93,7 @@ pub const RotationModes = struct { var rotatedModels: std.StringHashMap(u16) = undefined; fn init() void { - rotatedModels = std.StringHashMap(u16).init(main.globalAllocator.allocator); + rotatedModels = .init(main.globalAllocator.allocator); } fn deinit() void { @@ -138,7 +138,7 @@ pub const RotationModes = struct { var rotatedModels: std.StringHashMap(u16) = undefined; fn init() void { - rotatedModels = std.StringHashMap(u16).init(main.globalAllocator.allocator); + rotatedModels = .init(main.globalAllocator.allocator); } fn deinit() void { @@ -189,7 +189,7 @@ pub const RotationModes = struct { }; fn init() void { - fenceModels = std.StringHashMap(u16).init(main.globalAllocator.allocator); + fenceModels = .init(main.globalAllocator.allocator); } fn deinit() void { @@ -557,7 +557,7 @@ pub const RotationModes = struct { }; fn init() void { - rotatedModels = std.StringHashMap(u16).init(main.globalAllocator.allocator); + rotatedModels = .init(main.globalAllocator.allocator); } fn deinit() void { @@ -668,7 +668,7 @@ pub const RotationModes = struct { // MARK: init/register pub fn init() void { - rotationModes = std.StringHashMap(RotationMode).init(main.globalAllocator.allocator); + rotationModes = .init(main.globalAllocator.allocator); inline for(@typeInfo(RotationModes).@"struct".decls) |declaration| { register(@field(RotationModes, declaration.name)); } diff --git a/src/server/command/_command.zig b/src/server/command/_command.zig index 6b87e6c0..dfa0e468 100644 --- a/src/server/command/_command.zig +++ b/src/server/command/_command.zig @@ -13,7 +13,7 @@ pub const Command = struct { pub var commands: std.StringHashMap(Command) = undefined; pub fn init() void { - commands = std.StringHashMap(Command).init(main.globalAllocator.allocator); + commands = .init(main.globalAllocator.allocator); const commandList = @import("_list.zig"); inline for(@typeInfo(commandList).@"struct".decls) |decl| { commands.put(decl.name, .{ diff --git a/src/server/server.zig b/src/server/server.zig index 41a28fc5..468c3811 100644 --- a/src/server/server.zig +++ b/src/server/server.zig @@ -38,9 +38,9 @@ pub const User = struct { // MARK: User lastRenderDistance: u16 = 0, lastPos: Vec3i = @splat(0), - connected: Atomic(bool) = Atomic(bool).init(true), + connected: Atomic(bool) = .init(true), - refCount: Atomic(u32) = Atomic(u32).init(1), + refCount: Atomic(u32) = .init(1), pub fn initAndIncreaseRefCount(manager: *ConnectionManager, ipPort: []const u8) !*User { const self = main.globalAllocator.create(User); @@ -195,7 +195,7 @@ pub var userDeinitList: main.List(*User) = undefined; pub var connectionManager: *ConnectionManager = undefined; -pub var running: std.atomic.Value(bool) = std.atomic.Value(bool).init(false); +pub var running: std.atomic.Value(bool) = .init(false); var lastTime: i128 = undefined; pub var mutex: std.Thread.Mutex = .{}; @@ -205,8 +205,8 @@ pub var thread: ?std.Thread = null; fn init(name: []const u8, singlePlayerPort: ?u16) void { // MARK: init() std.debug.assert(world == null); // There can only be one world. command.init(); - users = main.List(*User).init(main.globalAllocator); - userDeinitList = main.List(*User).init(main.globalAllocator); + users = .init(main.globalAllocator); + userDeinitList = .init(main.globalAllocator); lastTime = std.time.nanoTimestamp(); connectionManager = ConnectionManager.init(main.settings.defaultPort, false) catch |err| { std.log.err("Couldn't create socket: {s}", .{@errorName(err)}); diff --git a/src/server/storage.zig b/src/server/storage.zig index 6dba9a29..e19b2205 100644 --- a/src/server/storage.zig +++ b/src/server/storage.zig @@ -17,7 +17,7 @@ pub const RegionFile = struct { // MARK: RegionFile pos: chunk.ChunkPosition, mutex: std.Thread.Mutex = .{}, modified: bool = false, - refCount: Atomic(u16) = Atomic(u16).init(1), + refCount: Atomic(u16) = .init(1), saveFolder: []const u8, pub fn getIndex(x: usize, y: usize, z: usize) usize { diff --git a/src/server/terrain/CaveBiomeMap.zig b/src/server/terrain/CaveBiomeMap.zig index 28491ec7..94e51549 100644 --- a/src/server/terrain/CaveBiomeMap.zig +++ b/src/server/terrain/CaveBiomeMap.zig @@ -27,7 +27,7 @@ pub const CaveBiomeMapFragment = struct { // MARK: caveBiomeMapFragment pos: main.chunk.ChunkPosition, biomeMap: [1 << 3*(caveBiomeMapShift - caveBiomeShift)][2]*const Biome = undefined, - refCount: std.atomic.Value(u16) = std.atomic.Value(u16).init(0), + refCount: std.atomic.Value(u16) = .init(0), pub fn init(self: *CaveBiomeMapFragment, wx: i32, wy: i32, wz: i32) void { self.* = .{ diff --git a/src/server/terrain/CaveMap.zig b/src/server/terrain/CaveMap.zig index 05023120..f9ea2b4f 100644 --- a/src/server/terrain/CaveMap.zig +++ b/src/server/terrain/CaveMap.zig @@ -21,7 +21,7 @@ pub const CaveMapFragment = struct { // MARK: CaveMapFragment data: [width*width]u64 = undefined, pos: ChunkPosition, voxelShift: u5, - refCount: Atomic(u16) = Atomic(u16).init(0), + refCount: Atomic(u16) = .init(0), pub fn init(self: *CaveMapFragment, wx: i32, wy: i32, wz: i32, voxelSize: u31) void { diff --git a/src/server/terrain/ClimateMap.zig b/src/server/terrain/ClimateMap.zig index e1207497..fe89b2fa 100644 --- a/src/server/terrain/ClimateMap.zig +++ b/src/server/terrain/ClimateMap.zig @@ -45,7 +45,7 @@ pub const ClimateMapFragment = struct { pos: ClimateMapFragmentPosition, map: [mapSize >> MapFragment.biomeShift][mapSize >> MapFragment.biomeShift]BiomeSample = undefined, - refCount: Atomic(u16) = Atomic(u16).init(0), + refCount: Atomic(u16) = .init(0), pub fn init(self: *ClimateMapFragment, wx: i32, wy: i32) void { self.* = .{ diff --git a/src/server/terrain/LightMap.zig b/src/server/terrain/LightMap.zig index 81c13aa7..14a847a7 100644 --- a/src/server/terrain/LightMap.zig +++ b/src/server/terrain/LightMap.zig @@ -21,7 +21,7 @@ pub const LightMapFragment = struct { startHeight: [mapSize*mapSize]i16 = undefined, pos: MapFragmentPosition, - refCount: Atomic(u16) = Atomic(u16).init(0), + refCount: Atomic(u16) = .init(0), pub fn init(self: *LightMapFragment, wx: i32, wy: i32, voxelSize: u31) void { self.* = .{ diff --git a/src/server/terrain/StructureMap.zig b/src/server/terrain/StructureMap.zig index d7e7b47f..25f11102 100644 --- a/src/server/terrain/StructureMap.zig +++ b/src/server/terrain/StructureMap.zig @@ -31,7 +31,7 @@ pub const StructureMapFragment = struct { pos: ChunkPosition, voxelShift: u5, - refCount: Atomic(u16) = Atomic(u16).init(0), + refCount: Atomic(u16) = .init(0), arena: main.utils.NeverFailingArenaAllocator, allocator: main.utils.NeverFailingAllocator, @@ -43,7 +43,7 @@ pub const StructureMapFragment = struct { .voxelSize = voxelSize, }, .voxelShift = @ctz(voxelSize), - .arena = main.utils.NeverFailingArenaAllocator.init(main.globalAllocator), + .arena = .init(main.globalAllocator), .allocator = self.arena.allocator(), }; @memset(&self.data, .{}); diff --git a/src/server/terrain/SurfaceMap.zig b/src/server/terrain/SurfaceMap.zig index 9c50e55e..8b7b3da6 100644 --- a/src/server/terrain/SurfaceMap.zig +++ b/src/server/terrain/SurfaceMap.zig @@ -70,9 +70,9 @@ pub const MapFragment = struct { // MARK: MapFragment maxHeight: i32 = 0, pos: MapFragmentPosition, - wasStored: Atomic(bool) = .{.raw = false}, + wasStored: Atomic(bool) = .init(false), - refCount: Atomic(u16) = Atomic(u16).init(0), + refCount: Atomic(u16) = .init(0), pub fn init(self: *MapFragment, wx: i32, wy: i32, voxelSize: u31) void { self.* = .{ diff --git a/src/server/terrain/biomes.zig b/src/server/terrain/biomes.zig index 5084aa4c..fa5e9a07 100644 --- a/src/server/terrain/biomes.zig +++ b/src/server/terrain/biomes.zig @@ -50,7 +50,7 @@ pub const SimpleStructureModel = struct { // MARK: SimpleStructureModel var modelRegistry: std.StringHashMapUnmanaged(VTable) = .{}; - var arena: main.utils.NeverFailingArenaAllocator = main.utils.NeverFailingArenaAllocator.init(main.globalAllocator); + var arena: main.utils.NeverFailingArenaAllocator = .init(main.globalAllocator); pub fn reset() void { std.debug.assert(arena.reset(.free_all)); @@ -425,7 +425,7 @@ pub const TreeNode = union(enum) { // MARK: TreeNode for(currentSlice) |biome| { self.leaf.totalChance += biome.chance; } - self.leaf.aliasTable = main.utils.AliasTable(Biome).init(allocator, currentSlice); + self.leaf.aliasTable = .init(allocator, currentSlice); return self; } var chanceLower: f32 = 0; @@ -462,9 +462,9 @@ pub const TreeNode = union(enum) { // MARK: TreeNode var upperIndex: usize = undefined; { var lists: [3]main.ListUnmanaged(Biome) = .{ - main.ListUnmanaged(Biome).initCapacity(main.stackAllocator, currentSlice.len), - main.ListUnmanaged(Biome).initCapacity(main.stackAllocator, currentSlice.len), - main.ListUnmanaged(Biome).initCapacity(main.stackAllocator, currentSlice.len), + .initCapacity(main.stackAllocator, currentSlice.len), + .initCapacity(main.stackAllocator, currentSlice.len), + .initCapacity(main.stackAllocator, currentSlice.len), }; defer for(lists) |list| { list.deinit(main.stackAllocator); @@ -542,9 +542,9 @@ const UnfinishedSubBiomeData = struct { var unfinishedSubBiomes: std.StringHashMapUnmanaged(main.ListUnmanaged(UnfinishedSubBiomeData)) = .{}; pub fn init() void { - biomes = main.List(Biome).init(main.globalAllocator); - caveBiomes = main.List(Biome).init(main.globalAllocator); - biomesById = std.StringHashMap(*Biome).init(main.globalAllocator.allocator); + biomes = .init(main.globalAllocator); + caveBiomes = .init(main.globalAllocator); + biomesById = .init(main.globalAllocator.allocator); const list = @import("simple_structures/_list.zig"); inline for(@typeInfo(list).@"struct".decls) |decl| { SimpleStructureModel.registerGenerator(@field(list, decl.name)); @@ -609,7 +609,7 @@ pub fn finishLoading() void { for(subBiomeDataList.items) |item| { parentBiome.subBiomeTotalChance += item.chance; } - parentBiome.subBiomes = main.utils.AliasTable(*const Biome).initFromContext(main.globalAllocator, subBiomeDataList.items); + parentBiome.subBiomes = .initFromContext(main.globalAllocator, subBiomeDataList.items); subBiomeDataList.deinit(main.globalAllocator); } unfinishedSubBiomes.clearAndFree(main.globalAllocator.allocator); diff --git a/src/server/terrain/noise/CachedFractalNoise.zig b/src/server/terrain/noise/CachedFractalNoise.zig index cbc7ec17..6bdf977d 100644 --- a/src/server/terrain/noise/CachedFractalNoise.zig +++ b/src/server/terrain/noise/CachedFractalNoise.zig @@ -20,7 +20,7 @@ pub fn init(wx: i32, wy: i32, voxelSize: u31, size: u31, worldSeed: u64, scale: .voxelSize = voxelSize, .voxelSizeShift = @ctz(voxelSize), }, - .cache = Array2D(f32).init(main.globalAllocator, cacheWidth, cacheWidth), + .cache = .init(main.globalAllocator, cacheWidth, cacheWidth), .scale = scale, .worldSeed = worldSeed, }; diff --git a/src/server/world.zig b/src/server/world.zig index 94ca0a6d..0df38d06 100644 --- a/src/server/world.zig +++ b/src/server/world.zig @@ -24,14 +24,14 @@ const Entity = server.Entity; const storage = @import("storage.zig"); pub const EntityChunk = struct { - chunk: std.atomic.Value(?*ServerChunk) = .{.raw = null}, + chunk: std.atomic.Value(?*ServerChunk) = .init(null), refCount: std.atomic.Value(u32), pos: chunk.ChunkPosition, pub fn initAndIncreaseRefCount(pos: ChunkPosition) *EntityChunk { const self = main.globalAllocator.create(EntityChunk); self.* = .{ - .refCount = std.atomic.Value(u32).init(1), + .refCount = .init(1), .pos = pos, }; return self; @@ -254,7 +254,7 @@ const ChunkManager = struct { // MARK: ChunkManager .world = world, .terrainGenerationProfile = try server.terrain.TerrainGenerationProfile.init(settings, world.seed), }; - entityChunkHashMap = @TypeOf(entityChunkHashMap).init(main.globalAllocator.allocator); + entityChunkHashMap = .init(main.globalAllocator.allocator); server.terrain.init(self.terrainGenerationProfile); storage.init(); return self; @@ -381,7 +381,7 @@ const WorldIO = struct { // MARK: WorldIO /// Load the seed, which is needed before custom item and ore generation. pub fn loadWorldSeed(self: WorldIO) !u64 { - const worldData: JsonElement = try self.dir.readToJson(main.stackAllocator, "world.dat"); + const worldData = try self.dir.readToJson(main.stackAllocator, "world.dat"); defer worldData.free(main.stackAllocator); if(worldData.get(u32, "version", 0) != worldDataVersion) { std.log.err("Cannot read world file version {}. Expected version {}.", .{worldData.get(u32, "version", 0), worldDataVersion}); @@ -391,7 +391,7 @@ const WorldIO = struct { // MARK: WorldIO } pub fn loadWorldData(self: WorldIO) !void { - const worldData: JsonElement = try self.dir.readToJson(main.stackAllocator, "world.dat"); + const worldData = try self.dir.readToJson(main.stackAllocator, "world.dat"); defer worldData.free(main.stackAllocator); self.world.doGameTimeCycle = worldData.get(bool, "doGameTimeCycle", true); @@ -401,7 +401,7 @@ const WorldIO = struct { // MARK: WorldIO } pub fn saveWorldData(self: WorldIO) !void { - const worldData: JsonElement = JsonElement.initObject(main.stackAllocator); + const worldData = JsonElement.initObject(main.stackAllocator); defer worldData.free(main.stackAllocator); worldData.put("version", worldDataVersion); worldData.put("seed", self.world.seed); @@ -464,8 +464,8 @@ pub const ServerWorld = struct { // MARK: ServerWorld .lastUnimportantDataSent = std.time.milliTimestamp(), .seed = @bitCast(@as(i64, @truncate(std.time.nanoTimestamp()))), .name = main.globalAllocator.dupe(u8, name), - .chunkUpdateQueue = main.utils.CircularBufferQueue(ChunkUpdateRequest).init(main.globalAllocator, 256), - .regionUpdateQueue = main.utils.CircularBufferQueue(RegionUpdateRequest).init(main.globalAllocator, 256), + .chunkUpdateQueue = .init(main.globalAllocator, 256), + .regionUpdateQueue = .init(main.globalAllocator, 256), }; self.itemDropManager.init(main.globalAllocator, self, self.gravity); errdefer self.itemDropManager.deinit(); diff --git a/src/utils.zig b/src/utils.zig index c7734b79..7018e593 100644 --- a/src/utils.zig +++ b/src/utils.zig @@ -765,7 +765,7 @@ pub const NeverFailingArenaAllocator = struct { // MARK: NeverFailingArena pub fn init(child_allocator: NeverFailingAllocator) NeverFailingArenaAllocator { return .{ - .arena = std.heap.ArenaAllocator.init(child_allocator.allocator), + .arena = .init(child_allocator.allocator), }; } @@ -802,7 +802,7 @@ pub const BufferFallbackAllocator = struct { // MARK: BufferFallbackAllocator pub fn init(buffer: []u8, fallbackAllocator: NeverFailingAllocator) BufferFallbackAllocator { return .{ - .fixedBuffer = std.heap.FixedBufferAllocator.init(buffer), + .fixedBuffer = .init(buffer), .fallbackAllocator = fallbackAllocator, }; } @@ -1178,7 +1178,7 @@ pub fn DynamicPackedIntArray(size: comptime_int) type { // MARK: DynamicPackedIn pub fn resize(self: *Self, allocator: main.utils.NeverFailingAllocator, newBitSize: u5) void { if(newBitSize == self.bitSize) return; - var newSelf: Self = Self.initCapacity(allocator, newBitSize); + var newSelf = Self.initCapacity(allocator, newBitSize); for(0..size) |i| { newSelf.setValue(i, self.getValue(i)); @@ -1430,8 +1430,8 @@ pub fn Cache(comptime T: type, comptime numberOfBuckets: u32, comptime bucketSiz return struct { buckets: [numberOfBuckets]Bucket = [_]Bucket {Bucket{}} ** numberOfBuckets, - cacheRequests: Atomic(usize) = Atomic(usize).init(0), - cacheMisses: Atomic(usize) = Atomic(usize).init(0), + cacheRequests: Atomic(usize) = .init(0), + cacheMisses: Atomic(usize) = .init(0), /// Tries to find the entry that fits to the supplied hashable. pub fn find(self: *@This(), compareAndHash: anytype, comptime postGetFunction: ?fn(*T) void) ?*T { @@ -1630,7 +1630,7 @@ pub fn GenericInterpolation(comptime elements: comptime_int) type { // MARK: Gen } pub const TimeDifference = struct { // MARK: TimeDifference - difference: Atomic(i16) = Atomic(i16).init(0), + difference: Atomic(i16) = .init(0), firstValue: bool = true, pub fn addDataPoint(self: *TimeDifference, time: i16) void { diff --git a/src/utils/file_monitor.zig b/src/utils/file_monitor.zig index 22f17a38..c0cb2d02 100644 --- a/src/utils/file_monitor.zig +++ b/src/utils/file_monitor.zig @@ -65,8 +65,8 @@ const LinuxImpl = struct { // MARK: LinuxImpl if(fd == -1) { std.log.err("Error while initializing inotifiy: {}", .{std.posix.errno(fd)}); } - watchDescriptors = std.StringHashMap(*DirectoryInfo).init(main.globalAllocator.allocator); - callbacks = std.AutoHashMap(c_int, *DirectoryInfo).init(main.globalAllocator.allocator); + watchDescriptors = .init(main.globalAllocator.allocator); + callbacks = .init(main.globalAllocator.allocator); } fn deinit() void { @@ -228,9 +228,9 @@ const WindowsImpl = struct { // MARK: WindowsImpl }; fn init() void { - notificationHandlers = std.StringHashMap(*DirectoryInfo).init(main.globalAllocator.allocator); - callbacks = main.List(*DirectoryInfo).init(main.globalAllocator); - justTheHandles = main.List(HANDLE).init(main.globalAllocator); + notificationHandlers = .init(main.globalAllocator.allocator); + callbacks = .init(main.globalAllocator); + justTheHandles = .init(main.globalAllocator); } fn deinit() void { From bfea4d9105ad30a21ef708c86421a544f6538f47 Mon Sep 17 00:00:00 2001 From: IntegratedQuantum Date: Sat, 14 Sep 2024 16:12:39 +0200 Subject: [PATCH 06/10] Fix one of Zig's accidental memcpy's introduced when refactoring chunk.Neighbor https://github.com/ziglang/zig/issues/13938 strikes back --- src/renderer/chunk_meshing.zig | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/renderer/chunk_meshing.zig b/src/renderer/chunk_meshing.zig index 9a76c6d7..5c0049ab 100644 --- a/src/renderer/chunk_meshing.zig +++ b/src/renderer/chunk_meshing.zig @@ -1031,7 +1031,7 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh const neighbor = chunk.Neighbor.dirNegX; for(1..chunk.chunkSize) |x| { for(0..chunk.chunkSize) |y| { - var bitMask = hasFaces[x][y] & (canSeeNeighbor[neighbor.reverse().toInt()][x - 1][y] | canSeeAllNeighbors[x - 1][y]); + var bitMask = hasFaces[x][y] & (canSeeNeighbor[comptime neighbor.reverse().toInt()][x - 1][y] | canSeeAllNeighbors[x - 1][y]); while(bitMask != 0) { const z = @ctz(bitMask); bitMask &= ~(@as(u32, 1) << @intCast(z)); @@ -1057,7 +1057,7 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh const neighbor = chunk.Neighbor.dirPosX; for(0..chunk.chunkSize-1) |x| { for(0..chunk.chunkSize) |y| { - var bitMask = hasFaces[x][y] & (canSeeNeighbor[neighbor.reverse().toInt()][x + 1][y] | canSeeAllNeighbors[x + 1][y]); + var bitMask = hasFaces[x][y] & (canSeeNeighbor[comptime neighbor.reverse().toInt()][x + 1][y] | canSeeAllNeighbors[x + 1][y]); while(bitMask != 0) { const z = @ctz(bitMask); bitMask &= ~(@as(u32, 1) << @intCast(z)); @@ -1083,7 +1083,7 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh const neighbor = chunk.Neighbor.dirNegY; for(0..chunk.chunkSize) |x| { for(1..chunk.chunkSize) |y| { - var bitMask = hasFaces[x][y] & (canSeeNeighbor[neighbor.reverse().toInt()][x][y - 1] | canSeeAllNeighbors[x][y - 1]); + var bitMask = hasFaces[x][y] & (canSeeNeighbor[comptime neighbor.reverse().toInt()][x][y - 1] | canSeeAllNeighbors[x][y - 1]); while(bitMask != 0) { const z = @ctz(bitMask); bitMask &= ~(@as(u32, 1) << @intCast(z)); @@ -1109,7 +1109,7 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh const neighbor = chunk.Neighbor.dirPosY; for(0..chunk.chunkSize) |x| { for(0..chunk.chunkSize-1) |y| { - var bitMask = hasFaces[x][y] & (canSeeNeighbor[neighbor.reverse().toInt()][x][y + 1] | canSeeAllNeighbors[x][y + 1]); + var bitMask = hasFaces[x][y] & (canSeeNeighbor[comptime neighbor.reverse().toInt()][x][y + 1] | canSeeAllNeighbors[x][y + 1]); while(bitMask != 0) { const z = @ctz(bitMask); bitMask &= ~(@as(u32, 1) << @intCast(z)); @@ -1135,7 +1135,7 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh const neighbor = chunk.Neighbor.dirDown; for(0..chunk.chunkSize) |x| { for(0..chunk.chunkSize) |y| { - var bitMask = hasFaces[x][y] & (canSeeNeighbor[neighbor.reverse().toInt()][x][y] | canSeeAllNeighbors[x][y]) << 1; + var bitMask = hasFaces[x][y] & (canSeeNeighbor[comptime neighbor.reverse().toInt()][x][y] | canSeeAllNeighbors[x][y]) << 1; while(bitMask != 0) { const z = @ctz(bitMask); bitMask &= ~(@as(u32, 1) << @intCast(z)); @@ -1161,7 +1161,7 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh const neighbor = chunk.Neighbor.dirUp; for(0..chunk.chunkSize) |x| { for(0..chunk.chunkSize) |y| { - var bitMask = hasFaces[x][y] & (canSeeNeighbor[neighbor.reverse().toInt()][x][y] | canSeeAllNeighbors[x][y]) >> 1; + var bitMask = hasFaces[x][y] & (canSeeNeighbor[comptime neighbor.reverse().toInt()][x][y] | canSeeAllNeighbors[x][y]) >> 1; while(bitMask != 0) { const z = @ctz(bitMask); bitMask &= ~(@as(u32, 1) << @intCast(z)); From d7055f6998a494fc515cc0a627f757feaf751949 Mon Sep 17 00:00:00 2001 From: IntegratedQuantum Date: Sun, 15 Sep 2024 13:02:02 +0200 Subject: [PATCH 07/10] Some small performance improvements to the CPU-side mesh traversal. Should help implementing #526 --- src/renderer/chunk_meshing.zig | 2 +- src/renderer/mesh_storage.zig | 44 +++++++++++++--------------------- 2 files changed, 17 insertions(+), 29 deletions(-) diff --git a/src/renderer/chunk_meshing.zig b/src/renderer/chunk_meshing.zig index 5c0049ab..d5848a0a 100644 --- a/src/renderer/chunk_meshing.zig +++ b/src/renderer/chunk_meshing.zig @@ -687,7 +687,7 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh refCount: std.atomic.Value(u32) = .init(1), needsLightRefresh: std.atomic.Value(bool) = .init(false), needsMeshUpdate: bool = false, - finishedMeshing: bool = false, + finishedMeshing: bool = false, // Must be synced with node.finishedMeshing in mesh_storage.zig finishedLighting: bool = false, litNeighbors: Atomic(u32) = .init(0), mutex: std.Thread.Mutex = .{}, diff --git a/src/renderer/mesh_storage.zig b/src/renderer/mesh_storage.zig index 66ba1802..ccf348d5 100644 --- a/src/renderer/mesh_storage.zig +++ b/src/renderer/mesh_storage.zig @@ -28,6 +28,7 @@ const ChunkMeshNode = struct { max: Vec2f = undefined, active: bool = false, rendered: bool = false, + finishedMeshing: bool = false, // Must be synced with mesh.finishedMeshing mutex: std.Thread.Mutex = .{}, }; const storageSize = 64; @@ -323,6 +324,7 @@ fn freeOldMeshes(olderPx: i32, olderPy: i32, olderPz: i32, olderRD: i32) void { node.mutex.lock(); const oldMesh = node.mesh; node.mesh = null; + node.finishedMeshing = false; node.mutex.unlock(); if(oldMesh) |mesh| { mesh.decreaseRefCount(); @@ -592,9 +594,7 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V var lod: u3 = 0; while(lod <= settings.highestLOD) : (lod += 1) { const node = getNodePointer(firstPos); - node.mutex.lock(); - const hasMesh = node.mesh != null and node.mesh.?.finishedMeshing; - node.mutex.unlock(); + const hasMesh = node.finishedMeshing; if(hasMesh) { node.lod = lod; node.min = @splat(-1); @@ -617,6 +617,7 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V defer nodeList.deinit(); const projRotMat = game.projectionMatrix.mul(game.camera.viewMatrix); while(searchList.removeOrNull()) |data| { + std.debug.assert(data.node.finishedMeshing); nodeList.append(data.node); data.node.active = false; @@ -625,10 +626,6 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V mutex.unlock(); continue; }; - if(!mesh.finishedMeshing) { - mutex.unlock(); - continue; - } mesh.increaseRefCount(); defer mesh.decreaseRefCount(); mutex.unlock(); @@ -638,10 +635,10 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V const relPosFloat: Vec3f = @floatCast(relPos); var isNeighborLod: [6]bool = .{false} ** 6; for(chunk.Neighbor.iterable) |neighbor| continueNeighborLoop: { - const component = neighbor.extractDirectionComponent(relPos); - if(neighbor.isPositive() and component + @as(f64, @floatFromInt(chunk.chunkSize*mesh.pos.voxelSize)) <= 0) continue; + const component = neighbor.extractDirectionComponent(relPosFloat); + if(neighbor.isPositive() and component + @as(f32, @floatFromInt(chunk.chunkSize*mesh.pos.voxelSize)) <= 0) continue; if(!neighbor.isPositive() and component >= 0) continue; - if(@reduce(.Or, @min(mesh.chunkBorders[neighbor.toInt()].min, mesh.chunkBorders[neighbor.toInt()].max) != mesh.chunkBorders[neighbor.toInt()].min)) continue; // There was not a single block in the chunk. TODO: Find a better solution. + if(@reduce(.Or, mesh.chunkBorders[neighbor.toInt()].max < mesh.chunkBorders[neighbor.toInt()].min)) continue; // There was not a single transparent block along the chunk border. TODO: Find a better solution. const minVec: Vec3f = @floatFromInt(mesh.chunkBorders[neighbor.toInt()].min*@as(Vec3i, @splat(mesh.pos.voxelSize))); const maxVec: Vec3f = @floatFromInt(mesh.chunkBorders[neighbor.toInt()].max*@as(Vec3i, @splat(mesh.pos.voxelSize))); var xyMin: Vec2f = .{10, 10}; @@ -781,7 +778,7 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V .voxelSize = mesh.pos.voxelSize, }; var lod: u3 = data.node.lod; - while(lod <= settings.highestLOD) : (lod += 1) { + lodLoop: while(lod <= settings.highestLOD) : (lod += 1) { defer { neighborPos.wx &= ~@as(i32, neighborPos.voxelSize*chunk.chunkSize); neighborPos.wy &= ~@as(i32, neighborPos.voxelSize*chunk.chunkSize); @@ -789,17 +786,13 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V neighborPos.voxelSize *= 2; } const node = getNodePointer(neighborPos); - if(getMeshAndIncreaseRefCount(neighborPos)) |neighborMesh| { - std.debug.assert(std.meta.eql(neighborPos, neighborMesh.pos)); - defer neighborMesh.decreaseRefCount(); - if(!neighborMesh.finishedMeshing) continue; + if(node.finishedMeshing) { // Ensure that there are no high-to-low lod transitions, which would produce cracks. if(lod == data.node.lod and lod != settings.highestLOD and !node.rendered) { - var isValid: bool = true; const relPos2: Vec3d = @as(Vec3d, @floatFromInt(Vec3i{neighborPos.wx, neighborPos.wy, neighborPos.wz})) - playerPos; for(chunk.Neighbor.iterable) |neighbor2| { const component2 = neighbor2.extractDirectionComponent(relPos2); - if(neighbor2.isPositive() and component2 + @as(f64, @floatFromInt(chunk.chunkSize*neighborMesh.pos.voxelSize)) >= 0) continue; + if(neighbor2.isPositive() and component2 + @as(f64, @floatFromInt(chunk.chunkSize*neighborPos.voxelSize)) >= 0) continue; if(!neighbor2.isPositive() and component2 <= 0) continue; { // Check the chunk of same lod: const neighborPos2 = chunk.ChunkPosition{ @@ -822,15 +815,11 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V }; const node2 = getNodePointer(neighborPos2); if(node2.rendered) { - isValid = false; - break; + isNeighborLod[neighbor.toInt()] = true; + continue :lodLoop; } } } - if(!isValid) { - isNeighborLod[neighbor.toInt()] = true; - continue; - } } if(lod != data.node.lod) { isNeighborLod[neighbor.toInt()] = true; @@ -845,7 +834,7 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V node.active = true; searchList.add(.{ .node = node, - .distance = neighborMesh.pos.getMaxDistanceSquared(playerPos), + .distance = neighborPos.getMaxDistanceSquared(playerPos), }) catch unreachable; node.rendered = true; } @@ -857,16 +846,13 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V } for(nodeList.items) |node| { node.rendered = false; + if(!node.finishedMeshing) continue; node.mutex.lock(); const mesh = node.mesh orelse { node.mutex.unlock(); continue; }; - if(!mesh.finishedMeshing) { - node.mutex.unlock(); - continue; - } mesh.increaseRefCount(); defer mesh.decreaseRefCount(); node.mutex.unlock(); @@ -982,6 +968,7 @@ pub fn updateMeshes(targetTime: i64) void { // MARK: updateMeshes() defer mutex.lock(); if(isInRenderDistance(mesh.pos)) { const node = getNodePointer(mesh.pos); + node.finishedMeshing = true; mesh.finishedMeshing = true; mesh.uploadData(); node.mutex.lock(); @@ -1032,6 +1019,7 @@ pub fn addMeshToStorage(mesh: *chunk_meshing.ChunkMesh) error{AlreadyStored}!voi return error.AlreadyStored; } node.mesh = mesh; + node.finishedMeshing = mesh.finishedMeshing; mesh.increaseRefCount(); } } From e9fdad732d4c4b31c6703c855bf6736e6ce5e95d Mon Sep 17 00:00:00 2001 From: IntegratedQuantum Date: Sun, 15 Sep 2024 17:26:56 +0200 Subject: [PATCH 08/10] Make flying through caves fun again (removes CPU-side occlusion culling) This is not quite the performance improvement I had planned. On the GPU-side the raster occlusion culling step got more expensive, since there now are more chunks checked on average. On the CPU-side the cost of traversing all the occluded chunks is roughly equal to the cost of the previous occlusion culling heuristic. On the bright side the cost is now constant, whereas previously looking into the sky was twice as expensive. fixes #526 fixes #514 fixes #259 --- src/renderer.zig | 3 +- src/renderer/chunk_meshing.zig | 26 ----- src/renderer/mesh_storage.zig | 198 ++++----------------------------- 3 files changed, 23 insertions(+), 204 deletions(-) diff --git a/src/renderer.zig b/src/renderer.zig index ce5eae8f..f9b7f0d2 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -174,7 +174,6 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo // Uses FrustumCulling on the chunks. const frustum = Frustum.init(Vec3f{0, 0, 0}, game.camera.viewMatrix, lastFov, lastWidth, lastHeight); - _ = frustum; const time: u32 = @intCast(std.time.milliTimestamp() & std.math.maxInt(u32)); @@ -196,7 +195,7 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo chunk_meshing.quadsDrawn = 0; chunk_meshing.transparentQuadsDrawn = 0; - const meshes = mesh_storage.updateAndGetRenderChunks(world.conn, playerPos, settings.renderDistance); + const meshes = mesh_storage.updateAndGetRenderChunks(world.conn, &frustum, playerPos, settings.renderDistance); gpu_performance_measuring.startQuery(.chunk_rendering_preparation); const direction = crosshairDirection(game.camera.viewMatrix, lastFov, lastWidth, lastHeight); diff --git a/src/renderer/chunk_meshing.zig b/src/renderer/chunk_meshing.zig index d5848a0a..767b7d2c 100644 --- a/src/renderer/chunk_meshing.zig +++ b/src/renderer/chunk_meshing.zig @@ -658,17 +658,6 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh self.distance = @abs(fullDx) + @abs(fullDy) + @abs(fullDz); } }; - const BoundingRectToNeighborChunk = struct { - min: Vec3i = @splat(std.math.maxInt(i32)), - max: Vec3i = @splat(0), - - fn adjustToBlock(self: *BoundingRectToNeighborChunk, block: Block, pos: Vec3i, neighbor: chunk.Neighbor) void { - if(block.viewThrough()) { - self.min = @min(self.min, pos); - self.max = @max(self.max, pos + neighbor.orthogonalComponents()); - } - } - }; pos: chunk.ChunkPosition, size: i32, chunk: *chunk.Chunk, @@ -695,8 +684,6 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh min: Vec3f = undefined, max: Vec3f = undefined, - chunkBorders: [6]BoundingRectToNeighborChunk = [1]BoundingRectToNeighborChunk{.{}} ** 6, - pub fn init(self: *ChunkMesh, pos: chunk.ChunkPosition, ch: *chunk.Chunk) void { self.* = ChunkMesh{ .pos = pos, @@ -1184,19 +1171,6 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh } } - // Check out the borders: - var x: u8 = 0; - while(x < chunk.chunkSize): (x += 1) { - var y: u8 = 0; - while(y < chunk.chunkSize): (y += 1) { - self.chunkBorders[chunk.Neighbor.dirNegX.toInt()].adjustToBlock(self.chunk.data.getValue(chunk.getIndex(0, x, y)), .{0, x, y}, chunk.Neighbor.dirNegX); - self.chunkBorders[chunk.Neighbor.dirPosX.toInt()].adjustToBlock(self.chunk.data.getValue(chunk.getIndex(chunk.chunkSize-1, x, y)), .{chunk.chunkSize, x, y}, chunk.Neighbor.dirPosX); - self.chunkBorders[chunk.Neighbor.dirNegY.toInt()].adjustToBlock(self.chunk.data.getValue(chunk.getIndex(x, 0, y)), .{x, 0, y}, chunk.Neighbor.dirNegY); - self.chunkBorders[chunk.Neighbor.dirPosY.toInt()].adjustToBlock(self.chunk.data.getValue(chunk.getIndex(x, chunk.chunkSize-1, y)), .{x, chunk.chunkSize, y}, chunk.Neighbor.dirPosY); - self.chunkBorders[chunk.Neighbor.dirDown.toInt()].adjustToBlock(self.chunk.data.getValue(chunk.getIndex(x, y, 0)), .{x, y, 0}, chunk.Neighbor.dirDown); - self.chunkBorders[chunk.Neighbor.dirUp.toInt()].adjustToBlock(self.chunk.data.getValue(chunk.getIndex(x, y, chunk.chunkSize-1)), .{x, y, chunk.chunkSize}, chunk.Neighbor.dirUp); - } - } self.mutex.unlock(); self.finishNeighbors(lightRefreshList); diff --git a/src/renderer/mesh_storage.zig b/src/renderer/mesh_storage.zig index ccf348d5..63d74579 100644 --- a/src/renderer/mesh_storage.zig +++ b/src/renderer/mesh_storage.zig @@ -24,8 +24,6 @@ const chunk_meshing = @import("chunk_meshing.zig"); const ChunkMeshNode = struct { mesh: ?*chunk_meshing.ChunkMesh = null, lod: u3 = undefined, - min: Vec2f = undefined, - max: Vec2f = undefined, active: bool = false, rendered: bool = false, finishedMeshing: bool = false, // Must be synced with mesh.finishedMeshing @@ -536,7 +534,7 @@ fn createNewMeshes(olderPx: i32, olderPy: i32, olderPz: i32, olderRD: i32, meshR } } -pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: Vec3d, renderDistance: i32) []*chunk_meshing.ChunkMesh { // MARK: updateAndGetRenderChunks() +pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, frustum: *const main.renderer.Frustum, playerPos: Vec3d, renderDistance: i32) []*chunk_meshing.ChunkMesh { // MARK: updateAndGetRenderChunks() meshList.clearRetainingCapacity(); if(lastRD != renderDistance) { network.Protocols.genericUpdate.sendRenderDistance(conn, renderDistance); @@ -565,9 +563,9 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V network.Protocols.lightMapRequest.sendRequest(conn, mapRequests.items); network.Protocols.chunkRequest.sendRequest(conn, meshRequests.items, .{lastPx, lastPy, lastPz}); - // Does occlusion using a breadth-first search that caches an on-screen visibility rectangle. + // Finds all visible chunks and lod chunks using a breadth-first search. - const OcclusionData = struct { + const SearchData = struct { node: *ChunkMeshNode, distance: f64, @@ -578,8 +576,7 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V } }; - // TODO: Is there a way to combine this with minecraft's approach? - var searchList = std.PriorityQueue(OcclusionData, void, OcclusionData.compare).init(main.stackAllocator.allocator, {}); + var searchList = std.PriorityQueue(SearchData, void, SearchData.compare).init(main.stackAllocator.allocator, {}); defer searchList.deinit(); { var firstPos = chunk.ChunkPosition{ @@ -597,8 +594,6 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V const hasMesh = node.finishedMeshing; if(hasMesh) { node.lod = lod; - node.min = @splat(-1); - node.max = @splat(1); node.active = true; node.rendered = true; searchList.add(.{ @@ -615,168 +610,32 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V } var nodeList = main.List(*ChunkMeshNode).init(main.stackAllocator); defer nodeList.deinit(); - const projRotMat = game.projectionMatrix.mul(game.camera.viewMatrix); while(searchList.removeOrNull()) |data| { std.debug.assert(data.node.finishedMeshing); nodeList.append(data.node); data.node.active = false; - mutex.lock(); - const mesh = data.node.mesh orelse { - mutex.unlock(); - continue; - }; - mesh.increaseRefCount(); - defer mesh.decreaseRefCount(); - mutex.unlock(); + const mesh = data.node.mesh.?; // No need to lock the mutex, since no other thread is allowed to overwrite the mesh (unless it's null). + const pos = mesh.pos; mesh.visibilityMask = 0xff; - const relPos: Vec3d = @as(Vec3d, @floatFromInt(Vec3i{mesh.pos.wx, mesh.pos.wy, mesh.pos.wz})) - playerPos; + const relPos: Vec3d = @as(Vec3d, @floatFromInt(Vec3i{pos.wx, pos.wy, pos.wz})) - playerPos; const relPosFloat: Vec3f = @floatCast(relPos); var isNeighborLod: [6]bool = .{false} ** 6; - for(chunk.Neighbor.iterable) |neighbor| continueNeighborLoop: { + neighborLoop: for(chunk.Neighbor.iterable) |neighbor| { const component = neighbor.extractDirectionComponent(relPosFloat); - if(neighbor.isPositive() and component + @as(f32, @floatFromInt(chunk.chunkSize*mesh.pos.voxelSize)) <= 0) continue; + if(neighbor.isPositive() and component + @as(f32, @floatFromInt(chunk.chunkSize*pos.voxelSize)) <= 0) continue; if(!neighbor.isPositive() and component >= 0) continue; - if(@reduce(.Or, mesh.chunkBorders[neighbor.toInt()].max < mesh.chunkBorders[neighbor.toInt()].min)) continue; // There was not a single transparent block along the chunk border. TODO: Find a better solution. - const minVec: Vec3f = @floatFromInt(mesh.chunkBorders[neighbor.toInt()].min*@as(Vec3i, @splat(mesh.pos.voxelSize))); - const maxVec: Vec3f = @floatFromInt(mesh.chunkBorders[neighbor.toInt()].max*@as(Vec3i, @splat(mesh.pos.voxelSize))); - var xyMin: Vec2f = .{10, 10}; - var xyMax: Vec2f = .{-10, -10}; - var numberOfNegatives: u8 = 0; - var corners: [5]Vec4f = undefined; - var curCorner: usize = 0; - for(0..2) |a| { - for(0..2) |b| { - - var cornerVector: Vec3f = undefined; - switch(neighbor.vectorComponent()) { - .x => { - cornerVector = @select(f32, @Vector(3, bool){true, a == 0, b == 0}, minVec, maxVec); - }, - .y => { - cornerVector = @select(f32, @Vector(3, bool){a == 0, true, b == 0}, minVec, maxVec); - }, - .z => { - cornerVector = @select(f32, @Vector(3, bool){a == 0, b == 0, true}, minVec, maxVec); - }, - } - corners[curCorner] = projRotMat.mulVec(vec.combine(relPosFloat + cornerVector, 1)); - if(corners[curCorner][3] < 0) { - numberOfNegatives += 1; - } - curCorner += 1; - } - } - switch(numberOfNegatives) { // Oh, so complicated. But this should only trigger very close to the player. - 4 => continue, - 0 => {}, - 1 => { - // Needs to duplicate the problematic corner and move it onto the projected plane. - var problematicOne: usize = 0; - for(0..curCorner) |i| { - if(corners[i][3] < 0) { - problematicOne = i; - break; - } - } - const problematicVector = corners[problematicOne]; - // The two neighbors of the quad: - const neighborA = corners[problematicOne ^ 1]; - const neighborB = corners[problematicOne ^ 2]; - // Move the problematic point towards the neighbor: - const one: Vec4f = @splat(1); - const weightA: Vec4f = @splat(problematicVector[3]/(problematicVector[3] - neighborA[3])); - var towardsA = neighborA*weightA + problematicVector*(one - weightA); - towardsA[3] = 0; // Prevent inaccuracies - const weightB: Vec4f = @splat(problematicVector[3]/(problematicVector[3] - neighborB[3])); - var towardsB = neighborB*weightB + problematicVector*(one - weightB); - towardsB[3] = 0; // Prevent inaccuracies - corners[problematicOne] = towardsA; - corners[curCorner] = towardsB; - curCorner += 1; - }, - 2 => { - // Needs to move the two problematic corners onto the projected plane. - var problematicOne: usize = undefined; - for(0..curCorner) |i| { - if(corners[i][3] < 0) { - problematicOne = i; - break; - } - } - const problematicVectorOne = corners[problematicOne]; - var problematicTwo: usize = undefined; - for(problematicOne+1..curCorner) |i| { - if(corners[i][3] < 0) { - problematicTwo = i; - break; - } - } - const problematicVectorTwo = corners[problematicTwo]; - - const commonDirection = problematicOne ^ problematicTwo; - const projectionDirection = commonDirection ^ 0b11; - // The respective neighbors: - const neighborOne = corners[problematicOne ^ projectionDirection]; - const neighborTwo = corners[problematicTwo ^ projectionDirection]; - // Move the problematic points towards the neighbor: - const one: Vec4f = @splat(1); - const weightOne: Vec4f = @splat(problematicVectorOne[3]/(problematicVectorOne[3] - neighborOne[3])); - var towardsOne = neighborOne*weightOne + problematicVectorOne*(one - weightOne); - towardsOne[3] = 0; // Prevent inaccuracies - corners[problematicOne] = towardsOne; - - const weightTwo: Vec4f = @splat(problematicVectorTwo[3]/(problematicVectorTwo[3] - neighborTwo[3])); - var towardsTwo = neighborTwo*weightTwo + problematicVectorTwo*(one - weightTwo); - towardsTwo[3] = 0; // Prevent inaccuracies - corners[problematicTwo] = towardsTwo; - }, - 3 => { - // Throw away the far problematic vector, move the other two onto the projection plane. - var neighborIndex: usize = undefined; - for(0..curCorner) |i| { - if(corners[i][3] >= 0) { - neighborIndex = i; - break; - } - } - const neighborVector = corners[neighborIndex]; - const problematicVectorOne = corners[neighborIndex ^ 1]; - const problematicVectorTwo = corners[neighborIndex ^ 2]; - // Move the problematic points towards the neighbor: - const one: Vec4f = @splat(1); - const weightOne: Vec4f = @splat(problematicVectorOne[3]/(problematicVectorOne[3] - neighborVector[3])); - var towardsOne = neighborVector*weightOne + problematicVectorOne*(one - weightOne); - towardsOne[3] = 0; // Prevent inaccuracies - - const weightTwo: Vec4f = @splat(problematicVectorTwo[3]/(problematicVectorTwo[3] - neighborVector[3])); - var towardsTwo = neighborVector*weightTwo + problematicVectorTwo*(one - weightTwo); - towardsTwo[3] = 0; // Prevent inaccuracies - - corners[0] = neighborVector; - corners[1] = towardsOne; - corners[2] = towardsTwo; - curCorner = 3; - }, - else => unreachable, - } - - for(0..curCorner) |i| { - const projected = corners[i]; - const xy = vec.xy(projected)/@as(Vec2f, @splat(@max(0, projected[3]))); - xyMin = @min(xyMin, xy); - xyMax = @max(xyMax, xy); - } - const min = @max(xyMin, data.node.min); - const max = @min(xyMax, data.node.max); - if(@reduce(.Or, min >= max)) continue; // Nothing to render. var neighborPos = chunk.ChunkPosition{ - .wx = mesh.pos.wx +% neighbor.relX()*chunk.chunkSize*mesh.pos.voxelSize, - .wy = mesh.pos.wy +% neighbor.relY()*chunk.chunkSize*mesh.pos.voxelSize, - .wz = mesh.pos.wz +% neighbor.relZ()*chunk.chunkSize*mesh.pos.voxelSize, - .voxelSize = mesh.pos.voxelSize, + .wx = pos.wx +% neighbor.relX()*chunk.chunkSize*pos.voxelSize, + .wy = pos.wy +% neighbor.relY()*chunk.chunkSize*pos.voxelSize, + .wz = pos.wz +% neighbor.relZ()*chunk.chunkSize*pos.voxelSize, + .voxelSize = pos.voxelSize, }; + if(!getNodePointer(neighborPos).active) { // Don't repeat the same frustum check all the time. + if(!frustum.testAAB(relPosFloat + @as(Vec3f, @floatFromInt(Vec3i{neighbor.relX()*chunk.chunkSize*pos.voxelSize, neighbor.relY()*chunk.chunkSize*pos.voxelSize, neighbor.relZ()*chunk.chunkSize*pos.voxelSize})), @splat(@floatFromInt(chunk.chunkSize*pos.voxelSize)))) + continue; + } var lod: u3 = data.node.lod; lodLoop: while(lod <= settings.highestLOD) : (lod += 1) { defer { @@ -824,13 +683,8 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V if(lod != data.node.lod) { isNeighborLod[neighbor.toInt()] = true; } - if(node.active) { - node.min = @min(node.min, min); - node.max = @max(node.max, max); - } else { + if(!node.active) { node.lod = lod; - node.min = min; - node.max = max; node.active = true; searchList.add(.{ .node = node, @@ -838,7 +692,7 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V }) catch unreachable; node.rendered = true; } - break :continueNeighborLoop; + continue :neighborLoop; } } } @@ -848,20 +702,12 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V node.rendered = false; if(!node.finishedMeshing) continue; - node.mutex.lock(); - const mesh = node.mesh orelse { - node.mutex.unlock(); - continue; - }; - mesh.increaseRefCount(); - defer mesh.decreaseRefCount(); - node.mutex.unlock(); + const mesh = node.mesh.?; // No need to lock the mutex, since no other thread is allowed to overwrite the mesh (unless it's null). if(mesh.pos.voxelSize != @as(u31, 1) << settings.highestLOD) { const parent = getNodePointer(.{.wx=mesh.pos.wx, .wy=mesh.pos.wy, .wz=mesh.pos.wz, .voxelSize=mesh.pos.voxelSize << 1}); - parent.mutex.lock(); - defer parent.mutex.unlock(); - if(parent.mesh) |parentMesh| { + if(parent.finishedMeshing) { + const parentMesh = parent.mesh.?; // No need to lock the mutex, since no other thread is allowed to overwrite the mesh (unless it's null). const sizeShift = chunk.chunkShift + @ctz(mesh.pos.voxelSize); const octantIndex: u3 = @intCast((mesh.pos.wx>>sizeShift & 1) | (mesh.pos.wy>>sizeShift & 1)<<1 | (mesh.pos.wz>>sizeShift & 1)<<2); parentMesh.visibilityMask &= ~(@as(u8, 1) << octantIndex); From e61163e43b691044e887331b10b86f37ff40627b Mon Sep 17 00:00:00 2001 From: OneAvargeCoder193 Date: Sun, 15 Sep 2024 11:41:57 -0400 Subject: [PATCH 09/10] give lava interior fog --- assets/cubyz/blocks/textures/lava.png_textureInfo.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 assets/cubyz/blocks/textures/lava.png_textureInfo.json diff --git a/assets/cubyz/blocks/textures/lava.png_textureInfo.json b/assets/cubyz/blocks/textures/lava.png_textureInfo.json new file mode 100644 index 00000000..4dd88790 --- /dev/null +++ b/assets/cubyz/blocks/textures/lava.png_textureInfo.json @@ -0,0 +1,4 @@ +{ + "fogDensity" : 0.7, + "fogColor" : 0xff9000, +} From d27029ee2b4c3591448179635063dd8eb4b6b119 Mon Sep 17 00:00:00 2001 From: IntegratedQuantum Date: Tue, 17 Sep 2024 20:03:22 +0200 Subject: [PATCH 10/10] Allow slightly changing the cave radius parameters in the biome settings. A negative radius is interpreted as adding terrain instead of removing terrain. This is used in the new void_roots biome and fixes #725 Until #231 is implemented I give this biome the entire area below -50000. --- assets/cubyz/biomes/cave/void_roots.json | 46 +++++++++++ src/server/terrain/biomes.zig | 2 + .../terrain/cavegen/FractalCaveGenerator.zig | 81 ++++++++++++++----- 3 files changed, 110 insertions(+), 19 deletions(-) create mode 100644 assets/cubyz/biomes/cave/void_roots.json diff --git a/assets/cubyz/biomes/cave/void_roots.json b/assets/cubyz/biomes/cave/void_roots.json new file mode 100644 index 00000000..8c91b499 --- /dev/null +++ b/assets/cubyz/biomes/cave/void_roots.json @@ -0,0 +1,46 @@ +{ + "isCave" : true, + "maxHeight" : -50000, + + "fogDensity" : 2, + "chance" : 100, + "caveRadiusFactor" : -1, + "caves" : 0.5, + + "music" : "cubyz:heart-of-the-beast", + + + + "structures" : [ + { + "id" : "cubyz:ground_patch", + "block" : "cubyz:gravel", + "chance" : 0.064, + "width" : 5, + "variation" : 5, + "depth" : 3, + "smoothness" : 0.1 + } + { + "id" : "cubyz:stalagmite", + "block" : "cubyz:stone", + "chance" : 0.048, + "size" : 3, + "size_variation" : 6 + }, + { + "id" : "cubyz:boulder", + "chance" : 0.016, + "block" : "cubyz:cobblestone", + "size" : 4, + "size_variance" : 3 + }, + { + "id" : "cubyz:boulder", + "chance" : 0.016, + "block" : "cubyz:stone", + "size" : 4, + "size_variance" : 4 + } + ] +} \ No newline at end of file diff --git a/src/server/terrain/biomes.zig b/src/server/terrain/biomes.zig index fa5e9a07..f621aa69 100644 --- a/src/server/terrain/biomes.zig +++ b/src/server/terrain/biomes.zig @@ -243,6 +243,7 @@ pub const Biome = struct { // MARK: Biome hills: f32, mountains: f32, caves: f32, + caveRadiusFactor: f32, crystals: u32, stoneBlockType: u16, fogDensity: f32, @@ -278,6 +279,7 @@ pub const Biome = struct { // MARK: Biome .interpolation = std.meta.stringToEnum(Interpolation, json.get([]const u8, "interpolation", "square")) orelse .square, .interpolationWeight = @max(json.get(f32, "interpolationWeight", 1), std.math.floatMin(f32)), .caves = json.get(f32, "caves", -0.375), + .caveRadiusFactor = @max(-2, @min(2, json.get(f32, "caveRadiusFactor", 1))), .crystals = json.get(u32, "crystals", 0), .minHeight = json.get(i32, "minHeight", std.math.minInt(i32)), .maxHeight = json.get(i32, "maxHeight", std.math.maxInt(i32)), diff --git a/src/server/terrain/cavegen/FractalCaveGenerator.zig b/src/server/terrain/cavegen/FractalCaveGenerator.zig index 46bdc5e2..cab11808 100644 --- a/src/server/terrain/cavegen/FractalCaveGenerator.zig +++ b/src/server/terrain/cavegen/FractalCaveGenerator.zig @@ -5,6 +5,7 @@ const random = main.random; const JsonElement = main.JsonElement; const terrain = main.server.terrain; const CaveMapFragment = terrain.CaveMap.CaveMapFragment; +const InterpolatableCaveBiomeMapView = terrain.CaveBiomeMap.InterpolatableCaveBiomeMapView; const vec = main.vec; const Vec3f = vec.Vec3f; const Vec3i = vec.Vec3i; @@ -43,6 +44,9 @@ const maxCaveDensity = 1.0/32.0; pub fn generate(map: *CaveMapFragment, worldSeed: u64) void { if(map.pos.voxelSize > 2) return; + + const biomeMap: InterpolatableCaveBiomeMapView = InterpolatableCaveBiomeMapView.init(main.stackAllocator, map.pos, CaveMapFragment.width*map.pos.voxelSize, CaveMapFragment.width*map.pos.voxelSize + maxCaveHeight*3); + defer biomeMap.deinit(); // Generate caves from all nearby chunks: var wx = map.pos.wx -% range; while(wx -% map.pos.wx -% CaveMapFragment.width*map.pos.voxelSize -% range < 0) : (wx +%= chunkSize) { @@ -51,13 +55,13 @@ pub fn generate(map: *CaveMapFragment, worldSeed: u64) void { var wz = map.pos.wz -% 2*range; while(wz -% map.pos.wz -% CaveMapFragment.height*map.pos.voxelSize -% range < 0) : (wz +%= chunkSize) { var seed: u64 = random.initSeed3D(worldSeed, .{wx, wy, wz}); - considerCoordinates(wx, wy, wz, map, &seed, worldSeed); + considerCoordinates(wx, wy, wz, map, &biomeMap, &seed, worldSeed); } } } } -fn generateSphere(seed: *u64, map: *CaveMapFragment, relPos: Vec3f, radius: f32) void { +fn generateSphere_(seed: *u64, map: *CaveMapFragment, relPos: Vec3f, radius: f32, comptime addTerrain: bool) void { const relX = relPos[0]; const relY = relPos[1]; const relZ = relPos[2]; @@ -86,7 +90,11 @@ fn generateSphere(seed: *u64, map: *CaveMapFragment, relPos: Vec3f, radius: f32) const zDistance = radius*@sqrt(0.9*0.9 - xyDistanceSquared); zMin = @intFromFloat(relZ - zDistance); zMax = @intFromFloat(relZ + zDistance); - map.removeRange(curX, curY, zMin, zMax); // Remove the center range in a single call. + if(addTerrain) { + map.addRange(curX, curY, zMin, zMax); // Add the center range in a single call. + } else { + map.removeRange(curX, curY, zMin, zMax); // Remove the center range in a single call. + } } // Add some roughness at the upper cave walls: var curZ: i32 = zMax; @@ -96,7 +104,11 @@ fn generateSphere(seed: *u64, map: *CaveMapFragment, relPos: Vec3f, radius: f32) if(distToCenter < 1) { // Add a small roughness parameter to make walls look a bit rough by filling only 5/6 of the blocks at the walls with air: if(random.nextIntBounded(u8, seed, 6) != 0) { - map.removeRange(curX, curY, curZ, curZ + 1); + if(addTerrain) { + map.addRange(curX, curY, curZ, curZ + 1); + } else { + map.removeRange(curX, curY, curZ, curZ + 1); + } } } else break; } @@ -108,23 +120,36 @@ fn generateSphere(seed: *u64, map: *CaveMapFragment, relPos: Vec3f, radius: f32) if(distToCenter < 1) { // Add a small roughness parameter to make walls look a bit rough by filling only 5/6 of the blocks at the walls with air: if(random.nextIntBounded(u8, seed, 6) != 0) { - map.removeRange(curX, curY, curZ, curZ + 1); + if(addTerrain) { + map.addRange(curX, curY, curZ, curZ + 1); + } else { + map.removeRange(curX, curY, curZ, curZ + 1); + } } } else break; } } } + +} + +fn generateSphere(seed: *u64, map: *CaveMapFragment, relPos: Vec3f, radius: f32) void { + if(radius < 0) { + generateSphere_(seed, map, relPos, -radius, true); + } else { + generateSphere_(seed, map, relPos, radius, false); + } } fn generateCaveBetween(_seed: u64, map: *CaveMapFragment, startRelPos: Vec3f, endRelPos: Vec3f, bias: Vec3f, startRadius: f32, endRadius: f32, randomness: f32) void { // Check if the segment can cross this chunk: - const maxHeight = @max(startRadius, endRadius); + const maxHeight = @max(@abs(startRadius), @abs(endRadius)); const distance = vec.length(startRelPos - endRelPos); const maxFractalShift = distance*randomness; const safetyInterval = maxHeight + maxFractalShift; const min: Vec3i = @intFromFloat(@min(startRelPos, endRelPos) - @as(Vec3f, @splat(safetyInterval))); const max: Vec3i = @intFromFloat(@max(startRelPos, endRelPos) + @as(Vec3f, @splat(safetyInterval))); - // Only divide further if the cave may go through ther considered chunk. + // Only divide further if the cave may go through the considered chunk. if(min[0] >= CaveMapFragment.width*map.pos.voxelSize or max[0] < 0) return; if(min[1] >= CaveMapFragment.width*map.pos.voxelSize or max[1] < 0) return; if(min[2] >= CaveMapFragment.height*map.pos.voxelSize or max[2] < 0) return; @@ -140,19 +165,37 @@ fn generateCaveBetween(_seed: u64, map: *CaveMapFragment, startRelPos: Vec3f, en random.nextFloatSigned(&seed), } + bias/@as(Vec3f, @splat(4)); var midRadius = (startRadius + endRadius)/2 + maxFractalShift*random.nextFloatSigned(&seed)*heightVariance; - midRadius = @max(midRadius, minRadius); + midRadius = std.math.sign(midRadius)*@max(@abs(midRadius), minRadius); generateCaveBetween(random.nextInt(u64, &seed), map, startRelPos, mid, bias/@as(Vec3f, @splat(4)), startRadius, midRadius, randomness); generateCaveBetween(random.nextInt(u64, &seed), map, mid, endRelPos, bias/@as(Vec3f, @splat(4)), midRadius, endRadius, randomness); } } -fn generateBranchingCaveBetween(_seed: u64, map: *CaveMapFragment, startRelPos: Vec3f, endRelPos: Vec3f, bias: Vec3f, startRadius: f32, endRadius: f32, seedPos: Vec3f, branchLength: f32, randomness: f32, isStart: bool, isEnd: bool) void { +fn generateCaveBetweenAndCheckBiomeProperties(_seed: u64, map: *CaveMapFragment, biomeMap: *const InterpolatableCaveBiomeMapView, startRelPos: Vec3f, endRelPos: Vec3f, bias: Vec3f, startRadius: f32, endRadius: f32, randomness: f32) void { + // Check if the segment can cross this chunk: + const maxHeight = @max(@abs(startRadius), @abs(endRadius)); + const distance = vec.length(startRelPos - endRelPos); + const maxFractalShift = distance*randomness; + const safetyInterval = maxHeight + maxFractalShift; + const min: Vec3i = @intFromFloat(@min(startRelPos, endRelPos) - @as(Vec3f, @splat(safetyInterval))); + const max: Vec3i = @intFromFloat(@max(startRelPos, endRelPos) + @as(Vec3f, @splat(safetyInterval))); + // Only divide further if the cave may go through the considered chunk. + if(min[0] >= CaveMapFragment.width*map.pos.voxelSize or max[0] < 0) return; + if(min[1] >= CaveMapFragment.width*map.pos.voxelSize or max[1] < 0) return; + if(min[2] >= CaveMapFragment.height*map.pos.voxelSize or max[2] < 0) return; + + const startRadiusFactor = biomeMap.getRoughBiome(map.pos.wx +% @as(i32, @intFromFloat(startRelPos[0])), map.pos.wy +% @as(i32, @intFromFloat(startRelPos[1])), map.pos.wz +% @as(i32, @intFromFloat(startRelPos[2])), false, undefined, false).caveRadiusFactor; + const endRadiusFactor = biomeMap.getRoughBiome(map.pos.wx +% @as(i32, @intFromFloat(endRelPos[0])), map.pos.wy +% @as(i32, @intFromFloat(endRelPos[1])), map.pos.wz +% @as(i32, @intFromFloat(endRelPos[2])), false, undefined, false).caveRadiusFactor; + generateCaveBetween(_seed, map, startRelPos, endRelPos, bias, startRadius*startRadiusFactor, endRadius*endRadiusFactor, randomness); +} + +fn generateBranchingCaveBetween(_seed: u64, map: *CaveMapFragment, biomeMap: *const InterpolatableCaveBiomeMapView, startRelPos: Vec3f, endRelPos: Vec3f, bias: Vec3f, startRadius: f32, endRadius: f32, seedPos: Vec3f, branchLength: f32, randomness: f32, isStart: bool, isEnd: bool) void { const distance = vec.length(startRelPos - endRelPos); var seed = _seed; random.scrambleSeed(&seed); if(distance < 32) { // No more branches below that level to avoid crowded caves. - generateCaveBetween(random.nextInt(u64, &seed), map, startRelPos, endRelPos, bias, startRadius, endRadius, randomness); + generateCaveBetweenAndCheckBiomeProperties(random.nextInt(u64, &seed), map, biomeMap, startRelPos, endRelPos, bias, startRadius, endRadius, randomness); // Small chance to branch off: if(!isStart and random.nextFloat(&seed) < branchChance and branchLength > 8) { var newEndPos = startRelPos + Vec3f { @@ -171,7 +214,7 @@ fn generateBranchingCaveBetween(_seed: u64, map: *CaveMapFragment, startRelPos: branchLength*random.nextFloatSigned(&seed), branchLength*random.nextFloatSigned(&seed)/2, }; - generateBranchingCaveBetween(random.nextInt(u64, &seed), map, startRelPos, newEndPos, newBias, newStartRadius, minRadius, seedPos, branchLength/2, @min(0.5/@sqrt(3.0) - 0.01, randomness + randomness*random.nextFloat(&seed)*random.nextFloat(&seed)), true, true); + generateBranchingCaveBetween(random.nextInt(u64, &seed), map, biomeMap, startRelPos, newEndPos, newBias, newStartRadius, minRadius, seedPos, branchLength/2, @min(0.5/@sqrt(3.0) - 0.01, randomness + randomness*random.nextFloat(&seed)*random.nextFloat(&seed)), true, true); } return; } @@ -211,14 +254,14 @@ fn generateBranchingCaveBetween(_seed: u64, map: *CaveMapFragment, startRelPos: } + newBias2*@as(Vec3f, @splat(weight*(1 - weight))); var midRadius = @max(minRadius, (startRadius + endRadius)/2 + maxFractalShift*random.nextFloatSigned(&seed)*heightVariance); - generateBranchingCaveBetween(random.nextInt(u64, &seed), map, startRelPos, mid1, newBias1*@as(Vec3f, @splat(w1)), startRadius, midRadius, seedPos, branchLength, randomness, isStart, false); - generateBranchingCaveBetween(random.nextInt(u64, &seed), map, mid1, endRelPos, newBias1*@as(Vec3f, @splat(w2)), midRadius, endRadius, seedPos, branchLength, randomness, false, isEnd); + generateBranchingCaveBetween(random.nextInt(u64, &seed), map, biomeMap, startRelPos, mid1, newBias1*@as(Vec3f, @splat(w1)), startRadius, midRadius, seedPos, branchLength, randomness, isStart, false); + generateBranchingCaveBetween(random.nextInt(u64, &seed), map, biomeMap, mid1, endRelPos, newBias1*@as(Vec3f, @splat(w2)), midRadius, endRadius, seedPos, branchLength, randomness, false, isEnd); // Do some tweaking to the radius before making the second part: const newStartRadius = (startRadius - minRadius)*random.nextFloat(&seed) + minRadius; const newEndRadius = (endRadius - minRadius)*random.nextFloat(&seed) + minRadius; midRadius = @max(minRadius, (newStartRadius + newEndRadius)/2 + maxFractalShift*random.nextFloatSigned(&seed)*heightVariance); - generateBranchingCaveBetween(random.nextInt(u64, &seed), map, startRelPos, mid2, newBias2*@as(Vec3f, @splat(w1)), newStartRadius, midRadius, seedPos, branchLength, randomness, isStart, false); - generateBranchingCaveBetween(random.nextInt(u64, &seed), map, mid2, endRelPos, newBias2*@as(Vec3f, @splat(w2)), midRadius, newEndRadius, seedPos, branchLength, randomness, false, isEnd); + generateBranchingCaveBetween(random.nextInt(u64, &seed), map, biomeMap, startRelPos, mid2, newBias2*@as(Vec3f, @splat(w1)), newStartRadius, midRadius, seedPos, branchLength, randomness, isStart, false); + generateBranchingCaveBetween(random.nextInt(u64, &seed), map, biomeMap, mid2, endRelPos, newBias2*@as(Vec3f, @splat(w2)), midRadius, newEndRadius, seedPos, branchLength, randomness, false, isEnd); return; } const mid = startRelPos*@as(Vec3f, @splat(weight)) + endRelPos*@as(Vec3f, @splat(1 - weight)) + @as(Vec3f, @splat(maxFractalShift))*Vec3f{ @@ -227,12 +270,12 @@ fn generateBranchingCaveBetween(_seed: u64, map: *CaveMapFragment, startRelPos: random.nextFloatSigned(&seed), } + bias*@as(Vec3f, @splat(weight*(1 - weight))); const midRadius = @max(minRadius, (startRadius + endRadius)/2 + maxFractalShift*random.nextFloatSigned(&seed)*heightVariance); - generateBranchingCaveBetween(random.nextInt(u64, &seed), map, startRelPos, mid, bias*@as(Vec3f, @splat(w1)), startRadius, midRadius, seedPos, branchLength, randomness, isStart, false); - generateBranchingCaveBetween(random.nextInt(u64, &seed), map, mid, endRelPos, bias*@as(Vec3f, @splat(w2)), midRadius, endRadius, seedPos, branchLength, randomness, false, isEnd); + generateBranchingCaveBetween(random.nextInt(u64, &seed), map, biomeMap, startRelPos, mid, bias*@as(Vec3f, @splat(w1)), startRadius, midRadius, seedPos, branchLength, randomness, isStart, false); + generateBranchingCaveBetween(random.nextInt(u64, &seed), map, biomeMap, mid, endRelPos, bias*@as(Vec3f, @splat(w2)), midRadius, endRadius, seedPos, branchLength, randomness, false, isEnd); } -fn considerCoordinates(wx: i32, wy: i32, wz: i32, map: *CaveMapFragment, seed: *u64, worldSeed: u64) void { +fn considerCoordinates(wx: i32, wy: i32, wz: i32, map: *CaveMapFragment, biomeMap: *const InterpolatableCaveBiomeMapView, seed: *u64, worldSeed: u64) void { // Choose some in world coordinates to start generating: const startWorldPos = Vec3f { @floatFromInt(wx +% random.nextIntBounded(u8, seed, chunkSize) -% map.pos.wx), @@ -257,7 +300,7 @@ fn considerCoordinates(wx: i32, wy: i32, wz: i32, map: *CaveMapFragment, seed: * const startRadius: f32 = random.nextFloat(seed)*maxInitialRadius + 2*minRadius; const endRadius: f32 = random.nextFloat(seed)*maxInitialRadius + 2*minRadius; const caveLength = vec.length(startWorldPos - endWorldPos); - generateBranchingCaveBetween(random.nextInt(u64, seed), map, startWorldPos, endWorldPos, Vec3f { + generateBranchingCaveBetween(random.nextInt(u64, seed), map, biomeMap, startWorldPos, endWorldPos, Vec3f { caveLength*random.nextFloatSigned(seed)/2, caveLength*random.nextFloatSigned(seed)/2, caveLength*random.nextFloatSigned(seed)/4,