lox_frames/transformations/
rotations.rs1use glam::{DMat3, DVec3};
2
3pub fn rotation_matrix_derivative(m: DMat3, v: DVec3) -> DMat3 {
4 let sx = DVec3::new(0.0, v.z, v.y);
5 let sy = DVec3::new(-v.z, 0.0, v.x);
6 let sz = DVec3::new(v.y, -v.x, 0.0);
7 let s = DMat3::from_cols(sx, sy, sz);
8 -s * m
9}
10
11pub struct Rotation {
12 m: DMat3,
13 dm: DMat3,
14}
15
16impl Rotation {
17 pub(crate) const IDENTITY: Self = Self {
18 m: DMat3::IDENTITY,
19 dm: DMat3::ZERO,
20 };
21
22 pub fn new(m: DMat3) -> Self {
23 Self { m, dm: DMat3::ZERO }
24 }
25
26 pub fn with_derivative(mut self, dm: DMat3) -> Self {
27 self.dm = dm;
28 self
29 }
30
31 pub fn with_angular_velocity(mut self, v: DVec3) -> Self {
32 self.dm = rotation_matrix_derivative(self.m, v);
33 self
34 }
35
36 pub fn position_matrix(&self) -> DMat3 {
37 self.m
38 }
39
40 pub fn velocity_matrix(&self) -> DMat3 {
41 self.dm
42 }
43
44 pub fn compose(&self, other: &Self) -> Self {
45 Self {
46 m: other.m * self.m,
47 dm: other.dm * self.m + other.m * self.dm,
48 }
49 }
50
51 pub fn transpose(&self) -> Self {
52 let m = self.m.transpose();
53 let dm = self.dm.transpose();
54 Self { m, dm }
55 }
56
57 pub fn rotate_position(&self, pos: DVec3) -> DVec3 {
58 self.m * pos
59 }
60
61 pub fn rotate_velocity(&self, pos: DVec3, vel: DVec3) -> DVec3 {
62 self.dm * pos + self.m * vel
63 }
64
65 pub fn rotate_state(&self, pos: DVec3, vel: DVec3) -> (DVec3, DVec3) {
66 (self.rotate_position(pos), self.rotate_velocity(pos, vel))
67 }
68}