Compare commits
10 commits
575c458705
...
d5e765db61
Author | SHA1 | Date | |
---|---|---|---|
|
d5e765db61 | ||
|
33fb2fd24f | ||
|
2e76e82cc0 | ||
|
11a5346291 | ||
|
78c082e944 | ||
|
d4d19b9122 | ||
|
af127633cc | ||
|
41fb64cea0 | ||
|
e57b543449 | ||
|
df218547d1 |
20 changed files with 180 additions and 140 deletions
|
@ -51,7 +51,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
- Add `Array::len`
|
- Add `Array::len`
|
||||||
- Re-export `Bounded` and implement for vectors, points, and angles
|
- Re-export `Bounded` and implement for vectors, points, and angles
|
||||||
- Add vector subtraction to `EuclideanSpace`
|
- Add vector subtraction to `EuclideanSpace`
|
||||||
- Add swizzle functions behinde that `"swizzle"` feature
|
- Add swizzle functions behind that `"swizzle"` feature
|
||||||
- Add `Matrix4::look_at_dir`
|
- Add `Matrix4::look_at_dir`
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -22,13 +22,14 @@ swizzle = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
approx = "0.5"
|
approx = "0.5"
|
||||||
mint = { version = "0.5", optional = true }
|
mint = { version = "0.5.8", optional = true }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
# small_rng used only for benchmarks
|
# small_rng used only for benchmarks
|
||||||
rand = { version = "0.8", features = ["small_rng"], optional = true }
|
rand = { version = "0.8", features = ["small_rng"], optional = true }
|
||||||
serde = { version = "1.0", features = ["serde_derive"], optional = true }
|
serde = { version = "1.0", features = ["serde_derive"], optional = true }
|
||||||
# works only in rust toolchain up to 1.32, disabled indefinitely
|
# works only in rust toolchain up to 1.32, disabled indefinitely
|
||||||
#simd = { version = "0.2", optional = true }
|
#simd = { version = "0.2", optional = true }
|
||||||
|
bytemuck = { version = "1.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
|
4
build.rs
4
build.rs
|
@ -7,7 +7,7 @@ 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.
|
||||||
/// NOTE: This function assumes that variables are in ASCII format
|
/// NOTE: This function assumes that variables are in ASCII format
|
||||||
#[cfg(feature = "swizzle")]
|
#[cfg(feature = "swizzle")]
|
||||||
fn gen_swizzle_nth<'a>(variables: &'a str, mut i: usize, upto: usize) -> Option<(String, String)> {
|
fn gen_swizzle_nth(variables: &str, mut i: usize, upto: usize) -> Option<(String, String)> {
|
||||||
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();
|
||||||
|
@ -22,7 +22,7 @@ fn gen_swizzle_nth<'a>(variables: &'a str, mut i: usize, upto: usize) -> Option<
|
||||||
let c = variables.as_bytes()[i % n - 1] as char;
|
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 /= n;
|
||||||
}
|
}
|
||||||
Some((swizzle, swizzle_impl))
|
Some((swizzle, swizzle_impl))
|
||||||
}
|
}
|
||||||
|
|
24
src/angle.rs
24
src/angle.rs
|
@ -30,7 +30,7 @@ use rand::{
|
||||||
use structure::*;
|
use structure::*;
|
||||||
|
|
||||||
use approx;
|
use approx;
|
||||||
use num::BaseFloat;
|
use num::{BaseFloat, BaseNum};
|
||||||
|
|
||||||
/// An angle, in radians.
|
/// An angle, in radians.
|
||||||
///
|
///
|
||||||
|
@ -138,38 +138,38 @@ macro_rules! impl_angle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator!(<S: BaseFloat> Add<$Angle<S> > for $Angle<S> {
|
impl_operator!(<S: BaseNum> Add<$Angle<S> > for $Angle<S> {
|
||||||
fn add(lhs, rhs) -> $Angle<S> { $Angle(lhs.0 + rhs.0) }
|
fn add(lhs, rhs) -> $Angle<S> { $Angle(lhs.0 + rhs.0) }
|
||||||
});
|
});
|
||||||
impl_operator!(<S: BaseFloat> Sub<$Angle<S> > for $Angle<S> {
|
impl_operator!(<S: BaseNum> Sub<$Angle<S> > for $Angle<S> {
|
||||||
fn sub(lhs, rhs) -> $Angle<S> { $Angle(lhs.0 - rhs.0) }
|
fn sub(lhs, rhs) -> $Angle<S> { $Angle(lhs.0 - rhs.0) }
|
||||||
});
|
});
|
||||||
impl_operator!(<S: BaseFloat> Div<$Angle<S> > for $Angle<S> {
|
impl_operator!(<S: BaseNum> Div<$Angle<S> > for $Angle<S> {
|
||||||
fn div(lhs, rhs) -> S { lhs.0 / rhs.0 }
|
fn div(lhs, rhs) -> S { lhs.0 / rhs.0 }
|
||||||
});
|
});
|
||||||
impl_operator!(<S: BaseFloat> Rem<$Angle<S> > for $Angle<S> {
|
impl_operator!(<S: BaseNum> Rem<$Angle<S> > for $Angle<S> {
|
||||||
fn rem(lhs, rhs) -> $Angle<S> { $Angle(lhs.0 % rhs.0) }
|
fn rem(lhs, rhs) -> $Angle<S> { $Angle(lhs.0 % rhs.0) }
|
||||||
});
|
});
|
||||||
impl_assignment_operator!(<S: BaseFloat> AddAssign<$Angle<S> > for $Angle<S> {
|
impl_assignment_operator!(<S: BaseNum> AddAssign<$Angle<S> > for $Angle<S> {
|
||||||
fn add_assign(&mut self, other) { self.0 += other.0; }
|
fn add_assign(&mut self, other) { self.0 += other.0; }
|
||||||
});
|
});
|
||||||
impl_assignment_operator!(<S: BaseFloat> SubAssign<$Angle<S> > for $Angle<S> {
|
impl_assignment_operator!(<S: BaseNum> SubAssign<$Angle<S> > for $Angle<S> {
|
||||||
fn sub_assign(&mut self, other) { self.0 -= other.0; }
|
fn sub_assign(&mut self, other) { self.0 -= other.0; }
|
||||||
});
|
});
|
||||||
impl_assignment_operator!(<S: BaseFloat> RemAssign<$Angle<S> > for $Angle<S> {
|
impl_assignment_operator!(<S: BaseNum> RemAssign<$Angle<S> > for $Angle<S> {
|
||||||
fn rem_assign(&mut self, other) { self.0 %= other.0; }
|
fn rem_assign(&mut self, other) { self.0 %= other.0; }
|
||||||
});
|
});
|
||||||
|
|
||||||
impl_operator!(<S: BaseFloat> Mul<S> for $Angle<S> {
|
impl_operator!(<S: BaseNum> Mul<S> for $Angle<S> {
|
||||||
fn mul(lhs, scalar) -> $Angle<S> { $Angle(lhs.0 * scalar) }
|
fn mul(lhs, scalar) -> $Angle<S> { $Angle(lhs.0 * scalar) }
|
||||||
});
|
});
|
||||||
impl_operator!(<S: BaseFloat> Div<S> for $Angle<S> {
|
impl_operator!(<S: BaseNum> Div<S> for $Angle<S> {
|
||||||
fn div(lhs, scalar) -> $Angle<S> { $Angle(lhs.0 / scalar) }
|
fn div(lhs, scalar) -> $Angle<S> { $Angle(lhs.0 / scalar) }
|
||||||
});
|
});
|
||||||
impl_assignment_operator!(<S: BaseFloat> MulAssign<S> for $Angle<S> {
|
impl_assignment_operator!(<S: BaseNum> MulAssign<S> for $Angle<S> {
|
||||||
fn mul_assign(&mut self, scalar) { self.0 *= scalar; }
|
fn mul_assign(&mut self, scalar) { self.0 *= scalar; }
|
||||||
});
|
});
|
||||||
impl_assignment_operator!(<S: BaseFloat> DivAssign<S> for $Angle<S> {
|
impl_assignment_operator!(<S: BaseNum> DivAssign<S> for $Angle<S> {
|
||||||
fn div_assign(&mut self, scalar) { self.0 /= scalar; }
|
fn div_assign(&mut self, scalar) { self.0 /= scalar; }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
//! let uniforms = uniform! {
|
//! let uniforms = uniform! {
|
||||||
//! point: Into::<[_; 2]>::into(point),
|
//! point: Into::<[_; 2]>::into(point),
|
||||||
//! matrix: Into::<[[_; 4]; 4]>::into(matrix),
|
//! matrix: Into::<[[_; 4]; 4]>::into(matrix),
|
||||||
//! // Yuck!! (ノಥ益ಥ)ノ ┻━┻
|
//! // Yuck!! (ノಥ益ಥ)ノ ┻━┻)
|
||||||
//! };
|
//! };
|
||||||
//! # }
|
//! # }
|
||||||
//! ` ` `
|
//! ` ` `
|
||||||
|
|
|
@ -224,3 +224,6 @@ impl<S: Clone, A: Angle + Into<S>> From<Euler<A>> for MintEuler<S> {
|
||||||
MintEuler::from([v.x.into(), v.y.into(), v.z.into()])
|
MintEuler::from([v.x.into(), v.y.into(), v.z.into()])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bytemuck")]
|
||||||
|
impl_bytemuck_cast!(Euler);
|
||||||
|
|
|
@ -55,6 +55,9 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate approx;
|
extern crate approx;
|
||||||
|
|
||||||
|
#[cfg(feature = "bytemuck")]
|
||||||
|
extern crate bytemuck;
|
||||||
|
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
pub extern crate mint;
|
pub extern crate mint;
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,10 @@ macro_rules! default_fn {
|
||||||
|
|
||||||
#[cfg(not(feature = "simd"))]
|
#[cfg(not(feature = "simd"))]
|
||||||
macro_rules! default_fn {
|
macro_rules! default_fn {
|
||||||
{ $($tt:tt)* } => { fn $( $tt )* };
|
{ $($tt:tt)* } => {
|
||||||
|
#[inline]
|
||||||
|
fn $( $tt )*
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a binary operator implementation for the permutations of by-ref and by-val
|
/// Generates a binary operator implementation for the permutations of by-ref and by-val
|
||||||
|
@ -35,7 +38,6 @@ macro_rules! impl_operator {
|
||||||
}) => {
|
}) => {
|
||||||
impl<$S: $Constraint> $Op for $Lhs {
|
impl<$S: $Constraint> $Op for $Lhs {
|
||||||
type Output = $Output;
|
type Output = $Output;
|
||||||
#[inline]
|
|
||||||
default_fn!($op(self) -> $Output {
|
default_fn!($op(self) -> $Output {
|
||||||
let $x = self; $body
|
let $x = self; $body
|
||||||
});
|
});
|
||||||
|
@ -43,7 +45,6 @@ macro_rules! impl_operator {
|
||||||
|
|
||||||
impl<'a, $S: $Constraint> $Op for &'a $Lhs {
|
impl<'a, $S: $Constraint> $Op for &'a $Lhs {
|
||||||
type Output = $Output;
|
type Output = $Output;
|
||||||
#[inline]
|
|
||||||
default_fn!($op(self) -> $Output {
|
default_fn!($op(self) -> $Output {
|
||||||
let $x = self; $body
|
let $x = self; $body
|
||||||
});
|
});
|
||||||
|
@ -55,7 +56,6 @@ macro_rules! impl_operator {
|
||||||
}) => {
|
}) => {
|
||||||
impl<$S: $Constraint> $Op<$Rhs> for $Lhs {
|
impl<$S: $Constraint> $Op<$Rhs> for $Lhs {
|
||||||
type Output = $Output;
|
type Output = $Output;
|
||||||
#[inline]
|
|
||||||
default_fn!($op(self, other: $Rhs) -> $Output {
|
default_fn!($op(self, other: $Rhs) -> $Output {
|
||||||
let ($lhs, $rhs) = (self, other); $body
|
let ($lhs, $rhs) = (self, other); $body
|
||||||
});
|
});
|
||||||
|
@ -63,7 +63,6 @@ macro_rules! impl_operator {
|
||||||
|
|
||||||
impl<'a, $S: $Constraint> $Op<$Rhs> for &'a $Lhs {
|
impl<'a, $S: $Constraint> $Op<$Rhs> for &'a $Lhs {
|
||||||
type Output = $Output;
|
type Output = $Output;
|
||||||
#[inline]
|
|
||||||
default_fn!($op(self, other: $Rhs) -> $Output {
|
default_fn!($op(self, other: $Rhs) -> $Output {
|
||||||
let ($lhs, $rhs) = (self, other); $body
|
let ($lhs, $rhs) = (self, other); $body
|
||||||
});
|
});
|
||||||
|
@ -75,7 +74,6 @@ macro_rules! impl_operator {
|
||||||
}) => {
|
}) => {
|
||||||
impl<$S: $Constraint> $Op<$Rhs> for $Lhs {
|
impl<$S: $Constraint> $Op<$Rhs> for $Lhs {
|
||||||
type Output = $Output;
|
type Output = $Output;
|
||||||
#[inline]
|
|
||||||
default_fn!( $op(self, other: $Rhs) -> $Output {
|
default_fn!( $op(self, other: $Rhs) -> $Output {
|
||||||
let ($lhs, $rhs) = (self, other); $body
|
let ($lhs, $rhs) = (self, other); $body
|
||||||
});
|
});
|
||||||
|
@ -83,7 +81,6 @@ macro_rules! impl_operator {
|
||||||
|
|
||||||
impl<'a, $S: $Constraint> $Op<&'a $Rhs> for $Lhs {
|
impl<'a, $S: $Constraint> $Op<&'a $Rhs> for $Lhs {
|
||||||
type Output = $Output;
|
type Output = $Output;
|
||||||
#[inline]
|
|
||||||
default_fn!( $op(self, other: &'a $Rhs) -> $Output {
|
default_fn!( $op(self, other: &'a $Rhs) -> $Output {
|
||||||
let ($lhs, $rhs) = (self, other); $body
|
let ($lhs, $rhs) = (self, other); $body
|
||||||
});
|
});
|
||||||
|
@ -91,7 +88,6 @@ macro_rules! impl_operator {
|
||||||
|
|
||||||
impl<'a, $S: $Constraint> $Op<$Rhs> for &'a $Lhs {
|
impl<'a, $S: $Constraint> $Op<$Rhs> for &'a $Lhs {
|
||||||
type Output = $Output;
|
type Output = $Output;
|
||||||
#[inline]
|
|
||||||
default_fn!( $op(self, other: $Rhs) -> $Output {
|
default_fn!( $op(self, other: $Rhs) -> $Output {
|
||||||
let ($lhs, $rhs) = (self, other); $body
|
let ($lhs, $rhs) = (self, other); $body
|
||||||
});
|
});
|
||||||
|
@ -99,7 +95,6 @@ macro_rules! impl_operator {
|
||||||
|
|
||||||
impl<'a, 'b, $S: $Constraint> $Op<&'a $Rhs> for &'b $Lhs {
|
impl<'a, 'b, $S: $Constraint> $Op<&'a $Rhs> for &'b $Lhs {
|
||||||
type Output = $Output;
|
type Output = $Output;
|
||||||
#[inline]
|
|
||||||
default_fn!( $op(self, other: &'a $Rhs) -> $Output {
|
default_fn!( $op(self, other: &'a $Rhs) -> $Output {
|
||||||
let ($lhs, $rhs) = (self, other); $body
|
let ($lhs, $rhs) = (self, other); $body
|
||||||
});
|
});
|
||||||
|
@ -111,7 +106,6 @@ macro_rules! impl_operator {
|
||||||
}) => {
|
}) => {
|
||||||
impl $Op<$Rhs<$S>> for $Lhs {
|
impl $Op<$Rhs<$S>> for $Lhs {
|
||||||
type Output = $Output;
|
type Output = $Output;
|
||||||
#[inline]
|
|
||||||
default_fn!( $op(self, other: $Rhs<$S>) -> $Output {
|
default_fn!( $op(self, other: $Rhs<$S>) -> $Output {
|
||||||
let ($lhs, $rhs) = (self, other); $body
|
let ($lhs, $rhs) = (self, other); $body
|
||||||
});
|
});
|
||||||
|
@ -119,7 +113,6 @@ macro_rules! impl_operator {
|
||||||
|
|
||||||
impl<'a> $Op<&'a $Rhs<$S>> for $Lhs {
|
impl<'a> $Op<&'a $Rhs<$S>> for $Lhs {
|
||||||
type Output = $Output;
|
type Output = $Output;
|
||||||
#[inline]
|
|
||||||
default_fn!( $op(self, other: &'a $Rhs<$S>) -> $Output {
|
default_fn!( $op(self, other: &'a $Rhs<$S>) -> $Output {
|
||||||
let ($lhs, $rhs) = (self, other); $body
|
let ($lhs, $rhs) = (self, other); $body
|
||||||
});
|
});
|
||||||
|
@ -132,7 +125,6 @@ macro_rules! impl_assignment_operator {
|
||||||
fn $op:ident(&mut $lhs:ident, $rhs:ident) $body:block
|
fn $op:ident(&mut $lhs:ident, $rhs:ident) $body:block
|
||||||
}) => {
|
}) => {
|
||||||
impl<$S: $Constraint + $Op<$S>> $Op<$Rhs> for $Lhs {
|
impl<$S: $Constraint + $Op<$S>> $Op<$Rhs> for $Lhs {
|
||||||
#[inline]
|
|
||||||
default_fn!( $op(&mut $lhs, $rhs: $Rhs) $body );
|
default_fn!( $op(&mut $lhs, $rhs: $Rhs) $body );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -218,7 +210,7 @@ macro_rules! impl_tuple_conversions {
|
||||||
impl<$S> From<$Tuple> for $ArrayN<$S> {
|
impl<$S> From<$Tuple> for $ArrayN<$S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(v: $Tuple) -> $ArrayN<$S> {
|
fn from(v: $Tuple) -> $ArrayN<$S> {
|
||||||
match v { ($($field),+,) => $ArrayN { $($field: $field),+ } }
|
match v { ($($field),+,) => $ArrayN { $($field),+ } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +365,20 @@ macro_rules! impl_mint_conversions {
|
||||||
$ArrayN { $( $field: v.$field, )+ }
|
$ArrayN { $( $field: v.$field, )+ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S: Clone> mint::IntoMint for $ArrayN<S> {
|
||||||
|
type MintType = mint::$Mint<S>;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate implementation required to cast using `bytemuck`
|
||||||
|
#[cfg(feature = "bytemuck")]
|
||||||
|
macro_rules! impl_bytemuck_cast {
|
||||||
|
($ArrayN:ident) => {
|
||||||
|
unsafe impl<S: bytemuck::Pod> bytemuck::Pod for $ArrayN<S> {}
|
||||||
|
unsafe impl<S: bytemuck::Zeroable> bytemuck::Zeroable for $ArrayN<S> {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/swizzle_operator_macro.rs"));
|
include!(concat!(env!("OUT_DIR"), "/swizzle_operator_macro.rs"));
|
||||||
|
|
|
@ -30,7 +30,7 @@ use structure::*;
|
||||||
use angle::Rad;
|
use angle::Rad;
|
||||||
use approx;
|
use approx;
|
||||||
use euler::Euler;
|
use euler::Euler;
|
||||||
use num::BaseFloat;
|
use num::{BaseFloat, BaseNum};
|
||||||
use point::{Point2, Point3};
|
use point::{Point2, Point3};
|
||||||
use quaternion::Quaternion;
|
use quaternion::Quaternion;
|
||||||
use transform::{Transform, Transform2, Transform3};
|
use transform::{Transform, Transform2, Transform3};
|
||||||
|
@ -563,8 +563,8 @@ impl<S: BaseFloat> VectorSpace for Matrix4<S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> Matrix for Matrix2<S> {
|
impl<S: BaseFloat> Matrix for Matrix2<S> {
|
||||||
type Column = Vector2<S>;
|
|
||||||
type Row = Vector2<S>;
|
type Row = Vector2<S>;
|
||||||
|
type Column = Vector2<S>;
|
||||||
type Transpose = Matrix2<S>;
|
type Transpose = Matrix2<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -661,8 +661,8 @@ impl<S: BaseFloat> SquareMatrix for Matrix2<S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> Matrix for Matrix3<S> {
|
impl<S: BaseFloat> Matrix for Matrix3<S> {
|
||||||
type Column = Vector3<S>;
|
|
||||||
type Row = Vector3<S>;
|
type Row = Vector3<S>;
|
||||||
|
type Column = Vector3<S>;
|
||||||
type Transpose = Matrix3<S>;
|
type Transpose = Matrix3<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -776,8 +776,8 @@ impl<S: BaseFloat> SquareMatrix for Matrix3<S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> Matrix for Matrix4<S> {
|
impl<S: BaseFloat> Matrix for Matrix4<S> {
|
||||||
type Column = Vector4<S>;
|
|
||||||
type Row = Vector4<S>;
|
type Row = Vector4<S>;
|
||||||
|
type Column = Vector4<S>;
|
||||||
type Transpose = Matrix4<S>;
|
type Transpose = Matrix4<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1092,13 +1092,13 @@ impl<S: BaseFloat> Transform<Point2<S>> for Matrix3<S> {
|
||||||
Matrix3::from(Matrix2::look_at(dir, up))
|
Matrix3::from(Matrix2::look_at(dir, up))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn look_at_lh(eye: Point2<S>, center: Point2<S>, up: Vector2<S>) -> Matrix3<S> {
|
fn look_at_rh(eye: Point2<S>, center: Point2<S>, up: Vector2<S>) -> Matrix3<S> {
|
||||||
let dir = center - eye;
|
let dir = eye - center;
|
||||||
Matrix3::from(Matrix2::look_at(dir, up))
|
Matrix3::from(Matrix2::look_at(dir, up))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn look_at_rh(eye: Point2<S>, center: Point2<S>, up: Vector2<S>) -> Matrix3<S> {
|
fn look_at_lh(eye: Point2<S>, center: Point2<S>, up: Vector2<S>) -> Matrix3<S> {
|
||||||
let dir = eye - center;
|
let dir = center - eye;
|
||||||
Matrix3::from(Matrix2::look_at(dir, up))
|
Matrix3::from(Matrix2::look_at(dir, up))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1125,16 +1125,16 @@ impl<S: BaseFloat> Transform<Point3<S>> for Matrix3<S> {
|
||||||
Matrix3::look_to_lh(dir, up)
|
Matrix3::look_to_lh(dir, up)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn look_at_lh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix3<S> {
|
|
||||||
let dir = center - eye;
|
|
||||||
Matrix3::look_to_lh(dir, up)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn look_at_rh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix3<S> {
|
fn look_at_rh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix3<S> {
|
||||||
let dir = center - eye;
|
let dir = center - eye;
|
||||||
Matrix3::look_to_rh(dir, up)
|
Matrix3::look_to_rh(dir, up)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn look_at_lh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix3<S> {
|
||||||
|
let dir = center - eye;
|
||||||
|
Matrix3::look_to_lh(dir, up)
|
||||||
|
}
|
||||||
|
|
||||||
fn transform_vector(&self, vec: Vector3<S>) -> Vector3<S> {
|
fn transform_vector(&self, vec: Vector3<S>) -> Vector3<S> {
|
||||||
self * vec
|
self * vec
|
||||||
}
|
}
|
||||||
|
@ -1157,14 +1157,14 @@ impl<S: BaseFloat> Transform<Point3<S>> for Matrix4<S> {
|
||||||
Matrix4::look_at_rh(eye, center, up)
|
Matrix4::look_at_rh(eye, center, up)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn look_at_lh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix4<S> {
|
|
||||||
Matrix4::look_at_lh(eye, center, up)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn look_at_rh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix4<S> {
|
fn look_at_rh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix4<S> {
|
||||||
Matrix4::look_at_rh(eye, center, up)
|
Matrix4::look_at_rh(eye, center, up)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn look_at_lh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix4<S> {
|
||||||
|
Matrix4::look_at_lh(eye, center, up)
|
||||||
|
}
|
||||||
|
|
||||||
fn transform_vector(&self, vec: Vector3<S>) -> Vector3<S> {
|
fn transform_vector(&self, vec: Vector3<S>) -> Vector3<S> {
|
||||||
(self * vec.extend(S::zero())).truncate()
|
(self * vec.extend(S::zero())).truncate()
|
||||||
}
|
}
|
||||||
|
@ -1559,6 +1559,9 @@ macro_rules! mint_conversions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S: Clone> mint::IntoMint for $MatrixN<S> {
|
||||||
|
type MintType = mint::$MintN<S>;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1569,7 +1572,14 @@ mint_conversions!(Matrix3 { x, y, z }, ColumnMatrix3);
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
mint_conversions!(Matrix4 { x, y, z, w }, ColumnMatrix4);
|
mint_conversions!(Matrix4 { x, y, z, w }, ColumnMatrix4);
|
||||||
|
|
||||||
impl<S: BaseFloat> From<Matrix2<S>> for Matrix3<S> {
|
#[cfg(feature = "bytemuck")]
|
||||||
|
impl_bytemuck_cast!(Matrix2);
|
||||||
|
#[cfg(feature = "bytemuck")]
|
||||||
|
impl_bytemuck_cast!(Matrix3);
|
||||||
|
#[cfg(feature = "bytemuck")]
|
||||||
|
impl_bytemuck_cast!(Matrix4);
|
||||||
|
|
||||||
|
impl<S: BaseNum> From<Matrix2<S>> for Matrix3<S> {
|
||||||
/// Clone the elements of a 2-dimensional matrix into the top-left corner
|
/// Clone the elements of a 2-dimensional matrix into the top-left corner
|
||||||
/// of a 3-dimensional identity matrix.
|
/// of a 3-dimensional identity matrix.
|
||||||
fn from(m: Matrix2<S>) -> Matrix3<S> {
|
fn from(m: Matrix2<S>) -> Matrix3<S> {
|
||||||
|
@ -1582,7 +1592,7 @@ impl<S: BaseFloat> From<Matrix2<S>> for Matrix3<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> From<Matrix2<S>> for Matrix4<S> {
|
impl<S: BaseNum> From<Matrix2<S>> for Matrix4<S> {
|
||||||
/// Clone the elements of a 2-dimensional matrix into the top-left corner
|
/// Clone the elements of a 2-dimensional matrix into the top-left corner
|
||||||
/// of a 4-dimensional identity matrix.
|
/// of a 4-dimensional identity matrix.
|
||||||
fn from(m: Matrix2<S>) -> Matrix4<S> {
|
fn from(m: Matrix2<S>) -> Matrix4<S> {
|
||||||
|
@ -1596,7 +1606,7 @@ impl<S: BaseFloat> From<Matrix2<S>> for Matrix4<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> From<Matrix3<S>> for Matrix4<S> {
|
impl<S: BaseNum> From<Matrix3<S>> for Matrix4<S> {
|
||||||
/// Clone the elements of a 3-dimensional matrix into the top-left corner
|
/// Clone the elements of a 3-dimensional matrix into the top-left corner
|
||||||
/// of a 4-dimensional identity matrix.
|
/// of a 4-dimensional identity matrix.
|
||||||
fn from(m: Matrix3<S>) -> Matrix4<S> {
|
fn from(m: Matrix3<S>) -> Matrix4<S> {
|
||||||
|
@ -1678,7 +1688,7 @@ impl<S: fmt::Debug> fmt::Debug for Matrix4<S> {
|
||||||
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: BaseNum,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix2<S> {
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix2<S> {
|
||||||
|
@ -1693,7 +1703,7 @@ where
|
||||||
impl<S> Distribution<Matrix3<S>> for Standard
|
impl<S> Distribution<Matrix3<S>> for Standard
|
||||||
where
|
where
|
||||||
Standard: Distribution<Vector3<S>>,
|
Standard: Distribution<Vector3<S>>,
|
||||||
S: BaseFloat,
|
S: BaseNum,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix3<S> {
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix3<S> {
|
||||||
|
@ -1709,7 +1719,7 @@ where
|
||||||
impl<S> Distribution<Matrix4<S>> for Standard
|
impl<S> Distribution<Matrix4<S>> for Standard
|
||||||
where
|
where
|
||||||
Standard: Distribution<Vector4<S>>,
|
Standard: Distribution<Vector4<S>>,
|
||||||
S: BaseFloat,
|
S: BaseNum,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix4<S> {
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix4<S> {
|
||||||
|
|
|
@ -18,7 +18,7 @@ use approx;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::*;
|
use std::ops::*;
|
||||||
|
|
||||||
use num_traits::{Float, Num, NumCast};
|
use num_traits::{Float, Num};
|
||||||
|
|
||||||
/// Base numeric types with partial ordering
|
/// Base numeric types with partial ordering
|
||||||
pub trait BaseNum:
|
pub trait BaseNum:
|
||||||
|
@ -26,7 +26,6 @@ pub trait BaseNum:
|
||||||
+ Clone
|
+ Clone
|
||||||
+ fmt::Debug
|
+ fmt::Debug
|
||||||
+ Num
|
+ Num
|
||||||
+ NumCast
|
|
||||||
+ PartialOrd
|
+ PartialOrd
|
||||||
+ AddAssign
|
+ AddAssign
|
||||||
+ SubAssign
|
+ SubAssign
|
||||||
|
@ -41,7 +40,6 @@ impl<T> BaseNum for T where
|
||||||
+ Clone
|
+ Clone
|
||||||
+ fmt::Debug
|
+ fmt::Debug
|
||||||
+ Num
|
+ Num
|
||||||
+ NumCast
|
|
||||||
+ PartialOrd
|
+ PartialOrd
|
||||||
+ AddAssign
|
+ AddAssign
|
||||||
+ SubAssign
|
+ SubAssign
|
||||||
|
|
15
src/point.rs
15
src/point.rs
|
@ -83,7 +83,7 @@ macro_rules! impl_point {
|
||||||
/// Construct a new point, using the provided values.
|
/// Construct a new point, using the provided values.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn new($($field: S),+) -> $PointN<S> {
|
pub const fn new($($field: S),+) -> $PointN<S> {
|
||||||
$PointN { $($field: $field),+ }
|
$PointN { $($field),+ }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform the given operation on each field in the point, returning a new point
|
/// Perform the given operation on each field in the point, returning a new point
|
||||||
|
@ -154,7 +154,7 @@ macro_rules! impl_point {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> MetricSpace for $PointN<S> {
|
impl<S: BaseNum> MetricSpace for $PointN<S> {
|
||||||
type Metric = S;
|
type Metric = S;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -368,6 +368,13 @@ impl_mint_conversions!(Point2 { x, y }, Point2);
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
impl_mint_conversions!(Point3 { x, y, z }, Point3);
|
impl_mint_conversions!(Point3 { x, y, z }, Point3);
|
||||||
|
|
||||||
|
#[cfg(feature = "bytemuck")]
|
||||||
|
impl_bytemuck_cast!(Point1);
|
||||||
|
#[cfg(feature = "bytemuck")]
|
||||||
|
impl_bytemuck_cast!(Point2);
|
||||||
|
#[cfg(feature = "bytemuck")]
|
||||||
|
impl_bytemuck_cast!(Point3);
|
||||||
|
|
||||||
impl<S: fmt::Debug> fmt::Debug for Point1<S> {
|
impl<S: fmt::Debug> fmt::Debug for Point1<S> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "Point1 ")?;
|
write!(f, "Point1 ")?;
|
||||||
|
@ -405,7 +412,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_index_mut() {
|
fn test_index_mut() {
|
||||||
let mut p = POINT2;
|
let mut p = POINT2;
|
||||||
*&mut p[0] = 0;
|
p[0] = 0;
|
||||||
assert_eq!(p, [0, 2].into());
|
assert_eq!(p, [0, 2].into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,7 +525,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_index_mut() {
|
fn test_index_mut() {
|
||||||
let mut p = POINT3;
|
let mut p = POINT3;
|
||||||
*&mut p[1] = 0;
|
p[1] = 0;
|
||||||
assert_eq!(p, [1, 0, 3].into());
|
assert_eq!(p, [1, 0, 3].into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ use angle::Rad;
|
||||||
use approx;
|
use approx;
|
||||||
use euler::Euler;
|
use euler::Euler;
|
||||||
use matrix::{Matrix3, Matrix4};
|
use matrix::{Matrix3, Matrix4};
|
||||||
use num::BaseFloat;
|
use num::{BaseFloat, BaseNum};
|
||||||
use point::Point3;
|
use point::Point3;
|
||||||
use quaternion;
|
use quaternion;
|
||||||
use rotation::{Basis3, Rotation, Rotation3};
|
use rotation::{Basis3, Rotation, Rotation3};
|
||||||
|
@ -72,10 +72,8 @@ impl<S: BaseFloat> Quaternion<S> {
|
||||||
///
|
///
|
||||||
/// Return the closest rotation that turns `src` vector into `dst`.
|
/// Return the closest rotation that turns `src` vector into `dst`.
|
||||||
///
|
///
|
||||||
/// - [Related StackOverflow question]
|
/// - [Related StackOverflow question](http://stackoverflow.com/questions/1171849/finding-quaternion-representing-the-rotation-from-one-vector-to-another)
|
||||||
/// (http://stackoverflow.com/questions/1171849/finding-quaternion-representing-the-rotation-from-one-vector-to-another)
|
/// - [Ogre implementation for normalized vectors](https://bitbucket.org/sinbad/ogre/src/9db75e3ba05c/OgreMain/include/OgreVector3.h?fileviewer=file-view-default#cl-651)
|
||||||
/// - [Ogre implementation for normalized vectors]
|
|
||||||
/// (https://bitbucket.org/sinbad/ogre/src/9db75e3ba05c/OgreMain/include/OgreVector3.h?fileviewer=file-view-default#cl-651)
|
|
||||||
pub fn from_arc(
|
pub fn from_arc(
|
||||||
src: Vector3<S>,
|
src: Vector3<S>,
|
||||||
dst: Vector3<S>,
|
dst: Vector3<S>,
|
||||||
|
@ -132,10 +130,8 @@ impl<S: BaseFloat> Quaternion<S> {
|
||||||
/// more advisable to use `nlerp` when you know your rotations are going
|
/// more advisable to use `nlerp` when you know your rotations are going
|
||||||
/// to be small.
|
/// to be small.
|
||||||
///
|
///
|
||||||
/// - [Understanding Slerp, Then Not Using It]
|
/// - [Understanding Slerp, Then Not Using It](http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/)
|
||||||
/// (http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/)
|
/// - [Arcsynthesis OpenGL tutorial](https://www.roiatalla.com/public/arcsynthesis/html/Positioning/Tut08%20Interpolation.html)
|
||||||
/// - [Arcsynthesis OpenGL tutorial]
|
|
||||||
/// (http://www.arcsynthesis.org/gltut/Positioning/Tut08%20Interpolation.html)
|
|
||||||
pub fn slerp(self, mut other: Quaternion<S>, amount: S) -> Quaternion<S> {
|
pub fn slerp(self, mut other: Quaternion<S>, amount: S) -> Quaternion<S> {
|
||||||
let mut dot = self.dot(other);
|
let mut dot = self.dot(other);
|
||||||
let dot_threshold: S = cast(0.9995f64).unwrap();
|
let dot_threshold: S = cast(0.9995f64).unwrap();
|
||||||
|
@ -242,7 +238,6 @@ impl<S: NumCast + Copy> Quaternion<S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> InnerSpace for Quaternion<S> {
|
impl<S: BaseFloat> InnerSpace for Quaternion<S> {
|
||||||
#[inline]
|
|
||||||
default_fn!( dot(self, other: Quaternion<S>) -> S {
|
default_fn!( dot(self, other: Quaternion<S>) -> S {
|
||||||
self.s * other.s + self.v.dot(other.v)
|
self.s * other.s + self.v.dot(other.v)
|
||||||
} );
|
} );
|
||||||
|
@ -414,7 +409,7 @@ impl<S: BaseFloat> approx::UlpsEq for Quaternion<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> From<Quaternion<S>> for Matrix3<S> {
|
impl<S: BaseNum> From<Quaternion<S>> for Matrix3<S> {
|
||||||
/// Convert the quaternion to a 3 x 3 rotation matrix.
|
/// Convert the quaternion to a 3 x 3 rotation matrix.
|
||||||
fn from(quat: Quaternion<S>) -> Matrix3<S> {
|
fn from(quat: Quaternion<S>) -> Matrix3<S> {
|
||||||
let x2 = quat.v.x + quat.v.x;
|
let x2 = quat.v.x + quat.v.x;
|
||||||
|
@ -442,7 +437,7 @@ impl<S: BaseFloat> From<Quaternion<S>> for Matrix3<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> From<Quaternion<S>> for Matrix4<S> {
|
impl<S: BaseNum> From<Quaternion<S>> for Matrix4<S> {
|
||||||
/// Convert the quaternion to a 4 x 4 rotation matrix.
|
/// Convert the quaternion to a 4 x 4 rotation matrix.
|
||||||
fn from(quat: Quaternion<S>) -> Matrix4<S> {
|
fn from(quat: Quaternion<S>) -> Matrix4<S> {
|
||||||
let x2 = quat.v.x + quat.v.x;
|
let x2 = quat.v.x + quat.v.x;
|
||||||
|
@ -538,7 +533,7 @@ impl<S: BaseFloat> Rotation3 for Quaternion<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> From<Quaternion<S>> for [S; 4] {
|
impl<S: BaseNum> From<Quaternion<S>> for [S; 4] {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(v: Quaternion<S>) -> Self {
|
fn from(v: Quaternion<S>) -> Self {
|
||||||
let (xi, yj, zk, w) = v.into();
|
let (xi, yj, zk, w) = v.into();
|
||||||
|
@ -546,42 +541,42 @@ impl<S: BaseFloat> From<Quaternion<S>> for [S; 4] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> AsRef<[S; 4]> for Quaternion<S> {
|
impl<S: BaseNum> AsRef<[S; 4]> for Quaternion<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_ref(&self) -> &[S; 4] {
|
fn as_ref(&self) -> &[S; 4] {
|
||||||
unsafe { &*(self as *const quaternion::Quaternion<S> as *const [S; 4]) }
|
unsafe { &*(self as *const quaternion::Quaternion<S> as *const [S; 4]) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> AsMut<[S; 4]> for Quaternion<S> {
|
impl<S: BaseNum> AsMut<[S; 4]> for Quaternion<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_mut(&mut self) -> &mut [S; 4] {
|
fn as_mut(&mut self) -> &mut [S; 4] {
|
||||||
unsafe { &mut *(self as *mut quaternion::Quaternion<S> as *mut [S; 4]) }
|
unsafe { &mut *(self as *mut quaternion::Quaternion<S> as *mut [S; 4]) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> From<[S; 4]> for Quaternion<S> {
|
impl<S: BaseNum> From<[S; 4]> for Quaternion<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(v: [S; 4]) -> Quaternion<S> {
|
fn from(v: [S; 4]) -> Quaternion<S> {
|
||||||
Quaternion::new(v[3], v[0], v[1], v[2])
|
Quaternion::new(v[3], v[0], v[1], v[2])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S: BaseFloat> From<&'a [S; 4]> for &'a Quaternion<S> {
|
impl<'a, S: BaseNum> From<&'a [S; 4]> for &'a Quaternion<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(v: &'a [S; 4]) -> &'a Quaternion<S> {
|
fn from(v: &'a [S; 4]) -> &'a Quaternion<S> {
|
||||||
unsafe { &*(v as *const [S; 4] as *const quaternion::Quaternion<S>) }
|
unsafe { &*(v as *const [S; 4] as *const quaternion::Quaternion<S>) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S: BaseFloat> From<&'a mut [S; 4]> for &'a mut Quaternion<S> {
|
impl<'a, S: BaseNum> From<&'a mut [S; 4]> for &'a mut Quaternion<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(v: &'a mut [S; 4]) -> &'a mut Quaternion<S> {
|
fn from(v: &'a mut [S; 4]) -> &'a mut Quaternion<S> {
|
||||||
unsafe { &mut *(v as *mut [S; 4] as *mut quaternion::Quaternion<S>) }
|
unsafe { &mut *(v as *mut [S; 4] as *mut quaternion::Quaternion<S>) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> From<Quaternion<S>> for (S, S, S, S) {
|
impl<S: BaseNum> From<Quaternion<S>> for (S, S, S, S) {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(v: Quaternion<S>) -> Self {
|
fn from(v: Quaternion<S>) -> Self {
|
||||||
let Quaternion {
|
let Quaternion {
|
||||||
|
@ -592,21 +587,21 @@ impl<S: BaseFloat> From<Quaternion<S>> for (S, S, S, S) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> AsRef<(S, S, S, S)> for Quaternion<S> {
|
impl<S: BaseNum> AsRef<(S, S, S, S)> for Quaternion<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_ref(&self) -> &(S, S, S, S) {
|
fn as_ref(&self) -> &(S, S, S, S) {
|
||||||
unsafe { &*(self as *const quaternion::Quaternion<S> as *const (S, S, S, S)) }
|
unsafe { &*(self as *const quaternion::Quaternion<S> as *const (S, S, S, S)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> AsMut<(S, S, S, S)> for Quaternion<S> {
|
impl<S: BaseNum> AsMut<(S, S, S, S)> for Quaternion<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_mut(&mut self) -> &mut (S, S, S, S) {
|
fn as_mut(&mut self) -> &mut (S, S, S, S) {
|
||||||
unsafe { &mut *(self as *mut quaternion::Quaternion<S> as *mut (S, S, S, S)) }
|
unsafe { &mut *(self as *mut quaternion::Quaternion<S> as *mut (S, S, S, S)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> From<(S, S, S, S)> for Quaternion<S> {
|
impl<S: BaseNum> From<(S, S, S, S)> for Quaternion<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(v: (S, S, S, S)) -> Quaternion<S> {
|
fn from(v: (S, S, S, S)) -> Quaternion<S> {
|
||||||
let (xi, yj, zk, w) = v;
|
let (xi, yj, zk, w) = v;
|
||||||
|
@ -614,14 +609,14 @@ impl<S: BaseFloat> From<(S, S, S, S)> for Quaternion<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S: BaseFloat> From<&'a (S, S, S, S)> for &'a Quaternion<S> {
|
impl<'a, S: BaseNum> From<&'a (S, S, S, S)> for &'a Quaternion<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(v: &'a (S, S, S, S)) -> &'a Quaternion<S> {
|
fn from(v: &'a (S, S, S, S)) -> &'a Quaternion<S> {
|
||||||
unsafe { &*(v as *const (S, S, S, S) as *const quaternion::Quaternion<S>) }
|
unsafe { &*(v as *const (S, S, S, S) as *const quaternion::Quaternion<S>) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S: BaseFloat> From<&'a mut (S, S, S, S)> for &'a mut Quaternion<S> {
|
impl<'a, S: BaseNum> From<&'a mut (S, S, S, S)> for &'a mut Quaternion<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(v: &'a mut (S, S, S, S)) -> &'a mut Quaternion<S> {
|
fn from(v: &'a mut (S, S, S, S)) -> &'a mut Quaternion<S> {
|
||||||
unsafe { &mut *(v as *mut (S, S, S, S) as *mut quaternion::Quaternion<S>) }
|
unsafe { &mut *(v as *mut (S, S, S, S) as *mut quaternion::Quaternion<S>) }
|
||||||
|
@ -630,7 +625,7 @@ impl<'a, S: BaseFloat> From<&'a mut (S, S, S, S)> for &'a mut Quaternion<S> {
|
||||||
|
|
||||||
macro_rules! index_operators {
|
macro_rules! index_operators {
|
||||||
($S:ident, $Output:ty, $I:ty) => {
|
($S:ident, $Output:ty, $I:ty) => {
|
||||||
impl<$S: BaseFloat> Index<$I> for Quaternion<$S> {
|
impl<$S: BaseNum> Index<$I> for Quaternion<$S> {
|
||||||
type Output = $Output;
|
type Output = $Output;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -640,7 +635,7 @@ macro_rules! index_operators {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<$S: BaseFloat> IndexMut<$I> for Quaternion<$S> {
|
impl<$S: BaseNum> 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();
|
let v: &mut [$S; 4] = self.as_mut();
|
||||||
|
@ -661,7 +656,7 @@ impl<S> Distribution<Quaternion<S>> for Standard
|
||||||
where
|
where
|
||||||
Standard: Distribution<S>,
|
Standard: Distribution<S>,
|
||||||
Standard: Distribution<Vector3<S>>,
|
Standard: Distribution<Vector3<S>>,
|
||||||
S: BaseFloat,
|
S: BaseNum,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Quaternion<S> {
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Quaternion<S> {
|
||||||
|
@ -689,6 +684,14 @@ impl<S: Clone> From<Quaternion<S>> for mint::Quaternion<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
|
impl<S: Clone> mint::IntoMint for Quaternion<S> {
|
||||||
|
type MintType = mint::Quaternion<S>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bytemuck")]
|
||||||
|
impl_bytemuck_cast!(Quaternion);
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use quaternion::*;
|
use quaternion::*;
|
||||||
|
|
|
@ -26,7 +26,7 @@ impl From<Simdf32x4> for Quaternion<f32> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(f: Simdf32x4) -> Self {
|
fn from(f: Simdf32x4) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut ret: Self = mem::uninitialized();
|
let mut ret: Self = mem::MaybeUninit();
|
||||||
{
|
{
|
||||||
let ret_mut: &mut [f32; 4] = ret.as_mut();
|
let ret_mut: &mut [f32; 4] = ret.as_mut();
|
||||||
f.store(ret_mut.as_mut(), 0 as usize);
|
f.store(ret_mut.as_mut(), 0 as usize);
|
||||||
|
|
|
@ -23,7 +23,7 @@ use angle::Rad;
|
||||||
use approx;
|
use approx;
|
||||||
use euler::Euler;
|
use euler::Euler;
|
||||||
use matrix::{Matrix2, Matrix3};
|
use matrix::{Matrix2, Matrix3};
|
||||||
use num::BaseFloat;
|
use num::{BaseFloat, BaseNum};
|
||||||
use point::{Point2, Point3};
|
use point::{Point2, Point3};
|
||||||
use quaternion::Quaternion;
|
use quaternion::Quaternion;
|
||||||
use vector::{Vector2, Vector3};
|
use vector::{Vector2, Vector3};
|
||||||
|
@ -36,7 +36,7 @@ where
|
||||||
Self: approx::AbsDiffEq<Epsilon = <<Self as Rotation>::Space as EuclideanSpace>::Scalar>,
|
Self: approx::AbsDiffEq<Epsilon = <<Self as Rotation>::Space as EuclideanSpace>::Scalar>,
|
||||||
Self: approx::RelativeEq<Epsilon = <<Self as Rotation>::Space as EuclideanSpace>::Scalar>,
|
Self: approx::RelativeEq<Epsilon = <<Self as Rotation>::Space as EuclideanSpace>::Scalar>,
|
||||||
Self: approx::UlpsEq<Epsilon = <<Self as Rotation>::Space as EuclideanSpace>::Scalar>,
|
Self: approx::UlpsEq<Epsilon = <<Self as Rotation>::Space as EuclideanSpace>::Scalar>,
|
||||||
<Self::Space as EuclideanSpace>::Scalar: BaseFloat,
|
<Self::Space as EuclideanSpace>::Scalar: BaseNum,
|
||||||
Self: iter::Product<Self>,
|
Self: iter::Product<Self>,
|
||||||
{
|
{
|
||||||
type Space: EuclideanSpace;
|
type Space: EuclideanSpace;
|
||||||
|
@ -149,7 +149,7 @@ pub trait Rotation3:
|
||||||
/// let unit_y = rot.rotate_vector(unit_x);
|
/// let unit_y = rot.rotate_vector(unit_x);
|
||||||
///
|
///
|
||||||
/// // Since sin(π/2) may not be exactly zero due to rounding errors, we can
|
/// // Since sin(π/2) may not be exactly zero due to rounding errors, we can
|
||||||
/// // use approx's assert_ulps_eq!() feature to show that it is close enough.
|
/// // use approx assert_ulps_eq!() feature to show that it is close enough.
|
||||||
/// // assert_ulps_eq!(&unit_y, &Vector2::unit_y()); // TODO: Figure out how to use this
|
/// // assert_ulps_eq!(&unit_y, &Vector2::unit_y()); // TODO: Figure out how to use this
|
||||||
///
|
///
|
||||||
/// // This is exactly equivalent to using the raw matrix itself:
|
/// // This is exactly equivalent to using the raw matrix itself:
|
||||||
|
@ -319,7 +319,7 @@ impl<S: BaseFloat> Basis3<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_quaternion(quaternion: &Quaternion<S>) -> Basis3<S> {
|
pub fn from_quaternion(quaternion: &Quaternion<S>) -> Basis3<S> {
|
||||||
Basis3 {
|
Basis3 {
|
||||||
mat: quaternion.clone().into(),
|
mat: (*quaternion).into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ use approx;
|
||||||
use angle::Rad;
|
use angle::Rad;
|
||||||
use num::{BaseFloat, BaseNum};
|
use num::{BaseFloat, BaseNum};
|
||||||
|
|
||||||
pub use num_traits::{Bounded, One, Zero};
|
pub use num_traits::{Bounded, Num, NumCast, One, Zero};
|
||||||
|
|
||||||
/// An array containing elements of type `Element`
|
/// An array containing elements of type `Element`
|
||||||
pub trait Array
|
pub trait Array
|
||||||
|
@ -388,7 +388,7 @@ where
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
fn midpoint(self, other: Self) -> Self {
|
fn midpoint(self, other: Self) -> Self {
|
||||||
self + (other - self) / cast(2).unwrap()
|
self + (other - self) / (Self::Scalar::one() + Self::Scalar::one())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the average position of all points in the slice.
|
/// Returns the average position of all points in the slice.
|
||||||
|
@ -406,7 +406,10 @@ where
|
||||||
/// let centroid = Point2::centroid(&triangle);
|
/// let centroid = Point2::centroid(&triangle);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
fn centroid(points: &[Self]) -> Self {
|
fn centroid(points: &[Self]) -> Self
|
||||||
|
where
|
||||||
|
Self::Scalar: NumCast,
|
||||||
|
{
|
||||||
let total_displacement = points
|
let total_displacement = points
|
||||||
.iter()
|
.iter()
|
||||||
.fold(Self::Diff::zero(), |acc, p| acc + p.to_vec());
|
.fold(Self::Diff::zero(), |acc, p| acc + p.to_vec());
|
||||||
|
@ -441,7 +444,7 @@ where
|
||||||
/// see `SquareMatrix`.
|
/// see `SquareMatrix`.
|
||||||
pub trait Matrix: VectorSpace
|
pub trait Matrix: VectorSpace
|
||||||
where
|
where
|
||||||
Self::Scalar: Float,
|
Self::Scalar: Num,
|
||||||
|
|
||||||
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
||||||
Self: Index<usize, Output = <Self as Matrix>::Column>,
|
Self: Index<usize, Output = <Self as Matrix>::Column>,
|
||||||
|
@ -493,7 +496,7 @@ where
|
||||||
/// A column-major major matrix where the rows and column vectors are of the same dimensions.
|
/// A column-major major matrix where the rows and column vectors are of the same dimensions.
|
||||||
pub trait SquareMatrix
|
pub trait SquareMatrix
|
||||||
where
|
where
|
||||||
Self::Scalar: Float,
|
Self::Scalar: Num,
|
||||||
|
|
||||||
Self: One,
|
Self: One,
|
||||||
Self: iter::Product<Self>,
|
Self: iter::Product<Self>,
|
||||||
|
@ -580,10 +583,10 @@ where
|
||||||
fn is_symmetric(&self) -> bool;
|
fn is_symmetric(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Angles and their associated trigonometric functions.
|
/// Angles, and their associated trigonometric functions.
|
||||||
///
|
///
|
||||||
/// Typed angles allow for the writing of self-documenting code that makes it
|
/// Typed angles allow for the writing of self-documenting code that makes it
|
||||||
/// clear when semantic violations have occured - for example, adding degrees to
|
/// clear when semantic violations have occurred - for example, adding degrees to
|
||||||
/// radians, or adding a number to an angle.
|
/// radians, or adding a number to an angle.
|
||||||
///
|
///
|
||||||
pub trait Angle
|
pub trait Angle
|
||||||
|
@ -609,7 +612,7 @@ where
|
||||||
{
|
{
|
||||||
type Unitless: BaseFloat;
|
type Unitless: BaseFloat;
|
||||||
|
|
||||||
/// Return the angle, normalized to the range `[0, full_turn)`.
|
/// Return the angle, normalized to the range `[0, full_turn]`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn normalize(self) -> Self {
|
fn normalize(self) -> Self {
|
||||||
let rem = self % Self::full_turn();
|
let rem = self % Self::full_turn();
|
||||||
|
@ -620,7 +623,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the angle, normalized to the range `[-turn_div_2, turn_div_2)`.
|
/// Return the angle, normalized to the range `[-turn_div_2, turn_div_2]`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn normalize_signed(self) -> Self {
|
fn normalize_signed(self) -> Self {
|
||||||
let rem = self.normalize();
|
let rem = self.normalize();
|
||||||
|
|
|
@ -123,8 +123,8 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn look_at_lh(eye: P, center: P, up: P::Diff) -> Decomposed<P::Diff, R> {
|
fn look_at_rh(eye: P, center: P, up: P::Diff) -> Decomposed<P::Diff, R> {
|
||||||
let rot = R::look_at(center - eye, up);
|
let rot = R::look_at(eye - center, up);
|
||||||
let disp = rot.rotate_vector(P::origin() - eye);
|
let disp = rot.rotate_vector(P::origin() - eye);
|
||||||
Decomposed {
|
Decomposed {
|
||||||
scale: P::Scalar::one(),
|
scale: P::Scalar::one(),
|
||||||
|
@ -134,8 +134,8 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn look_at_rh(eye: P, center: P, up: P::Diff) -> Decomposed<P::Diff, R> {
|
fn look_at_lh(eye: P, center: P, up: P::Diff) -> Decomposed<P::Diff, R> {
|
||||||
let rot = R::look_at(eye - center, up);
|
let rot = R::look_at(center - eye, up);
|
||||||
let disp = rot.rotate_vector(P::origin() - eye);
|
let disp = rot.rotate_vector(P::origin() - eye);
|
||||||
Decomposed {
|
Decomposed {
|
||||||
scale: P::Scalar::one(),
|
scale: P::Scalar::one(),
|
||||||
|
@ -366,7 +366,7 @@ mod serde_de {
|
||||||
where
|
where
|
||||||
D: serde::de::Deserializer<'a>,
|
D: serde::de::Deserializer<'a>,
|
||||||
{
|
{
|
||||||
const FIELDS: &'static [&'static str] = &["scale", "rot", "disp"];
|
const FIELDS: &[&str] = &["scale", "rot", "disp"];
|
||||||
deserializer.deserialize_struct("Decomposed", FIELDS, DecomposedVisitor(PhantomData))
|
deserializer.deserialize_struct("Decomposed", FIELDS, DecomposedVisitor(PhantomData))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -422,11 +422,7 @@ mod serde_de {
|
||||||
None => return Err(serde::de::Error::missing_field("disp")),
|
None => return Err(serde::de::Error::missing_field("disp")),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Decomposed {
|
Ok(Decomposed { scale, rot, disp })
|
||||||
scale: scale,
|
|
||||||
rot: rot,
|
|
||||||
disp: disp,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ macro_rules! impl_vector {
|
||||||
/// Construct a new vector, using the provided values.
|
/// Construct a new vector, using the provided values.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn new($($field: S),+) -> $VectorN<S> {
|
pub const fn new($($field: S),+) -> $VectorN<S> {
|
||||||
$VectorN { $($field: $field),+ }
|
$VectorN { $($field),+ }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform the given operation on each field in the vector, returning a new point
|
/// Perform the given operation on each field in the vector, returning a new point
|
||||||
|
@ -209,7 +209,6 @@ macro_rules! impl_vector {
|
||||||
impl<S: Neg<Output = S>> Neg for $VectorN<S> {
|
impl<S: Neg<Output = S>> Neg for $VectorN<S> {
|
||||||
type Output = $VectorN<S>;
|
type Output = $VectorN<S>;
|
||||||
|
|
||||||
#[inline]
|
|
||||||
default_fn!( neg(self) -> $VectorN<S> { $VectorN::new($(-self.$field),+) } );
|
default_fn!( neg(self) -> $VectorN<S> { $VectorN::new($(-self.$field),+) } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +253,7 @@ macro_rules! impl_vector {
|
||||||
#[cfg(feature = "rand")]
|
#[cfg(feature = "rand")]
|
||||||
impl<S> Distribution<$VectorN<S>> for Standard
|
impl<S> Distribution<$VectorN<S>> for Standard
|
||||||
where Standard: Distribution<S>,
|
where Standard: Distribution<S>,
|
||||||
S: BaseFloat {
|
S: BaseNum {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $VectorN<S> {
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $VectorN<S> {
|
||||||
$VectorN { $($field: rng.gen()),+ }
|
$VectorN { $($field: rng.gen()),+ }
|
||||||
|
@ -309,30 +308,30 @@ macro_rules! impl_vector {
|
||||||
});
|
});
|
||||||
|
|
||||||
impl<S: BaseNum> ElementWise for $VectorN<S> {
|
impl<S: BaseNum> ElementWise for $VectorN<S> {
|
||||||
#[inline] default_fn!( add_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field + rhs.$field),+) } );
|
default_fn!( add_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field + rhs.$field),+) } );
|
||||||
#[inline] default_fn!( sub_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field - rhs.$field),+) } );
|
default_fn!( sub_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field - rhs.$field),+) } );
|
||||||
#[inline] default_fn!( mul_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field * rhs.$field),+) } );
|
default_fn!( mul_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field * rhs.$field),+) } );
|
||||||
#[inline] default_fn!( div_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field / rhs.$field),+) } );
|
default_fn!( div_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field / rhs.$field),+) } );
|
||||||
#[inline] fn rem_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field % rhs.$field),+) }
|
#[inline] fn rem_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field % rhs.$field),+) }
|
||||||
|
|
||||||
#[inline] default_fn!( add_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field += rhs.$field);+ } );
|
default_fn!( add_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field += rhs.$field);+ } );
|
||||||
#[inline] default_fn!( sub_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field -= rhs.$field);+ } );
|
default_fn!( sub_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field -= rhs.$field);+ } );
|
||||||
#[inline] default_fn!( mul_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field *= rhs.$field);+ } );
|
default_fn!( mul_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field *= rhs.$field);+ } );
|
||||||
#[inline] default_fn!( div_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field /= rhs.$field);+ } );
|
default_fn!( div_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field /= rhs.$field);+ } );
|
||||||
#[inline] fn rem_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field %= rhs.$field);+ }
|
#[inline] fn rem_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field %= rhs.$field);+ }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum> ElementWise<S> for $VectorN<S> {
|
impl<S: BaseNum> ElementWise<S> for $VectorN<S> {
|
||||||
#[inline] default_fn!( add_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field + rhs),+) } );
|
default_fn!( add_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field + rhs),+) } );
|
||||||
#[inline] default_fn!( sub_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field - rhs),+) } );
|
default_fn!( sub_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field - rhs),+) } );
|
||||||
#[inline] default_fn!( mul_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field * rhs),+) } );
|
default_fn!( mul_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field * rhs),+) } );
|
||||||
#[inline] default_fn!( div_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field / rhs),+) } );
|
default_fn!( div_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field / rhs),+) } );
|
||||||
#[inline] fn rem_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field % rhs),+) }
|
#[inline] fn rem_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field % rhs),+) }
|
||||||
|
|
||||||
#[inline] default_fn!( add_assign_element_wise(&mut self, rhs: S) { $(self.$field += rhs);+ } );
|
default_fn!( add_assign_element_wise(&mut self, rhs: S) { $(self.$field += rhs);+ } );
|
||||||
#[inline] default_fn!( sub_assign_element_wise(&mut self, rhs: S) { $(self.$field -= rhs);+ } );
|
default_fn!( sub_assign_element_wise(&mut self, rhs: S) { $(self.$field -= rhs);+ } );
|
||||||
#[inline] default_fn!( mul_assign_element_wise(&mut self, rhs: S) { $(self.$field *= rhs);+ } );
|
default_fn!( mul_assign_element_wise(&mut self, rhs: S) { $(self.$field *= rhs);+ } );
|
||||||
#[inline] default_fn!( div_assign_element_wise(&mut self, rhs: S) { $(self.$field /= rhs);+ } );
|
default_fn!( div_assign_element_wise(&mut self, rhs: S) { $(self.$field /= rhs);+ } );
|
||||||
#[inline] fn rem_assign_element_wise(&mut self, rhs: S) { $(self.$field %= rhs);+ }
|
#[inline] fn rem_assign_element_wise(&mut self, rhs: S) { $(self.$field %= rhs);+ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,7 +519,7 @@ impl<S: BaseNum> Vector4<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn dot<V: InnerSpace>(a: V, b: V) -> V::Scalar
|
pub fn dot<V: InnerSpace>(a: V, b: V) -> V::Scalar
|
||||||
where
|
where
|
||||||
V::Scalar: BaseFloat,
|
V::Scalar: BaseNum,
|
||||||
{
|
{
|
||||||
V::dot(a, b)
|
V::dot(a, b)
|
||||||
}
|
}
|
||||||
|
@ -597,6 +596,18 @@ impl<S: fmt::Debug> fmt::Debug for Vector4<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bytemuck")]
|
||||||
|
impl_bytemuck_cast!(Vector1);
|
||||||
|
|
||||||
|
#[cfg(feature = "bytemuck")]
|
||||||
|
impl_bytemuck_cast!(Vector2);
|
||||||
|
|
||||||
|
#[cfg(feature = "bytemuck")]
|
||||||
|
impl_bytemuck_cast!(Vector3);
|
||||||
|
|
||||||
|
#[cfg(feature = "bytemuck")]
|
||||||
|
impl_bytemuck_cast!(Vector4);
|
||||||
|
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
impl_mint_conversions!(Vector2 { x, y }, Vector2);
|
impl_mint_conversions!(Vector2 { x, y }, Vector2);
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
|
@ -620,7 +631,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_index_mut() {
|
fn test_index_mut() {
|
||||||
let mut v = VECTOR2;
|
let mut v = VECTOR2;
|
||||||
*&mut v[0] = 0;
|
v[0] = 0;
|
||||||
assert_eq!(v, [0, 2].into());
|
assert_eq!(v, [0, 2].into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,7 +752,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_index_mut() {
|
fn test_index_mut() {
|
||||||
let mut v = VECTOR3;
|
let mut v = VECTOR3;
|
||||||
*&mut v[1] = 0;
|
v[1] = 0;
|
||||||
assert_eq!(v, [1, 0, 3].into());
|
assert_eq!(v, [1, 0, 3].into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -868,7 +879,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_index_mut() {
|
fn test_index_mut() {
|
||||||
let mut v = VECTOR4;
|
let mut v = VECTOR4;
|
||||||
*&mut v[2] = 0;
|
v[2] = 0;
|
||||||
assert_eq!(v, [1, 2, 0, 4].into());
|
assert_eq!(v, [1, 2, 0, 4].into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ impl From<Simdf32x4> for Vector4<f32> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(f: Simdf32x4) -> Self {
|
fn from(f: Simdf32x4) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut ret: Self = mem::uninitialized();
|
let mut ret: Self = mem::MaybeUninit();
|
||||||
{
|
{
|
||||||
let ret_mut: &mut [f32; 4] = ret.as_mut();
|
let ret_mut: &mut [f32; 4] = ret.as_mut();
|
||||||
f.store(ret_mut.as_mut(), 0 as usize);
|
f.store(ret_mut.as_mut(), 0 as usize);
|
||||||
|
@ -244,7 +244,7 @@ impl From<Simdi32x4> for Vector4<i32> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(f: Simdi32x4) -> Self {
|
fn from(f: Simdi32x4) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut ret: Self = mem::uninitialized();
|
let mut ret: Self = mem::MaybeUninit();
|
||||||
{
|
{
|
||||||
let ret_mut: &mut [i32; 4] = ret.as_mut();
|
let ret_mut: &mut [i32; 4] = ret.as_mut();
|
||||||
f.store(ret_mut.as_mut(), 0 as usize);
|
f.store(ret_mut.as_mut(), 0 as usize);
|
||||||
|
@ -324,7 +324,7 @@ impl From<Simdu32x4> for Vector4<u32> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(f: Simdu32x4) -> Self {
|
fn from(f: Simdu32x4) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut ret: Self = mem::uninitialized();
|
let mut ret: Self = mem::MaybeUninit();
|
||||||
{
|
{
|
||||||
let ret_mut: &mut [u32; 4] = ret.as_mut();
|
let ret_mut: &mut [u32; 4] = ret.as_mut();
|
||||||
f.store(ret_mut.as_mut(), 0 as usize);
|
f.store(ret_mut.as_mut(), 0 as usize);
|
||||||
|
|
|
@ -220,7 +220,7 @@ mod from {
|
||||||
use cgmath::*;
|
use cgmath::*;
|
||||||
|
|
||||||
fn check_with_euler(x: Rad<f32>, y: Rad<f32>, z: Rad<f32>) {
|
fn check_with_euler(x: Rad<f32>, y: Rad<f32>, z: Rad<f32>) {
|
||||||
let matrix3 = Matrix3::from(Euler { x: x, y: y, z: z });
|
let matrix3 = Matrix3::from(Euler { x, y, z });
|
||||||
let quaternion = Quaternion::from(matrix3);
|
let quaternion = Quaternion::from(matrix3);
|
||||||
let quaternion_matrix3 = Matrix3::from(quaternion);
|
let quaternion_matrix3 = Matrix3::from(quaternion);
|
||||||
assert_ulps_eq!(matrix3, quaternion_matrix3);
|
assert_ulps_eq!(matrix3, quaternion_matrix3);
|
||||||
|
@ -265,7 +265,7 @@ mod arc {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_same() {
|
fn test_same() {
|
||||||
let v = Vector3::unit_x();
|
let v = Vector3::unit_x();
|
||||||
let q = Quaternion::from_arc(v, v, None);
|
let q = Quaternion::from_arc(v.clone(), v, None);
|
||||||
assert_eq!(q, Quaternion::new(1.0, 0.0, 0.0, 0.0));
|
assert_eq!(q, Quaternion::new(1.0, 0.0, 0.0, 0.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,7 @@ fn test_look_at_lh() {
|
||||||
assert_ulps_eq!(t, Matrix4::<f64>::look_at_lh(eye, center, up));
|
assert_ulps_eq!(t, Matrix4::<f64>::look_at_lh(eye, center, up));
|
||||||
assert_ulps_eq!(&t.transform_point(point), &view_point);
|
assert_ulps_eq!(&t.transform_point(point), &view_point);
|
||||||
|
|
||||||
// Decomposed::look_at is inconsistent and deprecated, but verify that the behvaior
|
// Decomposed::look_at is inconsistent and deprecated, but verify that the behavior
|
||||||
// remains the same until removed.
|
// remains the same until removed.
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
let t: Decomposed<Vector3<f64>, Quaternion<f64>> = Transform::look_at(eye, center, up);
|
let t: Decomposed<Vector3<f64>, Quaternion<f64>> = Transform::look_at(eye, center, up);
|
||||||
|
|
Loading…
Reference in a new issue