From 807168f7872da6c9f0f6cf65c6f8c334990a08f0 Mon Sep 17 00:00:00 2001 From: hal8174 Date: Wed, 10 Sep 2025 22:38:41 +0200 Subject: [PATCH] Extract common shape intersection code --- ray-tracing-pbrt-scene/src/shape.rs | 66 ++++++++++++++--------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/ray-tracing-pbrt-scene/src/shape.rs b/ray-tracing-pbrt-scene/src/shape.rs index ab69922..36f676b 100644 --- a/ray-tracing-pbrt-scene/src/shape.rs +++ b/ray-tracing-pbrt-scene/src/shape.rs @@ -21,7 +21,7 @@ pub(crate) enum ShapeAlpha { Texture(String), } -// #[derive(Debug)] +#[derive(Debug)] #[allow(dead_code)] pub(crate) enum ShapeType { Sphere { @@ -156,14 +156,12 @@ fn bilinear_intersection( } impl Shape { - pub(crate) fn intersect( - &'_ self, + fn inner_intersect( + &self, ray: Ray, min: Float, max: Float, - ) -> Option, &'_ dyn Light>> { - let ray = self.ctm.transform_ray(ray); - + ) -> Option<(Float, Dir3, Float, Float)> { match &self.obj { &ShapeType::Sphere { radius, @@ -210,25 +208,12 @@ impl Shape { } false }) { - let p = ray.at(t0); + let p = ray.at(t); let mut phi = Float::atan2(p.y(), p.x()); if phi < 0.0 { phi += 2.0 * FloatConsts::PI; } - return Some(Intersection::new( - t, - self.ctm - .inverse_transform_normal((ray.at(t).as_dir()).normalize()), - self.material.get_a().map(|m| UVMaterial { - u: phi, - v: Float::acos(p.z() / radius), - material: m.as_ref(), - }), - self.material - .get_b() - .map(|l| l as &dyn ray_tracing_core::light::Light), - 0.0, - )); + return Some((t, p.as_dir(), phi, Float::acos(p.z() / radius))); } } } @@ -243,19 +228,7 @@ impl Shape { && let Some((t, u, v)) = bilinear_intersection(ray, min, max, [p[0], p[1], p[2], p[3]]) { - return Some(Intersection::new( - t, - Dir3::new(0.0, 0.0, 1.0), - self.material.get_a().map(|m| UVMaterial { - u, - v, - material: m.as_ref(), - }), - self.material - .get_b() - .map(|l| l as &dyn ray_tracing_core::light::Light), - 0.0, - )); + return Some((t, Dir3::new(0.0, 0.0, 1.0), u, v)); } } ShapeType::LoopSubDiv { .. } => todo!(), @@ -265,4 +238,29 @@ impl Shape { None } + pub(crate) fn intersect( + &'_ self, + ray: Ray, + min: Float, + max: Float, + ) -> Option, &'_ dyn Light>> { + let ray = self.ctm.transform_ray(ray); + + self.inner_intersect(ray, min, max) + .map(|(t, normal, u, v)| { + Intersection::new( + t, + self.ctm.inverse_transform_normal(normal).normalize(), + self.material.get_a().map(|m| UVMaterial { + u, + v, + material: m.as_ref(), + }), + self.material + .get_b() + .map(|l| l as &dyn ray_tracing_core::light::Light), + 0.0, + ) + }) + } }