From 1194a4240802312e76a7f5bc95159478edd60674 Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Wed, 28 Sep 2022 19:05:12 -0700 Subject: [PATCH 1/6] Fix negation and signum to consistently handle negative zero across platforms --- codegen/templates/vec.rs.tera | 19 +++++++++++++------ src/f32/sse2/vec3a.rs | 11 ++++++----- src/f32/sse2/vec4.rs | 11 ++++++----- src/f32/wasm32/vec3a.rs | 9 +++++---- src/f32/wasm32/vec4.rs | 9 +++++---- tests/vec2.rs | 4 +++- tests/vec3.rs | 4 +++- tests/vec4.rs | 4 +++- 8 files changed, 44 insertions(+), 27 deletions(-) diff --git a/codegen/templates/vec.rs.tera b/codegen/templates/vec.rs.tera index a8ca85be..26606a33 100644 --- a/codegen/templates/vec.rs.tera +++ b/codegen/templates/vec.rs.tera @@ -797,11 +797,18 @@ impl {{ self_t }} { } {% elif is_coresimd %} Self(self.0.signum()) - {% else %} - let mask = self.cmpge(Self::ZERO); - let result = Self::select(mask, Self::ONE, Self::NEG_ONE); - let mask = self.is_nan_mask(); - Self::select(mask, self, result) + {% elif is_sse2 %} + unsafe { + let result = Self(_mm_or_ps(_mm_and_ps(self.0, Self::NEG_ONE.0), Self::ONE.0)); + let mask = self.is_nan_mask(); + Self::select(mask, self, result) + } + {% elif is_wasm32 %} + unsafe { + let result = Self(v128_or(v128_and(self.0, Self::NEG_ONE.0), Self::ONE.0)); + let mask = self.is_nan_mask(); + Self::select(mask, self, result) + } {% endif %} } {% endif %} @@ -2021,7 +2028,7 @@ impl Neg for {{ self_t }} { {%- endfor %} } {% elif is_sse2 %} - Self(unsafe { _mm_sub_ps(Self::ZERO.0, self.0) }) + Self(unsafe { _mm_xor_ps(_mm_set1_ps(-0.0), self.0) }) {% elif is_wasm32 %} Self(f32x4_neg(self.0)) {% elif is_coresimd %} diff --git a/src/f32/sse2/vec3a.rs b/src/f32/sse2/vec3a.rs index 1ead0df4..7cd650e6 100644 --- a/src/f32/sse2/vec3a.rs +++ b/src/f32/sse2/vec3a.rs @@ -306,10 +306,11 @@ impl Vec3A { /// - `NAN` if the number is `NAN` #[inline] pub fn signum(self) -> Self { - let mask = self.cmpge(Self::ZERO); - let result = Self::select(mask, Self::ONE, Self::NEG_ONE); - let mask = self.is_nan_mask(); - Self::select(mask, self, result) + unsafe { + let result = Self(_mm_or_ps(_mm_and_ps(self.0, Self::NEG_ONE.0), Self::ONE.0)); + let mask = self.is_nan_mask(); + Self::select(mask, self, result) + } } /// Returns `true` if, and only if, all elements are finite. If any element is either @@ -987,7 +988,7 @@ impl Neg for Vec3A { type Output = Self; #[inline] fn neg(self) -> Self { - Self(unsafe { _mm_sub_ps(Self::ZERO.0, self.0) }) + Self(unsafe { _mm_xor_ps(_mm_set1_ps(-0.0), self.0) }) } } diff --git a/src/f32/sse2/vec4.rs b/src/f32/sse2/vec4.rs index ab645caa..6388e8f8 100644 --- a/src/f32/sse2/vec4.rs +++ b/src/f32/sse2/vec4.rs @@ -281,10 +281,11 @@ impl Vec4 { /// - `NAN` if the number is `NAN` #[inline] pub fn signum(self) -> Self { - let mask = self.cmpge(Self::ZERO); - let result = Self::select(mask, Self::ONE, Self::NEG_ONE); - let mask = self.is_nan_mask(); - Self::select(mask, self, result) + unsafe { + let result = Self(_mm_or_ps(_mm_and_ps(self.0, Self::NEG_ONE.0), Self::ONE.0)); + let mask = self.is_nan_mask(); + Self::select(mask, self, result) + } } /// Returns `true` if, and only if, all elements are finite. If any element is either @@ -900,7 +901,7 @@ impl Neg for Vec4 { type Output = Self; #[inline] fn neg(self) -> Self { - Self(unsafe { _mm_sub_ps(Self::ZERO.0, self.0) }) + Self(unsafe { _mm_xor_ps(_mm_set1_ps(-0.0), self.0) }) } } diff --git a/src/f32/wasm32/vec3a.rs b/src/f32/wasm32/vec3a.rs index cec3c790..6ee487bd 100644 --- a/src/f32/wasm32/vec3a.rs +++ b/src/f32/wasm32/vec3a.rs @@ -287,10 +287,11 @@ impl Vec3A { /// - `NAN` if the number is `NAN` #[inline] pub fn signum(self) -> Self { - let mask = self.cmpge(Self::ZERO); - let result = Self::select(mask, Self::ONE, Self::NEG_ONE); - let mask = self.is_nan_mask(); - Self::select(mask, self, result) + unsafe { + let result = Self(v128_or(v128_and(self.0, Self::NEG_ONE.0), Self::ONE.0)); + let mask = self.is_nan_mask(); + Self::select(mask, self, result) + } } /// Returns `true` if, and only if, all elements are finite. If any element is either diff --git a/src/f32/wasm32/vec4.rs b/src/f32/wasm32/vec4.rs index bc79cc8c..fee64a99 100644 --- a/src/f32/wasm32/vec4.rs +++ b/src/f32/wasm32/vec4.rs @@ -269,10 +269,11 @@ impl Vec4 { /// - `NAN` if the number is `NAN` #[inline] pub fn signum(self) -> Self { - let mask = self.cmpge(Self::ZERO); - let result = Self::select(mask, Self::ONE, Self::NEG_ONE); - let mask = self.is_nan_mask(); - Self::select(mask, self, result) + unsafe { + let result = Self(v128_or(v128_and(self.0, Self::NEG_ONE.0), Self::ONE.0)); + let mask = self.is_nan_mask(); + Self::select(mask, self, result) + } } /// Returns `true` if, and only if, all elements are finite. If any element is either diff --git a/tests/vec2.rs b/tests/vec2.rs index f1659821..ecec1492 100644 --- a/tests/vec2.rs +++ b/tests/vec2.rs @@ -473,6 +473,8 @@ macro_rules! impl_vec2_signed_tests { glam_test!(test_neg, { let a = $new(1 as $t, 2 as $t); assert_eq!($new(-1 as $t, -2 as $t), (-a)); + assert_eq!($new(-0.0 as $t, -0.0 as $t), -$new(0.0 as $t, 0.0 as $t)); + assert_eq!($new(0.0 as $t, -0.0 as $t), -$new(-0.0 as $t, 0.0 as $t)); }); glam_test!(test_perp, { @@ -590,7 +592,7 @@ macro_rules! impl_vec2_float_tests { glam_test!(test_sign, { assert_eq!($vec2::ZERO.signum(), $vec2::ONE); - assert_eq!(-$vec2::ZERO.signum(), -$vec2::ONE); + assert_eq!((-$vec2::ZERO).signum(), -$vec2::ONE); assert_eq!($vec2::ONE.signum(), $vec2::ONE); assert_eq!((-$vec2::ONE).signum(), -$vec2::ONE); assert_eq!($vec2::splat(INFINITY).signum(), $vec2::ONE); diff --git a/tests/vec3.rs b/tests/vec3.rs index 80956d77..c28474ed 100644 --- a/tests/vec3.rs +++ b/tests/vec3.rs @@ -518,6 +518,8 @@ macro_rules! impl_vec3_signed_tests { glam_test!(test_neg, { let a = $new(1 as $t, 2 as $t, 3 as $t); assert_eq!((-1 as $t, -2 as $t, -3 as $t), (-a).into()); + assert_eq!($new(-0.0 as $t, -0.0 as $t, -0.0 as $t), -$new(0.0 as $t, 0.0 as $t, 0.0 as $t)); + assert_eq!($new(0.0 as $t, -0.0 as $t, -0.0 as $t), -$new(-0.0 as $t, 0.0 as $t, 0.0 as $t)); }); glam_test!(test_dot_signed, { @@ -643,7 +645,7 @@ macro_rules! impl_vec3_float_tests { glam_test!(test_signum, { assert_eq!($vec3::ZERO.signum(), $vec3::ONE); - assert_eq!(-$vec3::ZERO.signum(), -$vec3::ONE); + assert_eq!((-$vec3::ZERO).signum(), -$vec3::ONE); assert_eq!($vec3::ONE.signum(), $vec3::ONE); assert_eq!((-$vec3::ONE).signum(), -$vec3::ONE); assert_eq!($vec3::splat(INFINITY).signum(), $vec3::ONE); diff --git a/tests/vec4.rs b/tests/vec4.rs index 60b282a5..a7b119f1 100644 --- a/tests/vec4.rs +++ b/tests/vec4.rs @@ -593,6 +593,8 @@ macro_rules! impl_vec4_signed_tests { glam_test!(test_neg, { let a = $new(1 as $t, 2 as $t, 3 as $t, 4 as $t); assert_eq!((-1 as $t, -2 as $t, -3 as $t, -4 as $t), (-a).into()); + assert_eq!($new(-0.0 as $t, -0.0 as $t, -0.0 as $t, -0.0 as $t), -$new(0.0 as $t, 0.0 as $t, 0.0 as $t, 0.0 as $t)); + assert_eq!($new(0.0 as $t, -0.0 as $t, -0.0 as $t, -0.0 as $t), -$new(-0.0 as $t, 0.0 as $t, 0.0 as $t, 0.0 as $t)); }); glam_test!(test_dot_signed, { @@ -725,7 +727,7 @@ macro_rules! impl_vec4_float_tests { glam_test!(test_signum, { assert_eq!($vec4::ZERO.signum(), $vec4::ONE); - assert_eq!(-$vec4::ZERO.signum(), -$vec4::ONE); + assert_eq!((-$vec4::ZERO).signum(), -$vec4::ONE); assert_eq!($vec4::ONE.signum(), $vec4::ONE); assert_eq!((-$vec4::ONE).signum(), -$vec4::ONE); assert_eq!($vec4::splat(INFINITY).signum(), $vec4::ONE); From b34fe86cd939379d04c49dbc2723ab8ffc35799f Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Wed, 28 Sep 2022 19:14:19 -0700 Subject: [PATCH 2/6] Add sign_bits and tests --- codegen/templates/vec.rs.tera | 43 +++++++++++++++++++++++++++++++++++ src/f32/coresimd/vec3a.rs | 9 ++++++++ src/f32/coresimd/vec4.rs | 9 ++++++++ src/f32/scalar/vec3a.rs | 11 +++++++++ src/f32/scalar/vec4.rs | 12 ++++++++++ src/f32/sse2/vec3a.rs | 9 ++++++++ src/f32/sse2/vec4.rs | 9 ++++++++ src/f32/vec2.rs | 9 ++++++++ src/f32/vec3.rs | 11 +++++++++ src/f32/wasm32/vec3a.rs | 9 ++++++++ src/f32/wasm32/vec4.rs | 9 ++++++++ src/f64/dvec2.rs | 9 ++++++++ src/f64/dvec3.rs | 11 +++++++++ src/f64/dvec4.rs | 12 ++++++++++ src/i32/ivec2.rs | 9 ++++++++ src/i32/ivec3.rs | 11 +++++++++ src/i32/ivec4.rs | 12 ++++++++++ tests/vec2.rs | 11 +++++++++ tests/vec3.rs | 12 ++++++++++ tests/vec4.rs | 12 ++++++++++ 20 files changed, 239 insertions(+) diff --git a/codegen/templates/vec.rs.tera b/codegen/templates/vec.rs.tera index 26606a33..f36e0e63 100644 --- a/codegen/templates/vec.rs.tera +++ b/codegen/templates/vec.rs.tera @@ -811,6 +811,49 @@ impl {{ self_t }} { } {% endif %} } + + /// Returns a bitmask with the lowest {{ dim }} bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + {% if is_scalar and is_float %} + {% for c in components %} + {% if loop.first %} + (self.{{ c }}.is_sign_negative() as u32) | + {% else %} + (self.{{ c }}.is_sign_negative() as u32) << {{ loop.index0 }} {% if not loop.last %} | {% endif %} + {% endif %} + {% endfor %} + {% elif is_scalar %} + {% for c in components %} + {% if loop.first %} + (self.{{ c }}.is_negative() as u32) | + {% else %} + (self.{{ c }}.is_negative() as u32) << {{ loop.index0 }} {% if not loop.last %} | {% endif %} + {% endif %} + {% endfor %} + {% elif is_sse2 %} + {% if dim == 3 %} + unsafe { (_mm_movemask_ps(self.0) as u32) & 0x7 } + {% elif dim == 4 %} + unsafe { _mm_movemask_ps(self.0) as u32 } + {% endif %} + {% elif is_wasm32 %} + {% if dim == 3 %} + (u32x4_bitmask(self.0) & 0x7) as u32 + {% elif dim == 4 %} + u32x4_bitmask(self.0) as u32 + {% endif %} + {% elif is_coresimd %} + {% if dim == 3 %} + (self.0.to_bitmask() & 0x7) as u32 + {% elif dim == 4 %} + self.0.to_bitmask() as u32 + {% endif %} + {% endif %} + } {% endif %} {% if is_float %} diff --git a/src/f32/coresimd/vec3a.rs b/src/f32/coresimd/vec3a.rs index 5215abb0..0d105e8e 100644 --- a/src/f32/coresimd/vec3a.rs +++ b/src/f32/coresimd/vec3a.rs @@ -286,6 +286,15 @@ impl Vec3A { Self(self.0.signum()) } + /// Returns a bitmask with the lowest 3 bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + (self.0.to_bitmask() & 0x7) as u32 + } + /// Returns `true` if, and only if, all elements are finite. If any element is either /// `NaN`, positive or negative infinity, this will return `false`. #[inline] diff --git a/src/f32/coresimd/vec4.rs b/src/f32/coresimd/vec4.rs index 03e5abe9..2d06f225 100644 --- a/src/f32/coresimd/vec4.rs +++ b/src/f32/coresimd/vec4.rs @@ -262,6 +262,15 @@ impl Vec4 { Self(self.0.signum()) } + /// Returns a bitmask with the lowest 4 bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + self.0.to_bitmask() as u32 + } + /// Returns `true` if, and only if, all elements are finite. If any element is either /// `NaN`, positive or negative infinity, this will return `false`. #[inline] diff --git a/src/f32/scalar/vec3a.rs b/src/f32/scalar/vec3a.rs index 71b9ebd9..c0ecca41 100644 --- a/src/f32/scalar/vec3a.rs +++ b/src/f32/scalar/vec3a.rs @@ -306,6 +306,17 @@ impl Vec3A { } } + /// Returns a bitmask with the lowest 3 bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + (self.x.is_sign_negative() as u32) + | (self.y.is_sign_negative() as u32) << 1 + | (self.z.is_sign_negative() as u32) << 2 + } + /// Returns `true` if, and only if, all elements are finite. If any element is either /// `NaN`, positive or negative infinity, this will return `false`. #[inline] diff --git a/src/f32/scalar/vec4.rs b/src/f32/scalar/vec4.rs index 7facd6cb..366985f8 100644 --- a/src/f32/scalar/vec4.rs +++ b/src/f32/scalar/vec4.rs @@ -333,6 +333,18 @@ impl Vec4 { } } + /// Returns a bitmask with the lowest 4 bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + (self.x.is_sign_negative() as u32) + | (self.y.is_sign_negative() as u32) << 1 + | (self.z.is_sign_negative() as u32) << 2 + | (self.w.is_sign_negative() as u32) << 3 + } + /// Returns `true` if, and only if, all elements are finite. If any element is either /// `NaN`, positive or negative infinity, this will return `false`. #[inline] diff --git a/src/f32/sse2/vec3a.rs b/src/f32/sse2/vec3a.rs index 7cd650e6..3d5036c5 100644 --- a/src/f32/sse2/vec3a.rs +++ b/src/f32/sse2/vec3a.rs @@ -313,6 +313,15 @@ impl Vec3A { } } + /// Returns a bitmask with the lowest 3 bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + unsafe { (_mm_movemask_ps(self.0) as u32) & 0x7 } + } + /// Returns `true` if, and only if, all elements are finite. If any element is either /// `NaN`, positive or negative infinity, this will return `false`. #[inline] diff --git a/src/f32/sse2/vec4.rs b/src/f32/sse2/vec4.rs index 6388e8f8..517eed3c 100644 --- a/src/f32/sse2/vec4.rs +++ b/src/f32/sse2/vec4.rs @@ -288,6 +288,15 @@ impl Vec4 { } } + /// Returns a bitmask with the lowest 4 bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + unsafe { _mm_movemask_ps(self.0) as u32 } + } + /// Returns `true` if, and only if, all elements are finite. If any element is either /// `NaN`, positive or negative infinity, this will return `false`. #[inline] diff --git a/src/f32/vec2.rs b/src/f32/vec2.rs index 7c275ebb..b4bf46b5 100644 --- a/src/f32/vec2.rs +++ b/src/f32/vec2.rs @@ -258,6 +258,15 @@ impl Vec2 { } } + /// Returns a bitmask with the lowest 2 bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + (self.x.is_sign_negative() as u32) | (self.y.is_sign_negative() as u32) << 1 + } + /// Returns `true` if, and only if, all elements are finite. If any element is either /// `NaN`, positive or negative infinity, this will return `false`. #[inline] diff --git a/src/f32/vec3.rs b/src/f32/vec3.rs index df0ae09a..87ccdb19 100644 --- a/src/f32/vec3.rs +++ b/src/f32/vec3.rs @@ -300,6 +300,17 @@ impl Vec3 { } } + /// Returns a bitmask with the lowest 3 bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + (self.x.is_sign_negative() as u32) + | (self.y.is_sign_negative() as u32) << 1 + | (self.z.is_sign_negative() as u32) << 2 + } + /// Returns `true` if, and only if, all elements are finite. If any element is either /// `NaN`, positive or negative infinity, this will return `false`. #[inline] diff --git a/src/f32/wasm32/vec3a.rs b/src/f32/wasm32/vec3a.rs index 6ee487bd..835aa169 100644 --- a/src/f32/wasm32/vec3a.rs +++ b/src/f32/wasm32/vec3a.rs @@ -294,6 +294,15 @@ impl Vec3A { } } + /// Returns a bitmask with the lowest 3 bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + (u32x4_bitmask(self.0) & 0x7) as u32 + } + /// Returns `true` if, and only if, all elements are finite. If any element is either /// `NaN`, positive or negative infinity, this will return `false`. #[inline] diff --git a/src/f32/wasm32/vec4.rs b/src/f32/wasm32/vec4.rs index fee64a99..46d97107 100644 --- a/src/f32/wasm32/vec4.rs +++ b/src/f32/wasm32/vec4.rs @@ -276,6 +276,15 @@ impl Vec4 { } } + /// Returns a bitmask with the lowest 4 bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + u32x4_bitmask(self.0) as u32 + } + /// Returns `true` if, and only if, all elements are finite. If any element is either /// `NaN`, positive or negative infinity, this will return `false`. #[inline] diff --git a/src/f64/dvec2.rs b/src/f64/dvec2.rs index 205dca2e..b9ed4552 100644 --- a/src/f64/dvec2.rs +++ b/src/f64/dvec2.rs @@ -258,6 +258,15 @@ impl DVec2 { } } + /// Returns a bitmask with the lowest 2 bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + (self.x.is_sign_negative() as u32) | (self.y.is_sign_negative() as u32) << 1 + } + /// Returns `true` if, and only if, all elements are finite. If any element is either /// `NaN`, positive or negative infinity, this will return `false`. #[inline] diff --git a/src/f64/dvec3.rs b/src/f64/dvec3.rs index 2251a28c..9f06e9c3 100644 --- a/src/f64/dvec3.rs +++ b/src/f64/dvec3.rs @@ -300,6 +300,17 @@ impl DVec3 { } } + /// Returns a bitmask with the lowest 3 bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + (self.x.is_sign_negative() as u32) + | (self.y.is_sign_negative() as u32) << 1 + | (self.z.is_sign_negative() as u32) << 2 + } + /// Returns `true` if, and only if, all elements are finite. If any element is either /// `NaN`, positive or negative infinity, this will return `false`. #[inline] diff --git a/src/f64/dvec4.rs b/src/f64/dvec4.rs index 132b8a80..aa86ee17 100644 --- a/src/f64/dvec4.rs +++ b/src/f64/dvec4.rs @@ -325,6 +325,18 @@ impl DVec4 { } } + /// Returns a bitmask with the lowest 4 bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + (self.x.is_sign_negative() as u32) + | (self.y.is_sign_negative() as u32) << 1 + | (self.z.is_sign_negative() as u32) << 2 + | (self.w.is_sign_negative() as u32) << 3 + } + /// Returns `true` if, and only if, all elements are finite. If any element is either /// `NaN`, positive or negative infinity, this will return `false`. #[inline] diff --git a/src/i32/ivec2.rs b/src/i32/ivec2.rs index 4ad537b5..e9be80e4 100644 --- a/src/i32/ivec2.rs +++ b/src/i32/ivec2.rs @@ -252,6 +252,15 @@ impl IVec2 { } } + /// Returns a bitmask with the lowest 2 bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + (self.x.is_negative() as u32) | (self.y.is_negative() as u32) << 1 + } + /// Returns a vector that is equal to `self` rotated by 90 degrees. #[inline] pub fn perp(self) -> Self { diff --git a/src/i32/ivec3.rs b/src/i32/ivec3.rs index 0019b515..f8e90c53 100644 --- a/src/i32/ivec3.rs +++ b/src/i32/ivec3.rs @@ -294,6 +294,17 @@ impl IVec3 { } } + /// Returns a bitmask with the lowest 3 bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + (self.x.is_negative() as u32) + | (self.y.is_negative() as u32) << 1 + | (self.z.is_negative() as u32) << 2 + } + /// Casts all elements of `self` to `f32`. #[inline] pub fn as_vec3(&self) -> crate::Vec3 { diff --git a/src/i32/ivec4.rs b/src/i32/ivec4.rs index 53e90ac0..4f7c8a5c 100644 --- a/src/i32/ivec4.rs +++ b/src/i32/ivec4.rs @@ -319,6 +319,18 @@ impl IVec4 { } } + /// Returns a bitmask with the lowest 4 bits set to the sign bits from the elements of `self`. + /// + /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes + /// into the first lowest bit, element `y` into the second, etc. + #[inline] + pub fn sign_bits(self) -> u32 { + (self.x.is_negative() as u32) + | (self.y.is_negative() as u32) << 1 + | (self.z.is_negative() as u32) << 2 + | (self.w.is_negative() as u32) << 3 + } + /// Casts all elements of `self` to `f32`. #[inline] pub fn as_vec4(&self) -> crate::Vec4 { diff --git a/tests/vec2.rs b/tests/vec2.rs index ecec1492..9cd3218c 100644 --- a/tests/vec2.rs +++ b/tests/vec2.rs @@ -600,6 +600,17 @@ macro_rules! impl_vec2_float_tests { assert!($vec2::splat(NAN).signum().is_nan_mask().all()); }); + glam_test!(test_sign_bits, { + assert_eq!($vec2::ZERO.sign_bits(), 0b00); + assert_eq!((-$vec2::ZERO).sign_bits(), 0b11); + assert_eq!($vec2::ONE.sign_bits(), 0b00); + assert_eq!((-$vec2::ONE).sign_bits(), 0b11); + assert_eq!($vec2::new(-0.1,0.2).sign_bits(), 0b01); + assert_eq!($vec2::new(0.8,0.3).sign_bits(), 0b00); + assert_eq!($vec2::new(0.3,-0.4).sign_bits(), 0b10); + assert_eq!($vec2::new(-0.2,-0.6).sign_bits(), 0b11); + }); + glam_test!(test_abs, { assert_eq!($vec2::ZERO.abs(), $vec2::ZERO); assert_eq!($vec2::ONE.abs(), $vec2::ONE); diff --git a/tests/vec3.rs b/tests/vec3.rs index c28474ed..bbf12c98 100644 --- a/tests/vec3.rs +++ b/tests/vec3.rs @@ -653,6 +653,18 @@ macro_rules! impl_vec3_float_tests { assert!($vec3::splat(NAN).signum().is_nan_mask().all()); }); + glam_test!(test_sign_bits, { + assert_eq!($vec3::ZERO.sign_bits(), 0b000); + assert_eq!((-$vec3::ZERO).sign_bits(), 0b111); + assert_eq!($vec3::ONE.sign_bits(), 0b000); + assert_eq!((-$vec3::ONE).sign_bits(), 0b111); + assert_eq!($vec3::new(-0.1,0.2,0.3).sign_bits(), 0b001); + assert_eq!($vec3::new(0.8,0.3,0.1).sign_bits(), 0b000); + assert_eq!($vec3::new(0.1,0.5,-0.3).sign_bits(), 0b100); + assert_eq!($vec3::new(0.3,-0.4,0.1).sign_bits(), 0b010); + assert_eq!($vec3::new(-0.2,0.6,-0.5).sign_bits(), 0b101); + }); + glam_test!(test_abs, { assert_eq!($vec3::ZERO.abs(), $vec3::ZERO); assert_eq!($vec3::ONE.abs(), $vec3::ONE); diff --git a/tests/vec4.rs b/tests/vec4.rs index a7b119f1..447b23d6 100644 --- a/tests/vec4.rs +++ b/tests/vec4.rs @@ -734,6 +734,18 @@ macro_rules! impl_vec4_float_tests { assert_eq!($vec4::splat(NEG_INFINITY).signum(), -$vec4::ONE); assert!($vec4::splat(NAN).signum().is_nan_mask().all()); }); + + glam_test!(test_sign_bits, { + assert_eq!($vec4::ZERO.sign_bits(), 0b0000); + assert_eq!((-$vec4::ZERO).sign_bits(), 0b1111); + assert_eq!($vec4::ONE.sign_bits(), 0b0000); + assert_eq!((-$vec4::ONE).sign_bits(), 0b1111); + assert_eq!($vec4::new(-0.1,0.2,0.3,-0.4).sign_bits(), 0b1001); + assert_eq!($vec4::new(0.8,0.3,0.1,-0.0).sign_bits(), 0b1000); + assert_eq!($vec4::new(0.1,0.5,-0.3,0.7).sign_bits(), 0b0100); + assert_eq!($vec4::new(0.3,-0.4,0.1,0.6).sign_bits(), 0b0010); + assert_eq!($vec4::new(0.2,-0.6,0.5,-0.3).sign_bits(), 0b1010); + }); glam_test!(test_abs, { assert_eq!($vec4::ZERO.abs(), $vec4::ZERO); From b36eb20b7c32731f98026715b428db57cbd85c60 Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Thu, 29 Sep 2022 23:39:20 -0700 Subject: [PATCH 3/6] rustfmt --- tests/vec2.rs | 8 ++++---- tests/vec3.rs | 10 +++++----- tests/vec4.rs | 12 ++++++------ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/vec2.rs b/tests/vec2.rs index fd04b436..c7aa1d5c 100644 --- a/tests/vec2.rs +++ b/tests/vec2.rs @@ -611,10 +611,10 @@ macro_rules! impl_vec2_float_tests { assert_eq!((-$vec2::ZERO).sign_bits(), 0b11); assert_eq!($vec2::ONE.sign_bits(), 0b00); assert_eq!((-$vec2::ONE).sign_bits(), 0b11); - assert_eq!($vec2::new(-0.1,0.2).sign_bits(), 0b01); - assert_eq!($vec2::new(0.8,0.3).sign_bits(), 0b00); - assert_eq!($vec2::new(0.3,-0.4).sign_bits(), 0b10); - assert_eq!($vec2::new(-0.2,-0.6).sign_bits(), 0b11); + assert_eq!($vec2::new(-0.1, 0.2).sign_bits(), 0b01); + assert_eq!($vec2::new(0.8, 0.3).sign_bits(), 0b00); + assert_eq!($vec2::new(0.3, -0.4).sign_bits(), 0b10); + assert_eq!($vec2::new(-0.2, -0.6).sign_bits(), 0b11); }); glam_test!(test_abs, { diff --git a/tests/vec3.rs b/tests/vec3.rs index dd3520cb..23278087 100644 --- a/tests/vec3.rs +++ b/tests/vec3.rs @@ -673,11 +673,11 @@ macro_rules! impl_vec3_float_tests { assert_eq!((-$vec3::ZERO).sign_bits(), 0b111); assert_eq!($vec3::ONE.sign_bits(), 0b000); assert_eq!((-$vec3::ONE).sign_bits(), 0b111); - assert_eq!($vec3::new(-0.1,0.2,0.3).sign_bits(), 0b001); - assert_eq!($vec3::new(0.8,0.3,0.1).sign_bits(), 0b000); - assert_eq!($vec3::new(0.1,0.5,-0.3).sign_bits(), 0b100); - assert_eq!($vec3::new(0.3,-0.4,0.1).sign_bits(), 0b010); - assert_eq!($vec3::new(-0.2,0.6,-0.5).sign_bits(), 0b101); + assert_eq!($vec3::new(-0.1, 0.2, 0.3).sign_bits(), 0b001); + assert_eq!($vec3::new(0.8, 0.3, 0.1).sign_bits(), 0b000); + assert_eq!($vec3::new(0.1, 0.5, -0.3).sign_bits(), 0b100); + assert_eq!($vec3::new(0.3, -0.4, 0.1).sign_bits(), 0b010); + assert_eq!($vec3::new(-0.2, 0.6, -0.5).sign_bits(), 0b101); }); glam_test!(test_abs, { diff --git a/tests/vec4.rs b/tests/vec4.rs index 6b6175a6..a4333b85 100644 --- a/tests/vec4.rs +++ b/tests/vec4.rs @@ -749,17 +749,17 @@ macro_rules! impl_vec4_float_tests { assert_eq!($vec4::splat(NEG_INFINITY).signum(), -$vec4::ONE); assert!($vec4::splat(NAN).signum().is_nan_mask().all()); }); - + glam_test!(test_sign_bits, { assert_eq!($vec4::ZERO.sign_bits(), 0b0000); assert_eq!((-$vec4::ZERO).sign_bits(), 0b1111); assert_eq!($vec4::ONE.sign_bits(), 0b0000); assert_eq!((-$vec4::ONE).sign_bits(), 0b1111); - assert_eq!($vec4::new(-0.1,0.2,0.3,-0.4).sign_bits(), 0b1001); - assert_eq!($vec4::new(0.8,0.3,0.1,-0.0).sign_bits(), 0b1000); - assert_eq!($vec4::new(0.1,0.5,-0.3,0.7).sign_bits(), 0b0100); - assert_eq!($vec4::new(0.3,-0.4,0.1,0.6).sign_bits(), 0b0010); - assert_eq!($vec4::new(0.2,-0.6,0.5,-0.3).sign_bits(), 0b1010); + assert_eq!($vec4::new(-0.1, 0.2, 0.3, -0.4).sign_bits(), 0b1001); + assert_eq!($vec4::new(0.8, 0.3, 0.1, -0.0).sign_bits(), 0b1000); + assert_eq!($vec4::new(0.1, 0.5, -0.3, 0.7).sign_bits(), 0b0100); + assert_eq!($vec4::new(0.3, -0.4, 0.1, 0.6).sign_bits(), 0b0010); + assert_eq!($vec4::new(0.2, -0.6, 0.5, -0.3).sign_bits(), 0b1010); }); glam_test!(test_abs, { From d6e4341621edb6b6bfbae493f729e28e381ab182 Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Fri, 30 Sep 2022 06:35:43 -0700 Subject: [PATCH 4/6] Try to fix coresimd --- codegen/templates/vec.rs.tera | 4 ++-- src/f32/coresimd/vec3a.rs | 2 +- src/f32/coresimd/vec4.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/codegen/templates/vec.rs.tera b/codegen/templates/vec.rs.tera index bd09e06c..34f71c71 100644 --- a/codegen/templates/vec.rs.tera +++ b/codegen/templates/vec.rs.tera @@ -862,9 +862,9 @@ impl {{ self_t }} { {% endif %} {% elif is_coresimd %} {% if dim == 3 %} - (self.0.to_bitmask() & 0x7) as u32 + (self.0.is_sign_negative().to_bitmask() & 0x7) as u32 {% elif dim == 4 %} - self.0.to_bitmask() as u32 + self.0.is_sign_negative().to_bitmask() as u32 {% endif %} {% endif %} } diff --git a/src/f32/coresimd/vec3a.rs b/src/f32/coresimd/vec3a.rs index 37e2e307..48d89f04 100644 --- a/src/f32/coresimd/vec3a.rs +++ b/src/f32/coresimd/vec3a.rs @@ -298,7 +298,7 @@ impl Vec3A { /// into the first lowest bit, element `y` into the second, etc. #[inline] pub fn sign_bits(self) -> u32 { - (self.0.to_bitmask() & 0x7) as u32 + (self.0.is_sign_negative().to_bitmask() & 0x7) as u32 } /// Returns `true` if, and only if, all elements are finite. If any element is either diff --git a/src/f32/coresimd/vec4.rs b/src/f32/coresimd/vec4.rs index 1971b877..36a7973c 100644 --- a/src/f32/coresimd/vec4.rs +++ b/src/f32/coresimd/vec4.rs @@ -274,7 +274,7 @@ impl Vec4 { /// into the first lowest bit, element `y` into the second, etc. #[inline] pub fn sign_bits(self) -> u32 { - self.0.to_bitmask() as u32 + self.0.is_sign_negative().to_bitmask() as u32 } /// Returns `true` if, and only if, all elements are finite. If any element is either From e716c95aa57338fcaa2a85dc698eb6c9e4de4ebc Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Fri, 30 Sep 2022 20:42:12 -0700 Subject: [PATCH 5/6] rename sign_bits to is_negative_bitmask --- codegen/templates/vec.rs.tera | 2 +- src/f32/coresimd/vec3a.rs | 2 +- src/f32/coresimd/vec4.rs | 2 +- src/f32/scalar/vec3a.rs | 2 +- src/f32/scalar/vec4.rs | 2 +- src/f32/sse2/vec3a.rs | 2 +- src/f32/sse2/vec4.rs | 2 +- src/f32/vec2.rs | 2 +- src/f32/vec3.rs | 2 +- src/f32/wasm32/vec3a.rs | 2 +- src/f32/wasm32/vec4.rs | 2 +- src/f64/dvec2.rs | 2 +- src/f64/dvec3.rs | 2 +- src/f64/dvec4.rs | 2 +- src/i32/ivec2.rs | 2 +- src/i32/ivec3.rs | 2 +- src/i32/ivec4.rs | 2 +- tests/vec2.rs | 18 +++++++++--------- tests/vec3.rs | 20 ++++++++++---------- tests/vec4.rs | 20 ++++++++++---------- 20 files changed, 46 insertions(+), 46 deletions(-) diff --git a/codegen/templates/vec.rs.tera b/codegen/templates/vec.rs.tera index 34f71c71..425262eb 100644 --- a/codegen/templates/vec.rs.tera +++ b/codegen/templates/vec.rs.tera @@ -831,7 +831,7 @@ impl {{ self_t }} { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { {% if is_scalar and is_float %} {% for c in components %} {% if loop.first %} diff --git a/src/f32/coresimd/vec3a.rs b/src/f32/coresimd/vec3a.rs index 48d89f04..71f5c646 100644 --- a/src/f32/coresimd/vec3a.rs +++ b/src/f32/coresimd/vec3a.rs @@ -297,7 +297,7 @@ impl Vec3A { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { (self.0.is_sign_negative().to_bitmask() & 0x7) as u32 } diff --git a/src/f32/coresimd/vec4.rs b/src/f32/coresimd/vec4.rs index 36a7973c..fa92f936 100644 --- a/src/f32/coresimd/vec4.rs +++ b/src/f32/coresimd/vec4.rs @@ -273,7 +273,7 @@ impl Vec4 { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { self.0.is_sign_negative().to_bitmask() as u32 } diff --git a/src/f32/scalar/vec3a.rs b/src/f32/scalar/vec3a.rs index 42225bdf..26b82b66 100644 --- a/src/f32/scalar/vec3a.rs +++ b/src/f32/scalar/vec3a.rs @@ -317,7 +317,7 @@ impl Vec3A { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { (self.x.is_sign_negative() as u32) | (self.y.is_sign_negative() as u32) << 1 | (self.z.is_sign_negative() as u32) << 2 diff --git a/src/f32/scalar/vec4.rs b/src/f32/scalar/vec4.rs index 345e4a36..6abcccd7 100644 --- a/src/f32/scalar/vec4.rs +++ b/src/f32/scalar/vec4.rs @@ -344,7 +344,7 @@ impl Vec4 { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { (self.x.is_sign_negative() as u32) | (self.y.is_sign_negative() as u32) << 1 | (self.z.is_sign_negative() as u32) << 2 diff --git a/src/f32/sse2/vec3a.rs b/src/f32/sse2/vec3a.rs index ce545d23..56b8c8d6 100644 --- a/src/f32/sse2/vec3a.rs +++ b/src/f32/sse2/vec3a.rs @@ -324,7 +324,7 @@ impl Vec3A { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { unsafe { (_mm_movemask_ps(self.0) as u32) & 0x7 } } diff --git a/src/f32/sse2/vec4.rs b/src/f32/sse2/vec4.rs index 3a2673aa..f72e0277 100644 --- a/src/f32/sse2/vec4.rs +++ b/src/f32/sse2/vec4.rs @@ -299,7 +299,7 @@ impl Vec4 { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { unsafe { _mm_movemask_ps(self.0) as u32 } } diff --git a/src/f32/vec2.rs b/src/f32/vec2.rs index e36355c6..13181e19 100644 --- a/src/f32/vec2.rs +++ b/src/f32/vec2.rs @@ -269,7 +269,7 @@ impl Vec2 { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { (self.x.is_sign_negative() as u32) | (self.y.is_sign_negative() as u32) << 1 } diff --git a/src/f32/vec3.rs b/src/f32/vec3.rs index 55faf368..56062638 100644 --- a/src/f32/vec3.rs +++ b/src/f32/vec3.rs @@ -311,7 +311,7 @@ impl Vec3 { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { (self.x.is_sign_negative() as u32) | (self.y.is_sign_negative() as u32) << 1 | (self.z.is_sign_negative() as u32) << 2 diff --git a/src/f32/wasm32/vec3a.rs b/src/f32/wasm32/vec3a.rs index b429fee7..08a6269f 100644 --- a/src/f32/wasm32/vec3a.rs +++ b/src/f32/wasm32/vec3a.rs @@ -305,7 +305,7 @@ impl Vec3A { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { (u32x4_bitmask(self.0) & 0x7) as u32 } diff --git a/src/f32/wasm32/vec4.rs b/src/f32/wasm32/vec4.rs index a7eae9ce..de16f666 100644 --- a/src/f32/wasm32/vec4.rs +++ b/src/f32/wasm32/vec4.rs @@ -287,7 +287,7 @@ impl Vec4 { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { u32x4_bitmask(self.0) as u32 } diff --git a/src/f64/dvec2.rs b/src/f64/dvec2.rs index cbf609e0..42039e98 100644 --- a/src/f64/dvec2.rs +++ b/src/f64/dvec2.rs @@ -269,7 +269,7 @@ impl DVec2 { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { (self.x.is_sign_negative() as u32) | (self.y.is_sign_negative() as u32) << 1 } diff --git a/src/f64/dvec3.rs b/src/f64/dvec3.rs index 42cb8b3a..0260d42f 100644 --- a/src/f64/dvec3.rs +++ b/src/f64/dvec3.rs @@ -311,7 +311,7 @@ impl DVec3 { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { (self.x.is_sign_negative() as u32) | (self.y.is_sign_negative() as u32) << 1 | (self.z.is_sign_negative() as u32) << 2 diff --git a/src/f64/dvec4.rs b/src/f64/dvec4.rs index b821eff0..50d49b45 100644 --- a/src/f64/dvec4.rs +++ b/src/f64/dvec4.rs @@ -336,7 +336,7 @@ impl DVec4 { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { (self.x.is_sign_negative() as u32) | (self.y.is_sign_negative() as u32) << 1 | (self.z.is_sign_negative() as u32) << 2 diff --git a/src/i32/ivec2.rs b/src/i32/ivec2.rs index 1fd466dd..599f4f59 100644 --- a/src/i32/ivec2.rs +++ b/src/i32/ivec2.rs @@ -263,7 +263,7 @@ impl IVec2 { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { (self.x.is_negative() as u32) | (self.y.is_negative() as u32) << 1 } diff --git a/src/i32/ivec3.rs b/src/i32/ivec3.rs index 211dcf75..7a87a304 100644 --- a/src/i32/ivec3.rs +++ b/src/i32/ivec3.rs @@ -305,7 +305,7 @@ impl IVec3 { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { (self.x.is_negative() as u32) | (self.y.is_negative() as u32) << 1 | (self.z.is_negative() as u32) << 2 diff --git a/src/i32/ivec4.rs b/src/i32/ivec4.rs index 1ae59e90..157cf05c 100644 --- a/src/i32/ivec4.rs +++ b/src/i32/ivec4.rs @@ -330,7 +330,7 @@ impl IVec4 { /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes /// into the first lowest bit, element `y` into the second, etc. #[inline] - pub fn sign_bits(self) -> u32 { + pub fn is_negative_bitmask(self) -> u32 { (self.x.is_negative() as u32) | (self.y.is_negative() as u32) << 1 | (self.z.is_negative() as u32) << 2 diff --git a/tests/vec2.rs b/tests/vec2.rs index c7aa1d5c..3ca9acc5 100644 --- a/tests/vec2.rs +++ b/tests/vec2.rs @@ -606,15 +606,15 @@ macro_rules! impl_vec2_float_tests { assert!($vec2::splat(NAN).signum().is_nan_mask().all()); }); - glam_test!(test_sign_bits, { - assert_eq!($vec2::ZERO.sign_bits(), 0b00); - assert_eq!((-$vec2::ZERO).sign_bits(), 0b11); - assert_eq!($vec2::ONE.sign_bits(), 0b00); - assert_eq!((-$vec2::ONE).sign_bits(), 0b11); - assert_eq!($vec2::new(-0.1, 0.2).sign_bits(), 0b01); - assert_eq!($vec2::new(0.8, 0.3).sign_bits(), 0b00); - assert_eq!($vec2::new(0.3, -0.4).sign_bits(), 0b10); - assert_eq!($vec2::new(-0.2, -0.6).sign_bits(), 0b11); + glam_test!(test_is_negative_bitmask, { + assert_eq!($vec2::ZERO.is_negative_bitmask(), 0b00); + assert_eq!((-$vec2::ZERO).is_negative_bitmask(), 0b11); + assert_eq!($vec2::ONE.is_negative_bitmask(), 0b00); + assert_eq!((-$vec2::ONE).is_negative_bitmask(), 0b11); + assert_eq!($vec2::new(-0.1, 0.2).is_negative_bitmask(), 0b01); + assert_eq!($vec2::new(0.8, 0.3).is_negative_bitmask(), 0b00); + assert_eq!($vec2::new(0.3, -0.4).is_negative_bitmask(), 0b10); + assert_eq!($vec2::new(-0.2, -0.6).is_negative_bitmask(), 0b11); }); glam_test!(test_abs, { diff --git a/tests/vec3.rs b/tests/vec3.rs index 23278087..92af042e 100644 --- a/tests/vec3.rs +++ b/tests/vec3.rs @@ -668,16 +668,16 @@ macro_rules! impl_vec3_float_tests { assert!($vec3::splat(NAN).signum().is_nan_mask().all()); }); - glam_test!(test_sign_bits, { - assert_eq!($vec3::ZERO.sign_bits(), 0b000); - assert_eq!((-$vec3::ZERO).sign_bits(), 0b111); - assert_eq!($vec3::ONE.sign_bits(), 0b000); - assert_eq!((-$vec3::ONE).sign_bits(), 0b111); - assert_eq!($vec3::new(-0.1, 0.2, 0.3).sign_bits(), 0b001); - assert_eq!($vec3::new(0.8, 0.3, 0.1).sign_bits(), 0b000); - assert_eq!($vec3::new(0.1, 0.5, -0.3).sign_bits(), 0b100); - assert_eq!($vec3::new(0.3, -0.4, 0.1).sign_bits(), 0b010); - assert_eq!($vec3::new(-0.2, 0.6, -0.5).sign_bits(), 0b101); + glam_test!(test_is_negative_bitmask, { + assert_eq!($vec3::ZERO.is_negative_bitmask(), 0b000); + assert_eq!((-$vec3::ZERO).is_negative_bitmask(), 0b111); + assert_eq!($vec3::ONE.is_negative_bitmask(), 0b000); + assert_eq!((-$vec3::ONE).is_negative_bitmask(), 0b111); + assert_eq!($vec3::new(-0.1, 0.2, 0.3).is_negative_bitmask(), 0b001); + assert_eq!($vec3::new(0.8, 0.3, 0.1).is_negative_bitmask(), 0b000); + assert_eq!($vec3::new(0.1, 0.5, -0.3).is_negative_bitmask(), 0b100); + assert_eq!($vec3::new(0.3, -0.4, 0.1).is_negative_bitmask(), 0b010); + assert_eq!($vec3::new(-0.2, 0.6, -0.5).is_negative_bitmask(), 0b101); }); glam_test!(test_abs, { diff --git a/tests/vec4.rs b/tests/vec4.rs index a4333b85..27d36302 100644 --- a/tests/vec4.rs +++ b/tests/vec4.rs @@ -750,16 +750,16 @@ macro_rules! impl_vec4_float_tests { assert!($vec4::splat(NAN).signum().is_nan_mask().all()); }); - glam_test!(test_sign_bits, { - assert_eq!($vec4::ZERO.sign_bits(), 0b0000); - assert_eq!((-$vec4::ZERO).sign_bits(), 0b1111); - assert_eq!($vec4::ONE.sign_bits(), 0b0000); - assert_eq!((-$vec4::ONE).sign_bits(), 0b1111); - assert_eq!($vec4::new(-0.1, 0.2, 0.3, -0.4).sign_bits(), 0b1001); - assert_eq!($vec4::new(0.8, 0.3, 0.1, -0.0).sign_bits(), 0b1000); - assert_eq!($vec4::new(0.1, 0.5, -0.3, 0.7).sign_bits(), 0b0100); - assert_eq!($vec4::new(0.3, -0.4, 0.1, 0.6).sign_bits(), 0b0010); - assert_eq!($vec4::new(0.2, -0.6, 0.5, -0.3).sign_bits(), 0b1010); + glam_test!(test_is_negative_bitmask, { + assert_eq!($vec4::ZERO.is_negative_bitmask(), 0b0000); + assert_eq!((-$vec4::ZERO).is_negative_bitmask(), 0b1111); + assert_eq!($vec4::ONE.is_negative_bitmask(), 0b0000); + assert_eq!((-$vec4::ONE).is_negative_bitmask(), 0b1111); + assert_eq!($vec4::new(-0.1, 0.2, 0.3, -0.4).is_negative_bitmask(), 0b1001); + assert_eq!($vec4::new(0.8, 0.3, 0.1, -0.0).is_negative_bitmask(), 0b1000); + assert_eq!($vec4::new(0.1, 0.5, -0.3, 0.7).is_negative_bitmask(), 0b0100); + assert_eq!($vec4::new(0.3, -0.4, 0.1, 0.6).is_negative_bitmask(), 0b0010); + assert_eq!($vec4::new(0.2, -0.6, 0.5, -0.3).is_negative_bitmask(), 0b1010); }); glam_test!(test_abs, { From 6fc89aead23e8b1ea4536c709fd35dbaa73ce0b8 Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Fri, 30 Sep 2022 20:43:50 -0700 Subject: [PATCH 6/6] rustfmt --- tests/vec4.rs | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/tests/vec4.rs b/tests/vec4.rs index 27d36302..9d063712 100644 --- a/tests/vec4.rs +++ b/tests/vec4.rs @@ -755,11 +755,26 @@ macro_rules! impl_vec4_float_tests { assert_eq!((-$vec4::ZERO).is_negative_bitmask(), 0b1111); assert_eq!($vec4::ONE.is_negative_bitmask(), 0b0000); assert_eq!((-$vec4::ONE).is_negative_bitmask(), 0b1111); - assert_eq!($vec4::new(-0.1, 0.2, 0.3, -0.4).is_negative_bitmask(), 0b1001); - assert_eq!($vec4::new(0.8, 0.3, 0.1, -0.0).is_negative_bitmask(), 0b1000); - assert_eq!($vec4::new(0.1, 0.5, -0.3, 0.7).is_negative_bitmask(), 0b0100); - assert_eq!($vec4::new(0.3, -0.4, 0.1, 0.6).is_negative_bitmask(), 0b0010); - assert_eq!($vec4::new(0.2, -0.6, 0.5, -0.3).is_negative_bitmask(), 0b1010); + assert_eq!( + $vec4::new(-0.1, 0.2, 0.3, -0.4).is_negative_bitmask(), + 0b1001 + ); + assert_eq!( + $vec4::new(0.8, 0.3, 0.1, -0.0).is_negative_bitmask(), + 0b1000 + ); + assert_eq!( + $vec4::new(0.1, 0.5, -0.3, 0.7).is_negative_bitmask(), + 0b0100 + ); + assert_eq!( + $vec4::new(0.3, -0.4, 0.1, 0.6).is_negative_bitmask(), + 0b0010 + ); + assert_eq!( + $vec4::new(0.2, -0.6, 0.5, -0.3).is_negative_bitmask(), + 0b1010 + ); }); glam_test!(test_abs, {