Skip to main content

rapier2d/utils/
cross_product_matrix.rs

1//! SimdCrossMatrix trait for computing cross product matrices.
2
3#[cfg(feature = "dim3")]
4use crate::math::Matrix;
5#[cfg(feature = "simd-is-enabled")]
6use crate::math::SimdReal;
7use crate::math::{Real, Vector};
8#[cfg(feature = "simd-is-enabled")]
9use crate::num::Zero;
10use crate::utils::SimdRealCopy;
11use na::{Matrix2, Matrix3, Vector2, Vector3};
12
13/// Trait for computing cross product matrices.
14pub trait CrossProductMatrix: Sized {
15    /// The cross product matrix type.
16    type CrossMat;
17    /// The transposed cross product matrix type.
18    type CrossMatTr;
19    /// Returns the cross product matrix of this vector.
20    fn gcross_matrix(self) -> Self::CrossMat;
21    /// Returns the transposed cross product matrix of this vector.
22    fn gcross_matrix_tr(self) -> Self::CrossMatTr;
23}
24
25impl<N: SimdRealCopy> CrossProductMatrix for Vector3<N> {
26    type CrossMat = Matrix3<N>;
27    type CrossMatTr = Matrix3<N>;
28
29    #[inline]
30    #[rustfmt::skip]
31    fn gcross_matrix(self) -> Self::CrossMat {
32        Matrix3::new(
33            N::zero(), -self.z, self.y,
34            self.z, N::zero(), -self.x,
35            -self.y, self.x, N::zero(),
36        )
37    }
38
39    #[inline]
40    #[rustfmt::skip]
41    fn gcross_matrix_tr(self) -> Self::CrossMatTr {
42        Matrix3::new(
43            N::zero(), self.z, -self.y,
44            -self.z, N::zero(), self.x,
45            self.y, -self.x, N::zero(),
46        )
47    }
48}
49
50impl<N: SimdRealCopy> CrossProductMatrix for Vector2<N> {
51    type CrossMat = Vector2<N>;
52    type CrossMatTr = Vector2<N>;
53
54    #[inline]
55    fn gcross_matrix(self) -> Self::CrossMat {
56        Vector2::new(-self.y, self.x)
57    }
58    #[inline]
59    fn gcross_matrix_tr(self) -> Self::CrossMatTr {
60        Vector2::new(-self.y, self.x)
61    }
62}
63impl CrossProductMatrix for Real {
64    type CrossMat = Matrix2<Real>;
65    type CrossMatTr = Matrix2<Real>;
66
67    #[inline]
68    fn gcross_matrix(self) -> Matrix2<Real> {
69        Matrix2::new(0.0, -self, self, 0.0)
70    }
71
72    #[inline]
73    fn gcross_matrix_tr(self) -> Matrix2<Real> {
74        Matrix2::new(0.0, self, -self, 0.0)
75    }
76}
77
78#[cfg(feature = "simd-is-enabled")]
79impl CrossProductMatrix for SimdReal {
80    type CrossMat = Matrix2<SimdReal>;
81    type CrossMatTr = Matrix2<SimdReal>;
82
83    #[inline]
84    fn gcross_matrix(self) -> Matrix2<SimdReal> {
85        Matrix2::new(SimdReal::zero(), -self, self, SimdReal::zero())
86    }
87
88    #[inline]
89    fn gcross_matrix_tr(self) -> Matrix2<SimdReal> {
90        Matrix2::new(SimdReal::zero(), self, -self, SimdReal::zero())
91    }
92}
93
94// Glam implementations for SimdCrossMatrix
95#[cfg(feature = "dim2")]
96impl CrossProductMatrix for Vector {
97    type CrossMat = Vector;
98    type CrossMatTr = Vector;
99
100    #[inline]
101    fn gcross_matrix(self) -> Self::CrossMat {
102        Vector::new(-self.y, self.x)
103    }
104    #[inline]
105    fn gcross_matrix_tr(self) -> Self::CrossMatTr {
106        Vector::new(-self.y, self.x)
107    }
108}
109
110#[cfg(feature = "dim3")]
111impl CrossProductMatrix for Vector {
112    type CrossMat = Matrix;
113    type CrossMatTr = Matrix;
114
115    #[inline]
116    #[rustfmt::skip]
117    fn gcross_matrix(self) -> Self::CrossMat {
118        Matrix::from_cols(
119            Vector::new(0.0, self.z, -self.y),
120            Vector::new(-self.z, 0.0, self.x),
121            Vector::new(self.y, -self.x, 0.0),
122        )
123    }
124
125    #[inline]
126    #[rustfmt::skip]
127    fn gcross_matrix_tr(self) -> Self::CrossMatTr {
128        Matrix::from_cols(
129            Vector::new(0.0, -self.z, self.y),
130            Vector::new(self.z, 0.0, -self.x),
131            Vector::new(-self.y, self.x, 0.0),
132        )
133    }
134}