Skip to main content

eulumdat_goniosim/
ray.rs

1//! Ray, hit record, and photon types for Monte Carlo tracing.
2
3use nalgebra::{Point3, Unit, Vector3};
4
5/// A ray with origin and direction.
6#[derive(Debug, Clone)]
7pub struct Ray {
8    pub origin: Point3<f64>,
9    pub direction: Unit<Vector3<f64>>,
10}
11
12impl Ray {
13    /// Create a new ray.
14    pub fn new(origin: Point3<f64>, direction: Unit<Vector3<f64>>) -> Self {
15        Self { origin, direction }
16    }
17
18    /// Point along the ray at parameter t.
19    pub fn at(&self, t: f64) -> Point3<f64> {
20        self.origin + self.direction.as_ref() * t
21    }
22}
23
24/// Record of a ray-surface intersection.
25#[derive(Debug, Clone)]
26pub struct HitRecord {
27    /// Distance along the ray to the hit point.
28    pub t: f64,
29    /// World-space hit position.
30    pub point: Point3<f64>,
31    /// Outward-facing surface normal at the hit point.
32    pub normal: Unit<Vector3<f64>>,
33    /// True if the ray hit the outside of the surface (front face).
34    pub front_face: bool,
35    /// Index into the scene's material list.
36    pub material: crate::MaterialId,
37}
38
39impl HitRecord {
40    /// Set the face normal based on ray direction.
41    /// Ensures the normal always points against the ray.
42    pub fn set_face_normal(&mut self, ray: &Ray, outward_normal: Unit<Vector3<f64>>) {
43        self.front_face = ray.direction.dot(outward_normal.as_ref()) < 0.0;
44        self.normal = if self.front_face {
45            outward_normal
46        } else {
47            Unit::new_unchecked(-outward_normal.into_inner())
48        };
49    }
50}
51
52/// A photon being traced through the scene.
53#[derive(Debug, Clone)]
54pub struct Photon {
55    /// Current ray (position + direction).
56    pub ray: Ray,
57    /// Relative energy, starts at 1.0, reduced by absorption at each interaction.
58    pub energy: f64,
59    /// Wavelength in nm (default 555nm, for future spectral rendering).
60    pub wavelength: f64,
61    /// Number of bounces so far.
62    pub bounces: u32,
63}
64
65impl Photon {
66    /// Create a new photon from a ray with full energy.
67    pub fn new(ray: Ray) -> Self {
68        Self {
69            ray,
70            energy: 1.0,
71            wavelength: 555.0,
72            bounces: 0,
73        }
74    }
75}