lumo 0.3.2

CPU based rendering engine
Documentation
use super::*;
use crate::tracer::{Plane, Sphere};
use crate::{Point, Direction};

/* light at y = 2, plane at y = 1 perp to z */
fn scene(m: Material) -> Scene {
    let mut scene = Scene::default();

    scene.add_light(Sphere::new(
        Point::new(0.0, 2.0, 0.0),
        crate::EPSILON,
        Material::Light(Texture::Solid(Color::WHITE))
    ));

    scene.add(Plane::new(
        Point::new(0.0, 1.0, 0.0),
        Point::new(0.0, -1.0, 0.0),
        m,
    ));

    scene
}

#[test]
fn light_no_pass() {
    let s = scene(Material::Mirror);
    let r = Ray::new(Point::ZERO, Direction::Y);
    assert!(s.hit_light(&r, s.lights[0].as_ref()).is_none());
}

#[test]
fn object_behind_light() {
    let s = scene(Material::Mirror);
    let r = Ray::new(3.0 * Point::Y, Direction::NEG_Y);
    assert!(s.hit_light(&r, s.lights[0].as_ref()).is_some());
}

#[test]
fn hits_closest() {
    let mut s = Scene::default();

    s.add(Plane::new(
        Point::Y,
        Point::NEG_Y,
        Material::Blank,
    ));

    s.add(Plane::new(
        2.0 * Point::Y,
        Point::NEG_Y,
        Material::Mirror,
    ));

    let r = Ray::new(Point::ZERO, Point::Y);
    let is_blank = |h: &Hit| -> bool { matches!(h.material, Material::Blank) };
    assert!(s.hit(&r).filter(is_blank).is_some());
}