From aefd204577902c95b8b1830e3f12a3546270ccac Mon Sep 17 00:00:00 2001 From: Wito Wiala Date: Fri, 5 Jun 2026 16:28:04 +0100 Subject: [PATCH] Eliminated duplicate and incorrect definitions of transform applications to geometric primitives --- shared/src/core/geometry/bounds.rs | 6 +- shared/src/utils/transform.rs | 142 +++++++++++++---------------- 2 files changed, 68 insertions(+), 80 deletions(-) diff --git a/shared/src/core/geometry/bounds.rs b/shared/src/core/geometry/bounds.rs index bb3e14b..ca74b02 100644 --- a/shared/src/core/geometry/bounds.rs +++ b/shared/src/core/geometry/bounds.rs @@ -294,7 +294,8 @@ impl Bounds3f { // Check 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 { return None; @@ -344,7 +345,8 @@ impl Bounds3f { } 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 { return false; diff --git a/shared/src/utils/transform.rs b/shared/src/utils/transform.rs index d3d6038..c6e2d78 100644 --- a/shared/src/utils/transform.rs +++ b/shared/src/utils/transform.rs @@ -94,46 +94,44 @@ impl Default for TransformGeneric { } } -pub type Transform = TransformGeneric; - -impl TransformGeneric { - pub fn apply_to_point(&self, p: Point3f) -> Point3f { - let x = p.x(); - let y = p.y(); - let z = p.z(); - let xp = self.m[0][0] * x + self.m[0][1] * y + self.m[0][2] * z + self.m[0][3]; - let yp = self.m[1][0] * x + self.m[1][1] * y + self.m[1][2] * z + self.m[1][3]; - 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) +impl TransformGeneric { + #[inline] + pub fn apply_to_point(&self, p: Point) -> Point { + 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 y = self.m[1][0]*p.x() + self.m[1][1]*p.y() + self.m[1][2]*p.z() + self.m[1][3]; + 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 w = self.m[3][0]*p.x() + self.m[3][1]*p.y() + self.m[3][2]*p.z() + self.m[3][3]; + if w == T::one() { + Point([x, y, z]) } 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 { - let x = v.x(); - let y = v.y(); - let z = v.z(); - let xv = self.m[0][0] * x + self.m[0][1] * y + self.m[0][2] * z; - let yv = self.m[1][0] * x + self.m[1][1] * y + self.m[1][2] * z; - let zv = self.m[2][0] * x + self.m[2][1] * y + self.m[2][2] * z; - Vector3f::new(xv, yv, zv) - + #[inline] + pub fn apply_to_vector(&self, v: Vector) -> Vector { + // directions: linear part only, no translation, no w-divide + Vector([ + self.m[0][0]*v.x() + self.m[0][1]*v.y() + self.m[0][2]*v.z(), + self.m[1][0]*v.x() + self.m[1][1]*v.y() + self.m[1][2]*v.z(), + self.m[2][0]*v.x() + self.m[2][1]*v.y() + self.m[2][2]*v.z(), + ]) } - pub fn apply_to_normal(&self, p: Normal3f) -> Normal3f { - let x = p.x(); - let y = p.y(); - let z = p.z(); - let xn = self.m_inv[0][0] * x + self.m_inv[1][1] * y + self.m_inv[2][0] * z; - let yn = self.m_inv[1][0] * x + self.m_inv[1][1] * y + self.m_inv[2][1] * z; - let zn = self.m_inv[2][0] * x + self.m_inv[1][2] * y + self.m_inv[2][2] * z; - Normal3f::new(xn, yn, zn) + #[inline] + pub fn apply_to_normal(&self, n: Normal) -> Normal { + // normals: inverse-transpose, no translation, no w-divide + Normal([ + self.m_inv[0][0]*n.x() + self.m_inv[1][0]*n.y() + self.m_inv[2][0]*n.z(), + self.m_inv[0][1]*n.x() + self.m_inv[1][1]*n.y() + self.m_inv[2][1]*n.z(), + self.m_inv[0][2]*n.x() + self.m_inv[1][2]*n.y() + self.m_inv[2][2]*n.z(), + ]) } +} +pub type Transform = TransformGeneric; + +impl Transform { pub fn apply_to_bounds(&self, b: Bounds3f) -> Bounds3f { let mut new_bounds = Bounds3f::default(); for i in 0..8 { @@ -669,60 +667,48 @@ impl Mul> for Float { } } -impl Mul> for TransformGeneric -where - T: NumFloat, -{ +impl Mul> for TransformGeneric { type Output = Point; - fn mul(self, p: Point) -> Self::Output { - let xp = self.m[0][0] * p.x() + self.m[0][1] * p.y() + self.m[0][2] * p.z() + self.m[0][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]; - 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]) - } + #[inline] + fn mul(self, p: Point) -> Point { + self.apply_to_point(p) } } - -impl Mul> for TransformGeneric -where - T: NumFloat, -{ +impl Mul> for TransformGeneric { type Output = Vector; - fn mul(self, p: Vector) -> Self::Output { - let xp = self.m[0][0] * p.x() + self.m[0][1] * p.y() + self.m[0][2] * p.z() + self.m[0][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]; - 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() { - Vector([xp, yp, zp]) - } else { - Vector([xp / wp, yp / wp, zp / wp]) - } + #[inline] + fn mul(self, v: Vector) -> Vector { + self.apply_to_vector(v) + } +} +impl Mul> for TransformGeneric { + type Output = Normal; + #[inline] + fn mul(self, n: Normal) -> Normal { + self.apply_to_normal(n) } } -impl Mul> for TransformGeneric -where - T: NumFloat, -{ +// reference versions, so `&t * v` works without consuming the transform +impl Mul> for &TransformGeneric { + type Output = Point; + #[inline] + fn mul(self, p: Point) -> Point { + self.apply_to_point(p) + } +} +impl Mul> for &TransformGeneric { + type Output = Vector; + #[inline] + fn mul(self, v: Vector) -> Vector { + self.apply_to_vector(v) + } +} +impl Mul> for &TransformGeneric { type Output = Normal; - fn mul(self, p: Normal) -> Self::Output { - let xp = self.m[0][0] * p.x() + self.m[0][1] * p.y() + self.m[0][2] * p.z() + self.m[0][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]; - 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]) - } + #[inline] + fn mul(self, n: Normal) -> Normal { + self.apply_to_normal(n) } }