Repository: bitshifter/glam-rs (rust)

Issue:
Why no {distance,length}_squared for {I,U}Vec{2,3,4} ?
I see no reason for the integer vectors to not have the `distance_squared` and `length_squared` methods, like the rest of the numeric vectors have. Is there any?

Pull request description:
Support length_squared and distance_squared on int vectors.
Fixes #381 

Patch:
diff --git a/codegen/templates/vec.rs.tera b/codegen/templates/vec.rs.tera
index f314038..cfb0f58 100644
--- a/codegen/templates/vec.rs.tera
+++ b/codegen/templates/vec.rs.tera
@@ -991,16 +991,20 @@ impl {{ self_t }} {
             dot.sqrt()[0]
         {% endif %}
     }
+{% endif %}
 
     /// Computes the squared length of `self`.
+{%- if is_float %}
     ///
     /// This is faster than `length()` as it avoids a square root operation.
+{%- endif %}
     #[doc(alias = "magnitude2")]
     #[inline]
     pub fn length_squared(self) -> {{ scalar_t }} {
         self.dot(self)
     }
 
+{% if is_float %}
     /// Computes `1.0 / length()`.
     ///
     /// For valid results, `self` must _not_ be of length zero.
@@ -1027,13 +1031,17 @@ impl {{ self_t }} {
     pub fn distance(self, rhs: Self) -> {{ scalar_t }} {
         (self - rhs).length()
     }
+{% endif %}
 
+{% if is_signed %}
     /// Compute the squared euclidean distance between two points in space.
     #[inline]
     pub fn distance_squared(self, rhs: Self) -> {{ scalar_t }} {
         (self - rhs).length_squared()
     }
+{% endif %}
 
+{% if is_float %}
     /// Returns `self` normalized to length 1.0.
     ///
     /// For valid results, `self` must _not_ be of length zero, nor very close to zero.
diff --git a/src/i32/ivec2.rs b/src/i32/ivec2.rs
index a5968d3..3ccfdc0 100644
--- a/src/i32/ivec2.rs
+++ b/src/i32/ivec2.rs
@@ -273,6 +273,19 @@ impl IVec2 {
         (self.x.is_negative() as u32) | (self.y.is_negative() as u32) << 1
     }
 
+    /// Computes the squared length of `self`.
+    #[doc(alias = "magnitude2")]
+    #[inline]
+    pub fn length_squared(self) -> i32 {
+        self.dot(self)
+    }
+
+    /// Compute the squared euclidean distance between two points in space.
+    #[inline]
+    pub fn distance_squared(self, rhs: Self) -> i32 {
+        (self - rhs).length_squared()
+    }
+
     /// 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 5d13d84..167e393 100644
--- a/src/i32/ivec3.rs
+++ b/src/i32/ivec3.rs
@@ -317,6 +317,19 @@ impl IVec3 {
             | (self.z.is_negative() as u32) << 2
     }
 
+    /// Computes the squared length of `self`.
+    #[doc(alias = "magnitude2")]
+    #[inline]
+    pub fn length_squared(self) -> i32 {
+        self.dot(self)
+    }
+
+    /// Compute the squared euclidean distance between two points in space.
+    #[inline]
+    pub fn distance_squared(self, rhs: Self) -> i32 {
+        (self - rhs).length_squared()
+    }
+
     /// 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 6a7a3e1..b2b2b33 100644
--- a/src/i32/ivec4.rs
+++ b/src/i32/ivec4.rs
@@ -343,6 +343,19 @@ impl IVec4 {
             | (self.w.is_negative() as u32) << 3
     }
 
+    /// Computes the squared length of `self`.
+    #[doc(alias = "magnitude2")]
+    #[inline]
+    pub fn length_squared(self) -> i32 {
+        self.dot(self)
+    }
+
+    /// Compute the squared euclidean distance between two points in space.
+    #[inline]
+    pub fn distance_squared(self, rhs: Self) -> i32 {
+        (self - rhs).length_squared()
+    }
+
     /// Casts all elements of `self` to `f32`.
     #[inline]
     pub fn as_vec4(&self) -> crate::Vec4 {
diff --git a/src/i64/i64vec2.rs b/src/i64/i64vec2.rs
index 803ad3c..2dccd89 100644
--- a/src/i64/i64vec2.rs
+++ b/src/i64/i64vec2.rs
@@ -273,6 +273,19 @@ impl I64Vec2 {
         (self.x.is_negative() as u32) | (self.y.is_negative() as u32) << 1
     }
 
+    /// Computes the squared length of `self`.
+    #[doc(alias = "magnitude2")]
+    #[inline]
+    pub fn length_squared(self) -> i64 {
+        self.dot(self)
+    }
+
+    /// Compute the squared euclidean distance between two points in space.
+    #[inline]
+    pub fn distance_squared(self, rhs: Self) -> i64 {
+        (self - rhs).length_squared()
+    }
+
     /// Returns a vector that is equal to `self` rotated by 90 degrees.
     #[inline]
     pub fn perp(self) -> Self {
diff --git a/src/i64/i64vec3.rs b/src/i64/i64vec3.rs
index 712f3c2..7bf66d5 100644
--- a/src/i64/i64vec3.rs
+++ b/src/i64/i64vec3.rs
@@ -317,6 +317,19 @@ impl I64Vec3 {
             | (self.z.is_negative() as u32) << 2
     }
 
+    /// Computes the squared length of `self`.
+    #[doc(alias = "magnitude2")]
+    #[inline]
+    pub fn length_squared(self) -> i64 {
+        self.dot(self)
+    }
+
+    /// Compute the squared euclidean distance between two points in space.
+    #[inline]
+    pub fn distance_squared(self, rhs: Self) -> i64 {
+        (self - rhs).length_squared()
+    }
+
     /// Casts all elements of `self` to `f32`.
     #[inline]
     pub fn as_vec3(&self) -> crate::Vec3 {
diff --git a/src/i64/i64vec4.rs b/src/i64/i64vec4.rs
index ff60ae2..35521eb 100644
--- a/src/i64/i64vec4.rs
+++ b/src/i64/i64vec4.rs
@@ -343,6 +343,19 @@ impl I64Vec4 {
             | (self.w.is_negative() as u32) << 3
     }
 
+    /// Computes the squared length of `self`.
+    #[doc(alias = "magnitude2")]
+    #[inline]
+    pub fn length_squared(self) -> i64 {
+        self.dot(self)
+    }
+
+    /// Compute the squared euclidean distance between two points in space.
+    #[inline]
+    pub fn distance_squared(self, rhs: Self) -> i64 {
+        (self - rhs).length_squared()
+    }
+
     /// Casts all elements of `self` to `f32`.
     #[inline]
     pub fn as_vec4(&self) -> crate::Vec4 {
diff --git a/src/u32/uvec2.rs b/src/u32/uvec2.rs
index fbc01e6..f147bb6 100644
--- a/src/u32/uvec2.rs
+++ b/src/u32/uvec2.rs
@@ -227,6 +227,13 @@ impl UVec2 {
         BVec2::new(self.x.lt(&rhs.x), self.y.lt(&rhs.y))
     }
 
+    /// Computes the squared length of `self`.
+    #[doc(alias = "magnitude2")]
+    #[inline]
+    pub fn length_squared(self) -> u32 {
+        self.dot(self)
+    }
+
     /// Casts all elements of `self` to `f32`.
     #[inline]
     pub fn as_vec2(&self) -> crate::Vec2 {
diff --git a/src/u32/uvec3.rs b/src/u32/uvec3.rs
index e969eed..fd31b4d 100644
--- a/src/u32/uvec3.rs
+++ b/src/u32/uvec3.rs
@@ -264,6 +264,13 @@ impl UVec3 {
         BVec3::new(self.x.lt(&rhs.x), self.y.lt(&rhs.y), self.z.lt(&rhs.z))
     }
 
+    /// Computes the squared length of `self`.
+    #[doc(alias = "magnitude2")]
+    #[inline]
+    pub fn length_squared(self) -> u32 {
+        self.dot(self)
+    }
+
     /// Casts all elements of `self` to `f32`.
     #[inline]
     pub fn as_vec3(&self) -> crate::Vec3 {
diff --git a/src/u32/uvec4.rs b/src/u32/uvec4.rs
index f142963..72d5625 100644
--- a/src/u32/uvec4.rs
+++ b/src/u32/uvec4.rs
@@ -284,6 +284,13 @@ impl UVec4 {
         )
     }
 
+    /// Computes the squared length of `self`.
+    #[doc(alias = "magnitude2")]
+    #[inline]
+    pub fn length_squared(self) -> u32 {
+        self.dot(self)
+    }
+
     /// Casts all elements of `self` to `f32`.
     #[inline]
     pub fn as_vec4(&self) -> crate::Vec4 {
diff --git a/src/u64/u64vec2.rs b/src/u64/u64vec2.rs
index 5302016..a67a486 100644
--- a/src/u64/u64vec2.rs
+++ b/src/u64/u64vec2.rs
@@ -227,6 +227,13 @@ impl U64Vec2 {
         BVec2::new(self.x.lt(&rhs.x), self.y.lt(&rhs.y))
     }
 
+    /// Computes the squared length of `self`.
+    #[doc(alias = "magnitude2")]
+    #[inline]
+    pub fn length_squared(self) -> u64 {
+        self.dot(self)
+    }
+
     /// Casts all elements of `self` to `f32`.
     #[inline]
     pub fn as_vec2(&self) -> crate::Vec2 {
diff --git a/src/u64/u64vec3.rs b/src/u64/u64vec3.rs
index 8e0345e..60ced60 100644
--- a/src/u64/u64vec3.rs
+++ b/src/u64/u64vec3.rs
@@ -264,6 +264,13 @@ impl U64Vec3 {
         BVec3::new(self.x.lt(&rhs.x), self.y.lt(&rhs.y), self.z.lt(&rhs.z))
     }
 
+    /// Computes the squared length of `self`.
+    #[doc(alias = "magnitude2")]
+    #[inline]
+    pub fn length_squared(self) -> u64 {
+        self.dot(self)
+    }
+
     /// Casts all elements of `self` to `f32`.
     #[inline]
     pub fn as_vec3(&self) -> crate::Vec3 {
diff --git a/src/u64/u64vec4.rs b/src/u64/u64vec4.rs
index 7bab5d1..5d44c37 100644
--- a/src/u64/u64vec4.rs
+++ b/src/u64/u64vec4.rs
@@ -284,6 +284,13 @@ impl U64Vec4 {
         )
     }
 
+    /// Computes the squared length of `self`.
+    #[doc(alias = "magnitude2")]
+    #[inline]
+    pub fn length_squared(self) -> u64 {
+        self.dot(self)
+    }
+
     /// Casts all elements of `self` to `f32`.
     #[inline]
     pub fn as_vec4(&self) -> crate::Vec4 {


Test patch:
diff --git a/tests/vec2.rs b/tests/vec2.rs
index c545455..bdde85b 100644
--- a/tests/vec2.rs
+++ b/tests/vec2.rs
@@ -102,6 +102,15 @@ macro_rules! impl_vec2_tests {
             assert_eq!(0 as $t, x.dot(y));
         });
 
+        glam_test!(test_length_squared_unsigned, {
+            let x = $new(1 as $t, 0 as $t);
+            assert_eq!(4 as $t, (2 as $t * x).length_squared());
+            assert_eq!(
+                2 as $t * 2 as $t + 3 as $t * 3 as $t,
+                $new(2 as $t, 3 as $t).length_squared()
+            );
+        });
+
         glam_test!(test_ops, {
             let a = $new(2 as $t, 4 as $t);
             assert_eq!($new(4 as $t, 8 as $t), (a + a));
@@ -472,6 +481,14 @@ macro_rules! impl_vec2_signed_tests {
             assert_eq!(-1 as $t, x.dot(-x));
         });
 
+        glam_test!(test_length_squared_signed, {
+            let x = $new(1 as $t, 0 as $t);
+            let y = $new(0 as $t, 1 as $t);
+            assert_eq!(9 as $t, (-3 as $t * y).length_squared());
+            assert_eq!(2 as $t, x.distance_squared(y));
+            assert_eq!(13 as $t, (2 as $t * x).distance_squared(-3 as $t * y));
+        });
+
         glam_test!(test_neg, {
             let a = $new(1 as $t, 2 as $t);
             assert_eq!($new(-1 as $t, -2 as $t), (-a));
@@ -547,19 +564,14 @@ macro_rules! impl_vec2_float_tests {
         glam_test!(test_length, {
             let x = $new(1.0, 0.0);
             let y = $new(0.0, 1.0);
-            assert_eq!(4.0, (2.0 * x).length_squared());
-            assert_eq!(9.0, (-3.0 * y).length_squared());
             assert_eq!(2.0, (-2.0 * x).length());
             assert_eq!(3.0, (3.0 * y).length());
-            assert_eq!(2.0, x.distance_squared(y));
-            assert_eq!(13.0, (2.0 * x).distance_squared(-3.0 * y));
             assert_eq!((2.0 as $t).sqrt(), x.distance(y));
             assert_eq!(5.0, (3.0 * x).distance(-4.0 * y));
             assert_eq!(13.0, (-5.0 * x).distance(12.0 * y));
             assert_eq!(x, (2.0 * x).normalize());
             assert_eq!(1.0 * 3.0 + 2.0 * 4.0, $new(1.0, 2.0).dot($new(3.0, 4.0)));
             assert_eq!($new(8.0, 8.0), $new(1.0, 2.0).dot_into_vec($new(4.0, 2.0)));
-            assert_eq!(2.0 * 2.0 + 3.0 * 3.0, $new(2.0, 3.0).length_squared());
             assert_eq!(
                 (2.0 as $t * 2.0 + 3.0 * 3.0).sqrt(),
                 $new(2.0, 3.0).length()
diff --git a/tests/vec3.rs b/tests/vec3.rs
index 84e6e6d..250ea97 100644
--- a/tests/vec3.rs
+++ b/tests/vec3.rs
@@ -110,6 +110,13 @@ macro_rules! impl_vec3_tests {
             assert_eq!(0 as $t, x.dot(y));
         });
 
+        glam_test!(test_length_squared_unsigned, {
+            let x = $new(1 as $t, 0 as $t, 0 as $t);
+            let z = $new(0 as $t, 0 as $t, 1 as $t);
+            assert_eq!(4 as $t, (2 as $t * x).length_squared());
+            assert_eq!(16 as $t, (4 as $t * z).length_squared());
+        });
+
         glam_test!(test_cross, {
             let x = $new(1 as $t, 0 as $t, 0 as $t);
             let y = $new(0 as $t, 1 as $t, 0 as $t);
@@ -538,6 +545,19 @@ macro_rules! impl_vec3_signed_tests {
             assert_eq!(0 as $t, x.dot(y));
             assert_eq!(-1 as $t, z.dot(-z));
         });
+
+        glam_test!(test_length_squared_signed, {
+            let x = $new(1 as $t, 0 as $t, 0 as $t);
+            let y = $new(0 as $t, 1 as $t, 0 as $t);
+            let z = $new(0 as $t, 0 as $t, 1 as $t);
+            assert_eq!(9 as $t, (-3 as $t * y).length_squared());
+            assert_eq!(
+                2 as $t * 2 as $t + 3 as $t * 3 as $t + 4 as $t * 4 as $t,
+                $new(2 as $t, 3 as $t, 4 as $t).length_squared()
+            );
+            assert_eq!(2 as $t, x.distance_squared(y));
+            assert_eq!(13 as $t, (2 as $t * x).distance_squared(-3 as $t * z));
+        });
     };
 }
 
@@ -592,14 +612,9 @@ macro_rules! impl_vec3_float_tests {
             let z = $new(0.0, 0.0, 1.0);
             assert_eq!(y, z.cross(x));
             assert_eq!(z, x.cross(y));
-            assert_eq!(4.0, (2.0 * x).length_squared());
-            assert_eq!(9.0, (-3.0 * y).length_squared());
-            assert_eq!(16.0, (4.0 * z).length_squared());
             assert_eq!(2.0, (-2.0 * x).length());
             assert_eq!(3.0, (3.0 * y).length());
             assert_eq!(4.0, (-4.0 * z).length());
-            assert_eq!(2.0, x.distance_squared(y));
-            assert_eq!(13.0, (2.0 * x).distance_squared(-3.0 * z));
             assert_eq!((2.0 as $t).sqrt(), x.distance(y));
             assert_eq!(5.0, (3.0 * x).distance(-4.0 * y));
             assert_eq!(13.0, (-5.0 * z).distance(12.0 * y));
@@ -612,10 +627,6 @@ macro_rules! impl_vec3_float_tests {
                 $new(14.0, 14.0, 14.0),
                 $new(0.0, 4.0, 6.0).dot_into_vec($new(3.0, 2.0, 1.0))
             );
-            assert_eq!(
-                2.0 * 2.0 + 3.0 * 3.0 + 4.0 * 4.0,
-                $new(2.0, 3.0, 4.0).length_squared()
-            );
             assert_eq!(
                 (2.0 as $t * 2.0 + 3.0 * 3.0 + 4.0 * 4.0).sqrt(),
                 $new(2.0, 3.0, 4.0).length()
diff --git a/tests/vec4.rs b/tests/vec4.rs
index 1b874a1..59d1fb9 100644
--- a/tests/vec4.rs
+++ b/tests/vec4.rs
@@ -148,6 +148,19 @@ macro_rules! impl_vec4_tests {
             assert_eq!(0 as $t, z.dot(w));
         });
 
+        glam_test!(test_length_squared_unsigned, {
+            let x = $new(1 as $t, 0 as $t, 0 as $t, 0 as $t);
+            let z = $new(0 as $t, 0 as $t, 1 as $t, 0 as $t);
+            let w = $new(0 as $t, 0 as $t, 0 as $t, 1 as $t);
+            assert_eq!(4 as $t, (2 as $t * x).length_squared());
+            assert_eq!(16 as $t, (4 as $t * z).length_squared());
+            assert_eq!(64 as $t, (8 as $t * w).length_squared());
+            assert_eq!(
+                2 as $t * 2 as $t + 3 as $t * 3 as $t + 4 as $t * 4 as $t + 5 as $t * 5 as $t,
+                $new(2 as $t, 3 as $t, 4 as $t, 5 as $t).length_squared()
+            );
+        });
+
         glam_test!(test_ops, {
             let a = $new(2 as $t, 4 as $t, 8 as $t, 16 as $t);
             assert_eq!($new(4 as $t, 8 as $t, 16 as $t, 32 as $t), a + a);
@@ -615,6 +628,23 @@ macro_rules! impl_vec4_signed_tests {
             assert_eq!(0 as $t, x.dot(-z));
             assert_eq!(-1 as $t, w.dot(-w));
         });
+
+        glam_test!(test_length_squared_signed, {
+            let x = $new(1 as $t, 0 as $t, 0 as $t, 0 as $t);
+            let y = $new(0 as $t, 1 as $t, 0 as $t, 0 as $t);
+            let z = $new(0 as $t, 0 as $t, 1 as $t, 0 as $t);
+            let w = $new(0 as $t, 0 as $t, 0 as $t, 1 as $t);
+            assert_eq!(4 as $t, (2 as $t * x).length_squared());
+            assert_eq!(9 as $t, (-3 as $t * y).length_squared());
+            assert_eq!(16 as $t, (4 as $t * z).length_squared());
+            assert_eq!(64 as $t, (8 as $t * w).length_squared());
+            assert_eq!(
+                2 as $t * 2 as $t + 3 as $t * 3 as $t + 4 as $t * 4 as $t + 5 as $t * 5 as $t,
+                $new(2 as $t, 3 as $t, 4 as $t, 5 as $t).length_squared()
+            );
+            assert_eq!(2 as $t, x.distance_squared(y));
+            assert_eq!(13 as $t, (2 as $t * x).distance_squared(-3 as $t * z));
+        });
     };
 }
 
@@ -668,16 +698,10 @@ macro_rules! impl_vec4_float_tests {
             let y = $new(0.0, 1.0, 0.0, 0.0);
             let z = $new(0.0, 0.0, 1.0, 0.0);
             let w = $new(0.0, 0.0, 0.0, 1.0);
-            assert_eq!(4.0, (2.0 * x).length_squared());
-            assert_eq!(9.0, (-3.0 * y).length_squared());
-            assert_eq!(16.0, (4.0 * z).length_squared());
-            assert_eq!(64.0, (8.0 * w).length_squared());
             assert_eq!(2.0, (-2.0 * x).length());
             assert_eq!(3.0, (3.0 * y).length());
             assert_eq!(4.0, (-4.0 * z).length());
             assert_eq!(5.0, (-5.0 * w).length());
-            assert_eq!(2.0, x.distance_squared(y));
-            assert_eq!(13.0, (2.0 * x).distance_squared(-3.0 * z));
             assert_eq!((2.0 as $t).sqrt(), w.distance(y));
             assert_eq!(5.0, (3.0 * x).distance(-4.0 * y));
             assert_eq!(13.0, (-5.0 * w).distance(12.0 * y));
@@ -690,10 +714,6 @@ macro_rules! impl_vec4_float_tests {
                 $new(28.0, 28.0, 28.0, 28.0),
                 $new(0.0, 5.0, 3.0, 6.0).dot_into_vec($new(7.0, 2.0, 4.0, 1.0))
             );
-            assert_eq!(
-                2.0 * 2.0 + 3.0 * 3.0 + 4.0 * 4.0 + 5.0 * 5.0,
-                $new(2.0, 3.0, 4.0, 5.0).length_squared()
-            );
             assert_eq!(
                 (2.0 as $t * 2.0 + 3.0 * 3.0 + 4.0 * 4.0 + 5.0 * 5.0).sqrt(),
                 $new(2.0, 3.0, 4.0, 5.0).length()