rapier3d/utils/
angular_inertia_ops.rs1use crate::math::SimdReal;
4#[cfg(feature = "dim3")]
5use crate::math::{Matrix, Real, Vector};
6use crate::utils::{SimdRealCopy, simd_inv};
7#[cfg(feature = "dim3")]
8use parry::utils::SdpMatrix3;
9
10pub trait AngularInertiaOps<N>: Copy + core::fmt::Debug + Default {
12 type AngVector;
14 type AngMatrix;
16 fn inverse(&self) -> Self;
18 fn transform_vector(&self, pt: Self::AngVector) -> Self::AngVector;
20 fn into_matrix(self) -> Self::AngMatrix;
22}
23
24impl<N: SimdRealCopy + Default> AngularInertiaOps<N> for N {
25 type AngVector = N;
26 type AngMatrix = N;
27
28 fn inverse(&self) -> Self {
29 simd_inv(*self)
30 }
31
32 fn transform_vector(&self, pt: N) -> N {
33 pt * *self
34 }
35
36 fn into_matrix(self) -> Self::AngMatrix {
37 self
38 }
39}
40
41#[cfg(feature = "dim3")]
42impl AngularInertiaOps<Real> for SdpMatrix3<Real> {
43 type AngVector = Vector;
44 type AngMatrix = Matrix;
45
46 #[inline]
47 fn inverse(&self) -> Self {
48 let minor_m12_m23 = self.m22 * self.m33 - self.m23 * self.m23;
49 let minor_m11_m23 = self.m12 * self.m33 - self.m13 * self.m23;
50 let minor_m11_m22 = self.m12 * self.m23 - self.m13 * self.m22;
51
52 let determinant =
53 self.m11 * minor_m12_m23 - self.m12 * minor_m11_m23 + self.m13 * minor_m11_m22;
54
55 if determinant == 0.0 {
56 Self::zero()
57 } else {
58 SdpMatrix3 {
59 m11: minor_m12_m23 / determinant,
60 m12: -minor_m11_m23 / determinant,
61 m13: minor_m11_m22 / determinant,
62 m22: (self.m11 * self.m33 - self.m13 * self.m13) / determinant,
63 m23: (self.m13 * self.m12 - self.m23 * self.m11) / determinant,
64 m33: (self.m11 * self.m22 - self.m12 * self.m12) / determinant,
65 }
66 }
67 }
68
69 fn transform_vector(&self, v: Vector) -> Vector {
70 let x = self.m11 * v.x + self.m12 * v.y + self.m13 * v.z;
71 let y = self.m12 * v.x + self.m22 * v.y + self.m23 * v.z;
72 let z = self.m13 * v.x + self.m23 * v.y + self.m33 * v.z;
73 Vector::new(x, y, z)
74 }
75
76 #[inline]
77 #[rustfmt::skip]
78 fn into_matrix(self) -> Matrix {
79 Matrix::from_cols_array(&[
80 self.m11, self.m12, self.m13,
81 self.m12, self.m22, self.m23,
82 self.m13, self.m23, self.m33,
83 ])
84 }
85}
86
87impl AngularInertiaOps<SimdReal> for parry::utils::SdpMatrix3<SimdReal> {
88 type AngVector = na::Vector3<SimdReal>;
89 type AngMatrix = na::Matrix3<SimdReal>;
90
91 #[inline]
92 fn inverse(&self) -> Self {
93 self.inverse_unchecked()
94 }
95
96 #[inline]
97 fn transform_vector(&self, v: na::Vector3<SimdReal>) -> na::Vector3<SimdReal> {
98 let x = self.m11 * v.x + self.m12 * v.y + self.m13 * v.z;
99 let y = self.m12 * v.x + self.m22 * v.y + self.m23 * v.z;
100 let z = self.m13 * v.x + self.m23 * v.y + self.m33 * v.z;
101 na::Vector3::new(x, y, z)
102 }
103
104 #[inline]
105 #[rustfmt::skip]
106 fn into_matrix(self) -> na::Matrix3<SimdReal> {
107 na::Matrix3::new(
108 self.m11, self.m12, self.m13,
109 self.m12, self.m22, self.m23,
110 self.m13, self.m23, self.m33,
111 )
112 }
113}