Code formatted with
This commit is contained in:
parent
04b21718f3
commit
ff1cda766d
25 changed files with 804 additions and 444 deletions
|
@ -28,9 +28,7 @@ macro_rules! bench_binop {
|
||||||
bh.iter(|| {
|
bh.iter(|| {
|
||||||
i = (i + 1) & (LEN - 1);
|
i = (i + 1) & (LEN - 1);
|
||||||
|
|
||||||
unsafe {
|
unsafe { test::black_box(elems1.get_unchecked(i).$binop(*elems2.get_unchecked(i))) }
|
||||||
test::black_box(elems1.get_unchecked(i).$binop(*elems2.get_unchecked(i)))
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -50,9 +48,7 @@ macro_rules! bench_unop {
|
||||||
bh.iter(|| {
|
bh.iter(|| {
|
||||||
i = (i + 1) & (LEN - 1);
|
i = (i + 1) & (LEN - 1);
|
||||||
|
|
||||||
unsafe {
|
unsafe { test::black_box(elems.get_unchecked_mut(i).$unop()) }
|
||||||
test::black_box(elems.get_unchecked_mut(i).$unop())
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,9 +20,9 @@ extern crate cgmath;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
use rand::{IsaacRng, Rng, FromEntropy};
|
|
||||||
use test::Bencher;
|
|
||||||
use cgmath::*;
|
use cgmath::*;
|
||||||
|
use rand::{FromEntropy, IsaacRng, Rng};
|
||||||
|
use test::Bencher;
|
||||||
|
|
||||||
#[path = "common/macros.rs"]
|
#[path = "common/macros.rs"]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -20,7 +20,7 @@ extern crate cgmath;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
use rand::{IsaacRng, Rng, FromEntropy};
|
use rand::{FromEntropy, IsaacRng, Rng};
|
||||||
use std::ops::*;
|
use std::ops::*;
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ extern crate cgmath;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
use rand::{IsaacRng, Rng, FromEntropy};
|
use rand::{FromEntropy, IsaacRng, Rng};
|
||||||
use std::ops::*;
|
use std::ops::*;
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ extern crate cgmath;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
use rand::{IsaacRng, Rng, FromEntropy};
|
use rand::{FromEntropy, IsaacRng, Rng};
|
||||||
use std::ops::*;
|
use std::ops::*;
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
|
|
||||||
|
|
29
build.rs
29
build.rs
|
@ -1,7 +1,7 @@
|
||||||
|
use std::env;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::env;
|
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
|
|
||||||
/// Generate the name of the swizzle function and what it returns.
|
/// Generate the name of the swizzle function and what it returns.
|
||||||
|
@ -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
|
debug_assert!(i > 0); // zeroth permutation is empty
|
||||||
let mut swizzle_impl = String::new();
|
let mut swizzle_impl = String::new();
|
||||||
let mut swizzle = String::new();
|
let mut swizzle = String::new();
|
||||||
let n = variables.len()+1;
|
let n = variables.len() + 1;
|
||||||
for _ in 0..upto {
|
for _ in 0..upto {
|
||||||
if i == 0 { break; }
|
if i == 0 {
|
||||||
if i % n == 0 { return None; }
|
break;
|
||||||
let c = variables.as_bytes()[i%n - 1] as char;
|
}
|
||||||
|
if i % n == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let c = variables.as_bytes()[i % n - 1] as char;
|
||||||
swizzle.push(c);
|
swizzle.push(c);
|
||||||
swizzle_impl.push_str(&format!("self.{}, ", c));
|
swizzle_impl.push_str(&format!("self.{}, ", c));
|
||||||
i = i/n;
|
i = i / n;
|
||||||
}
|
}
|
||||||
Some((swizzle, swizzle_impl))
|
Some((swizzle, swizzle_impl))
|
||||||
}
|
}
|
||||||
|
@ -31,15 +35,16 @@ fn gen_swizzle_nth<'a>(variables: &'a str, mut i: usize, upto: usize) -> Option<
|
||||||
#[cfg(feature = "swizzle")]
|
#[cfg(feature = "swizzle")]
|
||||||
fn gen_swizzle_functions(variables: &'static str, upto: usize) -> String {
|
fn gen_swizzle_functions(variables: &'static str, upto: usize) -> String {
|
||||||
let mut result = String::new();
|
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 {
|
for i in 1..nn {
|
||||||
if let Some((swizzle_name, swizzle_impl)) = gen_swizzle_nth(variables, i, upto) {
|
if let Some((swizzle_name, swizzle_impl)) = gen_swizzle_nth(variables, i, upto) {
|
||||||
let dim = format!("{}", swizzle_name.len());
|
let dim = format!("{}", swizzle_name.len());
|
||||||
result.push_str(
|
result.push_str(&format!(
|
||||||
&format!("
|
"
|
||||||
/// Swizzle operator that creates a new type with dimension {2} from variables `{0}`.
|
/// 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",
|
#[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
|
result
|
||||||
|
@ -50,7 +55,6 @@ fn gen_swizzle_functions(_: &'static str, _: usize) -> String {
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// This script generates the macro for building swizzle operators for multidimensional
|
/// This script generates the macro for building swizzle operators for multidimensional
|
||||||
/// vectors and points. This macro is included in macros.rs
|
/// vectors and points. This macro is included in macros.rs
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -92,5 +96,6 @@ macro_rules! impl_swizzle_functions {{
|
||||||
xyzw4 = gen_swizzle_functions("xyzw", 4));
|
xyzw4 = gen_swizzle_functions("xyzw", 4));
|
||||||
let mut f = File::create(swizzle_file_path)
|
let mut f = File::create(swizzle_file_path)
|
||||||
.expect("Unable to create file that defines the swizzle operator macro.");
|
.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.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,17 +15,17 @@
|
||||||
|
|
||||||
//! Angle units for type-safe, self-documenting code.
|
//! Angle units for type-safe, self-documenting code.
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
use std::f64;
|
use std::f64;
|
||||||
|
use std::fmt;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::ops::*;
|
use std::ops::*;
|
||||||
|
|
||||||
|
use num_traits::{cast, Bounded};
|
||||||
#[cfg(feature = "rand")]
|
#[cfg(feature = "rand")]
|
||||||
use rand::{
|
use rand::{
|
||||||
|
distributions::{uniform::SampleUniform, Distribution, Standard},
|
||||||
Rng,
|
Rng,
|
||||||
distributions::{Distribution, Standard, uniform::SampleUniform},
|
|
||||||
};
|
};
|
||||||
use num_traits::{cast, Bounded};
|
|
||||||
|
|
||||||
use structure::*;
|
use structure::*;
|
||||||
|
|
||||||
|
|
12
src/euler.rs
12
src/euler.rs
|
@ -13,21 +13,21 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use num_traits::cast;
|
||||||
#[cfg(feature = "rand")]
|
#[cfg(feature = "rand")]
|
||||||
use rand::{
|
use rand::{
|
||||||
Rng,
|
|
||||||
distributions::{Distribution, Standard},
|
distributions::{Distribution, Standard},
|
||||||
|
Rng,
|
||||||
};
|
};
|
||||||
use num_traits::cast;
|
|
||||||
|
|
||||||
use structure::*;
|
use structure::*;
|
||||||
|
|
||||||
use angle::Rad;
|
use angle::Rad;
|
||||||
use approx;
|
use approx;
|
||||||
use quaternion::Quaternion;
|
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
use mint;
|
use mint;
|
||||||
use num::BaseFloat;
|
use num::BaseFloat;
|
||||||
|
use quaternion::Quaternion;
|
||||||
|
|
||||||
/// A set of [Euler angles] representing a rotation in three-dimensional space.
|
/// A set of [Euler angles] representing a rotation in three-dimensional space.
|
||||||
///
|
///
|
||||||
|
@ -191,8 +191,10 @@ impl<A: Angle> approx::UlpsEq for Euler<A> {
|
||||||
|
|
||||||
#[cfg(feature = "rand")]
|
#[cfg(feature = "rand")]
|
||||||
impl<A> Distribution<Euler<A>> for Standard
|
impl<A> Distribution<Euler<A>> for Standard
|
||||||
where Standard: Distribution<A>,
|
where
|
||||||
A: Angle {
|
Standard: Distribution<A>,
|
||||||
|
A: Angle,
|
||||||
|
{
|
||||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Euler<A> {
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Euler<A> {
|
||||||
Euler {
|
Euler {
|
||||||
x: rng.gen(),
|
x: rng.gen(),
|
||||||
|
|
|
@ -58,9 +58,9 @@ extern crate approx;
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
pub extern crate mint;
|
pub extern crate mint;
|
||||||
|
|
||||||
|
pub extern crate num_traits;
|
||||||
#[cfg(feature = "rand")]
|
#[cfg(feature = "rand")]
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
pub extern crate num_traits;
|
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -77,11 +77,11 @@ pub use structure::*;
|
||||||
|
|
||||||
pub use matrix::{Matrix2, Matrix3, Matrix4};
|
pub use matrix::{Matrix2, Matrix3, Matrix4};
|
||||||
pub use quaternion::Quaternion;
|
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 angle::{Deg, Rad};
|
||||||
pub use euler::Euler;
|
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 rotation::*;
|
||||||
pub use transform::*;
|
pub use transform::*;
|
||||||
|
|
||||||
|
|
|
@ -139,14 +139,30 @@ macro_rules! impl_assignment_operator {
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! fold_array {
|
macro_rules! fold_array {
|
||||||
(&$method:ident, { $x:expr }) => { *$x };
|
(&$method:ident, { $x:expr }) => {
|
||||||
(&$method:ident, { $x:expr, $y:expr }) => { $x.$method(&$y) };
|
*$x
|
||||||
(&$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, $y:expr }) => {
|
||||||
($method:ident, { $x:expr }) => { $x };
|
$x.$method(&$y)
|
||||||
($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 }) => {
|
||||||
($method:ident, { $x:expr, $y:expr, $z:expr, $w:expr }) => { $x.$method($y).$method($z).$method($w) };
|
$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
|
/// Generate array conversion implementations for a compound array type
|
||||||
|
@ -252,17 +268,19 @@ macro_rules! impl_index_operators {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index<'a>(&'a self, i: $I) -> &'a $Output {
|
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> {
|
impl<$S> IndexMut<$I> for $VectorN<$S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index_mut<'a>(&'a mut self, i: $I) -> &'a mut $Output {
|
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
|
/// Generates a binary operator implementation for the permutations of by-ref and by-val, for simd
|
||||||
|
@ -272,11 +290,11 @@ macro_rules! impl_operator_simd {
|
||||||
([$Simd:ident]; $Op:ident for $Lhs:ty {
|
([$Simd:ident]; $Op:ident for $Lhs:ty {
|
||||||
fn $op:ident($x:ident) -> $Output:ty { $body:expr }
|
fn $op:ident($x:ident) -> $Output:ty { $body:expr }
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
impl $Op for $Lhs {
|
impl $Op for $Lhs {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $op(self) -> $Output {
|
fn $op(self) -> $Output {
|
||||||
let $x: $Simd = self.into(); $body
|
let $x: $Simd = self.into();
|
||||||
|
$body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -287,15 +305,16 @@ macro_rules! impl_operator_simd {
|
||||||
impl $Op<$Rhs> for $Lhs {
|
impl $Op<$Rhs> for $Lhs {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $op(self, other: $Rhs) -> $Output {
|
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 {
|
impl<'a> $Op<$Rhs> for &'a $Lhs {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $op(self, other: $Rhs) -> $Output {
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -304,33 +323,35 @@ macro_rules! impl_operator_simd {
|
||||||
([$Simd:ident]; $Op:ident<$Rhs:ty> for $Lhs:ty {
|
([$Simd:ident]; $Op:ident<$Rhs:ty> for $Lhs:ty {
|
||||||
fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
|
fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
impl $Op<$Rhs> for $Lhs {
|
impl $Op<$Rhs> for $Lhs {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $op(self, other: $Rhs) -> $Output {
|
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 {
|
impl<'a> $Op<&'a $Rhs> for $Lhs {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $op(self, other: &'a $Rhs) -> $Output {
|
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 {
|
impl<'a> $Op<$Rhs> for &'a $Lhs {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $op(self, other: $Rhs) -> $Output {
|
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 {
|
impl<'a, 'b> $Op<&'a $Rhs> for &'b $Lhs {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $op(self, other: &'a $Rhs) -> $Output {
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -342,14 +363,16 @@ macro_rules! impl_operator_simd {
|
||||||
impl $Op<$Rhs> for $Lhs {
|
impl $Op<$Rhs> for $Lhs {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $op(self, other: $Rhs) -> $Output {
|
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 {
|
impl<'a> $Op<&'a $Rhs> for $Lhs {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $op(self, other: &'a $Rhs) -> $Output {
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,12 +13,12 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use num_traits::{cast, NumCast};
|
||||||
#[cfg(feature = "rand")]
|
#[cfg(feature = "rand")]
|
||||||
use rand::{
|
use rand::{
|
||||||
|
distributions::{Distribution, Standard},
|
||||||
Rng,
|
Rng,
|
||||||
distributions::{Standard, Distribution},
|
|
||||||
};
|
};
|
||||||
use num_traits::{cast, NumCast};
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -285,7 +285,12 @@ impl<S> Matrix4<S> {
|
||||||
|
|
||||||
/// Create a new matrix, providing columns.
|
/// Create a new matrix, providing columns.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn from_cols(c0: Vector4<S>, c1: Vector4<S>, c2: Vector4<S>, c3: Vector4<S>) -> Matrix4<S> {
|
pub const fn from_cols(
|
||||||
|
c0: Vector4<S>,
|
||||||
|
c1: Vector4<S>,
|
||||||
|
c2: Vector4<S>,
|
||||||
|
c3: Vector4<S>,
|
||||||
|
) -> Matrix4<S> {
|
||||||
Matrix4 {
|
Matrix4 {
|
||||||
x: c0,
|
x: c0,
|
||||||
y: c1,
|
y: c1,
|
||||||
|
@ -696,21 +701,28 @@ impl<S: BaseFloat> SquareMatrix for Matrix3<S> {
|
||||||
self[1].cross(self[2]) / det,
|
self[1].cross(self[2]) / det,
|
||||||
self[2].cross(self[0]) / det,
|
self[2].cross(self[0]) / det,
|
||||||
self[0].cross(self[1]) / det,
|
self[0].cross(self[1]) / det,
|
||||||
).transpose(),
|
)
|
||||||
|
.transpose(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_diagonal(&self) -> bool {
|
fn is_diagonal(&self) -> bool {
|
||||||
ulps_eq!(self[0][1], &S::zero()) && ulps_eq!(self[0][2], &S::zero())
|
ulps_eq!(self[0][1], &S::zero())
|
||||||
&& ulps_eq!(self[1][0], &S::zero()) && ulps_eq!(self[1][2], &S::zero())
|
&& ulps_eq!(self[0][2], &S::zero())
|
||||||
&& ulps_eq!(self[2][0], &S::zero()) && ulps_eq!(self[2][1], &S::zero())
|
&& ulps_eq!(self[1][0], &S::zero())
|
||||||
|
&& ulps_eq!(self[1][2], &S::zero())
|
||||||
|
&& ulps_eq!(self[2][0], &S::zero())
|
||||||
|
&& ulps_eq!(self[2][1], &S::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_symmetric(&self) -> bool {
|
fn is_symmetric(&self) -> bool {
|
||||||
ulps_eq!(self[0][1], &self[1][0]) && ulps_eq!(self[0][2], &self[2][0])
|
ulps_eq!(self[0][1], &self[1][0])
|
||||||
&& ulps_eq!(self[1][0], &self[0][1]) && ulps_eq!(self[1][2], &self[2][1])
|
&& ulps_eq!(self[0][2], &self[2][0])
|
||||||
&& ulps_eq!(self[2][0], &self[0][2]) && ulps_eq!(self[2][1], &self[1][2])
|
&& ulps_eq!(self[1][0], &self[0][1])
|
||||||
|
&& ulps_eq!(self[1][2], &self[2][1])
|
||||||
|
&& ulps_eq!(self[2][0], &self[0][2])
|
||||||
|
&& ulps_eq!(self[2][1], &self[1][2])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -863,21 +875,33 @@ impl<S: BaseFloat> SquareMatrix for Matrix4<S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_diagonal(&self) -> bool {
|
fn is_diagonal(&self) -> bool {
|
||||||
ulps_eq!(self[0][1], &S::zero()) && ulps_eq!(self[0][2], &S::zero())
|
ulps_eq!(self[0][1], &S::zero())
|
||||||
&& ulps_eq!(self[0][3], &S::zero()) && ulps_eq!(self[1][0], &S::zero())
|
&& ulps_eq!(self[0][2], &S::zero())
|
||||||
&& ulps_eq!(self[1][2], &S::zero()) && ulps_eq!(self[1][3], &S::zero())
|
&& ulps_eq!(self[0][3], &S::zero())
|
||||||
&& ulps_eq!(self[2][0], &S::zero()) && ulps_eq!(self[2][1], &S::zero())
|
&& ulps_eq!(self[1][0], &S::zero())
|
||||||
&& ulps_eq!(self[2][3], &S::zero()) && ulps_eq!(self[3][0], &S::zero())
|
&& ulps_eq!(self[1][2], &S::zero())
|
||||||
&& ulps_eq!(self[3][1], &S::zero()) && ulps_eq!(self[3][2], &S::zero())
|
&& ulps_eq!(self[1][3], &S::zero())
|
||||||
|
&& ulps_eq!(self[2][0], &S::zero())
|
||||||
|
&& ulps_eq!(self[2][1], &S::zero())
|
||||||
|
&& ulps_eq!(self[2][3], &S::zero())
|
||||||
|
&& ulps_eq!(self[3][0], &S::zero())
|
||||||
|
&& ulps_eq!(self[3][1], &S::zero())
|
||||||
|
&& ulps_eq!(self[3][2], &S::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_symmetric(&self) -> bool {
|
fn is_symmetric(&self) -> bool {
|
||||||
ulps_eq!(self[0][1], &self[1][0]) && ulps_eq!(self[0][2], &self[2][0])
|
ulps_eq!(self[0][1], &self[1][0])
|
||||||
&& ulps_eq!(self[0][3], &self[3][0]) && ulps_eq!(self[1][0], &self[0][1])
|
&& ulps_eq!(self[0][2], &self[2][0])
|
||||||
&& ulps_eq!(self[1][2], &self[2][1]) && ulps_eq!(self[1][3], &self[3][1])
|
&& ulps_eq!(self[0][3], &self[3][0])
|
||||||
&& ulps_eq!(self[2][0], &self[0][2]) && ulps_eq!(self[2][1], &self[1][2])
|
&& ulps_eq!(self[1][0], &self[0][1])
|
||||||
&& ulps_eq!(self[2][3], &self[3][2]) && ulps_eq!(self[3][0], &self[0][3])
|
&& ulps_eq!(self[1][2], &self[2][1])
|
||||||
&& ulps_eq!(self[3][1], &self[1][3]) && ulps_eq!(self[3][2], &self[2][3])
|
&& ulps_eq!(self[1][3], &self[3][1])
|
||||||
|
&& ulps_eq!(self[2][0], &self[0][2])
|
||||||
|
&& ulps_eq!(self[2][1], &self[1][2])
|
||||||
|
&& ulps_eq!(self[2][3], &self[3][2])
|
||||||
|
&& ulps_eq!(self[3][0], &self[0][3])
|
||||||
|
&& ulps_eq!(self[3][1], &self[1][3])
|
||||||
|
&& ulps_eq!(self[3][2], &self[2][3])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1294,7 +1318,7 @@ macro_rules! index_operators {
|
||||||
From::from(&mut v[i])
|
From::from(&mut v[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
index_operators!(Matrix2<S>, 2, Vector2<S>, usize);
|
index_operators!(Matrix2<S>, 2, Vector2<S>, usize);
|
||||||
|
@ -1581,9 +1605,10 @@ impl<S: fmt::Debug> fmt::Debug for Matrix4<S> {
|
||||||
|
|
||||||
#[cfg(feature = "rand")]
|
#[cfg(feature = "rand")]
|
||||||
impl<S> Distribution<Matrix2<S>> for Standard
|
impl<S> Distribution<Matrix2<S>> for Standard
|
||||||
where
|
where
|
||||||
Standard: Distribution<Vector2<S>>,
|
Standard: Distribution<Vector2<S>>,
|
||||||
S: BaseFloat {
|
S: BaseFloat,
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix2<S> {
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix2<S> {
|
||||||
Matrix2 {
|
Matrix2 {
|
||||||
|
@ -1595,8 +1620,10 @@ impl<S> Distribution<Matrix2<S>> for Standard
|
||||||
|
|
||||||
#[cfg(feature = "rand")]
|
#[cfg(feature = "rand")]
|
||||||
impl<S> Distribution<Matrix3<S>> for Standard
|
impl<S> Distribution<Matrix3<S>> for Standard
|
||||||
where Standard: Distribution<Vector3<S>>,
|
where
|
||||||
S: BaseFloat {
|
Standard: Distribution<Vector3<S>>,
|
||||||
|
S: BaseFloat,
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix3<S> {
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix3<S> {
|
||||||
Matrix3 {
|
Matrix3 {
|
||||||
|
@ -1609,8 +1636,10 @@ impl<S> Distribution<Matrix3<S>> for Standard
|
||||||
|
|
||||||
#[cfg(feature = "rand")]
|
#[cfg(feature = "rand")]
|
||||||
impl<S> Distribution<Matrix4<S>> for Standard
|
impl<S> Distribution<Matrix4<S>> for Standard
|
||||||
where Standard: Distribution<Vector4<S>>,
|
where
|
||||||
S: BaseFloat {
|
Standard: Distribution<Vector4<S>>,
|
||||||
|
S: BaseFloat,
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix4<S> {
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix4<S> {
|
||||||
Matrix4 {
|
Matrix4 {
|
||||||
|
|
10
src/num.rs
10
src/num.rs
|
@ -36,8 +36,7 @@ pub trait BaseNum:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> BaseNum for T
|
impl<T> BaseNum for T where
|
||||||
where
|
|
||||||
T: Copy
|
T: Copy
|
||||||
+ Clone
|
+ Clone
|
||||||
+ fmt::Debug
|
+ fmt::Debug
|
||||||
|
@ -48,7 +47,7 @@ where
|
||||||
+ SubAssign
|
+ SubAssign
|
||||||
+ MulAssign
|
+ MulAssign
|
||||||
+ DivAssign
|
+ DivAssign
|
||||||
+ RemAssign,
|
+ RemAssign
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,12 +61,11 @@ pub trait BaseFloat:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> BaseFloat for T
|
impl<T> BaseFloat for T where
|
||||||
where
|
|
||||||
T: BaseNum
|
T: BaseNum
|
||||||
+ Float
|
+ Float
|
||||||
+ approx::AbsDiffEq<Epsilon = Self>
|
+ approx::AbsDiffEq<Epsilon = Self>
|
||||||
+ approx::RelativeEq<Epsilon = Self>
|
+ approx::RelativeEq<Epsilon = Self>
|
||||||
+ approx::UlpsEq<Epsilon = Self>,
|
+ approx::UlpsEq<Epsilon = Self>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use num_traits::Zero;
|
|
||||||
use num_traits::cast;
|
use num_traits::cast;
|
||||||
|
use num_traits::Zero;
|
||||||
|
|
||||||
use structure::Angle;
|
use structure::Angle;
|
||||||
|
|
||||||
|
@ -38,7 +38,8 @@ pub fn perspective<S: BaseFloat, A: Into<Rad<S>>>(
|
||||||
aspect: aspect,
|
aspect: aspect,
|
||||||
near: near,
|
near: near,
|
||||||
far: far,
|
far: far,
|
||||||
}.into()
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a perspective matrix from a view frustum.
|
/// Create a perspective matrix from a view frustum.
|
||||||
|
@ -54,7 +55,8 @@ pub fn frustum<S: BaseFloat>(left: S, right: S, bottom: S, top: S, near: S, far:
|
||||||
top: top,
|
top: top,
|
||||||
near: near,
|
near: near,
|
||||||
far: far,
|
far: far,
|
||||||
}.into()
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an orthographic projection matrix.
|
/// Create an orthographic projection matrix.
|
||||||
|
@ -70,7 +72,8 @@ pub fn ortho<S: BaseFloat>(left: S, right: S, bottom: S, top: S, near: S, far: S
|
||||||
top: top,
|
top: top,
|
||||||
near: near,
|
near: near,
|
||||||
far: far,
|
far: far,
|
||||||
}.into()
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A perspective projection based on a vertical field-of-view angle.
|
/// A perspective projection based on a vertical field-of-view angle.
|
||||||
|
|
|
@ -17,12 +17,12 @@ use std::iter;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::*;
|
use std::ops::*;
|
||||||
|
|
||||||
|
use num_traits::{cast, NumCast};
|
||||||
#[cfg(feature = "rand")]
|
#[cfg(feature = "rand")]
|
||||||
use rand::{
|
use rand::{
|
||||||
Rng,
|
|
||||||
distributions::{Distribution, Standard},
|
distributions::{Distribution, Standard},
|
||||||
|
Rng,
|
||||||
};
|
};
|
||||||
use num_traits::{cast, NumCast};
|
|
||||||
|
|
||||||
use structure::*;
|
use structure::*;
|
||||||
|
|
||||||
|
@ -626,17 +626,19 @@ macro_rules! index_operators {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index<'a>(&'a self, i: $I) -> &'a $Output {
|
fn index<'a>(&'a self, i: $I) -> &'a $Output {
|
||||||
let v: &[$S; 4] = self.as_ref(); &v[i]
|
let v: &[$S; 4] = self.as_ref();
|
||||||
|
&v[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<$S: BaseFloat> IndexMut<$I> for Quaternion<$S> {
|
impl<$S: BaseFloat> IndexMut<$I> for Quaternion<$S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index_mut<'a>(&'a mut self, i: $I) -> &'a mut $Output {
|
fn index_mut<'a>(&'a mut self, i: $I) -> &'a mut $Output {
|
||||||
let v: &mut [$S; 4] = self.as_mut(); &mut v[i]
|
let v: &mut [$S; 4] = self.as_mut();
|
||||||
}
|
&mut v[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
index_operators!(S, S, usize);
|
index_operators!(S, S, usize);
|
||||||
|
@ -647,9 +649,11 @@ index_operators!(S, [S], RangeFull);
|
||||||
|
|
||||||
#[cfg(feature = "rand")]
|
#[cfg(feature = "rand")]
|
||||||
impl<S> Distribution<Quaternion<S>> for Standard
|
impl<S> Distribution<Quaternion<S>> for Standard
|
||||||
where Standard: Distribution<S>,
|
where
|
||||||
|
Standard: Distribution<S>,
|
||||||
Standard: Distribution<Vector3<S>>,
|
Standard: Distribution<Vector3<S>>,
|
||||||
S: BaseFloat {
|
S: BaseFloat,
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Quaternion<S> {
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Quaternion<S> {
|
||||||
Quaternion::from_sv(rng.gen(), rng.gen())
|
Quaternion::from_sv(rng.gen(), rng.gen())
|
||||||
|
|
|
@ -54,7 +54,7 @@ impl InnerSpace for Quaternion<f32> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{
|
impl_operator_simd! {
|
||||||
[Simdf32x4]; Neg for Quaternion<f32> {
|
[Simdf32x4]; Neg for Quaternion<f32> {
|
||||||
fn neg(lhs) -> Quaternion<f32> {
|
fn neg(lhs) -> Quaternion<f32> {
|
||||||
(-lhs).into()
|
(-lhs).into()
|
||||||
|
@ -62,7 +62,7 @@ impl_operator_simd!{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{@rs
|
impl_operator_simd! {@rs
|
||||||
[Simdf32x4]; Mul<f32> for Quaternion<f32> {
|
[Simdf32x4]; Mul<f32> for Quaternion<f32> {
|
||||||
fn mul(lhs, rhs) -> Quaternion<f32> {
|
fn mul(lhs, rhs) -> Quaternion<f32> {
|
||||||
(lhs * rhs).into()
|
(lhs * rhs).into()
|
||||||
|
@ -78,7 +78,7 @@ impl MulAssign<f32> for Quaternion<f32> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{@rs
|
impl_operator_simd! {@rs
|
||||||
[Simdf32x4]; Div<f32> for Quaternion<f32> {
|
[Simdf32x4]; Div<f32> for Quaternion<f32> {
|
||||||
fn div(lhs, rhs) -> Quaternion<f32> {
|
fn div(lhs, rhs) -> Quaternion<f32> {
|
||||||
(lhs / rhs).into()
|
(lhs / rhs).into()
|
||||||
|
@ -94,7 +94,7 @@ impl DivAssign<f32> for Quaternion<f32> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{
|
impl_operator_simd! {
|
||||||
[Simdf32x4]; Add<Quaternion<f32>> for Quaternion<f32> {
|
[Simdf32x4]; Add<Quaternion<f32>> for Quaternion<f32> {
|
||||||
fn add(lhs, rhs) -> Quaternion<f32> {
|
fn add(lhs, rhs) -> Quaternion<f32> {
|
||||||
(lhs + rhs).into()
|
(lhs + rhs).into()
|
||||||
|
@ -111,7 +111,7 @@ impl AddAssign for Quaternion<f32> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{
|
impl_operator_simd! {
|
||||||
[Simdf32x4]; Sub<Quaternion<f32>> for Quaternion<f32> {
|
[Simdf32x4]; Sub<Quaternion<f32>> for Quaternion<f32> {
|
||||||
fn sub(lhs, rhs) -> Quaternion<f32> {
|
fn sub(lhs, rhs) -> Quaternion<f32> {
|
||||||
(lhs - rhs).into()
|
(lhs - rhs).into()
|
||||||
|
@ -128,7 +128,7 @@ impl SubAssign for Quaternion<f32> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{
|
impl_operator_simd! {
|
||||||
[Simdf32x4]; Mul<Quaternion<f32>> for Quaternion<f32> {
|
[Simdf32x4]; Mul<Quaternion<f32>> for Quaternion<f32> {
|
||||||
fn mul(lhs, rhs) -> Quaternion<f32> {
|
fn mul(lhs, rhs) -> Quaternion<f32> {
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,17 +62,18 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A two-dimensional rotation.
|
/// A two-dimensional rotation.
|
||||||
pub trait Rotation2<S: BaseFloat>
|
pub trait Rotation2<S: BaseFloat>:
|
||||||
: Rotation<Point2<S>> + Into<Matrix2<S>> + Into<Basis2<S>> {
|
Rotation<Point2<S>> + Into<Matrix2<S>> + Into<Basis2<S>>
|
||||||
|
{
|
||||||
/// Create a rotation by a given angle. Thus is a redundant case of both
|
/// Create a rotation by a given angle. Thus is a redundant case of both
|
||||||
/// from_axis_angle() and from_euler() for 2D space.
|
/// from_axis_angle() and from_euler() for 2D space.
|
||||||
fn from_angle<A: Into<Rad<S>>>(theta: A) -> Self;
|
fn from_angle<A: Into<Rad<S>>>(theta: A) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A three-dimensional rotation.
|
/// A three-dimensional rotation.
|
||||||
pub trait Rotation3<S: BaseFloat>
|
pub trait Rotation3<S: BaseFloat>:
|
||||||
: Rotation<Point3<S>> + Into<Matrix3<S>> + Into<Basis3<S>> + Into<Quaternion<S>> + From<Euler<Rad<S>>>
|
Rotation<Point3<S>> + Into<Matrix3<S>> + Into<Basis3<S>> + Into<Quaternion<S>> + From<Euler<Rad<S>>>
|
||||||
{
|
{
|
||||||
/// Create a rotation using an angle around a given axis.
|
/// Create a rotation using an angle around a given axis.
|
||||||
///
|
///
|
||||||
/// The specified axis **must be normalized**, or it represents an invalid rotation.
|
/// The specified axis **must be normalized**, or it represents an invalid rotation.
|
||||||
|
|
|
@ -607,7 +607,11 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
fn normalize_signed(self) -> Self {
|
fn normalize_signed(self) -> Self {
|
||||||
let rem = self.normalize();
|
let rem = self.normalize();
|
||||||
if Self::turn_div_2() < rem { rem - Self::full_turn() } else { rem }
|
if Self::turn_div_2() < rem {
|
||||||
|
rem - Self::full_turn()
|
||||||
|
} else {
|
||||||
|
rem
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the angle rotated by half a turn.
|
/// Return the angle rotated by half a turn.
|
||||||
|
|
|
@ -225,10 +225,10 @@ where
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
mod serde_ser {
|
mod serde_ser {
|
||||||
use structure::VectorSpace;
|
|
||||||
use super::Decomposed;
|
use super::Decomposed;
|
||||||
use serde::{self, Serialize};
|
|
||||||
use serde::ser::SerializeStruct;
|
use serde::ser::SerializeStruct;
|
||||||
|
use serde::{self, Serialize};
|
||||||
|
use structure::VectorSpace;
|
||||||
|
|
||||||
impl<V, R> Serialize for Decomposed<V, R>
|
impl<V, R> Serialize for Decomposed<V, R>
|
||||||
where
|
where
|
||||||
|
@ -252,11 +252,11 @@ mod serde_ser {
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
mod serde_de {
|
mod serde_de {
|
||||||
use structure::VectorSpace;
|
|
||||||
use super::Decomposed;
|
use super::Decomposed;
|
||||||
use serde::{self, Deserialize};
|
use serde::{self, Deserialize};
|
||||||
use std::marker::PhantomData;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use structure::VectorSpace;
|
||||||
|
|
||||||
enum DecomposedField {
|
enum DecomposedField {
|
||||||
Scale,
|
Scale,
|
||||||
|
|
|
@ -13,12 +13,12 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use num_traits::{Bounded, NumCast};
|
||||||
#[cfg(feature = "rand")]
|
#[cfg(feature = "rand")]
|
||||||
use rand::{
|
use rand::{
|
||||||
Rng,
|
|
||||||
distributions::{Distribution, Standard},
|
distributions::{Distribution, Standard},
|
||||||
|
Rng,
|
||||||
};
|
};
|
||||||
use num_traits::{Bounded, NumCast};
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
|
@ -69,7 +69,7 @@ impl Into<Simdf32x4> for Vector4<f32> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{
|
impl_operator_simd! {
|
||||||
[Simdf32x4]; Add<Vector4<f32>> for Vector4<f32> {
|
[Simdf32x4]; Add<Vector4<f32>> for Vector4<f32> {
|
||||||
fn add(lhs, rhs) -> Vector4<f32> {
|
fn add(lhs, rhs) -> Vector4<f32> {
|
||||||
(lhs + rhs).into()
|
(lhs + rhs).into()
|
||||||
|
@ -77,7 +77,7 @@ impl_operator_simd!{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{
|
impl_operator_simd! {
|
||||||
[Simdf32x4]; Sub<Vector4<f32>> for Vector4<f32> {
|
[Simdf32x4]; Sub<Vector4<f32>> for Vector4<f32> {
|
||||||
fn sub(lhs, rhs) -> Vector4<f32> {
|
fn sub(lhs, rhs) -> Vector4<f32> {
|
||||||
(lhs - rhs).into()
|
(lhs - rhs).into()
|
||||||
|
@ -85,7 +85,7 @@ impl_operator_simd!{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{@rs
|
impl_operator_simd! {@rs
|
||||||
[Simdf32x4]; Mul<f32> for Vector4<f32> {
|
[Simdf32x4]; Mul<f32> for Vector4<f32> {
|
||||||
fn mul(lhs, rhs) -> Vector4<f32> {
|
fn mul(lhs, rhs) -> Vector4<f32> {
|
||||||
(lhs * rhs).into()
|
(lhs * rhs).into()
|
||||||
|
@ -93,7 +93,7 @@ impl_operator_simd!{@rs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{@rs
|
impl_operator_simd! {@rs
|
||||||
[Simdf32x4]; Div<f32> for Vector4<f32> {
|
[Simdf32x4]; Div<f32> for Vector4<f32> {
|
||||||
fn div(lhs, rhs) -> Vector4<f32> {
|
fn div(lhs, rhs) -> Vector4<f32> {
|
||||||
(lhs / rhs).into()
|
(lhs / rhs).into()
|
||||||
|
@ -101,7 +101,7 @@ impl_operator_simd!{@rs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{
|
impl_operator_simd! {
|
||||||
[Simdf32x4]; Neg for Vector4<f32> {
|
[Simdf32x4]; Neg for Vector4<f32> {
|
||||||
fn neg(lhs) -> Vector4<f32> {
|
fn neg(lhs) -> Vector4<f32> {
|
||||||
(-lhs).into()
|
(-lhs).into()
|
||||||
|
@ -262,7 +262,7 @@ impl Into<Simdi32x4> for Vector4<i32> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{
|
impl_operator_simd! {
|
||||||
[Simdi32x4]; Add<Vector4<i32>> for Vector4<i32> {
|
[Simdi32x4]; Add<Vector4<i32>> for Vector4<i32> {
|
||||||
fn add(lhs, rhs) -> Vector4<i32> {
|
fn add(lhs, rhs) -> Vector4<i32> {
|
||||||
(lhs + rhs).into()
|
(lhs + rhs).into()
|
||||||
|
@ -270,7 +270,7 @@ impl_operator_simd!{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{
|
impl_operator_simd! {
|
||||||
[Simdi32x4]; Sub<Vector4<i32>> for Vector4<i32> {
|
[Simdi32x4]; Sub<Vector4<i32>> for Vector4<i32> {
|
||||||
fn sub(lhs, rhs) -> Vector4<i32> {
|
fn sub(lhs, rhs) -> Vector4<i32> {
|
||||||
(lhs - rhs).into()
|
(lhs - rhs).into()
|
||||||
|
@ -278,7 +278,7 @@ impl_operator_simd!{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{@rs
|
impl_operator_simd! {@rs
|
||||||
[Simdi32x4]; Mul<i32> for Vector4<i32> {
|
[Simdi32x4]; Mul<i32> for Vector4<i32> {
|
||||||
fn mul(lhs, rhs) -> Vector4<i32> {
|
fn mul(lhs, rhs) -> Vector4<i32> {
|
||||||
(lhs * rhs).into()
|
(lhs * rhs).into()
|
||||||
|
@ -286,7 +286,7 @@ impl_operator_simd!{@rs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{
|
impl_operator_simd! {
|
||||||
[Simdi32x4]; Neg for Vector4<i32> {
|
[Simdi32x4]; Neg for Vector4<i32> {
|
||||||
fn neg(lhs) -> Vector4<i32> {
|
fn neg(lhs) -> Vector4<i32> {
|
||||||
(-lhs).into()
|
(-lhs).into()
|
||||||
|
@ -342,7 +342,7 @@ impl Into<Simdu32x4> for Vector4<u32> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{
|
impl_operator_simd! {
|
||||||
[Simdu32x4]; Add<Vector4<u32>> for Vector4<u32> {
|
[Simdu32x4]; Add<Vector4<u32>> for Vector4<u32> {
|
||||||
fn add(lhs, rhs) -> Vector4<u32> {
|
fn add(lhs, rhs) -> Vector4<u32> {
|
||||||
(lhs + rhs).into()
|
(lhs + rhs).into()
|
||||||
|
@ -350,7 +350,7 @@ impl_operator_simd!{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{
|
impl_operator_simd! {
|
||||||
[Simdu32x4]; Sub<Vector4<u32>> for Vector4<u32> {
|
[Simdu32x4]; Sub<Vector4<u32>> for Vector4<u32> {
|
||||||
fn sub(lhs, rhs) -> Vector4<u32> {
|
fn sub(lhs, rhs) -> Vector4<u32> {
|
||||||
(lhs - rhs).into()
|
(lhs - rhs).into()
|
||||||
|
@ -358,7 +358,7 @@ impl_operator_simd!{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator_simd!{@rs
|
impl_operator_simd! {@rs
|
||||||
[Simdu32x4]; Mul<u32> for Vector4<u32> {
|
[Simdu32x4]; Mul<u32> for Vector4<u32> {
|
||||||
fn mul(lhs, rhs) -> Vector4<u32> {
|
fn mul(lhs, rhs) -> Vector4<u32> {
|
||||||
(lhs * rhs).into()
|
(lhs * rhs).into()
|
||||||
|
|
821
tests/matrix.rs
821
tests/matrix.rs
File diff suppressed because it is too large
Load diff
|
@ -17,7 +17,7 @@ extern crate approx;
|
||||||
extern crate cgmath;
|
extern crate cgmath;
|
||||||
|
|
||||||
macro_rules! impl_test_mul {
|
macro_rules! impl_test_mul {
|
||||||
($s:expr, $v:expr) => (
|
($s:expr, $v:expr) => {
|
||||||
// point * scalar ops
|
// point * scalar ops
|
||||||
assert_eq!($v * $s, Quaternion::from_sv($v.s * $s, $v.v * $s));
|
assert_eq!($v * $s, Quaternion::from_sv($v.s * $s, $v.v * $s));
|
||||||
assert_eq!($s * $v, Quaternion::from_sv($s * $v.s, $s * $v.v));
|
assert_eq!($s * $v, Quaternion::from_sv($s * $v.s, $s * $v.v));
|
||||||
|
@ -25,17 +25,17 @@ macro_rules! impl_test_mul {
|
||||||
assert_eq!($s * &$v, $s * $v);
|
assert_eq!($s * &$v, $s * $v);
|
||||||
// commutativity
|
// commutativity
|
||||||
assert_eq!($v * $s, $s * $v);
|
assert_eq!($v * $s, $s * $v);
|
||||||
)
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_test_div {
|
macro_rules! impl_test_div {
|
||||||
($s:expr, $v:expr) => (
|
($s:expr, $v:expr) => {
|
||||||
// point / scalar ops
|
// point / scalar ops
|
||||||
assert_eq!($v / $s, Quaternion::from_sv($v.s / $s, $v.v / $s));
|
assert_eq!($v / $s, Quaternion::from_sv($v.s / $s, $v.v / $s));
|
||||||
assert_eq!($s / $v, Quaternion::from_sv($s / $v.s, $s / $v.v));
|
assert_eq!($s / $v, Quaternion::from_sv($s / $v.s, $s / $v.v));
|
||||||
assert_eq!(&$v / $s, $v / $s);
|
assert_eq!(&$v / $s, $v / $s);
|
||||||
assert_eq!($s / &$v, $s / $v);
|
assert_eq!($s / &$v, $s / $v);
|
||||||
)
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
mod operators {
|
mod operators {
|
||||||
|
|
|
@ -29,7 +29,8 @@ fn test_invert() {
|
||||||
rot: Quaternion::new(0.5f64, 0.5, 0.5, 0.5),
|
rot: Quaternion::new(0.5f64, 0.5, 0.5, 0.5),
|
||||||
disp: Vector3::new(6.0f64, -7.0, 8.0),
|
disp: Vector3::new(6.0f64, -7.0, 8.0),
|
||||||
};
|
};
|
||||||
let ti = t.inverse_transform()
|
let ti = t
|
||||||
|
.inverse_transform()
|
||||||
.expect("Expected successful inversion");
|
.expect("Expected successful inversion");
|
||||||
let vt = t.transform_vector(v);
|
let vt = t.transform_vector(v);
|
||||||
assert_ulps_eq!(&v, &ti.transform_vector(vt));
|
assert_ulps_eq!(&v, &ti.transform_vector(vt));
|
||||||
|
@ -43,7 +44,8 @@ fn test_inverse_vector() {
|
||||||
rot: Quaternion::new(0.5f64, 0.5, 0.5, 0.5),
|
rot: Quaternion::new(0.5f64, 0.5, 0.5, 0.5),
|
||||||
disp: Vector3::new(6.0f64, -7.0, 8.0),
|
disp: Vector3::new(6.0f64, -7.0, 8.0),
|
||||||
};
|
};
|
||||||
let vt = t.inverse_transform_vector(v)
|
let vt = t
|
||||||
|
.inverse_transform_vector(v)
|
||||||
.expect("Expected successful inversion");
|
.expect("Expected successful inversion");
|
||||||
assert_ulps_eq!(v, t.transform_vector(vt));
|
assert_ulps_eq!(v, t.transform_vector(vt));
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,14 +212,8 @@ fn test_is_perpendicular() {
|
||||||
assert!(
|
assert!(
|
||||||
Vector3::new(0.0f64, 1.0f64, 0.0f64).is_perpendicular(Vector3::new(0.0f64, 0.0f64, 1.0f64))
|
Vector3::new(0.0f64, 1.0f64, 0.0f64).is_perpendicular(Vector3::new(0.0f64, 0.0f64, 1.0f64))
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(Vector4::new(1.0f64, 0.0f64, 0.0f64, 0.0f64)
|
||||||
Vector4::new(1.0f64, 0.0f64, 0.0f64, 0.0f64).is_perpendicular(Vector4::new(
|
.is_perpendicular(Vector4::new(0.0f64, 0.0f64, 0.0f64, 1.0f64)));
|
||||||
0.0f64,
|
|
||||||
0.0f64,
|
|
||||||
0.0f64,
|
|
||||||
1.0f64
|
|
||||||
))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -292,30 +286,18 @@ fn test_angle() {
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_ulps_eq!(
|
assert_ulps_eq!(
|
||||||
Vector4::new(1.0f64, 0.0f64, 1.0f64, 0.0f64).angle(Vector4::new(
|
Vector4::new(1.0f64, 0.0f64, 1.0f64, 0.0f64)
|
||||||
0.0f64,
|
.angle(Vector4::new(0.0f64, 1.0f64, 0.0f64, 1.0f64)),
|
||||||
1.0f64,
|
|
||||||
0.0f64,
|
|
||||||
1.0f64
|
|
||||||
)),
|
|
||||||
&Rad(f64::consts::FRAC_PI_2)
|
&Rad(f64::consts::FRAC_PI_2)
|
||||||
);
|
);
|
||||||
assert_ulps_eq!(
|
assert_ulps_eq!(
|
||||||
Vector4::new(10.0f64, 0.0f64, 10.0f64, 0.0f64).angle(Vector4::new(
|
Vector4::new(10.0f64, 0.0f64, 10.0f64, 0.0f64)
|
||||||
0.0f64,
|
.angle(Vector4::new(0.0f64, 5.0f64, 0.0f64, 5.0f64)),
|
||||||
5.0f64,
|
|
||||||
0.0f64,
|
|
||||||
5.0f64
|
|
||||||
)),
|
|
||||||
&Rad(f64::consts::FRAC_PI_2)
|
&Rad(f64::consts::FRAC_PI_2)
|
||||||
);
|
);
|
||||||
assert_ulps_eq!(
|
assert_ulps_eq!(
|
||||||
Vector4::new(-1.0f64, 0.0f64, -1.0f64, 0.0f64).angle(Vector4::new(
|
Vector4::new(-1.0f64, 0.0f64, -1.0f64, 0.0f64)
|
||||||
0.0f64,
|
.angle(Vector4::new(0.0f64, 1.0f64, 0.0f64, 1.0f64)),
|
||||||
1.0f64,
|
|
||||||
0.0f64,
|
|
||||||
1.0f64
|
|
||||||
)),
|
|
||||||
&Rad(f64::consts::FRAC_PI_2)
|
&Rad(f64::consts::FRAC_PI_2)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,12 +135,8 @@ fn test_rem() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_dot() {
|
fn test_dot() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Vector4::new(1.0f32, 2.0f32, 3.0f32, 4.0f32).dot(Vector4::new(
|
Vector4::new(1.0f32, 2.0f32, 3.0f32, 4.0f32)
|
||||||
5.0f32,
|
.dot(Vector4::new(5.0f32, 6.0f32, 7.0f32, 8.0f32)),
|
||||||
6.0f32,
|
|
||||||
7.0f32,
|
|
||||||
8.0f32
|
|
||||||
)),
|
|
||||||
70.0f32
|
70.0f32
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -164,14 +160,8 @@ fn test_product() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_perpendicular() {
|
fn test_is_perpendicular() {
|
||||||
assert!(
|
assert!(Vector4::new(1.0f32, 0.0f32, 0.0f32, 0.0f32)
|
||||||
Vector4::new(1.0f32, 0.0f32, 0.0f32, 0.0f32).is_perpendicular(Vector4::new(
|
.is_perpendicular(Vector4::new(0.0f32, 0.0f32, 0.0f32, 1.0f32)));
|
||||||
0.0f32,
|
|
||||||
0.0f32,
|
|
||||||
0.0f32,
|
|
||||||
1.0f32
|
|
||||||
))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -210,30 +200,18 @@ mod test_magnitude {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_angle() {
|
fn test_angle() {
|
||||||
assert_ulps_eq!(
|
assert_ulps_eq!(
|
||||||
Vector4::new(1.0f32, 0.0f32, 1.0f32, 0.0f32).angle(Vector4::new(
|
Vector4::new(1.0f32, 0.0f32, 1.0f32, 0.0f32)
|
||||||
0.0f32,
|
.angle(Vector4::new(0.0f32, 1.0f32, 0.0f32, 1.0f32)),
|
||||||
1.0f32,
|
|
||||||
0.0f32,
|
|
||||||
1.0f32
|
|
||||||
)),
|
|
||||||
&Rad(f32::consts::FRAC_PI_2)
|
&Rad(f32::consts::FRAC_PI_2)
|
||||||
);
|
);
|
||||||
assert_ulps_eq!(
|
assert_ulps_eq!(
|
||||||
Vector4::new(10.0f32, 0.0f32, 10.0f32, 0.0f32).angle(Vector4::new(
|
Vector4::new(10.0f32, 0.0f32, 10.0f32, 0.0f32)
|
||||||
0.0f32,
|
.angle(Vector4::new(0.0f32, 5.0f32, 0.0f32, 5.0f32)),
|
||||||
5.0f32,
|
|
||||||
0.0f32,
|
|
||||||
5.0f32
|
|
||||||
)),
|
|
||||||
&Rad(f32::consts::FRAC_PI_2)
|
&Rad(f32::consts::FRAC_PI_2)
|
||||||
);
|
);
|
||||||
assert_ulps_eq!(
|
assert_ulps_eq!(
|
||||||
Vector4::new(-1.0f32, 0.0f32, -1.0f32, 0.0f32).angle(Vector4::new(
|
Vector4::new(-1.0f32, 0.0f32, -1.0f32, 0.0f32)
|
||||||
0.0f32,
|
.angle(Vector4::new(0.0f32, 1.0f32, 0.0f32, 1.0f32)),
|
||||||
1.0f32,
|
|
||||||
0.0f32,
|
|
||||||
1.0f32
|
|
||||||
)),
|
|
||||||
&Rad(f32::consts::FRAC_PI_2)
|
&Rad(f32::consts::FRAC_PI_2)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue