use super::*;
impl Ray {
pub fn new(origin: Vector3D, direction: Vector3D) -> Ray {
Ray {
origin,
direction,
t_min: RAYTRACE_DEFAULT_T_MIN,
t_max: RAYTRACE_DEFAULT_T_MAX,
depth: 0,
}
}
pub fn at(&self, t: f64) -> Vector3D {
self.get_origin() + self.get_direction().scaled(t)
}
pub fn with_depth(&self, depth: u32) -> Ray {
Ray {
origin: self.get_origin(),
direction: self.get_direction(),
t_min: self.get_t_min(),
t_max: self.get_t_max(),
depth,
}
}
}
impl Occluder {
pub fn sphere(center: Vector3D, radius: f64, material: Material) -> Occluder {
Occluder {
kind: OccluderKind::Sphere,
center,
extent: Vector3D::new(radius, radius, radius),
material,
}
}
pub fn aabb(min: Vector3D, max: Vector3D, material: Material) -> Occluder {
Occluder {
kind: OccluderKind::Aabb,
center: min,
extent: max,
material,
}
}
pub fn occluder_points(&self) -> Vec<(Vector3D, f64)> {
collect_occluder_points(std::slice::from_ref(self))
}
}
impl RayTraceScene {
pub fn new(occluders: Vec<Occluder>) -> RayTraceScene {
let shadow_points: Vec<(Vector3D, f64)> = collect_occluder_points(&occluders);
RayTraceScene {
occluders,
shadow_points,
}
}
pub fn trace(&self, ray: Ray, lights: &LightingUniforms) -> Vector3D {
self.trace_with_bounces(ray, lights, RAYTRACE_DEFAULT_MAX_BOUNCES)
}
pub fn trace_with_bounces(
&self,
ray: Ray,
lights: &LightingUniforms,
max_bounces: u32,
) -> Vector3D {
trace_bounces(
ray,
self.get_occluders(),
self.get_shadow_points(),
lights,
max_bounces,
)
}
pub fn closest_hit(&self, ray: &Ray) -> Option<Hit> {
let occluders: &[Occluder] = self.get_occluders();
closest_hit_indexed(ray, occluders).map(
|(index, t, position, normal): (usize, f64, Vector3D, Vector3D)| Hit {
t,
position,
normal,
material: occluders[index].get_material().clone(),
},
)
}
}