Skip to content

Commit

Permalink
Added matrix assign ops and col_mut methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
bitshifter committed Jun 11, 2021
1 parent 1b403ee commit e0adc30
Show file tree
Hide file tree
Showing 10 changed files with 284 additions and 313 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog], and this project adheres to
[Semantic Versioning].

## [Unreleased]

### Added

* Added `col_mut()` method which returns a mutable reference to a matrix column
to all matrix types.
* Added `AddAssign`, `MulAssign` and `SubAssign` implementations for all matrix
types.

## [0.16.0] - 2021-06-06

### Breaking changes
Expand Down
10 changes: 5 additions & 5 deletions src/core/traits/matrix.rs
Expand Up @@ -625,7 +625,7 @@ pub trait Matrix4x4<T: NumEx, V4: Vector4<T>>: Matrix<T> {
}

#[inline]
fn mul_vector(&self, other: &V4) -> V4 {
fn mul_vector(&self, other: V4) -> V4 {
let mut res = self.x_axis().mul(other.splat_x());
res = self.y_axis().mul_add(other.splat_y(), res);
res = self.z_axis().mul_add(other.splat_z(), res);
Expand All @@ -636,10 +636,10 @@ pub trait Matrix4x4<T: NumEx, V4: Vector4<T>>: Matrix<T> {
#[inline]
fn mul_matrix(&self, other: &Self) -> Self {
Self::from_cols(
self.mul_vector(other.x_axis()),
self.mul_vector(other.y_axis()),
self.mul_vector(other.z_axis()),
self.mul_vector(other.w_axis()),
self.mul_vector(*other.x_axis()),
self.mul_vector(*other.y_axis()),
self.mul_vector(*other.z_axis()),
self.mul_vector(*other.w_axis()),
)
}

Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Expand Up @@ -233,6 +233,9 @@ The minimum supported Rust version is `1.45.0`.
#[macro_use]
mod macros;

#[macro_use]
mod mat;

#[macro_use]
mod vec;

Expand Down
108 changes: 108 additions & 0 deletions src/mat.rs
@@ -0,0 +1,108 @@
// Adds common vector trait implementations.
// The traits here should be supported for all types of $t and all sizes of vector.
macro_rules! impl_matn_common_traits {
($t:ty, $matn:ident, $vecn:ident) => {
impl Default for $matn {
#[inline(always)]
fn default() -> Self {
Self::IDENTITY
}
}

impl Add<$matn> for $matn {
type Output = Self;
#[inline(always)]
fn add(self, other: Self) -> Self::Output {
Self(self.0.add_matrix(&other.0))
}
}

impl AddAssign<$matn> for $matn {
#[inline(always)]
fn add_assign(&mut self, other: Self) {
self.0 = self.0.add_matrix(&other.0);
}
}

impl Sub<$matn> for $matn {
type Output = Self;
#[inline(always)]
fn sub(self, other: Self) -> Self::Output {
Self(self.0.sub_matrix(&other.0))
}
}

impl SubAssign<$matn> for $matn {
#[inline(always)]
fn sub_assign(&mut self, other: Self) {
self.0 = self.0.sub_matrix(&other.0);
}
}

impl Mul<$matn> for $matn {
type Output = Self;
#[inline(always)]
fn mul(self, other: Self) -> Self::Output {
Self(self.0.mul_matrix(&other.0))
}
}

impl MulAssign<$matn> for $matn {
#[inline(always)]
fn mul_assign(&mut self, other: Self) {
self.0 = self.0.mul_matrix(&other.0);
}
}

impl Mul<$vecn> for $matn {
type Output = $vecn;
#[inline(always)]
fn mul(self, other: $vecn) -> Self::Output {
$vecn(self.0.mul_vector(other.0))
}
}

impl Mul<$matn> for $t {
type Output = $matn;
#[inline(always)]
fn mul(self, other: $matn) -> Self::Output {
$matn(other.0.mul_scalar(self))
}
}

impl Mul<$t> for $matn {
type Output = Self;
#[inline(always)]
fn mul(self, other: $t) -> Self::Output {
Self(self.0.mul_scalar(other))
}
}

impl MulAssign<$t> for $matn {
#[inline(always)]
fn mul_assign(&mut self, other: $t) {
self.0 = self.0.mul_scalar(other);
}
}

#[cfg(feature = "std")]
impl<'a> Sum<&'a Self> for $matn {
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = &'a Self>,
{
iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
}
}

#[cfg(feature = "std")]
impl<'a> Product<&'a Self> for $matn {
fn product<I>(iter: I) -> Self
where
I: Iterator<Item = &'a Self>,
{
iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
}
}
};
}
106 changes: 19 additions & 87 deletions src/mat2.rs
Expand Up @@ -5,7 +5,7 @@ use crate::core::{
use crate::{DMat3, DVec2, Mat3, Vec2};
#[cfg(not(target_arch = "spirv"))]
use core::fmt;
use core::ops::{Add, Deref, DerefMut, Mul, Sub};
use core::ops::{Add, AddAssign, Deref, DerefMut, Mul, MulAssign, Sub, SubAssign};

#[cfg(all(
target_arch = "x86",
Expand Down Expand Up @@ -124,6 +124,23 @@ macro_rules! impl_mat2_methods {
}
}

/// Returns a mutable reference to the matrix column for the given `index`.
///
/// # Panics
///
/// Panics if `index` is greater than 1.
#[inline]
pub fn col_mut(&mut self, index: usize) -> &mut $vec2 {
match index {
0 => &mut self.x_axis,
1 => &mut self.y_axis,
_ => panic!(
"index out of bounds: the len is 2 but the index is {}",
index
),
}
}

/// Returns the matrix row for the given `index`.
///
/// # Panics
Expand All @@ -141,18 +158,6 @@ macro_rules! impl_mat2_methods {
}
}

// #[inline]
// pub(crate) fn col_mut(&mut self, index: usize) -> &mut $vec2 {
// match index {
// 0 => unsafe { &mut *(self.0.as_mut().as_mut_ptr() as *mut $vec2) },
// 1 => unsafe { &mut *(self.0.as_mut()[2..].as_mut_ptr() as *mut $vec2) },
// _ => panic!(
// "index out of bounds: the len is 2 but the index is {}",
// index
// ),
// }
// }

/// Returns `true` if, and only if, all elements are finite.
/// If any element is either `NaN`, positive or negative infinity, this will return `false`.
#[inline]
Expand Down Expand Up @@ -243,12 +248,7 @@ macro_rules! impl_mat2_traits {
$mat2::from_cols(x_axis, y_axis)
}

impl Default for $mat2 {
#[inline(always)]
fn default() -> Self {
Self::IDENTITY
}
}
impl_matn_common_traits!($t, $mat2, $vec2);

impl PartialEq for $mat2 {
#[inline]
Expand All @@ -271,54 +271,6 @@ macro_rules! impl_mat2_traits {
}
}

impl Add<$mat2> for $mat2 {
type Output = Self;
#[inline(always)]
fn add(self, other: Self) -> Self {
Self(self.0.add_matrix(&other.0))
}
}

impl Sub<$mat2> for $mat2 {
type Output = Self;
#[inline(always)]
fn sub(self, other: Self) -> Self {
Self(self.0.sub_matrix(&other.0))
}
}

impl Mul<$mat2> for $mat2 {
type Output = Self;
#[inline(always)]
fn mul(self, other: Self) -> Self {
Self(self.0.mul_matrix(&other.0))
}
}

impl Mul<$vec2> for $mat2 {
type Output = $vec2;
#[inline(always)]
fn mul(self, other: $vec2) -> $vec2 {
$vec2(self.0.mul_vector(other.0))
}
}

impl Mul<$mat2> for $t {
type Output = $mat2;
#[inline(always)]
fn mul(self, other: $mat2) -> $mat2 {
$mat2(other.0.mul_scalar(self))
}
}

impl Mul<$t> for $mat2 {
type Output = Self;
#[inline(always)]
fn mul(self, other: $t) -> Self {
Self(self.0.mul_scalar(other))
}
}

impl Deref for $mat2 {
type Target = Columns2<$vec2>;
#[inline(always)]
Expand Down Expand Up @@ -357,26 +309,6 @@ macro_rules! impl_mat2_traits {
write!(f, "[{}, {}]", self.x_axis, self.y_axis)
}
}

#[cfg(feature = "std")]
impl<'a> Sum<&'a Self> for $mat2 {
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = &'a Self>,
{
iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
}
}

#[cfg(feature = "std")]
impl<'a> Product<&'a Self> for $mat2 {
fn product<I>(iter: I) -> Self
where
I: Iterator<Item = &'a Self>,
{
iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
}
}
};
}

Expand Down

0 comments on commit e0adc30

Please sign in to comment.