From ab85e2a6aed9902845be2fe644d9fca2abf80444 Mon Sep 17 00:00:00 2001 From: Cameron Hart Date: Mon, 11 Mar 2024 16:40:46 +1300 Subject: [PATCH] Add Div and DivAssign by scalar implementations to matrix types. (#489) Fixes #476 --- CHANGELOG.md | 2 ++ codegen/templates/mat.rs.tera | 45 ++++++++++++++++++++++++++++++++++- src/f32/coresimd/mat2.rs | 32 ++++++++++++++++++++++++- src/f32/coresimd/mat3a.rs | 37 +++++++++++++++++++++++++++- src/f32/coresimd/mat4.rs | 38 ++++++++++++++++++++++++++++- src/f32/mat3.rs | 37 +++++++++++++++++++++++++++- src/f32/scalar/mat2.rs | 33 ++++++++++++++++++++++++- src/f32/scalar/mat3a.rs | 37 +++++++++++++++++++++++++++- src/f32/scalar/mat4.rs | 38 ++++++++++++++++++++++++++++- src/f32/sse2/mat2.rs | 32 ++++++++++++++++++++++++- src/f32/sse2/mat3a.rs | 37 +++++++++++++++++++++++++++- src/f32/sse2/mat4.rs | 38 ++++++++++++++++++++++++++++- src/f32/wasm32/mat2.rs | 32 ++++++++++++++++++++++++- src/f32/wasm32/mat3a.rs | 37 +++++++++++++++++++++++++++- src/f32/wasm32/mat4.rs | 38 ++++++++++++++++++++++++++++- src/f64/dmat2.rs | 33 ++++++++++++++++++++++++- src/f64/dmat3.rs | 37 +++++++++++++++++++++++++++- src/f64/dmat4.rs | 38 ++++++++++++++++++++++++++++- tests/mat2.rs | 6 +++++ tests/mat3.rs | 6 +++++ tests/mat4.rs | 6 +++++ 21 files changed, 622 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b418effb..8df33879 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,8 @@ The format is based on [Keep a Changelog], and this project adheres to * Added `From` support for all vector types. + * Added `Div` and `DivAssign` by scalar implementations to matrix types. + ## [0.25.0] - 2023-12-19 ### Breaking changes diff --git a/codegen/templates/mat.rs.tera b/codegen/templates/mat.rs.tera index 25a8c140..5b03978e 100644 --- a/codegen/templates/mat.rs.tera +++ b/codegen/templates/mat.rs.tera @@ -98,7 +98,7 @@ use crate::{ #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; {% if is_sse2 %} #[cfg(target_arch = "x86")] @@ -2068,6 +2068,26 @@ impl {{ self_t }} { {% endif %} } + /// Divides a {{ nxn }} matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: {{ scalar_t }}) -> Self { + {% if self_t == "Mat2" and is_sse2 %} + Self(unsafe { _mm_div_ps(self.0, _mm_set_ps1(rhs)) }) + {% elif self_t == "Mat2" and is_wasm32 %} + Self(f32x4_div(self.0, f32x4_splat(rhs))) + {% elif self_t == "Mat2" and is_coresimd %} + Self(self.0 / f32x4::splat(rhs)) + {% else %} + let rhs = {{ col_t }}::splat(rhs); + Self::from_cols( + {% for axis in axes %} + self.{{ axis }}.div(rhs), + {%- endfor %} + ) + {% endif %} + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -2225,6 +2245,29 @@ impl MulAssign<{{ scalar_t }}> for {{ self_t }} { } } +impl Div<{{ self_t }}> for {{ scalar_t }} { + type Output = {{ self_t }}; + #[inline] + fn div(self, rhs: {{ self_t }}) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div<{{ scalar_t }}> for {{ self_t }} { + type Output = Self; + #[inline] + fn div(self, rhs: {{ scalar_t }}) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign<{{ scalar_t }}> for {{ self_t }} { + #[inline] + fn div_assign(&mut self, rhs: {{ scalar_t }}) { + *self = self.div_scalar(rhs); + } +} + {% if self_t == "Mat3" %} impl Mul for Mat3 { type Output = Vec3A; diff --git a/src/f32/coresimd/mat2.rs b/src/f32/coresimd/mat2.rs index f0e604ec..f4fd04f7 100644 --- a/src/f32/coresimd/mat2.rs +++ b/src/f32/coresimd/mat2.rs @@ -4,7 +4,7 @@ use crate::{f32::math, swizzles::*, DMat2, Mat3, Mat3A, Vec2}; #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use core::simd::*; @@ -293,6 +293,13 @@ impl Mat2 { Self(self.0 * f32x4::splat(rhs)) } + /// Divides a 2x2 matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: f32) -> Self { + Self(self.0 / f32x4::splat(rhs)) + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -413,6 +420,29 @@ impl MulAssign for Mat2 { } } +impl Div for f32 { + type Output = Mat2; + #[inline] + fn div(self, rhs: Mat2) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div for Mat2 { + type Output = Self; + #[inline] + fn div(self, rhs: f32) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign for Mat2 { + #[inline] + fn div_assign(&mut self, rhs: f32) { + *self = self.div_scalar(rhs); + } +} + impl Sum for Mat2 { fn sum(iter: I) -> Self where diff --git a/src/f32/coresimd/mat3a.rs b/src/f32/coresimd/mat3a.rs index 733f97f1..927ab2b7 100644 --- a/src/f32/coresimd/mat3a.rs +++ b/src/f32/coresimd/mat3a.rs @@ -4,7 +4,7 @@ use crate::{f32::math, swizzles::*, DMat3, EulerRot, Mat2, Mat3, Mat4, Quat, Vec #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use core::simd::*; @@ -559,6 +559,18 @@ impl Mat3A { ) } + /// Divides a 3x3 matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: f32) -> Self { + let rhs = Vec3A::splat(rhs); + Self::from_cols( + self.x_axis.div(rhs), + self.y_axis.div(rhs), + self.z_axis.div(rhs), + ) + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -684,6 +696,29 @@ impl MulAssign for Mat3A { } } +impl Div for f32 { + type Output = Mat3A; + #[inline] + fn div(self, rhs: Mat3A) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div for Mat3A { + type Output = Self; + #[inline] + fn div(self, rhs: f32) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign for Mat3A { + #[inline] + fn div_assign(&mut self, rhs: f32) { + *self = self.div_scalar(rhs); + } +} + impl Mul for Mat3A { type Output = Vec3; #[inline] diff --git a/src/f32/coresimd/mat4.rs b/src/f32/coresimd/mat4.rs index 78987f97..8a18b8cc 100644 --- a/src/f32/coresimd/mat4.rs +++ b/src/f32/coresimd/mat4.rs @@ -6,7 +6,7 @@ use crate::{ #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use core::simd::*; @@ -1201,6 +1201,19 @@ impl Mat4 { ) } + /// Divides a 4x4 matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: f32) -> Self { + let rhs = Vec4::splat(rhs); + Self::from_cols( + self.x_axis.div(rhs), + self.y_axis.div(rhs), + self.z_axis.div(rhs), + self.w_axis.div(rhs), + ) + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -1338,6 +1351,29 @@ impl MulAssign for Mat4 { } } +impl Div for f32 { + type Output = Mat4; + #[inline] + fn div(self, rhs: Mat4) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div for Mat4 { + type Output = Self; + #[inline] + fn div(self, rhs: f32) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign for Mat4 { + #[inline] + fn div_assign(&mut self, rhs: f32) { + *self = self.div_scalar(rhs); + } +} + impl Sum for Mat4 { fn sum(iter: I) -> Self where diff --git a/src/f32/mat3.rs b/src/f32/mat3.rs index 7c419cda..0203231c 100644 --- a/src/f32/mat3.rs +++ b/src/f32/mat3.rs @@ -4,7 +4,7 @@ use crate::{f32::math, swizzles::*, DMat3, EulerRot, Mat2, Mat3A, Mat4, Quat, Ve #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; /// Creates a 3x3 matrix from three column vectors. #[inline(always)] @@ -553,6 +553,18 @@ impl Mat3 { ) } + /// Divides a 3x3 matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: f32) -> Self { + let rhs = Vec3::splat(rhs); + Self::from_cols( + self.x_axis.div(rhs), + self.y_axis.div(rhs), + self.z_axis.div(rhs), + ) + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -678,6 +690,29 @@ impl MulAssign for Mat3 { } } +impl Div for f32 { + type Output = Mat3; + #[inline] + fn div(self, rhs: Mat3) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div for Mat3 { + type Output = Self; + #[inline] + fn div(self, rhs: f32) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign for Mat3 { + #[inline] + fn div_assign(&mut self, rhs: f32) { + *self = self.div_scalar(rhs); + } +} + impl Mul for Mat3 { type Output = Vec3A; #[inline] diff --git a/src/f32/scalar/mat2.rs b/src/f32/scalar/mat2.rs index 12767c71..8ab90aa1 100644 --- a/src/f32/scalar/mat2.rs +++ b/src/f32/scalar/mat2.rs @@ -4,7 +4,7 @@ use crate::{f32::math, swizzles::*, DMat2, Mat3, Mat3A, Vec2}; #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; /// Creates a 2x2 matrix from two column vectors. #[inline(always)] @@ -288,6 +288,14 @@ impl Mat2 { Self::from_cols(self.x_axis.mul(rhs), self.y_axis.mul(rhs)) } + /// Divides a 2x2 matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: f32) -> Self { + let rhs = Vec2::splat(rhs); + Self::from_cols(self.x_axis.div(rhs), self.y_axis.div(rhs)) + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -408,6 +416,29 @@ impl MulAssign for Mat2 { } } +impl Div for f32 { + type Output = Mat2; + #[inline] + fn div(self, rhs: Mat2) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div for Mat2 { + type Output = Self; + #[inline] + fn div(self, rhs: f32) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign for Mat2 { + #[inline] + fn div_assign(&mut self, rhs: f32) { + *self = self.div_scalar(rhs); + } +} + impl Sum for Mat2 { fn sum(iter: I) -> Self where diff --git a/src/f32/scalar/mat3a.rs b/src/f32/scalar/mat3a.rs index e48b1d46..86f76e57 100644 --- a/src/f32/scalar/mat3a.rs +++ b/src/f32/scalar/mat3a.rs @@ -4,7 +4,7 @@ use crate::{f32::math, swizzles::*, DMat3, EulerRot, Mat2, Mat3, Mat4, Quat, Vec #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; /// Creates a 3x3 matrix from three column vectors. #[inline(always)] @@ -557,6 +557,18 @@ impl Mat3A { ) } + /// Divides a 3x3 matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: f32) -> Self { + let rhs = Vec3A::splat(rhs); + Self::from_cols( + self.x_axis.div(rhs), + self.y_axis.div(rhs), + self.z_axis.div(rhs), + ) + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -682,6 +694,29 @@ impl MulAssign for Mat3A { } } +impl Div for f32 { + type Output = Mat3A; + #[inline] + fn div(self, rhs: Mat3A) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div for Mat3A { + type Output = Self; + #[inline] + fn div(self, rhs: f32) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign for Mat3A { + #[inline] + fn div_assign(&mut self, rhs: f32) { + *self = self.div_scalar(rhs); + } +} + impl Mul for Mat3A { type Output = Vec3; #[inline] diff --git a/src/f32/scalar/mat4.rs b/src/f32/scalar/mat4.rs index 47953844..0de4514e 100644 --- a/src/f32/scalar/mat4.rs +++ b/src/f32/scalar/mat4.rs @@ -4,7 +4,7 @@ use crate::{f32::math, swizzles::*, DMat4, EulerRot, Mat3, Mat3A, Quat, Vec3, Ve #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; /// Creates a 4x4 matrix from four column vectors. #[inline(always)] @@ -1113,6 +1113,19 @@ impl Mat4 { ) } + /// Divides a 4x4 matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: f32) -> Self { + let rhs = Vec4::splat(rhs); + Self::from_cols( + self.x_axis.div(rhs), + self.y_axis.div(rhs), + self.z_axis.div(rhs), + self.w_axis.div(rhs), + ) + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -1250,6 +1263,29 @@ impl MulAssign for Mat4 { } } +impl Div for f32 { + type Output = Mat4; + #[inline] + fn div(self, rhs: Mat4) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div for Mat4 { + type Output = Self; + #[inline] + fn div(self, rhs: f32) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign for Mat4 { + #[inline] + fn div_assign(&mut self, rhs: f32) { + *self = self.div_scalar(rhs); + } +} + impl Sum for Mat4 { fn sum(iter: I) -> Self where diff --git a/src/f32/sse2/mat2.rs b/src/f32/sse2/mat2.rs index 7db655a9..d84b29a9 100644 --- a/src/f32/sse2/mat2.rs +++ b/src/f32/sse2/mat2.rs @@ -4,7 +4,7 @@ use crate::{f32::math, swizzles::*, DMat2, Mat3, Mat3A, Vec2}; #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; #[cfg(target_arch = "x86")] use core::arch::x86::*; @@ -325,6 +325,13 @@ impl Mat2 { Self(unsafe { _mm_mul_ps(self.0, _mm_set_ps1(rhs)) }) } + /// Divides a 2x2 matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: f32) -> Self { + Self(unsafe { _mm_div_ps(self.0, _mm_set_ps1(rhs)) }) + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -445,6 +452,29 @@ impl MulAssign for Mat2 { } } +impl Div for f32 { + type Output = Mat2; + #[inline] + fn div(self, rhs: Mat2) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div for Mat2 { + type Output = Self; + #[inline] + fn div(self, rhs: f32) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign for Mat2 { + #[inline] + fn div_assign(&mut self, rhs: f32) { + *self = self.div_scalar(rhs); + } +} + impl Sum for Mat2 { fn sum(iter: I) -> Self where diff --git a/src/f32/sse2/mat3a.rs b/src/f32/sse2/mat3a.rs index 141e6b47..4475c047 100644 --- a/src/f32/sse2/mat3a.rs +++ b/src/f32/sse2/mat3a.rs @@ -4,7 +4,7 @@ use crate::{f32::math, swizzles::*, DMat3, EulerRot, Mat2, Mat3, Mat4, Quat, Vec #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; #[cfg(target_arch = "x86")] use core::arch::x86::*; @@ -564,6 +564,18 @@ impl Mat3A { ) } + /// Divides a 3x3 matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: f32) -> Self { + let rhs = Vec3A::splat(rhs); + Self::from_cols( + self.x_axis.div(rhs), + self.y_axis.div(rhs), + self.z_axis.div(rhs), + ) + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -689,6 +701,29 @@ impl MulAssign for Mat3A { } } +impl Div for f32 { + type Output = Mat3A; + #[inline] + fn div(self, rhs: Mat3A) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div for Mat3A { + type Output = Self; + #[inline] + fn div(self, rhs: f32) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign for Mat3A { + #[inline] + fn div_assign(&mut self, rhs: f32) { + *self = self.div_scalar(rhs); + } +} + impl Mul for Mat3A { type Output = Vec3; #[inline] diff --git a/src/f32/sse2/mat4.rs b/src/f32/sse2/mat4.rs index 81926817..b3173f50 100644 --- a/src/f32/sse2/mat4.rs +++ b/src/f32/sse2/mat4.rs @@ -6,7 +6,7 @@ use crate::{ #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; #[cfg(target_arch = "x86")] use core::arch::x86::*; @@ -1210,6 +1210,19 @@ impl Mat4 { ) } + /// Divides a 4x4 matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: f32) -> Self { + let rhs = Vec4::splat(rhs); + Self::from_cols( + self.x_axis.div(rhs), + self.y_axis.div(rhs), + self.z_axis.div(rhs), + self.w_axis.div(rhs), + ) + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -1347,6 +1360,29 @@ impl MulAssign for Mat4 { } } +impl Div for f32 { + type Output = Mat4; + #[inline] + fn div(self, rhs: Mat4) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div for Mat4 { + type Output = Self; + #[inline] + fn div(self, rhs: f32) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign for Mat4 { + #[inline] + fn div_assign(&mut self, rhs: f32) { + *self = self.div_scalar(rhs); + } +} + impl Sum for Mat4 { fn sum(iter: I) -> Self where diff --git a/src/f32/wasm32/mat2.rs b/src/f32/wasm32/mat2.rs index 34dc8082..b8ecd23f 100644 --- a/src/f32/wasm32/mat2.rs +++ b/src/f32/wasm32/mat2.rs @@ -4,7 +4,7 @@ use crate::{f32::math, swizzles::*, DMat2, Mat3, Mat3A, Vec2}; #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use core::arch::wasm32::*; @@ -299,6 +299,13 @@ impl Mat2 { Self(f32x4_mul(self.0, f32x4_splat(rhs))) } + /// Divides a 2x2 matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: f32) -> Self { + Self(f32x4_div(self.0, f32x4_splat(rhs))) + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -419,6 +426,29 @@ impl MulAssign for Mat2 { } } +impl Div for f32 { + type Output = Mat2; + #[inline] + fn div(self, rhs: Mat2) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div for Mat2 { + type Output = Self; + #[inline] + fn div(self, rhs: f32) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign for Mat2 { + #[inline] + fn div_assign(&mut self, rhs: f32) { + *self = self.div_scalar(rhs); + } +} + impl Sum for Mat2 { fn sum(iter: I) -> Self where diff --git a/src/f32/wasm32/mat3a.rs b/src/f32/wasm32/mat3a.rs index c29ceccf..b1fdbf5b 100644 --- a/src/f32/wasm32/mat3a.rs +++ b/src/f32/wasm32/mat3a.rs @@ -4,7 +4,7 @@ use crate::{f32::math, swizzles::*, DMat3, EulerRot, Mat2, Mat3, Mat4, Quat, Vec #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use core::arch::wasm32::*; @@ -559,6 +559,18 @@ impl Mat3A { ) } + /// Divides a 3x3 matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: f32) -> Self { + let rhs = Vec3A::splat(rhs); + Self::from_cols( + self.x_axis.div(rhs), + self.y_axis.div(rhs), + self.z_axis.div(rhs), + ) + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -684,6 +696,29 @@ impl MulAssign for Mat3A { } } +impl Div for f32 { + type Output = Mat3A; + #[inline] + fn div(self, rhs: Mat3A) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div for Mat3A { + type Output = Self; + #[inline] + fn div(self, rhs: f32) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign for Mat3A { + #[inline] + fn div_assign(&mut self, rhs: f32) { + *self = self.div_scalar(rhs); + } +} + impl Mul for Mat3A { type Output = Vec3; #[inline] diff --git a/src/f32/wasm32/mat4.rs b/src/f32/wasm32/mat4.rs index c0eeecac..3d28ed50 100644 --- a/src/f32/wasm32/mat4.rs +++ b/src/f32/wasm32/mat4.rs @@ -6,7 +6,7 @@ use crate::{ #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use core::arch::wasm32::*; @@ -1201,6 +1201,19 @@ impl Mat4 { ) } + /// Divides a 4x4 matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: f32) -> Self { + let rhs = Vec4::splat(rhs); + Self::from_cols( + self.x_axis.div(rhs), + self.y_axis.div(rhs), + self.z_axis.div(rhs), + self.w_axis.div(rhs), + ) + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -1338,6 +1351,29 @@ impl MulAssign for Mat4 { } } +impl Div for f32 { + type Output = Mat4; + #[inline] + fn div(self, rhs: Mat4) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div for Mat4 { + type Output = Self; + #[inline] + fn div(self, rhs: f32) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign for Mat4 { + #[inline] + fn div_assign(&mut self, rhs: f32) { + *self = self.div_scalar(rhs); + } +} + impl Sum for Mat4 { fn sum(iter: I) -> Self where diff --git a/src/f64/dmat2.rs b/src/f64/dmat2.rs index 5608bfd7..208d158d 100644 --- a/src/f64/dmat2.rs +++ b/src/f64/dmat2.rs @@ -4,7 +4,7 @@ use crate::{f64::math, swizzles::*, DMat3, DVec2, Mat2}; #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; /// Creates a 2x2 matrix from two column vectors. #[inline(always)] @@ -277,6 +277,14 @@ impl DMat2 { Self::from_cols(self.x_axis.mul(rhs), self.y_axis.mul(rhs)) } + /// Divides a 2x2 matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: f64) -> Self { + let rhs = DVec2::splat(rhs); + Self::from_cols(self.x_axis.div(rhs), self.y_axis.div(rhs)) + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -397,6 +405,29 @@ impl MulAssign for DMat2 { } } +impl Div for f64 { + type Output = DMat2; + #[inline] + fn div(self, rhs: DMat2) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div for DMat2 { + type Output = Self; + #[inline] + fn div(self, rhs: f64) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign for DMat2 { + #[inline] + fn div_assign(&mut self, rhs: f64) { + *self = self.div_scalar(rhs); + } +} + impl Sum for DMat2 { fn sum(iter: I) -> Self where diff --git a/src/f64/dmat3.rs b/src/f64/dmat3.rs index bbb24d75..f1379027 100644 --- a/src/f64/dmat3.rs +++ b/src/f64/dmat3.rs @@ -4,7 +4,7 @@ use crate::{f64::math, swizzles::*, DMat2, DMat4, DQuat, DVec2, DVec3, EulerRot, #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; /// Creates a 3x3 matrix from three column vectors. #[inline(always)] @@ -550,6 +550,18 @@ impl DMat3 { ) } + /// Divides a 3x3 matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: f64) -> Self { + let rhs = DVec3::splat(rhs); + Self::from_cols( + self.x_axis.div(rhs), + self.y_axis.div(rhs), + self.z_axis.div(rhs), + ) + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -675,6 +687,29 @@ impl MulAssign for DMat3 { } } +impl Div for f64 { + type Output = DMat3; + #[inline] + fn div(self, rhs: DMat3) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div for DMat3 { + type Output = Self; + #[inline] + fn div(self, rhs: f64) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign for DMat3 { + #[inline] + fn div_assign(&mut self, rhs: f64) { + *self = self.div_scalar(rhs); + } +} + impl Sum for DMat3 { fn sum(iter: I) -> Self where diff --git a/src/f64/dmat4.rs b/src/f64/dmat4.rs index f064aad2..0ec45ce2 100644 --- a/src/f64/dmat4.rs +++ b/src/f64/dmat4.rs @@ -4,7 +4,7 @@ use crate::{f64::math, swizzles::*, DMat3, DQuat, DVec3, DVec4, EulerRot, Mat4}; #[cfg(not(target_arch = "spirv"))] use core::fmt; use core::iter::{Product, Sum}; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; /// Creates a 4x4 matrix from four column vectors. #[inline(always)] @@ -1077,6 +1077,19 @@ impl DMat4 { ) } + /// Divides a 4x4 matrix by a scalar. + #[inline] + #[must_use] + pub fn div_scalar(&self, rhs: f64) -> Self { + let rhs = DVec4::splat(rhs); + Self::from_cols( + self.x_axis.div(rhs), + self.y_axis.div(rhs), + self.z_axis.div(rhs), + self.w_axis.div(rhs), + ) + } + /// Returns true if the absolute difference of all elements between `self` and `rhs` /// is less than or equal to `max_abs_diff`. /// @@ -1214,6 +1227,29 @@ impl MulAssign for DMat4 { } } +impl Div for f64 { + type Output = DMat4; + #[inline] + fn div(self, rhs: DMat4) -> Self::Output { + rhs.div_scalar(self) + } +} + +impl Div for DMat4 { + type Output = Self; + #[inline] + fn div(self, rhs: f64) -> Self::Output { + self.div_scalar(rhs) + } +} + +impl DivAssign for DMat4 { + #[inline] + fn div_assign(&mut self, rhs: f64) { + *self = self.div_scalar(rhs); + } +} + impl Sum for DMat4 { fn sum(iter: I) -> Self where diff --git a/tests/mat2.rs b/tests/mat2.rs index 9d579e48..1c11cfbb 100644 --- a/tests/mat2.rs +++ b/tests/mat2.rs @@ -161,6 +161,8 @@ macro_rules! impl_mat2_tests { let m0_neg = $mat2::from_cols_array_2d(&[[-1.0, -2.0], [-3.0, -4.0]]); assert_eq!(m0x2, m0 * 2.0); assert_eq!(m0x2, 2.0 * m0); + assert_eq!(m0, m0x2 / 2.0); + assert_eq!(m0, 2.0 / m0x2); assert_eq!(m0x2, m0 + m0); assert_eq!($mat2::ZERO, m0 - m0); assert_eq!(m0_neg, -m0); @@ -171,6 +173,10 @@ macro_rules! impl_mat2_tests { m1 *= 2.0; assert_eq!(m0x2, m1); + let mut m1 = m0x2; + m1 /= 2.0; + assert_eq!(m0, m1); + let mut m1 = m0; m1 += m0; assert_eq!(m0x2, m1); diff --git a/tests/mat3.rs b/tests/mat3.rs index 36a8d384..376815b4 100644 --- a/tests/mat3.rs +++ b/tests/mat3.rs @@ -300,6 +300,8 @@ macro_rules! impl_mat3_tests { ]); assert_eq!(m0x2, m0 * 2.0); assert_eq!(m0x2, 2.0 * m0); + assert_eq!(m0, m0x2 / 2.0); + assert_eq!(m0, 2.0 / m0x2); assert_eq!(m0x2, m0 + m0); assert_eq!($mat3::ZERO, m0 - m0); assert_eq!(m0_neg, -m0); @@ -310,6 +312,10 @@ macro_rules! impl_mat3_tests { m1 *= 2.0; assert_eq!(m0x2, m1); + let mut m1 = m0x2; + m1 /= 2.0; + assert_eq!(m0, m1); + let mut m1 = m0; m1 += m0; assert_eq!(m0x2, m1); diff --git a/tests/mat4.rs b/tests/mat4.rs index 492f9fa2..f6109f57 100644 --- a/tests/mat4.rs +++ b/tests/mat4.rs @@ -603,6 +603,8 @@ macro_rules! impl_mat4_tests { ]); assert_eq!(m0x2, m0 * 2.0); assert_eq!(m0x2, 2.0 * m0); + assert_eq!(m0, m0x2 / 2.0); + assert_eq!(m0, 2.0 / m0x2); assert_eq!(m0x2, m0 + m0); assert_eq!($mat4::ZERO, m0 - m0); assert_eq!(m0_neg, -m0); @@ -613,6 +615,10 @@ macro_rules! impl_mat4_tests { m1 *= 2.0; assert_eq!(m0x2, m1); + let mut m1 = m0x2; + m1 /= 2.0; + assert_eq!(m0, m1); + let mut m1 = m0; m1 += m0; assert_eq!(m0x2, m1);