rapier3d/utils/
copysign.rs1use crate::math::Real;
4use crate::math::SimdReal;
5#[cfg(not(target_arch = "spirv"))]
6use na::{Scalar, Vector2, Vector3};
7use simba::simd::SimdRealField;
8
9pub trait CopySign<Rhs>: Sized {
11 fn copy_sign_to(self, to: Rhs) -> Rhs;
14}
15
16impl CopySign<Real> for Real {
17 fn copy_sign_to(self, to: Self) -> Self {
18 const MINUS_ZERO: Real = -0.0;
19 let signbit = MINUS_ZERO.to_bits();
20 Real::from_bits((signbit & self.to_bits()) | ((!signbit) & to.to_bits()))
21 }
22}
23
24#[cfg(not(target_arch = "spirv"))]
25impl<N: Scalar + Copy + CopySign<N>> CopySign<Vector2<N>> for N {
26 fn copy_sign_to(self, to: Vector2<N>) -> Vector2<N> {
27 Vector2::new(self.copy_sign_to(to.x), self.copy_sign_to(to.y))
28 }
29}
30
31#[cfg(not(target_arch = "spirv"))]
32impl<N: Scalar + Copy + CopySign<N>> CopySign<Vector3<N>> for N {
33 fn copy_sign_to(self, to: Vector3<N>) -> Vector3<N> {
34 Vector3::new(
35 self.copy_sign_to(to.x),
36 self.copy_sign_to(to.y),
37 self.copy_sign_to(to.z),
38 )
39 }
40}
41
42#[cfg(not(target_arch = "spirv"))]
43impl<N: Scalar + Copy + CopySign<N>> CopySign<Vector2<N>> for Vector2<N> {
44 fn copy_sign_to(self, to: Vector2<N>) -> Vector2<N> {
45 Vector2::new(self.x.copy_sign_to(to.x), self.y.copy_sign_to(to.y))
46 }
47}
48
49#[cfg(not(target_arch = "spirv"))]
50impl<N: Scalar + Copy + CopySign<N>> CopySign<Vector3<N>> for Vector3<N> {
51 fn copy_sign_to(self, to: Vector3<N>) -> Vector3<N> {
52 Vector3::new(
53 self.x.copy_sign_to(to.x),
54 self.y.copy_sign_to(to.y),
55 self.z.copy_sign_to(to.z),
56 )
57 }
58}
59
60impl CopySign<SimdReal> for SimdReal {
61 fn copy_sign_to(self, to: SimdReal) -> SimdReal {
62 to.simd_copysign(self)
63 }
64}