common/
hittable.rs

1use std::sync::Arc;
2use crate::material::Material;
3use crate::vec3::{Point3, Vec3, dot};
4use crate::ray::Ray;
5
6/// Stores the result of a ray–object intersection.
7pub struct HitRecord {
8    /// Intersection point.
9    pub p: Point3,
10    /// Surface normal at the intersection (always points against the incident ray).
11    pub normal: Vec3,
12    /// Ray parameter at the intersection.
13    pub t: f64,
14    /// `true` if the ray hit the front (outside) face.
15    pub front_face: bool,
16    /// Material at the hit point (`None` means no scattering).
17    pub mat: Option<Arc<dyn Material>>,
18}
19
20impl HitRecord {
21    /// Sets `front_face` and `normal` so the normal always points against the incident ray.
22    pub fn set_face_normal(&mut self, r: &Ray, outward_normal: Vec3) {
23        self.front_face = dot(r.direction(), outward_normal) < 0.0;
24        self.normal = if self.front_face { outward_normal } else { -outward_normal };
25    }
26}
27
28/// Trait for objects that can be intersected by a ray.
29pub trait Hittable {
30    /// Returns `Some(HitRecord)` if the ray intersects in the interval `[t_min, t_max]`, or `None`.
31    fn hit(&self, r: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord>;
32}