diff --git a/src/chunk.zig b/src/chunk.zig index 20b7c861..0dd8cafd 100644 --- a/src/chunk.zig +++ b/src/chunk.zig @@ -371,16 +371,6 @@ pub const Chunk = struct { } } } - -// TODO: Check if/how they are needed: -// -// public Vector3d getMin() { -// return new Vector3d(wx, wy, wz); -// } -// -// public Vector3d getMax() { -// return new Vector3d(wx + width, wy + width, wz + width); -// } }; @@ -1067,14 +1057,12 @@ pub const meshing = struct { }/@as(Vec3d, @splat(@as(f64, @floatFromInt(self.pos.voxelSize)))); relativePos = @min(relativePos, @as(Vec3d, @splat(0))); relativePos = @max(relativePos, @as(Vec3d, @splat(-32))); - var updatePos = vec.intFromFloat(i32, relativePos); + var updatePos: Vec3i = @intFromFloat(relativePos); if(@reduce(.Or, updatePos != self.lastTransparentUpdatePos)) { self.lastTransparentUpdatePos = updatePos; needsUpdate = true; } if(needsUpdate) { - // TODO: Could additionally filter back-faces to reduce work on the gpu side. - for(self.currentSorting) |*val| { val.update( updatePos[0], diff --git a/src/gui/gui.zig b/src/gui/gui.zig index 3a7681ea..48639e53 100644 --- a/src/gui/gui.zig +++ b/src/gui/gui.zig @@ -643,12 +643,12 @@ pub const inventory = struct { } } else if(!hoveredAWindow) { if(leftClick or carriedItemStack.amount == 1) { - main.network.Protocols.genericUpdate.itemStackDrop(main.game.world.?.conn, carriedItemStack, vec.floatCast(f32, main.game.Player.getPosBlocking()), main.game.camera.direction, 20) catch |err| { + main.network.Protocols.genericUpdate.itemStackDrop(main.game.world.?.conn, carriedItemStack, @floatCast(main.game.Player.getPosBlocking()), main.game.camera.direction, 20) catch |err| { std.log.err("Error while dropping itemStack: {s}", .{@errorName(err)}); }; carriedItemStack.clear(); } else if(carriedItemStack.amount != 0) { - main.network.Protocols.genericUpdate.itemStackDrop(main.game.world.?.conn, .{.item = carriedItemStack.item, .amount = 1}, vec.floatCast(f32, main.game.Player.getPosBlocking()), main.game.camera.direction, 20) catch |err| { + main.network.Protocols.genericUpdate.itemStackDrop(main.game.world.?.conn, .{.item = carriedItemStack.item, .amount = 1}, @floatCast(main.game.Player.getPosBlocking()), main.game.camera.direction, 20) catch |err| { std.log.err("Error while dropping itemStack: {s}", .{@errorName(err)}); }; _ = carriedItemStack.add(@as(i32, -1)); diff --git a/src/itemdrop.zig b/src/itemdrop.zig index 084f540b..4f4ba61a 100644 --- a/src/itemdrop.zig +++ b/src/itemdrop.zig @@ -358,7 +358,7 @@ pub const ItemDropManager = struct { fn fixStuckInBlock(self: *ItemDropManager, chunk: *Chunk, pos: *Vec3d, vel: *Vec3d, deltaTime: f64) void { std.debug.assert(!self.mutex.tryLock()); // Mutex must be locked! const centeredPos = pos.* - @as(Vec3d, @splat(0.5)); - const pos0 = vec.intFromFloat(i32, @floor(centeredPos)); + const pos0: Vec3i = @intFromFloat(@floor(centeredPos)); var closestEmptyBlock: Vec3i = @splat(-1); var closestDist = std.math.floatMax(f64); @@ -370,7 +370,7 @@ pub const ItemDropManager = struct { while(delta[2] <= 1) : (delta[2] += 1) { const isSolid = self.checkBlock(chunk, pos, pos0 + delta); if(!isSolid) { - const dist = vec.lengthSquare(vec.floatFromInt(f64, pos0 + delta) - centeredPos); + const dist = vec.lengthSquare(@as(Vec3d, @floatFromInt(pos0 + delta)) - centeredPos); if(dist < closestDist) { closestDist = dist; closestEmptyBlock = delta; @@ -381,13 +381,13 @@ pub const ItemDropManager = struct { } vel.* = @splat(0); - const factor: f64 = 1; // TODO: Investigate what past me wanted to accomplish here. + const unstuckVelocity: f64 = 1; if(closestDist == std.math.floatMax(f64)) { // Surrounded by solid blocks → move upwards - vel.*[1] = factor; + vel.*[1] = unstuckVelocity; pos.*[1] += vel.*[1]*deltaTime; } else { - vel.* = @as(Vec3d, @splat(factor))*(vec.floatFromInt(f64, pos0 + closestEmptyBlock) - centeredPos); + vel.* = @as(Vec3d, @splat(unstuckVelocity))*(@as(Vec3d, @floatFromInt(pos0 + closestEmptyBlock)) - centeredPos); pos.* += (vel.*)*@as(Vec3d, @splat(deltaTime)); } } @@ -395,7 +395,7 @@ pub const ItemDropManager = struct { fn checkBlocks(self: *ItemDropManager, chunk: *Chunk, pos: *Vec3d) bool { const lowerCornerPos = pos.* - @as(Vec3d, @splat(radius)); const pos0f64 = @floor(lowerCornerPos); - const pos0 = vec.intFromFloat(i32, pos0f64); + const pos0: Vec3i = @intFromFloat(pos0f64); var isSolid = self.checkBlock(chunk, pos, pos0); if(pos.*[0] - pos0f64[0] + diameter >= 1) { isSolid = isSolid or self.checkBlock(chunk, pos, pos0 + Vec3i{1, 0, 0}); @@ -454,7 +454,7 @@ pub const ClientItemDropManager = struct { timeDifference: utils.TimeDifference = .{}, - interpolation: utils.GenericInterpolation(maxf64Capacity)align(32) = undefined, // TODO: Remove align(32) after #14527 + interpolation: utils.GenericInterpolation(maxf64Capacity)align(64) = undefined, var instance: ?*ClientItemDropManager = null; @@ -750,7 +750,7 @@ pub const ItemDropRenderer = struct { Vec3f{light >> 16 & 255, light >> 8 & 255, light & 255}/@as(Vec3f, @splat(255)) ))); pos -= playerPos; - var modelMatrix = Mat4f.translation(vec.floatCast(f32, pos)); + var modelMatrix = Mat4f.translation(@floatCast(pos)); modelMatrix = modelMatrix.mul(Mat4f.rotationX(-rot[0])); modelMatrix = modelMatrix.mul(Mat4f.rotationY(-rot[1])); modelMatrix = modelMatrix.mul(Mat4f.rotationZ(-rot[2])); diff --git a/src/main.zig b/src/main.zig index dd5dc299..bf6f8c12 100644 --- a/src/main.zig +++ b/src/main.zig @@ -734,8 +734,10 @@ pub fn main() !void { c.glfwSwapBuffers(Window.window); Window.handleEvents(); gui.windowlist.gpu_performance_measuring.startQuery(.screenbuffer_clear); - c.glClearColor(0.5, 1, 1, 1); - c.glClear(c.GL_DEPTH_BUFFER_BIT | c.GL_STENCIL_BUFFER_BIT | c.GL_COLOR_BUFFER_BIT); // TODO: It appears that this is only needed, in the menu, if we don't have a background scene. + if(game.world == null) { // Clearing is only needed in the menu. + c.glClearColor(0.5, 1, 1, 1); + c.glClear(c.GL_DEPTH_BUFFER_BIT | c.GL_STENCIL_BUFFER_BIT | c.GL_COLOR_BUFFER_BIT); + } gui.windowlist.gpu_performance_measuring.stopQuery(); var newTime = std.time.nanoTimestamp(); var deltaTime = @as(f64, @floatFromInt(newTime -% lastTime))/1e9; diff --git a/src/renderer.zig b/src/renderer.zig index ab5982f4..7c0f350e 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -512,6 +512,10 @@ pub const MenuBackGround = struct { c.glDeleteBuffers(2, &vbos); } + pub fn hasImage() bool { + return texture.textureID != 0; + } + pub fn render() void { if(texture.textureID == 0) return; c.glDisable(c.GL_CULL_FACE); // I'm not sure if my triangles are rotated correctly, and there are no triangles facing away from the player anyways. @@ -697,19 +701,19 @@ pub const MeshSelection = struct { var pos = _pos; // TODO: pos.y += Player.cameraHeight; lastPos = pos; - var dir = vec.floatCast(f64, _dir); + var dir: Vec3d = @floatCast(_dir); lastDir = _dir; // Test blocks: const closestDistance: f64 = 6.0; // selection now limited // Implementation of "A Fast Voxel Traversal Algorithm for Ray Tracing" http://www.cse.yorku.ca/~amana/research/grid.pdf - const step = vec.intFromFloat(i32, std.math.sign(dir)); + const step: Vec3i = @intFromFloat(std.math.sign(dir)); const invDir = @as(Vec3d, @splat(1))/dir; const tDelta = @abs(invDir); var tMax = (@floor(pos) - pos)*invDir; - tMax = @max(tMax, tMax + tDelta*vec.floatFromInt(f64, step)); + tMax = @max(tMax, tMax + tDelta*@as(Vec3f, @floatFromInt(step))); tMax = @select(f64, dir == @as(Vec3d, @splat(0)), @as(Vec3d, @splat(std.math.inf(f64))), tMax); - var voxelPos = vec.intFromFloat(i32, @floor(pos)); + var voxelPos: Vec3i = @intFromFloat(@floor(pos)); var total_tMax: f64 = 0; @@ -723,10 +727,11 @@ pub const MeshSelection = struct { const voxelModel = &models.voxelModels.items[model.modelIndex]; var transformedMin = model.permutation.transform(voxelModel.min - @as(Vec3i, @splat(8))) + @as(Vec3i, @splat(8)); var transformedMax = model.permutation.transform(voxelModel.max - @as(Vec3i, @splat(8))) + @as(Vec3i, @splat(8)); - const min = @min(transformedMin, transformedMax); - const max = @max(transformedMin ,transformedMax); - const t1 = (vec.floatFromInt(f64, voxelPos) + vec.floatFromInt(f64, min)/@as(Vec3d, @splat(16.0)) - pos)*invDir; - const t2 = (vec.floatFromInt(f64, voxelPos) + vec.floatFromInt(f64, max)/@as(Vec3d, @splat(16.0)) - pos)*invDir; + const min: Vec3d = @floatFromInt(@min(transformedMin, transformedMax)); + const max: Vec3d = @floatFromInt(@max(transformedMin ,transformedMax)); + const voxelPosFloat: Vec3d = @floatFromInt(voxelPos); + const t1 = (voxelPosFloat + min/@as(Vec3d, @splat(16.0)) - pos)*invDir; + const t2 = (voxelPosFloat + max/@as(Vec3d, @splat(16.0)) - pos)*invDir; const boxTMin = @reduce(.Max, @min(t1, t2)); const boxTMax = @reduce(.Min, @max(t1, t2)); if(boxTMin <= boxTMax and boxTMin <= closestDistance and boxTMax > 0) { @@ -771,7 +776,7 @@ pub const MeshSelection = struct { var neighborDir = Vec3i{0, 0, 0}; // Check if stuff can be added to the block itself: if(itemBlock == block.typ) { - const relPos = lastPos - vec.floatFromInt(f64, selectedPos); + const relPos = lastPos - @as(Vec3d, @floatFromInt(selectedPos)); if(rotationMode.generateData(main.game.world.?, selectedPos, relPos, lastDir, neighborDir, &block, false)) { // TODO: world.updateBlock(bi.x, bi.y, bi.z, block.data); (→ Sending it over the network) try RenderStructure.updateBlock(selectedPos[0], selectedPos[1], selectedPos[2], block); @@ -782,7 +787,7 @@ pub const MeshSelection = struct { // Check the block in front of it: const neighborPos = posBeforeBlock; neighborDir = selectedPos - posBeforeBlock; - const relPos = lastPos - vec.floatFromInt(f64, neighborPos); + const relPos = lastPos - @as(Vec3d, @floatFromInt(neighborPos)); block = RenderStructure.getBlock(neighborPos[0], neighborPos[1], neighborPos[2]) orelse return; if(block.typ == itemBlock) { if(rotationMode.generateData(main.game.world.?, neighborPos, relPos, lastDir, neighborDir, &block, false)) { @@ -851,9 +856,9 @@ pub const MeshSelection = struct { const voxelModel = &models.voxelModels.items[model.modelIndex]; var transformedMin = model.permutation.transform(voxelModel.min - @as(Vec3i, @splat(8))) + @as(Vec3i, @splat(8)); var transformedMax = model.permutation.transform(voxelModel.max - @as(Vec3i, @splat(8))) + @as(Vec3i, @splat(8)); - const min = @min(transformedMin, transformedMax); - const max = @max(transformedMin ,transformedMax); - drawCube(projectionMatrix, viewMatrix, vec.floatFromInt(f64, _selectedBlockPos) - playerPos, vec.floatFromInt(f32, min)/@as(Vec3f, @splat(16.0)), vec.floatFromInt(f32, max)/@as(Vec3f, @splat(16.0))); + const min: Vec3f = @floatFromInt(@min(transformedMin, transformedMax)); + const max: Vec3f = @floatFromInt(@max(transformedMin ,transformedMax)); + drawCube(projectionMatrix, viewMatrix, @as(Vec3d, @floatFromInt(_selectedBlockPos)) - playerPos, min/@as(Vec3f, @splat(16.0)), max/@as(Vec3f, @splat(16.0))); } } }; @@ -1154,15 +1159,15 @@ pub const RenderStructure = struct { } } try meshList.append(mesh); - const relPos: Vec3d = vec.floatFromInt(f64, Vec3i{mesh.pos.wx, mesh.pos.wy, mesh.pos.wz}) - playerPos; - const relPosFloat: Vec3f = vec.floatCast(f32, relPos); + const relPos: Vec3d = @as(Vec3d, @floatFromInt(Vec3i{mesh.pos.wx, mesh.pos.wy, mesh.pos.wz})) - playerPos; + const relPosFloat: Vec3f = @floatCast(relPos); for(chunk.Neighbors.iterable) |neighbor| continueNeighborLoop: { const component = chunk.Neighbors.extractDirectionComponent(neighbor, relPos); if(chunk.Neighbors.isPositive[neighbor] and component + @as(f64, @floatFromInt(chunk.chunkSize*mesh.pos.voxelSize)) <= 0) continue; if(!chunk.Neighbors.isPositive[neighbor] and component >= 0) continue; if(@reduce(.Or, @min(mesh.chunkBorders[neighbor].min, mesh.chunkBorders[neighbor].max) != mesh.chunkBorders[neighbor].min)) continue; // There was not a single block in the chunk. TODO: Find a better solution. - const minVec = vec.floatFromInt(f32, mesh.chunkBorders[neighbor].min*@as(Vec3i, @splat(mesh.pos.voxelSize))); - const maxVec = vec.floatFromInt(f32, mesh.chunkBorders[neighbor].max*@as(Vec3i, @splat(mesh.pos.voxelSize))); + const minVec: Vec3f = @floatFromInt(mesh.chunkBorders[neighbor].min*@as(Vec3i, @splat(mesh.pos.voxelSize))); + const maxVec: Vec3f = @floatFromInt(mesh.chunkBorders[neighbor].max*@as(Vec3i, @splat(mesh.pos.voxelSize))); var xyMin: Vec2f = .{10, 10}; var xyMax: Vec2f = .{-10, -10}; var numberOfNegatives: u8 = 0; diff --git a/src/server/terrain/CaveBiomeMap.zig b/src/server/terrain/CaveBiomeMap.zig index 1cf101c9..026333d6 100644 --- a/src/server/terrain/CaveBiomeMap.zig +++ b/src/server/terrain/CaveBiomeMap.zig @@ -364,10 +364,12 @@ pub const CaveBiomeMapView = struct { .super = try InterpolatableCaveBiomeMapView.init(chunk.pos, chunk.width), }; if(chunk.pos.voxelSize < 8) { - // TODO: Reduce line length. - self.noiseX = try CachedFractalNoise3D.init((chunk.pos.wx - 32) & ~@as(i32, 63), (chunk.pos.wy - 32) & ~@as(i32, 63), (chunk.pos.wz - 32) & ~@as(i32, 63), chunk.pos.voxelSize*4, chunk.width + 128, main.server.world.?.seed ^ 0x764923684396, 64); - self.noiseY = try CachedFractalNoise3D.init((chunk.pos.wx - 32) & ~@as(i32, 63), (chunk.pos.wy - 32) & ~@as(i32, 63), (chunk.pos.wz - 32) & ~@as(i32, 63), chunk.pos.voxelSize*4, chunk.width + 128, main.server.world.?.seed ^ 0x6547835649265429, 64); - self.noiseZ = try CachedFractalNoise3D.init((chunk.pos.wx - 32) & ~@as(i32, 63), (chunk.pos.wy - 32) & ~@as(i32, 63), (chunk.pos.wz - 32) & ~@as(i32, 63), chunk.pos.voxelSize*4, chunk.width + 128, main.server.world.?.seed ^ 0x56789365396783, 64); + 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 = try CachedFractalNoise3D.init(startX, startY, startZ, chunk.pos.voxelSize*4, chunk.width + 128, main.server.world.?.seed ^ 0x764923684396, 64); + self.noiseY = try CachedFractalNoise3D.init(startX, startY, startZ, chunk.pos.voxelSize*4, chunk.width + 128, main.server.world.?.seed ^ 0x6547835649265429, 64); + self.noiseZ = try CachedFractalNoise3D.init(startX, startY, startZ, chunk.pos.voxelSize*4, chunk.width + 128, main.server.world.?.seed ^ 0x56789365396783, 64); } return self; } diff --git a/src/server/terrain/cavegen/FractalCaveGenerator.zig b/src/server/terrain/cavegen/FractalCaveGenerator.zig index 026126d2..ada1940e 100644 --- a/src/server/terrain/cavegen/FractalCaveGenerator.zig +++ b/src/server/terrain/cavegen/FractalCaveGenerator.zig @@ -127,8 +127,8 @@ fn generateCaveBetween(_seed: u64, map: *CaveMapFragment, startWorldPos: Vec3d, const distance = vec.length(startWorldPos - endWorldPos); const maxFractalShift = distance*randomness; const safetyInterval = maxHeight + maxFractalShift; - const min = vec.intFromFloat(i32, @min(startWorldPos, endWorldPos) - @as(Vec3d, @splat(safetyInterval))); - const max = vec.intFromFloat(i32, @max(startWorldPos, endWorldPos) + @as(Vec3d, @splat(safetyInterval))); + const min: Vec3i = @intFromFloat(@min(startWorldPos, endWorldPos) - @as(Vec3d, @splat(safetyInterval))); + const max: Vec3i = @intFromFloat(@max(startWorldPos, endWorldPos) + @as(Vec3d, @splat(safetyInterval))); // Only divide further if the cave may go through ther considered chunk. if(min[0] >= map.pos.wx +% CaveMapFragment.width*map.pos.voxelSize or max[0] < map.pos.wx) return; if(min[1] >= map.pos.wy +% CaveMapFragment.height*map.pos.voxelSize or max[1] < map.pos.wy) return; @@ -168,7 +168,8 @@ fn generateBranchingCaveBetween(_seed: u64, map: *CaveMapFragment, startWorldPos const distanceToSeedPoint = vec.length(startWorldPos - newEndPos); // Reduce distance to avoid cutoffs: if(distanceToSeedPoint > (range - 1)*chunkSize) { - newEndPos = vec.floatFromInt(f64, centerWorldPos) + (newEndPos - vec.floatFromInt(f64, centerWorldPos))*@as(Vec3d, @splat(((range - 1)*chunkSize)/distanceToSeedPoint)); + const centerWorldPosFloat: Vec3d = @floatFromInt(centerWorldPos); + newEndPos = centerWorldPosFloat + (newEndPos - centerWorldPosFloat)*@as(Vec3d, @splat(((range - 1)*chunkSize)/distanceToSeedPoint)); } const newStartRadius = (startRadius - minRadius)*random.nextDouble(&seed) + minRadius; const newBias = Vec3d { diff --git a/src/server/terrain/cavegen/NoiseCaveGenerator.zig b/src/server/terrain/cavegen/NoiseCaveGenerator.zig index 6020e2f1..423efba2 100644 --- a/src/server/terrain/cavegen/NoiseCaveGenerator.zig +++ b/src/server/terrain/cavegen/NoiseCaveGenerator.zig @@ -32,12 +32,8 @@ pub fn deinit() void { const scale = 64; const interpolatedPart = 4; -fn getValue(noise: Array3D(f32), map: *CaveMapFragment, outerSize: u31, biomeMap: InterpolatableCaveBiomeMapView, wx: i32, wy: i32, wz: i32) f32 { - _ = biomeMap; // TODO: clean this up at some point. - const relX: u31 = @intCast(wx - map.pos.wx); - const relY: u31 = @intCast(wy - map.pos.wy); - const relZ: u31 = @intCast(wz - map.pos.wz); - return noise.get(relX/outerSize, relY/outerSize, relZ/outerSize);// + biomeMap.interpolateValue(wx, wy, wz, "caves")*scale; +fn getValue(noise: Array3D(f32), outerSizeShift: u5, relX: u31, relY: u31, relZ: u31) f32 { + return noise.get(relX >> outerSizeShift, relY >> outerSizeShift, relZ >> outerSizeShift); } pub fn generate(map: *CaveMapFragment, worldSeed: u64) Allocator.Error!void { @@ -45,6 +41,7 @@ pub fn generate(map: *CaveMapFragment, worldSeed: u64) Allocator.Error!void { const biomeMap = try InterpolatableCaveBiomeMapView.init(map.pos, CaveMapFragment.width*map.pos.voxelSize); defer biomeMap.deinit(); const outerSize = @max(map.pos.voxelSize, interpolatedPart); + const outerSizeShift = std.math.log2_int(u31, outerSize); const outerSizeFloat: f32 = @floatFromInt(outerSize); var noise = try FractalNoise3D.generateAligned(main.threadAllocator, map.pos.wx, map.pos.wy, map.pos.wz, outerSize, CaveMapFragment.width*map.pos.voxelSize/outerSize + 1, CaveMapFragment.height*map.pos.voxelSize/outerSize + 1, CaveMapFragment.width*map.pos.voxelSize/outerSize + 1, worldSeed, scale);//try Cached3DFractalNoise.init(map.pos.wx, map.pos.wy & ~@as(i32, CaveMapFragment.width*map.pos.voxelSize - 1), map.pos.wz, outerSize, map.pos.voxelSize*CaveMapFragment.width, worldSeed, scale); defer noise.deinit(main.threadAllocator); @@ -55,14 +52,14 @@ pub fn generate(map: *CaveMapFragment, worldSeed: u64) Allocator.Error!void { while(y < map.pos.voxelSize*CaveMapFragment.height) : (y += outerSize) { var z: u31 = 0; while(z < map.pos.voxelSize*CaveMapFragment.width) : (z += outerSize) { - const val000 = getValue(noise, map, outerSize, biomeMap, x + map.pos.wx, y + map.pos.wy, z + map.pos.wz); - const val001 = getValue(noise, map, outerSize, biomeMap, x + map.pos.wx, y + map.pos.wy, z + map.pos.wz + outerSize); - const val010 = getValue(noise, map, outerSize, biomeMap, x + map.pos.wx, y + map.pos.wy + outerSize, z + map.pos.wz); - const val011 = getValue(noise, map, outerSize, biomeMap, x + map.pos.wx, y + map.pos.wy + outerSize, z + map.pos.wz + outerSize); - const val100 = getValue(noise, map, outerSize, biomeMap, x + map.pos.wx + outerSize, y + map.pos.wy, z + map.pos.wz); - const val101 = getValue(noise, map, outerSize, biomeMap, x + map.pos.wx + outerSize, y + map.pos.wy, z + map.pos.wz + outerSize); - const val110 = getValue(noise, map, outerSize, biomeMap, x + map.pos.wx + outerSize, y + map.pos.wy + outerSize, z + map.pos.wz); - const val111 = getValue(noise, map, outerSize, biomeMap, x + map.pos.wx + outerSize, y + map.pos.wy + outerSize, z + map.pos.wz + outerSize); + const val000 = getValue(noise, outerSizeShift, x, y, z); + const val001 = getValue(noise, outerSizeShift, x, y, z + outerSize); + const val010 = getValue(noise, outerSizeShift, x, y + outerSize, z); + const val011 = getValue(noise, outerSizeShift, x, y + outerSize, z + outerSize); + const val100 = getValue(noise, outerSizeShift, x + outerSize, y, z); + const val101 = getValue(noise, outerSizeShift, x + outerSize, y, z + outerSize); + const val110 = getValue(noise, outerSizeShift, x + outerSize, y + outerSize, z); + const val111 = getValue(noise, outerSizeShift, x + outerSize, y + outerSize, z + outerSize); // Test if they are all inside or all outside the cave to skip these cases: const measureForEquality = sign(val000) + sign(val001) + sign(val010) + sign(val011) + sign(val100) + sign(val101) + sign(val110) + sign(val111); if(measureForEquality == -8) { diff --git a/src/server/terrain/climategen/NoiseBasedVoronoi.zig b/src/server/terrain/climategen/NoiseBasedVoronoi.zig index e256ecd9..f16f025c 100644 --- a/src/server/terrain/climategen/NoiseBasedVoronoi.zig +++ b/src/server/terrain/climategen/NoiseBasedVoronoi.zig @@ -263,10 +263,10 @@ const GenerationStructure = struct { } fn drawCircleOnTheMap(map: *ClimateMapFragment, biome: *const Biome, wx: i32, wz: i32, width: u31, height: u31, pos: Vec2f) void { - const relPos = (pos - vec.floatFromInt(f32, Vec2i{wx, wz}))/@as(Vec2f, @splat(terrain.SurfaceMap.MapFragment.biomeSize)); + const relPos = (pos - @as(Vec2f, @floatFromInt(Vec2i{wx, wz})))/@as(Vec2f, @splat(terrain.SurfaceMap.MapFragment.biomeSize)); const relRadius = biome.radius/terrain.SurfaceMap.MapFragment.biomeSize; const min = @floor(@max(Vec2f{0, 0}, relPos - @as(Vec2f, @splat(relRadius)))); - const max = @ceil(@min(vec.floatFromInt(f32, Vec2i{width, height})/@as(Vec2f, @splat(terrain.SurfaceMap.MapFragment.biomeSize)), relPos + @as(Vec2f, @splat(relRadius)))); + const max = @ceil(@min(@as(Vec2f, @floatFromInt(Vec2i{width, height}))/@as(Vec2f, @splat(terrain.SurfaceMap.MapFragment.biomeSize)), relPos + @as(Vec2f, @splat(relRadius)))); var x: f32 = min[0]; while(x < max[0]) : (x += 1) { var z: f32 = min[1]; diff --git a/src/server/terrain/structures/Boulder.zig b/src/server/terrain/structures/Boulder.zig index d7c3cc61..a9c3ea94 100644 --- a/src/server/terrain/structures/Boulder.zig +++ b/src/server/terrain/structures/Boulder.zig @@ -54,7 +54,7 @@ pub fn generate(self: *Boulder, x: i32, y: i32, z: i32, chunk: *main.chunk.Chunk if(!chunk.liesInChunk(px, py, pz)) continue; var potential: f32 = 0; for(&pointCloud) |point| { - const delta = vec.floatFromInt(f32, Vec3i{px, py, pz} - Vec3i{x, y, z}) - point; + const delta = @as(Vec3f, @floatFromInt(Vec3i{px, py, pz} - Vec3i{x, y, z})) - point; const distSqr = vec.dot(delta, delta); potential += 1/distSqr; } diff --git a/src/server/world.zig b/src/server/world.zig index ab1d3a66..f7bd3e9c 100644 --- a/src/server/world.zig +++ b/src/server/world.zig @@ -381,7 +381,7 @@ pub const ServerWorld = struct { const player = &user.player; if(playerData == .JsonNull) { // Generate a new player: - player.pos = vec.floatFromInt(f64, self.spawn); + player.pos = @floatFromInt(self.spawn); } else { player.loadFrom(playerData); } diff --git a/src/vec.zig b/src/vec.zig index c48dfba6..e834db0d 100644 --- a/src/vec.zig +++ b/src/vec.zig @@ -38,33 +38,6 @@ pub fn normalize(self: anytype) @TypeOf(self) { return self/@as(@TypeOf(self), @splat(length(self))); } -pub fn intFromFloat(comptime DestType: type, self: anytype) @Vector(@typeInfo(@TypeOf(self)).Vector.len, DestType) { // TODO: Remove once @floatToInt supports vectors. - const len = @typeInfo(@TypeOf(self)).Vector.len; - var result: @Vector(len, DestType) = undefined; - inline for(0..len) |i| { - result[i] = @intFromFloat(self[i]); - } - return result; -} - -pub fn floatFromInt(comptime DestType: type, self: anytype) @Vector(@typeInfo(@TypeOf(self)).Vector.len, DestType) { // TODO: Remove once @intToFloat supports vectors. - const len = @typeInfo(@TypeOf(self)).Vector.len; - var result: @Vector(len, DestType) = undefined; - inline for(0..len) |i| { - result[i] = @floatFromInt(self[i]); - } - return result; -} - -pub fn floatCast(comptime DestType: type, self: anytype) @Vector(@typeInfo(@TypeOf(self)).Vector.len, DestType) { // TODO: Remove once @floatCast supports vectors. - const len = @typeInfo(@TypeOf(self)).Vector.len; - var result: @Vector(len, DestType) = undefined; - inline for(0..len) |i| { - result[i] = @floatCast(self[i]); - } - return result; -} - 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."); return @TypeOf(self) { @@ -77,7 +50,7 @@ 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."); const sin = @sin(angle); - const cos = @cos(angle); // TODO: Consider using sqrt here. + const cos = @cos(angle); return @TypeOf(self){ self[0], self[1]*cos - self[2]*sin, @@ -88,7 +61,7 @@ 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."); const sin = @sin(angle); - const cos = @cos(angle); // TODO: Consider using sqrt here. + const cos = @cos(angle); return @TypeOf(self){ self[0]*cos + self[2]*sin, self[1], @@ -99,7 +72,7 @@ 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."); const sin = @sin(angle); - const cos = @cos(angle); // TODO: Consider using sqrt here. + const cos = @cos(angle); return @TypeOf(self){ self[0]*cos - self[1]*sin, self[0]*sin + self[1]*cos,