Skip to main content

rapier3d/utils/
cross_product.rs

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