Skip to content

Commit

Permalink
Add Div and DivAssign by scalar implementations to matrix types. (#489)
Browse files Browse the repository at this point in the history
Fixes #476
  • Loading branch information
bitshifter authored Mar 11, 2024
1 parent fb8ef0f commit ab85e2a
Show file tree
Hide file tree
Showing 21 changed files with 622 additions and 17 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ The format is based on [Keep a Changelog], and this project adheres to

* Added `From<BVecN>` support for all vector types.

* Added `Div` and `DivAssign` by scalar implementations to matrix types.

## [0.25.0] - 2023-12-19

### Breaking changes
Expand Down
45 changes: 44 additions & 1 deletion codegen/templates/mat.rs.tera
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down Expand Up @@ -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`.
///
Expand Down Expand Up @@ -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<Vec3A> for Mat3 {
type Output = Vec3A;
Expand Down
32 changes: 31 additions & 1 deletion src/f32/coresimd/mat2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;

Expand Down Expand Up @@ -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`.
///
Expand Down Expand Up @@ -413,6 +420,29 @@ impl MulAssign<f32> for Mat2 {
}
}

impl Div<Mat2> for f32 {
type Output = Mat2;
#[inline]
fn div(self, rhs: Mat2) -> Self::Output {
rhs.div_scalar(self)
}
}

impl Div<f32> for Mat2 {
type Output = Self;
#[inline]
fn div(self, rhs: f32) -> Self::Output {
self.div_scalar(rhs)
}
}

impl DivAssign<f32> for Mat2 {
#[inline]
fn div_assign(&mut self, rhs: f32) {
*self = self.div_scalar(rhs);
}
}

impl Sum<Self> for Mat2 {
fn sum<I>(iter: I) -> Self
where
Expand Down
37 changes: 36 additions & 1 deletion src/f32/coresimd/mat3a.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;

Expand Down Expand Up @@ -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`.
///
Expand Down Expand Up @@ -684,6 +696,29 @@ impl MulAssign<f32> for Mat3A {
}
}

impl Div<Mat3A> for f32 {
type Output = Mat3A;
#[inline]
fn div(self, rhs: Mat3A) -> Self::Output {
rhs.div_scalar(self)
}
}

impl Div<f32> for Mat3A {
type Output = Self;
#[inline]
fn div(self, rhs: f32) -> Self::Output {
self.div_scalar(rhs)
}
}

impl DivAssign<f32> for Mat3A {
#[inline]
fn div_assign(&mut self, rhs: f32) {
*self = self.div_scalar(rhs);
}
}

impl Mul<Vec3> for Mat3A {
type Output = Vec3;
#[inline]
Expand Down
38 changes: 37 additions & 1 deletion src/f32/coresimd/mat4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;

Expand Down Expand Up @@ -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`.
///
Expand Down Expand Up @@ -1338,6 +1351,29 @@ impl MulAssign<f32> for Mat4 {
}
}

impl Div<Mat4> for f32 {
type Output = Mat4;
#[inline]
fn div(self, rhs: Mat4) -> Self::Output {
rhs.div_scalar(self)
}
}

impl Div<f32> for Mat4 {
type Output = Self;
#[inline]
fn div(self, rhs: f32) -> Self::Output {
self.div_scalar(rhs)
}
}

impl DivAssign<f32> for Mat4 {
#[inline]
fn div_assign(&mut self, rhs: f32) {
*self = self.div_scalar(rhs);
}
}

impl Sum<Self> for Mat4 {
fn sum<I>(iter: I) -> Self
where
Expand Down
37 changes: 36 additions & 1 deletion src/f32/mat3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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`.
///
Expand Down Expand Up @@ -678,6 +690,29 @@ impl MulAssign<f32> for Mat3 {
}
}

impl Div<Mat3> for f32 {
type Output = Mat3;
#[inline]
fn div(self, rhs: Mat3) -> Self::Output {
rhs.div_scalar(self)
}
}

impl Div<f32> for Mat3 {
type Output = Self;
#[inline]
fn div(self, rhs: f32) -> Self::Output {
self.div_scalar(rhs)
}
}

impl DivAssign<f32> for Mat3 {
#[inline]
fn div_assign(&mut self, rhs: f32) {
*self = self.div_scalar(rhs);
}
}

impl Mul<Vec3A> for Mat3 {
type Output = Vec3A;
#[inline]
Expand Down
33 changes: 32 additions & 1 deletion src/f32/scalar/mat2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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`.
///
Expand Down Expand Up @@ -408,6 +416,29 @@ impl MulAssign<f32> for Mat2 {
}
}

impl Div<Mat2> for f32 {
type Output = Mat2;
#[inline]
fn div(self, rhs: Mat2) -> Self::Output {
rhs.div_scalar(self)
}
}

impl Div<f32> for Mat2 {
type Output = Self;
#[inline]
fn div(self, rhs: f32) -> Self::Output {
self.div_scalar(rhs)
}
}

impl DivAssign<f32> for Mat2 {
#[inline]
fn div_assign(&mut self, rhs: f32) {
*self = self.div_scalar(rhs);
}
}

impl Sum<Self> for Mat2 {
fn sum<I>(iter: I) -> Self
where
Expand Down
Loading

0 comments on commit ab85e2a

Please sign in to comment.