Compare commits

..

No commits in common. "d5e765db61cf9039cb625a789a59ddf6b6ab2337" and "575c458705a735b3e1f723fd4917de7661c3ae23" have entirely different histories.

20 changed files with 140 additions and 180 deletions

View file

@ -51,7 +51,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Add `Array::len`
- Re-export `Bounded` and implement for vectors, points, and angles
- Add vector subtraction to `EuclideanSpace`
- Add swizzle functions behind that `"swizzle"` feature
- Add swizzle functions behinde that `"swizzle"` feature
- Add `Matrix4::look_at_dir`
### Changed

View file

@ -22,14 +22,13 @@ swizzle = []
[dependencies]
approx = "0.5"
mint = { version = "0.5.8", optional = true }
mint = { version = "0.5", optional = true }
num-traits = "0.2"
# small_rng used only for benchmarks
rand = { version = "0.8", features = ["small_rng"], optional = true }
serde = { version = "1.0", features = ["serde_derive"], optional = true }
# works only in rust toolchain up to 1.32, disabled indefinitely
#simd = { version = "0.2", optional = true }
bytemuck = { version = "1.0", optional = true }
[dev-dependencies]
serde_json = "1.0"

View file

@ -7,7 +7,7 @@ use std::string::String;
/// Generate the name of the swizzle function and what it returns.
/// NOTE: This function assumes that variables are in ASCII format
#[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
let mut swizzle_impl = 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;
swizzle.push(c);
swizzle_impl.push_str(&format!("self.{}, ", c));
i /= n;
i = i / n;
}
Some((swizzle, swizzle_impl))
}

View file

@ -30,7 +30,7 @@ use rand::{
use structure::*;
use approx;
use num::{BaseFloat, BaseNum};
use num::BaseFloat;
/// 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) }
});
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) }
});
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 }
});
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) }
});
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; }
});
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; }
});
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; }
});
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) }
});
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) }
});
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; }
});
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; }
});

View file

@ -20,7 +20,7 @@
//! let uniforms = uniform! {
//! point: Into::<[_; 2]>::into(point),
//! matrix: Into::<[[_; 4]; 4]>::into(matrix),
//! // Yuck!! (ノಥ益ಥ)ノ ┻━┻)
//! // Yuck!! (ノಥ益ಥ)ノ ┻━┻
//! };
//! # }
//! ` ` `

View file

@ -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()])
}
}
#[cfg(feature = "bytemuck")]
impl_bytemuck_cast!(Euler);

View file

@ -55,9 +55,6 @@
#[macro_use]
extern crate approx;
#[cfg(feature = "bytemuck")]
extern crate bytemuck;
#[cfg(feature = "mint")]
pub extern crate mint;

View file

@ -24,10 +24,7 @@ macro_rules! default_fn {
#[cfg(not(feature = "simd"))]
macro_rules! default_fn {
{ $($tt:tt)* } => {
#[inline]
fn $( $tt )*
};
{ $($tt:tt)* } => { fn $( $tt )* };
}
/// 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 {
type Output = $Output;
#[inline]
default_fn!($op(self) -> $Output {
let $x = self; $body
});
@ -45,6 +43,7 @@ macro_rules! impl_operator {
impl<'a, $S: $Constraint> $Op for &'a $Lhs {
type Output = $Output;
#[inline]
default_fn!($op(self) -> $Output {
let $x = self; $body
});
@ -56,6 +55,7 @@ macro_rules! impl_operator {
}) => {
impl<$S: $Constraint> $Op<$Rhs> for $Lhs {
type Output = $Output;
#[inline]
default_fn!($op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
});
@ -63,6 +63,7 @@ macro_rules! impl_operator {
impl<'a, $S: $Constraint> $Op<$Rhs> for &'a $Lhs {
type Output = $Output;
#[inline]
default_fn!($op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
});
@ -74,6 +75,7 @@ macro_rules! impl_operator {
}) => {
impl<$S: $Constraint> $Op<$Rhs> for $Lhs {
type Output = $Output;
#[inline]
default_fn!( $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
});
@ -81,6 +83,7 @@ macro_rules! impl_operator {
impl<'a, $S: $Constraint> $Op<&'a $Rhs> for $Lhs {
type Output = $Output;
#[inline]
default_fn!( $op(self, other: &'a $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
});
@ -88,6 +91,7 @@ macro_rules! impl_operator {
impl<'a, $S: $Constraint> $Op<$Rhs> for &'a $Lhs {
type Output = $Output;
#[inline]
default_fn!( $op(self, other: $Rhs) -> $Output {
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 {
type Output = $Output;
#[inline]
default_fn!( $op(self, other: &'a $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
});
@ -106,6 +111,7 @@ macro_rules! impl_operator {
}) => {
impl $Op<$Rhs<$S>> for $Lhs {
type Output = $Output;
#[inline]
default_fn!( $op(self, other: $Rhs<$S>) -> $Output {
let ($lhs, $rhs) = (self, other); $body
});
@ -113,6 +119,7 @@ macro_rules! impl_operator {
impl<'a> $Op<&'a $Rhs<$S>> for $Lhs {
type Output = $Output;
#[inline]
default_fn!( $op(self, other: &'a $Rhs<$S>) -> $Output {
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
}) => {
impl<$S: $Constraint + $Op<$S>> $Op<$Rhs> for $Lhs {
#[inline]
default_fn!( $op(&mut $lhs, $rhs: $Rhs) $body );
}
};
@ -210,7 +218,7 @@ macro_rules! impl_tuple_conversions {
impl<$S> From<$Tuple> for $ArrayN<$S> {
#[inline]
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, )+ }
}
}
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"));

View file

@ -30,7 +30,7 @@ use structure::*;
use angle::Rad;
use approx;
use euler::Euler;
use num::{BaseFloat, BaseNum};
use num::BaseFloat;
use point::{Point2, Point3};
use quaternion::Quaternion;
use transform::{Transform, Transform2, Transform3};
@ -563,8 +563,8 @@ impl<S: BaseFloat> VectorSpace for Matrix4<S> {
}
impl<S: BaseFloat> Matrix for Matrix2<S> {
type Row = Vector2<S>;
type Column = Vector2<S>;
type Row = Vector2<S>;
type Transpose = Matrix2<S>;
#[inline]
@ -661,8 +661,8 @@ impl<S: BaseFloat> SquareMatrix for Matrix2<S> {
}
impl<S: BaseFloat> Matrix for Matrix3<S> {
type Row = Vector3<S>;
type Column = Vector3<S>;
type Row = Vector3<S>;
type Transpose = Matrix3<S>;
#[inline]
@ -776,8 +776,8 @@ impl<S: BaseFloat> SquareMatrix for Matrix3<S> {
}
impl<S: BaseFloat> Matrix for Matrix4<S> {
type Row = Vector4<S>;
type Column = Vector4<S>;
type Row = Vector4<S>;
type Transpose = Matrix4<S>;
#[inline]
@ -1092,13 +1092,13 @@ impl<S: BaseFloat> Transform<Point2<S>> for Matrix3<S> {
Matrix3::from(Matrix2::look_at(dir, up))
}
fn look_at_rh(eye: Point2<S>, center: Point2<S>, up: Vector2<S>) -> Matrix3<S> {
let dir = eye - center;
fn look_at_lh(eye: Point2<S>, center: Point2<S>, up: Vector2<S>) -> Matrix3<S> {
let dir = center - eye;
Matrix3::from(Matrix2::look_at(dir, up))
}
fn look_at_lh(eye: Point2<S>, center: Point2<S>, up: Vector2<S>) -> Matrix3<S> {
let dir = center - eye;
fn look_at_rh(eye: Point2<S>, center: Point2<S>, up: Vector2<S>) -> Matrix3<S> {
let dir = eye - center;
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)
}
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> {
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> {
let dir = center - eye;
Matrix3::look_to_rh(dir, up)
}
fn transform_vector(&self, vec: Vector3<S>) -> Vector3<S> {
self * vec
}
@ -1157,14 +1157,14 @@ impl<S: BaseFloat> Transform<Point3<S>> for Matrix4<S> {
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> {
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> {
(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")]
mint_conversions!(Matrix4 { x, y, z, w }, ColumnMatrix4);
#[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> {
impl<S: BaseFloat> From<Matrix2<S>> for Matrix3<S> {
/// Clone the elements of a 2-dimensional matrix into the top-left corner
/// of a 3-dimensional identity matrix.
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
/// of a 4-dimensional identity matrix.
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
/// of a 4-dimensional identity matrix.
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
where
Standard: Distribution<Vector2<S>>,
S: BaseNum,
S: BaseFloat,
{
#[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix2<S> {
@ -1703,7 +1693,7 @@ where
impl<S> Distribution<Matrix3<S>> for Standard
where
Standard: Distribution<Vector3<S>>,
S: BaseNum,
S: BaseFloat,
{
#[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix3<S> {
@ -1719,7 +1709,7 @@ where
impl<S> Distribution<Matrix4<S>> for Standard
where
Standard: Distribution<Vector4<S>>,
S: BaseNum,
S: BaseFloat,
{
#[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix4<S> {

View file

@ -18,7 +18,7 @@ use approx;
use std::fmt;
use std::ops::*;
use num_traits::{Float, Num};
use num_traits::{Float, Num, NumCast};
/// Base numeric types with partial ordering
pub trait BaseNum:
@ -26,6 +26,7 @@ pub trait BaseNum:
+ Clone
+ fmt::Debug
+ Num
+ NumCast
+ PartialOrd
+ AddAssign
+ SubAssign
@ -40,6 +41,7 @@ impl<T> BaseNum for T where
+ Clone
+ fmt::Debug
+ Num
+ NumCast
+ PartialOrd
+ AddAssign
+ SubAssign

View file

@ -83,7 +83,7 @@ macro_rules! impl_point {
/// Construct a new point, using the provided values.
#[inline]
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
@ -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;
#[inline]
@ -368,13 +368,6 @@ impl_mint_conversions!(Point2 { x, y }, Point2);
#[cfg(feature = "mint")]
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> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Point1 ")?;
@ -412,7 +405,7 @@ mod tests {
#[test]
fn test_index_mut() {
let mut p = POINT2;
p[0] = 0;
*&mut p[0] = 0;
assert_eq!(p, [0, 2].into());
}
@ -525,7 +518,7 @@ mod tests {
#[test]
fn test_index_mut() {
let mut p = POINT3;
p[1] = 0;
*&mut p[1] = 0;
assert_eq!(p, [1, 0, 3].into());
}

View file

@ -29,7 +29,7 @@ use angle::Rad;
use approx;
use euler::Euler;
use matrix::{Matrix3, Matrix4};
use num::{BaseFloat, BaseNum};
use num::BaseFloat;
use point::Point3;
use quaternion;
use rotation::{Basis3, Rotation, Rotation3};
@ -72,8 +72,10 @@ impl<S: BaseFloat> Quaternion<S> {
///
/// 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)
/// - [Ogre implementation for normalized vectors](https://bitbucket.org/sinbad/ogre/src/9db75e3ba05c/OgreMain/include/OgreVector3.h?fileviewer=file-view-default#cl-651)
/// - [Related StackOverflow question]
/// (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(
src: 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
/// to be small.
///
/// - [Understanding Slerp, Then Not Using It](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)
/// - [Understanding Slerp, Then Not Using It]
/// (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> {
let mut dot = self.dot(other);
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> {
#[inline]
default_fn!( dot(self, other: Quaternion<S>) -> S {
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.
fn from(quat: Quaternion<S>) -> Matrix3<S> {
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.
fn from(quat: Quaternion<S>) -> Matrix4<S> {
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]
fn from(v: Quaternion<S>) -> Self {
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]
fn as_ref(&self) -> &[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]
fn as_mut(&mut self) -> &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]
fn from(v: [S; 4]) -> Quaternion<S> {
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]
fn from(v: &'a [S; 4]) -> &'a 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]
fn from(v: &'a mut [S; 4]) -> &'a mut 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]
fn from(v: Quaternion<S>) -> Self {
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]
fn as_ref(&self) -> &(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]
fn as_mut(&mut self) -> &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]
fn from(v: (S, S, S, S)) -> Quaternion<S> {
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]
fn from(v: &'a (S, S, S, S)) -> &'a 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]
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>) }
@ -625,7 +630,7 @@ impl<'a, S: BaseNum> From<&'a mut (S, S, S, S)> for &'a mut Quaternion<S> {
macro_rules! index_operators {
($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;
#[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]
fn index_mut<'a>(&'a mut self, i: $I) -> &'a mut $Output {
let v: &mut [$S; 4] = self.as_mut();
@ -656,7 +661,7 @@ impl<S> Distribution<Quaternion<S>> for Standard
where
Standard: Distribution<S>,
Standard: Distribution<Vector3<S>>,
S: BaseNum,
S: BaseFloat,
{
#[inline]
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)]
mod tests {
use quaternion::*;

View file

@ -26,7 +26,7 @@ impl From<Simdf32x4> for Quaternion<f32> {
#[inline]
fn from(f: Simdf32x4) -> Self {
unsafe {
let mut ret: Self = mem::MaybeUninit();
let mut ret: Self = mem::uninitialized();
{
let ret_mut: &mut [f32; 4] = ret.as_mut();
f.store(ret_mut.as_mut(), 0 as usize);

View file

@ -23,7 +23,7 @@ use angle::Rad;
use approx;
use euler::Euler;
use matrix::{Matrix2, Matrix3};
use num::{BaseFloat, BaseNum};
use num::BaseFloat;
use point::{Point2, Point3};
use quaternion::Quaternion;
use vector::{Vector2, Vector3};
@ -36,7 +36,7 @@ where
Self: approx::AbsDiffEq<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::Space as EuclideanSpace>::Scalar: BaseNum,
<Self::Space as EuclideanSpace>::Scalar: BaseFloat,
Self: iter::Product<Self>,
{
type Space: EuclideanSpace;
@ -149,7 +149,7 @@ pub trait Rotation3:
/// let unit_y = rot.rotate_vector(unit_x);
///
/// // 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
///
/// // This is exactly equivalent to using the raw matrix itself:
@ -319,7 +319,7 @@ impl<S: BaseFloat> Basis3<S> {
#[inline]
pub fn from_quaternion(quaternion: &Quaternion<S>) -> Basis3<S> {
Basis3 {
mat: (*quaternion).into(),
mat: quaternion.clone().into(),
}
}
}

View file

@ -25,7 +25,7 @@ use approx;
use angle::Rad;
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`
pub trait Array
@ -388,7 +388,7 @@ where
/// ```
#[inline]
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.
@ -406,10 +406,7 @@ where
/// let centroid = Point2::centroid(&triangle);
/// ```
#[inline]
fn centroid(points: &[Self]) -> Self
where
Self::Scalar: NumCast,
{
fn centroid(points: &[Self]) -> Self {
let total_displacement = points
.iter()
.fold(Self::Diff::zero(), |acc, p| acc + p.to_vec());
@ -444,7 +441,7 @@ where
/// see `SquareMatrix`.
pub trait Matrix: VectorSpace
where
Self::Scalar: Num,
Self::Scalar: Float,
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
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.
pub trait SquareMatrix
where
Self::Scalar: Num,
Self::Scalar: Float,
Self: One,
Self: iter::Product<Self>,
@ -583,10 +580,10 @@ where
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
/// 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.
///
pub trait Angle
@ -612,7 +609,7 @@ where
{
type Unitless: BaseFloat;
/// Return the angle, normalized to the range `[0, full_turn]`.
/// Return the angle, normalized to the range `[0, full_turn)`.
#[inline]
fn normalize(self) -> Self {
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]
fn normalize_signed(self) -> Self {
let rem = self.normalize();

View file

@ -123,8 +123,8 @@ where
}
#[inline]
fn look_at_rh(eye: P, center: P, up: P::Diff) -> Decomposed<P::Diff, R> {
let rot = R::look_at(eye - center, up);
fn look_at_lh(eye: P, center: P, up: P::Diff) -> Decomposed<P::Diff, R> {
let rot = R::look_at(center - eye, up);
let disp = rot.rotate_vector(P::origin() - eye);
Decomposed {
scale: P::Scalar::one(),
@ -134,8 +134,8 @@ where
}
#[inline]
fn look_at_lh(eye: P, center: P, up: P::Diff) -> Decomposed<P::Diff, R> {
let rot = R::look_at(center - eye, up);
fn look_at_rh(eye: P, center: P, up: P::Diff) -> Decomposed<P::Diff, R> {
let rot = R::look_at(eye - center, up);
let disp = rot.rotate_vector(P::origin() - eye);
Decomposed {
scale: P::Scalar::one(),
@ -366,7 +366,7 @@ mod serde_de {
where
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))
}
}
@ -422,7 +422,11 @@ mod serde_de {
None => return Err(serde::de::Error::missing_field("disp")),
};
Ok(Decomposed { scale, rot, disp })
Ok(Decomposed {
scale: scale,
rot: rot,
disp: disp,
})
}
}
}

View file

@ -96,7 +96,7 @@ macro_rules! impl_vector {
/// Construct a new vector, using the provided values.
#[inline]
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
@ -209,6 +209,7 @@ macro_rules! impl_vector {
impl<S: Neg<Output = S>> Neg for $VectorN<S> {
type Output = $VectorN<S>;
#[inline]
default_fn!( neg(self) -> $VectorN<S> { $VectorN::new($(-self.$field),+) } );
}
@ -253,7 +254,7 @@ macro_rules! impl_vector {
#[cfg(feature = "rand")]
impl<S> Distribution<$VectorN<S>> for Standard
where Standard: Distribution<S>,
S: BaseNum {
S: BaseFloat {
#[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $VectorN<S> {
$VectorN { $($field: rng.gen()),+ }
@ -308,30 +309,30 @@ macro_rules! impl_vector {
});
impl<S: BaseNum> ElementWise for $VectorN<S> {
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),+) } );
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!( 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),+) } );
#[inline] 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),+) } );
#[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);+ } );
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);+ } );
default_fn!( div_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);+ } );
#[inline] 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);+ } );
#[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);+ }
}
impl<S: BaseNum> ElementWise<S> for $VectorN<S> {
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),+) } );
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!( 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),+) } );
#[inline] 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),+) } );
#[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);+ } );
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);+ } );
default_fn!( div_assign_element_wise(&mut self, rhs: S) { $(self.$field /= rhs);+ } );
#[inline] 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);+ } );
#[inline] 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);+ } );
#[inline] fn rem_assign_element_wise(&mut self, rhs: S) { $(self.$field %= rhs);+ }
}
@ -519,7 +520,7 @@ impl<S: BaseNum> Vector4<S> {
#[inline]
pub fn dot<V: InnerSpace>(a: V, b: V) -> V::Scalar
where
V::Scalar: BaseNum,
V::Scalar: BaseFloat,
{
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")]
impl_mint_conversions!(Vector2 { x, y }, Vector2);
#[cfg(feature = "mint")]
@ -631,7 +620,7 @@ mod tests {
#[test]
fn test_index_mut() {
let mut v = VECTOR2;
v[0] = 0;
*&mut v[0] = 0;
assert_eq!(v, [0, 2].into());
}
@ -752,7 +741,7 @@ mod tests {
#[test]
fn test_index_mut() {
let mut v = VECTOR3;
v[1] = 0;
*&mut v[1] = 0;
assert_eq!(v, [1, 0, 3].into());
}
@ -879,7 +868,7 @@ mod tests {
#[test]
fn test_index_mut() {
let mut v = VECTOR4;
v[2] = 0;
*&mut v[2] = 0;
assert_eq!(v, [1, 2, 0, 4].into());
}

View file

@ -28,7 +28,7 @@ impl From<Simdf32x4> for Vector4<f32> {
#[inline]
fn from(f: Simdf32x4) -> Self {
unsafe {
let mut ret: Self = mem::MaybeUninit();
let mut ret: Self = mem::uninitialized();
{
let ret_mut: &mut [f32; 4] = ret.as_mut();
f.store(ret_mut.as_mut(), 0 as usize);
@ -244,7 +244,7 @@ impl From<Simdi32x4> for Vector4<i32> {
#[inline]
fn from(f: Simdi32x4) -> Self {
unsafe {
let mut ret: Self = mem::MaybeUninit();
let mut ret: Self = mem::uninitialized();
{
let ret_mut: &mut [i32; 4] = ret.as_mut();
f.store(ret_mut.as_mut(), 0 as usize);
@ -324,7 +324,7 @@ impl From<Simdu32x4> for Vector4<u32> {
#[inline]
fn from(f: Simdu32x4) -> Self {
unsafe {
let mut ret: Self = mem::MaybeUninit();
let mut ret: Self = mem::uninitialized();
{
let ret_mut: &mut [u32; 4] = ret.as_mut();
f.store(ret_mut.as_mut(), 0 as usize);

View file

@ -220,7 +220,7 @@ mod from {
use cgmath::*;
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_matrix3 = Matrix3::from(quaternion);
assert_ulps_eq!(matrix3, quaternion_matrix3);
@ -265,7 +265,7 @@ mod arc {
#[test]
fn test_same() {
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));
}

View file

@ -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.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.
#[allow(deprecated)]
let t: Decomposed<Vector3<f64>, Quaternion<f64>> = Transform::look_at(eye, center, up);