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