Eliminated duplicate and incorrect definitions of transform applications to geometric primitives

This commit is contained in:
Wito Wiala 2026-06-05 16:28:04 +01:00
parent ac7fdd7486
commit aefd204577
2 changed files with 68 additions and 80 deletions

View file

@ -294,7 +294,8 @@ impl Bounds3f {
// Check Z // Check Z
let tz_min = (bounds[dir_is_neg[2]].z() - o.z()) * inv_dir.z(); let tz_min = (bounds[dir_is_neg[2]].z() - o.z()) * inv_dir.z();
let tz_max = (bounds[1 - dir_is_neg[2]].z() - o.z()) * inv_dir.z(); let mut tz_max = (bounds[1 - dir_is_neg[2]].z() - o.z()) * inv_dir.z();
tz_max = tz_max * (1. + 2. * gamma(3));
if t_min > tz_max || tz_min > t_max { if t_min > tz_max || tz_min > t_max {
return None; return None;
@ -344,7 +345,8 @@ impl Bounds3f {
} }
let tz_min = (bounds[dir_is_neg[2]].z() - o.z()) * inv_dir.z(); let tz_min = (bounds[dir_is_neg[2]].z() - o.z()) * inv_dir.z();
let tz_max = (bounds[1 - dir_is_neg[2]].z() - o.z()) * inv_dir.z(); let mut tz_max = (bounds[1 - dir_is_neg[2]].z() - o.z()) * inv_dir.z();
tz_max = tz_max * (1. + 2. * gamma(3));
if t_min > tz_max || tz_min > t_max { if t_min > tz_max || tz_min > t_max {
return false; return false;

View file

@ -94,46 +94,44 @@ impl<T: NumFloat + Sum + Product> Default for TransformGeneric<T> {
} }
} }
pub type Transform = TransformGeneric<Float>; impl<T: NumFloat> TransformGeneric<T> {
#[inline]
impl TransformGeneric<Float> { pub fn apply_to_point(&self, p: Point<T, 3>) -> Point<T, 3> {
pub fn apply_to_point(&self, p: Point3f) -> Point3f { let x = self.m[0][0]*p.x() + self.m[0][1]*p.y() + self.m[0][2]*p.z() + self.m[0][3];
let x = p.x(); let y = self.m[1][0]*p.x() + self.m[1][1]*p.y() + self.m[1][2]*p.z() + self.m[1][3];
let y = p.y(); let z = self.m[2][0]*p.x() + self.m[2][1]*p.y() + self.m[2][2]*p.z() + self.m[2][3];
let z = p.z(); let w = self.m[3][0]*p.x() + self.m[3][1]*p.y() + self.m[3][2]*p.z() + self.m[3][3];
let xp = self.m[0][0] * x + self.m[0][1] * y + self.m[0][2] * z + self.m[0][3]; if w == T::one() {
let yp = self.m[1][0] * x + self.m[1][1] * y + self.m[1][2] * z + self.m[1][3]; Point([x, y, z])
let zp = self.m[2][0] * x + self.m[2][1] * y + self.m[2][2] * z + self.m[2][3];
let wp = self.m[3][0] * x + self.m[3][1] * y + self.m[3][2] * z + self.m[3][3];
if wp == 1. {
Point3f::new(xp, yp, zp)
} else { } else {
Point3f::new(xp / wp, yp / wp, zp / wp) Point([x / w, y / w, z / w])
} }
} }
pub fn apply_to_vector(&self, v: Vector3f) -> Vector3f { #[inline]
let x = v.x(); pub fn apply_to_vector(&self, v: Vector<T, 3>) -> Vector<T, 3> {
let y = v.y(); // directions: linear part only, no translation, no w-divide
let z = v.z(); Vector([
let xv = self.m[0][0] * x + self.m[0][1] * y + self.m[0][2] * z; self.m[0][0]*v.x() + self.m[0][1]*v.y() + self.m[0][2]*v.z(),
let yv = self.m[1][0] * x + self.m[1][1] * y + self.m[1][2] * z; self.m[1][0]*v.x() + self.m[1][1]*v.y() + self.m[1][2]*v.z(),
let zv = self.m[2][0] * x + self.m[2][1] * y + self.m[2][2] * z; self.m[2][0]*v.x() + self.m[2][1]*v.y() + self.m[2][2]*v.z(),
Vector3f::new(xv, yv, zv) ])
} }
pub fn apply_to_normal(&self, p: Normal3f) -> Normal3f { #[inline]
let x = p.x(); pub fn apply_to_normal(&self, n: Normal<T, 3>) -> Normal<T, 3> {
let y = p.y(); // normals: inverse-transpose, no translation, no w-divide
let z = p.z(); Normal([
let xn = self.m_inv[0][0] * x + self.m_inv[1][1] * y + self.m_inv[2][0] * z; self.m_inv[0][0]*n.x() + self.m_inv[1][0]*n.y() + self.m_inv[2][0]*n.z(),
let yn = self.m_inv[1][0] * x + self.m_inv[1][1] * y + self.m_inv[2][1] * z; self.m_inv[0][1]*n.x() + self.m_inv[1][1]*n.y() + self.m_inv[2][1]*n.z(),
let zn = self.m_inv[2][0] * x + self.m_inv[1][2] * y + self.m_inv[2][2] * z; self.m_inv[0][2]*n.x() + self.m_inv[1][2]*n.y() + self.m_inv[2][2]*n.z(),
Normal3f::new(xn, yn, zn) ])
} }
}
pub type Transform = TransformGeneric<Float>;
impl Transform {
pub fn apply_to_bounds(&self, b: Bounds3f) -> Bounds3f { pub fn apply_to_bounds(&self, b: Bounds3f) -> Bounds3f {
let mut new_bounds = Bounds3f::default(); let mut new_bounds = Bounds3f::default();
for i in 0..8 { for i in 0..8 {
@ -669,60 +667,48 @@ impl Mul<TransformGeneric<Float>> for Float {
} }
} }
impl<T> Mul<Point<T, 3>> for TransformGeneric<T> impl<T: NumFloat> Mul<Point<T, 3>> for TransformGeneric<T> {
where
T: NumFloat,
{
type Output = Point<T, 3>; type Output = Point<T, 3>;
fn mul(self, p: Point<T, 3>) -> Self::Output { #[inline]
let xp = self.m[0][0] * p.x() + self.m[0][1] * p.y() + self.m[0][2] * p.z() + self.m[0][3]; fn mul(self, p: Point<T, 3>) -> Point<T, 3> {
let yp = self.m[1][0] * p.x() + self.m[1][1] * p.y() + self.m[1][2] * p.z() + self.m[1][3]; self.apply_to_point(p)
let zp = self.m[2][0] * p.x() + self.m[2][1] * p.y() + self.m[2][2] * p.z() + self.m[2][3];
let wp = self.m[3][0] * p.x() + self.m[3][1] * p.y() + self.m[3][2] * p.z() + self.m[3][3];
if wp == T::one() {
Point([xp, yp, zp])
} else {
Point([xp / wp, yp / wp, zp / wp])
}
} }
} }
impl<T: NumFloat> Mul<Vector<T, 3>> for TransformGeneric<T> {
impl<T> Mul<Vector<T, 3>> for TransformGeneric<T>
where
T: NumFloat,
{
type Output = Vector<T, 3>; type Output = Vector<T, 3>;
fn mul(self, p: Vector<T, 3>) -> Self::Output { #[inline]
let xp = self.m[0][0] * p.x() + self.m[0][1] * p.y() + self.m[0][2] * p.z() + self.m[0][3]; fn mul(self, v: Vector<T, 3>) -> Vector<T, 3> {
let yp = self.m[1][0] * p.x() + self.m[1][1] * p.y() + self.m[1][2] * p.z() + self.m[1][3]; self.apply_to_vector(v)
let zp = self.m[2][0] * p.x() + self.m[2][1] * p.y() + self.m[2][2] * p.z() + self.m[2][3]; }
let wp = self.m[3][0] * p.x() + self.m[3][1] * p.y() + self.m[3][2] * p.z() + self.m[3][3]; }
impl<T: NumFloat> Mul<Normal<T, 3>> for TransformGeneric<T> {
if wp == T::one() { type Output = Normal<T, 3>;
Vector([xp, yp, zp]) #[inline]
} else { fn mul(self, n: Normal<T, 3>) -> Normal<T, 3> {
Vector([xp / wp, yp / wp, zp / wp]) self.apply_to_normal(n)
}
} }
} }
impl<T> Mul<Normal<T, 3>> for TransformGeneric<T> // reference versions, so `&t * v` works without consuming the transform
where impl<T: NumFloat> Mul<Point<T, 3>> for &TransformGeneric<T> {
T: NumFloat, type Output = Point<T, 3>;
{ #[inline]
fn mul(self, p: Point<T, 3>) -> Point<T, 3> {
self.apply_to_point(p)
}
}
impl<T: NumFloat> Mul<Vector<T, 3>> for &TransformGeneric<T> {
type Output = Vector<T, 3>;
#[inline]
fn mul(self, v: Vector<T, 3>) -> Vector<T, 3> {
self.apply_to_vector(v)
}
}
impl<T: NumFloat> Mul<Normal<T, 3>> for &TransformGeneric<T> {
type Output = Normal<T, 3>; type Output = Normal<T, 3>;
fn mul(self, p: Normal<T, 3>) -> Self::Output { #[inline]
let xp = self.m[0][0] * p.x() + self.m[0][1] * p.y() + self.m[0][2] * p.z() + self.m[0][3]; fn mul(self, n: Normal<T, 3>) -> Normal<T, 3> {
let yp = self.m[1][0] * p.x() + self.m[1][1] * p.y() + self.m[1][2] * p.z() + self.m[1][3]; self.apply_to_normal(n)
let zp = self.m[2][0] * p.x() + self.m[2][1] * p.y() + self.m[2][2] * p.z() + self.m[2][3];
let wp = self.m[3][0] * p.x() + self.m[3][1] * p.y() + self.m[3][2] * p.z() + self.m[3][3];
if wp == T::one() {
Normal([xp, yp, zp])
} else {
Normal([xp / wp, yp / wp, zp / wp])
}
} }
} }