]> git.nega.tv - josh/narcissus/commitdiff
Implement some more maths basics
authorJoshua Simmons <josh@nega.tv>
Sun, 16 Oct 2022 21:41:28 +0000 (23:41 +0200)
committerJoshua Simmons <josh@nega.tv>
Sun, 16 Oct 2022 21:41:28 +0000 (23:41 +0200)
narcissus-maths/src/affine2.rs
narcissus-maths/src/affine3.rs
narcissus-maths/src/mat2.rs
narcissus-maths/src/mat3.rs
narcissus-maths/src/mat4.rs
narcissus-maths/src/vec2.rs
narcissus-maths/src/vec3.rs

index 0d10b17936c736b07da42d9a1669532967be443d..8d3cafbd2ec36b3197f7730c7703ef14258b6593 100644 (file)
@@ -1,4 +1,4 @@
-use crate::{Mat2, Vec2};
+use crate::{Mat2, Point2, Vec2};
 
 /// Matrix and translation vector which together represent a 2d affine transformation.
 #[derive(Clone, Copy, PartialEq)]
@@ -7,3 +7,23 @@ pub struct Affine2 {
     matrix: Mat2,
     translate: Vec2,
 }
+
+impl Affine2 {
+    pub const ZERO: Affine2 = Affine2 {
+        matrix: Mat2::ZERO,
+        translate: Vec2::ZERO,
+    };
+
+    pub const IDENTITY: Affine2 = Affine2 {
+        matrix: Mat2::IDENTITY,
+        translate: Vec2::ZERO,
+    };
+
+    pub fn mul_vec2(&self, vec: Vec2) -> Vec2 {
+        todo!()
+    }
+
+    pub fn mul_point2(&self, point: Point2) -> Point2 {
+        todo!()
+    }
+}
index 39c924eef529db3d95f313ae02aeeccf95c19141..eac081492e726ce946d97ddbea5ba7e3e6508fc5 100644 (file)
@@ -1,4 +1,4 @@
-use crate::{Mat3, Vec3};
+use crate::{Mat3, Point3, Vec2, Vec3};
 
 /// Matrix and translation vector which together represent a 3d affine transformation.
 #[derive(Clone, Copy, PartialEq)]
@@ -7,3 +7,78 @@ pub struct Affine3 {
     matrix: Mat3,
     translate: Vec3,
 }
+
+impl Affine3 {
+    pub const ZERO: Affine3 = Affine3 {
+        matrix: Mat3::ZERO,
+        translate: Vec3::ZERO,
+    };
+
+    pub const IDENTITY: Affine3 = Affine3 {
+        matrix: Mat3::IDENTITY,
+        translate: Vec3::ZERO,
+    };
+
+    pub const fn from_scale(scale: Vec3) -> Affine3 {
+        Self {
+            matrix: Mat3::from_scale(scale),
+            translate: Vec3::ZERO,
+        }
+    }
+
+    pub const fn from_translation(translate: Vec3) -> Affine3 {
+        Self {
+            matrix: Mat3::IDENTITY,
+            translate,
+        }
+    }
+
+    pub fn mul_affine3(&self, rhs: Affine3) -> Affine3 {
+        Self {
+            matrix: self.matrix * rhs.matrix,
+            translate: self.translate + rhs.translate,
+        }
+    }
+
+    pub fn mul_vec3(&self, vec: Vec3) -> Vec3 {
+        self.matrix * vec + self.translate
+    }
+
+    pub fn mul_point3(&self, point: Point3) -> Point3 {
+        self.matrix * point + self.translate
+    }
+}
+
+impl std::ops::Mul for Affine3 {
+    type Output = Affine3;
+
+    #[inline(always)]
+    fn mul(self, rhs: Self) -> Self::Output {
+        self.mul_affine3(rhs)
+    }
+}
+
+impl std::ops::MulAssign for Affine3 {
+    #[inline(always)]
+    fn mul_assign(&mut self, rhs: Self) {
+        *self = *self * rhs
+    }
+}
+
+impl std::ops::Mul<Vec3> for Affine3 {
+    type Output = Vec3;
+
+    #[inline(always)]
+    fn mul(self, rhs: Vec3) -> Self::Output {
+        self.mul_vec3(rhs)
+    }
+}
+
+impl std::ops::Mul<Point3> for Affine3 {
+    type Output = Point3;
+
+    #[inline(always)]
+    fn mul(self, rhs: Point3) -> Self::Output {
+        self.mul_point3(rhs)
+    }
+}
index e36669feea1e88c49a93529a923e9f84482bcd0d..afab4bbef1dff78308006406064ffb875a51fe08 100644 (file)
@@ -1,3 +1,5 @@
+use crate::{Point2, Vec2};
+
 /// 2x2 matrix.
 #[derive(Clone, Copy, PartialEq)]
 #[repr(C)]
@@ -35,4 +37,113 @@ impl Mat2 {
     pub const fn from_rows(rows: [[f32; 2]; 2]) -> Self {
         unsafe { std::mem::transmute(rows) }
     }
+
+    /// Construct a matrix with the provided `diagonal` and all other values set to `0.0`.
+    pub const fn from_diagonal(diagonal: Vec2) -> Mat2 {
+        Mat2::from_rows([[diagonal.x, 0.0], [0.0, diagonal.y]])
+    }
+
+    /// Construct a transformation matrix which scales along the coordinate axis by the values given in `scale`.
+    pub const fn from_scale(scale: Vec2) -> Mat2 {
+        Mat2::from_diagonal(scale)
+    }
+
+    /// Returns the transpose of `self`.
+    #[must_use]
+    #[inline(always)]
+    pub fn transpose(self) -> Mat2 {
+        let m = &self.0;
+        Mat2::from_rows([[m[0], m[2]], [m[1], m[3]]])
+    }
+
+    #[must_use]
+    pub fn mul_mat2(self: &Mat2, rhs: Mat2) -> Mat2 {
+        let mut result = Mat2::IDENTITY;
+        {
+            let result = result.as_rows_mut();
+            let lhs = self.as_rows();
+            let rhs = rhs.as_rows();
+            for i in 0..2 {
+                for j in 0..2 {
+                    result[i][j] = lhs[i][0] * rhs[0][j] + lhs[i][1] * rhs[1][j];
+                }
+            }
+        }
+        result
+    }
+
+    #[must_use]
+    #[inline]
+    pub fn mul_point2(self: &Mat2, point: Point2) -> Point2 {
+        self.mul_vec2(point.as_vec2()).as_point2()
+    }
+
+    #[must_use]
+    #[inline]
+    pub fn mul_vec2(self: &Mat2, vec: Vec2) -> Vec2 {
+        let vec = Vec2::new(vec.x, vec.y);
+        let rows = self.as_rows();
+        Vec2::new(
+            Vec2::dot(rows[0].into(), vec),
+            Vec2::dot(rows[1].into(), vec),
+        )
+    }
+}
+
+impl std::ops::Mul for Mat2 {
+    type Output = Mat2;
+
+    #[inline(always)]
+    fn mul(self, rhs: Self) -> Self::Output {
+        self.mul_mat2(rhs)
+    }
+}
+
+impl std::ops::MulAssign for Mat2 {
+    #[inline(always)]
+    fn mul_assign(&mut self, rhs: Self) {
+        *self = *self * rhs
+    }
+}
+
+impl std::ops::Mul<Vec2> for Mat2 {
+    type Output = Vec2;
+
+    #[inline(always)]
+    fn mul(self, rhs: Vec2) -> Self::Output {
+        self.mul_vec2(rhs)
+    }
+}
+
+impl std::ops::Mul<Point2> for Mat2 {
+    type Output = Point2;
+
+    #[inline(always)]
+    fn mul(self, rhs: Point2) -> Self::Output {
+        self.mul_point2(rhs)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::Mat2;
+
+    const I: Mat2 = Mat2::IDENTITY;
+    const M: Mat2 = Mat2::from_rows([[1.0, 2.0], [3.0, 4.0]]);
+    const T: Mat2 = Mat2::from_rows([[1.0, 3.0], [2.0, 4.0]]);
+
+    #[test]
+    fn transpose() {
+        assert_eq!(I.transpose(), I);
+        assert_eq!(M.transpose(), T);
+        assert_eq!(M.transpose().transpose(), M);
+        assert_eq!(T.transpose().transpose(), T);
+    }
+
+    #[test]
+    fn mul() {
+        assert_eq!(I * I, I);
+        assert_eq!(M * I, M);
+        assert_eq!(I * M, M);
+    }
 }
index 33741fc9f15ff8bf69fb9ede33190f26bb8d39b2..38f6ae2a2f713ac74cb92b406cac6feef3673f92 100644 (file)
@@ -1,4 +1,4 @@
-use crate::{Rad, Vec3};
+use crate::{sin_cos_pi_f32, HalfTurn, Point2, Point3, Vec2, Vec3};
 
 /// 3x3 matrix.
 #[derive(Clone, Copy, PartialEq)]
@@ -53,8 +53,8 @@ impl Mat3 {
     }
 
     /// Constructs a transformation matrix which rotates around the given `axis` by `angle`.
-    pub fn from_axis_angle(axis: Vec3, angle: Rad) -> Mat3 {
-        let (sin, cos) = angle.as_f32().sin_cos();
+    pub fn from_axis_rotation(axis: Vec3, rotation: HalfTurn) -> Mat3 {
+        let (sin, cos) = sin_cos_pi_f32(rotation.as_f32());
         let axis_sin = axis * sin;
         let axis_sq = axis * axis;
         let one_minus_cos = 1.0 - cos;
@@ -79,4 +79,166 @@ impl Mat3 {
             ],
         ])
     }
+
+    /// Returns the transpose of `self`.
+    #[must_use]
+    #[inline(always)]
+    pub fn transpose(self) -> Mat3 {
+        let m = &self.0;
+        Mat3::from_rows([[m[0], m[3], m[6]], [m[1], m[4], m[7]], [m[2], m[5], m[8]]])
+    }
+
+    #[must_use]
+    pub fn mul_mat3(self: &Mat3, rhs: Mat3) -> Mat3 {
+        let mut result = Mat3::IDENTITY;
+        {
+            let result = result.as_rows_mut();
+            let lhs = self.as_rows();
+            let rhs = rhs.as_rows();
+            for i in 0..3 {
+                for j in 0..3 {
+                    result[i][j] =
+                        lhs[i][0] * rhs[0][j] + lhs[i][1] * rhs[1][j] + lhs[i][2] * rhs[2][j];
+                }
+            }
+        }
+        result
+    }
+
+    #[must_use]
+    #[inline]
+    pub fn mul_point2(self: &Mat3, point: Point2) -> Point2 {
+        let vec = Vec3::new(point.x, point.y, 1.0);
+        let rows = self.as_rows();
+        Point2::new(
+            Vec3::dot(rows[0].into(), vec),
+            Vec3::dot(rows[1].into(), vec),
+        )
+    }
+
+    #[must_use]
+    #[inline]
+    pub fn mul_vec2(self: &Mat3, vec: Vec2) -> Vec2 {
+        let vec = Vec3::new(vec.x, vec.y, 0.0);
+        let rows = self.as_rows();
+        Vec2::new(
+            Vec3::dot(rows[0].into(), vec),
+            Vec3::dot(rows[1].into(), vec),
+        )
+    }
+
+    #[must_use]
+    #[inline]
+    pub fn mul_point3(self: &Mat3, point: Point3) -> Point3 {
+        self.mul_vec3(point.as_vec3()).as_point3()
+    }
+
+    #[must_use]
+    #[inline]
+    pub fn mul_vec3(self: &Mat3, vec: Vec3) -> Vec3 {
+        let rows = self.as_rows();
+        Vec3::new(
+            Vec3::dot(rows[0].into(), vec),
+            Vec3::dot(rows[1].into(), vec),
+            Vec3::dot(rows[2].into(), vec),
+        )
+    }
+}
+
+impl std::ops::Mul for Mat3 {
+    type Output = Mat3;
+
+    #[inline(always)]
+    fn mul(self, rhs: Self) -> Self::Output {
+        self.mul_mat3(rhs)
+    }
+}
+
+impl std::ops::MulAssign for Mat3 {
+    #[inline(always)]
+    fn mul_assign(&mut self, rhs: Self) {
+        *self = *self * rhs
+    }
+}
+
+impl std::ops::Mul<Vec3> for Mat3 {
+    type Output = Vec3;
+
+    #[inline(always)]
+    fn mul(self, rhs: Vec3) -> Self::Output {
+        self.mul_vec3(rhs)
+    }
+}
+
+impl std::ops::Mul<Point3> for Mat3 {
+    type Output = Point3;
+
+    #[inline(always)]
+    fn mul(self, rhs: Point3) -> Self::Output {
+        self.mul_point3(rhs)
+    }
+}
+
+impl std::ops::Mul<Vec2> for Mat3 {
+    type Output = Vec2;
+
+    #[inline(always)]
+    fn mul(self, rhs: Vec2) -> Self::Output {
+        self.mul_vec2(rhs)
+    }
+}
+
+impl std::ops::Mul<Point2> for Mat3 {
+    type Output = Point2;
+
+    #[inline(always)]
+    fn mul(self, rhs: Point2) -> Self::Output {
+        self.mul_point2(rhs)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::{HalfTurn, Mat3, Vec2, Vec3};
+
+    const I: Mat3 = Mat3::IDENTITY;
+    const M: Mat3 = Mat3::from_rows([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]);
+    const T: Mat3 = Mat3::from_rows([[1.0, 4.0, 7.0], [2.0, 5.0, 8.0], [3.0, 6.0, 9.0]]);
+
+    #[test]
+    fn transpose() {
+        assert_eq!(I.transpose(), I);
+        assert_eq!(M.transpose(), T);
+        assert_eq!(M.transpose().transpose(), M);
+        assert_eq!(T.transpose().transpose(), T);
+    }
+
+    #[test]
+    fn axis_angle() {
+        let rot_180_x = Mat3::from_axis_rotation(Vec3::X, HalfTurn::new(1.0));
+        assert_eq!(rot_180_x * Vec3::X, Vec3::X);
+        assert_eq!(rot_180_x * Vec3::Y, -Vec3::Y);
+        assert_eq!(rot_180_x * Vec3::Z, -Vec3::Z);
+        assert_eq!(rot_180_x * Vec2::X, Vec2::X);
+        assert_eq!(rot_180_x * Vec2::Y, -Vec2::Y);
+        let rot_180_y = Mat3::from_axis_rotation(Vec3::Y, HalfTurn::new(1.0));
+        assert_eq!(rot_180_y * Vec3::X, -Vec3::X);
+        assert_eq!(rot_180_y * Vec3::Y, Vec3::Y);
+        assert_eq!(rot_180_y * Vec3::Z, -Vec3::Z);
+        assert_eq!(rot_180_y * Vec2::X, -Vec2::X);
+        assert_eq!(rot_180_y * Vec2::Y, Vec2::Y);
+        let rot_180_z = Mat3::from_axis_rotation(Vec3::Z, HalfTurn::new(1.0));
+        assert_eq!(rot_180_z * Vec3::X, -Vec3::X);
+        assert_eq!(rot_180_z * Vec3::Y, -Vec3::Y);
+        assert_eq!(rot_180_z * Vec3::Z, Vec3::Z);
+        assert_eq!(rot_180_z * Vec2::X, -Vec2::X);
+        assert_eq!(rot_180_z * Vec2::Y, -Vec2::Y);
+    }
+
+    #[test]
+    fn mul() {
+        assert_eq!(I * I, I);
+        assert_eq!(M * I, M);
+        assert_eq!(I * M, M);
+    }
 }
index c506275b8c8711b6ba36b226c85e6d0a579aafed..12425c66617aa763fad32c27e1de8b75c99fdb76 100644 (file)
@@ -491,9 +491,7 @@ impl std::ops::Mul<Point2> for Mat4 {
 mod tests {
     use super::*;
 
-    const IDENTITY: Mat4 = Mat4::IDENTITY;
-    const SCALE: Mat4 = Mat4::from_scale(Vec3::splat(2.0));
-    const TRANSLATE: Mat4 = Mat4::from_translation(Vec3::new(1.0, 2.0, 3.0));
+    const I: Mat4 = Mat4::IDENTITY;
     const M: Mat4 = Mat4::from_rows([
         [1.0, 2.0, 3.0, 4.0],
         [5.0, 6.0, 7.0, 8.0],
@@ -507,6 +505,9 @@ mod tests {
         [4.0, 8.0, 12.0, 16.0],
     ]);
 
+    const SCALE: Mat4 = Mat4::from_scale(Vec3::splat(2.0));
+    const TRANSLATE: Mat4 = Mat4::from_translation(Vec3::new(1.0, 2.0, 3.0));
+
     const V2: Vec2 = Vec2::new(1.0, 2.0);
     const V3: Vec3 = Vec3::new(1.0, 2.0, 3.0);
     const V4: Vec4 = Vec4::new(1.0, 2.0, 3.0, 4.0);
@@ -515,9 +516,10 @@ mod tests {
 
     #[test]
     fn transpose() {
-        assert_eq!(IDENTITY.transpose(), IDENTITY);
+        assert_eq!(I.transpose(), I);
         assert_eq!(M.transpose(), T);
         assert_eq!(M.transpose().transpose(), M);
+        assert_eq!(T.transpose().transpose(), T);
     }
 
     #[test]
@@ -526,43 +528,49 @@ mod tests {
         assert_eq!(rot_180_x * Vec3::X, Vec3::X);
         assert_eq!(rot_180_x * Vec3::Y, -Vec3::Y);
         assert_eq!(rot_180_x * Vec3::Z, -Vec3::Z);
+        assert_eq!(rot_180_x * Vec2::X, Vec2::X);
+        assert_eq!(rot_180_x * Vec2::Y, -Vec2::Y);
         let rot_180_y = Mat4::from_axis_rotation(Vec3::Y, HalfTurn::new(1.0));
         assert_eq!(rot_180_y * Vec3::X, -Vec3::X);
         assert_eq!(rot_180_y * Vec3::Y, Vec3::Y);
         assert_eq!(rot_180_y * Vec3::Z, -Vec3::Z);
+        assert_eq!(rot_180_y * Vec2::X, -Vec2::X);
+        assert_eq!(rot_180_y * Vec2::Y, Vec2::Y);
         let rot_180_z = Mat4::from_axis_rotation(Vec3::Z, HalfTurn::new(1.0));
         assert_eq!(rot_180_z * Vec3::X, -Vec3::X);
         assert_eq!(rot_180_z * Vec3::Y, -Vec3::Y);
         assert_eq!(rot_180_z * Vec3::Z, Vec3::Z);
+        assert_eq!(rot_180_z * Vec2::X, -Vec2::X);
+        assert_eq!(rot_180_z * Vec2::Y, -Vec2::Y);
     }
 
     #[test]
     fn mul() {
-        assert_eq!(IDENTITY * IDENTITY, IDENTITY);
-        assert_eq!(SCALE * IDENTITY, SCALE);
-        assert_eq!(M * IDENTITY, M);
+        assert_eq!(I * I, I);
+        assert_eq!(SCALE * I, SCALE);
+        assert_eq!(M * I, M);
 
-        assert_eq!(IDENTITY.mul_mat4_base(IDENTITY), IDENTITY);
-        assert_eq!(SCALE.mul_mat4_base(IDENTITY), SCALE);
-        assert_eq!(M.mul_mat4_base(IDENTITY), M);
+        assert_eq!(I.mul_mat4_base(I), I);
+        assert_eq!(SCALE.mul_mat4_base(I), SCALE);
+        assert_eq!(M.mul_mat4_base(I), M);
 
         if std::is_x86_feature_detected!("sse2") {
-            assert_eq!(unsafe { IDENTITY.mul_mat4_sse2(IDENTITY) }, IDENTITY);
-            assert_eq!(unsafe { SCALE.mul_mat4_sse2(IDENTITY) }, SCALE);
-            assert_eq!(unsafe { M.mul_mat4_sse2(IDENTITY) }, M);
+            assert_eq!(unsafe { I.mul_mat4_sse2(I) }, I);
+            assert_eq!(unsafe { SCALE.mul_mat4_sse2(I) }, SCALE);
+            assert_eq!(unsafe { M.mul_mat4_sse2(I) }, M);
         }
 
         if std::is_x86_feature_detected!("avx2") {
-            assert_eq!(unsafe { IDENTITY.mul_mat4_avx2(IDENTITY) }, IDENTITY);
-            assert_eq!(unsafe { SCALE.mul_mat4_avx2(IDENTITY) }, SCALE);
-            assert_eq!(unsafe { M.mul_mat4_avx2(IDENTITY) }, M);
+            assert_eq!(unsafe { I.mul_mat4_avx2(I) }, I);
+            assert_eq!(unsafe { SCALE.mul_mat4_avx2(I) }, SCALE);
+            assert_eq!(unsafe { M.mul_mat4_avx2(I) }, M);
         }
     }
 
     #[test]
     fn mul_vec2() {
-        assert_eq!(IDENTITY * Vec2::ZERO, Vec2::ZERO);
-        assert_eq!(IDENTITY * V2, V2);
+        assert_eq!(I * Vec2::ZERO, Vec2::ZERO);
+        assert_eq!(I * V2, V2);
         assert_eq!(SCALE * Vec2::ZERO, Vec2::ZERO);
         assert_eq!(SCALE * Vec2::ONE, Vec2::splat(2.0));
         assert_eq!(TRANSLATE * Vec2::ZERO, Vec2::ZERO);
@@ -570,8 +578,8 @@ mod tests {
 
     #[test]
     fn mul_point2() {
-        assert_eq!(IDENTITY * Point2::ZERO, Point2::ZERO);
-        assert_eq!(IDENTITY * P2, P2);
+        assert_eq!(I * Point2::ZERO, Point2::ZERO);
+        assert_eq!(I * P2, P2);
         assert_eq!(SCALE * Point2::ZERO, Point2::ZERO);
         assert_eq!(SCALE * Point2::ONE, Point2::splat(2.0));
         assert_eq!(TRANSLATE * Point2::ZERO, P2);
@@ -579,8 +587,8 @@ mod tests {
 
     #[test]
     fn mul_vec3() {
-        assert_eq!(IDENTITY * Vec3::ZERO, Vec3::ZERO);
-        assert_eq!(IDENTITY * V3, V3);
+        assert_eq!(I * Vec3::ZERO, Vec3::ZERO);
+        assert_eq!(I * V3, V3);
         assert_eq!(SCALE * Vec3::ZERO, Vec3::ZERO);
         assert_eq!(SCALE * Vec3::ONE, Vec3::splat(2.0));
         assert_eq!(TRANSLATE * Vec3::ZERO, Vec3::ZERO);
@@ -588,8 +596,8 @@ mod tests {
 
     #[test]
     fn mul_point3() {
-        assert_eq!(IDENTITY * Point3::ZERO, Point3::ZERO);
-        assert_eq!(IDENTITY * P3, P3);
+        assert_eq!(I * Point3::ZERO, Point3::ZERO);
+        assert_eq!(I * P3, P3);
         assert_eq!(SCALE * Point3::ZERO, Point3::ZERO);
         assert_eq!(SCALE * Point3::ONE, Point3::splat(2.0));
         assert_eq!(TRANSLATE * Point3::ZERO, P3);
@@ -597,8 +605,8 @@ mod tests {
 
     #[test]
     fn mul_vec4() {
-        assert_eq!(IDENTITY * Vec4::ZERO, Vec4::ZERO);
-        assert_eq!(IDENTITY * V4, V4);
+        assert_eq!(I * Vec4::ZERO, Vec4::ZERO);
+        assert_eq!(I * V4, V4);
         assert_eq!(SCALE * Vec4::ZERO, Vec4::ZERO);
         assert_eq!(SCALE * Vec4::ONE, Vec4::new(2.0, 2.0, 2.0, 1.0));
         assert_eq!(
@@ -608,8 +616,8 @@ mod tests {
 
         if std::is_x86_feature_detected!("sse4.1") {
             unsafe {
-                assert_eq!(IDENTITY.mul_vec4_sse41(Vec4::ZERO), Vec4::ZERO);
-                assert_eq!(IDENTITY.mul_vec4_sse41(V4), V4);
+                assert_eq!(I.mul_vec4_sse41(Vec4::ZERO), Vec4::ZERO);
+                assert_eq!(I.mul_vec4_sse41(V4), V4);
                 assert_eq!(SCALE.mul_vec4_sse41(Vec4::ZERO), Vec4::ZERO);
                 assert_eq!(
                     SCALE.mul_vec4_sse41(Vec4::ONE),
index 8ca9ed4b21abb4603a4f5b203d42305136acc0ce..ad91d1cb7ebc356e719dcf7a4a92028b68e3308d 100644 (file)
@@ -1,4 +1,4 @@
-use crate::{impl_shared, impl_vector};
+use crate::{impl_shared, impl_vector, Point2};
 
 #[derive(Clone, Copy, PartialEq, PartialOrd, Default, Debug)]
 #[repr(C)]
@@ -20,6 +20,12 @@ impl Vec2 {
         Self { x, y }
     }
 
+    /// Converts this point to the equivalent point.
+    #[inline(always)]
+    pub const fn as_point2(self) -> Point2 {
+        Point2::new(self.x, self.y)
+    }
+
     /// Returns a [`Vec2`] with the function `f` applied to each component in order.
     #[inline(always)]
     pub fn map<F>(self, mut f: F) -> Vec2
@@ -53,7 +59,7 @@ impl Vec2 {
 
 impl std::ops::Add for Vec2 {
     type Output = Vec2;
-    #[inline]
+    #[inline(always)]
     fn add(self, rhs: Self) -> Self::Output {
         Self::Output {
             x: self.x + rhs.x,
@@ -64,7 +70,7 @@ impl std::ops::Add for Vec2 {
 
 impl std::ops::Sub for Vec2 {
     type Output = Vec2;
-    #[inline]
+    #[inline(always)]
     fn sub(self, rhs: Self) -> Self::Output {
         Self::Output {
             x: self.x - rhs.x,
@@ -75,7 +81,7 @@ impl std::ops::Sub for Vec2 {
 
 impl std::ops::Mul for Vec2 {
     type Output = Vec2;
-    #[inline]
+    #[inline(always)]
     fn mul(self, rhs: Self) -> Self::Output {
         Self::Output {
             x: self.x * rhs.x,
@@ -86,7 +92,7 @@ impl std::ops::Mul for Vec2 {
 
 impl std::ops::Div for Vec2 {
     type Output = Vec2;
-    #[inline]
+    #[inline(always)]
     fn div(self, rhs: Self) -> Self::Output {
         Self::Output {
             x: self.x / rhs.x,
@@ -96,7 +102,7 @@ impl std::ops::Div for Vec2 {
 }
 
 impl std::ops::AddAssign for Vec2 {
-    #[inline]
+    #[inline(always)]
     fn add_assign(&mut self, rhs: Self) {
         self.x += rhs.x;
         self.y += rhs.y;
@@ -104,7 +110,7 @@ impl std::ops::AddAssign for Vec2 {
 }
 
 impl std::ops::SubAssign for Vec2 {
-    #[inline]
+    #[inline(always)]
     fn sub_assign(&mut self, rhs: Self) {
         self.x -= rhs.x;
         self.y -= rhs.y;
@@ -112,7 +118,7 @@ impl std::ops::SubAssign for Vec2 {
 }
 
 impl std::ops::MulAssign for Vec2 {
-    #[inline]
+    #[inline(always)]
     fn mul_assign(&mut self, rhs: Self) {
         self.x *= rhs.x;
         self.y *= rhs.y;
@@ -120,7 +126,7 @@ impl std::ops::MulAssign for Vec2 {
 }
 
 impl std::ops::DivAssign for Vec2 {
-    #[inline]
+    #[inline(always)]
     fn div_assign(&mut self, rhs: Self) {
         self.x /= rhs.x;
         self.y /= rhs.y;
index b758641b87181a5b106aabbb151b42127ca366bd..488b4792e3312236251979ddeb22e687b706253c 100644 (file)
@@ -1,4 +1,4 @@
-use crate::{impl_shared, impl_vector};
+use crate::{impl_shared, impl_vector, Point3};
 
 #[derive(Clone, Copy, PartialEq, PartialOrd, Default, Debug)]
 #[repr(C)]
@@ -22,6 +22,12 @@ impl Vec3 {
         Vec3 { x, y, z }
     }
 
+    /// Converts this point to the equivalent point.
+    #[inline(always)]
+    pub const fn as_point3(self) -> Point3 {
+        Point3::new(self.x, self.y, self.z)
+    }
+
     /// Returns a [`Vec3`] with the function `f` applied to each component in order.
     #[inline(always)]
     pub fn map<F>(self, mut f: F) -> Vec3
@@ -92,7 +98,7 @@ impl std::ops::Sub for Vec3 {
 
 impl std::ops::Mul for Vec3 {
     type Output = Vec3;
-    #[inline]
+    #[inline(always)]
     fn mul(self, rhs: Self) -> Self::Output {
         Self::Output {
             x: self.x * rhs.x,
@@ -104,7 +110,7 @@ impl std::ops::Mul for Vec3 {
 
 impl std::ops::Div for Vec3 {
     type Output = Vec3;
-    #[inline]
+    #[inline(always)]
     fn div(self, rhs: Self) -> Self::Output {
         Self::Output {
             x: self.x / rhs.x,
@@ -115,7 +121,7 @@ impl std::ops::Div for Vec3 {
 }
 
 impl std::ops::AddAssign for Vec3 {
-    #[inline]
+    #[inline(always)]
     fn add_assign(&mut self, rhs: Self) {
         self.x += rhs.x;
         self.y += rhs.y;
@@ -124,7 +130,7 @@ impl std::ops::AddAssign for Vec3 {
 }
 
 impl std::ops::SubAssign for Vec3 {
-    #[inline]
+    #[inline(always)]
     fn sub_assign(&mut self, rhs: Self) {
         self.x -= rhs.x;
         self.y -= rhs.y;
@@ -142,7 +148,7 @@ impl std::ops::MulAssign for Vec3 {
 }
 
 impl std::ops::DivAssign for Vec3 {
-    #[inline]
+    #[inline(always)]
     fn div_assign(&mut self, rhs: Self) {
         self.x /= rhs.x;
         self.y /= rhs.y;