commit 04d09de0b45d9d57e623811aa525fd7ad9f0aca2
parent e8c54fdd890cb1cd5da91b2de598de228d03a766
Author: Christian Ermann <christianermann@gmail.com>
Date: Sun, 8 Dec 2024 17:33:28 -0800
Add cube
Diffstat:
A | src/cube.zig | | | 139 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | src/main.zig | | | 10 | ++++++++++ |
2 files changed, 149 insertions(+), 0 deletions(-)
diff --git a/src/cube.zig b/src/cube.zig
@@ -0,0 +1,139 @@
+const std = @import("std");
+
+const Mesh = @import("mesh.zig");
+
+const f32x3 = @Vector(3, f32);
+const f32x4 = @Vector(4, f32);
+
+pub fn generateCube(n_subdivisions: u32, allocator: std.mem.Allocator) !Mesh {
+ var positions = std.ArrayList(f32x4).init(allocator);
+ var normals = std.ArrayList(f32x3).init(allocator);
+ var tex_coords = std.ArrayList(f32x3).init(allocator);
+ defer positions.deinit();
+ defer normals.deinit();
+ defer tex_coords.deinit();
+
+ try generateFace(&positions, &normals, &tex_coords, n_subdivisions, .{
+ .u_axis = 0,
+ .v_axis = 1,
+ .w_axis = 2,
+ .u_dir = 1,
+ .v_dir = 1,
+ .w_dir = 1,
+ });
+ try generateFace(&positions, &normals, &tex_coords, n_subdivisions, .{
+ .u_axis = 0,
+ .v_axis = 1,
+ .w_axis = 2,
+ .u_dir = -1,
+ .v_dir = 1,
+ .w_dir = -1,
+ });
+ try generateFace(&positions, &normals, &tex_coords, n_subdivisions, .{
+ .u_axis = 2,
+ .v_axis = 1,
+ .w_axis = 0,
+ .u_dir = -1,
+ .v_dir = 1,
+ .w_dir = 1,
+ });
+ try generateFace(&positions, &normals, &tex_coords, n_subdivisions, .{
+ .u_axis = 2,
+ .v_axis = 1,
+ .w_axis = 0,
+ .u_dir = 1,
+ .v_dir = 1,
+ .w_dir = -1,
+ });
+ try generateFace(&positions, &normals, &tex_coords, n_subdivisions, .{
+ .u_axis = 0,
+ .v_axis = 2,
+ .w_axis = 1,
+ .u_dir = 1,
+ .v_dir = 1,
+ .w_dir = -1,
+ });
+ try generateFace(&positions, &normals, &tex_coords, n_subdivisions, .{
+ .u_axis = 0,
+ .v_axis = 2,
+ .w_axis = 1,
+ .u_dir = 1,
+ .v_dir = -1,
+ .w_dir = 1,
+ });
+
+ var indices = std.ArrayList(u32).init(allocator);
+ defer indices.deinit();
+ var offset: u32 = 0;
+ for (0..6) |_| {
+ offset += try generateFaceIndices(&indices, n_subdivisions, offset);
+ }
+
+ const n_vertices: u32 = @intCast(positions.items.len);
+ var mesh = Mesh{
+ .positions = try positions.toOwnedSlice(),
+ .normals = try normals.toOwnedSlice(),
+ .tex_coords = try tex_coords.toOwnedSlice(),
+ .indices = try indices.toOwnedSlice(),
+ .tangents = try allocator.alloc(f32x3, n_vertices),
+ .bitangents = try allocator.alloc(f32x3, n_vertices),
+ };
+
+ try mesh.tangentsAndBitangents(allocator);
+ return mesh;
+}
+
+const FaceOptions = struct {
+ u_axis: u32,
+ v_axis: u32,
+ w_axis: u32,
+ u_dir: f32,
+ v_dir: f32,
+ w_dir: f32,
+};
+
+fn generateFace(
+ positions: *std.ArrayList(f32x4),
+ normals: *std.ArrayList(f32x3),
+ tex_coords: *std.ArrayList(f32x3),
+ n_subdivisions: u32,
+ face_options: FaceOptions,
+) !void {
+ for (0..n_subdivisions + 2) |i| {
+ const v = @as(f32, @floatFromInt(i)) / @as(f32, @floatFromInt(n_subdivisions + 1));
+ for (0..n_subdivisions + 2) |j| {
+ const u = @as(f32, @floatFromInt(j)) / @as(f32, @floatFromInt(n_subdivisions + 1));
+ var position = f32x4{ 0, 0, 0, 1 };
+ position[face_options.u_axis] = (u - 0.5) * face_options.u_dir;
+ position[face_options.v_axis] = (v - 0.5) * face_options.v_dir;
+ position[face_options.w_axis] = 0.5 * face_options.w_dir;
+ var normal = f32x3{ 0, 0, 0 };
+ normal[face_options.w_axis] = face_options.w_dir;
+ const tex_coord = f32x3{ u, v, 0.0 };
+
+ try positions.append(position);
+ try normals.append(normal);
+ try tex_coords.append(tex_coord);
+ }
+ }
+}
+
+fn generateFaceIndices(
+ indices: *std.ArrayList(u32),
+ n_subdivisions: u32,
+ offset: u32,
+) !u32 {
+ for (0..n_subdivisions + 1) |i| {
+ for (0..n_subdivisions + 1) |j| {
+ const a: u32 = @intCast(i * (n_subdivisions + 2) + j + offset);
+ const b: u32 = @intCast((i + 1) * (n_subdivisions + 2) + j + offset);
+ try indices.append(a);
+ try indices.append(a + 1);
+ try indices.append(b + 1);
+ try indices.append(a);
+ try indices.append(b + 1);
+ try indices.append(b);
+ }
+ }
+ return (n_subdivisions + 2) * (n_subdivisions + 2);
+}
diff --git a/src/main.zig b/src/main.zig
@@ -431,6 +431,9 @@ pub fn main() !void {
const generateUVSphere = @import("uvsphere.zig").generateUVSphere;
const sphere_mesh = try generateUVSphere(16, 16, allocator);
+ const generateCube = @import("cube.zig").generateCube;
+ const cube_mesh = try generateCube(1, allocator);
+
var rp = try MeshRenderPipeline.init(
&app,
.{
@@ -462,6 +465,7 @@ pub fn main() !void {
var transform_1 = Transform{};
var transform_2 = Transform{};
var transform_3 = Transform{ .offset = .{ 3, 3, 3 } };
+ var transform_4 = Transform{ .offset = .{ -3, -3, 0 } };
var render_mesh = try render_data.addMesh(
&transform_1,
@@ -481,6 +485,12 @@ pub fn main() !void {
allocator,
);
+ _ = try render_data.addMesh(
+ &transform_4,
+ &cube_mesh,
+ allocator,
+ );
+
const corners = mesh.bboxVertices();
const bbox_indices = Mesh.bboxIndices();