diff --git a/src/renderer.zig b/src/renderer.zig index a4911bdc..ee3376e2 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -746,21 +746,21 @@ pub const MeshSelection = struct { posBeforeBlock = voxelPos; if(tMax[0] < tMax[1]) { if(tMax[0] < tMax[2]) { - voxelPos[0] += step[0]; + voxelPos[0] +%= step[0]; total_tMax = tMax[0]; tMax[0] += tDelta[0]; } else { - voxelPos[2] += step[2]; + voxelPos[2] +%= step[2]; total_tMax = tMax[2]; tMax[2] += tDelta[2]; } } else { if(tMax[1] < tMax[2]) { - voxelPos[1] += step[1]; + voxelPos[1] +%= step[1]; total_tMax = tMax[1]; tMax[1] += tDelta[1]; } else { - voxelPos[2] += step[2]; + voxelPos[2] +%= step[2]; total_tMax = tMax[2]; tMax[2] += tDelta[2]; } diff --git a/src/renderer/mesh_storage.zig b/src/renderer/mesh_storage.zig index 15faaaec..6d6ebe0a 100644 --- a/src/renderer/mesh_storage.zig +++ b/src/renderer/mesh_storage.zig @@ -167,9 +167,9 @@ pub fn getMeshFromAnyLodFromRenderThread(wx: i32, wy: i32, wz: i32, voxelSize: u pub fn getNeighborFromRenderThread(_pos: chunk.ChunkPosition, resolution: u31, neighbor: u3) ?*chunk_meshing.ChunkMesh { var pos = _pos; - pos.wx += pos.voxelSize*chunk.chunkSize*chunk.Neighbors.relX[neighbor]; - pos.wy += pos.voxelSize*chunk.chunkSize*chunk.Neighbors.relY[neighbor]; - pos.wz += pos.voxelSize*chunk.chunkSize*chunk.Neighbors.relZ[neighbor]; + pos.wx +%= pos.voxelSize*chunk.chunkSize*chunk.Neighbors.relX[neighbor]; + pos.wy +%= pos.voxelSize*chunk.chunkSize*chunk.Neighbors.relY[neighbor]; + pos.wz +%= pos.voxelSize*chunk.chunkSize*chunk.Neighbors.relZ[neighbor]; pos.voxelSize = resolution; const node = getNodeFromRenderThread(pos); return node.mesh.load(.acquire); @@ -219,16 +219,16 @@ fn isInRenderDistance(pos: chunk.ChunkPosition) bool { const minX = lastPx-%maxRenderDistance & invMask; const maxX = lastPx+%maxRenderDistance+%size & invMask; - if(pos.wx < minX) return false; - if(pos.wx >= maxX) return false; + if(pos.wx -% minX < 0) return false; + if(pos.wx -% maxX >= 0) return false; var deltaX: i64 = @abs(pos.wx +% size/2 -% lastPx); deltaX = @max(0, deltaX - size/2); const maxYRenderDistance: i32 = reduceRenderDistance(maxRenderDistance, deltaX); const minY = lastPy-%maxYRenderDistance & invMask; const maxY = lastPy+%maxYRenderDistance+%size & invMask; - if(pos.wy < minY) return false; - if(pos.wy >= maxY) return false; + if(pos.wy -% minY < 0) return false; + if(pos.wy -% maxY >= 0) return false; var deltaY: i64 = @abs(pos.wy +% size/2 -% lastPy); deltaY = @max(0, deltaY - size/2); @@ -236,8 +236,8 @@ fn isInRenderDistance(pos: chunk.ChunkPosition) bool { if(maxZRenderDistance == 0) return false; const minZ = lastPz-%maxZRenderDistance & invMask; const maxZ = lastPz+%maxZRenderDistance+%size & invMask; - if(pos.wz < minZ) return false; - if(pos.wz >= maxZ) return false; + if(pos.wz -% minZ < 0) return false; + if(pos.wz -% maxZ >= 0) return false; return true; } @@ -249,8 +249,8 @@ fn isMapInRenderDistance(pos: LightMap.MapFragmentPosition) bool { const minX = lastPx-%maxRenderDistance & invMask; const maxX = lastPx+%maxRenderDistance+%size & invMask; - if(pos.wx < minX) return false; - if(pos.wx >= maxX) return false; + if(pos.wx -% minX < 0) return false; + if(pos.wx -% maxX >= 0) return false; var deltaX: i64 = @abs(pos.wx +% size/2 -% lastPx); deltaX = @max(0, deltaX - size/2); @@ -258,8 +258,8 @@ fn isMapInRenderDistance(pos: LightMap.MapFragmentPosition) bool { if(maxYRenderDistance == 0) return false; const minY = lastPy-%maxYRenderDistance & invMask; const maxY = lastPy+%maxYRenderDistance+%size & invMask; - if(pos.wy < minY) return false; - if(pos.wy >= maxY) return false; + if(pos.wy -% minY < 0) return false; + if(pos.wy -% maxY >= 0) return false; return true; } @@ -751,9 +751,9 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V const max = data.node.max; if(@reduce(.Or, min >= max)) continue; // Nothing to render. var neighborPos = chunk.ChunkPosition{ - .wx = mesh.pos.wx + chunk.Neighbors.relX[neighbor]*chunk.chunkSize*mesh.pos.voxelSize, - .wy = mesh.pos.wy + chunk.Neighbors.relY[neighbor]*chunk.chunkSize*mesh.pos.voxelSize, - .wz = mesh.pos.wz + chunk.Neighbors.relZ[neighbor]*chunk.chunkSize*mesh.pos.voxelSize, + .wx = mesh.pos.wx +% chunk.Neighbors.relX[neighbor]*chunk.chunkSize*mesh.pos.voxelSize, + .wy = mesh.pos.wy +% chunk.Neighbors.relY[neighbor]*chunk.chunkSize*mesh.pos.voxelSize, + .wz = mesh.pos.wz +% chunk.Neighbors.relZ[neighbor]*chunk.chunkSize*mesh.pos.voxelSize, .voxelSize = mesh.pos.voxelSize, }; var lod: u3 = data.node.lod; diff --git a/src/server/terrain/CaveBiomeMap.zig b/src/server/terrain/CaveBiomeMap.zig index c3743636..101b4c2d 100644 --- a/src/server/terrain/CaveBiomeMap.zig +++ b/src/server/terrain/CaveBiomeMap.zig @@ -375,9 +375,9 @@ pub const CaveBiomeMapView = struct { .super = InterpolatableCaveBiomeMapView.init(chunk.pos, chunk.width), }; if(chunk.pos.voxelSize < 8) { - const startX = (chunk.pos.wx - 32) & ~@as(i32, 63); - const startY = (chunk.pos.wy - 32) & ~@as(i32, 63); - const startZ = (chunk.pos.wz - 32) & ~@as(i32, 63); + const startX = (chunk.pos.wx -% 32) & ~@as(i32, 63); + const startY = (chunk.pos.wy -% 32) & ~@as(i32, 63); + const startZ = (chunk.pos.wz -% 32) & ~@as(i32, 63); self.noiseX = CachedFractalNoise3D.init(startX, startY, startZ, chunk.pos.voxelSize*4, chunk.width + 128, main.server.world.?.seed ^ 0x764923684396, 64); self.noiseY = CachedFractalNoise3D.init(startX, startY, startZ, chunk.pos.voxelSize*4, chunk.width + 128, main.server.world.?.seed ^ 0x6547835649265429, 64); self.noiseZ = CachedFractalNoise3D.init(startX, startY, startZ, chunk.pos.voxelSize*4, chunk.width + 128, main.server.world.?.seed ^ 0x56789365396783, 64); diff --git a/src/server/terrain/CaveMap.zig b/src/server/terrain/CaveMap.zig index a9a088f5..18baff77 100644 --- a/src/server/terrain/CaveMap.zig +++ b/src/server/terrain/CaveMap.zig @@ -184,7 +184,7 @@ pub const CaveMapView = struct { if(wy -% self.fragments[0].pos.wy >= CaveMapFragment.width*self.reference.pos.voxelSize) { index += 2; } - var deltaZ = self.reference.pos.wz - self.fragments[0].pos.wz; + var deltaZ = self.reference.pos.wz -% self.fragments[0].pos.wz; if(deltaZ >= CaveMapFragment.height*self.reference.pos.voxelSize) { index += 1; deltaZ -= CaveMapFragment.height*self.reference.pos.voxelSize; @@ -209,7 +209,7 @@ pub const CaveMapView = struct { if(wy -% self.fragments[0].pos.wy >= CaveMapFragment.width*self.reference.pos.voxelSize) { index += 2; } - var relativeZ = @divFloor(z + self.reference.pos.wz - self.fragments[0].pos.wz, self.reference.pos.voxelSize); + var relativeZ = @divFloor(z +% self.reference.pos.wz -% self.fragments[0].pos.wz, self.reference.pos.voxelSize); std.debug.assert(relativeZ >= 0 and relativeZ < 2*CaveMapFragment.height); const fragmentRelX = wx - self.fragments[index].pos.wx; const fragmentRelY = wy - self.fragments[index].pos.wy; @@ -237,7 +237,7 @@ pub const CaveMapView = struct { } } result += @ctz(height); - return result*self.reference.pos.voxelSize + self.fragments[0].pos.wz - self.reference.pos.wz; + return result*self.reference.pos.voxelSize +% self.fragments[0].pos.wz -% self.reference.pos.wz; } pub fn findTerrainChangeBelow(self: CaveMapView, relX: i32, relY: i32, z: i32) i32 { @@ -250,7 +250,7 @@ pub const CaveMapView = struct { if(wy -% self.fragments[0].pos.wy >= CaveMapFragment.width*self.reference.pos.voxelSize) { index += 2; } - var relativeZ = @divFloor(z + self.reference.pos.wz - self.fragments[0].pos.wz, self.reference.pos.voxelSize); + var relativeZ = @divFloor(z +% self.reference.pos.wz -% self.fragments[0].pos.wz, self.reference.pos.voxelSize); std.debug.assert(relativeZ >= 0 and relativeZ < 2*CaveMapFragment.height); const fragmentRelX = wx - self.fragments[index].pos.wx; const fragmentRelY = wy - self.fragments[index].pos.wy; @@ -278,7 +278,7 @@ pub const CaveMapView = struct { } } result -= @clz(height); - return result*self.reference.pos.voxelSize + self.fragments[0].pos.wz - self.reference.pos.wz; + return result*self.reference.pos.voxelSize +% self.fragments[0].pos.wz -% self.reference.pos.wz; } }; diff --git a/src/server/terrain/SurfaceMap.zig b/src/server/terrain/SurfaceMap.zig index a0084c63..7ad4252c 100644 --- a/src/server/terrain/SurfaceMap.zig +++ b/src/server/terrain/SurfaceMap.zig @@ -41,9 +41,10 @@ pub const MapFragmentPosition = struct { } pub fn getMinDistanceSquared(self: MapFragmentPosition, playerPosition: Vec3d, comptime width: comptime_int) f64 { + const adjustedPosition = @mod(playerPosition + @as(Vec3d, @splat(1 << 31)), @as(Vec3d, @splat(1 << 32))) - @as(Vec3d, @splat(1 << 31)); const halfWidth: f64 = @floatFromInt(self.voxelSize*@divExact(width, 2)); - var dx = @abs(@as(f64, @floatFromInt(self.wx)) + halfWidth - playerPosition[0]); - var dy = @abs(@as(f64, @floatFromInt(self.wy)) + halfWidth - playerPosition[1]); + var dx = @abs(@as(f64, @floatFromInt(self.wx)) + halfWidth - adjustedPosition[0]); + var dy = @abs(@as(f64, @floatFromInt(self.wy)) + halfWidth - adjustedPosition[1]); dx = @max(0, dx - halfWidth); dy = @max(0, dy - halfWidth); return dx*dx + dy*dy; diff --git a/src/server/terrain/cavebiomegen/RandomBiomeDistribution.zig b/src/server/terrain/cavebiomegen/RandomBiomeDistribution.zig index cfa26a45..4a8bd930 100644 --- a/src/server/terrain/cavebiomegen/RandomBiomeDistribution.zig +++ b/src/server/terrain/cavebiomegen/RandomBiomeDistribution.zig @@ -48,7 +48,7 @@ pub fn generate(map: *CaveBiomeMapFragment, worldSeed: u64) void { var insertionIndex: usize = 0; var i: usize = 0; while(i < validBiomes.items.len) : (i += 1) { - if(validBiomes.items[i].minHeight < map.pos.wz +% z +% CaveBiomeMapFragment.caveBiomeSize and validBiomes.items[i].maxHeight > map.pos.wz +% z) { + if(validBiomes.items[i].minHeight < map.pos.wz + z + (CaveBiomeMapFragment.caveBiomeSize - 1) and validBiomes.items[i].maxHeight > map.pos.wz + z) { if(insertionIndex != i) { const swap = validBiomes.items[i]; validBiomes.items[i] = validBiomes.items[insertionIndex]; diff --git a/src/server/terrain/cavegen/SurfaceGenerator.zig b/src/server/terrain/cavegen/SurfaceGenerator.zig index 19ee534e..c8e4d4ec 100644 --- a/src/server/terrain/cavegen/SurfaceGenerator.zig +++ b/src/server/terrain/cavegen/SurfaceGenerator.zig @@ -45,7 +45,7 @@ pub fn generate(map: *CaveMapFragment, worldSeed: u64) void { biomeMap.getSurfaceHeight(map.pos.wx +% x, map.pos.wy +% y -% 1), height, ) - 0.5)); - const relativeHeight: i32 = @as(i32, @intFromFloat(height)) - map.pos.wz; + const relativeHeight: i32 = @as(i32, @intFromFloat(height)) -% map.pos.wz; map.removeRange(x, y, relativeHeight, CaveMapFragment.height*map.pos.voxelSize); if(smallestHeight < 1) { // Seal off caves that intersect the ocean floor. map.addRange(x, y, smallestHeight -% 1 -% map.pos.wz, relativeHeight); diff --git a/src/server/terrain/chunkgen/StructureGenerator.zig b/src/server/terrain/chunkgen/StructureGenerator.zig index 6b1126be..20a25c3d 100644 --- a/src/server/terrain/chunkgen/StructureGenerator.zig +++ b/src/server/terrain/chunkgen/StructureGenerator.zig @@ -30,7 +30,7 @@ pub fn deinit() void { pub fn generate(worldSeed: u64, chunk: *main.chunk.Chunk, caveMap: CaveMap.CaveMapView, biomeMap: CaveBiomeMap.CaveBiomeMapView) void { if(chunk.pos.voxelSize < 4) { // Uses a blue noise pattern for all structure that shouldn't touch. - const blueNoise = noise.BlueNoise.getRegionData(main.stackAllocator, chunk.pos.wx - 8, chunk.pos.wy - 8, chunk.width + 16, chunk.width + 16); + const blueNoise = noise.BlueNoise.getRegionData(main.stackAllocator, chunk.pos.wx -% 8, chunk.pos.wy -% 8, chunk.width + 16, chunk.width + 16); defer main.stackAllocator.free(blueNoise); for(blueNoise) |coordinatePair| { const px = @as(i32, @intCast(coordinatePair >> 16)) - 8; // TODO: Maybe add a blue-noise iterator or something like that? @@ -71,7 +71,7 @@ pub fn generate(worldSeed: u64, chunk: *main.chunk.Chunk, caveMap: CaveMap.CaveM const wpx = px -% 8 +% chunk.pos.wx; const wpy = py -% 8 +% chunk.pos.wy; - const relZ = @as(i32, @intFromFloat(biomeMap.getSurfaceHeight(wpx, wpy))) - chunk.pos.wz; + const relZ = @as(i32, @intFromFloat(biomeMap.getSurfaceHeight(wpx, wpy))) -% chunk.pos.wz; if(relZ < -32 or relZ >= chunk.width + 32) continue; var seed = random.initSeed3D(worldSeed, .{wpx, wpy, relZ});