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
use std::ops;
use nalgebra::Perspective3;
use super::{Aabb, Point, Segment, Triangle, Vector};
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct Transform(nalgebra::Transform<f64, nalgebra::TAffine, 3>);
impl Transform {
pub fn identity() -> Self {
Self(nalgebra::Transform::identity())
}
pub fn translation(vector: impl Into<Vector<3>>) -> Self {
let vector = vector.into();
Self(nalgebra::Transform::from_matrix_unchecked(
nalgebra::OMatrix::new_translation(&vector.to_na()),
))
}
pub fn rotation(axis_angle: impl Into<Vector<3>>) -> Self {
let axis_angle = axis_angle.into();
Self(nalgebra::Transform::from_matrix_unchecked(
nalgebra::OMatrix::<_, nalgebra::Const<4>, _>::new_rotation(
axis_angle.to_na(),
),
))
}
pub fn transform_point(&self, point: &Point<3>) -> Point<3> {
Point::from(self.0.transform_point(&point.to_na()))
}
pub fn inverse_transform_point(&self, point: &Point<3>) -> Point<3> {
Point::from(self.0.inverse_transform_point(&point.to_na()))
}
pub fn transform_vector(&self, vector: &Vector<3>) -> Vector<3> {
Vector::from(self.0.transform_vector(&vector.to_na()))
}
pub fn transform_segment(&self, segment: &Segment<3>) -> Segment<3> {
let [a, b] = &segment.points();
Segment::from([self.transform_point(a), self.transform_point(b)])
}
pub fn transform_triangle(&self, triangle: &Triangle<3>) -> Triangle<3> {
let [a, b, c] = &triangle.points();
Triangle::from([
self.transform_point(a),
self.transform_point(b),
self.transform_point(c),
])
}
pub fn inverse(&self) -> Transform {
Self(self.0.inverse())
}
pub fn transpose(&self) -> Transform {
Self(nalgebra::Transform::from_matrix_unchecked(
self.0.to_homogeneous().transpose(),
))
}
pub fn project_to_slice(
&self,
aspect_ratio: f64,
fovy: f64,
znear: f64,
zfar: f64,
) -> [f64; 16] {
let projection = Perspective3::new(aspect_ratio, fovy, znear, zfar);
let mut res = [0f64; 16];
res.copy_from_slice(
(projection.to_projective() * self.0).matrix().as_slice(),
);
res
}
pub fn transform_aabb(&self, aabb: &Aabb<3>) -> Aabb<3> {
Aabb {
min: self.transform_point(&aabb.min),
max: self.transform_point(&aabb.max),
}
}
pub fn data(&self) -> &[f64] {
self.0.matrix().data.as_slice()
}
}
impl ops::Mul<Self> for Transform {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
Self(self.0.mul(rhs.0))
}
}