Skip to content

Commit

Permalink
math: Implement VectorOps for Box3D.
Browse files Browse the repository at this point in the history
This will allow us to use `Box3D::map()` for infallible conversion.
  • Loading branch information
kpreid committed Jul 27, 2024
1 parent def4358 commit a87f27e
Showing 1 changed file with 47 additions and 22 deletions.
69 changes: 47 additions & 22 deletions all-is-cubes-base/src/math/coord.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Numeric types used for coordinates and related quantities.
use euclid::{Point3D, Size2D, Size3D, Vector3D};
use euclid::{Box3D, Point3D, Size2D, Size3D, Vector3D};

use crate::math::Cube;

Expand Down Expand Up @@ -47,30 +47,55 @@ pub trait VectorOps<O> {
fn zip<F: FnMut(Self::Elem, Self::Elem) -> O>(self, rhs: Self, f: F) -> Self::Output;
}

macro_rules! impl_vector_ops {
($vec:ident, ($( $field:ident )*)) => {
impl<T, O, U> VectorOps<O> for $vec<T, U> {
type Elem = T;
type Output = $vec<O, U>;
mod impl_euclid {
use super::*;

#[inline]
fn map<F: FnMut(Self::Elem) -> O>(self, mut f: F) -> Self::Output {
$vec::new($(f(self.$field),)*)
}
macro_rules! impl_vector_ops {
($vec:ident, ($( $field:ident )*)) => {
impl<T, O, U> VectorOps<O> for $vec<T, U> {
type Elem = T;
type Output = $vec<O, U>;

#[inline]
fn map<F: FnMut(Self::Elem) -> O>(self, mut f: F) -> Self::Output {
$vec::new($(f(self.$field),)*)
}

#[inline]
fn zip<F: FnMut(Self::Elem, Self::Elem) -> O>(
self,
rhs: Self,
mut f: F,
) -> Self::Output {
$vec::new($(f(self.$field, rhs.$field),)*)
#[inline]
fn zip<F: FnMut(Self::Elem, Self::Elem) -> O>(
self,
rhs: Self,
mut f: F,
) -> Self::Output {
$vec::new($(f(self.$field, rhs.$field),)*)
}
}
}
};
}
mod impl_euclid {
use super::*;
};
}

// TODO: contribute inherent methods for this to euclid
impl_vector_ops!(Size2D, (width height));
impl_vector_ops!(Size3D, (width height depth));

// TODO: contribute inherent methods for this (at least map()) to euclid
impl<T, O: Copy, U> VectorOps<O> for Box3D<T, U> {
type Elem = T;
type Output = Box3D<O, U>;

#[inline]
fn map<F: FnMut(Self::Elem) -> O>(self, mut f: F) -> Self::Output {
Box3D {
min: self.min.map(&mut f),
max: self.max.map(&mut f),
}
}

#[inline]
fn zip<F: FnMut(Self::Elem, Self::Elem) -> O>(self, rhs: Self, mut f: F) -> Self::Output {
Box3D {
min: self.min.zip(rhs.min, &mut f).to_point(),
max: self.max.zip(rhs.max, &mut f).to_point(),
}
}
}
}

0 comments on commit a87f27e

Please sign in to comment.