diff --git a/assets/cubyz/shaders/chunks/chunk_vertex.vert b/assets/cubyz/shaders/chunks/chunk_vertex.vert index a11246e6..c706e9ca 100644 --- a/assets/cubyz/shaders/chunks/chunk_vertex.vert +++ b/assets/cubyz/shaders/chunks/chunk_vertex.vert @@ -28,7 +28,7 @@ layout(std430, binding = 3) buffer _faceData struct QuadInfo { vec3 normal; - vec3 corners[4]; + float corners[4][3]; vec2 cornerUV[4]; uint textureSlot; int opaqueInLod; @@ -97,7 +97,7 @@ void main() { normal = quads[quadIndex].normal; - position += quads[quadIndex].corners[vertexID]; + position += vec3(quads[quadIndex].corners[vertexID][0], quads[quadIndex].corners[vertexID][1], quads[quadIndex].corners[vertexID][2]); position *= voxelSize; position += vec3(chunks[chunkID].position.xyz - playerPositionInteger); position -= playerPositionFraction; diff --git a/mods/cubyz/rotation/branch.zig b/mods/cubyz/rotation/branch.zig index d2b199d9..653684f9 100644 --- a/mods/cubyz/rotation/branch.zig +++ b/mods/cubyz/rotation/branch.zig @@ -118,7 +118,7 @@ fn rotateQuad(originalCorners: [4]Vec2f, pattern: Pattern, min: f32, max: f32, s corners3d[3] + offset, }, .cornerUV = originalCorners, - .normal = @floatFromInt(side.relPos()), + .normal = @as(Vec3f, @floatFromInt(side.relPos())), .textureSlot = textureSlotOffset + @intFromEnum(pattern), }; diff --git a/mods/cubyz/rotation/log.zig b/mods/cubyz/rotation/log.zig index c56ce5fa..5e2c7d17 100644 --- a/mods/cubyz/rotation/log.zig +++ b/mods/cubyz/rotation/log.zig @@ -118,7 +118,7 @@ fn rotateQuad(pattern: Pattern, side: Neighbor) main.models.QuadInfo { corners3d[3] + offset, }, .cornerUV = corners, - .normal = @floatFromInt(side.relPos()), + .normal = @as(Vec3f, @floatFromInt(side.relPos())), .textureSlot = @intFromEnum(pattern), }; diff --git a/src/game.zig b/src/game.zig index 0b202363..4416635a 100644 --- a/src/game.zig +++ b/src/game.zig @@ -162,9 +162,9 @@ pub const collision = struct { for(model.neighborFacingQuads) |quads| { for(quads) |quadIndex| { const quad = quadIndex.quadInfo(); - if(triangleAABB(.{quad.corners[0] + quad.normal + pos, quad.corners[2] + quad.normal + pos, quad.corners[1] + quad.normal + pos}, entityPosition, entityBoundingBoxExtent)) { - const min = @min(@min(quad.corners[0], quad.corners[1]), @min(quad.corners[2], quad.corners[3])) + quad.normal + pos; - const max = @max(@max(quad.corners[0], quad.corners[1]), @max(quad.corners[2], quad.corners[3])) + quad.normal + pos; + if(triangleAABB(.{quad.cornerVec(0) + quad.normalVec() + pos, quad.cornerVec(2) + quad.normalVec() + pos, quad.cornerVec(1) + quad.normalVec() + pos}, entityPosition, entityBoundingBoxExtent)) { + const min = @min(@min(quad.cornerVec(0), quad.cornerVec(1)), @min(quad.cornerVec(2), quad.cornerVec(3))) + quad.normalVec() + pos; + const max = @max(@max(quad.cornerVec(0), quad.cornerVec(1)), @max(quad.cornerVec(2), quad.cornerVec(3))) + quad.normalVec() + pos; const dist = @min(vec.dot(directionVector, min), vec.dot(directionVector, max)); if(dist < minDistance) { resultBox = .{.min = min, .max = max}; @@ -174,9 +174,9 @@ pub const collision = struct { resultBox.?.max = @min(resultBox.?.max, max); } } - if(triangleAABB(.{quad.corners[1] + quad.normal + pos, quad.corners[2] + quad.normal + pos, quad.corners[3] + quad.normal + pos}, entityPosition, entityBoundingBoxExtent)) { - const min = @min(@min(quad.corners[0], quad.corners[1]), @min(quad.corners[2], quad.corners[3])) + quad.normal + pos; - const max = @max(@max(quad.corners[0], quad.corners[1]), @max(quad.corners[2], quad.corners[3])) + quad.normal + pos; + if(triangleAABB(.{quad.cornerVec(1) + quad.normalVec() + pos, quad.cornerVec(2) + quad.normalVec() + pos, quad.cornerVec(3) + quad.normalVec() + pos}, entityPosition, entityBoundingBoxExtent)) { + const min = @min(@min(quad.cornerVec(0), quad.cornerVec(1)), @min(quad.cornerVec(2), quad.cornerVec(3))) + quad.normalVec() + pos; + const max = @max(@max(quad.cornerVec(0), quad.cornerVec(1)), @max(quad.cornerVec(2), quad.cornerVec(3))) + quad.normalVec() + pos; const dist = @min(vec.dot(directionVector, min), vec.dot(directionVector, max)); if(dist < minDistance) { resultBox = .{.min = min, .max = max}; @@ -191,9 +191,9 @@ pub const collision = struct { for(model.internalQuads) |quadIndex| { const quad = quadIndex.quadInfo(); - if(triangleAABB(.{quad.corners[0] + pos, quad.corners[2] + pos, quad.corners[1] + pos}, entityPosition, entityBoundingBoxExtent)) { - const min = @min(@min(quad.corners[0], quad.corners[1]), @min(quad.corners[2], quad.corners[3])) + pos; - const max = @max(@max(quad.corners[0], quad.corners[1]), @max(quad.corners[2], quad.corners[3])) + pos; + if(triangleAABB(.{quad.cornerVec(0) + pos, quad.cornerVec(2) + pos, quad.cornerVec(1) + pos}, entityPosition, entityBoundingBoxExtent)) { + const min = @min(@min(quad.cornerVec(0), quad.cornerVec(1)), @min(quad.cornerVec(2), quad.cornerVec(3))) + pos; + const max = @max(@max(quad.cornerVec(0), quad.cornerVec(1)), @max(quad.cornerVec(2), quad.cornerVec(3))) + pos; const dist = @min(vec.dot(directionVector, min), vec.dot(directionVector, max)); if(dist < minDistance) { resultBox = .{.min = min, .max = max}; @@ -203,9 +203,9 @@ pub const collision = struct { resultBox.?.max = @min(resultBox.?.max, max); } } - if(triangleAABB(.{quad.corners[1] + pos, quad.corners[2] + pos, quad.corners[3] + pos}, entityPosition, entityBoundingBoxExtent)) { - const min = @min(@min(quad.corners[0], quad.corners[1]), @min(quad.corners[2], quad.corners[3])) + pos; - const max = @max(@max(quad.corners[0], quad.corners[1]), @max(quad.corners[2], quad.corners[3])) + pos; + if(triangleAABB(.{quad.cornerVec(1) + pos, quad.cornerVec(2) + pos, quad.cornerVec(3) + pos}, entityPosition, entityBoundingBoxExtent)) { + const min = @min(@min(quad.cornerVec(0), quad.cornerVec(1)), @min(quad.cornerVec(2), quad.cornerVec(3))) + pos; + const max = @max(@max(quad.cornerVec(0), quad.cornerVec(1)), @max(quad.cornerVec(2), quad.cornerVec(3))) + pos; const dist = @min(vec.dot(directionVector, min), vec.dot(directionVector, max)); if(dist < minDistance) { resultBox = .{.min = min, .max = max}; @@ -371,14 +371,14 @@ pub const collision = struct { for(model.neighborFacingQuads) |quads| { for(quads) |quadIndex| { const quad = quadIndex.quadInfo(); - if(triangleAABB(.{quad.corners[0] + quad.normal + position, quad.corners[2] + quad.normal + position, quad.corners[1] + quad.normal + position}, center, extent) or - triangleAABB(.{quad.corners[1] + quad.normal + position, quad.corners[2] + quad.normal + position, quad.corners[3] + quad.normal + position}, center, extent)) return true; + if(triangleAABB(.{quad.cornerVec(0) + quad.normalVec() + position, quad.cornerVec(2) + quad.normalVec() + position, quad.cornerVec(1) + quad.normalVec() + position}, center, extent) or + triangleAABB(.{quad.cornerVec(1) + quad.normalVec() + position, quad.cornerVec(2) + quad.normalVec() + position, quad.cornerVec(3) + quad.normalVec() + position}, center, extent)) return true; } } for(model.internalQuads) |quadIndex| { const quad = quadIndex.quadInfo(); - if(triangleAABB(.{quad.corners[0] + position, quad.corners[2] + position, quad.corners[1] + position}, center, extent) or - triangleAABB(.{quad.corners[1] + position, quad.corners[2] + position, quad.corners[3] + position}, center, extent)) return true; + if(triangleAABB(.{quad.cornerVec(0) + position, quad.cornerVec(2) + position, quad.cornerVec(1) + position}, center, extent) or + triangleAABB(.{quad.cornerVec(1) + position, quad.cornerVec(2) + position, quad.cornerVec(3) + position}, center, extent)) return true; } return false; } diff --git a/src/models.zig b/src/models.zig index 11aa5656..16168597 100644 --- a/src/models.zig +++ b/src/models.zig @@ -15,11 +15,21 @@ const NeverFailingAllocator = main.heap.NeverFailingAllocator; var quadSSBO: graphics.SSBO = undefined; pub const QuadInfo = extern struct { - normal: Vec3f, - corners: [4]Vec3f, - cornerUV: [4]Vec2f, + normal: [3]f32 align(16), + corners: [4][3]f32, + cornerUV: [4][2]f32 align(8), textureSlot: u32, opaqueInLod: u32 = 0, + + pub fn normalVec(self: QuadInfo) Vec3f { + return self.normal; + } + pub fn cornerVec(self: QuadInfo, i: usize) Vec3f { + return self.corners[i]; + } + pub fn cornerUvVec(self: QuadInfo, i: usize) Vec2f { + return self.cornerUV[i]; + } }; const ExtraQuadInfo = struct { @@ -33,8 +43,9 @@ 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))))); - return @as(T, @floatFromInt(int))/@as(T, @splat(gridSize)); + const Vec = @Vector(x.len, std.meta.Child(T)); + const int = @as(@Vector(x.len, i32), @intFromFloat(std.math.round(@as(Vec, x)*@as(Vec, @splat(gridSize))))); + return @as(Vec, @floatFromInt(int))/@as(Vec, @splat(gridSize)); } const Triangle = struct { @@ -132,8 +143,8 @@ pub const Model = struct { self.isNeighborOccluded = @splat(false); for(adjustedQuads) |*quad| { for(quad.corners) |corner| { - self.min = @min(self.min, corner); - self.max = @max(self.max, corner); + self.min = @min(self.min, @as(Vec3f, corner)); + self.max = @max(self.max, @as(Vec3f, corner)); } if(getFaceNeighbor(quad)) |neighbor| { amounts[neighbor.toInt()] += 1; @@ -153,7 +164,7 @@ pub const Model = struct { var quad = _quad; if(getFaceNeighbor(&quad)) |neighbor| { for(&quad.corners) |*corner| { - corner.* -= quad.normal; + corner.* = @as(Vec3f, corner.*) - @as(Vec3f, quad.normal); } const quadIndex = addQuad(quad) catch continue; self.neighborFacingQuads[neighbor.toInt()][indices[neighbor.toInt()]] = quadIndex; @@ -202,8 +213,8 @@ pub const Model = struct { for(quadInfos) |*quad| { var minUv: Vec2f = @splat(std.math.inf(f32)); for(0..4) |i| { - quad.cornerUV[i] *= @splat(4); - minUv = @min(minUv, quad.cornerUV[i]); + quad.cornerUV[i] = @as(Vec2f, quad.cornerUV[i])*@as(Vec2f, @splat(4)); + minUv = @min(minUv, @as(Vec2f, quad.cornerUV[i])); } minUv = @floor(minUv); quad.textureSlot = @as(u32, @intFromFloat(minUv[1]))*4 + @as(u32, @intFromFloat(minUv[0])); @@ -213,7 +224,7 @@ pub const Model = struct { } for(0..4) |i| { - quad.cornerUV[i] -= minUv; + quad.cornerUV[i] = @as(Vec2f, quad.cornerUV[i]) - minUv; } } return Model.init(quadInfos); @@ -382,7 +393,7 @@ pub const Model = struct { for(model.neighborFacingQuads[neighbor]) |quadIndex| { var quad = quadIndex.quadInfo().*; for(&quad.corners) |*corner| { - corner.* += quad.normal; + corner.* = @as(Vec3f, corner.*) + @as(Vec3f, quad.normal); } quadList.append(quad); } @@ -448,7 +459,7 @@ fn addQuad(info_: QuadInfo) error{Degenerate}!QuadIndex { var cornerEqualities: u32 = 0; for(0..4) |i| { for(i + 1..4) |j| { - if(@reduce(.And, info.corners[i] == info.corners[j])) cornerEqualities += 1; + if(@reduce(.And, @as(Vec3f, info.corners[i]) == @as(Vec3f, info.corners[j]))) cornerEqualities += 1; } } if(cornerEqualities >= 2) return error.Degenerate; // One corner equality is fine, since then the quad degenerates to a triangle, which has a non-zero area. diff --git a/src/renderer/chunk_meshing.zig b/src/renderer/chunk_meshing.zig index 1c474f78..1d0b7741 100644 --- a/src/renderer/chunk_meshing.zig +++ b/src/renderer/chunk_meshing.zig @@ -517,7 +517,7 @@ pub const PrimitiveMesh = struct { // MARK: PrimitiveMesh if(extraQuadInfo.hasOnlyCornerVertices) { // Fast path for simple quads. var rawVals: [4][6]u5 = undefined; for(0..4) |i| { - const vertexPos = quadInfo.corners[i]; + const vertexPos: Vec3f = quadInfo.corners[i]; const fullPos = blockPos +% @as(Vec3i, @intFromFloat(vertexPos)); const fullValues = if(extraQuadInfo.alignedNormalDirection) |dir| getCornerLightAligned(parent, fullPos, dir) @@ -547,7 +547,7 @@ pub const PrimitiveMesh = struct { // MARK: PrimitiveMesh } var rawVals: [4][6]u5 = undefined; for(0..4) |i| { - const vertexPos = quadInfo.corners[i]; + const vertexPos: Vec3f = quadInfo.corners[i]; const lightPos = vertexPos + @as(Vec3f, @floatFromInt(blockPos)); const interp = lightPos - @as(Vec3f, @floatFromInt(blockPos)); var val: [6]f32 = .{0, 0, 0, 0, 0, 0}; @@ -652,7 +652,7 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh const dz = z + chunkDz; self.isBackFace = self.face.position.isBackFace; const quadIndex = self.face.blockAndQuad.quadIndex; - const normalVector = quadIndex.quadInfo().normal; + const normalVector: Vec3f = quadIndex.quadInfo().normal; self.shouldBeCulled = vec.dot(normalVector, @floatFromInt(Vec3i{dx, dy, dz})) > 0; // TODO: Adjust for arbitrary voxel models. const fullDx = dx - @as(i32, @intFromFloat(normalVector[0])); // TODO: This calculation should only be done for border faces. const fullDy = dy - @as(i32, @intFromFloat(normalVector[1]));