From eaf7256642808b10f8d24ee9e016af8579a60c54 Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Sun, 16 Oct 2022 23:41:28 +0200 Subject: [PATCH] Implement some more maths basics --- narcissus-maths/src/affine2.rs | 22 ++++- narcissus-maths/src/affine3.rs | 77 ++++++++++++++- narcissus-maths/src/mat2.rs | 111 ++++++++++++++++++++++ narcissus-maths/src/mat3.rs | 168 ++++++++++++++++++++++++++++++++- narcissus-maths/src/mat4.rs | 64 +++++++------ narcissus-maths/src/vec2.rs | 24 +++-- narcissus-maths/src/vec3.rs | 18 ++-- 7 files changed, 436 insertions(+), 48 deletions(-) diff --git a/narcissus-maths/src/affine2.rs b/narcissus-maths/src/affine2.rs index 0d10b17..8d3cafb 100644 --- a/narcissus-maths/src/affine2.rs +++ b/narcissus-maths/src/affine2.rs @@ -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!() + } +} diff --git a/narcissus-maths/src/affine3.rs b/narcissus-maths/src/affine3.rs index 39c924e..eac0814 100644 --- a/narcissus-maths/src/affine3.rs +++ b/narcissus-maths/src/affine3.rs @@ -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 for Affine3 { + type Output = Vec3; + + #[inline(always)] + fn mul(self, rhs: Vec3) -> Self::Output { + self.mul_vec3(rhs) + } +} + +impl std::ops::Mul for Affine3 { + type Output = Point3; + + #[inline(always)] + fn mul(self, rhs: Point3) -> Self::Output { + self.mul_point3(rhs) + } +} diff --git a/narcissus-maths/src/mat2.rs b/narcissus-maths/src/mat2.rs index e36669f..afab4bb 100644 --- a/narcissus-maths/src/mat2.rs +++ b/narcissus-maths/src/mat2.rs @@ -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 for Mat2 { + type Output = Vec2; + + #[inline(always)] + fn mul(self, rhs: Vec2) -> Self::Output { + self.mul_vec2(rhs) + } +} + +impl std::ops::Mul 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); + } } diff --git a/narcissus-maths/src/mat3.rs b/narcissus-maths/src/mat3.rs index 33741fc..38f6ae2 100644 --- a/narcissus-maths/src/mat3.rs +++ b/narcissus-maths/src/mat3.rs @@ -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 for Mat3 { + type Output = Vec3; + + #[inline(always)] + fn mul(self, rhs: Vec3) -> Self::Output { + self.mul_vec3(rhs) + } +} + +impl std::ops::Mul for Mat3 { + type Output = Point3; + + #[inline(always)] + fn mul(self, rhs: Point3) -> Self::Output { + self.mul_point3(rhs) + } +} + +impl std::ops::Mul for Mat3 { + type Output = Vec2; + + #[inline(always)] + fn mul(self, rhs: Vec2) -> Self::Output { + self.mul_vec2(rhs) + } +} + +impl std::ops::Mul 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); + } } diff --git a/narcissus-maths/src/mat4.rs b/narcissus-maths/src/mat4.rs index c506275..12425c6 100644 --- a/narcissus-maths/src/mat4.rs +++ b/narcissus-maths/src/mat4.rs @@ -491,9 +491,7 @@ impl std::ops::Mul 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), diff --git a/narcissus-maths/src/vec2.rs b/narcissus-maths/src/vec2.rs index 8ca9ed4..ad91d1c 100644 --- a/narcissus-maths/src/vec2.rs +++ b/narcissus-maths/src/vec2.rs @@ -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(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; diff --git a/narcissus-maths/src/vec3.rs b/narcissus-maths/src/vec3.rs index b758641..488b479 100644 --- a/narcissus-maths/src/vec3.rs +++ b/narcissus-maths/src/vec3.rs @@ -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(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; -- 2.49.0