refactor
This commit is contained in:
parent
4633aed567
commit
389e934900
1 changed files with 139 additions and 101 deletions
|
|
@ -5,6 +5,9 @@ const v3 = raylib_helper.v3;
|
|||
const A7r = std.mem.Allocator;
|
||||
const comptimePrint = std.fmt.comptimePrint;
|
||||
|
||||
const COORDINATE_FIELD_BYTES = 5; // 5 for 32x32x32 chunk size.
|
||||
const CHUNK_SIZE = 1 >> COORDINATE_FIELD_BYTES; // 32
|
||||
|
||||
const RawQuad = struct {
|
||||
tile: u32,
|
||||
top_left: raylib.Vector3,
|
||||
|
|
@ -14,6 +17,15 @@ const RawQuad = struct {
|
|||
normal: raylib.Vector3,
|
||||
width: f32,
|
||||
height: f32,
|
||||
|
||||
top_obscuring_pattern: u32,
|
||||
left_obscuring_pattern: u32,
|
||||
right_obscuring_pattern: u32,
|
||||
bottom_obscuring_pattern: u32,
|
||||
top_left_obscured: bool,
|
||||
top_right_obscured: bool,
|
||||
bottom_right_obscured: bool,
|
||||
bottom_left_obscured: bool,
|
||||
};
|
||||
|
||||
const Metadata1 = packed struct {
|
||||
|
|
@ -52,18 +64,22 @@ pub const Chunk = struct {
|
|||
}
|
||||
|
||||
pub fn getTile(self: Chunk, x: u5, y: u5, z: u5) u32 {
|
||||
// Fetch the tile at (x, y, z), but with potential side effects. If you imagine tiles to be a 3-dimensional array, this would be tiles[x][y][z].
|
||||
return self.tiles[@as(u15, x) << 10 | @as(u15, y) << 5 | @as(u15, z)];
|
||||
}
|
||||
|
||||
pub fn setTile(self: Chunk, x: u5, y: u5, z: u5, tile: u32) void {
|
||||
// Set the tile at (x, y, z). If you imagine tiles to be a 3-dimensional array, this would be tiles[x][y][z] = tile.
|
||||
self.tiles[@as(u15, x) << 10 | @as(u15, y) << 5 | @as(u15, z)] = tile;
|
||||
}
|
||||
|
||||
fn getTileRaw(self: Chunk, x: u5, y: u5, z: u5) u32 {
|
||||
// Fetch the tile at (x, y, z) without changin anything. If you imagine tiles to be a 3-dimensional array, this would be tiles[x][y][z].
|
||||
return self.tiles[@as(u15, x) << 10 | @as(u15, y) << 5 | @as(u15, z)];
|
||||
}
|
||||
|
||||
inline fn getTileRawShifted(self: Chunk, x: u5, y: u5, z: u5, comptime d: comptime_int) u32 {
|
||||
// This cyclicaly permutes the x, y, z coordinates at compile time. Useful when iterating over x, y, and z axis.
|
||||
if (d % 3 == 0) {
|
||||
return self.getTileRaw(x, y, z);
|
||||
} else if (d % 3 == 1) {
|
||||
|
|
@ -73,11 +89,91 @@ pub const Chunk = struct {
|
|||
}
|
||||
}
|
||||
|
||||
fn pack_raw_quad(y: usize, y2: usize, z: usize, z2: usize, sign: comptime_int, d: comptime_int, surface: u32, xf: f32) RawQuad {
|
||||
const ymin: f32 = @as(f32, @floatFromInt(y)) - 0.5;
|
||||
const ymax: f32 = @as(f32, @floatFromInt(y2)) + 0.5;
|
||||
const zmin: f32 = @as(f32, @floatFromInt(z)) - 0.5;
|
||||
const zmax: f32 = @as(f32, @floatFromInt(z2)) + 0.5;
|
||||
const yleft: f32 = if (sign == 1) ymin else ymax;
|
||||
const yright: f32 = if (sign == 1) ymax else ymin;
|
||||
const zleft: f32 = if (sign == 1) zmin else zmax;
|
||||
const zright: f32 = if (sign == 1) zmax else zmin;
|
||||
var raw_quad: RawQuad = undefined;
|
||||
switch (d) {
|
||||
0 => {
|
||||
raw_quad = .{
|
||||
.tile = surface,
|
||||
.top_left = v3.new(xf + 0.5 * sign, ymax, zright),
|
||||
.top_right = v3.new(xf + 0.5 * sign, ymax, zleft),
|
||||
.bottom_left = v3.new(xf + 0.5 * sign, ymin, zright),
|
||||
.bottom_right = v3.new(xf + 0.5 * sign, ymin, zleft),
|
||||
.normal = v3.new(sign, 0, 0),
|
||||
.width = zmax - zmin,
|
||||
.height = ymax - ymin,
|
||||
|
||||
.top_obscuring_pattern = 0,
|
||||
.left_obscuring_pattern = 0,
|
||||
.right_obscuring_pattern = 0,
|
||||
.bottom_obscuring_pattern = 0,
|
||||
.top_left_obscured = false,
|
||||
.top_right_obscured = false,
|
||||
.bottom_right_obscured = false,
|
||||
.bottom_left_obscured = false,
|
||||
};
|
||||
},
|
||||
1 => {
|
||||
raw_quad = .{
|
||||
.tile = surface,
|
||||
.bottom_left = v3.new(yleft, zmin, xf + 0.5 * sign),
|
||||
.top_left = v3.new(yleft, zmax, xf + 0.5 * sign),
|
||||
.bottom_right = v3.new(yright, zmin, xf + 0.5 * sign),
|
||||
.top_right = v3.new(yright, zmax, xf + 0.5 * sign),
|
||||
.normal = v3.new(0, 0, sign),
|
||||
.height = zmax - zmin,
|
||||
.width = ymax - ymin,
|
||||
|
||||
.top_obscuring_pattern = 0,
|
||||
.left_obscuring_pattern = 0,
|
||||
.right_obscuring_pattern = 0,
|
||||
.bottom_obscuring_pattern = 0,
|
||||
.top_left_obscured = false,
|
||||
.top_right_obscured = false,
|
||||
.bottom_right_obscured = false,
|
||||
.bottom_left_obscured = false,
|
||||
};
|
||||
},
|
||||
2 => {
|
||||
raw_quad = .{
|
||||
.tile = surface,
|
||||
.top_left = v3.new(zleft, xf + 0.5 * sign, ymin),
|
||||
.top_right = v3.new(zright, xf + 0.5 * sign, ymin),
|
||||
.bottom_left = v3.new(zleft, xf + 0.5 * sign, ymax),
|
||||
.bottom_right = v3.new(zright, xf + 0.5 * sign, ymax),
|
||||
.normal = v3.new(0, sign, 0),
|
||||
.width = zmax - zmin,
|
||||
.height = ymax - ymin,
|
||||
|
||||
.top_obscuring_pattern = 0xffffffff,
|
||||
.left_obscuring_pattern = 0xffffffff,
|
||||
.right_obscuring_pattern = 0xffffffff,
|
||||
.bottom_obscuring_pattern = 0xffffffff,
|
||||
.top_left_obscured = false,
|
||||
.top_right_obscured = false,
|
||||
.bottom_right_obscured = false,
|
||||
.bottom_left_obscured = false,
|
||||
};
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
return raw_quad;
|
||||
}
|
||||
|
||||
pub fn createMesh(chunk: Chunk, tile_rows: u32, tile_columns: u32) !raylib.Mesh {
|
||||
var raw_quads = try std.ArrayList(RawQuad).initCapacity(chunk.a7r, 4096);
|
||||
defer raw_quads.deinit();
|
||||
|
||||
inline for (0..3) |d| {
|
||||
// Begin scanning the chunk for block surfaces to make raw quads.
|
||||
inline for (0..3) |d| { // For each of the 3 dimensions,
|
||||
for (0..32) |raw_x| {
|
||||
const x: u5 = @intCast(raw_x);
|
||||
var positive_tile_surfaces: [32][32]u32 = .{.{0} ** 32} ** 32;
|
||||
|
|
@ -105,57 +201,11 @@ pub const Chunk = struct {
|
|||
for (y..y2) |ytmp| if (tile_surfaces[ytmp][z2] != surface) break :zloop;
|
||||
for (y..y2) |ytmp| tile_surfaces[ytmp][z2] = 0;
|
||||
}
|
||||
// todo: scan tiles around quad surface for ambient occlusion
|
||||
y2 -= 1;
|
||||
z2 -= 1;
|
||||
tile_surfaces[y][z] = 0;
|
||||
const ymin: f32 = @as(f32, @floatFromInt(y)) - 0.5;
|
||||
const ymax: f32 = @as(f32, @floatFromInt(y2)) + 0.5;
|
||||
const zmin: f32 = @as(f32, @floatFromInt(z)) - 0.5;
|
||||
const zmax: f32 = @as(f32, @floatFromInt(z2)) + 0.5;
|
||||
const yleft: f32 = if (sign == 1) ymin else ymax;
|
||||
const yright: f32 = if (sign == 1) ymax else ymin;
|
||||
const zleft: f32 = if (sign == 1) zmin else zmax;
|
||||
const zright: f32 = if (sign == 1) zmax else zmin;
|
||||
var raw_quad: RawQuad = undefined;
|
||||
switch (d) {
|
||||
0 => {
|
||||
raw_quad = .{
|
||||
.tile = surface,
|
||||
.top_left = v3.new(xf + 0.5 * sign, ymax, zright),
|
||||
.top_right = v3.new(xf + 0.5 * sign, ymax, zleft),
|
||||
.bottom_left = v3.new(xf + 0.5 * sign, ymin, zright),
|
||||
.bottom_right = v3.new(xf + 0.5 * sign, ymin, zleft),
|
||||
.normal = v3.new(sign, 0, 0),
|
||||
.width = zmax - zmin,
|
||||
.height = ymax - ymin,
|
||||
};
|
||||
},
|
||||
1 => {
|
||||
raw_quad = .{
|
||||
.tile = surface,
|
||||
.bottom_left = v3.new(yleft, zmin, xf + 0.5 * sign),
|
||||
.top_left = v3.new(yleft, zmax, xf + 0.5 * sign),
|
||||
.bottom_right = v3.new(yright, zmin, xf + 0.5 * sign),
|
||||
.top_right = v3.new(yright, zmax, xf + 0.5 * sign),
|
||||
.normal = v3.new(0, 0, sign),
|
||||
.height = zmax - zmin,
|
||||
.width = ymax - ymin,
|
||||
};
|
||||
},
|
||||
2 => {
|
||||
raw_quad = .{
|
||||
.tile = surface,
|
||||
.top_left = v3.new(zleft, xf + 0.5 * sign, ymin),
|
||||
.top_right = v3.new(zright, xf + 0.5 * sign, ymin),
|
||||
.bottom_left = v3.new(zleft, xf + 0.5 * sign, ymax),
|
||||
.bottom_right = v3.new(zright, xf + 0.5 * sign, ymax),
|
||||
.normal = v3.new(0, sign, 0),
|
||||
.width = zmax - zmin,
|
||||
.height = ymax - ymin,
|
||||
};
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
const raw_quad = pack_raw_quad(y, y2, z, z2, sign, d, surface, xf);
|
||||
try raw_quads.append(raw_quad);
|
||||
};
|
||||
}
|
||||
|
|
@ -186,62 +236,49 @@ pub const Chunk = struct {
|
|||
const right_uv = @as(f32, @floatFromInt(tile % tile_columns + 1)) / @as(f32, @floatFromInt(tile_columns));
|
||||
const top_uv = @as(f32, @floatFromInt(tile / tile_columns)) / @as(f32, @floatFromInt(tile_rows));
|
||||
const bottom_uv = @as(f32, @floatFromInt(tile / tile_columns + 1)) / @as(f32, @floatFromInt(tile_rows));
|
||||
const VERTICES_BLOCK_SIZE = 2 * 3 * 3;
|
||||
const TEXCOORDS_BLOCK_SIZE = 2 * 2 * 3;
|
||||
|
||||
vertices[18 * i + 0] = raw_quad.top_left.x;
|
||||
vertices[18 * i + 1] = raw_quad.top_left.y;
|
||||
vertices[18 * i + 2] = raw_quad.top_left.z;
|
||||
texcoords[12 * i + 0] = left_uv;
|
||||
texcoords[12 * i + 1] = top_uv;
|
||||
texcoords2[12 * i + 0] = 0.0;
|
||||
texcoords2[12 * i + 1] = 0.0;
|
||||
// Unwrap raw quads vertex coordinates and UV coordinates into OpenGL buffers.
|
||||
const vertex_corners = .{ raw_quad.top_left, raw_quad.bottom_left, raw_quad.top_right, raw_quad.bottom_right, raw_quad.top_right, raw_quad.bottom_left };
|
||||
const texcoords_x = .{ left_uv, left_uv, right_uv, right_uv, right_uv, left_uv };
|
||||
const texcoords_y = .{ top_uv, bottom_uv } ** 3;
|
||||
const texcoords2_x = .{ 0.0, 0.0, raw_quad.width, raw_quad.width, raw_quad.width, 0.0 };
|
||||
const texcoords2_y = .{ 0.0, raw_quad.height } ** 3;
|
||||
|
||||
vertices[18 * i + 3] = raw_quad.bottom_left.x;
|
||||
vertices[18 * i + 4] = raw_quad.bottom_left.y;
|
||||
vertices[18 * i + 5] = raw_quad.bottom_left.z;
|
||||
texcoords[12 * i + 2] = left_uv;
|
||||
texcoords[12 * i + 3] = bottom_uv;
|
||||
texcoords2[12 * i + 2] = 0.0;
|
||||
texcoords2[12 * i + 3] = raw_quad.height;
|
||||
inline for (0..6) |corner_id| {
|
||||
vertices[VERTICES_BLOCK_SIZE * i + corner_id * 3 + 0] = vertex_corners[corner_id].x;
|
||||
vertices[VERTICES_BLOCK_SIZE * i + corner_id * 3 + 1] = vertex_corners[corner_id].y;
|
||||
vertices[VERTICES_BLOCK_SIZE * i + corner_id * 3 + 2] = vertex_corners[corner_id].z;
|
||||
texcoords[TEXCOORDS_BLOCK_SIZE * i + corner_id * 2 + 0] = texcoords_x[corner_id];
|
||||
texcoords[TEXCOORDS_BLOCK_SIZE * i + corner_id * 2 + 1] = texcoords_y[corner_id];
|
||||
texcoords2[TEXCOORDS_BLOCK_SIZE * i + corner_id * 2 + 0] = texcoords2_x[corner_id];
|
||||
texcoords2[TEXCOORDS_BLOCK_SIZE * i + corner_id * 2 + 1] = texcoords2_y[corner_id];
|
||||
}
|
||||
|
||||
vertices[18 * i + 6] = raw_quad.top_right.x;
|
||||
vertices[18 * i + 7] = raw_quad.top_right.y;
|
||||
vertices[18 * i + 8] = raw_quad.top_right.z;
|
||||
texcoords[12 * i + 4] = right_uv;
|
||||
texcoords[12 * i + 5] = top_uv;
|
||||
texcoords2[12 * i + 4] = raw_quad.width;
|
||||
texcoords2[12 * i + 5] = 0.0;
|
||||
|
||||
vertices[18 * i + 9] = raw_quad.bottom_right.x;
|
||||
vertices[18 * i + 10] = raw_quad.bottom_right.y;
|
||||
vertices[18 * i + 11] = raw_quad.bottom_right.z;
|
||||
texcoords[12 * i + 6] = right_uv;
|
||||
texcoords[12 * i + 7] = bottom_uv;
|
||||
texcoords2[12 * i + 6] = raw_quad.width;
|
||||
texcoords2[12 * i + 7] = raw_quad.height;
|
||||
|
||||
vertices[18 * i + 12] = raw_quad.top_right.x;
|
||||
vertices[18 * i + 13] = raw_quad.top_right.y;
|
||||
vertices[18 * i + 14] = raw_quad.top_right.z;
|
||||
texcoords[12 * i + 8] = right_uv;
|
||||
texcoords[12 * i + 9] = top_uv;
|
||||
texcoords2[12 * i + 8] = raw_quad.width;
|
||||
texcoords2[12 * i + 9] = 0.0;
|
||||
|
||||
vertices[18 * i + 15] = raw_quad.bottom_left.x;
|
||||
vertices[18 * i + 16] = raw_quad.bottom_left.y;
|
||||
vertices[18 * i + 17] = raw_quad.bottom_left.z;
|
||||
texcoords[12 * i + 10] = left_uv;
|
||||
texcoords[12 * i + 11] = bottom_uv;
|
||||
texcoords2[12 * i + 10] = 0.0;
|
||||
texcoords2[12 * i + 11] = raw_quad.height;
|
||||
|
||||
for (0..6) |j| {
|
||||
// Store metadata into OpenGL buffers.
|
||||
for (0..3) |j| {
|
||||
const metadata1 = Metadata1{
|
||||
.ambient_occlusion_1 = 0xffffffff,
|
||||
.ambient_occlusion_2 = 0xffffffff,
|
||||
.ambient_occlusion_corner1 = true,
|
||||
.ambient_occlusion_corner2 = true,
|
||||
.ambient_occlusion_corner3 = true,
|
||||
.ambient_occlusion_1 = raw_quad.left_obscuring_pattern,
|
||||
.ambient_occlusion_2 = raw_quad.right_obscuring_pattern,
|
||||
.ambient_occlusion_corner1 = raw_quad.top_left_obscured,
|
||||
.ambient_occlusion_corner2 = raw_quad.bottom_left_obscured,
|
||||
.ambient_occlusion_corner3 = raw_quad.top_right_obscured,
|
||||
.quad_height = @intFromFloat(raw_quad.height),
|
||||
.quad_width = @intFromFloat(raw_quad.width),
|
||||
};
|
||||
const metadata1_baked: [4]f32 = @bitCast(metadata1);
|
||||
for (0..4) |k| {
|
||||
metadata1_packed[24 * i + 4 * j + k] = @bitCast(@as(f32, metadata1_baked[k]));
|
||||
}
|
||||
}
|
||||
for (3..6) |j| {
|
||||
const metadata1 = Metadata1{
|
||||
.ambient_occlusion_1 = raw_quad.right_obscuring_pattern,
|
||||
.ambient_occlusion_2 = raw_quad.bottom_obscuring_pattern,
|
||||
.ambient_occlusion_corner1 = raw_quad.bottom_right_obscured,
|
||||
.ambient_occlusion_corner2 = raw_quad.top_right_obscured,
|
||||
.ambient_occlusion_corner3 = raw_quad.bottom_left_obscured,
|
||||
.quad_height = @intFromFloat(raw_quad.height),
|
||||
.quad_width = @intFromFloat(raw_quad.width),
|
||||
};
|
||||
|
|
@ -252,6 +289,7 @@ pub const Chunk = struct {
|
|||
}
|
||||
}
|
||||
|
||||
// Create mesh.
|
||||
var mesh = raylib.Mesh{
|
||||
.triangleCount = triangle_count,
|
||||
.vertexCount = triangle_count * 3,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue