this repo has no description
1const std = @import("std");
2
3const zm = @import("zmath");
4
5const IntervalF32 = @import("a").interval.IntervalF32;
6const Material = @import("material.zig").Material;
7const Ray = @import("ray.zig");
8
9// Hittable Objects
10pub const Sphere = @import("hittable/sphere.zig");
11
12pub const HitRecord = struct {
13 p: zm.Vec,
14 normal: zm.Vec = zm.f32x4s(1.0),
15 mat: *Material,
16 t: f32,
17 front_face: bool = true,
18
19 pub fn setFaceNormal(self: *HitRecord, r: *Ray, outward_normal: zm.Vec) void {
20 self.front_face = zm.dot3(r.dir, outward_normal)[0] < 0.0;
21 self.normal = if (self.front_face) outward_normal else -outward_normal;
22 }
23};
24
25pub const HittableType = enum {
26 sphere,
27};
28
29pub const Hittable = union(HittableType) {
30 sphere: Sphere,
31
32 pub fn initSphere(sphere: Sphere) Hittable {
33 return .{ .sphere = sphere };
34 }
35
36 pub fn hit(self: *Hittable, r: *Ray, ray_t: IntervalF32) ?HitRecord {
37 switch (self.*) {
38 .sphere => |*sphere| {
39 return sphere.hit(r, ray_t);
40 },
41 }
42
43 return null;
44 }
45};
46
47pub const HittableList = struct {
48 list: std.ArrayList(Hittable),
49
50 pub fn init(allocator: std.mem.Allocator) HittableList {
51 const list = std.ArrayList(Hittable).init(allocator);
52
53 return .{ .list = list };
54 }
55
56 pub fn deinit(self: *HittableList) void {
57 self.list.deinit();
58 }
59
60 pub fn add(self: *HittableList, item: Hittable) !void {
61 try self.list.append(item);
62 }
63
64 pub fn hit(self: *HittableList, r: *Ray, ray_t: IntervalF32) ?HitRecord {
65 var rec: ?HitRecord = null;
66 var hit_anything = false;
67 var closest_so_far = ray_t.max;
68
69 for (self.list.items) |*object| {
70 if (object.hit(r, IntervalF32.init(ray_t.min, closest_so_far))) |new_rec| {
71 rec = new_rec;
72 hit_anything = true;
73 closest_so_far = new_rec.t;
74 }
75 }
76
77 return rec;
78 }
79};