51 lines
1.4 KiB
Rust
51 lines
1.4 KiB
Rust
use rand::Rng;
|
|
use ray_tracing_core::material::DefaultMaterial;
|
|
use ray_tracing_core::prelude::*;
|
|
use ray_tracing_core::scene::{Intersection, Scene};
|
|
|
|
pub mod sphere;
|
|
|
|
pub struct BasicScene {
|
|
spheres: Vec<(Pos3, Float)>,
|
|
}
|
|
|
|
impl BasicScene {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
spheres: vec![(Pos3::zero(), 1.0), (Pos3::new(0.0, 0.0, 2.5), 2.0)],
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<R: Rng> Scene<R> for BasicScene {
|
|
fn intersect(&self, ray: Ray, min: Float, max: Float) -> Option<Intersection<'_, R>> {
|
|
let mut intersection: Option<Intersection<'_, R>> = None;
|
|
|
|
for &(c, r) in &self.spheres {
|
|
let offset = ray.start() - c;
|
|
let p = Dir3::dot(ray.dir(), offset);
|
|
let delta = p * p - (offset.length_squared() - r * r);
|
|
|
|
if delta >= 0.0 {
|
|
let d = -p - Float::sqrt(delta);
|
|
|
|
let int = Intersection::new(
|
|
d,
|
|
((ray.start() + d * ray.dir()) - c).normalize(),
|
|
&DefaultMaterial {},
|
|
);
|
|
if d >= min && d <= max {
|
|
if let Some(i) = intersection.as_ref() {
|
|
if i.t() > d {
|
|
intersection.replace(int);
|
|
}
|
|
} else {
|
|
intersection = Some(int)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
intersection
|
|
}
|
|
}
|