-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplane.rs
56 lines (52 loc) · 1.72 KB
/
plane.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
use crate::{
geo::{Geo, HitResult, HitTemp, Texture, TextureRaw},
linalg::{Ray, Transform, Vct},
Deserialize, Serialize, EPS,
};
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Plane {
pub transform: Transform,
pub texture: Texture,
}
impl Plane {
pub fn new(texture: Texture, transform: Transform) -> Self {
Self { texture, transform }
}
}
impl Geo for Plane {
// calculate t, which means r.origin + r.direct * t is the intersection point
fn hit_t(&self, r: &Ray) -> Option<HitTemp> {
let n = self.transform.z();
let d = n.dot(r.direct);
if d.abs() > EPS {
let t = n.dot(self.transform.pos() - r.origin) / d;
if t > EPS {
return Some((t, None));
}
}
None
}
// return the hit result
fn hit(&self, r: &Ray, tmp: HitTemp) -> HitResult {
let pos = r.origin + r.direct * tmp.0;
let n = self.transform.z();
HitResult {
pos,
norm: if n.dot(r.direct) > 0.0 { n } else { -n },
texture: match self.texture {
Texture::Raw(ref raw) => *raw,
Texture::Image(ref img) => {
let v = pos - self.transform.pos();
let px = self.transform.x().dot(v) * img.width_ratio;
let py = self.transform.y().dot(v) * img.height_ratio;
let col = img.image.get_repeat(px as isize, py as isize);
TextureRaw {
emission: Vct::zero(),
color: Vct::new(col.0, col.1, col.2),
material: img.material,
}
}
},
}
}
}