this repo has no description
1const zm = @import("zmath");
2
3const HitRecord = @import("hittable.zig").HitRecord;
4const Interval = @import("interval.zig").IntervalF32;
5const Ray = @import("Ray.zig");
6
7const AABB = @This();
8
9x: Interval = Interval.empty,
10y: Interval = Interval.empty,
11z: Interval = Interval.empty,
12
13pub fn init(x: Interval, y: Interval, z: Interval) AABB {
14 return AABB{ .x = x, .y = y, .z = z };
15}
16
17pub fn initP(a: zm.Vec, b: zm.Vec) AABB {
18 // Treat the two points a and b as extrema for the bounding box, so we don't require a
19 // particular minimum/maximum coordinate order.
20 return AABB{
21 .x = blk: {
22 if (a[0] <= b[0]) break :blk Interval.init(a[0], b[0]) else break :blk Interval.init(b[0], a[0]);
23 },
24 .y = blk: {
25 if (a[1] <= b[1]) break :blk Interval.init(a[1], b[1]) else break :blk Interval.init(b[1], a[1]);
26 },
27 .z = blk: {
28 if (a[2] <= b[2]) break :blk Interval.init(a[2], b[2]) else break :blk Interval.init(b[2], a[2]);
29 },
30 };
31}
32
33pub fn initAB(a: *const AABB, b: *const AABB) AABB {
34 return AABB{
35 .x = Interval.initI(a.x, b.x),
36 .y = Interval.initI(a.y, b.y),
37 .z = Interval.initI(a.z, b.z),
38 };
39}
40
41pub fn axisInterval(self: *const AABB, n: i32) Interval {
42 if (n == 1) return self.y;
43 if (n == 2) return self.z;
44 return self.x;
45}
46
47pub fn hit(self: *AABB, r: *Ray, ray_t: Interval) bool {
48 if (ray_t.max <= ray_t.min) return false;
49
50 const ray_orig = r.orig;
51 const ray_dir = r.dir;
52
53 var t = ray_t;
54
55 var axis: u8 = 0;
56 while (axis < 3) : (axis += 1) {
57 const ax = self.axisInterval(@intCast(axis));
58 const adinv = 1.0 / ray_dir[axis];
59
60 const t0 = (ax.min - ray_orig[axis]) * adinv;
61 const t1 = (ax.max - ray_orig[axis]) * adinv;
62
63 if (t0 < t1) {
64 if (t0 > t.min) t.min = t0;
65 if (t1 < t.max) t.max = t1;
66 } else {
67 if (t1 > t.min) t.min = t1;
68 if (t0 < t.max) t.max = t0;
69 }
70
71 if (t.max <= t.min) return false;
72 }
73
74 return true;
75}
76
77pub fn longestAxis(self: *AABB) i32 {
78 if (self.x.size() > self.y.size()) {
79 if (self.x.size() > self.z.size()) {
80 return 0;
81 } else return 2;
82 } else {
83 if (self.y.size() > self.z.size()) {
84 return 1;
85 } else return 2;
86 }
87}