-
Notifications
You must be signed in to change notification settings - Fork 2
/
mod.rs
122 lines (108 loc) · 3.21 KB
/
mod.rs
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use crate::prelude::*;
mod disk;
mod instance;
mod mesh;
mod rect;
mod sphere;
pub use disk::Disk;
pub use instance::Instance;
pub use mesh::{Mesh, MeshTriangleRef};
pub use rect::AARect;
pub use sphere::Sphere;
use crate::hittable::{HasBoundingBox, HitRecord, Hittable, AABB};
macro_rules! generate_aggregate {
($($e:ident),+) => {
#[derive(Clone, Debug)]
pub enum Aggregate {
$(
$e($e),
)+
}
$(
impl From<$e> for Aggregate {
fn from(data: $e) -> Self {
Aggregate::$e(data)
}
}
)+
impl HasBoundingBox for Aggregate {
fn aabb(&self) -> AABB {
match self {
$(
Self::$e(inner) => inner.aabb(),
)+
}
}
}
impl Hittable for Aggregate {
fn hit(&self, r: Ray, t0: f32, t1: f32) -> Option<HitRecord> {
debug_assert!(r.origin.0.is_finite().all());
debug_assert!(r.direction.0.is_finite().all());
debug_assert!(t0.is_finite());
debug_assert!(!t1.is_nan(), "{:?} {:?} {:?}", r, t0, t1);
match self {
$(
Self::$e(inner) => {
// trace!("attempting hit at variant {:?}, ray {:?}, t0 {:?}, t1 {:?}", inner, r, t0, t1);
inner.hit(r, t0, t1)
},
)+
}
}
fn sample(&self, s: Sample2D, from: Point3) -> (Vec3, PDF<f32, SolidAngle>) {
debug_assert!(from.0.is_finite().all());
let pair = match self {
$(
Self::$e(inner) => inner.sample(s, from),
)+
};
debug_assert!((pair.0).0.is_finite().all(), "{:?} {:?}", self, pair.0);
debug_assert!((*pair.1).is_finite());
pair
}
fn sample_surface(&self, s: Sample2D) -> (Point3, Vec3, PDF<f32, Area>) {
let triplet = match self {
$(
Self::$e(inner) => inner.sample_surface(s),
)+
};
debug_assert!((triplet.0).0.is_finite().all());
debug_assert!((triplet.1).0.is_finite().all());
debug_assert!((*triplet.2).is_finite());
triplet
}
fn psa_pdf(&self, cos_o: f32, cos_i: f32, from: Point3, to: Point3) -> PDF<f32, ProjectedSolidAngle> {
debug_assert!(cos_o.is_finite());
debug_assert!(from.0.is_finite().all());
debug_assert!(to.0.is_finite().all());
let pdf = match self {
$(
Self::$e(inner) => inner.psa_pdf(cos_o, cos_i, from, to),
)+
};
debug_assert!(
pdf.is_finite(),
"{:?}, {:?}, {:?}, {:?}, {:?}",
self,
cos_o,
from,
to,
pdf
);
pdf
}
fn surface_area(&self, transform: &Transform3) -> f32 {
let res = match self {
$(
Self::$e(inner) => inner.surface_area(transform),
)+
};
debug_assert!(res.is_finite());
res
}
}
};
}
type Triangle = MeshTriangleRef;
pub type InstanceId = u32;
generate_aggregate! {AARect, Sphere, Disk, Mesh, Triangle}