Skip to content

Commit

Permalink
Merge rustgd#495
Browse files Browse the repository at this point in the history
495: Mat3 constructors enhancement r=kvark a=AndreaCatania

The reason of this PR is because I need to transform thing in a 2d plane, and these functions are really handy.

- Added to the Mat3 the possibility to be constructed from a translation vector, similarly to the Mat4.
- Added unit tests.

Co-authored-by: Andrea Catania <[email protected]>
  • Loading branch information
bors[bot] and AndreaCatania authored Nov 5, 2019
2 parents f69e781 + ff1cda7 commit 50a345b
Show file tree
Hide file tree
Showing 25 changed files with 845 additions and 449 deletions.
8 changes: 2 additions & 6 deletions benches/common/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ macro_rules! bench_binop {
bh.iter(|| {
i = (i + 1) & (LEN - 1);

unsafe {
test::black_box(elems1.get_unchecked(i).$binop(*elems2.get_unchecked(i)))
}
unsafe { test::black_box(elems1.get_unchecked(i).$binop(*elems2.get_unchecked(i))) }
})
}
};
Expand All @@ -50,9 +48,7 @@ macro_rules! bench_unop {
bh.iter(|| {
i = (i + 1) & (LEN - 1);

unsafe {
test::black_box(elems.get_unchecked_mut(i).$unop())
}
unsafe { test::black_box(elems.get_unchecked_mut(i).$unop()) }
})
}
};
Expand Down
4 changes: 2 additions & 2 deletions benches/construction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ extern crate cgmath;
extern crate rand;
extern crate test;

use rand::{IsaacRng, Rng, FromEntropy};
use test::Bencher;
use cgmath::*;
use rand::{FromEntropy, IsaacRng, Rng};
use test::Bencher;

#[path = "common/macros.rs"]
#[macro_use]
Expand Down
2 changes: 1 addition & 1 deletion benches/mat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ extern crate cgmath;
extern crate rand;
extern crate test;

use rand::{IsaacRng, Rng, FromEntropy};
use rand::{FromEntropy, IsaacRng, Rng};
use std::ops::*;
use test::Bencher;

Expand Down
2 changes: 1 addition & 1 deletion benches/quat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ extern crate cgmath;
extern crate rand;
extern crate test;

use rand::{IsaacRng, Rng, FromEntropy};
use rand::{FromEntropy, IsaacRng, Rng};
use std::ops::*;
use test::Bencher;

Expand Down
2 changes: 1 addition & 1 deletion benches/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ extern crate cgmath;
extern crate rand;
extern crate test;

use rand::{IsaacRng, Rng, FromEntropy};
use rand::{FromEntropy, IsaacRng, Rng};
use std::ops::*;
use test::Bencher;

Expand Down
29 changes: 17 additions & 12 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use std::env;
use std::string::String;

/// Generate the name of the swizzle function and what it returns.
Expand All @@ -11,14 +11,18 @@ fn gen_swizzle_nth<'a>(variables: &'a str, mut i: usize, upto: usize) -> Option<
debug_assert!(i > 0); // zeroth permutation is empty
let mut swizzle_impl = String::new();
let mut swizzle = String::new();
let n = variables.len()+1;
let n = variables.len() + 1;
for _ in 0..upto {
if i == 0 { break; }
if i % n == 0 { return None; }
let c = variables.as_bytes()[i%n - 1] as char;
if i == 0 {
break;
}
if i % n == 0 {
return None;
}
let c = variables.as_bytes()[i % n - 1] as char;
swizzle.push(c);
swizzle_impl.push_str(&format!("self.{}, ", c));
i = i/n;
i = i / n;
}
Some((swizzle, swizzle_impl))
}
Expand All @@ -31,15 +35,16 @@ fn gen_swizzle_nth<'a>(variables: &'a str, mut i: usize, upto: usize) -> Option<
#[cfg(feature = "swizzle")]
fn gen_swizzle_functions(variables: &'static str, upto: usize) -> String {
let mut result = String::new();
let nn = (variables.len()+1).pow(upto as u32);
let nn = (variables.len() + 1).pow(upto as u32);
for i in 1..nn {
if let Some((swizzle_name, swizzle_impl)) = gen_swizzle_nth(variables, i, upto) {
let dim = format!("{}", swizzle_name.len());
result.push_str(
&format!("
result.push_str(&format!(
"
/// Swizzle operator that creates a new type with dimension {2} from variables `{0}`.
#[inline] pub fn {0}(&self) -> $vector_type{2}<$S> {{ $vector_type{2}::new({1}) }}\n",
swizzle_name, swizzle_impl, dim));
swizzle_name, swizzle_impl, dim
));
}
}
result
Expand All @@ -50,7 +55,6 @@ fn gen_swizzle_functions(_: &'static str, _: usize) -> String {
String::new()
}


/// This script generates the macro for building swizzle operators for multidimensional
/// vectors and points. This macro is included in macros.rs
fn main() {
Expand Down Expand Up @@ -92,5 +96,6 @@ macro_rules! impl_swizzle_functions {{
xyzw4 = gen_swizzle_functions("xyzw", 4));
let mut f = File::create(swizzle_file_path)
.expect("Unable to create file that defines the swizzle operator macro.");
f.write_all(data.as_bytes()).expect("Unable to write swizzle operator macro.");
f.write_all(data.as_bytes())
.expect("Unable to write swizzle operator macro.");
}
6 changes: 3 additions & 3 deletions src/angle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@

//! Angle units for type-safe, self-documenting code.
use std::fmt;
use std::f64;
use std::fmt;
use std::iter;
use std::ops::*;

use num_traits::{cast, Bounded};
#[cfg(feature = "rand")]
use rand::{
distributions::{uniform::SampleUniform, Distribution, Standard},
Rng,
distributions::{Distribution, Standard, uniform::SampleUniform},
};
use num_traits::{cast, Bounded};

use structure::*;

Expand Down
12 changes: 7 additions & 5 deletions src/euler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use num_traits::cast;
#[cfg(feature = "rand")]
use rand::{
Rng,
distributions::{Distribution, Standard},
Rng,
};
use num_traits::cast;

use structure::*;

use angle::Rad;
use approx;
use quaternion::Quaternion;
#[cfg(feature = "mint")]
use mint;
use num::BaseFloat;
use quaternion::Quaternion;

/// A set of [Euler angles] representing a rotation in three-dimensional space.
///
Expand Down Expand Up @@ -191,8 +191,10 @@ impl<A: Angle> approx::UlpsEq for Euler<A> {

#[cfg(feature = "rand")]
impl<A> Distribution<Euler<A>> for Standard
where Standard: Distribution<A>,
A: Angle {
where
Standard: Distribution<A>,
A: Angle,
{
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Euler<A> {
Euler {
x: rng.gen(),
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ extern crate approx;
#[cfg(feature = "mint")]
pub extern crate mint;

pub extern crate num_traits;
#[cfg(feature = "rand")]
extern crate rand;
pub extern crate num_traits;

#[cfg(feature = "serde")]
#[macro_use]
Expand All @@ -77,11 +77,11 @@ pub use structure::*;

pub use matrix::{Matrix2, Matrix3, Matrix4};
pub use quaternion::Quaternion;
pub use vector::{dot, Vector1, Vector2, Vector3, Vector4, vec1, vec2, vec3, vec4};
pub use vector::{dot, vec1, vec2, vec3, vec4, Vector1, Vector2, Vector3, Vector4};

pub use angle::{Deg, Rad};
pub use euler::Euler;
pub use point::{Point1, Point2, Point3, point1, point2, point3};
pub use point::{point1, point2, point3, Point1, Point2, Point3};
pub use rotation::*;
pub use transform::*;

Expand Down
71 changes: 47 additions & 24 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,30 @@ macro_rules! impl_assignment_operator {
}

macro_rules! fold_array {
(&$method:ident, { $x:expr }) => { *$x };
(&$method:ident, { $x:expr, $y:expr }) => { $x.$method(&$y) };
(&$method:ident, { $x:expr, $y:expr, $z:expr }) => { $x.$method(&$y).$method(&$z) };
(&$method:ident, { $x:expr, $y:expr, $z:expr, $w:expr }) => { $x.$method(&$y).$method(&$z).$method(&$w) };
($method:ident, { $x:expr }) => { $x };
($method:ident, { $x:expr, $y:expr }) => { $x.$method($y) };
($method:ident, { $x:expr, $y:expr, $z:expr }) => { $x.$method($y).$method($z) };
($method:ident, { $x:expr, $y:expr, $z:expr, $w:expr }) => { $x.$method($y).$method($z).$method($w) };
(&$method:ident, { $x:expr }) => {
*$x
};
(&$method:ident, { $x:expr, $y:expr }) => {
$x.$method(&$y)
};
(&$method:ident, { $x:expr, $y:expr, $z:expr }) => {
$x.$method(&$y).$method(&$z)
};
(&$method:ident, { $x:expr, $y:expr, $z:expr, $w:expr }) => {
$x.$method(&$y).$method(&$z).$method(&$w)
};
($method:ident, { $x:expr }) => {
$x
};
($method:ident, { $x:expr, $y:expr }) => {
$x.$method($y)
};
($method:ident, { $x:expr, $y:expr, $z:expr }) => {
$x.$method($y).$method($z)
};
($method:ident, { $x:expr, $y:expr, $z:expr, $w:expr }) => {
$x.$method($y).$method($z).$method($w)
};
}

/// Generate array conversion implementations for a compound array type
Expand Down Expand Up @@ -252,17 +268,19 @@ macro_rules! impl_index_operators {

#[inline]
fn index<'a>(&'a self, i: $I) -> &'a $Output {
let v: &[$S; $n] = self.as_ref(); &v[i]
let v: &[$S; $n] = self.as_ref();
&v[i]
}
}

impl<$S> IndexMut<$I> for $VectorN<$S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: $I) -> &'a mut $Output {
let v: &mut [$S; $n] = self.as_mut(); &mut v[i]
let v: &mut [$S; $n] = self.as_mut();
&mut v[i]
}
}
}
};
}

/// Generates a binary operator implementation for the permutations of by-ref and by-val, for simd
Expand All @@ -272,11 +290,11 @@ macro_rules! impl_operator_simd {
([$Simd:ident]; $Op:ident for $Lhs:ty {
fn $op:ident($x:ident) -> $Output:ty { $body:expr }
}) => {

impl $Op for $Lhs {
#[inline]
fn $op(self) -> $Output {
let $x: $Simd = self.into(); $body
let $x: $Simd = self.into();
$body
}
}
};
Expand All @@ -287,15 +305,16 @@ macro_rules! impl_operator_simd {
impl $Op<$Rhs> for $Lhs {
#[inline]
fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs): ($Simd, $Simd) = (self.into(), $Simd::splat(other)); $body
let ($lhs, $rhs): ($Simd, $Simd) = (self.into(), $Simd::splat(other));
$body
}
}


impl<'a> $Op<$Rhs> for &'a $Lhs {
#[inline]
fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs): ($Simd, $Simd) = ((*self).into(), $Simd::splat(other)); $body
let ($lhs, $rhs): ($Simd, $Simd) = ((*self).into(), $Simd::splat(other));
$body
}
}
};
Expand All @@ -304,33 +323,35 @@ macro_rules! impl_operator_simd {
([$Simd:ident]; $Op:ident<$Rhs:ty> for $Lhs:ty {
fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
}) => {

impl $Op<$Rhs> for $Lhs {
#[inline]
fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs): ($Simd, $Simd) = (self.into(), other.into()); $body
let ($lhs, $rhs): ($Simd, $Simd) = (self.into(), other.into());
$body
}
}


impl<'a> $Op<&'a $Rhs> for $Lhs {
#[inline]
fn $op(self, other: &'a $Rhs) -> $Output {
let ($lhs, $rhs): ($Simd, $Simd) = (self.into(), (*other).into()); $body
let ($lhs, $rhs): ($Simd, $Simd) = (self.into(), (*other).into());
$body
}
}

impl<'a> $Op<$Rhs> for &'a $Lhs {
#[inline]
fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs): ($Simd, $Simd) = ((*self).into(), other.into()); $body
let ($lhs, $rhs): ($Simd, $Simd) = ((*self).into(), other.into());
$body
}
}

impl<'a, 'b> $Op<&'a $Rhs> for &'b $Lhs {
#[inline]
fn $op(self, other: &'a $Rhs) -> $Output {
let ($lhs, $rhs): ($Simd, $Simd) = ((*self).into(), (*other).into()); $body
let ($lhs, $rhs): ($Simd, $Simd) = ((*self).into(), (*other).into());
$body
}
}
};
Expand All @@ -342,14 +363,16 @@ macro_rules! impl_operator_simd {
impl $Op<$Rhs> for $Lhs {
#[inline]
fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs): ($Simd, $Simd) = ($Simd::splat(self), other.into()); $body
let ($lhs, $rhs): ($Simd, $Simd) = ($Simd::splat(self), other.into());
$body
}
}

impl<'a> $Op<&'a $Rhs> for $Lhs {
#[inline]
fn $op(self, other: &'a $Rhs) -> $Output {
let ($lhs, $rhs): ($Simd, $Simd) = ($Simd::splat(self), (*other).into()); $body
let ($lhs, $rhs): ($Simd, $Simd) = ($Simd::splat(self), (*other).into());
$body
}
}
};
Expand Down
Loading

0 comments on commit 50a345b

Please sign in to comment.