this repo has no description
at main 2.4 kB view raw
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}