Skip to main content

rapier2d/utils/
cross_product.rs

1//! SimdCross trait for generalized cross product.
2
3use crate::math::{Real, Vector};
4use na::{SimdRealField, Vector2, Vector3};
5
6/// Trait for computing generalized cross products.
7pub trait CrossProduct<Rhs>: Sized {
8    /// The result type of the cross product.
9    type Result;
10    /// Computes the generalized cross product of `self` with `rhs`.
11    fn gcross(&self, rhs: Rhs) -> Self::Result;
12}
13
14impl<T: SimdRealField + Copy> CrossProduct<Vector3<T>> for Vector3<T> {
15    type Result = Self;
16
17    fn gcross(&self, rhs: Vector3<T>) -> Self::Result {
18        self.cross(&rhs)
19    }
20}
21
22impl<T: SimdRealField + Copy> CrossProduct<Vector2<T>> for Vector2<T> {
23    type Result = T;
24
25    fn gcross(&self, rhs: Vector2<T>) -> Self::Result {
26        self.x * rhs.y - self.y * rhs.x
27    }
28}
29
30impl<T: SimdRealField + Copy> CrossProduct<Vector2<T>> for T {
31    type Result = Vector2<T>;
32
33    fn gcross(&self, rhs: Vector2<T>) -> Self::Result {
34        Vector2::new(-rhs.y * *self, rhs.x * *self)
35    }
36}
37
38impl<T: SimdRealField + Copy> CrossProduct<Vector3<T>> for T {
39    type Result = Vector3<T>;
40
41    fn gcross(&self, _rhs: Vector3<T>) -> Self::Result {
42        unreachable!()
43    }
44}
45
46#[cfg(feature = "dim3")]
47impl CrossProduct<Vector> for Real {
48    type Result = Vector;
49
50    fn gcross(&self, _rhs: Vector) -> Self::Result {
51        todo!("This isn't really used by rapier")
52    }
53}
54
55// Glam implementations for concrete Vector type
56#[cfg(feature = "dim3")]
57impl CrossProduct<Vector> for Vector {
58    type Result = Vector;
59
60    fn gcross(&self, rhs: Vector) -> Self::Result {
61        self.cross(rhs)
62    }
63}
64
65#[cfg(feature = "dim2")]
66impl CrossProduct<Vector> for Vector {
67    type Result = Real;
68
69    fn gcross(&self, rhs: Vector) -> Self::Result {
70        self.x * rhs.y - self.y * rhs.x
71    }
72}
73
74#[cfg(feature = "dim2")]
75impl CrossProduct<Vector> for Real {
76    type Result = Vector;
77
78    fn gcross(&self, rhs: Vector) -> Self::Result {
79        Vector::new(-rhs.y * *self, rhs.x * *self)
80    }
81}