Skip to main content

rapier3d/utils/
dot_product.rs

1//! SimdDot and SimdLength traits for generalized dot product and length.
2
3use crate::math::SimdReal;
4use crate::math::{Real, Vector};
5#[cfg(not(target_arch = "spirv"))]
6use crate::utils::SimdRealCopy;
7#[cfg(not(target_arch = "spirv"))]
8use na::{Vector1, Vector2, Vector3};
9use simba::simd::SimdRealField;
10
11/// Trait for computing generalized dot products.
12pub trait DotProduct<Rhs>: Sized + Copy {
13    /// The result type of the dot product.
14    type Result: SimdRealField;
15    /// Computes the generalized dot product of `self` with `rhs`.
16    fn gdot(&self, rhs: Rhs) -> Self::Result;
17}
18
19/// Trait for computing generalized lengths.
20pub trait SimdLength: DotProduct<Self> {
21    /// Computes the SIMD length of this value.
22    fn simd_length(&self) -> Self::Result {
23        use simba::simd::SimdComplexField;
24        self.gdot(*self).simd_sqrt()
25    }
26}
27
28impl<T: DotProduct<T>> SimdLength for T {}
29
30#[cfg(not(target_arch = "spirv"))]
31impl<N: SimdRealCopy> DotProduct<Vector3<N>> for Vector3<N> {
32    type Result = N;
33
34    fn gdot(&self, rhs: Vector3<N>) -> Self::Result {
35        self.x * rhs.x + self.y * rhs.y + self.z * rhs.z
36    }
37}
38
39#[cfg(not(target_arch = "spirv"))]
40impl<N: SimdRealCopy> DotProduct<Vector2<N>> for Vector2<N> {
41    type Result = N;
42
43    fn gdot(&self, rhs: Vector2<N>) -> Self::Result {
44        self.x * rhs.x + self.y * rhs.y
45    }
46}
47
48#[cfg(not(target_arch = "spirv"))]
49impl<N: SimdRealCopy> DotProduct<Vector1<N>> for N {
50    type Result = N;
51
52    fn gdot(&self, rhs: Vector1<N>) -> Self::Result {
53        *self * rhs.x
54    }
55}
56
57impl DotProduct<Real> for Real {
58    type Result = Real;
59
60    fn gdot(&self, rhs: Real) -> Self::Result {
61        *self * rhs
62    }
63}
64
65impl DotProduct<SimdReal> for SimdReal {
66    type Result = SimdReal;
67
68    fn gdot(&self, rhs: SimdReal) -> Self::Result {
69        *self * rhs
70    }
71}
72
73#[cfg(not(target_arch = "spirv"))]
74impl<N: SimdRealCopy> DotProduct<N> for Vector1<N> {
75    type Result = N;
76
77    fn gdot(&self, rhs: N) -> Self::Result {
78        self.x * rhs
79    }
80}
81
82// Glam implementations for concrete Vector type
83impl DotProduct<Vector> for Vector {
84    type Result = Real;
85
86    fn gdot(&self, rhs: Vector) -> Self::Result {
87        self.dot(rhs)
88    }
89}