Extract common shape intersection code

This commit is contained in:
hal8174 2025-09-10 22:38:41 +02:00
parent 333acab099
commit 807168f787
Signed by: hal8174
SSH key fingerprint: SHA256:NN98ZYwnrreQLSOV/g+amY7C3yL/mS1heD7bi5t6PPw

View file

@ -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<R: Rng + std::fmt::Debug> Shape<R> {
pub(crate) fn intersect(
&'_ self,
fn inner_intersect(
&self,
ray: Ray,
min: Float,
max: Float,
) -> Option<Intersection<R, UVMaterial<'_, R>, &'_ dyn Light<R>>> {
let ray = self.ctm.transform_ray(ray);
) -> Option<(Float, Dir3, Float, Float)> {
match &self.obj {
&ShapeType::Sphere {
radius,
@ -210,25 +208,12 @@ impl<R: Rng + std::fmt::Debug> Shape<R> {
}
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<R>),
0.0,
));
return Some((t, p.as_dir(), phi, Float::acos(p.z() / radius)));
}
}
}
@ -243,19 +228,7 @@ impl<R: Rng + std::fmt::Debug> Shape<R> {
&& 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<R>),
0.0,
));
return Some((t, Dir3::new(0.0, 0.0, 1.0), u, v));
}
}
ShapeType::LoopSubDiv { .. } => todo!(),
@ -265,4 +238,29 @@ impl<R: Rng + std::fmt::Debug> Shape<R> {
None
}
pub(crate) fn intersect(
&'_ self,
ray: Ray,
min: Float,
max: Float,
) -> Option<Intersection<R, UVMaterial<'_, R>, &'_ dyn Light<R>>> {
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<R>),
0.0,
)
})
}
}