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
use crate::{
access,
math::{Dir3, Pos3, Rot3, Vec3},
};
#[derive(Clone)]
pub struct Ray {
pos: Pos3,
dir: Dir3,
}
impl Ray {
access!(pos, pos_mut, Pos3);
access!(dir, dir_mut, Dir3);
#[inline]
#[must_use]
pub fn new(pos: Pos3, mut dir: Dir3) -> Self {
dir.renormalize();
Self { pos, dir }
}
#[inline]
#[must_use]
pub const fn destruct(self) -> (Pos3, Dir3) {
(self.pos, self.dir)
}
#[inline]
pub fn travel(&mut self, dist: f64) {
debug_assert!(dist > 0.0);
self.pos += self.dir.as_ref() * dist;
}
#[inline]
pub fn rotate(&mut self, pitch: f64, roll: f64) {
let arbitrary_axis = if (1.0 - self.dir.z.abs()) >= 1.0e-1 {
Vec3::z_axis()
} else {
Vec3::y_axis()
};
let pitch_axis = Dir3::new_normalize(self.dir.cross(&arbitrary_axis));
let pitch_rot = Rot3::from_axis_angle(&pitch_axis, pitch);
let roll_rot = Rot3::from_axis_angle(&self.dir, roll);
self.dir = roll_rot * pitch_rot * self.dir;
self.dir.renormalize();
}
}