Compare commits
No commits in common. "d5e765db61cf9039cb625a789a59ddf6b6ab2337" and "575c458705a735b3e1f723fd4917de7661c3ae23" have entirely different histories.
d5e765db61
...
575c458705
20 changed files with 140 additions and 180 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 behind that `"swizzle"` feature
|
- Add swizzle functions behinde that `"swizzle"` feature
|
||||||
- Add `Matrix4::look_at_dir`
|
- Add `Matrix4::look_at_dir`
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -22,14 +22,13 @@ swizzle = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
approx = "0.5"
|
approx = "0.5"
|
||||||
mint = { version = "0.5.8", optional = true }
|
mint = { version = "0.5", 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(variables: &str, mut i: usize, upto: usize) -> Option<(String, String)> {
|
fn gen_swizzle_nth<'a>(variables: &'a 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(variables: &str, mut i: usize, upto: usize) -> Option<(String
|
||||||
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 /= n;
|
i = 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, BaseNum};
|
use num::BaseFloat;
|
||||||
|
|
||||||
/// An angle, in radians.
|
/// An angle, in radians.
|
||||||
///
|
///
|
||||||
|
@ -138,38 +138,38 @@ macro_rules! impl_angle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_operator!(<S: BaseNum> Add<$Angle<S> > for $Angle<S> {
|
impl_operator!(<S: BaseFloat> 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: BaseNum> Sub<$Angle<S> > for $Angle<S> {
|
impl_operator!(<S: BaseFloat> 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: BaseNum> Div<$Angle<S> > for $Angle<S> {
|
impl_operator!(<S: BaseFloat> 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: BaseNum> Rem<$Angle<S> > for $Angle<S> {
|
impl_operator!(<S: BaseFloat> 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: BaseNum> AddAssign<$Angle<S> > for $Angle<S> {
|
impl_assignment_operator!(<S: BaseFloat> 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: BaseNum> SubAssign<$Angle<S> > for $Angle<S> {
|
impl_assignment_operator!(<S: BaseFloat> 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: BaseNum> RemAssign<$Angle<S> > for $Angle<S> {
|
impl_assignment_operator!(<S: BaseFloat> 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: BaseNum> Mul<S> for $Angle<S> {
|
impl_operator!(<S: BaseFloat> 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: BaseNum> Div<S> for $Angle<S> {
|
impl_operator!(<S: BaseFloat> 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: BaseNum> MulAssign<S> for $Angle<S> {
|
impl_assignment_operator!(<S: BaseFloat> 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: BaseNum> DivAssign<S> for $Angle<S> {
|
impl_assignment_operator!(<S: BaseFloat> 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,6 +224,3 @@ 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,9 +55,6 @@
|
||||||
#[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,10 +24,7 @@ macro_rules! default_fn {
|
||||||
|
|
||||||
#[cfg(not(feature = "simd"))]
|
#[cfg(not(feature = "simd"))]
|
||||||
macro_rules! default_fn {
|
macro_rules! default_fn {
|
||||||
{ $($tt:tt)* } => {
|
{ $($tt:tt)* } => { fn $( $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
|
||||||
|
@ -38,6 +35,7 @@ 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
|
||||||
});
|
});
|
||||||
|
@ -45,6 +43,7 @@ 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
|
||||||
});
|
});
|
||||||
|
@ -56,6 +55,7 @@ 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,6 +63,7 @@ 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
|
||||||
});
|
});
|
||||||
|
@ -74,6 +75,7 @@ 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
|
||||||
});
|
});
|
||||||
|
@ -81,6 +83,7 @@ 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
|
||||||
});
|
});
|
||||||
|
@ -88,6 +91,7 @@ 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
|
||||||
});
|
});
|
||||||
|
@ -95,6 +99,7 @@ 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
|
||||||
});
|
});
|
||||||
|
@ -106,6 +111,7 @@ 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
|
||||||
});
|
});
|
||||||
|
@ -113,6 +119,7 @@ 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
|
||||||
});
|
});
|
||||||
|
@ -125,6 +132,7 @@ 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 );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -210,7 +218,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),+ } }
|
match v { ($($field),+,) => $ArrayN { $($field: $field),+ } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,20 +373,7 @@ 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, BaseNum};
|
use num::BaseFloat;
|
||||||
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 Row = Vector2<S>;
|
|
||||||
type Column = Vector2<S>;
|
type Column = Vector2<S>;
|
||||||
|
type Row = 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 Row = Vector3<S>;
|
|
||||||
type Column = Vector3<S>;
|
type Column = Vector3<S>;
|
||||||
|
type Row = 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 Row = Vector4<S>;
|
|
||||||
type Column = Vector4<S>;
|
type Column = Vector4<S>;
|
||||||
|
type Row = 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_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))
|
||||||
}
|
}
|
||||||
|
|
||||||
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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_rh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix3<S> {
|
|
||||||
let dir = center - eye;
|
|
||||||
Matrix3::look_to_rh(dir, up)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn look_at_lh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix3<S> {
|
fn look_at_lh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix3<S> {
|
||||||
let dir = center - eye;
|
let dir = center - eye;
|
||||||
Matrix3::look_to_lh(dir, up)
|
Matrix3::look_to_lh(dir, up)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn look_at_rh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix3<S> {
|
||||||
|
let dir = center - eye;
|
||||||
|
Matrix3::look_to_rh(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_rh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix4<S> {
|
|
||||||
Matrix4::look_at_rh(eye, center, up)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn look_at_lh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix4<S> {
|
fn look_at_lh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix4<S> {
|
||||||
Matrix4::look_at_lh(eye, center, up)
|
Matrix4::look_at_lh(eye, center, up)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn look_at_rh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix4<S> {
|
||||||
|
Matrix4::look_at_rh(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,9 +1559,6 @@ macro_rules! mint_conversions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Clone> mint::IntoMint for $MatrixN<S> {
|
|
||||||
type MintType = mint::$MintN<S>;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1572,14 +1569,7 @@ 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);
|
||||||
|
|
||||||
#[cfg(feature = "bytemuck")]
|
impl<S: BaseFloat> From<Matrix2<S>> for Matrix3<S> {
|
||||||
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> {
|
||||||
|
@ -1592,7 +1582,7 @@ impl<S: BaseNum> From<Matrix2<S>> for Matrix3<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum> From<Matrix2<S>> for Matrix4<S> {
|
impl<S: BaseFloat> 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> {
|
||||||
|
@ -1606,7 +1596,7 @@ impl<S: BaseNum> From<Matrix2<S>> for Matrix4<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum> From<Matrix3<S>> for Matrix4<S> {
|
impl<S: BaseFloat> 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> {
|
||||||
|
@ -1688,7 +1678,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: BaseNum,
|
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> {
|
||||||
|
@ -1703,7 +1693,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: BaseNum,
|
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> {
|
||||||
|
@ -1719,7 +1709,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: BaseNum,
|
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> {
|
||||||
|
|
|
@ -18,7 +18,7 @@ use approx;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::*;
|
use std::ops::*;
|
||||||
|
|
||||||
use num_traits::{Float, Num};
|
use num_traits::{Float, Num, NumCast};
|
||||||
|
|
||||||
/// Base numeric types with partial ordering
|
/// Base numeric types with partial ordering
|
||||||
pub trait BaseNum:
|
pub trait BaseNum:
|
||||||
|
@ -26,6 +26,7 @@ pub trait BaseNum:
|
||||||
+ Clone
|
+ Clone
|
||||||
+ fmt::Debug
|
+ fmt::Debug
|
||||||
+ Num
|
+ Num
|
||||||
|
+ NumCast
|
||||||
+ PartialOrd
|
+ PartialOrd
|
||||||
+ AddAssign
|
+ AddAssign
|
||||||
+ SubAssign
|
+ SubAssign
|
||||||
|
@ -40,6 +41,7 @@ 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),+ }
|
$PointN { $($field: $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: BaseNum> MetricSpace for $PointN<S> {
|
impl<S: BaseFloat> MetricSpace for $PointN<S> {
|
||||||
type Metric = S;
|
type Metric = S;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -368,13 +368,6 @@ 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 ")?;
|
||||||
|
@ -412,7 +405,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_index_mut() {
|
fn test_index_mut() {
|
||||||
let mut p = POINT2;
|
let mut p = POINT2;
|
||||||
p[0] = 0;
|
*&mut p[0] = 0;
|
||||||
assert_eq!(p, [0, 2].into());
|
assert_eq!(p, [0, 2].into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,7 +518,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_index_mut() {
|
fn test_index_mut() {
|
||||||
let mut p = POINT3;
|
let mut p = POINT3;
|
||||||
p[1] = 0;
|
*&mut 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, BaseNum};
|
use num::BaseFloat;
|
||||||
use point::Point3;
|
use point::Point3;
|
||||||
use quaternion;
|
use quaternion;
|
||||||
use rotation::{Basis3, Rotation, Rotation3};
|
use rotation::{Basis3, Rotation, Rotation3};
|
||||||
|
@ -72,8 +72,10 @@ 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](http://stackoverflow.com/questions/1171849/finding-quaternion-representing-the-rotation-from-one-vector-to-another)
|
/// - [Related StackOverflow question]
|
||||||
/// - [Ogre implementation for normalized vectors](https://bitbucket.org/sinbad/ogre/src/9db75e3ba05c/OgreMain/include/OgreVector3.h?fileviewer=file-view-default#cl-651)
|
/// (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)
|
||||||
pub fn from_arc(
|
pub fn from_arc(
|
||||||
src: Vector3<S>,
|
src: Vector3<S>,
|
||||||
dst: Vector3<S>,
|
dst: Vector3<S>,
|
||||||
|
@ -130,8 +132,10 @@ 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](http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/)
|
/// - [Understanding Slerp, Then Not Using It]
|
||||||
/// - [Arcsynthesis OpenGL tutorial](https://www.roiatalla.com/public/arcsynthesis/html/Positioning/Tut08%20Interpolation.html)
|
/// (http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/)
|
||||||
|
/// - [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();
|
||||||
|
@ -238,6 +242,7 @@ 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)
|
||||||
} );
|
} );
|
||||||
|
@ -409,7 +414,7 @@ impl<S: BaseFloat> approx::UlpsEq for Quaternion<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum> From<Quaternion<S>> for Matrix3<S> {
|
impl<S: BaseFloat> 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;
|
||||||
|
@ -437,7 +442,7 @@ impl<S: BaseNum> From<Quaternion<S>> for Matrix3<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum> From<Quaternion<S>> for Matrix4<S> {
|
impl<S: BaseFloat> 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;
|
||||||
|
@ -533,7 +538,7 @@ impl<S: BaseFloat> Rotation3 for Quaternion<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum> From<Quaternion<S>> for [S; 4] {
|
impl<S: BaseFloat> 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();
|
||||||
|
@ -541,42 +546,42 @@ impl<S: BaseNum> From<Quaternion<S>> for [S; 4] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum> AsRef<[S; 4]> for Quaternion<S> {
|
impl<S: BaseFloat> 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: BaseNum> AsMut<[S; 4]> for Quaternion<S> {
|
impl<S: BaseFloat> 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: BaseNum> From<[S; 4]> for Quaternion<S> {
|
impl<S: BaseFloat> 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: BaseNum> From<&'a [S; 4]> for &'a Quaternion<S> {
|
impl<'a, S: BaseFloat> 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: BaseNum> From<&'a mut [S; 4]> for &'a mut Quaternion<S> {
|
impl<'a, S: BaseFloat> 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: BaseNum> From<Quaternion<S>> for (S, S, S, S) {
|
impl<S: BaseFloat> 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 {
|
||||||
|
@ -587,21 +592,21 @@ impl<S: BaseNum> From<Quaternion<S>> for (S, S, S, S) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum> AsRef<(S, S, S, S)> for Quaternion<S> {
|
impl<S: BaseFloat> 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: BaseNum> AsMut<(S, S, S, S)> for Quaternion<S> {
|
impl<S: BaseFloat> 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: BaseNum> From<(S, S, S, S)> for Quaternion<S> {
|
impl<S: BaseFloat> 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;
|
||||||
|
@ -609,14 +614,14 @@ impl<S: BaseNum> From<(S, S, S, S)> for Quaternion<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S: BaseNum> From<&'a (S, S, S, S)> for &'a Quaternion<S> {
|
impl<'a, S: BaseFloat> 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: BaseNum> From<&'a mut (S, S, S, S)> for &'a mut Quaternion<S> {
|
impl<'a, S: BaseFloat> 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>) }
|
||||||
|
@ -625,7 +630,7 @@ impl<'a, S: BaseNum> 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: BaseNum> Index<$I> for Quaternion<$S> {
|
impl<$S: BaseFloat> Index<$I> for Quaternion<$S> {
|
||||||
type Output = $Output;
|
type Output = $Output;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -635,7 +640,7 @@ macro_rules! index_operators {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<$S: BaseNum> 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();
|
let v: &mut [$S; 4] = self.as_mut();
|
||||||
|
@ -656,7 +661,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: BaseNum,
|
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> {
|
||||||
|
@ -684,14 +689,6 @@ 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::MaybeUninit();
|
let mut ret: Self = mem::uninitialized();
|
||||||
{
|
{
|
||||||
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, BaseNum};
|
use num::BaseFloat;
|
||||||
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: BaseNum,
|
<Self::Space as EuclideanSpace>::Scalar: BaseFloat,
|
||||||
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 assert_ulps_eq!() feature to show that it is close enough.
|
/// // use approx's 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).into(),
|
mat: quaternion.clone().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, Num, NumCast, One, Zero};
|
pub use num_traits::{Bounded, 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) / (Self::Scalar::one() + Self::Scalar::one())
|
self + (other - self) / cast(2).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the average position of all points in the slice.
|
/// Returns the average position of all points in the slice.
|
||||||
|
@ -406,10 +406,7 @@ 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());
|
||||||
|
@ -444,7 +441,7 @@ where
|
||||||
/// see `SquareMatrix`.
|
/// see `SquareMatrix`.
|
||||||
pub trait Matrix: VectorSpace
|
pub trait Matrix: VectorSpace
|
||||||
where
|
where
|
||||||
Self::Scalar: Num,
|
Self::Scalar: Float,
|
||||||
|
|
||||||
// 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>,
|
||||||
|
@ -496,7 +493,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: Num,
|
Self::Scalar: Float,
|
||||||
|
|
||||||
Self: One,
|
Self: One,
|
||||||
Self: iter::Product<Self>,
|
Self: iter::Product<Self>,
|
||||||
|
@ -583,10 +580,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 occurred - for example, adding degrees to
|
/// clear when semantic violations have occured - 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
|
||||||
|
@ -612,7 +609,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();
|
||||||
|
@ -623,7 +620,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_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(),
|
||||||
|
@ -134,8 +134,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(),
|
||||||
|
@ -366,7 +366,7 @@ mod serde_de {
|
||||||
where
|
where
|
||||||
D: serde::de::Deserializer<'a>,
|
D: serde::de::Deserializer<'a>,
|
||||||
{
|
{
|
||||||
const FIELDS: &[&str] = &["scale", "rot", "disp"];
|
const FIELDS: &'static [&'static str] = &["scale", "rot", "disp"];
|
||||||
deserializer.deserialize_struct("Decomposed", FIELDS, DecomposedVisitor(PhantomData))
|
deserializer.deserialize_struct("Decomposed", FIELDS, DecomposedVisitor(PhantomData))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -422,7 +422,11 @@ mod serde_de {
|
||||||
None => return Err(serde::de::Error::missing_field("disp")),
|
None => return Err(serde::de::Error::missing_field("disp")),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Decomposed { scale, rot, disp })
|
Ok(Decomposed {
|
||||||
|
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),+ }
|
$VectorN { $($field: $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,6 +209,7 @@ 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),+) } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +254,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: BaseNum {
|
S: BaseFloat {
|
||||||
#[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()),+ }
|
||||||
|
@ -308,30 +309,30 @@ macro_rules! impl_vector {
|
||||||
});
|
});
|
||||||
|
|
||||||
impl<S: BaseNum> ElementWise for $VectorN<S> {
|
impl<S: BaseNum> ElementWise for $VectorN<S> {
|
||||||
default_fn!( add_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field + rhs.$field),+) } );
|
#[inline] default_fn!( add_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!( sub_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!( mul_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] 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),+) }
|
||||||
|
|
||||||
default_fn!( add_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field += rhs.$field);+ } );
|
#[inline] default_fn!( add_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!( sub_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!( mul_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] 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> {
|
||||||
default_fn!( add_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field + rhs),+) } );
|
#[inline] default_fn!( add_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!( sub_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!( mul_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] 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),+) }
|
||||||
|
|
||||||
default_fn!( add_assign_element_wise(&mut self, rhs: S) { $(self.$field += rhs);+ } );
|
#[inline] default_fn!( add_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!( sub_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!( mul_assign_element_wise(&mut self, rhs: S) { $(self.$field *= rhs);+ } );
|
||||||
default_fn!( div_assign_element_wise(&mut self, rhs: S) { $(self.$field /= rhs);+ } );
|
#[inline] 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);+ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,7 +520,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: BaseNum,
|
V::Scalar: BaseFloat,
|
||||||
{
|
{
|
||||||
V::dot(a, b)
|
V::dot(a, b)
|
||||||
}
|
}
|
||||||
|
@ -596,18 +597,6 @@ 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")]
|
||||||
|
@ -631,7 +620,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_index_mut() {
|
fn test_index_mut() {
|
||||||
let mut v = VECTOR2;
|
let mut v = VECTOR2;
|
||||||
v[0] = 0;
|
*&mut v[0] = 0;
|
||||||
assert_eq!(v, [0, 2].into());
|
assert_eq!(v, [0, 2].into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -752,7 +741,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_index_mut() {
|
fn test_index_mut() {
|
||||||
let mut v = VECTOR3;
|
let mut v = VECTOR3;
|
||||||
v[1] = 0;
|
*&mut v[1] = 0;
|
||||||
assert_eq!(v, [1, 0, 3].into());
|
assert_eq!(v, [1, 0, 3].into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -879,7 +868,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_index_mut() {
|
fn test_index_mut() {
|
||||||
let mut v = VECTOR4;
|
let mut v = VECTOR4;
|
||||||
v[2] = 0;
|
*&mut 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::MaybeUninit();
|
let mut ret: Self = mem::uninitialized();
|
||||||
{
|
{
|
||||||
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::MaybeUninit();
|
let mut ret: Self = mem::uninitialized();
|
||||||
{
|
{
|
||||||
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::MaybeUninit();
|
let mut ret: Self = mem::uninitialized();
|
||||||
{
|
{
|
||||||
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, y, z });
|
let matrix3 = Matrix3::from(Euler { x: x, y: y, z: 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.clone(), v, None);
|
let q = Quaternion::from_arc(v, 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 behavior
|
// Decomposed::look_at is inconsistent and deprecated, but verify that the behvaior
|
||||||
// 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