Compare commits
10 commits
575c458705
...
d5e765db61
Author | SHA1 | Date | |
---|---|---|---|
|
d5e765db61 | ||
|
33fb2fd24f | ||
|
2e76e82cc0 | ||
|
11a5346291 | ||
|
78c082e944 | ||
|
d4d19b9122 | ||
|
af127633cc | ||
|
41fb64cea0 | ||
|
e57b543449 | ||
|
df218547d1 |
20 changed files with 180 additions and 140 deletions
|
@ -51,7 +51,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- Add `Array::len`
|
||||
- Re-export `Bounded` and implement for vectors, points, and angles
|
||||
- Add vector subtraction to `EuclideanSpace`
|
||||
- Add swizzle functions behinde that `"swizzle"` feature
|
||||
- Add swizzle functions behind that `"swizzle"` feature
|
||||
- Add `Matrix4::look_at_dir`
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -22,13 +22,14 @@ swizzle = []
|
|||
|
||||
[dependencies]
|
||||
approx = "0.5"
|
||||
mint = { version = "0.5", optional = true }
|
||||
mint = { version = "0.5.8", 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"
|
||||
|
|
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.
|
||||
/// NOTE: This function assumes that variables are in ASCII format
|
||||
#[cfg(feature = "swizzle")]
|
||||
fn gen_swizzle_nth<'a>(variables: &'a str, mut i: usize, upto: usize) -> Option<(String, String)> {
|
||||
fn gen_swizzle_nth(variables: &str, mut i: usize, upto: usize) -> Option<(String, String)> {
|
||||
debug_assert!(i > 0); // zeroth permutation is empty
|
||||
let mut swizzle_impl = String::new();
|
||||
let mut swizzle = String::new();
|
||||
|
@ -22,7 +22,7 @@ fn gen_swizzle_nth<'a>(variables: &'a str, mut i: usize, upto: usize) -> Option<
|
|||
let c = variables.as_bytes()[i % n - 1] as char;
|
||||
swizzle.push(c);
|
||||
swizzle_impl.push_str(&format!("self.{}, ", c));
|
||||
i = i / n;
|
||||
i /= n;
|
||||
}
|
||||
Some((swizzle, swizzle_impl))
|
||||
}
|
||||
|
|
24
src/angle.rs
24
src/angle.rs
|
@ -30,7 +30,7 @@ use rand::{
|
|||
use structure::*;
|
||||
|
||||
use approx;
|
||||
use num::BaseFloat;
|
||||
use num::{BaseFloat, BaseNum};
|
||||
|
||||
/// An angle, in radians.
|
||||
///
|
||||
|
@ -138,38 +138,38 @@ macro_rules! impl_angle {
|
|||
}
|
||||
}
|
||||
|
||||
impl_operator!(<S: BaseFloat> Add<$Angle<S> > for $Angle<S> {
|
||||
impl_operator!(<S: BaseNum> Add<$Angle<S> > for $Angle<S> {
|
||||
fn add(lhs, rhs) -> $Angle<S> { $Angle(lhs.0 + rhs.0) }
|
||||
});
|
||||
impl_operator!(<S: BaseFloat> Sub<$Angle<S> > for $Angle<S> {
|
||||
impl_operator!(<S: BaseNum> Sub<$Angle<S> > for $Angle<S> {
|
||||
fn sub(lhs, rhs) -> $Angle<S> { $Angle(lhs.0 - rhs.0) }
|
||||
});
|
||||
impl_operator!(<S: BaseFloat> Div<$Angle<S> > for $Angle<S> {
|
||||
impl_operator!(<S: BaseNum> Div<$Angle<S> > for $Angle<S> {
|
||||
fn div(lhs, rhs) -> S { lhs.0 / rhs.0 }
|
||||
});
|
||||
impl_operator!(<S: BaseFloat> Rem<$Angle<S> > for $Angle<S> {
|
||||
impl_operator!(<S: BaseNum> Rem<$Angle<S> > for $Angle<S> {
|
||||
fn rem(lhs, rhs) -> $Angle<S> { $Angle(lhs.0 % rhs.0) }
|
||||
});
|
||||
impl_assignment_operator!(<S: BaseFloat> AddAssign<$Angle<S> > for $Angle<S> {
|
||||
impl_assignment_operator!(<S: BaseNum> AddAssign<$Angle<S> > for $Angle<S> {
|
||||
fn add_assign(&mut self, other) { self.0 += other.0; }
|
||||
});
|
||||
impl_assignment_operator!(<S: BaseFloat> SubAssign<$Angle<S> > for $Angle<S> {
|
||||
impl_assignment_operator!(<S: BaseNum> SubAssign<$Angle<S> > for $Angle<S> {
|
||||
fn sub_assign(&mut self, other) { self.0 -= other.0; }
|
||||
});
|
||||
impl_assignment_operator!(<S: BaseFloat> RemAssign<$Angle<S> > for $Angle<S> {
|
||||
impl_assignment_operator!(<S: BaseNum> RemAssign<$Angle<S> > for $Angle<S> {
|
||||
fn rem_assign(&mut self, other) { self.0 %= other.0; }
|
||||
});
|
||||
|
||||
impl_operator!(<S: BaseFloat> Mul<S> for $Angle<S> {
|
||||
impl_operator!(<S: BaseNum> Mul<S> for $Angle<S> {
|
||||
fn mul(lhs, scalar) -> $Angle<S> { $Angle(lhs.0 * scalar) }
|
||||
});
|
||||
impl_operator!(<S: BaseFloat> Div<S> for $Angle<S> {
|
||||
impl_operator!(<S: BaseNum> Div<S> for $Angle<S> {
|
||||
fn div(lhs, scalar) -> $Angle<S> { $Angle(lhs.0 / scalar) }
|
||||
});
|
||||
impl_assignment_operator!(<S: BaseFloat> MulAssign<S> for $Angle<S> {
|
||||
impl_assignment_operator!(<S: BaseNum> MulAssign<S> for $Angle<S> {
|
||||
fn mul_assign(&mut self, scalar) { self.0 *= scalar; }
|
||||
});
|
||||
impl_assignment_operator!(<S: BaseFloat> DivAssign<S> for $Angle<S> {
|
||||
impl_assignment_operator!(<S: BaseNum> DivAssign<S> for $Angle<S> {
|
||||
fn div_assign(&mut self, scalar) { self.0 /= scalar; }
|
||||
});
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
//! let uniforms = uniform! {
|
||||
//! point: Into::<[_; 2]>::into(point),
|
||||
//! matrix: Into::<[[_; 4]; 4]>::into(matrix),
|
||||
//! // Yuck!! (ノಥ益ಥ)ノ ┻━┻
|
||||
//! // Yuck!! (ノಥ益ಥ)ノ ┻━┻)
|
||||
//! };
|
||||
//! # }
|
||||
//! ` ` `
|
||||
|
|
|
@ -224,3 +224,6 @@ impl<S: Clone, A: Angle + Into<S>> From<Euler<A>> for MintEuler<S> {
|
|||
MintEuler::from([v.x.into(), v.y.into(), v.z.into()])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bytemuck")]
|
||||
impl_bytemuck_cast!(Euler);
|
||||
|
|
|
@ -55,6 +55,9 @@
|
|||
#[macro_use]
|
||||
extern crate approx;
|
||||
|
||||
#[cfg(feature = "bytemuck")]
|
||||
extern crate bytemuck;
|
||||
|
||||
#[cfg(feature = "mint")]
|
||||
pub extern crate mint;
|
||||
|
||||
|
|
|
@ -24,7 +24,10 @@ macro_rules! default_fn {
|
|||
|
||||
#[cfg(not(feature = "simd"))]
|
||||
macro_rules! default_fn {
|
||||
{ $($tt:tt)* } => { fn $( $tt )* };
|
||||
{ $($tt:tt)* } => {
|
||||
#[inline]
|
||||
fn $( $tt )*
|
||||
};
|
||||
}
|
||||
|
||||
/// Generates a binary operator implementation for the permutations of by-ref and by-val
|
||||
|
@ -35,7 +38,6 @@ macro_rules! impl_operator {
|
|||
}) => {
|
||||
impl<$S: $Constraint> $Op for $Lhs {
|
||||
type Output = $Output;
|
||||
#[inline]
|
||||
default_fn!($op(self) -> $Output {
|
||||
let $x = self; $body
|
||||
});
|
||||
|
@ -43,7 +45,6 @@ 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
|
||||
});
|
||||
|
@ -55,7 +56,6 @@ 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,7 +63,6 @@ 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
|
||||
});
|
||||
|
@ -75,7 +74,6 @@ 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
|
||||
});
|
||||
|
@ -83,7 +81,6 @@ 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
|
||||
});
|
||||
|
@ -91,7 +88,6 @@ 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
|
||||
});
|
||||
|
@ -99,7 +95,6 @@ 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
|
||||
});
|
||||
|
@ -111,7 +106,6 @@ 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
|
||||
});
|
||||
|
@ -119,7 +113,6 @@ 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
|
||||
});
|
||||
|
@ -132,7 +125,6 @@ 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 );
|
||||
}
|
||||
};
|
||||
|
@ -218,7 +210,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: $field),+ } }
|
||||
match v { ($($field),+,) => $ArrayN { $($field),+ } }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -373,7 +365,20 @@ 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"));
|
||||
|
|
|
@ -30,7 +30,7 @@ use structure::*;
|
|||
use angle::Rad;
|
||||
use approx;
|
||||
use euler::Euler;
|
||||
use num::BaseFloat;
|
||||
use num::{BaseFloat, BaseNum};
|
||||
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 Column = Vector2<S>;
|
||||
type Row = Vector2<S>;
|
||||
type Column = 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 Column = Vector3<S>;
|
||||
type Row = Vector3<S>;
|
||||
type Column = 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 Column = Vector4<S>;
|
||||
type Row = Vector4<S>;
|
||||
type Column = 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_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))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
|
@ -1125,16 +1125,16 @@ impl<S: BaseFloat> Transform<Point3<S>> for Matrix3<S> {
|
|||
Matrix3::look_to_lh(dir, up)
|
||||
}
|
||||
|
||||
fn look_at_lh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix3<S> {
|
||||
let dir = center - eye;
|
||||
Matrix3::look_to_lh(dir, up)
|
||||
}
|
||||
|
||||
fn look_at_rh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix3<S> {
|
||||
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 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_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 look_at_lh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix4<S> {
|
||||
Matrix4::look_at_lh(eye, center, up)
|
||||
}
|
||||
|
||||
fn transform_vector(&self, vec: Vector3<S>) -> Vector3<S> {
|
||||
(self * vec.extend(S::zero())).truncate()
|
||||
}
|
||||
|
@ -1559,6 +1559,9 @@ macro_rules! mint_conversions {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Clone> mint::IntoMint for $MatrixN<S> {
|
||||
type MintType = mint::$MintN<S>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1569,7 +1572,14 @@ mint_conversions!(Matrix3 { x, y, z }, ColumnMatrix3);
|
|||
#[cfg(feature = "mint")]
|
||||
mint_conversions!(Matrix4 { x, y, z, w }, ColumnMatrix4);
|
||||
|
||||
impl<S: BaseFloat> From<Matrix2<S>> for Matrix3<S> {
|
||||
#[cfg(feature = "bytemuck")]
|
||||
impl_bytemuck_cast!(Matrix2);
|
||||
#[cfg(feature = "bytemuck")]
|
||||
impl_bytemuck_cast!(Matrix3);
|
||||
#[cfg(feature = "bytemuck")]
|
||||
impl_bytemuck_cast!(Matrix4);
|
||||
|
||||
impl<S: BaseNum> From<Matrix2<S>> for Matrix3<S> {
|
||||
/// Clone the elements of a 2-dimensional matrix into the top-left corner
|
||||
/// of a 3-dimensional identity matrix.
|
||||
fn from(m: Matrix2<S>) -> Matrix3<S> {
|
||||
|
@ -1582,7 +1592,7 @@ impl<S: BaseFloat> From<Matrix2<S>> for Matrix3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> From<Matrix2<S>> for Matrix4<S> {
|
||||
impl<S: BaseNum> From<Matrix2<S>> for Matrix4<S> {
|
||||
/// Clone the elements of a 2-dimensional matrix into the top-left corner
|
||||
/// of a 4-dimensional identity matrix.
|
||||
fn from(m: Matrix2<S>) -> Matrix4<S> {
|
||||
|
@ -1596,7 +1606,7 @@ impl<S: BaseFloat> From<Matrix2<S>> for Matrix4<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> From<Matrix3<S>> for Matrix4<S> {
|
||||
impl<S: BaseNum> From<Matrix3<S>> for Matrix4<S> {
|
||||
/// Clone the elements of a 3-dimensional matrix into the top-left corner
|
||||
/// of a 4-dimensional identity matrix.
|
||||
fn from(m: Matrix3<S>) -> Matrix4<S> {
|
||||
|
@ -1678,7 +1688,7 @@ impl<S: fmt::Debug> fmt::Debug for Matrix4<S> {
|
|||
impl<S> Distribution<Matrix2<S>> for Standard
|
||||
where
|
||||
Standard: Distribution<Vector2<S>>,
|
||||
S: BaseFloat,
|
||||
S: BaseNum,
|
||||
{
|
||||
#[inline]
|
||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix2<S> {
|
||||
|
@ -1693,7 +1703,7 @@ where
|
|||
impl<S> Distribution<Matrix3<S>> for Standard
|
||||
where
|
||||
Standard: Distribution<Vector3<S>>,
|
||||
S: BaseFloat,
|
||||
S: BaseNum,
|
||||
{
|
||||
#[inline]
|
||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix3<S> {
|
||||
|
@ -1709,7 +1719,7 @@ where
|
|||
impl<S> Distribution<Matrix4<S>> for Standard
|
||||
where
|
||||
Standard: Distribution<Vector4<S>>,
|
||||
S: BaseFloat,
|
||||
S: BaseNum,
|
||||
{
|
||||
#[inline]
|
||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix4<S> {
|
||||
|
|
|
@ -18,7 +18,7 @@ use approx;
|
|||
use std::fmt;
|
||||
use std::ops::*;
|
||||
|
||||
use num_traits::{Float, Num, NumCast};
|
||||
use num_traits::{Float, Num};
|
||||
|
||||
/// Base numeric types with partial ordering
|
||||
pub trait BaseNum:
|
||||
|
@ -26,7 +26,6 @@ pub trait BaseNum:
|
|||
+ Clone
|
||||
+ fmt::Debug
|
||||
+ Num
|
||||
+ NumCast
|
||||
+ PartialOrd
|
||||
+ AddAssign
|
||||
+ SubAssign
|
||||
|
@ -41,7 +40,6 @@ impl<T> BaseNum for T where
|
|||
+ Clone
|
||||
+ fmt::Debug
|
||||
+ Num
|
||||
+ NumCast
|
||||
+ PartialOrd
|
||||
+ AddAssign
|
||||
+ 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.
|
||||
#[inline]
|
||||
pub const fn new($($field: S),+) -> $PointN<S> {
|
||||
$PointN { $($field: $field),+ }
|
||||
$PointN { $($field),+ }
|
||||
}
|
||||
|
||||
/// Perform the given operation on each field in the point, returning a new point
|
||||
|
@ -154,7 +154,7 @@ macro_rules! impl_point {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> MetricSpace for $PointN<S> {
|
||||
impl<S: BaseNum> MetricSpace for $PointN<S> {
|
||||
type Metric = S;
|
||||
|
||||
#[inline]
|
||||
|
@ -368,6 +368,13 @@ 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 ")?;
|
||||
|
@ -405,7 +412,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_index_mut() {
|
||||
let mut p = POINT2;
|
||||
*&mut p[0] = 0;
|
||||
p[0] = 0;
|
||||
assert_eq!(p, [0, 2].into());
|
||||
}
|
||||
|
||||
|
@ -518,7 +525,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_index_mut() {
|
||||
let mut p = POINT3;
|
||||
*&mut p[1] = 0;
|
||||
p[1] = 0;
|
||||
assert_eq!(p, [1, 0, 3].into());
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ use angle::Rad;
|
|||
use approx;
|
||||
use euler::Euler;
|
||||
use matrix::{Matrix3, Matrix4};
|
||||
use num::BaseFloat;
|
||||
use num::{BaseFloat, BaseNum};
|
||||
use point::Point3;
|
||||
use quaternion;
|
||||
use rotation::{Basis3, Rotation, Rotation3};
|
||||
|
@ -72,10 +72,8 @@ 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>,
|
||||
|
@ -132,10 +130,8 @@ 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]
|
||||
/// (http://www.arcsynthesis.org/gltut/Positioning/Tut08%20Interpolation.html)
|
||||
/// - [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)
|
||||
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();
|
||||
|
@ -242,7 +238,6 @@ 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)
|
||||
} );
|
||||
|
@ -414,7 +409,7 @@ impl<S: BaseFloat> approx::UlpsEq for Quaternion<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> From<Quaternion<S>> for Matrix3<S> {
|
||||
impl<S: BaseNum> From<Quaternion<S>> for Matrix3<S> {
|
||||
/// Convert the quaternion to a 3 x 3 rotation matrix.
|
||||
fn from(quat: Quaternion<S>) -> Matrix3<S> {
|
||||
let x2 = quat.v.x + quat.v.x;
|
||||
|
@ -442,7 +437,7 @@ impl<S: BaseFloat> From<Quaternion<S>> for Matrix3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> From<Quaternion<S>> for Matrix4<S> {
|
||||
impl<S: BaseNum> From<Quaternion<S>> for Matrix4<S> {
|
||||
/// Convert the quaternion to a 4 x 4 rotation matrix.
|
||||
fn from(quat: Quaternion<S>) -> Matrix4<S> {
|
||||
let x2 = quat.v.x + quat.v.x;
|
||||
|
@ -538,7 +533,7 @@ impl<S: BaseFloat> Rotation3 for Quaternion<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> From<Quaternion<S>> for [S; 4] {
|
||||
impl<S: BaseNum> From<Quaternion<S>> for [S; 4] {
|
||||
#[inline]
|
||||
fn from(v: Quaternion<S>) -> Self {
|
||||
let (xi, yj, zk, w) = v.into();
|
||||
|
@ -546,42 +541,42 @@ impl<S: BaseFloat> From<Quaternion<S>> for [S; 4] {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> AsRef<[S; 4]> for Quaternion<S> {
|
||||
impl<S: BaseNum> AsRef<[S; 4]> for Quaternion<S> {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &[S; 4] {
|
||||
unsafe { &*(self as *const quaternion::Quaternion<S> as *const [S; 4]) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> AsMut<[S; 4]> for Quaternion<S> {
|
||||
impl<S: BaseNum> AsMut<[S; 4]> for Quaternion<S> {
|
||||
#[inline]
|
||||
fn as_mut(&mut self) -> &mut [S; 4] {
|
||||
unsafe { &mut *(self as *mut quaternion::Quaternion<S> as *mut [S; 4]) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> From<[S; 4]> for Quaternion<S> {
|
||||
impl<S: BaseNum> From<[S; 4]> for Quaternion<S> {
|
||||
#[inline]
|
||||
fn from(v: [S; 4]) -> Quaternion<S> {
|
||||
Quaternion::new(v[3], v[0], v[1], v[2])
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S: BaseFloat> From<&'a [S; 4]> for &'a Quaternion<S> {
|
||||
impl<'a, S: BaseNum> From<&'a [S; 4]> for &'a Quaternion<S> {
|
||||
#[inline]
|
||||
fn from(v: &'a [S; 4]) -> &'a Quaternion<S> {
|
||||
unsafe { &*(v as *const [S; 4] as *const quaternion::Quaternion<S>) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S: BaseFloat> From<&'a mut [S; 4]> for &'a mut Quaternion<S> {
|
||||
impl<'a, S: BaseNum> From<&'a mut [S; 4]> for &'a mut Quaternion<S> {
|
||||
#[inline]
|
||||
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: BaseFloat> From<Quaternion<S>> for (S, S, S, S) {
|
||||
impl<S: BaseNum> From<Quaternion<S>> for (S, S, S, S) {
|
||||
#[inline]
|
||||
fn from(v: Quaternion<S>) -> Self {
|
||||
let Quaternion {
|
||||
|
@ -592,21 +587,21 @@ impl<S: BaseFloat> From<Quaternion<S>> for (S, S, S, S) {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> AsRef<(S, S, S, S)> for Quaternion<S> {
|
||||
impl<S: BaseNum> AsRef<(S, S, S, S)> for Quaternion<S> {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &(S, S, S, S) {
|
||||
unsafe { &*(self as *const quaternion::Quaternion<S> as *const (S, S, S, S)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> AsMut<(S, S, S, S)> for Quaternion<S> {
|
||||
impl<S: BaseNum> AsMut<(S, S, S, S)> for Quaternion<S> {
|
||||
#[inline]
|
||||
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: BaseFloat> From<(S, S, S, S)> for Quaternion<S> {
|
||||
impl<S: BaseNum> From<(S, S, S, S)> for Quaternion<S> {
|
||||
#[inline]
|
||||
fn from(v: (S, S, S, S)) -> Quaternion<S> {
|
||||
let (xi, yj, zk, w) = v;
|
||||
|
@ -614,14 +609,14 @@ impl<S: BaseFloat> From<(S, S, S, S)> for Quaternion<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, S: BaseFloat> From<&'a (S, S, S, S)> for &'a Quaternion<S> {
|
||||
impl<'a, S: BaseNum> From<&'a (S, S, S, S)> for &'a Quaternion<S> {
|
||||
#[inline]
|
||||
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: BaseFloat> From<&'a mut (S, S, S, S)> for &'a mut Quaternion<S> {
|
||||
impl<'a, S: BaseNum> From<&'a mut (S, S, S, S)> for &'a mut Quaternion<S> {
|
||||
#[inline]
|
||||
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>) }
|
||||
|
@ -630,7 +625,7 @@ impl<'a, S: BaseFloat> From<&'a mut (S, S, S, S)> for &'a mut Quaternion<S> {
|
|||
|
||||
macro_rules! index_operators {
|
||||
($S:ident, $Output:ty, $I:ty) => {
|
||||
impl<$S: BaseFloat> Index<$I> for Quaternion<$S> {
|
||||
impl<$S: BaseNum> Index<$I> for Quaternion<$S> {
|
||||
type Output = $Output;
|
||||
|
||||
#[inline]
|
||||
|
@ -640,7 +635,7 @@ macro_rules! index_operators {
|
|||
}
|
||||
}
|
||||
|
||||
impl<$S: BaseFloat> IndexMut<$I> for Quaternion<$S> {
|
||||
impl<$S: BaseNum> IndexMut<$I> for Quaternion<$S> {
|
||||
#[inline]
|
||||
fn index_mut<'a>(&'a mut self, i: $I) -> &'a mut $Output {
|
||||
let v: &mut [$S; 4] = self.as_mut();
|
||||
|
@ -661,7 +656,7 @@ impl<S> Distribution<Quaternion<S>> for Standard
|
|||
where
|
||||
Standard: Distribution<S>,
|
||||
Standard: Distribution<Vector3<S>>,
|
||||
S: BaseFloat,
|
||||
S: BaseNum,
|
||||
{
|
||||
#[inline]
|
||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Quaternion<S> {
|
||||
|
@ -689,6 +684,14 @@ impl<S: Clone> From<Quaternion<S>> for mint::Quaternion<S> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "mint")]
|
||||
impl<S: Clone> mint::IntoMint for Quaternion<S> {
|
||||
type MintType = mint::Quaternion<S>;
|
||||
}
|
||||
|
||||
#[cfg(feature = "bytemuck")]
|
||||
impl_bytemuck_cast!(Quaternion);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use quaternion::*;
|
||||
|
|
|
@ -26,7 +26,7 @@ impl From<Simdf32x4> for Quaternion<f32> {
|
|||
#[inline]
|
||||
fn from(f: Simdf32x4) -> Self {
|
||||
unsafe {
|
||||
let mut ret: Self = mem::uninitialized();
|
||||
let mut ret: Self = mem::MaybeUninit();
|
||||
{
|
||||
let ret_mut: &mut [f32; 4] = ret.as_mut();
|
||||
f.store(ret_mut.as_mut(), 0 as usize);
|
||||
|
|
|
@ -23,7 +23,7 @@ use angle::Rad;
|
|||
use approx;
|
||||
use euler::Euler;
|
||||
use matrix::{Matrix2, Matrix3};
|
||||
use num::BaseFloat;
|
||||
use num::{BaseFloat, BaseNum};
|
||||
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: BaseFloat,
|
||||
<Self::Space as EuclideanSpace>::Scalar: BaseNum,
|
||||
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's assert_ulps_eq!() feature to show that it is close enough.
|
||||
/// // use approx assert_ulps_eq!() feature to show that it is close enough.
|
||||
/// // assert_ulps_eq!(&unit_y, &Vector2::unit_y()); // TODO: Figure out how to use this
|
||||
///
|
||||
/// // 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.clone().into(),
|
||||
mat: (*quaternion).into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ use approx;
|
|||
use angle::Rad;
|
||||
use num::{BaseFloat, BaseNum};
|
||||
|
||||
pub use num_traits::{Bounded, One, Zero};
|
||||
pub use num_traits::{Bounded, Num, NumCast, One, Zero};
|
||||
|
||||
/// An array containing elements of type `Element`
|
||||
pub trait Array
|
||||
|
@ -388,7 +388,7 @@ where
|
|||
/// ```
|
||||
#[inline]
|
||||
fn midpoint(self, other: Self) -> Self {
|
||||
self + (other - self) / cast(2).unwrap()
|
||||
self + (other - self) / (Self::Scalar::one() + Self::Scalar::one())
|
||||
}
|
||||
|
||||
/// Returns the average position of all points in the slice.
|
||||
|
@ -406,7 +406,10 @@ where
|
|||
/// let centroid = Point2::centroid(&triangle);
|
||||
/// ```
|
||||
#[inline]
|
||||
fn centroid(points: &[Self]) -> Self {
|
||||
fn centroid(points: &[Self]) -> Self
|
||||
where
|
||||
Self::Scalar: NumCast,
|
||||
{
|
||||
let total_displacement = points
|
||||
.iter()
|
||||
.fold(Self::Diff::zero(), |acc, p| acc + p.to_vec());
|
||||
|
@ -441,7 +444,7 @@ where
|
|||
/// see `SquareMatrix`.
|
||||
pub trait Matrix: VectorSpace
|
||||
where
|
||||
Self::Scalar: Float,
|
||||
Self::Scalar: Num,
|
||||
|
||||
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
||||
Self: Index<usize, Output = <Self as Matrix>::Column>,
|
||||
|
@ -493,7 +496,7 @@ where
|
|||
/// A column-major major matrix where the rows and column vectors are of the same dimensions.
|
||||
pub trait SquareMatrix
|
||||
where
|
||||
Self::Scalar: Float,
|
||||
Self::Scalar: Num,
|
||||
|
||||
Self: One,
|
||||
Self: iter::Product<Self>,
|
||||
|
@ -580,10 +583,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 occured - for example, adding degrees to
|
||||
/// clear when semantic violations have occurred - for example, adding degrees to
|
||||
/// radians, or adding a number to an angle.
|
||||
///
|
||||
pub trait Angle
|
||||
|
@ -609,7 +612,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();
|
||||
|
@ -620,7 +623,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Return the angle, normalized to the range `[-turn_div_2, turn_div_2)`.
|
||||
/// Return the angle, normalized to the range `[-turn_div_2, turn_div_2]`.
|
||||
#[inline]
|
||||
fn normalize_signed(self) -> Self {
|
||||
let rem = self.normalize();
|
||||
|
|
|
@ -123,8 +123,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(),
|
||||
|
@ -134,8 +134,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(),
|
||||
|
@ -366,7 +366,7 @@ mod serde_de {
|
|||
where
|
||||
D: serde::de::Deserializer<'a>,
|
||||
{
|
||||
const FIELDS: &'static [&'static str] = &["scale", "rot", "disp"];
|
||||
const FIELDS: &[&str] = &["scale", "rot", "disp"];
|
||||
deserializer.deserialize_struct("Decomposed", FIELDS, DecomposedVisitor(PhantomData))
|
||||
}
|
||||
}
|
||||
|
@ -422,11 +422,7 @@ mod serde_de {
|
|||
None => return Err(serde::de::Error::missing_field("disp")),
|
||||
};
|
||||
|
||||
Ok(Decomposed {
|
||||
scale: scale,
|
||||
rot: rot,
|
||||
disp: disp,
|
||||
})
|
||||
Ok(Decomposed { scale, rot, disp })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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: $field),+ }
|
||||
$VectorN { $($field),+ }
|
||||
}
|
||||
|
||||
/// Perform the given operation on each field in the vector, returning a new point
|
||||
|
@ -209,7 +209,6 @@ macro_rules! impl_vector {
|
|||
impl<S: Neg<Output = S>> Neg for $VectorN<S> {
|
||||
type Output = $VectorN<S>;
|
||||
|
||||
#[inline]
|
||||
default_fn!( neg(self) -> $VectorN<S> { $VectorN::new($(-self.$field),+) } );
|
||||
}
|
||||
|
||||
|
@ -254,7 +253,7 @@ macro_rules! impl_vector {
|
|||
#[cfg(feature = "rand")]
|
||||
impl<S> Distribution<$VectorN<S>> for Standard
|
||||
where Standard: Distribution<S>,
|
||||
S: BaseFloat {
|
||||
S: BaseNum {
|
||||
#[inline]
|
||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $VectorN<S> {
|
||||
$VectorN { $($field: rng.gen()),+ }
|
||||
|
@ -309,30 +308,30 @@ macro_rules! impl_vector {
|
|||
});
|
||||
|
||||
impl<S: BaseNum> ElementWise for $VectorN<S> {
|
||||
#[inline] default_fn!( add_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field + rhs.$field),+) } );
|
||||
#[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),+) } );
|
||||
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] fn rem_element_wise(self, rhs: $VectorN<S>) -> $VectorN<S> { $VectorN::new($(self.$field % rhs.$field),+) }
|
||||
|
||||
#[inline] default_fn!( add_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field += rhs.$field);+ } );
|
||||
#[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);+ } );
|
||||
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] fn rem_assign_element_wise(&mut self, rhs: $VectorN<S>) { $(self.$field %= rhs.$field);+ }
|
||||
}
|
||||
|
||||
impl<S: BaseNum> ElementWise<S> for $VectorN<S> {
|
||||
#[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),+) } );
|
||||
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] fn rem_element_wise(self, rhs: S) -> $VectorN<S> { $VectorN::new($(self.$field % rhs),+) }
|
||||
|
||||
#[inline] default_fn!( add_assign_element_wise(&mut self, rhs: S) { $(self.$field += rhs);+ } );
|
||||
#[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);+ } );
|
||||
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] fn rem_assign_element_wise(&mut self, rhs: S) { $(self.$field %= rhs);+ }
|
||||
}
|
||||
|
||||
|
@ -520,7 +519,7 @@ impl<S: BaseNum> Vector4<S> {
|
|||
#[inline]
|
||||
pub fn dot<V: InnerSpace>(a: V, b: V) -> V::Scalar
|
||||
where
|
||||
V::Scalar: BaseFloat,
|
||||
V::Scalar: BaseNum,
|
||||
{
|
||||
V::dot(a, b)
|
||||
}
|
||||
|
@ -597,6 +596,18 @@ impl<S: fmt::Debug> fmt::Debug for Vector4<S> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bytemuck")]
|
||||
impl_bytemuck_cast!(Vector1);
|
||||
|
||||
#[cfg(feature = "bytemuck")]
|
||||
impl_bytemuck_cast!(Vector2);
|
||||
|
||||
#[cfg(feature = "bytemuck")]
|
||||
impl_bytemuck_cast!(Vector3);
|
||||
|
||||
#[cfg(feature = "bytemuck")]
|
||||
impl_bytemuck_cast!(Vector4);
|
||||
|
||||
#[cfg(feature = "mint")]
|
||||
impl_mint_conversions!(Vector2 { x, y }, Vector2);
|
||||
#[cfg(feature = "mint")]
|
||||
|
@ -620,7 +631,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_index_mut() {
|
||||
let mut v = VECTOR2;
|
||||
*&mut v[0] = 0;
|
||||
v[0] = 0;
|
||||
assert_eq!(v, [0, 2].into());
|
||||
}
|
||||
|
||||
|
@ -741,7 +752,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_index_mut() {
|
||||
let mut v = VECTOR3;
|
||||
*&mut v[1] = 0;
|
||||
v[1] = 0;
|
||||
assert_eq!(v, [1, 0, 3].into());
|
||||
}
|
||||
|
||||
|
@ -868,7 +879,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_index_mut() {
|
||||
let mut v = VECTOR4;
|
||||
*&mut v[2] = 0;
|
||||
v[2] = 0;
|
||||
assert_eq!(v, [1, 2, 0, 4].into());
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ impl From<Simdf32x4> for Vector4<f32> {
|
|||
#[inline]
|
||||
fn from(f: Simdf32x4) -> Self {
|
||||
unsafe {
|
||||
let mut ret: Self = mem::uninitialized();
|
||||
let mut ret: Self = mem::MaybeUninit();
|
||||
{
|
||||
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::uninitialized();
|
||||
let mut ret: Self = mem::MaybeUninit();
|
||||
{
|
||||
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::uninitialized();
|
||||
let mut ret: Self = mem::MaybeUninit();
|
||||
{
|
||||
let ret_mut: &mut [u32; 4] = ret.as_mut();
|
||||
f.store(ret_mut.as_mut(), 0 as usize);
|
||||
|
|
|
@ -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: x, y: y, z: z });
|
||||
let matrix3 = Matrix3::from(Euler { x, y, 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, v, None);
|
||||
let q = Quaternion::from_arc(v.clone(), v, None);
|
||||
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.transform_point(point), &view_point);
|
||||
|
||||
// Decomposed::look_at is inconsistent and deprecated, but verify that the behvaior
|
||||
// Decomposed::look_at is inconsistent and deprecated, but verify that the behavior
|
||||
// remains the same until removed.
|
||||
#[allow(deprecated)]
|
||||
let t: Decomposed<Vector3<f64>, Quaternion<f64>> = Transform::look_at(eye, center, up);
|
||||
|
|
Loading…
Reference in a new issue