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