Repository: bitshifter/glam-rs
Pull request #499 (2024-03-23 03:06:41)

Implement fract as self - self.trunc() rather than GLSL's self - self.floor()


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 65fae2c..b717d9e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog], and this project adheres to
 [Semantic Versioning].
 
+## [0.27.0] - 2024-03-23
+
+### Breaking changes
+
+* Changed implementation of vector `fract` method to match the Rust
+  implementation instead of the GLSL implementation, that is `self -
+  self.trunc()` instead of `self - self.floor()`.
+
+### Added
+
+* Added vector `fract_gl` which uses the GLSL specification of fract,
+ `self - self.floor()`.
+
 ## [0.26.0] - 2024-03-18
 
 ### Breaking changes
@@ -1043,7 +1056,8 @@ The format is based on [Keep a Changelog], and this project adheres to
 
 [Keep a Changelog]: https://keepachangelog.com/
 [Semantic Versioning]: https://semver.org/spec/v2.0.0.html
-[Unreleased]: https://github.com/bitshifter/glam-rs/compare/0.26.0...HEAD
+[Unreleased]: https://github.com/bitshifter/glam-rs/compare/0.27.0...HEAD
+[0.27.0]: https://github.com/bitshifter/glam-rs/compare/0.26.0...0.27.0
 [0.26.0]: https://github.com/bitshifter/glam-rs/compare/0.25.0...0.26.0
 [0.25.0]: https://github.com/bitshifter/glam-rs/compare/0.24.2...0.25.0
 [0.24.2]: https://github.com/bitshifter/glam-rs/compare/0.24.1...0.24.2
diff --git a/Cargo.toml b/Cargo.toml
index dd900c9..b966506 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "glam"
-version = "0.26.0" # remember to update html_root_url
+version = "0.27.0" # remember to update html_root_url
 edition = "2021"
 authors = ["Cameron Hart <cameron.hart@gmail.com>"]
 description = "A simple and fast 3D math library for games and graphics"
diff --git a/README.md b/README.md
index cabaddb..4e4c8f5 100644
--- a/README.md
+++ b/README.md
@@ -78,7 +78,7 @@ defined in `std`. For example:
 
 ```toml
 [dependencies]
-glam = { version = "0.26", default-features = false, features = ["libm"] }
+glam = { version = "0.27", default-features = false, features = ["libm"] }
 ```
 
 To support both `std` and `no_std` builds in project, you can use the following
@@ -92,7 +92,7 @@ std = ["glam/std"]
 libm = ["glam/libm"]
 
 [dependencies]
-glam = { version = "0.26", default-features = false }
+glam = { version = "0.27", default-features = false }
 ```
 
 ### Optional features
diff --git a/codegen/templates/vec.rs.tera b/codegen/templates/vec.rs.tera
index 6f931c5..39199d1 100644
--- a/codegen/templates/vec.rs.tera
+++ b/codegen/templates/vec.rs.tera
@@ -1556,13 +1556,27 @@ impl {{ self_t }} {
         {% endif %}
     }
 
-    /// Returns a vector containing the fractional part of the vector, e.g. `self -
-    /// self.floor()`.
+    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
+    ///
+    /// Note that this differs from the GLSL implementation of `fract` which returns
+    /// `self - self.floor()`.
     ///
     /// Note that this is fast but not precise for large numbers.
     #[inline]
     #[must_use]
     pub fn fract(self) -> Self {
+        self - self.trunc()
+    }
+
+    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
+    ///
+    /// Note that this differs from the Rust implementation of `fract` which returns
+    /// `self - self.trunc()`.
+    ///
+    /// Note that this is fast but not precise for large numbers.
+    #[inline]
+    #[must_use]
+    pub fn fract_gl(self) -> Self {
         self - self.floor()
     }
 
diff --git a/src/f32/coresimd/vec3a.rs b/src/f32/coresimd/vec3a.rs
index c96a8f5..02fdb47 100644
--- a/src/f32/coresimd/vec3a.rs
+++ b/src/f32/coresimd/vec3a.rs
@@ -649,13 +649,27 @@ impl Vec3A {
         Self(self.0.trunc())
     }
 
-    /// Returns a vector containing the fractional part of the vector, e.g. `self -
-    /// self.floor()`.
+    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
+    ///
+    /// Note that this differs from the GLSL implementation of `fract` which returns
+    /// `self - self.floor()`.
     ///
     /// Note that this is fast but not precise for large numbers.
     #[inline]
     #[must_use]
     pub fn fract(self) -> Self {
+        self - self.trunc()
+    }
+
+    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
+    ///
+    /// Note that this differs from the Rust implementation of `fract` which returns
+    /// `self - self.trunc()`.
+    ///
+    /// Note that this is fast but not precise for large numbers.
+    #[inline]
+    #[must_use]
+    pub fn fract_gl(self) -> Self {
         self - self.floor()
     }
 
diff --git a/src/f32/coresimd/vec4.rs b/src/f32/coresimd/vec4.rs
index 05f2b67..eb8a609 100644
--- a/src/f32/coresimd/vec4.rs
+++ b/src/f32/coresimd/vec4.rs
@@ -629,13 +629,27 @@ impl Vec4 {
         Self(self.0.trunc())
     }
 
-    /// Returns a vector containing the fractional part of the vector, e.g. `self -
-    /// self.floor()`.
+    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
+    ///
+    /// Note that this differs from the GLSL implementation of `fract` which returns
+    /// `self - self.floor()`.
     ///
     /// Note that this is fast but not precise for large numbers.
     #[inline]
     #[must_use]
     pub fn fract(self) -> Self {
+        self - self.trunc()
+    }
+
+    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
+    ///
+    /// Note that this differs from the Rust implementation of `fract` which returns
+    /// `self - self.trunc()`.
+    ///
+    /// Note that this is fast but not precise for large numbers.
+    #[inline]
+    #[must_use]
+    pub fn fract_gl(self) -> Self {
         self - self.floor()
     }
 
diff --git a/src/f32/scalar/vec3a.rs b/src/f32/scalar/vec3a.rs
index 7ab1db5..0ef554a 100644
--- a/src/f32/scalar/vec3a.rs
+++ b/src/f32/scalar/vec3a.rs
@@ -686,13 +686,27 @@ impl Vec3A {
         }
     }
 
-    /// Returns a vector containing the fractional part of the vector, e.g. `self -
-    /// self.floor()`.
+    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
+    ///
+    /// Note that this differs from the GLSL implementation of `fract` which returns
+    /// `self - self.floor()`.
     ///
     /// Note that this is fast but not precise for large numbers.
     #[inline]
     #[must_use]
     pub fn fract(self) -> Self {
+        self - self.trunc()
+    }
+
+    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
+    ///
+    /// Note that this differs from the Rust implementation of `fract` which returns
+    /// `self - self.trunc()`.
+    ///
+    /// Note that this is fast but not precise for large numbers.
+    #[inline]
+    #[must_use]
+    pub fn fract_gl(self) -> Self {
         self - self.floor()
     }
 
diff --git a/src/f32/scalar/vec4.rs b/src/f32/scalar/vec4.rs
index 68fb638..f3d9514 100644
--- a/src/f32/scalar/vec4.rs
+++ b/src/f32/scalar/vec4.rs
@@ -733,13 +733,27 @@ impl Vec4 {
         }
     }
 
-    /// Returns a vector containing the fractional part of the vector, e.g. `self -
-    /// self.floor()`.
+    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
+    ///
+    /// Note that this differs from the GLSL implementation of `fract` which returns
+    /// `self - self.floor()`.
     ///
     /// Note that this is fast but not precise for large numbers.
     #[inline]
     #[must_use]
     pub fn fract(self) -> Self {
+        self - self.trunc()
+    }
+
+    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
+    ///
+    /// Note that this differs from the Rust implementation of `fract` which returns
+    /// `self - self.trunc()`.
+    ///
+    /// Note that this is fast but not precise for large numbers.
+    #[inline]
+    #[must_use]
+    pub fn fract_gl(self) -> Self {
         self - self.floor()
     }
 
diff --git a/src/f32/sse2/vec3a.rs b/src/f32/sse2/vec3a.rs
index 3549878..9b3ab8b 100644
--- a/src/f32/sse2/vec3a.rs
+++ b/src/f32/sse2/vec3a.rs
@@ -697,13 +697,27 @@ impl Vec3A {
         Self(unsafe { m128_trunc(self.0) })
     }
 
-    /// Returns a vector containing the fractional part of the vector, e.g. `self -
-    /// self.floor()`.
+    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
+    ///
+    /// Note that this differs from the GLSL implementation of `fract` which returns
+    /// `self - self.floor()`.
     ///
     /// Note that this is fast but not precise for large numbers.
     #[inline]
     #[must_use]
     pub fn fract(self) -> Self {
+        self - self.trunc()
+    }
+
+    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
+    ///
+    /// Note that this differs from the Rust implementation of `fract` which returns
+    /// `self - self.trunc()`.
+    ///
+    /// Note that this is fast but not precise for large numbers.
+    #[inline]
+    #[must_use]
+    pub fn fract_gl(self) -> Self {
         self - self.floor()
     }
 
diff --git a/src/f32/sse2/vec4.rs b/src/f32/sse2/vec4.rs
index dd0c5a5..9f19836 100644
--- a/src/f32/sse2/vec4.rs
+++ b/src/f32/sse2/vec4.rs
@@ -678,13 +678,27 @@ impl Vec4 {
         Self(unsafe { m128_trunc(self.0) })
     }
 
-    /// Returns a vector containing the fractional part of the vector, e.g. `self -
-    /// self.floor()`.
+    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
+    ///
+    /// Note that this differs from the GLSL implementation of `fract` which returns
+    /// `self - self.floor()`.
     ///
     /// Note that this is fast but not precise for large numbers.
     #[inline]
     #[must_use]
     pub fn fract(self) -> Self {
+        self - self.trunc()
+    }
+
+    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
+    ///
+    /// Note that this differs from the Rust implementation of `fract` which returns
+    /// `self - self.trunc()`.
+    ///
+    /// Note that this is fast but not precise for large numbers.
+    #[inline]
+    #[must_use]
+    pub fn fract_gl(self) -> Self {
         self - self.floor()
     }
 
diff --git a/src/f32/vec2.rs b/src/f32/vec2.rs
index 6880c7d..0b460a8 100644
--- a/src/f32/vec2.rs
+++ b/src/f32/vec2.rs
@@ -615,13 +615,27 @@ impl Vec2 {
         }
     }
 
-    /// Returns a vector containing the fractional part of the vector, e.g. `self -
-    /// self.floor()`.
+    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
+    ///
+    /// Note that this differs from the GLSL implementation of `fract` which returns
+    /// `self - self.floor()`.
     ///
     /// Note that this is fast but not precise for large numbers.
     #[inline]
     #[must_use]
     pub fn fract(self) -> Self {
+        self - self.trunc()
+    }
+
+    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
+    ///
+    /// Note that this differs from the Rust implementation of `fract` which returns
+    /// `self - self.trunc()`.
+    ///
+    /// Note that this is fast but not precise for large numbers.
+    #[inline]
+    #[must_use]
+    pub fn fract_gl(self) -> Self {
         self - self.floor()
     }
 
diff --git a/src/f32/vec3.rs b/src/f32/vec3.rs
index ce0cdbc..69d21a1 100644
--- a/src/f32/vec3.rs
+++ b/src/f32/vec3.rs
@@ -677,13 +677,27 @@ impl Vec3 {
         }
     }
 
-    /// Returns a vector containing the fractional part of the vector, e.g. `self -
-    /// self.floor()`.
+    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
+    ///
+    /// Note that this differs from the GLSL implementation of `fract` which returns
+    /// `self - self.floor()`.
     ///
     /// Note that this is fast but not precise for large numbers.
     #[inline]
     #[must_use]
     pub fn fract(self) -> Self {
+        self - self.trunc()
+    }
+
+    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
+    ///
+    /// Note that this differs from the Rust implementation of `fract` which returns
+    /// `self - self.trunc()`.
+    ///
+    /// Note that this is fast but not precise for large numbers.
+    #[inline]
+    #[must_use]
+    pub fn fract_gl(self) -> Self {
         self - self.floor()
     }
 
diff --git a/src/f32/wasm32/vec3a.rs b/src/f32/wasm32/vec3a.rs
index 9da2897..34a5db8 100644
--- a/src/f32/wasm32/vec3a.rs
+++ b/src/f32/wasm32/vec3a.rs
@@ -668,13 +668,27 @@ impl Vec3A {
         Self(f32x4_trunc(self.0))
     }
 
-    /// Returns a vector containing the fractional part of the vector, e.g. `self -
-    /// self.floor()`.
+    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
+    ///
+    /// Note that this differs from the GLSL implementation of `fract` which returns
+    /// `self - self.floor()`.
     ///
     /// Note that this is fast but not precise for large numbers.
     #[inline]
     #[must_use]
     pub fn fract(self) -> Self {
+        self - self.trunc()
+    }
+
+    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
+    ///
+    /// Note that this differs from the Rust implementation of `fract` which returns
+    /// `self - self.trunc()`.
+    ///
+    /// Note that this is fast but not precise for large numbers.
+    #[inline]
+    #[must_use]
+    pub fn fract_gl(self) -> Self {
         self - self.floor()
     }
 
diff --git a/src/f32/wasm32/vec4.rs b/src/f32/wasm32/vec4.rs
index 3d6c55b..a095d3c 100644
--- a/src/f32/wasm32/vec4.rs
+++ b/src/f32/wasm32/vec4.rs
@@ -656,13 +656,27 @@ impl Vec4 {
         Self(f32x4_trunc(self.0))
     }
 
-    /// Returns a vector containing the fractional part of the vector, e.g. `self -
-    /// self.floor()`.
+    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
+    ///
+    /// Note that this differs from the GLSL implementation of `fract` which returns
+    /// `self - self.floor()`.
     ///
     /// Note that this is fast but not precise for large numbers.
     #[inline]
     #[must_use]
     pub fn fract(self) -> Self {
+        self - self.trunc()
+    }
+
+    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
+    ///
+    /// Note that this differs from the Rust implementation of `fract` which returns
+    /// `self - self.trunc()`.
+    ///
+    /// Note that this is fast but not precise for large numbers.
+    #[inline]
+    #[must_use]
+    pub fn fract_gl(self) -> Self {
         self - self.floor()
     }
 
diff --git a/src/f64/dvec2.rs b/src/f64/dvec2.rs
index c438f41..a13b603 100644
--- a/src/f64/dvec2.rs
+++ b/src/f64/dvec2.rs
@@ -615,13 +615,27 @@ impl DVec2 {
         }
     }
 
-    /// Returns a vector containing the fractional part of the vector, e.g. `self -
-    /// self.floor()`.
+    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
+    ///
+    /// Note that this differs from the GLSL implementation of `fract` which returns
+    /// `self - self.floor()`.
     ///
     /// Note that this is fast but not precise for large numbers.
     #[inline]
     #[must_use]
     pub fn fract(self) -> Self {
+        self - self.trunc()
+    }
+
+    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
+    ///
+    /// Note that this differs from the Rust implementation of `fract` which returns
+    /// `self - self.trunc()`.
+    ///
+    /// Note that this is fast but not precise for large numbers.
+    #[inline]
+    #[must_use]
+    pub fn fract_gl(self) -> Self {
         self - self.floor()
     }
 
diff --git a/src/f64/dvec3.rs b/src/f64/dvec3.rs
index 94edb91..daa57ba 100644
--- a/src/f64/dvec3.rs
+++ b/src/f64/dvec3.rs
@@ -677,13 +677,27 @@ impl DVec3 {
         }
     }
 
-    /// Returns a vector containing the fractional part of the vector, e.g. `self -
-    /// self.floor()`.
+    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
+    ///
+    /// Note that this differs from the GLSL implementation of `fract` which returns
+    /// `self - self.floor()`.
     ///
     /// Note that this is fast but not precise for large numbers.
     #[inline]
     #[must_use]
     pub fn fract(self) -> Self {
+        self - self.trunc()
+    }
+
+    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
+    ///
+    /// Note that this differs from the Rust implementation of `fract` which returns
+    /// `self - self.trunc()`.
+    ///
+    /// Note that this is fast but not precise for large numbers.
+    #[inline]
+    #[must_use]
+    pub fn fract_gl(self) -> Self {
         self - self.floor()
     }
 
diff --git a/src/f64/dvec4.rs b/src/f64/dvec4.rs
index 031e9b3..19649bb 100644
--- a/src/f64/dvec4.rs
+++ b/src/f64/dvec4.rs
@@ -722,13 +722,27 @@ impl DVec4 {
         }
     }
 
-    /// Returns a vector containing the fractional part of the vector, e.g. `self -
-    /// self.floor()`.
+    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
+    ///
+    /// Note that this differs from the GLSL implementation of `fract` which returns
+    /// `self - self.floor()`.
     ///
     /// Note that this is fast but not precise for large numbers.
     #[inline]
     #[must_use]
     pub fn fract(self) -> Self {
+        self - self.trunc()
+    }
+
+    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
+    ///
+    /// Note that this differs from the Rust implementation of `fract` which returns
+    /// `self - self.trunc()`.
+    ///
+    /// Note that this is fast but not precise for large numbers.
+    #[inline]
+    #[must_use]
+    pub fn fract_gl(self) -> Self {
         self - self.floor()
     }
 
diff --git a/src/lib.rs b/src/lib.rs
index b41b434..54bb8f2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -251,7 +251,7 @@ and benchmarks.
 The minimum supported Rust version is `1.68.2`.
 
 */
-#![doc(html_root_url = "https://docs.rs/glam/0.26.0")]
+#![doc(html_root_url = "https://docs.rs/glam/0.27.0")]
 #![cfg_attr(not(feature = "std"), no_std)]
 #![cfg_attr(target_arch = "spirv", feature(repr_simd))]
 #![deny(


Test patch:
diff --git a/tests/vec2.rs b/tests/vec2.rs
index 5712e55..6071f19 100644
--- a/tests/vec2.rs
+++ b/tests/vec2.rs
@@ -782,11 +782,20 @@ macro_rules! impl_vec2_float_tests {
             );
         });
 
+        glam_test!(test_fract_gl, {
+            assert_approx_eq!($vec2::new(1.35, -1.5).fract_gl(), $vec2::new(0.35, 0.5));
+            assert_approx_eq!(
+                $vec2::new(-2000000.123, 1000000.123).fract_gl(),
+                $vec2::new(0.877, 0.123),
+                0.002
+            );
+        });
+
         glam_test!(test_fract, {
-            assert_approx_eq!($vec2::new(1.35, -1.5).fract(), $vec2::new(0.35, 0.5));
+            assert_approx_eq!($vec2::new(1.35, -1.5).fract(), $vec2::new(0.35, -0.5));
             assert_approx_eq!(
                 $vec2::new(-2000000.123, 1000000.123).fract(),
-                $vec2::new(0.877, 0.123),
+                $vec2::new(-0.123, 0.123),
                 0.002
             );
         });
diff --git a/tests/vec3.rs b/tests/vec3.rs
index 5d77d84..fe9ac23 100644
--- a/tests/vec3.rs
+++ b/tests/vec3.rs
@@ -909,14 +909,26 @@ macro_rules! impl_vec3_float_tests {
             );
         });
 
+        glam_test!(test_fract_gl, {
+            assert_approx_eq!(
+                $vec3::new(1.35, 1.5, -1.5).fract_gl(),
+                $vec3::new(0.35, 0.5, 0.5)
+            );
+            assert_approx_eq!(
+                $vec3::new(-200000.123, 1000000.123, 1000.9).fract_gl(),
+                $vec3::new(0.877, 0.123, 0.9),
+                0.002
+            );
+        });
+
         glam_test!(test_fract, {
             assert_approx_eq!(
                 $vec3::new(1.35, 1.5, -1.5).fract(),
-                $vec3::new(0.35, 0.5, 0.5)
+                $vec3::new(0.35, 0.5, -0.5)
             );
             assert_approx_eq!(
                 $vec3::new(-200000.123, 1000000.123, 1000.9).fract(),
-                $vec3::new(0.877, 0.123, 0.9),
+                $vec3::new(-0.123, 0.123, 0.9),
                 0.002
             );
         });
diff --git a/tests/vec4.rs b/tests/vec4.rs
index 3978475..424b7ea 100644
--- a/tests/vec4.rs
+++ b/tests/vec4.rs
@@ -1030,14 +1030,26 @@ macro_rules! impl_vec4_float_tests {
             );
         });
 
+        glam_test!(test_fract_gl, {
+            assert_approx_eq!(
+                $vec4::new(1.35, 1.5, -1.5, 1.999).fract_gl(),
+                $vec4::new(0.35, 0.5, 0.5, 0.999)
+            );
+            assert_approx_eq!(
+                $vec4::new(-0.0, -200000.123, 1000000.123, 1000.9).fract_gl(),
+                $vec4::new(0.0, 0.877, 0.123, 0.9),
+                0.002
+            );
+        });
+
         glam_test!(test_fract, {
             assert_approx_eq!(
                 $vec4::new(1.35, 1.5, -1.5, 1.999).fract(),
-                $vec4::new(0.35, 0.5, 0.5, 0.999)
+                $vec4::new(0.35, 0.5, -0.5, 0.999)
             );
             assert_approx_eq!(
                 $vec4::new(-0.0, -200000.123, 1000000.123, 1000.9).fract(),
-                $vec4::new(0.0, 0.877, 0.123, 0.9),
+                $vec4::new(0.0, -0.123, 0.123, 0.9),
                 0.002
             );
         });