mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 03:06:55 -04:00
Don't use vector types in the GPU buffer.
I decided to pack the corner positions, everything else would have made it more ugly. fixes the most relevant part of #1634
This commit is contained in:
parent
9c33f8184d
commit
a8b36f3ca4
@ -28,7 +28,7 @@ layout(std430, binding = 3) buffer _faceData
|
|||||||
|
|
||||||
struct QuadInfo {
|
struct QuadInfo {
|
||||||
vec3 normal;
|
vec3 normal;
|
||||||
vec3 corners[4];
|
float corners[4][3];
|
||||||
vec2 cornerUV[4];
|
vec2 cornerUV[4];
|
||||||
uint textureSlot;
|
uint textureSlot;
|
||||||
int opaqueInLod;
|
int opaqueInLod;
|
||||||
@ -97,7 +97,7 @@ void main() {
|
|||||||
|
|
||||||
normal = quads[quadIndex].normal;
|
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 *= voxelSize;
|
||||||
position += vec3(chunks[chunkID].position.xyz - playerPositionInteger);
|
position += vec3(chunks[chunkID].position.xyz - playerPositionInteger);
|
||||||
position -= playerPositionFraction;
|
position -= playerPositionFraction;
|
||||||
|
@ -118,7 +118,7 @@ fn rotateQuad(originalCorners: [4]Vec2f, pattern: Pattern, min: f32, max: f32, s
|
|||||||
corners3d[3] + offset,
|
corners3d[3] + offset,
|
||||||
},
|
},
|
||||||
.cornerUV = originalCorners,
|
.cornerUV = originalCorners,
|
||||||
.normal = @floatFromInt(side.relPos()),
|
.normal = @as(Vec3f, @floatFromInt(side.relPos())),
|
||||||
.textureSlot = textureSlotOffset + @intFromEnum(pattern),
|
.textureSlot = textureSlotOffset + @intFromEnum(pattern),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ fn rotateQuad(pattern: Pattern, side: Neighbor) main.models.QuadInfo {
|
|||||||
corners3d[3] + offset,
|
corners3d[3] + offset,
|
||||||
},
|
},
|
||||||
.cornerUV = corners,
|
.cornerUV = corners,
|
||||||
.normal = @floatFromInt(side.relPos()),
|
.normal = @as(Vec3f, @floatFromInt(side.relPos())),
|
||||||
.textureSlot = @intFromEnum(pattern),
|
.textureSlot = @intFromEnum(pattern),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
32
src/game.zig
32
src/game.zig
@ -162,9 +162,9 @@ pub const collision = struct {
|
|||||||
for(model.neighborFacingQuads) |quads| {
|
for(model.neighborFacingQuads) |quads| {
|
||||||
for(quads) |quadIndex| {
|
for(quads) |quadIndex| {
|
||||||
const quad = quadIndex.quadInfo();
|
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)) {
|
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.corners[0], quad.corners[1]), @min(quad.corners[2], quad.corners[3])) + quad.normal + pos;
|
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.corners[0], quad.corners[1]), @max(quad.corners[2], quad.corners[3])) + quad.normal + 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));
|
const dist = @min(vec.dot(directionVector, min), vec.dot(directionVector, max));
|
||||||
if(dist < minDistance) {
|
if(dist < minDistance) {
|
||||||
resultBox = .{.min = min, .max = max};
|
resultBox = .{.min = min, .max = max};
|
||||||
@ -174,9 +174,9 @@ pub const collision = struct {
|
|||||||
resultBox.?.max = @min(resultBox.?.max, max);
|
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)) {
|
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.corners[0], quad.corners[1]), @min(quad.corners[2], quad.corners[3])) + quad.normal + pos;
|
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.corners[0], quad.corners[1]), @max(quad.corners[2], quad.corners[3])) + quad.normal + 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));
|
const dist = @min(vec.dot(directionVector, min), vec.dot(directionVector, max));
|
||||||
if(dist < minDistance) {
|
if(dist < minDistance) {
|
||||||
resultBox = .{.min = min, .max = max};
|
resultBox = .{.min = min, .max = max};
|
||||||
@ -191,9 +191,9 @@ pub const collision = struct {
|
|||||||
|
|
||||||
for(model.internalQuads) |quadIndex| {
|
for(model.internalQuads) |quadIndex| {
|
||||||
const quad = quadIndex.quadInfo();
|
const quad = quadIndex.quadInfo();
|
||||||
if(triangleAABB(.{quad.corners[0] + pos, quad.corners[2] + pos, quad.corners[1] + pos}, entityPosition, entityBoundingBoxExtent)) {
|
if(triangleAABB(.{quad.cornerVec(0) + pos, quad.cornerVec(2) + pos, quad.cornerVec(1) + pos}, entityPosition, entityBoundingBoxExtent)) {
|
||||||
const min = @min(@min(quad.corners[0], quad.corners[1]), @min(quad.corners[2], quad.corners[3])) + pos;
|
const min = @min(@min(quad.cornerVec(0), quad.cornerVec(1)), @min(quad.cornerVec(2), quad.cornerVec(3))) + pos;
|
||||||
const max = @max(@max(quad.corners[0], quad.corners[1]), @max(quad.corners[2], quad.corners[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));
|
const dist = @min(vec.dot(directionVector, min), vec.dot(directionVector, max));
|
||||||
if(dist < minDistance) {
|
if(dist < minDistance) {
|
||||||
resultBox = .{.min = min, .max = max};
|
resultBox = .{.min = min, .max = max};
|
||||||
@ -203,9 +203,9 @@ pub const collision = struct {
|
|||||||
resultBox.?.max = @min(resultBox.?.max, max);
|
resultBox.?.max = @min(resultBox.?.max, max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(triangleAABB(.{quad.corners[1] + pos, quad.corners[2] + pos, quad.corners[3] + pos}, entityPosition, entityBoundingBoxExtent)) {
|
if(triangleAABB(.{quad.cornerVec(1) + pos, quad.cornerVec(2) + pos, quad.cornerVec(3) + pos}, entityPosition, entityBoundingBoxExtent)) {
|
||||||
const min = @min(@min(quad.corners[0], quad.corners[1]), @min(quad.corners[2], quad.corners[3])) + pos;
|
const min = @min(@min(quad.cornerVec(0), quad.cornerVec(1)), @min(quad.cornerVec(2), quad.cornerVec(3))) + pos;
|
||||||
const max = @max(@max(quad.corners[0], quad.corners[1]), @max(quad.corners[2], quad.corners[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));
|
const dist = @min(vec.dot(directionVector, min), vec.dot(directionVector, max));
|
||||||
if(dist < minDistance) {
|
if(dist < minDistance) {
|
||||||
resultBox = .{.min = min, .max = max};
|
resultBox = .{.min = min, .max = max};
|
||||||
@ -371,14 +371,14 @@ pub const collision = struct {
|
|||||||
for(model.neighborFacingQuads) |quads| {
|
for(model.neighborFacingQuads) |quads| {
|
||||||
for(quads) |quadIndex| {
|
for(quads) |quadIndex| {
|
||||||
const quad = quadIndex.quadInfo();
|
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
|
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.corners[1] + quad.normal + position, quad.corners[2] + quad.normal + position, quad.corners[3] + quad.normal + position}, center, extent)) return true;
|
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| {
|
for(model.internalQuads) |quadIndex| {
|
||||||
const quad = quadIndex.quadInfo();
|
const quad = quadIndex.quadInfo();
|
||||||
if(triangleAABB(.{quad.corners[0] + position, quad.corners[2] + position, quad.corners[1] + position}, center, extent) or
|
if(triangleAABB(.{quad.cornerVec(0) + position, quad.cornerVec(2) + position, quad.cornerVec(1) + position}, center, extent) or
|
||||||
triangleAABB(.{quad.corners[1] + position, quad.corners[2] + position, quad.corners[3] + position}, center, extent)) return true;
|
triangleAABB(.{quad.cornerVec(1) + position, quad.cornerVec(2) + position, quad.cornerVec(3) + position}, center, extent)) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,21 @@ const NeverFailingAllocator = main.heap.NeverFailingAllocator;
|
|||||||
var quadSSBO: graphics.SSBO = undefined;
|
var quadSSBO: graphics.SSBO = undefined;
|
||||||
|
|
||||||
pub const QuadInfo = extern struct {
|
pub const QuadInfo = extern struct {
|
||||||
normal: Vec3f,
|
normal: [3]f32 align(16),
|
||||||
corners: [4]Vec3f,
|
corners: [4][3]f32,
|
||||||
cornerUV: [4]Vec2f,
|
cornerUV: [4][2]f32 align(8),
|
||||||
textureSlot: u32,
|
textureSlot: u32,
|
||||||
opaqueInLod: u32 = 0,
|
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 {
|
const ExtraQuadInfo = struct {
|
||||||
@ -33,8 +43,9 @@ const gridSize = 4096;
|
|||||||
|
|
||||||
fn snapToGrid(x: anytype) @TypeOf(x) {
|
fn snapToGrid(x: anytype) @TypeOf(x) {
|
||||||
const T = @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 Vec = @Vector(x.len, std.meta.Child(T));
|
||||||
return @as(T, @floatFromInt(int))/@as(T, @splat(gridSize));
|
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 {
|
const Triangle = struct {
|
||||||
@ -132,8 +143,8 @@ pub const Model = struct {
|
|||||||
self.isNeighborOccluded = @splat(false);
|
self.isNeighborOccluded = @splat(false);
|
||||||
for(adjustedQuads) |*quad| {
|
for(adjustedQuads) |*quad| {
|
||||||
for(quad.corners) |corner| {
|
for(quad.corners) |corner| {
|
||||||
self.min = @min(self.min, corner);
|
self.min = @min(self.min, @as(Vec3f, corner));
|
||||||
self.max = @max(self.max, corner);
|
self.max = @max(self.max, @as(Vec3f, corner));
|
||||||
}
|
}
|
||||||
if(getFaceNeighbor(quad)) |neighbor| {
|
if(getFaceNeighbor(quad)) |neighbor| {
|
||||||
amounts[neighbor.toInt()] += 1;
|
amounts[neighbor.toInt()] += 1;
|
||||||
@ -153,7 +164,7 @@ pub const Model = struct {
|
|||||||
var quad = _quad;
|
var quad = _quad;
|
||||||
if(getFaceNeighbor(&quad)) |neighbor| {
|
if(getFaceNeighbor(&quad)) |neighbor| {
|
||||||
for(&quad.corners) |*corner| {
|
for(&quad.corners) |*corner| {
|
||||||
corner.* -= quad.normal;
|
corner.* = @as(Vec3f, corner.*) - @as(Vec3f, quad.normal);
|
||||||
}
|
}
|
||||||
const quadIndex = addQuad(quad) catch continue;
|
const quadIndex = addQuad(quad) catch continue;
|
||||||
self.neighborFacingQuads[neighbor.toInt()][indices[neighbor.toInt()]] = quadIndex;
|
self.neighborFacingQuads[neighbor.toInt()][indices[neighbor.toInt()]] = quadIndex;
|
||||||
@ -202,8 +213,8 @@ pub const Model = struct {
|
|||||||
for(quadInfos) |*quad| {
|
for(quadInfos) |*quad| {
|
||||||
var minUv: Vec2f = @splat(std.math.inf(f32));
|
var minUv: Vec2f = @splat(std.math.inf(f32));
|
||||||
for(0..4) |i| {
|
for(0..4) |i| {
|
||||||
quad.cornerUV[i] *= @splat(4);
|
quad.cornerUV[i] = @as(Vec2f, quad.cornerUV[i])*@as(Vec2f, @splat(4));
|
||||||
minUv = @min(minUv, quad.cornerUV[i]);
|
minUv = @min(minUv, @as(Vec2f, quad.cornerUV[i]));
|
||||||
}
|
}
|
||||||
minUv = @floor(minUv);
|
minUv = @floor(minUv);
|
||||||
quad.textureSlot = @as(u32, @intFromFloat(minUv[1]))*4 + @as(u32, @intFromFloat(minUv[0]));
|
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| {
|
for(0..4) |i| {
|
||||||
quad.cornerUV[i] -= minUv;
|
quad.cornerUV[i] = @as(Vec2f, quad.cornerUV[i]) - minUv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Model.init(quadInfos);
|
return Model.init(quadInfos);
|
||||||
@ -382,7 +393,7 @@ pub const Model = struct {
|
|||||||
for(model.neighborFacingQuads[neighbor]) |quadIndex| {
|
for(model.neighborFacingQuads[neighbor]) |quadIndex| {
|
||||||
var quad = quadIndex.quadInfo().*;
|
var quad = quadIndex.quadInfo().*;
|
||||||
for(&quad.corners) |*corner| {
|
for(&quad.corners) |*corner| {
|
||||||
corner.* += quad.normal;
|
corner.* = @as(Vec3f, corner.*) + @as(Vec3f, quad.normal);
|
||||||
}
|
}
|
||||||
quadList.append(quad);
|
quadList.append(quad);
|
||||||
}
|
}
|
||||||
@ -448,7 +459,7 @@ fn addQuad(info_: QuadInfo) error{Degenerate}!QuadIndex {
|
|||||||
var cornerEqualities: u32 = 0;
|
var cornerEqualities: u32 = 0;
|
||||||
for(0..4) |i| {
|
for(0..4) |i| {
|
||||||
for(i + 1..4) |j| {
|
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.
|
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.
|
||||||
|
@ -517,7 +517,7 @@ pub const PrimitiveMesh = struct { // MARK: PrimitiveMesh
|
|||||||
if(extraQuadInfo.hasOnlyCornerVertices) { // Fast path for simple quads.
|
if(extraQuadInfo.hasOnlyCornerVertices) { // Fast path for simple quads.
|
||||||
var rawVals: [4][6]u5 = undefined;
|
var rawVals: [4][6]u5 = undefined;
|
||||||
for(0..4) |i| {
|
for(0..4) |i| {
|
||||||
const vertexPos = quadInfo.corners[i];
|
const vertexPos: Vec3f = quadInfo.corners[i];
|
||||||
const fullPos = blockPos +% @as(Vec3i, @intFromFloat(vertexPos));
|
const fullPos = blockPos +% @as(Vec3i, @intFromFloat(vertexPos));
|
||||||
const fullValues = if(extraQuadInfo.alignedNormalDirection) |dir|
|
const fullValues = if(extraQuadInfo.alignedNormalDirection) |dir|
|
||||||
getCornerLightAligned(parent, fullPos, dir)
|
getCornerLightAligned(parent, fullPos, dir)
|
||||||
@ -547,7 +547,7 @@ pub const PrimitiveMesh = struct { // MARK: PrimitiveMesh
|
|||||||
}
|
}
|
||||||
var rawVals: [4][6]u5 = undefined;
|
var rawVals: [4][6]u5 = undefined;
|
||||||
for(0..4) |i| {
|
for(0..4) |i| {
|
||||||
const vertexPos = quadInfo.corners[i];
|
const vertexPos: Vec3f = quadInfo.corners[i];
|
||||||
const lightPos = vertexPos + @as(Vec3f, @floatFromInt(blockPos));
|
const lightPos = vertexPos + @as(Vec3f, @floatFromInt(blockPos));
|
||||||
const interp = lightPos - @as(Vec3f, @floatFromInt(blockPos));
|
const interp = lightPos - @as(Vec3f, @floatFromInt(blockPos));
|
||||||
var val: [6]f32 = .{0, 0, 0, 0, 0, 0};
|
var val: [6]f32 = .{0, 0, 0, 0, 0, 0};
|
||||||
@ -652,7 +652,7 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh
|
|||||||
const dz = z + chunkDz;
|
const dz = z + chunkDz;
|
||||||
self.isBackFace = self.face.position.isBackFace;
|
self.isBackFace = self.face.position.isBackFace;
|
||||||
const quadIndex = self.face.blockAndQuad.quadIndex;
|
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.
|
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 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]));
|
const fullDy = dy - @as(i32, @intFromFloat(normalVector[1]));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user