render-zig

A 3D rendering engine written in Zig
git clone git://git.christianermann.dev/render-zig
Log | Files | Refs

commit 1e1a77b4ca78a098b8f054754a6eb4562e4f47fa
parent dd09b4131dced5f702ba7c26bbe413a1f6316fb3
Author: Christian Ermann <christianermann@gmail.com>
Date:   Sun,  8 Dec 2024 13:42:58 -0800

Move 'tangentsAndBitangents' from 'load_obj.zig' to 'mesh.zig'

Diffstat:
Msrc/load_obj.zig | 68+-------------------------------------------------------------------
Msrc/mesh.zig | 72+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 70 insertions(+), 70 deletions(-)

diff --git a/src/load_obj.zig b/src/load_obj.zig @@ -192,73 +192,7 @@ pub fn loadFile(options: LoadFileOptions) !Mesh { .bitangents = try allocator.alloc(f32x3, pslice.len), }; mesh.bbox = mesh.axisAlignedBoundingBox(); - try tangentsAndBitangents(&mesh, allocator); + try mesh.tangentsAndBitangents(allocator); return mesh; } - -fn tangentsAndBitangents( - mesh: *const Mesh, - allocator: std.mem.Allocator, -) !void { - const positions = mesh.positions; - const tex_coords = mesh.tex_coords; - const indices = mesh.indices; - const tangents = mesh.tangents; - const bitangents = mesh.bitangents; - - @memset(std.mem.asBytes(tangents), 0); - @memset(std.mem.asBytes(bitangents), 0); - if (tex_coords.len <= 0) { - return; - } - - var references = try allocator.alloc(u32, positions.len); - defer allocator.free(references); - @memset(references, 0); - - var i: u32 = 0; - while (i < indices.len) : (i += 3) { - const idx_0 = indices[i + 0]; - const idx_1 = indices[i + 1]; - const idx_2 = indices[i + 2]; - - const p0: f32x3 = @as([4]f32, positions[idx_0])[0..3].*; - const p1: f32x3 = @as([4]f32, positions[idx_1])[0..3].*; - const p2: f32x3 = @as([4]f32, positions[idx_2])[0..3].*; - const delta_p1 = p1 - p0; - const delta_p2 = p2 - p0; - - const t0 = tex_coords[idx_0]; - const t1 = tex_coords[idx_1]; - const t2 = tex_coords[idx_2]; - const delta_t1 = t1 - t0; - const delta_t2 = t2 - t0; - - const r = 1.0 / (delta_t1[0] * delta_t2[1] - delta_t1[1] * delta_t2[0]); - - const tangent_a = delta_p1 * @as(f32x3, @splat(delta_t2[1])); - const tangent_b = delta_p2 * @as(f32x3, @splat(delta_t1[1])); - const tangent = (tangent_a - tangent_b) * @as(f32x3, @splat(r)); - tangents[idx_0] += tangent; - tangents[idx_1] += tangent; - tangents[idx_2] += tangent; - - const bitangent_a = delta_p2 * @as(f32x3, @splat(delta_t1[0])); - const bitangent_b = delta_p1 * @as(f32x3, @splat(delta_t2[0])); - const bitangent = (bitangent_a - bitangent_b) * @as(f32x3, @splat(-r)); - bitangents[idx_0] += bitangent; - bitangents[idx_1] += bitangent; - bitangents[idx_2] += bitangent; - - references[idx_0] += 1; - references[idx_1] += 1; - references[idx_2] += 1; - } - - for (references, 0..references.len) |ref_count, idx| { - const scale = @as(f32x3, @splat(1 / @as(f32, @floatFromInt(ref_count)))); - tangents[idx] *= scale; - bitangents[idx] *= scale; - } -} diff --git a/src/mesh.zig b/src/mesh.zig @@ -3,7 +3,7 @@ const std = @import("std"); const f32x3 = @Vector(3, f32); const f32x4 = @Vector(4, f32); -const Self = @This(); +const Mesh = @This(); positions: []f32x4, normals: []f32x3, @@ -20,7 +20,73 @@ pub const MeshletDescriptor = struct { num_triangles: u32, }; -pub fn axisAlignedBoundingBox(self: *const Self) [6]f32 { +pub fn tangentsAndBitangents( + mesh: *const Mesh, + allocator: std.mem.Allocator, +) !void { + const positions = mesh.positions; + const tex_coords = mesh.tex_coords; + const indices = mesh.indices; + const tangents = mesh.tangents; + const bitangents = mesh.bitangents; + + @memset(std.mem.asBytes(tangents), 0); + @memset(std.mem.asBytes(bitangents), 0); + if (tex_coords.len <= 0) { + return; + } + + var references = try allocator.alloc(u32, positions.len); + defer allocator.free(references); + @memset(references, 0); + + var i: u32 = 0; + while (i < indices.len) : (i += 3) { + const idx_0 = indices[i + 0]; + const idx_1 = indices[i + 1]; + const idx_2 = indices[i + 2]; + + const p0: f32x3 = @as([4]f32, positions[idx_0])[0..3].*; + const p1: f32x3 = @as([4]f32, positions[idx_1])[0..3].*; + const p2: f32x3 = @as([4]f32, positions[idx_2])[0..3].*; + const delta_p1 = p1 - p0; + const delta_p2 = p2 - p0; + + const t0 = tex_coords[idx_0]; + const t1 = tex_coords[idx_1]; + const t2 = tex_coords[idx_2]; + const delta_t1 = t1 - t0; + const delta_t2 = t2 - t0; + + const r = 1.0 / (delta_t1[0] * delta_t2[1] - delta_t1[1] * delta_t2[0]); + + const tangent_a = delta_p1 * @as(f32x3, @splat(delta_t2[1])); + const tangent_b = delta_p2 * @as(f32x3, @splat(delta_t1[1])); + const tangent = (tangent_a - tangent_b) * @as(f32x3, @splat(r)); + tangents[idx_0] += tangent; + tangents[idx_1] += tangent; + tangents[idx_2] += tangent; + + const bitangent_a = delta_p2 * @as(f32x3, @splat(delta_t1[0])); + const bitangent_b = delta_p1 * @as(f32x3, @splat(delta_t2[0])); + const bitangent = (bitangent_a - bitangent_b) * @as(f32x3, @splat(-r)); + bitangents[idx_0] += bitangent; + bitangents[idx_1] += bitangent; + bitangents[idx_2] += bitangent; + + references[idx_0] += 1; + references[idx_1] += 1; + references[idx_2] += 1; + } + + for (references, 0..references.len) |ref_count, idx| { + const scale = @as(f32x3, @splat(1 / @as(f32, @floatFromInt(ref_count)))); + tangents[idx] *= scale; + bitangents[idx] *= scale; + } +} + +pub fn axisAlignedBoundingBox(self: *const Mesh) [6]f32 { var min_x: f32 = self.positions[0][0]; var max_x: f32 = self.positions[0][0]; var min_y: f32 = self.positions[0][1]; @@ -55,7 +121,7 @@ pub fn axisAlignedBoundingBox(self: *const Self) [6]f32 { return .{ min_x, min_y, min_z, max_x, max_y, max_z }; } -pub fn bboxVertices(self: *const Self) [8]f32x4 { +pub fn bboxVertices(self: *const Mesh) [8]f32x4 { const min_x = self.bbox[0]; const min_y = self.bbox[1]; const min_z = self.bbox[2];