aboutsummaryrefslogtreecommitdiff
path: root/src/hittable/hittable_box.rs
blob: 9631635ff19a8198e182267b698a3d81c4b4be1d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use std::sync::Arc;

use crate::{
    hittable::{
        hittable_list::HittableList, xy_rect::XYRect, xz_rect::XZRect, yz_rect::YZRect, HitRecord,
        Hittable, AABB,
    },
    material::Material,
    ray::Ray,
    vec3::Point3,
};

pub struct HittableBox {
    min: Point3,
    max: Point3,
    sides: HittableList,
}

impl HittableBox {
    pub fn new(min: Point3, max: Point3, material: Arc<dyn Material>) -> Self {
        let mut sides = HittableList::new();

        sides.add(Arc::new(XYRect {
            material: material.clone(),
            x0: min.x,
            x1: max.x,
            y0: min.y,
            y1: max.y,
            k: max.z,
        }));
        sides.add(Arc::new(XYRect {
            material: material.clone(),
            x0: min.x,
            x1: max.x,
            y0: min.y,
            y1: max.y,
            k: min.z,
        }));

        sides.add(Arc::new(XZRect {
            material: material.clone(),
            x0: min.x,
            x1: max.x,
            z0: min.z,
            z1: max.z,
            k: max.y,
        }));
        sides.add(Arc::new(XZRect {
            material: material.clone(),
            x0: min.x,
            x1: max.x,
            z0: min.z,
            z1: max.z,
            k: min.y,
        }));

        sides.add(Arc::new(YZRect {
            material: material.clone(),
            y0: min.y,
            y1: max.y,
            z0: min.z,
            z1: max.z,
            k: max.x,
        }));
        sides.add(Arc::new(YZRect {
            material: material.clone(),
            y0: min.y,
            y1: max.y,
            z0: min.z,
            z1: max.z,
            k: min.x,
        }));

        Self { min, max, sides }
    }
}

impl Hittable for HittableBox {
    fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord> {
        self.sides.hit(ray, t_min, t_max)
    }

    fn bounding_box(&self, _: f64, _: f64) -> Option<AABB> {
        Some(AABB {
            minimum: self.min.clone(),
            maximum: self.max.clone(),
        })
    }
}