///|
pub fn Aabb::intersects(self : Aabb, other : Aabb) -> Bool {
self.min.x <= other.max.x &&
other.min.x <= self.max.x &&
self.min.y <= other.max.y &&
other.min.y <= self.max.y &&
self.min.z <= other.max.z &&
other.min.z <= self.max.z
}
///|
pub fn Aabb::contains(self : Aabb, other : Aabb) -> Bool {
self.min.x <= other.min.x &&
other.max.x <= self.max.x &&
self.min.y <= other.min.y &&
other.max.y <= self.max.y &&
self.min.z <= other.min.z &&
other.max.z <= self.max.z
}
///|
// When subtraction overflows, halve its operands first. This path only handles
// large opposite-sign operands, so halving cannot discard a small difference.
fn parameter(bound : Double, origin : Double, direction : Double) -> Double {
let delta = bound - origin
if finite(delta) {
delta / direction
} else {
(bound * 0.5 - origin * 0.5) / direction * 2.0
}
}
///|
pub fn Ray::intersects(self : Ray, bounds : Aabb) -> Bool {
let mut near = self.t_min
let mut far = self.t_max
for axis in 0..<3 {
let (origin, direction, lo, hi) = match axis {
0 => (self.origin.x, self.direction.x, bounds.min.x, bounds.max.x)
1 => (self.origin.y, self.direction.y, bounds.min.y, bounds.max.y)
_ => (self.origin.z, self.direction.z, bounds.min.z, bounds.max.z)
}
if direction == 0.0 {
if origin < lo || origin > hi {
return false
}
} else {
let a = parameter(lo, origin, direction)
let b = parameter(hi, origin, direction)
let (enter, leave) = if a <= b { (a, b) } else { (b, a) }
if enter > near {
near = enter
}
if leave < far {
far = leave
}
if near > far {
return false
}
}
}
true
}