Merge pull request #962 from dimforge/non-copy-types
Tha clone wars: allow non-copy scalar types everywhere
This commit is contained in:
commit
1bc919e0db
|
@ -70,7 +70,7 @@ num-traits = { version = "0.2", default-features = false }
|
||||||
num-complex = { version = "0.4", default-features = false }
|
num-complex = { version = "0.4", default-features = false }
|
||||||
num-rational = { version = "0.4", default-features = false }
|
num-rational = { version = "0.4", default-features = false }
|
||||||
approx = { version = "0.5", default-features = false }
|
approx = { version = "0.5", default-features = false }
|
||||||
simba = { version = "0.5", default-features = false }
|
simba = { version = "0.6", default-features = false }
|
||||||
alga = { version = "0.9", default-features = false, optional = true }
|
alga = { version = "0.9", default-features = false, optional = true }
|
||||||
rand_distr = { version = "0.4", default-features = false, optional = true }
|
rand_distr = { version = "0.4", default-features = false, optional = true }
|
||||||
matrixmultiply = { version = "0.3", optional = true }
|
matrixmultiply = { version = "0.3", optional = true }
|
||||||
|
@ -113,6 +113,10 @@ harness = false
|
||||||
path = "benches/lib.rs"
|
path = "benches/lib.rs"
|
||||||
required-features = ["rand"]
|
required-features = ["rand"]
|
||||||
|
|
||||||
|
#[profile.bench]
|
||||||
|
#opt-level = 0
|
||||||
|
#lto = false
|
||||||
|
|
||||||
[profile.bench]
|
[profile.bench]
|
||||||
lto = true
|
lto = true
|
||||||
|
|
||||||
|
|
|
@ -26,5 +26,5 @@ abomonation-serialize = [ "nalgebra/abomonation-serialize" ]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
num-traits = { version = "0.2", default-features = false }
|
num-traits = { version = "0.2", default-features = false }
|
||||||
approx = { version = "0.5", default-features = false }
|
approx = { version = "0.5", default-features = false }
|
||||||
simba = { version = "0.5", default-features = false }
|
simba = { version = "0.6", default-features = false }
|
||||||
nalgebra = { path = "..", version = "0.28", default-features = false }
|
nalgebra = { path = "..", version = "0.28", default-features = false }
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use na::{self, RealField};
|
use na;
|
||||||
use num::FromPrimitive;
|
|
||||||
|
|
||||||
use crate::aliases::{TMat, TVec};
|
use crate::aliases::{TMat, TVec};
|
||||||
use crate::traits::Number;
|
use crate::traits::Number;
|
||||||
|
use crate::RealNumber;
|
||||||
|
|
||||||
/// For each matrix or vector component `x` if `x >= 0`; otherwise, it returns `-x`.
|
/// For each matrix or vector component `x` if `x >= 0`; otherwise, it returns `-x`.
|
||||||
///
|
///
|
||||||
|
@ -42,7 +42,7 @@ pub fn abs<T: Number, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> TMat
|
||||||
/// * [`fract`](fn.fract.html)
|
/// * [`fract`](fn.fract.html)
|
||||||
/// * [`round`](fn.round.html)
|
/// * [`round`](fn.round.html)
|
||||||
/// * [`trunc`](fn.trunc.html)
|
/// * [`trunc`](fn.trunc.html)
|
||||||
pub fn ceil<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn ceil<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.map(|x| x.ceil())
|
x.map(|x| x.ceil())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ pub fn float_bits_to_uint_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<u32, D>
|
||||||
/// * [`fract`](fn.fract.html)
|
/// * [`fract`](fn.fract.html)
|
||||||
/// * [`round`](fn.round.html)
|
/// * [`round`](fn.round.html)
|
||||||
/// * [`trunc`](fn.trunc.html)
|
/// * [`trunc`](fn.trunc.html)
|
||||||
pub fn floor<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn floor<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.map(|x| x.floor())
|
x.map(|x| x.floor())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,13 +240,13 @@ pub fn floor<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
/// * [`floor`](fn.floor.html)
|
/// * [`floor`](fn.floor.html)
|
||||||
/// * [`round`](fn.round.html)
|
/// * [`round`](fn.round.html)
|
||||||
/// * [`trunc`](fn.trunc.html)
|
/// * [`trunc`](fn.trunc.html)
|
||||||
pub fn fract<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn fract<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.map(|x| x.fract())
|
x.map(|x| x.fract())
|
||||||
}
|
}
|
||||||
|
|
||||||
//// TODO: should be implemented for TVec/TMat?
|
//// TODO: should be implemented for TVec/TMat?
|
||||||
///// Returns the (significant, exponent) of this float number.
|
///// Returns the (significant, exponent) of this float number.
|
||||||
//pub fn frexp<T: RealField>(x: T, exp: T) -> (T, T) {
|
//pub fn frexp<T: RealNumber>(x: T, exp: T) -> (T, T) {
|
||||||
// // TODO: is there a better approach?
|
// // TODO: is there a better approach?
|
||||||
// let e = x.log2().ceil();
|
// let e = x.log2().ceil();
|
||||||
// (x * (-e).exp2(), e)
|
// (x * (-e).exp2(), e)
|
||||||
|
@ -297,7 +297,7 @@ pub fn int_bits_to_float_vec<const D: usize>(v: &TVec<i32, D>) -> TVec<f32, D> {
|
||||||
//}
|
//}
|
||||||
|
|
||||||
///// Returns the (significant, exponent) of this float number.
|
///// Returns the (significant, exponent) of this float number.
|
||||||
//pub fn ldexp<T: RealField>(x: T, exp: T) -> T {
|
//pub fn ldexp<T: RealNumber>(x: T, exp: T) -> T {
|
||||||
// // TODO: is there a better approach?
|
// // TODO: is there a better approach?
|
||||||
// x * (exp).exp2()
|
// x * (exp).exp2()
|
||||||
//}
|
//}
|
||||||
|
@ -477,7 +477,7 @@ pub fn modf<T: Number>(x: T, i: T) -> T {
|
||||||
/// * [`floor`](fn.floor.html)
|
/// * [`floor`](fn.floor.html)
|
||||||
/// * [`fract`](fn.fract.html)
|
/// * [`fract`](fn.fract.html)
|
||||||
/// * [`trunc`](fn.trunc.html)
|
/// * [`trunc`](fn.trunc.html)
|
||||||
pub fn round<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn round<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.map(|x| x.round())
|
x.map(|x| x.round())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,9 +507,9 @@ pub fn sign<T: Number, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
///
|
///
|
||||||
/// This is useful in cases where you would want a threshold function with a smooth transition.
|
/// This is useful in cases where you would want a threshold function with a smooth transition.
|
||||||
/// This is equivalent to: `let result = clamp((x - edge0) / (edge1 - edge0), 0, 1); return t * t * (3 - 2 * t);` Results are undefined if `edge0 >= edge1`.
|
/// This is equivalent to: `let result = clamp((x - edge0) / (edge1 - edge0), 0, 1); return t * t * (3 - 2 * t);` Results are undefined if `edge0 >= edge1`.
|
||||||
pub fn smoothstep<T: Number>(edge0: T, edge1: T, x: T) -> T {
|
pub fn smoothstep<T: RealNumber>(edge0: T, edge1: T, x: T) -> T {
|
||||||
let _3: T = FromPrimitive::from_f64(3.0).unwrap();
|
let _3 = T::from_subset(&3.0f64);
|
||||||
let _2: T = FromPrimitive::from_f64(2.0).unwrap();
|
let _2 = T::from_subset(&2.0f64);
|
||||||
let t = na::clamp((x - edge0) / (edge1 - edge0), T::zero(), T::one());
|
let t = na::clamp((x - edge0) / (edge1 - edge0), T::zero(), T::one());
|
||||||
t * t * (_3 - t * _2)
|
t * t * (_3 - t * _2)
|
||||||
}
|
}
|
||||||
|
@ -549,7 +549,7 @@ pub fn step_vec<T: Number, const D: usize>(edge: &TVec<T, D>, x: &TVec<T, D>) ->
|
||||||
/// * [`floor`](fn.floor.html)
|
/// * [`floor`](fn.floor.html)
|
||||||
/// * [`fract`](fn.fract.html)
|
/// * [`fract`](fn.fract.html)
|
||||||
/// * [`round`](fn.round.html)
|
/// * [`round`](fn.round.html)
|
||||||
pub fn trunc<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn trunc<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.map(|x| x.trunc())
|
x.map(|x| x.trunc())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,8 @@ use crate::aliases::{
|
||||||
Qua, TMat, TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3, TVec1,
|
Qua, TMat, TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3, TVec1,
|
||||||
TVec2, TVec3, TVec4,
|
TVec2, TVec3, TVec4,
|
||||||
};
|
};
|
||||||
use na::{RealField, Scalar};
|
use crate::RealNumber;
|
||||||
|
use na::Scalar;
|
||||||
|
|
||||||
/// Creates a new 1D vector.
|
/// Creates a new 1D vector.
|
||||||
///
|
///
|
||||||
|
@ -178,6 +179,6 @@ pub fn mat4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new quaternion.
|
/// Creates a new quaternion.
|
||||||
pub fn quat<T: RealField>(x: T, y: T, z: T, w: T) -> Qua<T> {
|
pub fn quat<T: RealNumber>(x: T, y: T, z: T, w: T) -> Qua<T> {
|
||||||
Qua::new(w, x, y, z)
|
Qua::new(w, x, y, z)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use na::RealField;
|
use crate::RealNumber;
|
||||||
|
|
||||||
/// Component-wise exponential.
|
/// Component-wise exponential.
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`exp2`](fn.exp2.html)
|
/// * [`exp2`](fn.exp2.html)
|
||||||
pub fn exp<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
pub fn exp<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
v.map(|x| x.exp())
|
v.map(|x| x.exp())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ pub fn exp<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`exp`](fn.exp.html)
|
/// * [`exp`](fn.exp.html)
|
||||||
pub fn exp2<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
pub fn exp2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
v.map(|x| x.exp2())
|
v.map(|x| x.exp2())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ pub fn exp2<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`sqrt`](fn.sqrt.html)
|
/// * [`sqrt`](fn.sqrt.html)
|
||||||
pub fn inversesqrt<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
pub fn inversesqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
v.map(|x| T::one() / x.sqrt())
|
v.map(|x| T::one() / x.sqrt())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ pub fn inversesqrt<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`log2`](fn.log2.html)
|
/// * [`log2`](fn.log2.html)
|
||||||
pub fn log<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
pub fn log<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
v.map(|x| x.ln())
|
v.map(|x| x.ln())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,12 +42,12 @@ pub fn log<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`log`](fn.log.html)
|
/// * [`log`](fn.log.html)
|
||||||
pub fn log2<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
pub fn log2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
v.map(|x| x.log2())
|
v.map(|x| x.log2())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise power.
|
/// Component-wise power.
|
||||||
pub fn pow<T: RealField, const D: usize>(base: &TVec<T, D>, exponent: &TVec<T, D>) -> TVec<T, D> {
|
pub fn pow<T: RealNumber, const D: usize>(base: &TVec<T, D>, exponent: &TVec<T, D>) -> TVec<T, D> {
|
||||||
base.zip_map(exponent, |b, e| b.powf(e))
|
base.zip_map(exponent, |b, e| b.powf(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,6 @@ pub fn pow<T: RealField, const D: usize>(base: &TVec<T, D>, exponent: &TVec<T, D
|
||||||
/// * [`exp2`](fn.exp2.html)
|
/// * [`exp2`](fn.exp2.html)
|
||||||
/// * [`inversesqrt`](fn.inversesqrt.html)
|
/// * [`inversesqrt`](fn.inversesqrt.html)
|
||||||
/// * [`pow`](fn.pow.html)
|
/// * [`pow`](fn.pow.html)
|
||||||
pub fn sqrt<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
pub fn sqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
v.map(|x| x.sqrt())
|
v.map(|x| x.sqrt())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,51 +1,51 @@
|
||||||
use crate::aliases::TMat4;
|
use crate::aliases::TMat4;
|
||||||
use na::RealField;
|
use crate::RealNumber;
|
||||||
|
|
||||||
//pub fn frustum<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
//pub fn frustum<T: RealNumber>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//pub fn frustum_lh<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
//pub fn frustum_lh<T: RealNumber>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_lr_no<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
//pub fn frustum_lr_no<T: RealNumber>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_lh_zo<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
//pub fn frustum_lh_zo<T: RealNumber>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_no<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
//pub fn frustum_no<T: RealNumber>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_rh<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
//pub fn frustum_rh<T: RealNumber>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_rh_no<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
//pub fn frustum_rh_no<T: RealNumber>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_rh_zo<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
//pub fn frustum_rh_zo<T: RealNumber>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_zo<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
//pub fn frustum_zo<T: RealNumber>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//pub fn infinite_perspective<T: RealField>(fovy: T, aspect: T, near: T) -> TMat4<T> {
|
//pub fn infinite_perspective<T: RealNumber>(fovy: T, aspect: T, near: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn infinite_perspective_lh<T: RealField>(fovy: T, aspect: T, near: T) -> TMat4<T> {
|
//pub fn infinite_perspective_lh<T: RealNumber>(fovy: T, aspect: T, near: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn infinite_ortho<T: RealField>(left: T, right: T, bottom: T, top: T) -> TMat4<T> {
|
//pub fn infinite_ortho<T: RealNumber>(left: T, right: T, bottom: T, top: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ use na::RealField;
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> TMat4<T> {
|
pub fn ortho<T: RealNumber>(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> TMat4<T> {
|
||||||
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,14 @@ pub fn ortho<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zfar:
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho_lh<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> TMat4<T> {
|
pub fn ortho_lh<T: RealNumber>(
|
||||||
|
left: T,
|
||||||
|
right: T,
|
||||||
|
bottom: T,
|
||||||
|
top: T,
|
||||||
|
znear: T,
|
||||||
|
zfar: T,
|
||||||
|
) -> TMat4<T> {
|
||||||
ortho_lh_no(left, right, bottom, top, znear, zfar)
|
ortho_lh_no(left, right, bottom, top, znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +97,7 @@ pub fn ortho_lh<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zf
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho_lh_no<T: RealField>(
|
pub fn ortho_lh_no<T: RealNumber>(
|
||||||
left: T,
|
left: T,
|
||||||
right: T,
|
right: T,
|
||||||
bottom: T,
|
bottom: T,
|
||||||
|
@ -122,7 +129,7 @@ pub fn ortho_lh_no<T: RealField>(
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho_lh_zo<T: RealField>(
|
pub fn ortho_lh_zo<T: RealNumber>(
|
||||||
left: T,
|
left: T,
|
||||||
right: T,
|
right: T,
|
||||||
bottom: T,
|
bottom: T,
|
||||||
|
@ -155,7 +162,14 @@ pub fn ortho_lh_zo<T: RealField>(
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho_no<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> TMat4<T> {
|
pub fn ortho_no<T: RealNumber>(
|
||||||
|
left: T,
|
||||||
|
right: T,
|
||||||
|
bottom: T,
|
||||||
|
top: T,
|
||||||
|
znear: T,
|
||||||
|
zfar: T,
|
||||||
|
) -> TMat4<T> {
|
||||||
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +184,14 @@ pub fn ortho_no<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zf
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho_rh<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> TMat4<T> {
|
pub fn ortho_rh<T: RealNumber>(
|
||||||
|
left: T,
|
||||||
|
right: T,
|
||||||
|
bottom: T,
|
||||||
|
top: T,
|
||||||
|
znear: T,
|
||||||
|
zfar: T,
|
||||||
|
) -> TMat4<T> {
|
||||||
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,7 +206,7 @@ pub fn ortho_rh<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zf
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho_rh_no<T: RealField>(
|
pub fn ortho_rh_no<T: RealNumber>(
|
||||||
left: T,
|
left: T,
|
||||||
right: T,
|
right: T,
|
||||||
bottom: T,
|
bottom: T,
|
||||||
|
@ -217,7 +238,7 @@ pub fn ortho_rh_no<T: RealField>(
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho_rh_zo<T: RealField>(
|
pub fn ortho_rh_zo<T: RealNumber>(
|
||||||
left: T,
|
left: T,
|
||||||
right: T,
|
right: T,
|
||||||
bottom: T,
|
bottom: T,
|
||||||
|
@ -250,7 +271,14 @@ pub fn ortho_rh_zo<T: RealField>(
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho_zo<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> TMat4<T> {
|
pub fn ortho_zo<T: RealNumber>(
|
||||||
|
left: T,
|
||||||
|
right: T,
|
||||||
|
bottom: T,
|
||||||
|
top: T,
|
||||||
|
znear: T,
|
||||||
|
zfar: T,
|
||||||
|
) -> TMat4<T> {
|
||||||
ortho_rh_zo(left, right, bottom, top, znear, zfar)
|
ortho_rh_zo(left, right, bottom, top, znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +292,7 @@ pub fn ortho_zo<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zf
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov<T: RealField>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
|
pub fn perspective_fov<T: RealNumber>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_fov_rh_no(fov, width, height, near, far)
|
perspective_fov_rh_no(fov, width, height, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +306,7 @@ pub fn perspective_fov<T: RealField>(fov: T, width: T, height: T, near: T, far:
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov_lh<T: RealField>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
|
pub fn perspective_fov_lh<T: RealNumber>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_fov_lh_no(fov, width, height, near, far)
|
perspective_fov_lh_no(fov, width, height, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,7 +320,7 @@ pub fn perspective_fov_lh<T: RealField>(fov: T, width: T, height: T, near: T, fa
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov_lh_no<T: RealField>(
|
pub fn perspective_fov_lh_no<T: RealNumber>(
|
||||||
fov: T,
|
fov: T,
|
||||||
width: T,
|
width: T,
|
||||||
height: T,
|
height: T,
|
||||||
|
@ -328,7 +356,7 @@ pub fn perspective_fov_lh_no<T: RealField>(
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov_lh_zo<T: RealField>(
|
pub fn perspective_fov_lh_zo<T: RealNumber>(
|
||||||
fov: T,
|
fov: T,
|
||||||
width: T,
|
width: T,
|
||||||
height: T,
|
height: T,
|
||||||
|
@ -364,7 +392,7 @@ pub fn perspective_fov_lh_zo<T: RealField>(
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov_no<T: RealField>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
|
pub fn perspective_fov_no<T: RealNumber>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_fov_rh_no(fov, width, height, near, far)
|
perspective_fov_rh_no(fov, width, height, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +406,7 @@ pub fn perspective_fov_no<T: RealField>(fov: T, width: T, height: T, near: T, fa
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov_rh<T: RealField>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
|
pub fn perspective_fov_rh<T: RealNumber>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_fov_rh_no(fov, width, height, near, far)
|
perspective_fov_rh_no(fov, width, height, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,7 +420,7 @@ pub fn perspective_fov_rh<T: RealField>(fov: T, width: T, height: T, near: T, fa
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov_rh_no<T: RealField>(
|
pub fn perspective_fov_rh_no<T: RealNumber>(
|
||||||
fov: T,
|
fov: T,
|
||||||
width: T,
|
width: T,
|
||||||
height: T,
|
height: T,
|
||||||
|
@ -428,7 +456,7 @@ pub fn perspective_fov_rh_no<T: RealField>(
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov_rh_zo<T: RealField>(
|
pub fn perspective_fov_rh_zo<T: RealNumber>(
|
||||||
fov: T,
|
fov: T,
|
||||||
width: T,
|
width: T,
|
||||||
height: T,
|
height: T,
|
||||||
|
@ -464,7 +492,7 @@ pub fn perspective_fov_rh_zo<T: RealField>(
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov_zo<T: RealField>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
|
pub fn perspective_fov_zo<T: RealNumber>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_fov_rh_zo(fov, width, height, near, far)
|
perspective_fov_rh_zo(fov, width, height, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,7 +507,7 @@ pub fn perspective_fov_zo<T: RealField>(fov: T, width: T, height: T, near: T, fa
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
pub fn perspective<T: RealNumber>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
// TODO: Breaking change - revert back to proper glm conventions?
|
// TODO: Breaking change - revert back to proper glm conventions?
|
||||||
//
|
//
|
||||||
// Prior to changes to support configuring the behaviour of this function it was simply
|
// Prior to changes to support configuring the behaviour of this function it was simply
|
||||||
|
@ -508,7 +536,7 @@ pub fn perspective<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective_lh<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
pub fn perspective_lh<T: RealNumber>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_lh_no(aspect, fovy, near, far)
|
perspective_lh_no(aspect, fovy, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,7 +551,7 @@ pub fn perspective_lh<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective_lh_no<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
pub fn perspective_lh_no<T: RealNumber>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(far - near, T::zero()),
|
!relative_eq!(far - near, T::zero()),
|
||||||
"The near-plane and far-plane must not be superimposed."
|
"The near-plane and far-plane must not be superimposed."
|
||||||
|
@ -559,7 +587,7 @@ pub fn perspective_lh_no<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> T
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective_lh_zo<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
pub fn perspective_lh_zo<T: RealNumber>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(far - near, T::zero()),
|
!relative_eq!(far - near, T::zero()),
|
||||||
"The near-plane and far-plane must not be superimposed."
|
"The near-plane and far-plane must not be superimposed."
|
||||||
|
@ -595,7 +623,7 @@ pub fn perspective_lh_zo<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> T
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective_no<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
pub fn perspective_no<T: RealNumber>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_rh_no(aspect, fovy, near, far)
|
perspective_rh_no(aspect, fovy, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -610,7 +638,7 @@ pub fn perspective_no<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective_rh<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
pub fn perspective_rh<T: RealNumber>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_rh_no(aspect, fovy, near, far)
|
perspective_rh_no(aspect, fovy, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,7 +653,7 @@ pub fn perspective_rh<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective_rh_no<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
pub fn perspective_rh_no<T: RealNumber>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(far - near, T::zero()),
|
!relative_eq!(far - near, T::zero()),
|
||||||
"The near-plane and far-plane must not be superimposed."
|
"The near-plane and far-plane must not be superimposed."
|
||||||
|
@ -662,7 +690,7 @@ pub fn perspective_rh_no<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> T
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective_rh_zo<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
pub fn perspective_rh_zo<T: RealNumber>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(far - near, T::zero()),
|
!relative_eq!(far - near, T::zero()),
|
||||||
"The near-plane and far-plane must not be superimposed."
|
"The near-plane and far-plane must not be superimposed."
|
||||||
|
@ -699,7 +727,7 @@ pub fn perspective_rh_zo<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> T
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective_zo<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
pub fn perspective_zo<T: RealNumber>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_rh_zo(aspect, fovy, near, far)
|
perspective_rh_zo(aspect, fovy, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,7 +741,7 @@ pub fn perspective_zo<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn infinite_perspective_rh_no<T: RealField>(aspect: T, fovy: T, near: T) -> TMat4<T> {
|
pub fn infinite_perspective_rh_no<T: RealNumber>(aspect: T, fovy: T, near: T) -> TMat4<T> {
|
||||||
let f = T::one() / (fovy * na::convert(0.5)).tan();
|
let f = T::one() / (fovy * na::convert(0.5)).tan();
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
|
@ -738,7 +766,7 @@ pub fn infinite_perspective_rh_no<T: RealField>(aspect: T, fovy: T, near: T) ->
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
///
|
///
|
||||||
// https://discourse.nphysics.org/t/reversed-z-and-infinite-zfar-in-projections/341/2
|
// https://discourse.nphysics.org/t/reversed-z-and-infinite-zfar-in-projections/341/2
|
||||||
pub fn infinite_perspective_rh_zo<T: RealField>(aspect: T, fovy: T, near: T) -> TMat4<T> {
|
pub fn infinite_perspective_rh_zo<T: RealNumber>(aspect: T, fovy: T, near: T) -> TMat4<T> {
|
||||||
let f = T::one() / (fovy * na::convert(0.5)).tan();
|
let f = T::one() / (fovy * na::convert(0.5)).tan();
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
|
@ -763,7 +791,7 @@ pub fn infinite_perspective_rh_zo<T: RealField>(aspect: T, fovy: T, near: T) ->
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
// NOTE: The variants `_no` of reversed perspective are not useful.
|
// NOTE: The variants `_no` of reversed perspective are not useful.
|
||||||
pub fn reversed_perspective_rh_zo<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
pub fn reversed_perspective_rh_zo<T: RealNumber>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
let one = T::one();
|
let one = T::one();
|
||||||
let two = crate::convert(2.0);
|
let two = crate::convert(2.0);
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
@ -791,7 +819,7 @@ pub fn reversed_perspective_rh_zo<T: RealField>(aspect: T, fovy: T, near: T, far
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
// Credit: https://discourse.nphysics.org/t/reversed-z-and-infinite-zfar-in-projections/341/2
|
// Credit: https://discourse.nphysics.org/t/reversed-z-and-infinite-zfar-in-projections/341/2
|
||||||
// NOTE: The variants `_no` of reversed perspective are not useful.
|
// NOTE: The variants `_no` of reversed perspective are not useful.
|
||||||
pub fn reversed_infinite_perspective_rh_zo<T: RealField>(aspect: T, fovy: T, near: T) -> TMat4<T> {
|
pub fn reversed_infinite_perspective_rh_zo<T: RealNumber>(aspect: T, fovy: T, near: T) -> TMat4<T> {
|
||||||
let f = T::one() / (fovy * na::convert(0.5)).tan();
|
let f = T::one() / (fovy * na::convert(0.5)).tan();
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
|
@ -803,10 +831,10 @@ pub fn reversed_infinite_perspective_rh_zo<T: RealField>(aspect: T, fovy: T, nea
|
||||||
mat
|
mat
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn tweaked_infinite_perspective<T: RealField>(fovy: T, aspect: T, near: T) -> TMat4<T> {
|
//pub fn tweaked_infinite_perspective<T: RealNumber>(fovy: T, aspect: T, near: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn tweaked_infinite_perspective_ep<T: RealField>(fovy: T, aspect: T, near: T, ep: T) -> TMat4<T> {
|
//pub fn tweaked_infinite_perspective_ep<T: RealNumber>(fovy: T, aspect: T, near: T, ep: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use na::{self, RealField};
|
use na;
|
||||||
|
|
||||||
use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
|
use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
|
||||||
|
use crate::RealNumber;
|
||||||
|
|
||||||
/// Define a picking region.
|
/// Define a picking region.
|
||||||
///
|
///
|
||||||
|
@ -9,7 +10,7 @@ use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
|
||||||
/// * `center` - Specify the center of a picking region in window coordinates.
|
/// * `center` - Specify the center of a picking region in window coordinates.
|
||||||
/// * `delta` - Specify the width and height, respectively, of the picking region in window coordinates.
|
/// * `delta` - Specify the width and height, respectively, of the picking region in window coordinates.
|
||||||
/// * `viewport` - Rendering viewport.
|
/// * `viewport` - Rendering viewport.
|
||||||
pub fn pick_matrix<T: RealField>(
|
pub fn pick_matrix<T: RealNumber>(
|
||||||
center: &TVec2<T>,
|
center: &TVec2<T>,
|
||||||
delta: &TVec2<T>,
|
delta: &TVec2<T>,
|
||||||
viewport: &TVec4<T>,
|
viewport: &TVec4<T>,
|
||||||
|
@ -45,7 +46,7 @@ pub fn pick_matrix<T: RealField>(
|
||||||
/// * [`unproject`](fn.unproject.html)
|
/// * [`unproject`](fn.unproject.html)
|
||||||
/// * [`unproject_no`](fn.unproject_no.html)
|
/// * [`unproject_no`](fn.unproject_no.html)
|
||||||
/// * [`unproject_zo`](fn.unproject_zo.html)
|
/// * [`unproject_zo`](fn.unproject_zo.html)
|
||||||
pub fn project<T: RealField>(
|
pub fn project<T: RealNumber>(
|
||||||
obj: &TVec3<T>,
|
obj: &TVec3<T>,
|
||||||
model: &TMat4<T>,
|
model: &TMat4<T>,
|
||||||
proj: &TMat4<T>,
|
proj: &TMat4<T>,
|
||||||
|
@ -72,7 +73,7 @@ pub fn project<T: RealField>(
|
||||||
/// * [`unproject`](fn.unproject.html)
|
/// * [`unproject`](fn.unproject.html)
|
||||||
/// * [`unproject_no`](fn.unproject_no.html)
|
/// * [`unproject_no`](fn.unproject_no.html)
|
||||||
/// * [`unproject_zo`](fn.unproject_zo.html)
|
/// * [`unproject_zo`](fn.unproject_zo.html)
|
||||||
pub fn project_no<T: RealField>(
|
pub fn project_no<T: RealNumber>(
|
||||||
obj: &TVec3<T>,
|
obj: &TVec3<T>,
|
||||||
model: &TMat4<T>,
|
model: &TMat4<T>,
|
||||||
proj: &TMat4<T>,
|
proj: &TMat4<T>,
|
||||||
|
@ -100,7 +101,7 @@ pub fn project_no<T: RealField>(
|
||||||
/// * [`unproject`](fn.unproject.html)
|
/// * [`unproject`](fn.unproject.html)
|
||||||
/// * [`unproject_no`](fn.unproject_no.html)
|
/// * [`unproject_no`](fn.unproject_no.html)
|
||||||
/// * [`unproject_zo`](fn.unproject_zo.html)
|
/// * [`unproject_zo`](fn.unproject_zo.html)
|
||||||
pub fn project_zo<T: RealField>(
|
pub fn project_zo<T: RealNumber>(
|
||||||
obj: &TVec3<T>,
|
obj: &TVec3<T>,
|
||||||
model: &TMat4<T>,
|
model: &TMat4<T>,
|
||||||
proj: &TMat4<T>,
|
proj: &TMat4<T>,
|
||||||
|
@ -133,7 +134,7 @@ pub fn project_zo<T: RealField>(
|
||||||
/// * [`project_zo`](fn.project_zo.html)
|
/// * [`project_zo`](fn.project_zo.html)
|
||||||
/// * [`unproject_no`](fn.unproject_no.html)
|
/// * [`unproject_no`](fn.unproject_no.html)
|
||||||
/// * [`unproject_zo`](fn.unproject_zo.html)
|
/// * [`unproject_zo`](fn.unproject_zo.html)
|
||||||
pub fn unproject<T: RealField>(
|
pub fn unproject<T: RealNumber>(
|
||||||
win: &TVec3<T>,
|
win: &TVec3<T>,
|
||||||
model: &TMat4<T>,
|
model: &TMat4<T>,
|
||||||
proj: &TMat4<T>,
|
proj: &TMat4<T>,
|
||||||
|
@ -160,7 +161,7 @@ pub fn unproject<T: RealField>(
|
||||||
/// * [`project_zo`](fn.project_zo.html)
|
/// * [`project_zo`](fn.project_zo.html)
|
||||||
/// * [`unproject`](fn.unproject.html)
|
/// * [`unproject`](fn.unproject.html)
|
||||||
/// * [`unproject_zo`](fn.unproject_zo.html)
|
/// * [`unproject_zo`](fn.unproject_zo.html)
|
||||||
pub fn unproject_no<T: RealField>(
|
pub fn unproject_no<T: RealNumber>(
|
||||||
win: &TVec3<T>,
|
win: &TVec3<T>,
|
||||||
model: &TMat4<T>,
|
model: &TMat4<T>,
|
||||||
proj: &TMat4<T>,
|
proj: &TMat4<T>,
|
||||||
|
@ -197,7 +198,7 @@ pub fn unproject_no<T: RealField>(
|
||||||
/// * [`project_zo`](fn.project_zo.html)
|
/// * [`project_zo`](fn.project_zo.html)
|
||||||
/// * [`unproject`](fn.unproject.html)
|
/// * [`unproject`](fn.unproject.html)
|
||||||
/// * [`unproject_no`](fn.unproject_no.html)
|
/// * [`unproject_no`](fn.unproject_no.html)
|
||||||
pub fn unproject_zo<T: RealField>(
|
pub fn unproject_zo<T: RealNumber>(
|
||||||
win: &TVec3<T>,
|
win: &TVec3<T>,
|
||||||
model: &TMat4<T>,
|
model: &TMat4<T>,
|
||||||
proj: &TMat4<T>,
|
proj: &TMat4<T>,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{Point3, RealField, Rotation3, Unit};
|
use na::{Point3, Rotation3, Unit};
|
||||||
|
|
||||||
use crate::aliases::{TMat, TMat4, TVec, TVec3};
|
use crate::aliases::{TMat, TMat4, TVec, TVec3};
|
||||||
use crate::traits::Number;
|
use crate::traits::{Number, RealNumber};
|
||||||
|
|
||||||
/// The identity matrix.
|
/// The identity matrix.
|
||||||
pub fn identity<T: Number, const D: usize>() -> TMat<T, D, D> {
|
pub fn identity<T: Number, const D: usize>() -> TMat<T, D, D> {
|
||||||
|
@ -20,7 +20,7 @@ pub fn identity<T: Number, const D: usize>() -> TMat<T, D, D> {
|
||||||
///
|
///
|
||||||
/// * [`look_at_lh`](fn.look_at_lh.html)
|
/// * [`look_at_lh`](fn.look_at_lh.html)
|
||||||
/// * [`look_at_rh`](fn.look_at_rh.html)
|
/// * [`look_at_rh`](fn.look_at_rh.html)
|
||||||
pub fn look_at<T: RealField>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
pub fn look_at<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
||||||
look_at_rh(eye, center, up)
|
look_at_rh(eye, center, up)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ pub fn look_at<T: RealField>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -
|
||||||
///
|
///
|
||||||
/// * [`look_at`](fn.look_at.html)
|
/// * [`look_at`](fn.look_at.html)
|
||||||
/// * [`look_at_rh`](fn.look_at_rh.html)
|
/// * [`look_at_rh`](fn.look_at_rh.html)
|
||||||
pub fn look_at_lh<T: RealField>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
pub fn look_at_lh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
||||||
TMat::look_at_lh(&Point3::from(*eye), &Point3::from(*center), up)
|
TMat::look_at_lh(&Point3::from(*eye), &Point3::from(*center), up)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ pub fn look_at_lh<T: RealField>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>
|
||||||
///
|
///
|
||||||
/// * [`look_at`](fn.look_at.html)
|
/// * [`look_at`](fn.look_at.html)
|
||||||
/// * [`look_at_lh`](fn.look_at_lh.html)
|
/// * [`look_at_lh`](fn.look_at_lh.html)
|
||||||
pub fn look_at_rh<T: RealField>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
pub fn look_at_rh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
||||||
TMat::look_at_rh(&Point3::from(*eye), &Point3::from(*center), up)
|
TMat::look_at_rh(&Point3::from(*eye), &Point3::from(*center), up)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ pub fn look_at_rh<T: RealField>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>
|
||||||
/// * [`rotate_z`](fn.rotate_z.html)
|
/// * [`rotate_z`](fn.rotate_z.html)
|
||||||
/// * [`scale`](fn.scale.html)
|
/// * [`scale`](fn.scale.html)
|
||||||
/// * [`translate`](fn.translate.html)
|
/// * [`translate`](fn.translate.html)
|
||||||
pub fn rotate<T: RealField>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T> {
|
pub fn rotate<T: RealNumber>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T> {
|
||||||
m * Rotation3::from_axis_angle(&Unit::new_normalize(*axis), angle).to_homogeneous()
|
m * Rotation3::from_axis_angle(&Unit::new_normalize(*axis), angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ pub fn rotate<T: RealField>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T>
|
||||||
/// * [`rotate_z`](fn.rotate_z.html)
|
/// * [`rotate_z`](fn.rotate_z.html)
|
||||||
/// * [`scale`](fn.scale.html)
|
/// * [`scale`](fn.scale.html)
|
||||||
/// * [`translate`](fn.translate.html)
|
/// * [`translate`](fn.translate.html)
|
||||||
pub fn rotate_x<T: RealField>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
pub fn rotate_x<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
||||||
rotate(m, angle, &TVec::x())
|
rotate(m, angle, &TVec::x())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ pub fn rotate_x<T: RealField>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
||||||
/// * [`rotate_z`](fn.rotate_z.html)
|
/// * [`rotate_z`](fn.rotate_z.html)
|
||||||
/// * [`scale`](fn.scale.html)
|
/// * [`scale`](fn.scale.html)
|
||||||
/// * [`translate`](fn.translate.html)
|
/// * [`translate`](fn.translate.html)
|
||||||
pub fn rotate_y<T: RealField>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
pub fn rotate_y<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
||||||
rotate(m, angle, &TVec::y())
|
rotate(m, angle, &TVec::y())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ pub fn rotate_y<T: RealField>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
||||||
/// * [`rotate_y`](fn.rotate_y.html)
|
/// * [`rotate_y`](fn.rotate_y.html)
|
||||||
/// * [`scale`](fn.scale.html)
|
/// * [`scale`](fn.scale.html)
|
||||||
/// * [`translate`](fn.translate.html)
|
/// * [`translate`](fn.translate.html)
|
||||||
pub fn rotate_z<T: RealField>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
pub fn rotate_z<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
||||||
rotate(m, angle, &TVec::z())
|
rotate(m, angle, &TVec::z())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,36 +1,37 @@
|
||||||
use na::{self, RealField, Unit};
|
use na::{self, Unit};
|
||||||
|
|
||||||
use crate::aliases::Qua;
|
use crate::aliases::Qua;
|
||||||
|
use crate::RealNumber;
|
||||||
|
|
||||||
/// The conjugate of `q`.
|
/// The conjugate of `q`.
|
||||||
pub fn quat_conjugate<T: RealField>(q: &Qua<T>) -> Qua<T> {
|
pub fn quat_conjugate<T: RealNumber>(q: &Qua<T>) -> Qua<T> {
|
||||||
q.conjugate()
|
q.conjugate()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The inverse of `q`.
|
/// The inverse of `q`.
|
||||||
pub fn quat_inverse<T: RealField>(q: &Qua<T>) -> Qua<T> {
|
pub fn quat_inverse<T: RealNumber>(q: &Qua<T>) -> Qua<T> {
|
||||||
q.try_inverse().unwrap_or_else(na::zero)
|
q.try_inverse().unwrap_or_else(na::zero)
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn quat_isinf<T: RealField>(x: &Qua<T>) -> TVec<bool, U4> {
|
//pub fn quat_isinf<T: RealNumber>(x: &Qua<T>) -> TVec<bool, U4> {
|
||||||
// x.coords.map(|e| e.is_inf())
|
// x.coords.map(|e| e.is_inf())
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//pub fn quat_isnan<T: RealField>(x: &Qua<T>) -> TVec<bool, U4> {
|
//pub fn quat_isnan<T: RealNumber>(x: &Qua<T>) -> TVec<bool, U4> {
|
||||||
// x.coords.map(|e| e.is_nan())
|
// x.coords.map(|e| e.is_nan())
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/// Interpolate linearly between `x` and `y`.
|
/// Interpolate linearly between `x` and `y`.
|
||||||
pub fn quat_lerp<T: RealField>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
|
pub fn quat_lerp<T: RealNumber>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
|
||||||
x.lerp(y, a)
|
x.lerp(y, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn quat_mix<T: RealField>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
|
//pub fn quat_mix<T: RealNumber>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
|
||||||
// x * (T::one() - a) + y * a
|
// x * (T::one() - a) + y * a
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/// Interpolate spherically between `x` and `y`.
|
/// Interpolate spherically between `x` and `y`.
|
||||||
pub fn quat_slerp<T: RealField>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
|
pub fn quat_slerp<T: RealNumber>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
|
||||||
Unit::new_normalize(*x)
|
Unit::new_normalize(*x)
|
||||||
.slerp(&Unit::new_normalize(*y), a)
|
.slerp(&Unit::new_normalize(*y), a)
|
||||||
.into_inner()
|
.into_inner()
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
use na::RealField;
|
use crate::RealNumber;
|
||||||
|
|
||||||
use crate::aliases::Qua;
|
use crate::aliases::Qua;
|
||||||
|
|
||||||
/// Multiplies two quaternions.
|
/// Multiplies two quaternions.
|
||||||
pub fn quat_cross<T: RealField>(q1: &Qua<T>, q2: &Qua<T>) -> Qua<T> {
|
pub fn quat_cross<T: RealNumber>(q1: &Qua<T>, q2: &Qua<T>) -> Qua<T> {
|
||||||
q1 * q2
|
q1 * q2
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The scalar product of two quaternions.
|
/// The scalar product of two quaternions.
|
||||||
pub fn quat_dot<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> T {
|
pub fn quat_dot<T: RealNumber>(x: &Qua<T>, y: &Qua<T>) -> T {
|
||||||
x.dot(y)
|
x.dot(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The magnitude of the quaternion `q`.
|
/// The magnitude of the quaternion `q`.
|
||||||
pub fn quat_length<T: RealField>(q: &Qua<T>) -> T {
|
pub fn quat_length<T: RealNumber>(q: &Qua<T>) -> T {
|
||||||
q.norm()
|
q.norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The magnitude of the quaternion `q`.
|
/// The magnitude of the quaternion `q`.
|
||||||
pub fn quat_magnitude<T: RealField>(q: &Qua<T>) -> T {
|
pub fn quat_magnitude<T: RealNumber>(q: &Qua<T>) -> T {
|
||||||
q.norm()
|
q.norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Normalizes the quaternion `q`.
|
/// Normalizes the quaternion `q`.
|
||||||
pub fn quat_normalize<T: RealField>(q: &Qua<T>) -> Qua<T> {
|
pub fn quat_normalize<T: RealNumber>(q: &Qua<T>) -> Qua<T> {
|
||||||
q.normalize()
|
q.normalize()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,22 @@
|
||||||
use na::RealField;
|
|
||||||
|
|
||||||
use crate::aliases::{Qua, TVec};
|
use crate::aliases::{Qua, TVec};
|
||||||
|
use crate::RealNumber;
|
||||||
|
|
||||||
/// Component-wise equality comparison between two quaternions.
|
/// Component-wise equality comparison between two quaternions.
|
||||||
pub fn quat_equal<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
pub fn quat_equal<T: RealNumber>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
||||||
crate::equal(&x.coords, &y.coords)
|
crate::equal(&x.coords, &y.coords)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise approximate equality comparison between two quaternions.
|
/// Component-wise approximate equality comparison between two quaternions.
|
||||||
pub fn quat_equal_eps<T: RealField>(x: &Qua<T>, y: &Qua<T>, epsilon: T) -> TVec<bool, 4> {
|
pub fn quat_equal_eps<T: RealNumber>(x: &Qua<T>, y: &Qua<T>, epsilon: T) -> TVec<bool, 4> {
|
||||||
crate::equal_eps(&x.coords, &y.coords, epsilon)
|
crate::equal_eps(&x.coords, &y.coords, epsilon)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise non-equality comparison between two quaternions.
|
/// Component-wise non-equality comparison between two quaternions.
|
||||||
pub fn quat_not_equal<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
pub fn quat_not_equal<T: RealNumber>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
||||||
crate::not_equal(&x.coords, &y.coords)
|
crate::not_equal(&x.coords, &y.coords)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise approximate non-equality comparison between two quaternions.
|
/// Component-wise approximate non-equality comparison between two quaternions.
|
||||||
pub fn quat_not_equal_eps<T: RealField>(x: &Qua<T>, y: &Qua<T>, epsilon: T) -> TVec<bool, 4> {
|
pub fn quat_not_equal_eps<T: RealNumber>(x: &Qua<T>, y: &Qua<T>, epsilon: T) -> TVec<bool, 4> {
|
||||||
crate::not_equal_eps(&x.coords, &y.coords, epsilon)
|
crate::not_equal_eps(&x.coords, &y.coords, epsilon)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,28 @@
|
||||||
use na::{RealField, Unit, UnitQuaternion};
|
use na::{Unit, UnitQuaternion};
|
||||||
|
|
||||||
use crate::aliases::{Qua, TVec3};
|
use crate::aliases::{Qua, TVec3};
|
||||||
|
use crate::RealNumber;
|
||||||
|
|
||||||
/// Computes the quaternion exponential.
|
/// Computes the quaternion exponential.
|
||||||
pub fn quat_exp<T: RealField>(q: &Qua<T>) -> Qua<T> {
|
pub fn quat_exp<T: RealNumber>(q: &Qua<T>) -> Qua<T> {
|
||||||
q.exp()
|
q.exp()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the quaternion logarithm.
|
/// Computes the quaternion logarithm.
|
||||||
pub fn quat_log<T: RealField>(q: &Qua<T>) -> Qua<T> {
|
pub fn quat_log<T: RealNumber>(q: &Qua<T>) -> Qua<T> {
|
||||||
q.ln()
|
q.ln()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Raises the quaternion `q` to the power `y`.
|
/// Raises the quaternion `q` to the power `y`.
|
||||||
pub fn quat_pow<T: RealField>(q: &Qua<T>, y: T) -> Qua<T> {
|
pub fn quat_pow<T: RealNumber>(q: &Qua<T>, y: T) -> Qua<T> {
|
||||||
q.powf(y)
|
q.powf(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a quaternion from an axis and an angle, and right-multiply it to the quaternion `q`.
|
/// Builds a quaternion from an axis and an angle, and right-multiply it to the quaternion `q`.
|
||||||
pub fn quat_rotate<T: RealField>(q: &Qua<T>, angle: T, axis: &TVec3<T>) -> Qua<T> {
|
pub fn quat_rotate<T: RealNumber>(q: &Qua<T>, angle: T, axis: &TVec3<T>) -> Qua<T> {
|
||||||
q * UnitQuaternion::from_axis_angle(&Unit::new_normalize(*axis), angle).into_inner()
|
q * UnitQuaternion::from_axis_angle(&Unit::new_normalize(*axis), angle).into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn quat_sqrt<T: RealField>(q: &Qua<T>) -> Qua<T> {
|
//pub fn quat_sqrt<T: RealNumber>(q: &Qua<T>) -> Qua<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
use na::{RealField, Unit, UnitQuaternion};
|
use na::{Unit, UnitQuaternion};
|
||||||
|
|
||||||
use crate::aliases::{Qua, TVec3};
|
use crate::aliases::{Qua, TVec3};
|
||||||
|
use crate::RealNumber;
|
||||||
|
|
||||||
/// The rotation angle of this quaternion assumed to be normalized.
|
/// The rotation angle of this quaternion assumed to be normalized.
|
||||||
pub fn quat_angle<T: RealField>(x: &Qua<T>) -> T {
|
pub fn quat_angle<T: RealNumber>(x: &Qua<T>) -> T {
|
||||||
UnitQuaternion::from_quaternion(*x).angle()
|
UnitQuaternion::from_quaternion(*x).angle()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a quaternion from an axis and an angle.
|
/// Creates a quaternion from an axis and an angle.
|
||||||
pub fn quat_angle_axis<T: RealField>(angle: T, axis: &TVec3<T>) -> Qua<T> {
|
pub fn quat_angle_axis<T: RealNumber>(angle: T, axis: &TVec3<T>) -> Qua<T> {
|
||||||
UnitQuaternion::from_axis_angle(&Unit::new_normalize(*axis), angle).into_inner()
|
UnitQuaternion::from_axis_angle(&Unit::new_normalize(*axis), angle).into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The rotation axis of a quaternion assumed to be normalized.
|
/// The rotation axis of a quaternion assumed to be normalized.
|
||||||
pub fn quat_axis<T: RealField>(x: &Qua<T>) -> TVec3<T> {
|
pub fn quat_axis<T: RealNumber>(x: &Qua<T>) -> TVec3<T> {
|
||||||
if let Some(a) = UnitQuaternion::from_quaternion(*x).axis() {
|
if let Some(a) = UnitQuaternion::from_quaternion(*x).axis() {
|
||||||
a.into_inner()
|
a.into_inner()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
use crate::RealNumber;
|
||||||
use approx::AbsDiffEq;
|
use approx::AbsDiffEq;
|
||||||
use na::RealField;
|
|
||||||
|
|
||||||
/// Default epsilon value used for approximate comparison.
|
/// Default epsilon value used for approximate comparison.
|
||||||
pub fn epsilon<T: AbsDiffEq<Epsilon = T>>() -> T {
|
pub fn epsilon<T: AbsDiffEq<Epsilon = T>>() -> T {
|
||||||
|
@ -22,6 +22,6 @@ pub fn epsilon<T: AbsDiffEq<Epsilon = T>>() -> T {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn pi<T: RealField>() -> T {
|
pub fn pi<T: RealNumber>() -> T {
|
||||||
T::pi()
|
T::pi()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use na::RealField;
|
use crate::RealNumber;
|
||||||
|
|
||||||
use crate::aliases::{TVec, TVec3};
|
use crate::aliases::{TVec, TVec3};
|
||||||
use crate::traits::Number;
|
use crate::traits::Number;
|
||||||
|
@ -13,7 +13,7 @@ pub fn cross<T: Number>(x: &TVec3<T>, y: &TVec3<T>) -> TVec3<T> {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`distance2`](fn.distance2.html)
|
/// * [`distance2`](fn.distance2.html)
|
||||||
pub fn distance<T: RealField, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
|
pub fn distance<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
|
||||||
(p1 - p0).norm()
|
(p1 - p0).norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ pub fn faceforward<T: Number, const D: usize>(
|
||||||
/// * [`length2`](fn.length2.html)
|
/// * [`length2`](fn.length2.html)
|
||||||
/// * [`magnitude`](fn.magnitude.html)
|
/// * [`magnitude`](fn.magnitude.html)
|
||||||
/// * [`magnitude2`](fn.magnitude2.html)
|
/// * [`magnitude2`](fn.magnitude2.html)
|
||||||
pub fn length<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
|
pub fn length<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
x.norm()
|
x.norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,12 +57,12 @@ pub fn length<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
/// * [`length`](fn.length.html)
|
/// * [`length`](fn.length.html)
|
||||||
/// * [`magnitude2`](fn.magnitude2.html)
|
/// * [`magnitude2`](fn.magnitude2.html)
|
||||||
/// * [`nalgebra::norm`](../nalgebra/fn.norm.html)
|
/// * [`nalgebra::norm`](../nalgebra/fn.norm.html)
|
||||||
pub fn magnitude<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
|
pub fn magnitude<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
x.norm()
|
x.norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Normalizes a vector.
|
/// Normalizes a vector.
|
||||||
pub fn normalize<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn normalize<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.normalize()
|
x.normalize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ pub fn reflect_vec<T: Number, const D: usize>(i: &TVec<T, D>, n: &TVec<T, D>) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For the incident vector `i` and surface normal `n`, and the ratio of indices of refraction `eta`, return the refraction vector.
|
/// For the incident vector `i` and surface normal `n`, and the ratio of indices of refraction `eta`, return the refraction vector.
|
||||||
pub fn refract_vec<T: RealField, const D: usize>(
|
pub fn refract_vec<T: RealNumber, const D: usize>(
|
||||||
i: &TVec<T, D>,
|
i: &TVec<T, D>,
|
||||||
n: &TVec<T, D>,
|
n: &TVec<T, D>,
|
||||||
eta: T,
|
eta: T,
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
use na::{self, RealField};
|
use crate::RealNumber;
|
||||||
|
use na;
|
||||||
|
|
||||||
/// The Euler constant.
|
/// The Euler constant.
|
||||||
///
|
///
|
||||||
/// This is a shorthand alias for [`euler`](fn.euler.html).
|
/// This is a shorthand alias for [`euler`](fn.euler.html).
|
||||||
pub fn e<T: RealField>() -> T {
|
pub fn e<T: RealNumber>() -> T {
|
||||||
T::e()
|
T::e()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The Euler constant.
|
/// The Euler constant.
|
||||||
pub fn euler<T: RealField>() -> T {
|
pub fn euler<T: RealNumber>() -> T {
|
||||||
T::e()
|
T::e()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,12 +29,12 @@ pub fn euler<T: RealField>() -> T {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn four_over_pi<T: RealField>() -> T {
|
pub fn four_over_pi<T: RealNumber>() -> T {
|
||||||
na::convert::<_, T>(4.0) / T::pi()
|
na::convert::<_, T>(4.0) / T::pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the golden ratio.
|
/// Returns the golden ratio.
|
||||||
pub fn golden_ratio<T: RealField>() -> T {
|
pub fn golden_ratio<T: RealNumber>() -> T {
|
||||||
(T::one() + root_five()) / na::convert(2.0)
|
(T::one() + root_five()) / na::convert(2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ pub fn golden_ratio<T: RealField>() -> T {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn half_pi<T: RealField>() -> T {
|
pub fn half_pi<T: RealNumber>() -> T {
|
||||||
T::frac_pi_2()
|
T::frac_pi_2()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +64,7 @@ pub fn half_pi<T: RealField>() -> T {
|
||||||
///
|
///
|
||||||
/// * [`ln_ten`](fn.ln_ten.html)
|
/// * [`ln_ten`](fn.ln_ten.html)
|
||||||
/// * [`ln_two`](fn.ln_two.html)
|
/// * [`ln_two`](fn.ln_two.html)
|
||||||
pub fn ln_ln_two<T: RealField>() -> T {
|
pub fn ln_ln_two<T: RealNumber>() -> T {
|
||||||
T::ln_2().ln()
|
T::ln_2().ln()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +74,7 @@ pub fn ln_ln_two<T: RealField>() -> T {
|
||||||
///
|
///
|
||||||
/// * [`ln_ln_two`](fn.ln_ln_two.html)
|
/// * [`ln_ln_two`](fn.ln_ln_two.html)
|
||||||
/// * [`ln_two`](fn.ln_two.html)
|
/// * [`ln_two`](fn.ln_two.html)
|
||||||
pub fn ln_ten<T: RealField>() -> T {
|
pub fn ln_ten<T: RealNumber>() -> T {
|
||||||
T::ln_10()
|
T::ln_10()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +84,7 @@ pub fn ln_ten<T: RealField>() -> T {
|
||||||
///
|
///
|
||||||
/// * [`ln_ln_two`](fn.ln_ln_two.html)
|
/// * [`ln_ln_two`](fn.ln_ln_two.html)
|
||||||
/// * [`ln_ten`](fn.ln_ten.html)
|
/// * [`ln_ten`](fn.ln_ten.html)
|
||||||
pub fn ln_two<T: RealField>() -> T {
|
pub fn ln_two<T: RealNumber>() -> T {
|
||||||
T::ln_2()
|
T::ln_2()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,12 +107,12 @@ pub use na::one;
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn one_over_pi<T: RealField>() -> T {
|
pub fn one_over_pi<T: RealNumber>() -> T {
|
||||||
T::frac_1_pi()
|
T::frac_1_pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `1 / sqrt(2)`.
|
/// Returns `1 / sqrt(2)`.
|
||||||
pub fn one_over_root_two<T: RealField>() -> T {
|
pub fn one_over_root_two<T: RealNumber>() -> T {
|
||||||
T::one() / root_two()
|
T::one() / root_two()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +132,7 @@ pub fn one_over_root_two<T: RealField>() -> T {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn one_over_two_pi<T: RealField>() -> T {
|
pub fn one_over_two_pi<T: RealNumber>() -> T {
|
||||||
T::frac_1_pi() * na::convert(0.5)
|
T::frac_1_pi() * na::convert(0.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +152,7 @@ pub fn one_over_two_pi<T: RealField>() -> T {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn quarter_pi<T: RealField>() -> T {
|
pub fn quarter_pi<T: RealNumber>() -> T {
|
||||||
T::frac_pi_4()
|
T::frac_pi_4()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +162,7 @@ pub fn quarter_pi<T: RealField>() -> T {
|
||||||
///
|
///
|
||||||
/// * [`root_three`](fn.root_three.html)
|
/// * [`root_three`](fn.root_three.html)
|
||||||
/// * [`root_two`](fn.root_two.html)
|
/// * [`root_two`](fn.root_two.html)
|
||||||
pub fn root_five<T: RealField>() -> T {
|
pub fn root_five<T: RealNumber>() -> T {
|
||||||
na::convert::<_, T>(5.0).sqrt()
|
na::convert::<_, T>(5.0).sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,12 +182,12 @@ pub fn root_five<T: RealField>() -> T {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn root_half_pi<T: RealField>() -> T {
|
pub fn root_half_pi<T: RealNumber>() -> T {
|
||||||
(T::pi() / na::convert(2.0)).sqrt()
|
(T::pi() / na::convert(2.0)).sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `sqrt(ln(4))`.
|
/// Returns `sqrt(ln(4))`.
|
||||||
pub fn root_ln_four<T: RealField>() -> T {
|
pub fn root_ln_four<T: RealNumber>() -> T {
|
||||||
na::convert::<_, T>(4.0).ln().sqrt()
|
na::convert::<_, T>(4.0).ln().sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,7 +207,7 @@ pub fn root_ln_four<T: RealField>() -> T {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn root_pi<T: RealField>() -> T {
|
pub fn root_pi<T: RealNumber>() -> T {
|
||||||
T::pi().sqrt()
|
T::pi().sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +217,7 @@ pub fn root_pi<T: RealField>() -> T {
|
||||||
///
|
///
|
||||||
/// * [`root_five`](fn.root_five.html)
|
/// * [`root_five`](fn.root_five.html)
|
||||||
/// * [`root_two`](fn.root_two.html)
|
/// * [`root_two`](fn.root_two.html)
|
||||||
pub fn root_three<T: RealField>() -> T {
|
pub fn root_three<T: RealNumber>() -> T {
|
||||||
na::convert::<_, T>(3.0).sqrt()
|
na::convert::<_, T>(3.0).sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,8 +227,8 @@ pub fn root_three<T: RealField>() -> T {
|
||||||
///
|
///
|
||||||
/// * [`root_five`](fn.root_five.html)
|
/// * [`root_five`](fn.root_five.html)
|
||||||
/// * [`root_three`](fn.root_three.html)
|
/// * [`root_three`](fn.root_three.html)
|
||||||
pub fn root_two<T: RealField>() -> T {
|
pub fn root_two<T: RealNumber>() -> T {
|
||||||
// TODO: there should be a crate::sqrt_2() on the RealField trait.
|
// TODO: there should be a crate::sqrt_2() on the RealNumber trait.
|
||||||
na::convert::<_, T>(2.0).sqrt()
|
na::convert::<_, T>(2.0).sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,7 +248,7 @@ pub fn root_two<T: RealField>() -> T {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn root_two_pi<T: RealField>() -> T {
|
pub fn root_two_pi<T: RealNumber>() -> T {
|
||||||
T::two_pi().sqrt()
|
T::two_pi().sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +257,7 @@ pub fn root_two_pi<T: RealField>() -> T {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`two_thirds`](fn.two_thirds.html)
|
/// * [`two_thirds`](fn.two_thirds.html)
|
||||||
pub fn third<T: RealField>() -> T {
|
pub fn third<T: RealNumber>() -> T {
|
||||||
na::convert(1.0 / 3.0)
|
na::convert(1.0 / 3.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +277,7 @@ pub fn third<T: RealField>() -> T {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn three_over_two_pi<T: RealField>() -> T {
|
pub fn three_over_two_pi<T: RealNumber>() -> T {
|
||||||
na::convert::<_, T>(3.0) / T::two_pi()
|
na::convert::<_, T>(3.0) / T::two_pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +296,7 @@ pub fn three_over_two_pi<T: RealField>() -> T {
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn two_over_pi<T: RealField>() -> T {
|
pub fn two_over_pi<T: RealNumber>() -> T {
|
||||||
T::frac_2_pi()
|
T::frac_2_pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +316,7 @@ pub fn two_over_pi<T: RealField>() -> T {
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn two_over_root_pi<T: RealField>() -> T {
|
pub fn two_over_root_pi<T: RealNumber>() -> T {
|
||||||
T::frac_2_sqrt_pi()
|
T::frac_2_sqrt_pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +336,7 @@ pub fn two_over_root_pi<T: RealField>() -> T {
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
pub fn two_pi<T: RealField>() -> T {
|
pub fn two_pi<T: RealNumber>() -> T {
|
||||||
T::two_pi()
|
T::two_pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,7 +345,7 @@ pub fn two_pi<T: RealField>() -> T {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`third`](fn.third.html)
|
/// * [`third`](fn.third.html)
|
||||||
pub fn two_thirds<T: RealField>() -> T {
|
pub fn two_thirds<T: RealNumber>() -> T {
|
||||||
na::convert(2.0 / 3.0)
|
na::convert(2.0 / 3.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
use na::RealField;
|
use crate::RealNumber;
|
||||||
|
|
||||||
use crate::aliases::TMat;
|
use crate::aliases::TMat;
|
||||||
|
|
||||||
/// Fast matrix inverse for affine matrix.
|
/// Fast matrix inverse for affine matrix.
|
||||||
pub fn affine_inverse<T: RealField, const D: usize>(m: TMat<T, D, D>) -> TMat<T, D, D> {
|
pub fn affine_inverse<T: RealNumber, const D: usize>(m: TMat<T, D, D>) -> TMat<T, D, D> {
|
||||||
// TODO: this should be optimized.
|
// TODO: this should be optimized.
|
||||||
m.try_inverse().unwrap_or_else(TMat::<_, D, D>::zeros)
|
m.try_inverse().unwrap_or_else(TMat::<_, D, D>::zeros)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the transpose of the inverse of a matrix.
|
/// Compute the transpose of the inverse of a matrix.
|
||||||
pub fn inverse_transpose<T: RealField, const D: usize>(m: TMat<T, D, D>) -> TMat<T, D, D> {
|
pub fn inverse_transpose<T: RealNumber, const D: usize>(m: TMat<T, D, D>) -> TMat<T, D, D> {
|
||||||
m.try_inverse()
|
m.try_inverse()
|
||||||
.unwrap_or_else(TMat::<_, D, D>::zeros)
|
.unwrap_or_else(TMat::<_, D, D>::zeros)
|
||||||
.transpose()
|
.transpose()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use na::{DefaultAllocator, RealField, Scalar, U3, U4};
|
use na::{DefaultAllocator, RealNumber, Scalar, U3, U4};
|
||||||
|
|
||||||
use crate::aliases::*;
|
use crate::aliases::*;
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ pub fn packRGBM<T: Scalar>(rgb: &TVec3<T>) -> TVec4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn packSnorm<I: Scalar, T: RealField, const D: usize>(v: TVec<T, D>) -> TVec<I, D>
|
pub fn packSnorm<I: Scalar, T: RealNumber, const D: usize>(v: TVec<T, D>) -> TVec<I, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Alloc<T, D> + Alloc<I, D>,
|
DefaultAllocator: Alloc<T, D> + Alloc<I, D>,
|
||||||
{
|
{
|
||||||
|
@ -104,7 +104,7 @@ pub fn packUint4x8(v: &U8Vec4) -> i32 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn packUnorm<UI: Scalar, T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<UI, D>
|
pub fn packUnorm<UI: Scalar, T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<UI, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Alloc<T, D> + Alloc<UI, D>,
|
DefaultAllocator: Alloc<T, D> + Alloc<UI, D>,
|
||||||
{
|
{
|
||||||
|
@ -199,7 +199,7 @@ pub fn unpackRGBM<T: Scalar>(rgbm: &TVec4<T>) -> TVec3<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpackSnorm<I: Scalar, T: RealField, const D: usize>(v: &TVec<I, D>) -> TVec<T, D>
|
pub fn unpackSnorm<I: Scalar, T: RealNumber, const D: usize>(v: &TVec<I, D>) -> TVec<T, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Alloc<T, D> + Alloc<I, D>,
|
DefaultAllocator: Alloc<T, D> + Alloc<I, D>,
|
||||||
{
|
{
|
||||||
|
@ -250,7 +250,7 @@ pub fn unpackUint4x8(p: i32) -> U8Vec4 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpackUnorm<UI: Scalar, T: RealField, const D: usize>(v: &TVec<UI, D>) -> TVec<T, D>
|
pub fn unpackUnorm<UI: Scalar, T: RealNumber, const D: usize>(v: &TVec<UI, D>) -> TVec<T, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Alloc<T, D> + Alloc<UI, D>,
|
DefaultAllocator: Alloc<T, D> + Alloc<UI, D>,
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,36 +1,37 @@
|
||||||
use na::{RealField, UnitQuaternion};
|
use na::UnitQuaternion;
|
||||||
|
|
||||||
use crate::aliases::{Qua, TMat4, TVec, TVec3};
|
use crate::aliases::{Qua, TMat4, TVec, TVec3};
|
||||||
|
use crate::RealNumber;
|
||||||
|
|
||||||
/// Euler angles of the quaternion `q` as (pitch, yaw, roll).
|
/// Euler angles of the quaternion `q` as (pitch, yaw, roll).
|
||||||
pub fn quat_euler_angles<T: RealField>(x: &Qua<T>) -> TVec3<T> {
|
pub fn quat_euler_angles<T: RealNumber>(x: &Qua<T>) -> TVec3<T> {
|
||||||
let q = UnitQuaternion::new_unchecked(*x);
|
let q = UnitQuaternion::new_unchecked(*x);
|
||||||
let a = q.euler_angles();
|
let a = q.euler_angles();
|
||||||
TVec3::new(a.2, a.1, a.0)
|
TVec3::new(a.2, a.1, a.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise `>` comparison between two quaternions.
|
/// Component-wise `>` comparison between two quaternions.
|
||||||
pub fn quat_greater_than<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
pub fn quat_greater_than<T: RealNumber>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
||||||
crate::greater_than(&x.coords, &y.coords)
|
crate::greater_than(&x.coords, &y.coords)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise `>=` comparison between two quaternions.
|
/// Component-wise `>=` comparison between two quaternions.
|
||||||
pub fn quat_greater_than_equal<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
pub fn quat_greater_than_equal<T: RealNumber>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
||||||
crate::greater_than_equal(&x.coords, &y.coords)
|
crate::greater_than_equal(&x.coords, &y.coords)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise `<` comparison between two quaternions.
|
/// Component-wise `<` comparison between two quaternions.
|
||||||
pub fn quat_less_than<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
pub fn quat_less_than<T: RealNumber>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
||||||
crate::less_than(&x.coords, &y.coords)
|
crate::less_than(&x.coords, &y.coords)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise `<=` comparison between two quaternions.
|
/// Component-wise `<=` comparison between two quaternions.
|
||||||
pub fn quat_less_than_equal<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
pub fn quat_less_than_equal<T: RealNumber>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
||||||
crate::less_than_equal(&x.coords, &y.coords)
|
crate::less_than_equal(&x.coords, &y.coords)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a quaternion to a rotation matrix in homogeneous coordinates.
|
/// Convert a quaternion to a rotation matrix in homogeneous coordinates.
|
||||||
pub fn quat_cast<T: RealField>(x: &Qua<T>) -> TMat4<T> {
|
pub fn quat_cast<T: RealNumber>(x: &Qua<T>) -> TMat4<T> {
|
||||||
crate::quat_to_mat4(x)
|
crate::quat_to_mat4(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,34 +42,34 @@ pub fn quat_cast<T: RealField>(x: &Qua<T>) -> TMat4<T> {
|
||||||
/// * `direction` - Direction vector point at where to look
|
/// * `direction` - Direction vector point at where to look
|
||||||
/// * `up` - Object up vector
|
/// * `up` - Object up vector
|
||||||
///
|
///
|
||||||
pub fn quat_look_at<T: RealField>(direction: &TVec3<T>, up: &TVec3<T>) -> Qua<T> {
|
pub fn quat_look_at<T: RealNumber>(direction: &TVec3<T>, up: &TVec3<T>) -> Qua<T> {
|
||||||
quat_look_at_rh(direction, up)
|
quat_look_at_rh(direction, up)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes a left-handed look-at quaternion (equivalent to a left-handed look-at matrix).
|
/// Computes a left-handed look-at quaternion (equivalent to a left-handed look-at matrix).
|
||||||
pub fn quat_look_at_lh<T: RealField>(direction: &TVec3<T>, up: &TVec3<T>) -> Qua<T> {
|
pub fn quat_look_at_lh<T: RealNumber>(direction: &TVec3<T>, up: &TVec3<T>) -> Qua<T> {
|
||||||
UnitQuaternion::look_at_lh(direction, up).into_inner()
|
UnitQuaternion::look_at_lh(direction, up).into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes a right-handed look-at quaternion (equivalent to a right-handed look-at matrix).
|
/// Computes a right-handed look-at quaternion (equivalent to a right-handed look-at matrix).
|
||||||
pub fn quat_look_at_rh<T: RealField>(direction: &TVec3<T>, up: &TVec3<T>) -> Qua<T> {
|
pub fn quat_look_at_rh<T: RealNumber>(direction: &TVec3<T>, up: &TVec3<T>) -> Qua<T> {
|
||||||
UnitQuaternion::look_at_rh(direction, up).into_inner()
|
UnitQuaternion::look_at_rh(direction, up).into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The "roll" Euler angle of the quaternion `x` assumed to be normalized.
|
/// The "roll" Euler angle of the quaternion `x` assumed to be normalized.
|
||||||
pub fn quat_roll<T: RealField>(x: &Qua<T>) -> T {
|
pub fn quat_roll<T: RealNumber>(x: &Qua<T>) -> T {
|
||||||
// TODO: optimize this.
|
// TODO: optimize this.
|
||||||
quat_euler_angles(x).z
|
quat_euler_angles(x).z
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The "yaw" Euler angle of the quaternion `x` assumed to be normalized.
|
/// The "yaw" Euler angle of the quaternion `x` assumed to be normalized.
|
||||||
pub fn quat_yaw<T: RealField>(x: &Qua<T>) -> T {
|
pub fn quat_yaw<T: RealNumber>(x: &Qua<T>) -> T {
|
||||||
// TODO: optimize this.
|
// TODO: optimize this.
|
||||||
quat_euler_angles(x).y
|
quat_euler_angles(x).y
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The "pitch" Euler angle of the quaternion `x` assumed to be normalized.
|
/// The "pitch" Euler angle of the quaternion `x` assumed to be normalized.
|
||||||
pub fn quat_pitch<T: RealField>(x: &Qua<T>) -> T {
|
pub fn quat_pitch<T: RealNumber>(x: &Qua<T>) -> T {
|
||||||
// TODO: optimize this.
|
// TODO: optimize this.
|
||||||
quat_euler_angles(x).x
|
quat_euler_angles(x).x
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use na::{DefaultAllocator, RealField, Scalar, U3};
|
use na::{DefaultAllocator, RealNumber, Scalar, U3};
|
||||||
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use crate::traits::{Alloc, Dimension, Number};
|
use crate::traits::{Alloc, Dimension, Number};
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use na::{Quaternion, RealField, Scalar};
|
use na::{Quaternion, Scalar};
|
||||||
|
|
||||||
use crate::aliases::{
|
use crate::aliases::{
|
||||||
Qua, TMat, TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3, TVec1,
|
Qua, TMat, TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3, TVec1,
|
||||||
TVec2, TVec3, TVec4,
|
TVec2, TVec3, TVec4,
|
||||||
};
|
};
|
||||||
use crate::traits::Number;
|
use crate::traits::{Number, RealNumber};
|
||||||
|
|
||||||
/// Creates a 2x2 matrix from a slice arranged in column-major order.
|
/// Creates a 2x2 matrix from a slice arranged in column-major order.
|
||||||
pub fn make_mat2<T: Scalar>(ptr: &[T]) -> TMat2<T> {
|
pub fn make_mat2<T: Scalar>(ptr: &[T]) -> TMat2<T> {
|
||||||
|
@ -76,12 +76,7 @@ pub fn mat2_to_mat3<T: Number>(m: &TMat2<T>) -> TMat3<T> {
|
||||||
|
|
||||||
/// Converts a 3x3 matrix to a 2x2 matrix.
|
/// Converts a 3x3 matrix to a 2x2 matrix.
|
||||||
pub fn mat3_to_mat2<T: Scalar>(m: &TMat3<T>) -> TMat2<T> {
|
pub fn mat3_to_mat2<T: Scalar>(m: &TMat3<T>) -> TMat2<T> {
|
||||||
TMat2::new(
|
TMat2::new(m.m11.clone(), m.m12.clone(), m.m21.clone(), m.m22.clone())
|
||||||
m.m11.inlined_clone(),
|
|
||||||
m.m12.inlined_clone(),
|
|
||||||
m.m21.inlined_clone(),
|
|
||||||
m.m22.inlined_clone(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a 3x3 matrix to a 4x4 matrix.
|
/// Converts a 3x3 matrix to a 4x4 matrix.
|
||||||
|
@ -97,15 +92,15 @@ pub fn mat3_to_mat4<T: Number>(m: &TMat3<T>) -> TMat4<T> {
|
||||||
/// Converts a 4x4 matrix to a 3x3 matrix.
|
/// Converts a 4x4 matrix to a 3x3 matrix.
|
||||||
pub fn mat4_to_mat3<T: Scalar>(m: &TMat4<T>) -> TMat3<T> {
|
pub fn mat4_to_mat3<T: Scalar>(m: &TMat4<T>) -> TMat3<T> {
|
||||||
TMat3::new(
|
TMat3::new(
|
||||||
m.m11.inlined_clone(),
|
m.m11.clone(),
|
||||||
m.m12.inlined_clone(),
|
m.m12.clone(),
|
||||||
m.m13.inlined_clone(),
|
m.m13.clone(),
|
||||||
m.m21.inlined_clone(),
|
m.m21.clone(),
|
||||||
m.m22.inlined_clone(),
|
m.m22.clone(),
|
||||||
m.m23.inlined_clone(),
|
m.m23.clone(),
|
||||||
m.m31.inlined_clone(),
|
m.m31.clone(),
|
||||||
m.m32.inlined_clone(),
|
m.m32.clone(),
|
||||||
m.m33.inlined_clone(),
|
m.m33.clone(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,16 +116,11 @@ pub fn mat2_to_mat4<T: Number>(m: &TMat2<T>) -> TMat4<T> {
|
||||||
|
|
||||||
/// Converts a 4x4 matrix to a 2x2 matrix.
|
/// Converts a 4x4 matrix to a 2x2 matrix.
|
||||||
pub fn mat4_to_mat2<T: Scalar>(m: &TMat4<T>) -> TMat2<T> {
|
pub fn mat4_to_mat2<T: Scalar>(m: &TMat4<T>) -> TMat2<T> {
|
||||||
TMat2::new(
|
TMat2::new(m.m11.clone(), m.m12.clone(), m.m21.clone(), m.m22.clone())
|
||||||
m.m11.inlined_clone(),
|
|
||||||
m.m12.inlined_clone(),
|
|
||||||
m.m21.inlined_clone(),
|
|
||||||
m.m22.inlined_clone(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a quaternion from a slice arranged as `[x, y, z, w]`.
|
/// Creates a quaternion from a slice arranged as `[x, y, z, w]`.
|
||||||
pub fn make_quat<T: RealField>(ptr: &[T]) -> Qua<T> {
|
pub fn make_quat<T: RealNumber>(ptr: &[T]) -> Qua<T> {
|
||||||
Quaternion::from(TVec4::from_column_slice(ptr))
|
Quaternion::from(TVec4::from_column_slice(ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +146,7 @@ pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> {
|
||||||
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
||||||
pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
|
pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
|
||||||
TVec1::new(v.x.inlined_clone())
|
TVec1::new(v.x.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 1D vector from another vector.
|
/// Creates a 1D vector from another vector.
|
||||||
|
@ -170,7 +160,7 @@ pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
|
||||||
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
||||||
pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
|
pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
|
||||||
TVec1::new(v.x.inlined_clone())
|
TVec1::new(v.x.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 1D vector from another vector.
|
/// Creates a 1D vector from another vector.
|
||||||
|
@ -184,7 +174,7 @@ pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
|
||||||
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
||||||
pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
|
pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
|
||||||
TVec1::new(v.x.inlined_clone())
|
TVec1::new(v.x.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 2D vector from another vector.
|
/// Creates a 2D vector from another vector.
|
||||||
|
@ -200,7 +190,7 @@ pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
||||||
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
||||||
pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> {
|
pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> {
|
||||||
TVec2::new(v.x.inlined_clone(), T::zero())
|
TVec2::new(v.x.clone(), T::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 2D vector from another vector.
|
/// Creates a 2D vector from another vector.
|
||||||
|
@ -229,7 +219,7 @@ pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> {
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
||||||
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
||||||
pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> {
|
pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> {
|
||||||
TVec2::new(v.x.inlined_clone(), v.y.inlined_clone())
|
TVec2::new(v.x.clone(), v.y.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 2D vector from another vector.
|
/// Creates a 2D vector from another vector.
|
||||||
|
@ -243,7 +233,7 @@ pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> {
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
||||||
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
||||||
pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> {
|
pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> {
|
||||||
TVec2::new(v.x.inlined_clone(), v.y.inlined_clone())
|
TVec2::new(v.x.clone(), v.y.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 2D vector from a slice.
|
/// Creates a 2D vector from a slice.
|
||||||
|
@ -269,7 +259,7 @@ pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> {
|
||||||
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
||||||
pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> {
|
pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> {
|
||||||
TVec3::new(v.x.inlined_clone(), T::zero(), T::zero())
|
TVec3::new(v.x.clone(), T::zero(), T::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 3D vector from another vector.
|
/// Creates a 3D vector from another vector.
|
||||||
|
@ -285,7 +275,7 @@ pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> {
|
||||||
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
||||||
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
||||||
pub fn vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> {
|
pub fn vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> {
|
||||||
TVec3::new(v.x.inlined_clone(), v.y.inlined_clone(), T::zero())
|
TVec3::new(v.x.clone(), v.y.clone(), T::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 3D vector from another vector.
|
/// Creates a 3D vector from another vector.
|
||||||
|
@ -313,11 +303,7 @@ pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> {
|
||||||
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
||||||
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
||||||
pub fn vec4_to_vec3<T: Scalar>(v: &TVec4<T>) -> TVec3<T> {
|
pub fn vec4_to_vec3<T: Scalar>(v: &TVec4<T>) -> TVec3<T> {
|
||||||
TVec3::new(
|
TVec3::new(v.x.clone(), v.y.clone(), v.z.clone())
|
||||||
v.x.inlined_clone(),
|
|
||||||
v.y.inlined_clone(),
|
|
||||||
v.z.inlined_clone(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 3D vector from another vector.
|
/// Creates a 3D vector from another vector.
|
||||||
|
|
|
@ -1,163 +1,163 @@
|
||||||
use na::{RealField, U3, U4};
|
use na::{RealNumber, U3, U4};
|
||||||
|
|
||||||
use crate::aliases::{TMat, TVec};
|
use crate::aliases::{TMat, TVec};
|
||||||
|
|
||||||
pub fn derivedEulerAngleX<T: RealField>(angleX: T, angularVelocityX: T) -> TMat4<T> {
|
pub fn derivedEulerAngleX<T: RealNumber>(angleX: T, angularVelocityX: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn derivedEulerAngleY<T: RealField>(angleY: T, angularVelocityY: T) -> TMat4<T> {
|
pub fn derivedEulerAngleY<T: RealNumber>(angleY: T, angularVelocityY: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn derivedEulerAngleZ<T: RealField>(angleZ: T, angularVelocityZ: T) -> TMat4<T> {
|
pub fn derivedEulerAngleZ<T: RealNumber>(angleZ: T, angularVelocityZ: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleX<T: RealField>(angleX: T) -> TMat4<T> {
|
pub fn eulerAngleX<T: RealNumber>(angleX: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXY<T: RealField>(angleX: T, angleY: T) -> TMat4<T> {
|
pub fn eulerAngleXY<T: RealNumber>(angleX: T, angleY: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXYX<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
pub fn eulerAngleXYX<T: RealNumber>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXYZ<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
pub fn eulerAngleXYZ<T: RealNumber>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXZ<T: RealField>(angleX: T, angleZ: T) -> TMat4<T> {
|
pub fn eulerAngleXZ<T: RealNumber>(angleX: T, angleZ: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXZX<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
pub fn eulerAngleXZX<T: RealNumber>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXZY<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
pub fn eulerAngleXZY<T: RealNumber>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleY<T: RealField>(angleY: T) -> TMat4<T> {
|
pub fn eulerAngleY<T: RealNumber>(angleY: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYX<T: RealField>(angleY: T, angleX: T) -> TMat4<T> {
|
pub fn eulerAngleYX<T: RealNumber>(angleY: T, angleX: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYXY<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
pub fn eulerAngleYXY<T: RealNumber>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYXZ<T: RealField>(yaw: T, pitch: T, roll: T) -> TMat4<T> {
|
pub fn eulerAngleYXZ<T: RealNumber>(yaw: T, pitch: T, roll: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYZ<T: RealField>(angleY: T, angleZ: T) -> TMat4<T> {
|
pub fn eulerAngleYZ<T: RealNumber>(angleY: T, angleZ: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYZX<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
pub fn eulerAngleYZX<T: RealNumber>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYZY<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
pub fn eulerAngleYZY<T: RealNumber>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZ<T: RealField>(angleZ: T) -> TMat4<T> {
|
pub fn eulerAngleZ<T: RealNumber>(angleZ: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZX<T: RealField>(angle: T, angleX: T) -> TMat4<T> {
|
pub fn eulerAngleZX<T: RealNumber>(angle: T, angleX: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZXY<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
pub fn eulerAngleZXY<T: RealNumber>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZXZ<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
pub fn eulerAngleZXZ<T: RealNumber>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZY<T: RealField>(angleZ: T, angleY: T) -> TMat4<T> {
|
pub fn eulerAngleZY<T: RealNumber>(angleZ: T, angleY: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZYX<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
pub fn eulerAngleZYX<T: RealNumber>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZYZ<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
pub fn eulerAngleZYZ<T: RealNumber>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleXYX<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
pub fn extractEulerAngleXYX<T: RealNumber>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleXYZ<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
pub fn extractEulerAngleXYZ<T: RealNumber>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleXZX<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
pub fn extractEulerAngleXZX<T: RealNumber>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleXZY<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
pub fn extractEulerAngleXZY<T: RealNumber>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleYXY<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
pub fn extractEulerAngleYXY<T: RealNumber>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleYXZ<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
pub fn extractEulerAngleYXZ<T: RealNumber>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleYZX<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
pub fn extractEulerAngleYZX<T: RealNumber>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleYZY<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
pub fn extractEulerAngleYZY<T: RealNumber>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleZXY<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
pub fn extractEulerAngleZXY<T: RealNumber>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleZXZ<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
pub fn extractEulerAngleZXZ<T: RealNumber>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleZYX<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
pub fn extractEulerAngleZYX<T: RealNumber>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleZYZ<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
pub fn extractEulerAngleZYZ<T: RealNumber>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn orientate2<T: RealField>(angle: T) -> TMat3x3<T> {
|
pub fn orientate2<T: RealNumber>(angle: T) -> TMat3x3<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn orientate3<T: RealField>(angles: TVec3<T>) -> TMat3x3<T> {
|
pub fn orientate3<T: RealNumber>(angles: TVec3<T>) -> TMat3x3<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn orientate4<T: RealField>(angles: TVec3<T>) -> TMat4<T> {
|
pub fn orientate4<T: RealNumber>(angles: TVec3<T>) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn yawPitchRoll<T: RealField>(yaw: T, pitch: T, roll: T) -> TMat4<T> {
|
pub fn yawPitchRoll<T: RealNumber>(yaw: T, pitch: T, roll: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
use na::RealField;
|
|
||||||
|
|
||||||
use crate::aliases::{TMat3, TMat4, TVec3};
|
use crate::aliases::{TMat3, TMat4, TVec3};
|
||||||
|
use crate::RealNumber;
|
||||||
|
|
||||||
/// Builds a 3x3 matrix `m` such that for any `v`: `m * v == cross(x, v)`.
|
/// Builds a 3x3 matrix `m` such that for any `v`: `m * v == cross(x, v)`.
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`matrix_cross`](fn.matrix_cross.html)
|
/// * [`matrix_cross`](fn.matrix_cross.html)
|
||||||
pub fn matrix_cross3<T: RealField>(x: &TVec3<T>) -> TMat3<T> {
|
pub fn matrix_cross3<T: RealNumber>(x: &TVec3<T>) -> TMat3<T> {
|
||||||
x.cross_matrix()
|
x.cross_matrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +15,6 @@ pub fn matrix_cross3<T: RealField>(x: &TVec3<T>) -> TMat3<T> {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`matrix_cross3`](fn.matrix_cross3.html)
|
/// * [`matrix_cross3`](fn.matrix_cross3.html)
|
||||||
pub fn matrix_cross<T: RealField>(x: &TVec3<T>) -> TMat4<T> {
|
pub fn matrix_cross<T: RealNumber>(x: &TVec3<T>) -> TMat4<T> {
|
||||||
crate::mat3_to_mat4(&x.cross_matrix())
|
crate::mat3_to_mat4(&x.cross_matrix())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
use na::RealField;
|
|
||||||
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
|
use crate::RealNumber;
|
||||||
|
|
||||||
/// The squared distance between two points.
|
/// The squared distance between two points.
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`distance`](fn.distance.html)
|
/// * [`distance`](fn.distance.html)
|
||||||
pub fn distance2<T: RealField, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
|
pub fn distance2<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
|
||||||
(p1 - p0).norm_squared()
|
(p1 - p0).norm_squared()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +17,7 @@ pub fn distance2<T: RealField, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>)
|
||||||
/// * [`l1_norm`](fn.l1_norm.html)
|
/// * [`l1_norm`](fn.l1_norm.html)
|
||||||
/// * [`l2_distance`](fn.l2_distance.html)
|
/// * [`l2_distance`](fn.l2_distance.html)
|
||||||
/// * [`l2_norm`](fn.l2_norm.html)
|
/// * [`l2_norm`](fn.l2_norm.html)
|
||||||
pub fn l1_distance<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
pub fn l1_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
||||||
l1_norm(&(y - x))
|
l1_norm(&(y - x))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +31,7 @@ pub fn l1_distance<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>)
|
||||||
/// * [`l1_distance`](fn.l1_distance.html)
|
/// * [`l1_distance`](fn.l1_distance.html)
|
||||||
/// * [`l2_distance`](fn.l2_distance.html)
|
/// * [`l2_distance`](fn.l2_distance.html)
|
||||||
/// * [`l2_norm`](fn.l2_norm.html)
|
/// * [`l2_norm`](fn.l2_norm.html)
|
||||||
pub fn l1_norm<T: RealField, const D: usize>(v: &TVec<T, D>) -> T {
|
pub fn l1_norm<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> T {
|
||||||
crate::comp_add(&v.abs())
|
crate::comp_add(&v.abs())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +49,7 @@ pub fn l1_norm<T: RealField, const D: usize>(v: &TVec<T, D>) -> T {
|
||||||
/// * [`length2`](fn.length2.html)
|
/// * [`length2`](fn.length2.html)
|
||||||
/// * [`magnitude`](fn.magnitude.html)
|
/// * [`magnitude`](fn.magnitude.html)
|
||||||
/// * [`magnitude2`](fn.magnitude2.html)
|
/// * [`magnitude2`](fn.magnitude2.html)
|
||||||
pub fn l2_distance<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
pub fn l2_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
||||||
l2_norm(&(y - x))
|
l2_norm(&(y - x))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +69,7 @@ pub fn l2_distance<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>)
|
||||||
/// * [`length2`](fn.length2.html)
|
/// * [`length2`](fn.length2.html)
|
||||||
/// * [`magnitude`](fn.magnitude.html)
|
/// * [`magnitude`](fn.magnitude.html)
|
||||||
/// * [`magnitude2`](fn.magnitude2.html)
|
/// * [`magnitude2`](fn.magnitude2.html)
|
||||||
pub fn l2_norm<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
|
pub fn l2_norm<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
x.norm()
|
x.norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +84,7 @@ pub fn l2_norm<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
/// * [`length`](fn.length.html)
|
/// * [`length`](fn.length.html)
|
||||||
/// * [`magnitude`](fn.magnitude.html)
|
/// * [`magnitude`](fn.magnitude.html)
|
||||||
/// * [`magnitude2`](fn.magnitude2.html)
|
/// * [`magnitude2`](fn.magnitude2.html)
|
||||||
pub fn length2<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
|
pub fn length2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
x.norm_squared()
|
x.norm_squared()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,14 +99,14 @@ pub fn length2<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
/// * [`length2`](fn.length2.html)
|
/// * [`length2`](fn.length2.html)
|
||||||
/// * [`magnitude`](fn.magnitude.html)
|
/// * [`magnitude`](fn.magnitude.html)
|
||||||
/// * [`nalgebra::norm_squared`](../nalgebra/fn.norm_squared.html)
|
/// * [`nalgebra::norm_squared`](../nalgebra/fn.norm_squared.html)
|
||||||
pub fn magnitude2<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
|
pub fn magnitude2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
x.norm_squared()
|
x.norm_squared()
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn lxNorm<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, unsigned int Depth) -> T {
|
//pub fn lxNorm<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, unsigned int Depth) -> T {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn lxNorm<T: RealField, const D: usize>(x: &TVec<T, D>, unsigned int Depth) -> T {
|
//pub fn lxNorm<T: RealNumber, const D: usize>(x: &TVec<T, D>, unsigned int Depth) -> T {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use na::RealField;
|
use crate::RealNumber;
|
||||||
|
|
||||||
use crate::aliases::TVec3;
|
use crate::aliases::TVec3;
|
||||||
|
|
||||||
/// The normal vector of the given triangle.
|
/// The normal vector of the given triangle.
|
||||||
///
|
///
|
||||||
/// The normal is computed as the normalized vector `cross(p2 - p1, p3 - p1)`.
|
/// The normal is computed as the normalized vector `cross(p2 - p1, p3 - p1)`.
|
||||||
pub fn triangle_normal<T: RealField>(p1: &TVec3<T>, p2: &TVec3<T>, p3: &TVec3<T>) -> TVec3<T> {
|
pub fn triangle_normal<T: RealNumber>(p1: &TVec3<T>, p2: &TVec3<T>, p3: &TVec3<T>) -> TVec3<T> {
|
||||||
(p2 - p1).cross(&(p3 - p1)).normalize()
|
(p2 - p1).cross(&(p3 - p1)).normalize()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use na::RealField;
|
use crate::RealNumber;
|
||||||
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ use crate::aliases::TVec;
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`normalize_dot`](fn.normalize_dot.html`)
|
/// * [`normalize_dot`](fn.normalize_dot.html`)
|
||||||
pub fn fast_normalize_dot<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
pub fn fast_normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
||||||
// XXX: improve those.
|
// XXX: improve those.
|
||||||
x.normalize().dot(&y.normalize())
|
x.normalize().dot(&y.normalize())
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ pub fn fast_normalize_dot<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`fast_normalize_dot`](fn.fast_normalize_dot.html`)
|
/// * [`fast_normalize_dot`](fn.fast_normalize_dot.html`)
|
||||||
pub fn normalize_dot<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
pub fn normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
||||||
// XXX: improve those.
|
// XXX: improve those.
|
||||||
x.normalize().dot(&y.normalize())
|
x.normalize().dot(&y.normalize())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,97 +1,98 @@
|
||||||
use na::{RealField, Rotation3, Unit, UnitQuaternion};
|
use na::{Rotation3, Unit, UnitQuaternion};
|
||||||
|
|
||||||
use crate::aliases::{Qua, TMat3, TMat4, TVec3, TVec4};
|
use crate::aliases::{Qua, TMat3, TMat4, TVec3, TVec4};
|
||||||
|
use crate::RealNumber;
|
||||||
|
|
||||||
/// Rotate the vector `v` by the quaternion `q` assumed to be normalized.
|
/// Rotate the vector `v` by the quaternion `q` assumed to be normalized.
|
||||||
pub fn quat_cross_vec<T: RealField>(q: &Qua<T>, v: &TVec3<T>) -> TVec3<T> {
|
pub fn quat_cross_vec<T: RealNumber>(q: &Qua<T>, v: &TVec3<T>) -> TVec3<T> {
|
||||||
UnitQuaternion::new_unchecked(*q) * v
|
UnitQuaternion::new_unchecked(*q) * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate the vector `v` by the inverse of the quaternion `q` assumed to be normalized.
|
/// Rotate the vector `v` by the inverse of the quaternion `q` assumed to be normalized.
|
||||||
pub fn quat_inv_cross_vec<T: RealField>(v: &TVec3<T>, q: &Qua<T>) -> TVec3<T> {
|
pub fn quat_inv_cross_vec<T: RealNumber>(v: &TVec3<T>, q: &Qua<T>) -> TVec3<T> {
|
||||||
UnitQuaternion::new_unchecked(*q).inverse() * v
|
UnitQuaternion::new_unchecked(*q).inverse() * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The quaternion `w` component.
|
/// The quaternion `w` component.
|
||||||
pub fn quat_extract_real_component<T: RealField>(q: &Qua<T>) -> T {
|
pub fn quat_extract_real_component<T: RealNumber>(q: &Qua<T>) -> T {
|
||||||
q.w
|
q.w
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Normalized linear interpolation between two quaternions.
|
/// Normalized linear interpolation between two quaternions.
|
||||||
pub fn quat_fast_mix<T: RealField>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
|
pub fn quat_fast_mix<T: RealNumber>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
|
||||||
Unit::new_unchecked(*x)
|
Unit::new_unchecked(*x)
|
||||||
.nlerp(&Unit::new_unchecked(*y), a)
|
.nlerp(&Unit::new_unchecked(*y), a)
|
||||||
.into_inner()
|
.into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn quat_intermediate<T: RealField>(prev: &Qua<T>, curr: &Qua<T>, next: &Qua<T>) -> Qua<T> {
|
//pub fn quat_intermediate<T: RealNumber>(prev: &Qua<T>, curr: &Qua<T>, next: &Qua<T>) -> Qua<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/// The squared magnitude of a quaternion `q`.
|
/// The squared magnitude of a quaternion `q`.
|
||||||
pub fn quat_length2<T: RealField>(q: &Qua<T>) -> T {
|
pub fn quat_length2<T: RealNumber>(q: &Qua<T>) -> T {
|
||||||
q.norm_squared()
|
q.norm_squared()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The squared magnitude of a quaternion `q`.
|
/// The squared magnitude of a quaternion `q`.
|
||||||
pub fn quat_magnitude2<T: RealField>(q: &Qua<T>) -> T {
|
pub fn quat_magnitude2<T: RealNumber>(q: &Qua<T>) -> T {
|
||||||
q.norm_squared()
|
q.norm_squared()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The quaternion representing the identity rotation.
|
/// The quaternion representing the identity rotation.
|
||||||
pub fn quat_identity<T: RealField>() -> Qua<T> {
|
pub fn quat_identity<T: RealNumber>() -> Qua<T> {
|
||||||
UnitQuaternion::identity().into_inner()
|
UnitQuaternion::identity().into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotates a vector by a quaternion assumed to be normalized.
|
/// Rotates a vector by a quaternion assumed to be normalized.
|
||||||
pub fn quat_rotate_vec3<T: RealField>(q: &Qua<T>, v: &TVec3<T>) -> TVec3<T> {
|
pub fn quat_rotate_vec3<T: RealNumber>(q: &Qua<T>, v: &TVec3<T>) -> TVec3<T> {
|
||||||
UnitQuaternion::new_unchecked(*q) * v
|
UnitQuaternion::new_unchecked(*q) * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotates a vector in homogeneous coordinates by a quaternion assumed to be normalized.
|
/// Rotates a vector in homogeneous coordinates by a quaternion assumed to be normalized.
|
||||||
pub fn quat_rotate_vec<T: RealField>(q: &Qua<T>, v: &TVec4<T>) -> TVec4<T> {
|
pub fn quat_rotate_vec<T: RealNumber>(q: &Qua<T>, v: &TVec4<T>) -> TVec4<T> {
|
||||||
let rotated = Unit::new_unchecked(*q) * v.fixed_rows::<3>(0);
|
let rotated = Unit::new_unchecked(*q) * v.fixed_rows::<3>(0);
|
||||||
TVec4::new(rotated.x, rotated.y, rotated.z, v.w)
|
TVec4::new(rotated.x, rotated.y, rotated.z, v.w)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The rotation required to align `orig` to `dest`.
|
/// The rotation required to align `orig` to `dest`.
|
||||||
pub fn quat_rotation<T: RealField>(orig: &TVec3<T>, dest: &TVec3<T>) -> Qua<T> {
|
pub fn quat_rotation<T: RealNumber>(orig: &TVec3<T>, dest: &TVec3<T>) -> Qua<T> {
|
||||||
UnitQuaternion::rotation_between(orig, dest)
|
UnitQuaternion::rotation_between(orig, dest)
|
||||||
.unwrap_or_else(UnitQuaternion::identity)
|
.unwrap_or_else(UnitQuaternion::identity)
|
||||||
.into_inner()
|
.into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The spherical linear interpolation between two quaternions.
|
/// The spherical linear interpolation between two quaternions.
|
||||||
pub fn quat_short_mix<T: RealField>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
|
pub fn quat_short_mix<T: RealNumber>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
|
||||||
Unit::new_normalize(*x)
|
Unit::new_normalize(*x)
|
||||||
.slerp(&Unit::new_normalize(*y), a)
|
.slerp(&Unit::new_normalize(*y), a)
|
||||||
.into_inner()
|
.into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn quat_squad<T: RealField>(q1: &Qua<T>, q2: &Qua<T>, s1: &Qua<T>, s2: &Qua<T>, h: T) -> Qua<T> {
|
//pub fn quat_squad<T: RealNumber>(q1: &Qua<T>, q2: &Qua<T>, s1: &Qua<T>, s2: &Qua<T>, h: T) -> Qua<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/// Converts a quaternion to a rotation matrix.
|
/// Converts a quaternion to a rotation matrix.
|
||||||
pub fn quat_to_mat3<T: RealField>(x: &Qua<T>) -> TMat3<T> {
|
pub fn quat_to_mat3<T: RealNumber>(x: &Qua<T>) -> TMat3<T> {
|
||||||
UnitQuaternion::new_unchecked(*x)
|
UnitQuaternion::new_unchecked(*x)
|
||||||
.to_rotation_matrix()
|
.to_rotation_matrix()
|
||||||
.into_inner()
|
.into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a quaternion to a rotation matrix in homogenous coordinates.
|
/// Converts a quaternion to a rotation matrix in homogenous coordinates.
|
||||||
pub fn quat_to_mat4<T: RealField>(x: &Qua<T>) -> TMat4<T> {
|
pub fn quat_to_mat4<T: RealNumber>(x: &Qua<T>) -> TMat4<T> {
|
||||||
UnitQuaternion::new_unchecked(*x).to_homogeneous()
|
UnitQuaternion::new_unchecked(*x).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a rotation matrix to a quaternion.
|
/// Converts a rotation matrix to a quaternion.
|
||||||
pub fn mat3_to_quat<T: RealField>(x: &TMat3<T>) -> Qua<T> {
|
pub fn mat3_to_quat<T: RealNumber>(x: &TMat3<T>) -> Qua<T> {
|
||||||
let r = Rotation3::from_matrix_unchecked(*x);
|
let r = Rotation3::from_matrix_unchecked(*x);
|
||||||
UnitQuaternion::from_rotation_matrix(&r).into_inner()
|
UnitQuaternion::from_rotation_matrix(&r).into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a rotation matrix in homogeneous coordinates to a quaternion.
|
/// Converts a rotation matrix in homogeneous coordinates to a quaternion.
|
||||||
pub fn to_quat<T: RealField>(x: &TMat4<T>) -> Qua<T> {
|
pub fn to_quat<T: RealNumber>(x: &TMat4<T>) -> Qua<T> {
|
||||||
let rot = x.fixed_slice::<3, 3>(0, 0).into_owned();
|
let rot = x.fixed_slice::<3, 3>(0, 0).into_owned();
|
||||||
mat3_to_quat(&rot)
|
mat3_to_quat(&rot)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use na::{RealField, Rotation3, Unit, UnitQuaternion};
|
use na::{Rotation3, Unit, UnitQuaternion};
|
||||||
|
|
||||||
use crate::aliases::{Qua, TMat4, TVec3};
|
use crate::aliases::{Qua, TMat4, TVec3};
|
||||||
|
use crate::RealNumber;
|
||||||
|
|
||||||
/// Builds a rotation 4 * 4 matrix created from a normalized axis and an angle.
|
/// Builds a rotation 4 * 4 matrix created from a normalized axis and an angle.
|
||||||
///
|
///
|
||||||
|
@ -9,7 +10,7 @@ use crate::aliases::{Qua, TMat4, TVec3};
|
||||||
/// * `m` - Input matrix multiplied by this rotation matrix.
|
/// * `m` - Input matrix multiplied by this rotation matrix.
|
||||||
/// * `angle` - Rotation angle expressed in radians.
|
/// * `angle` - Rotation angle expressed in radians.
|
||||||
/// * `axis` - Rotation axis, must be normalized.
|
/// * `axis` - Rotation axis, must be normalized.
|
||||||
pub fn rotate_normalized_axis<T: RealField>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T> {
|
pub fn rotate_normalized_axis<T: RealNumber>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T> {
|
||||||
m * Rotation3::from_axis_angle(&Unit::new_unchecked(*axis), angle).to_homogeneous()
|
m * Rotation3::from_axis_angle(&Unit::new_unchecked(*axis), angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +21,6 @@ pub fn rotate_normalized_axis<T: RealField>(m: &TMat4<T>, angle: T, axis: &TVec3
|
||||||
/// * `q` - Source orientation.
|
/// * `q` - Source orientation.
|
||||||
/// * `angle` - Angle expressed in radians.
|
/// * `angle` - Angle expressed in radians.
|
||||||
/// * `axis` - Normalized axis of the rotation, must be normalized.
|
/// * `axis` - Normalized axis of the rotation, must be normalized.
|
||||||
pub fn quat_rotate_normalized_axis<T: RealField>(q: &Qua<T>, angle: T, axis: &TVec3<T>) -> Qua<T> {
|
pub fn quat_rotate_normalized_axis<T: RealNumber>(q: &Qua<T>, angle: T, axis: &TVec3<T>) -> Qua<T> {
|
||||||
q * UnitQuaternion::from_axis_angle(&Unit::new_unchecked(*axis), angle).into_inner()
|
q * UnitQuaternion::from_axis_angle(&Unit::new_unchecked(*axis), angle).into_inner()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use na::{RealField, Rotation3, Unit, UnitComplex};
|
use na::{Rotation3, Unit, UnitComplex};
|
||||||
|
|
||||||
use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
|
use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
|
||||||
|
use crate::RealNumber;
|
||||||
|
|
||||||
/// Build the rotation matrix needed to align `normal` and `up`.
|
/// Build the rotation matrix needed to align `normal` and `up`.
|
||||||
pub fn orientation<T: RealField>(normal: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
pub fn orientation<T: RealNumber>(normal: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
||||||
if let Some(r) = Rotation3::rotation_between(normal, up) {
|
if let Some(r) = Rotation3::rotation_between(normal, up) {
|
||||||
r.to_homogeneous()
|
r.to_homogeneous()
|
||||||
} else {
|
} else {
|
||||||
|
@ -12,52 +13,52 @@ pub fn orientation<T: RealField>(normal: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a two dimensional vector.
|
/// Rotate a two dimensional vector.
|
||||||
pub fn rotate_vec2<T: RealField>(v: &TVec2<T>, angle: T) -> TVec2<T> {
|
pub fn rotate_vec2<T: RealNumber>(v: &TVec2<T>, angle: T) -> TVec2<T> {
|
||||||
UnitComplex::new(angle) * v
|
UnitComplex::new(angle) * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a three dimensional vector around an axis.
|
/// Rotate a three dimensional vector around an axis.
|
||||||
pub fn rotate_vec3<T: RealField>(v: &TVec3<T>, angle: T, normal: &TVec3<T>) -> TVec3<T> {
|
pub fn rotate_vec3<T: RealNumber>(v: &TVec3<T>, angle: T, normal: &TVec3<T>) -> TVec3<T> {
|
||||||
Rotation3::from_axis_angle(&Unit::new_normalize(*normal), angle) * v
|
Rotation3::from_axis_angle(&Unit::new_normalize(*normal), angle) * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a thee dimensional vector in homogeneous coordinates around an axis.
|
/// Rotate a thee dimensional vector in homogeneous coordinates around an axis.
|
||||||
pub fn rotate_vec4<T: RealField>(v: &TVec4<T>, angle: T, normal: &TVec3<T>) -> TVec4<T> {
|
pub fn rotate_vec4<T: RealNumber>(v: &TVec4<T>, angle: T, normal: &TVec3<T>) -> TVec4<T> {
|
||||||
Rotation3::from_axis_angle(&Unit::new_normalize(*normal), angle).to_homogeneous() * v
|
Rotation3::from_axis_angle(&Unit::new_normalize(*normal), angle).to_homogeneous() * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a three dimensional vector around the `X` axis.
|
/// Rotate a three dimensional vector around the `X` axis.
|
||||||
pub fn rotate_x_vec3<T: RealField>(v: &TVec3<T>, angle: T) -> TVec3<T> {
|
pub fn rotate_x_vec3<T: RealNumber>(v: &TVec3<T>, angle: T) -> TVec3<T> {
|
||||||
Rotation3::from_axis_angle(&TVec3::x_axis(), angle) * v
|
Rotation3::from_axis_angle(&TVec3::x_axis(), angle) * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a three dimensional vector in homogeneous coordinates around the `X` axis.
|
/// Rotate a three dimensional vector in homogeneous coordinates around the `X` axis.
|
||||||
pub fn rotate_x_vec4<T: RealField>(v: &TVec4<T>, angle: T) -> TVec4<T> {
|
pub fn rotate_x_vec4<T: RealNumber>(v: &TVec4<T>, angle: T) -> TVec4<T> {
|
||||||
Rotation3::from_axis_angle(&TVec3::x_axis(), angle).to_homogeneous() * v
|
Rotation3::from_axis_angle(&TVec3::x_axis(), angle).to_homogeneous() * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a three dimensional vector around the `Y` axis.
|
/// Rotate a three dimensional vector around the `Y` axis.
|
||||||
pub fn rotate_y_vec3<T: RealField>(v: &TVec3<T>, angle: T) -> TVec3<T> {
|
pub fn rotate_y_vec3<T: RealNumber>(v: &TVec3<T>, angle: T) -> TVec3<T> {
|
||||||
Rotation3::from_axis_angle(&TVec3::y_axis(), angle) * v
|
Rotation3::from_axis_angle(&TVec3::y_axis(), angle) * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a three dimensional vector in homogeneous coordinates around the `Y` axis.
|
/// Rotate a three dimensional vector in homogeneous coordinates around the `Y` axis.
|
||||||
pub fn rotate_y_vec4<T: RealField>(v: &TVec4<T>, angle: T) -> TVec4<T> {
|
pub fn rotate_y_vec4<T: RealNumber>(v: &TVec4<T>, angle: T) -> TVec4<T> {
|
||||||
Rotation3::from_axis_angle(&TVec3::y_axis(), angle).to_homogeneous() * v
|
Rotation3::from_axis_angle(&TVec3::y_axis(), angle).to_homogeneous() * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a three dimensional vector around the `Z` axis.
|
/// Rotate a three dimensional vector around the `Z` axis.
|
||||||
pub fn rotate_z_vec3<T: RealField>(v: &TVec3<T>, angle: T) -> TVec3<T> {
|
pub fn rotate_z_vec3<T: RealNumber>(v: &TVec3<T>, angle: T) -> TVec3<T> {
|
||||||
Rotation3::from_axis_angle(&TVec3::z_axis(), angle) * v
|
Rotation3::from_axis_angle(&TVec3::z_axis(), angle) * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a three dimensional vector in homogeneous coordinates around the `Z` axis.
|
/// Rotate a three dimensional vector in homogeneous coordinates around the `Z` axis.
|
||||||
pub fn rotate_z_vec4<T: RealField>(v: &TVec4<T>, angle: T) -> TVec4<T> {
|
pub fn rotate_z_vec4<T: RealNumber>(v: &TVec4<T>, angle: T) -> TVec4<T> {
|
||||||
Rotation3::from_axis_angle(&TVec3::z_axis(), angle).to_homogeneous() * v
|
Rotation3::from_axis_angle(&TVec3::z_axis(), angle).to_homogeneous() * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes a spherical linear interpolation between the vectors `x` and `y` assumed to be normalized.
|
/// Computes a spherical linear interpolation between the vectors `x` and `y` assumed to be normalized.
|
||||||
pub fn slerp<T: RealField>(x: &TVec3<T>, y: &TVec3<T>, a: T) -> TVec3<T> {
|
pub fn slerp<T: RealNumber>(x: &TVec3<T>, y: &TVec3<T>, a: T) -> TVec3<T> {
|
||||||
Unit::new_unchecked(*x)
|
Unit::new_unchecked(*x)
|
||||||
.slerp(&Unit::new_unchecked(*y), a)
|
.slerp(&Unit::new_unchecked(*y), a)
|
||||||
.into_inner()
|
.into_inner()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{RealField, Rotation2, Rotation3, Unit};
|
use na::{Rotation2, Rotation3, Unit};
|
||||||
|
|
||||||
use crate::aliases::{TMat3, TMat4, TVec2, TVec3};
|
use crate::aliases::{TMat3, TMat4, TVec2, TVec3};
|
||||||
use crate::traits::Number;
|
use crate::traits::{Number, RealNumber};
|
||||||
|
|
||||||
/// A rotation 4 * 4 matrix created from an axis of 3 scalars and an angle expressed in radians.
|
/// A rotation 4 * 4 matrix created from an axis of 3 scalars and an angle expressed in radians.
|
||||||
///
|
///
|
||||||
|
@ -12,7 +12,7 @@ use crate::traits::Number;
|
||||||
/// * [`rotation2d`](fn.rotation2d.html)
|
/// * [`rotation2d`](fn.rotation2d.html)
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d`](fn.scaling2d.html)
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d`](fn.translation2d.html)
|
||||||
pub fn rotation<T: RealField>(angle: T, v: &TVec3<T>) -> TMat4<T> {
|
pub fn rotation<T: RealNumber>(angle: T, v: &TVec3<T>) -> TMat4<T> {
|
||||||
Rotation3::from_axis_angle(&Unit::new_normalize(*v), angle).to_homogeneous()
|
Rotation3::from_axis_angle(&Unit::new_normalize(*v), angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ pub fn translation<T: Number>(v: &TVec3<T>) -> TMat4<T> {
|
||||||
/// * [`translation`](fn.translation.html)
|
/// * [`translation`](fn.translation.html)
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d`](fn.scaling2d.html)
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d`](fn.translation2d.html)
|
||||||
pub fn rotation2d<T: RealField>(angle: T) -> TMat3<T> {
|
pub fn rotation2d<T: RealNumber>(angle: T) -> TMat3<T> {
|
||||||
Rotation2::new(angle).to_homogeneous()
|
Rotation2::new(angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::aliases::{TMat3, TMat4, TVec2, TVec3};
|
use crate::aliases::{TMat3, TMat4, TVec2, TVec3};
|
||||||
use crate::traits::Number;
|
use crate::traits::Number;
|
||||||
|
use crate::RealNumber;
|
||||||
|
|
||||||
/// Build planar projection matrix along normal axis and right-multiply it to `m`.
|
/// Build planar projection matrix along normal axis and right-multiply it to `m`.
|
||||||
pub fn proj2d<T: Number>(m: &TMat3<T>, normal: &TVec2<T>) -> TMat3<T> {
|
pub fn proj2d<T: Number>(m: &TMat3<T>, normal: &TVec2<T>) -> TMat3<T> {
|
||||||
|
@ -26,24 +27,24 @@ pub fn proj<T: Number>(m: &TMat4<T>, normal: &TVec3<T>) -> TMat4<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a reflection matrix and right-multiply it to `m`.
|
/// Builds a reflection matrix and right-multiply it to `m`.
|
||||||
pub fn reflect2d<T: Number>(m: &TMat3<T>, normal: &TVec2<T>) -> TMat3<T> {
|
pub fn reflect2d<T: RealNumber>(m: &TMat3<T>, normal: &TVec2<T>) -> TMat3<T> {
|
||||||
let mut res = TMat3::identity();
|
let mut res = TMat3::identity();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut part = res.fixed_slice_mut::<2, 2>(0, 0);
|
let mut part = res.fixed_slice_mut::<2, 2>(0, 0);
|
||||||
part -= (normal * T::from_f64(2.0).unwrap()) * normal.transpose();
|
part -= (normal * T::from_subset(&2.0)) * normal.transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
m * res
|
m * res
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a reflection matrix, and right-multiply it to `m`.
|
/// Builds a reflection matrix, and right-multiply it to `m`.
|
||||||
pub fn reflect<T: Number>(m: &TMat4<T>, normal: &TVec3<T>) -> TMat4<T> {
|
pub fn reflect<T: RealNumber>(m: &TMat4<T>, normal: &TVec3<T>) -> TMat4<T> {
|
||||||
let mut res = TMat4::identity();
|
let mut res = TMat4::identity();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut part = res.fixed_slice_mut::<3, 3>(0, 0);
|
let mut part = res.fixed_slice_mut::<3, 3>(0, 0);
|
||||||
part -= (normal * T::from_f64(2.0).unwrap()) * normal.transpose();
|
part -= (normal * T::from_subset(&2.0)) * normal.transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
m * res
|
m * res
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{RealField, UnitComplex};
|
use na::UnitComplex;
|
||||||
|
|
||||||
use crate::aliases::{TMat3, TVec2};
|
use crate::aliases::{TMat3, TVec2};
|
||||||
use crate::traits::Number;
|
use crate::traits::{Number, RealNumber};
|
||||||
|
|
||||||
/// Builds a 2D rotation matrix from an angle and right-multiply it to `m`.
|
/// Builds a 2D rotation matrix from an angle and right-multiply it to `m`.
|
||||||
///
|
///
|
||||||
|
@ -12,7 +12,7 @@ use crate::traits::Number;
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d`](fn.scaling2d.html)
|
||||||
/// * [`translate2d`](fn.translate2d.html)
|
/// * [`translate2d`](fn.translate2d.html)
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d`](fn.translation2d.html)
|
||||||
pub fn rotate2d<T: RealField>(m: &TMat3<T>, angle: T) -> TMat3<T> {
|
pub fn rotate2d<T: RealNumber>(m: &TMat3<T>, angle: T) -> TMat3<T> {
|
||||||
m * UnitComplex::new(angle).to_homogeneous()
|
m * UnitComplex::new(angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
use na::RealField;
|
use crate::RealNumber;
|
||||||
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
|
|
||||||
/// The angle between two vectors.
|
/// The angle between two vectors.
|
||||||
pub fn angle<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
pub fn angle<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
||||||
x.angle(y)
|
x.angle(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn oriented_angle<T: RealField>(x: &TVec2<T>, y: &TVec2<T>) -> T {
|
//pub fn oriented_angle<T: RealNumber>(x: &TVec2<T>, y: &TVec2<T>) -> T {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn oriented_angle_ref<T: RealField>(x: &TVec3<T>, y: &TVec3<T>, refv: &TVec3<T>) -> T {
|
//pub fn oriented_angle_ref<T: RealNumber>(x: &TVec3<T>, y: &TVec3<T>, refv: &TVec3<T>) -> T {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use na::RealField;
|
use crate::RealNumber;
|
||||||
|
|
||||||
use crate::aliases::{TVec, TVec2, TVec3};
|
use crate::aliases::{TVec, TVec2, TVec3};
|
||||||
use crate::traits::Number;
|
use crate::traits::Number;
|
||||||
|
@ -40,7 +40,7 @@ pub fn is_comp_null<T: Number, const D: usize>(v: &TVec<T, D>, epsilon: T) -> TV
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if `v` has a magnitude of 1 (up to an epsilon).
|
/// Returns `true` if `v` has a magnitude of 1 (up to an epsilon).
|
||||||
pub fn is_normalized<T: RealField, const D: usize>(v: &TVec<T, D>, epsilon: T) -> bool {
|
pub fn is_normalized<T: RealNumber, const D: usize>(v: &TVec<T, D>, epsilon: T) -> bool {
|
||||||
abs_diff_eq!(v.norm_squared(), T::one(), epsilon = epsilon * epsilon)
|
abs_diff_eq!(v.norm_squared(), T::one(), epsilon = epsilon * epsilon)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use na::{DefaultAllocator, RealField, Scalar, U3};
|
use na::{DefaultAllocator, RealNumber, Scalar, U3};
|
||||||
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use crate::traits::{Alloc, Dimension, Number};
|
use crate::traits::{Alloc, Dimension, Number};
|
||||||
|
|
|
@ -129,7 +129,7 @@ extern crate approx;
|
||||||
extern crate nalgebra as na;
|
extern crate nalgebra as na;
|
||||||
|
|
||||||
pub use crate::aliases::*;
|
pub use crate::aliases::*;
|
||||||
pub use crate::traits::Number;
|
pub use crate::traits::{Number, RealNumber};
|
||||||
pub use common::{
|
pub use common::{
|
||||||
abs, ceil, clamp, clamp_scalar, clamp_vec, float_bits_to_int, float_bits_to_int_vec,
|
abs, ceil, clamp, clamp_scalar, clamp_vec, float_bits_to_int, float_bits_to_int_vec,
|
||||||
float_bits_to_uint, float_bits_to_uint_vec, floor, fract, int_bits_to_float,
|
float_bits_to_uint, float_bits_to_uint_vec, floor, fract, int_bits_to_float,
|
||||||
|
@ -201,7 +201,7 @@ pub use gtx::{
|
||||||
pub use na::{
|
pub use na::{
|
||||||
convert, convert_ref, convert_ref_unchecked, convert_unchecked, try_convert, try_convert_ref,
|
convert, convert_ref, convert_ref_unchecked, convert_unchecked, try_convert, try_convert_ref,
|
||||||
};
|
};
|
||||||
pub use na::{DefaultAllocator, RealField, Scalar, U1, U2, U3, U4};
|
pub use na::{DefaultAllocator, Scalar, U1, U2, U3, U4};
|
||||||
|
|
||||||
mod aliases;
|
mod aliases;
|
||||||
mod common;
|
mod common;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use na::{Const, DimMin, RealField, Scalar};
|
use na::{Const, DimMin, Scalar};
|
||||||
|
|
||||||
use crate::aliases::{TMat, TVec};
|
use crate::aliases::{TMat, TVec};
|
||||||
use crate::traits::Number;
|
use crate::traits::{Number, RealNumber};
|
||||||
|
|
||||||
/// The determinant of the matrix `m`.
|
/// The determinant of the matrix `m`.
|
||||||
pub fn determinant<T: RealField, const D: usize>(m: &TMat<T, D, D>) -> T
|
pub fn determinant<T: RealNumber, const D: usize>(m: &TMat<T, D, D>) -> T
|
||||||
where
|
where
|
||||||
Const<D>: DimMin<Const<D>, Output = Const<D>>,
|
Const<D>: DimMin<Const<D>, Output = Const<D>>,
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The inverse of the matrix `m`.
|
/// The inverse of the matrix `m`.
|
||||||
pub fn inverse<T: RealField, const D: usize>(m: &TMat<T, D, D>) -> TMat<T, D, D> {
|
pub fn inverse<T: RealNumber, const D: usize>(m: &TMat<T, D, D>) -> TMat<T, D, D> {
|
||||||
m.clone()
|
m.clone()
|
||||||
.try_inverse()
|
.try_inverse()
|
||||||
.unwrap_or_else(TMat::<T, D, D>::zeros)
|
.unwrap_or_else(TMat::<T, D, D>::zeros)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use approx::AbsDiffEq;
|
use approx::AbsDiffEq;
|
||||||
use num::{Bounded, FromPrimitive, Signed};
|
use num::{Bounded, Signed};
|
||||||
|
|
||||||
use na::Scalar;
|
use na::Scalar;
|
||||||
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub};
|
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub, RealField};
|
||||||
use std::cmp::PartialOrd;
|
use std::cmp::PartialOrd;
|
||||||
|
|
||||||
/// A number that can either be an integer or a float.
|
/// A number that can either be an integer or a float.
|
||||||
|
@ -15,7 +15,6 @@ pub trait Number:
|
||||||
+ ClosedMul
|
+ ClosedMul
|
||||||
+ AbsDiffEq<Epsilon = Self>
|
+ AbsDiffEq<Epsilon = Self>
|
||||||
+ Signed
|
+ Signed
|
||||||
+ FromPrimitive
|
|
||||||
+ Bounded
|
+ Bounded
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -29,8 +28,12 @@ impl<
|
||||||
+ ClosedMul
|
+ ClosedMul
|
||||||
+ AbsDiffEq<Epsilon = Self>
|
+ AbsDiffEq<Epsilon = Self>
|
||||||
+ Signed
|
+ Signed
|
||||||
+ FromPrimitive
|
|
||||||
+ Bounded,
|
+ Bounded,
|
||||||
> Number for T
|
> Number for T
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A number that can be any float type.
|
||||||
|
pub trait RealNumber: Number + RealField {}
|
||||||
|
|
||||||
|
impl<T: Number + RealField> RealNumber for T {}
|
||||||
|
|
|
@ -1,78 +1,79 @@
|
||||||
use na::{self, RealField};
|
use na;
|
||||||
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
|
use crate::RealNumber;
|
||||||
|
|
||||||
/// Component-wise arc-cosinus.
|
/// Component-wise arc-cosinus.
|
||||||
pub fn acos<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn acos<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.map(|e| e.acos())
|
x.map(|e| e.acos())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise hyperbolic arc-cosinus.
|
/// Component-wise hyperbolic arc-cosinus.
|
||||||
pub fn acosh<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn acosh<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.map(|e| e.acosh())
|
x.map(|e| e.acosh())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise arc-sinus.
|
/// Component-wise arc-sinus.
|
||||||
pub fn asin<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn asin<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.map(|e| e.asin())
|
x.map(|e| e.asin())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise hyperbolic arc-sinus.
|
/// Component-wise hyperbolic arc-sinus.
|
||||||
pub fn asinh<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn asinh<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.map(|e| e.asinh())
|
x.map(|e| e.asinh())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise arc-tangent of `y / x`.
|
/// Component-wise arc-tangent of `y / x`.
|
||||||
pub fn atan2<T: RealField, const D: usize>(y: &TVec<T, D>, x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn atan2<T: RealNumber, const D: usize>(y: &TVec<T, D>, x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
y.zip_map(x, |y, x| y.atan2(x))
|
y.zip_map(x, |y, x| y.atan2(x))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise arc-tangent.
|
/// Component-wise arc-tangent.
|
||||||
pub fn atan<T: RealField, const D: usize>(y_over_x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn atan<T: RealNumber, const D: usize>(y_over_x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
y_over_x.map(|e| e.atan())
|
y_over_x.map(|e| e.atan())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise hyperbolic arc-tangent.
|
/// Component-wise hyperbolic arc-tangent.
|
||||||
pub fn atanh<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn atanh<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.map(|e| e.atanh())
|
x.map(|e| e.atanh())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise cosinus.
|
/// Component-wise cosinus.
|
||||||
pub fn cos<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
pub fn cos<T: RealNumber, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
||||||
angle.map(|e| e.cos())
|
angle.map(|e| e.cos())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise hyperbolic cosinus.
|
/// Component-wise hyperbolic cosinus.
|
||||||
pub fn cosh<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
pub fn cosh<T: RealNumber, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
||||||
angle.map(|e| e.cosh())
|
angle.map(|e| e.cosh())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise conversion from radians to degrees.
|
/// Component-wise conversion from radians to degrees.
|
||||||
pub fn degrees<T: RealField, const D: usize>(radians: &TVec<T, D>) -> TVec<T, D> {
|
pub fn degrees<T: RealNumber, const D: usize>(radians: &TVec<T, D>) -> TVec<T, D> {
|
||||||
radians.map(|e| e * na::convert(180.0) / T::pi())
|
radians.map(|e| e * na::convert(180.0) / T::pi())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise conversion fro degrees to radians.
|
/// Component-wise conversion fro degrees to radians.
|
||||||
pub fn radians<T: RealField, const D: usize>(degrees: &TVec<T, D>) -> TVec<T, D> {
|
pub fn radians<T: RealNumber, const D: usize>(degrees: &TVec<T, D>) -> TVec<T, D> {
|
||||||
degrees.map(|e| e * T::pi() / na::convert(180.0))
|
degrees.map(|e| e * T::pi() / na::convert(180.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise sinus.
|
/// Component-wise sinus.
|
||||||
pub fn sin<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
pub fn sin<T: RealNumber, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
||||||
angle.map(|e| e.sin())
|
angle.map(|e| e.sin())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise hyperbolic sinus.
|
/// Component-wise hyperbolic sinus.
|
||||||
pub fn sinh<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
pub fn sinh<T: RealNumber, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
||||||
angle.map(|e| e.sinh())
|
angle.map(|e| e.sinh())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise tangent.
|
/// Component-wise tangent.
|
||||||
pub fn tan<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
pub fn tan<T: RealNumber, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
||||||
angle.map(|e| e.tan())
|
angle.map(|e| e.tan())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise hyperbolic tangent.
|
/// Component-wise hyperbolic tangent.
|
||||||
pub fn tanh<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
pub fn tanh<T: RealNumber, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
||||||
angle.map(|e| e.tanh())
|
angle.map(|e| e.tanh())
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ where
|
||||||
// We use the fact that matrix iteration is guaranteed to be column-major
|
// We use the fact that matrix iteration is guaranteed to be column-major
|
||||||
let i = index % dense.nrows();
|
let i = index % dense.nrows();
|
||||||
let j = index / dense.nrows();
|
let j = index / dense.nrows();
|
||||||
coo.push(i, j, v.inlined_clone());
|
coo.push(i, j, v.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ where
|
||||||
{
|
{
|
||||||
let mut output = DMatrix::repeat(coo.nrows(), coo.ncols(), T::zero());
|
let mut output = DMatrix::repeat(coo.nrows(), coo.ncols(), T::zero());
|
||||||
for (i, j, v) in coo.triplet_iter() {
|
for (i, j, v) in coo.triplet_iter() {
|
||||||
output[(i, j)] += v.inlined_clone();
|
output[(i, j)] += v.clone();
|
||||||
}
|
}
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ where
|
||||||
pub fn convert_csr_coo<T: Scalar>(csr: &CsrMatrix<T>) -> CooMatrix<T> {
|
pub fn convert_csr_coo<T: Scalar>(csr: &CsrMatrix<T>) -> CooMatrix<T> {
|
||||||
let mut result = CooMatrix::new(csr.nrows(), csr.ncols());
|
let mut result = CooMatrix::new(csr.nrows(), csr.ncols());
|
||||||
for (i, j, v) in csr.triplet_iter() {
|
for (i, j, v) in csr.triplet_iter() {
|
||||||
result.push(i, j, v.inlined_clone());
|
result.push(i, j, v.clone());
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ where
|
||||||
let mut output = DMatrix::zeros(csr.nrows(), csr.ncols());
|
let mut output = DMatrix::zeros(csr.nrows(), csr.ncols());
|
||||||
|
|
||||||
for (i, j, v) in csr.triplet_iter() {
|
for (i, j, v) in csr.triplet_iter() {
|
||||||
output[(i, j)] += v.inlined_clone();
|
output[(i, j)] += v.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
output
|
output
|
||||||
|
@ -111,7 +111,7 @@ where
|
||||||
let v = dense.index((i, j));
|
let v = dense.index((i, j));
|
||||||
if v != &T::zero() {
|
if v != &T::zero() {
|
||||||
col_idx.push(j);
|
col_idx.push(j);
|
||||||
values.push(v.inlined_clone());
|
values.push(v.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
row_offsets.push(col_idx.len());
|
row_offsets.push(col_idx.len());
|
||||||
|
@ -148,7 +148,7 @@ where
|
||||||
{
|
{
|
||||||
let mut coo = CooMatrix::new(csc.nrows(), csc.ncols());
|
let mut coo = CooMatrix::new(csc.nrows(), csc.ncols());
|
||||||
for (i, j, v) in csc.triplet_iter() {
|
for (i, j, v) in csc.triplet_iter() {
|
||||||
coo.push(i, j, v.inlined_clone());
|
coo.push(i, j, v.clone());
|
||||||
}
|
}
|
||||||
coo
|
coo
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,7 @@ where
|
||||||
let mut output = DMatrix::zeros(csc.nrows(), csc.ncols());
|
let mut output = DMatrix::zeros(csc.nrows(), csc.ncols());
|
||||||
|
|
||||||
for (i, j, v) in csc.triplet_iter() {
|
for (i, j, v) in csc.triplet_iter() {
|
||||||
output[(i, j)] += v.inlined_clone();
|
output[(i, j)] += v.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
output
|
output
|
||||||
|
@ -185,7 +185,7 @@ where
|
||||||
let v = dense.index((i, j));
|
let v = dense.index((i, j));
|
||||||
if v != &T::zero() {
|
if v != &T::zero() {
|
||||||
row_idx.push(i);
|
row_idx.push(i);
|
||||||
values.push(v.inlined_clone());
|
values.push(v.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col_offsets.push(row_idx.len());
|
col_offsets.push(row_idx.len());
|
||||||
|
|
|
@ -522,7 +522,7 @@ where
|
||||||
let entry_offset = target_offsets[source_minor_idx] + *target_lane_count;
|
let entry_offset = target_offsets[source_minor_idx] + *target_lane_count;
|
||||||
target_indices[entry_offset] = source_major_idx;
|
target_indices[entry_offset] = source_major_idx;
|
||||||
unsafe {
|
unsafe {
|
||||||
target_values.set(entry_offset, val.inlined_clone());
|
target_values.set(entry_offset, val.clone());
|
||||||
}
|
}
|
||||||
*target_lane_count += 1;
|
*target_lane_count += 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::ops::serial::spsolve_csc_lower_triangular;
|
||||||
use crate::ops::Op;
|
use crate::ops::Op;
|
||||||
use crate::pattern::SparsityPattern;
|
use crate::pattern::SparsityPattern;
|
||||||
use core::{iter, mem};
|
use core::{iter, mem};
|
||||||
use nalgebra::{DMatrix, DMatrixSlice, DMatrixSliceMut, RealField, Scalar};
|
use nalgebra::{DMatrix, DMatrixSlice, DMatrixSliceMut, RealField};
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
/// A symbolic sparse Cholesky factorization of a CSC matrix.
|
/// A symbolic sparse Cholesky factorization of a CSC matrix.
|
||||||
|
@ -209,15 +209,16 @@ impl<T: RealField> CscCholesky<T> {
|
||||||
let irow = *self.m_pattern.minor_indices().get_unchecked(p);
|
let irow = *self.m_pattern.minor_indices().get_unchecked(p);
|
||||||
|
|
||||||
if irow >= k {
|
if irow >= k {
|
||||||
*self.work_x.get_unchecked_mut(irow) = *values.get_unchecked(p);
|
*self.work_x.get_unchecked_mut(irow) = values.get_unchecked(p).clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for &j in self.u_pattern.lane(k) {
|
for &j in self.u_pattern.lane(k) {
|
||||||
let factor = -*self
|
let factor = -self
|
||||||
.l_factor
|
.l_factor
|
||||||
.values()
|
.values()
|
||||||
.get_unchecked(*self.work_c.get_unchecked(j));
|
.get_unchecked(*self.work_c.get_unchecked(j))
|
||||||
|
.clone();
|
||||||
*self.work_c.get_unchecked_mut(j) += 1;
|
*self.work_c.get_unchecked_mut(j) += 1;
|
||||||
|
|
||||||
if j < k {
|
if j < k {
|
||||||
|
@ -225,27 +226,27 @@ impl<T: RealField> CscCholesky<T> {
|
||||||
let col_j_entries = col_j.row_indices().iter().zip(col_j.values());
|
let col_j_entries = col_j.row_indices().iter().zip(col_j.values());
|
||||||
for (&z, val) in col_j_entries {
|
for (&z, val) in col_j_entries {
|
||||||
if z >= k {
|
if z >= k {
|
||||||
*self.work_x.get_unchecked_mut(z) += val.inlined_clone() * factor;
|
*self.work_x.get_unchecked_mut(z) += val.clone() * factor.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let diag = *self.work_x.get_unchecked(k);
|
let diag = self.work_x.get_unchecked(k).clone();
|
||||||
|
|
||||||
if diag > T::zero() {
|
if diag > T::zero() {
|
||||||
let denom = diag.sqrt();
|
let denom = diag.sqrt();
|
||||||
|
|
||||||
{
|
{
|
||||||
let (offsets, _, values) = self.l_factor.csc_data_mut();
|
let (offsets, _, values) = self.l_factor.csc_data_mut();
|
||||||
*values.get_unchecked_mut(*offsets.get_unchecked(k)) = denom;
|
*values.get_unchecked_mut(*offsets.get_unchecked(k)) = denom.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut col_k = self.l_factor.col_mut(k);
|
let mut col_k = self.l_factor.col_mut(k);
|
||||||
let (col_k_rows, col_k_values) = col_k.rows_and_values_mut();
|
let (col_k_rows, col_k_values) = col_k.rows_and_values_mut();
|
||||||
let col_k_entries = col_k_rows.iter().zip(col_k_values);
|
let col_k_entries = col_k_rows.iter().zip(col_k_values);
|
||||||
for (&p, val) in col_k_entries {
|
for (&p, val) in col_k_entries {
|
||||||
*val = *self.work_x.get_unchecked(p) / denom;
|
*val = self.work_x.get_unchecked(p).clone() / denom.clone();
|
||||||
*self.work_x.get_unchecked_mut(p) = T::zero();
|
*self.work_x.get_unchecked_mut(p) = T::zero();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -141,7 +141,7 @@ macro_rules! impl_scalar_mul {
|
||||||
impl_mul!(<'a, T>(a: &'a $matrix_type<T>, b: &'a T) -> $matrix_type<T> {
|
impl_mul!(<'a, T>(a: &'a $matrix_type<T>, b: &'a T) -> $matrix_type<T> {
|
||||||
let values: Vec<_> = a.values()
|
let values: Vec<_> = a.values()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v_i| v_i.inlined_clone() * b.inlined_clone())
|
.map(|v_i| v_i.clone() * b.clone())
|
||||||
.collect();
|
.collect();
|
||||||
$matrix_type::try_from_pattern_and_values(a.pattern().clone(), values).unwrap()
|
$matrix_type::try_from_pattern_and_values(a.pattern().clone(), values).unwrap()
|
||||||
});
|
});
|
||||||
|
@ -151,7 +151,7 @@ macro_rules! impl_scalar_mul {
|
||||||
impl_mul!(<'a, T>(a: $matrix_type<T>, b: &'a T) -> $matrix_type<T> {
|
impl_mul!(<'a, T>(a: $matrix_type<T>, b: &'a T) -> $matrix_type<T> {
|
||||||
let mut a = a;
|
let mut a = a;
|
||||||
for value in a.values_mut() {
|
for value in a.values_mut() {
|
||||||
*value = b.inlined_clone() * value.inlined_clone();
|
*value = b.clone() * value.clone();
|
||||||
}
|
}
|
||||||
a
|
a
|
||||||
});
|
});
|
||||||
|
@ -168,7 +168,7 @@ macro_rules! impl_scalar_mul {
|
||||||
{
|
{
|
||||||
fn mul_assign(&mut self, scalar: T) {
|
fn mul_assign(&mut self, scalar: T) {
|
||||||
for val in self.values_mut() {
|
for val in self.values_mut() {
|
||||||
*val *= scalar.inlined_clone();
|
*val *= scalar.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ macro_rules! impl_scalar_mul {
|
||||||
{
|
{
|
||||||
fn mul_assign(&mut self, scalar: &'a T) {
|
fn mul_assign(&mut self, scalar: &'a T) {
|
||||||
for val in self.values_mut() {
|
for val in self.values_mut() {
|
||||||
*val *= scalar.inlined_clone();
|
*val *= scalar.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ macro_rules! impl_neg {
|
||||||
|
|
||||||
fn neg(mut self) -> Self::Output {
|
fn neg(mut self) -> Self::Output {
|
||||||
for v_i in self.values_mut() {
|
for v_i in self.values_mut() {
|
||||||
*v_i = -v_i.inlined_clone();
|
*v_i = -v_i.clone();
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -233,25 +233,25 @@ macro_rules! impl_div {
|
||||||
matrix
|
matrix
|
||||||
});
|
});
|
||||||
impl_bin_op!(Div, div, <'a, T: ClosedDiv>(matrix: $matrix_type<T>, scalar: &T) -> $matrix_type<T> {
|
impl_bin_op!(Div, div, <'a, T: ClosedDiv>(matrix: $matrix_type<T>, scalar: &T) -> $matrix_type<T> {
|
||||||
matrix / scalar.inlined_clone()
|
matrix / scalar.clone()
|
||||||
});
|
});
|
||||||
impl_bin_op!(Div, div, <'a, T: ClosedDiv>(matrix: &'a $matrix_type<T>, scalar: T) -> $matrix_type<T> {
|
impl_bin_op!(Div, div, <'a, T: ClosedDiv>(matrix: &'a $matrix_type<T>, scalar: T) -> $matrix_type<T> {
|
||||||
let new_values = matrix.values()
|
let new_values = matrix.values()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v_i| v_i.inlined_clone() / scalar.inlined_clone())
|
.map(|v_i| v_i.clone() / scalar.clone())
|
||||||
.collect();
|
.collect();
|
||||||
$matrix_type::try_from_pattern_and_values(matrix.pattern().clone(), new_values)
|
$matrix_type::try_from_pattern_and_values(matrix.pattern().clone(), new_values)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
impl_bin_op!(Div, div, <'a, T: ClosedDiv>(matrix: &'a $matrix_type<T>, scalar: &'a T) -> $matrix_type<T> {
|
impl_bin_op!(Div, div, <'a, T: ClosedDiv>(matrix: &'a $matrix_type<T>, scalar: &'a T) -> $matrix_type<T> {
|
||||||
matrix / scalar.inlined_clone()
|
matrix / scalar.clone()
|
||||||
});
|
});
|
||||||
|
|
||||||
impl<T> DivAssign<T> for $matrix_type<T>
|
impl<T> DivAssign<T> for $matrix_type<T>
|
||||||
where T : Scalar + ClosedAdd + ClosedMul + ClosedDiv + Zero + One
|
where T : Scalar + ClosedAdd + ClosedMul + ClosedDiv + Zero + One
|
||||||
{
|
{
|
||||||
fn div_assign(&mut self, scalar: T) {
|
fn div_assign(&mut self, scalar: T) {
|
||||||
self.values_mut().iter_mut().for_each(|v_i| *v_i /= scalar.inlined_clone());
|
self.values_mut().iter_mut().for_each(|v_i| *v_i /= scalar.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ macro_rules! impl_div {
|
||||||
where T : Scalar + ClosedAdd + ClosedMul + ClosedDiv + Zero + One
|
where T : Scalar + ClosedAdd + ClosedMul + ClosedDiv + Zero + One
|
||||||
{
|
{
|
||||||
fn div_assign(&mut self, scalar: &'a T) {
|
fn div_assign(&mut self, scalar: &'a T) {
|
||||||
*self /= scalar.inlined_clone();
|
*self /= scalar.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,13 +34,13 @@ where
|
||||||
let a_lane_i = a.get_lane(i).unwrap();
|
let a_lane_i = a.get_lane(i).unwrap();
|
||||||
let mut c_lane_i = c.get_lane_mut(i).unwrap();
|
let mut c_lane_i = c.get_lane_mut(i).unwrap();
|
||||||
for c_ij in c_lane_i.values_mut() {
|
for c_ij in c_lane_i.values_mut() {
|
||||||
*c_ij = beta.inlined_clone() * c_ij.inlined_clone();
|
*c_ij = beta.clone() * c_ij.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (&k, a_ik) in a_lane_i.minor_indices().iter().zip(a_lane_i.values()) {
|
for (&k, a_ik) in a_lane_i.minor_indices().iter().zip(a_lane_i.values()) {
|
||||||
let b_lane_k = b.get_lane(k).unwrap();
|
let b_lane_k = b.get_lane(k).unwrap();
|
||||||
let (mut c_lane_i_cols, mut c_lane_i_values) = c_lane_i.indices_and_values_mut();
|
let (mut c_lane_i_cols, mut c_lane_i_values) = c_lane_i.indices_and_values_mut();
|
||||||
let alpha_aik = alpha.inlined_clone() * a_ik.inlined_clone();
|
let alpha_aik = alpha.clone() * a_ik.clone();
|
||||||
for (j, b_kj) in b_lane_k.minor_indices().iter().zip(b_lane_k.values()) {
|
for (j, b_kj) in b_lane_k.minor_indices().iter().zip(b_lane_k.values()) {
|
||||||
// Determine the location in C to append the value
|
// Determine the location in C to append the value
|
||||||
let (c_local_idx, _) = c_lane_i_cols
|
let (c_local_idx, _) = c_lane_i_cols
|
||||||
|
@ -49,7 +49,7 @@ where
|
||||||
.find(|(_, c_col)| *c_col == j)
|
.find(|(_, c_col)| *c_col == j)
|
||||||
.ok_or_else(spmm_cs_unexpected_entry)?;
|
.ok_or_else(spmm_cs_unexpected_entry)?;
|
||||||
|
|
||||||
c_lane_i_values[c_local_idx] += alpha_aik.inlined_clone() * b_kj.inlined_clone();
|
c_lane_i_values[c_local_idx] += alpha_aik.clone() * b_kj.clone();
|
||||||
c_lane_i_cols = &c_lane_i_cols[c_local_idx..];
|
c_lane_i_cols = &c_lane_i_cols[c_local_idx..];
|
||||||
c_lane_i_values = &mut c_lane_i_values[c_local_idx..];
|
c_lane_i_values = &mut c_lane_i_values[c_local_idx..];
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ where
|
||||||
for (mut c_lane_i, a_lane_i) in c.lane_iter_mut().zip(a.lane_iter()) {
|
for (mut c_lane_i, a_lane_i) in c.lane_iter_mut().zip(a.lane_iter()) {
|
||||||
if beta != T::one() {
|
if beta != T::one() {
|
||||||
for c_ij in c_lane_i.values_mut() {
|
for c_ij in c_lane_i.values_mut() {
|
||||||
*c_ij *= beta.inlined_clone();
|
*c_ij *= beta.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ where
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|(_, c_col)| *c_col == a_col)
|
.find(|(_, c_col)| *c_col == a_col)
|
||||||
.ok_or_else(spadd_cs_unexpected_entry)?;
|
.ok_or_else(spadd_cs_unexpected_entry)?;
|
||||||
c_vals[c_idx] += alpha.inlined_clone() * a_val.inlined_clone();
|
c_vals[c_idx] += alpha.clone() * a_val.clone();
|
||||||
c_minors = &c_minors[c_idx..];
|
c_minors = &c_minors[c_idx..];
|
||||||
c_vals = &mut c_vals[c_idx..];
|
c_vals = &mut c_vals[c_idx..];
|
||||||
}
|
}
|
||||||
|
@ -106,14 +106,14 @@ where
|
||||||
Op::Transpose(a) => {
|
Op::Transpose(a) => {
|
||||||
if beta != T::one() {
|
if beta != T::one() {
|
||||||
for c_ij in c.values_mut() {
|
for c_ij in c.values_mut() {
|
||||||
*c_ij *= beta.inlined_clone();
|
*c_ij *= beta.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, a_lane_i) in a.lane_iter().enumerate() {
|
for (i, a_lane_i) in a.lane_iter().enumerate() {
|
||||||
for (&j, a_val) in a_lane_i.minor_indices().iter().zip(a_lane_i.values()) {
|
for (&j, a_val) in a_lane_i.minor_indices().iter().zip(a_lane_i.values()) {
|
||||||
let a_val = a_val.inlined_clone();
|
let a_val = a_val.clone();
|
||||||
let alpha = alpha.inlined_clone();
|
let alpha = alpha.clone();
|
||||||
match c.get_entry_mut(j, i).unwrap() {
|
match c.get_entry_mut(j, i).unwrap() {
|
||||||
SparseEntryMut::NonZero(c_ji) => *c_ji += alpha * a_val,
|
SparseEntryMut::NonZero(c_ji) => *c_ji += alpha * a_val,
|
||||||
SparseEntryMut::Zero => return Err(spadd_cs_unexpected_entry()),
|
SparseEntryMut::Zero => return Err(spadd_cs_unexpected_entry()),
|
||||||
|
@ -149,10 +149,9 @@ pub fn spmm_cs_dense<T>(
|
||||||
Op::NoOp(ref b) => b.index((k, j)),
|
Op::NoOp(ref b) => b.index((k, j)),
|
||||||
Op::Transpose(ref b) => b.index((j, k)),
|
Op::Transpose(ref b) => b.index((j, k)),
|
||||||
};
|
};
|
||||||
dot_ij += a_ik.inlined_clone() * b_contrib.inlined_clone();
|
dot_ij += a_ik.clone() * b_contrib.clone();
|
||||||
}
|
}
|
||||||
*c_ij = beta.inlined_clone() * c_ij.inlined_clone()
|
*c_ij = beta.clone() * c_ij.clone() + alpha.clone() * dot_ij;
|
||||||
+ alpha.inlined_clone() * dot_ij;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,19 +162,19 @@ pub fn spmm_cs_dense<T>(
|
||||||
for k in 0..a.pattern().major_dim() {
|
for k in 0..a.pattern().major_dim() {
|
||||||
let a_row_k = a.get_lane(k).unwrap();
|
let a_row_k = a.get_lane(k).unwrap();
|
||||||
for (&i, a_ki) in a_row_k.minor_indices().iter().zip(a_row_k.values()) {
|
for (&i, a_ki) in a_row_k.minor_indices().iter().zip(a_row_k.values()) {
|
||||||
let gamma_ki = alpha.inlined_clone() * a_ki.inlined_clone();
|
let gamma_ki = alpha.clone() * a_ki.clone();
|
||||||
let mut c_row_i = c.row_mut(i);
|
let mut c_row_i = c.row_mut(i);
|
||||||
match b {
|
match b {
|
||||||
Op::NoOp(ref b) => {
|
Op::NoOp(ref b) => {
|
||||||
let b_row_k = b.row(k);
|
let b_row_k = b.row(k);
|
||||||
for (c_ij, b_kj) in c_row_i.iter_mut().zip(b_row_k.iter()) {
|
for (c_ij, b_kj) in c_row_i.iter_mut().zip(b_row_k.iter()) {
|
||||||
*c_ij += gamma_ki.inlined_clone() * b_kj.inlined_clone();
|
*c_ij += gamma_ki.clone() * b_kj.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Op::Transpose(ref b) => {
|
Op::Transpose(ref b) => {
|
||||||
let b_col_k = b.column(k);
|
let b_col_k = b.column(k);
|
||||||
for (c_ij, b_jk) in c_row_i.iter_mut().zip(b_col_k.iter()) {
|
for (c_ij, b_jk) in c_row_i.iter_mut().zip(b_col_k.iter()) {
|
||||||
*c_ij += gamma_ki.inlined_clone() * b_jk.inlined_clone();
|
*c_ij += gamma_ki.clone() * b_jk.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,13 +165,13 @@ fn spsolve_csc_lower_triangular_no_transpose<T: RealField>(
|
||||||
// a severe penalty)
|
// a severe penalty)
|
||||||
let diag_csc_index = l_col_k.row_indices().iter().position(|&i| i == k);
|
let diag_csc_index = l_col_k.row_indices().iter().position(|&i| i == k);
|
||||||
if let Some(diag_csc_index) = diag_csc_index {
|
if let Some(diag_csc_index) = diag_csc_index {
|
||||||
let l_kk = l_col_k.values()[diag_csc_index];
|
let l_kk = l_col_k.values()[diag_csc_index].clone();
|
||||||
|
|
||||||
if l_kk != T::zero() {
|
if l_kk != T::zero() {
|
||||||
// Update entry associated with diagonal
|
// Update entry associated with diagonal
|
||||||
x_col_j[k] /= l_kk;
|
x_col_j[k] /= l_kk;
|
||||||
// Copy value after updating (so we don't run into the borrow checker)
|
// Copy value after updating (so we don't run into the borrow checker)
|
||||||
let x_kj = x_col_j[k];
|
let x_kj = x_col_j[k].clone();
|
||||||
|
|
||||||
let row_indices = &l_col_k.row_indices()[(diag_csc_index + 1)..];
|
let row_indices = &l_col_k.row_indices()[(diag_csc_index + 1)..];
|
||||||
let l_values = &l_col_k.values()[(diag_csc_index + 1)..];
|
let l_values = &l_col_k.values()[(diag_csc_index + 1)..];
|
||||||
|
@ -179,7 +179,7 @@ fn spsolve_csc_lower_triangular_no_transpose<T: RealField>(
|
||||||
// Note: The remaining entries are below the diagonal
|
// Note: The remaining entries are below the diagonal
|
||||||
for (&i, l_ik) in row_indices.iter().zip(l_values) {
|
for (&i, l_ik) in row_indices.iter().zip(l_values) {
|
||||||
let x_ij = &mut x_col_j[i];
|
let x_ij = &mut x_col_j[i];
|
||||||
*x_ij -= l_ik.inlined_clone() * x_kj;
|
*x_ij -= l_ik.clone() * x_kj.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
x_col_j[k] = x_kj;
|
x_col_j[k] = x_kj;
|
||||||
|
@ -223,22 +223,22 @@ fn spsolve_csc_lower_triangular_transpose<T: RealField>(
|
||||||
// TODO: Can use exponential search here to quickly skip entries
|
// TODO: Can use exponential search here to quickly skip entries
|
||||||
let diag_csc_index = l_col_i.row_indices().iter().position(|&k| i == k);
|
let diag_csc_index = l_col_i.row_indices().iter().position(|&k| i == k);
|
||||||
if let Some(diag_csc_index) = diag_csc_index {
|
if let Some(diag_csc_index) = diag_csc_index {
|
||||||
let l_ii = l_col_i.values()[diag_csc_index];
|
let l_ii = l_col_i.values()[diag_csc_index].clone();
|
||||||
|
|
||||||
if l_ii != T::zero() {
|
if l_ii != T::zero() {
|
||||||
// // Update entry associated with diagonal
|
// // Update entry associated with diagonal
|
||||||
// x_col_j[k] /= a_kk;
|
// x_col_j[k] /= a_kk;
|
||||||
|
|
||||||
// Copy value after updating (so we don't run into the borrow checker)
|
// Copy value after updating (so we don't run into the borrow checker)
|
||||||
let mut x_ii = x_col_j[i];
|
let mut x_ii = x_col_j[i].clone();
|
||||||
|
|
||||||
let row_indices = &l_col_i.row_indices()[(diag_csc_index + 1)..];
|
let row_indices = &l_col_i.row_indices()[(diag_csc_index + 1)..];
|
||||||
let a_values = &l_col_i.values()[(diag_csc_index + 1)..];
|
let a_values = &l_col_i.values()[(diag_csc_index + 1)..];
|
||||||
|
|
||||||
// Note: The remaining entries are below the diagonal
|
// Note: The remaining entries are below the diagonal
|
||||||
for (&k, &l_ki) in row_indices.iter().zip(a_values) {
|
for (k, l_ki) in row_indices.iter().zip(a_values) {
|
||||||
let x_kj = x_col_j[k];
|
let x_kj = x_col_j[*k].clone();
|
||||||
x_ii -= l_ki * x_kj;
|
x_ii -= l_ki.clone() * x_kj;
|
||||||
}
|
}
|
||||||
|
|
||||||
x_col_j[i] = x_ii / l_ii;
|
x_col_j[i] = x_ii / l_ii;
|
||||||
|
|
121
src/base/blas.rs
121
src/base/blas.rs
|
@ -47,36 +47,36 @@ where
|
||||||
// because the `for` loop below won't be very efficient on those.
|
// because the `for` loop below won't be very efficient on those.
|
||||||
if (R::is::<U2>() || R2::is::<U2>()) && (C::is::<U1>() || C2::is::<U1>()) {
|
if (R::is::<U2>() || R2::is::<U2>()) && (C::is::<U1>() || C2::is::<U1>()) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let a = conjugate(self.get_unchecked((0, 0)).inlined_clone())
|
let a = conjugate(self.get_unchecked((0, 0)).clone())
|
||||||
* rhs.get_unchecked((0, 0)).inlined_clone();
|
* rhs.get_unchecked((0, 0)).clone();
|
||||||
let b = conjugate(self.get_unchecked((1, 0)).inlined_clone())
|
let b = conjugate(self.get_unchecked((1, 0)).clone())
|
||||||
* rhs.get_unchecked((1, 0)).inlined_clone();
|
* rhs.get_unchecked((1, 0)).clone();
|
||||||
|
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (R::is::<U3>() || R2::is::<U3>()) && (C::is::<U1>() || C2::is::<U1>()) {
|
if (R::is::<U3>() || R2::is::<U3>()) && (C::is::<U1>() || C2::is::<U1>()) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let a = conjugate(self.get_unchecked((0, 0)).inlined_clone())
|
let a = conjugate(self.get_unchecked((0, 0)).clone())
|
||||||
* rhs.get_unchecked((0, 0)).inlined_clone();
|
* rhs.get_unchecked((0, 0)).clone();
|
||||||
let b = conjugate(self.get_unchecked((1, 0)).inlined_clone())
|
let b = conjugate(self.get_unchecked((1, 0)).clone())
|
||||||
* rhs.get_unchecked((1, 0)).inlined_clone();
|
* rhs.get_unchecked((1, 0)).clone();
|
||||||
let c = conjugate(self.get_unchecked((2, 0)).inlined_clone())
|
let c = conjugate(self.get_unchecked((2, 0)).clone())
|
||||||
* rhs.get_unchecked((2, 0)).inlined_clone();
|
* rhs.get_unchecked((2, 0)).clone();
|
||||||
|
|
||||||
return a + b + c;
|
return a + b + c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (R::is::<U4>() || R2::is::<U4>()) && (C::is::<U1>() || C2::is::<U1>()) {
|
if (R::is::<U4>() || R2::is::<U4>()) && (C::is::<U1>() || C2::is::<U1>()) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut a = conjugate(self.get_unchecked((0, 0)).inlined_clone())
|
let mut a = conjugate(self.get_unchecked((0, 0)).clone())
|
||||||
* rhs.get_unchecked((0, 0)).inlined_clone();
|
* rhs.get_unchecked((0, 0)).clone();
|
||||||
let mut b = conjugate(self.get_unchecked((1, 0)).inlined_clone())
|
let mut b = conjugate(self.get_unchecked((1, 0)).clone())
|
||||||
* rhs.get_unchecked((1, 0)).inlined_clone();
|
* rhs.get_unchecked((1, 0)).clone();
|
||||||
let c = conjugate(self.get_unchecked((2, 0)).inlined_clone())
|
let c = conjugate(self.get_unchecked((2, 0)).clone())
|
||||||
* rhs.get_unchecked((2, 0)).inlined_clone();
|
* rhs.get_unchecked((2, 0)).clone();
|
||||||
let d = conjugate(self.get_unchecked((3, 0)).inlined_clone())
|
let d = conjugate(self.get_unchecked((3, 0)).clone())
|
||||||
* rhs.get_unchecked((3, 0)).inlined_clone();
|
* rhs.get_unchecked((3, 0)).clone();
|
||||||
|
|
||||||
a += c;
|
a += c;
|
||||||
b += d;
|
b += d;
|
||||||
|
@ -117,36 +117,36 @@ where
|
||||||
|
|
||||||
while self.nrows() - i >= 8 {
|
while self.nrows() - i >= 8 {
|
||||||
acc0 += unsafe {
|
acc0 += unsafe {
|
||||||
conjugate(self.get_unchecked((i, j)).inlined_clone())
|
conjugate(self.get_unchecked((i, j)).clone())
|
||||||
* rhs.get_unchecked((i, j)).inlined_clone()
|
* rhs.get_unchecked((i, j)).clone()
|
||||||
};
|
};
|
||||||
acc1 += unsafe {
|
acc1 += unsafe {
|
||||||
conjugate(self.get_unchecked((i + 1, j)).inlined_clone())
|
conjugate(self.get_unchecked((i + 1, j)).clone())
|
||||||
* rhs.get_unchecked((i + 1, j)).inlined_clone()
|
* rhs.get_unchecked((i + 1, j)).clone()
|
||||||
};
|
};
|
||||||
acc2 += unsafe {
|
acc2 += unsafe {
|
||||||
conjugate(self.get_unchecked((i + 2, j)).inlined_clone())
|
conjugate(self.get_unchecked((i + 2, j)).clone())
|
||||||
* rhs.get_unchecked((i + 2, j)).inlined_clone()
|
* rhs.get_unchecked((i + 2, j)).clone()
|
||||||
};
|
};
|
||||||
acc3 += unsafe {
|
acc3 += unsafe {
|
||||||
conjugate(self.get_unchecked((i + 3, j)).inlined_clone())
|
conjugate(self.get_unchecked((i + 3, j)).clone())
|
||||||
* rhs.get_unchecked((i + 3, j)).inlined_clone()
|
* rhs.get_unchecked((i + 3, j)).clone()
|
||||||
};
|
};
|
||||||
acc4 += unsafe {
|
acc4 += unsafe {
|
||||||
conjugate(self.get_unchecked((i + 4, j)).inlined_clone())
|
conjugate(self.get_unchecked((i + 4, j)).clone())
|
||||||
* rhs.get_unchecked((i + 4, j)).inlined_clone()
|
* rhs.get_unchecked((i + 4, j)).clone()
|
||||||
};
|
};
|
||||||
acc5 += unsafe {
|
acc5 += unsafe {
|
||||||
conjugate(self.get_unchecked((i + 5, j)).inlined_clone())
|
conjugate(self.get_unchecked((i + 5, j)).clone())
|
||||||
* rhs.get_unchecked((i + 5, j)).inlined_clone()
|
* rhs.get_unchecked((i + 5, j)).clone()
|
||||||
};
|
};
|
||||||
acc6 += unsafe {
|
acc6 += unsafe {
|
||||||
conjugate(self.get_unchecked((i + 6, j)).inlined_clone())
|
conjugate(self.get_unchecked((i + 6, j)).clone())
|
||||||
* rhs.get_unchecked((i + 6, j)).inlined_clone()
|
* rhs.get_unchecked((i + 6, j)).clone()
|
||||||
};
|
};
|
||||||
acc7 += unsafe {
|
acc7 += unsafe {
|
||||||
conjugate(self.get_unchecked((i + 7, j)).inlined_clone())
|
conjugate(self.get_unchecked((i + 7, j)).clone())
|
||||||
* rhs.get_unchecked((i + 7, j)).inlined_clone()
|
* rhs.get_unchecked((i + 7, j)).clone()
|
||||||
};
|
};
|
||||||
i += 8;
|
i += 8;
|
||||||
}
|
}
|
||||||
|
@ -158,8 +158,8 @@ where
|
||||||
|
|
||||||
for k in i..self.nrows() {
|
for k in i..self.nrows() {
|
||||||
res += unsafe {
|
res += unsafe {
|
||||||
conjugate(self.get_unchecked((k, j)).inlined_clone())
|
conjugate(self.get_unchecked((k, j)).clone())
|
||||||
* rhs.get_unchecked((k, j)).inlined_clone()
|
* rhs.get_unchecked((k, j)).clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,8 +266,7 @@ where
|
||||||
for j in 0..self.nrows() {
|
for j in 0..self.nrows() {
|
||||||
for i in 0..self.ncols() {
|
for i in 0..self.ncols() {
|
||||||
res += unsafe {
|
res += unsafe {
|
||||||
self.get_unchecked((j, i)).inlined_clone()
|
self.get_unchecked((j, i)).clone() * rhs.get_unchecked((i, j)).clone()
|
||||||
* rhs.get_unchecked((i, j)).inlined_clone()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -398,9 +397,9 @@ where
|
||||||
|
|
||||||
// TODO: avoid bound checks.
|
// TODO: avoid bound checks.
|
||||||
let col2 = a.column(0);
|
let col2 = a.column(0);
|
||||||
let val = unsafe { x.vget_unchecked(0).inlined_clone() };
|
let val = unsafe { x.vget_unchecked(0).clone() };
|
||||||
self.axpy(alpha.inlined_clone() * val, &col2, beta);
|
self.axpy(alpha.clone() * val, &col2, beta);
|
||||||
self[0] += alpha.inlined_clone() * dot(&a.slice_range(1.., 0), &x.rows_range(1..));
|
self[0] += alpha.clone() * dot(&a.slice_range(1.., 0), &x.rows_range(1..));
|
||||||
|
|
||||||
for j in 1..dim2 {
|
for j in 1..dim2 {
|
||||||
let col2 = a.column(j);
|
let col2 = a.column(j);
|
||||||
|
@ -408,11 +407,11 @@ where
|
||||||
|
|
||||||
let val;
|
let val;
|
||||||
unsafe {
|
unsafe {
|
||||||
val = x.vget_unchecked(j).inlined_clone();
|
val = x.vget_unchecked(j).clone();
|
||||||
*self.vget_unchecked_mut(j) += alpha.inlined_clone() * dot;
|
*self.vget_unchecked_mut(j) += alpha.clone() * dot;
|
||||||
}
|
}
|
||||||
self.rows_range_mut(j + 1..).axpy(
|
self.rows_range_mut(j + 1..).axpy(
|
||||||
alpha.inlined_clone() * val,
|
alpha.clone() * val,
|
||||||
&col2.rows_range(j + 1..),
|
&col2.rows_range(j + 1..),
|
||||||
T::one(),
|
T::one(),
|
||||||
);
|
);
|
||||||
|
@ -538,13 +537,12 @@ where
|
||||||
if beta.is_zero() {
|
if beta.is_zero() {
|
||||||
for j in 0..ncols2 {
|
for j in 0..ncols2 {
|
||||||
let val = unsafe { self.vget_unchecked_mut(j) };
|
let val = unsafe { self.vget_unchecked_mut(j) };
|
||||||
*val = alpha.inlined_clone() * dot(&a.column(j), x)
|
*val = alpha.clone() * dot(&a.column(j), x)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for j in 0..ncols2 {
|
for j in 0..ncols2 {
|
||||||
let val = unsafe { self.vget_unchecked_mut(j) };
|
let val = unsafe { self.vget_unchecked_mut(j) };
|
||||||
*val = alpha.inlined_clone() * dot(&a.column(j), x)
|
*val = alpha.clone() * dot(&a.column(j), x) + beta.clone() * val.clone();
|
||||||
+ beta.inlined_clone() * val.inlined_clone();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -648,9 +646,9 @@ where
|
||||||
|
|
||||||
for j in 0..ncols1 {
|
for j in 0..ncols1 {
|
||||||
// TODO: avoid bound checks.
|
// TODO: avoid bound checks.
|
||||||
let val = unsafe { conjugate(y.vget_unchecked(j).inlined_clone()) };
|
let val = unsafe { conjugate(y.vget_unchecked(j).clone()) };
|
||||||
self.column_mut(j)
|
self.column_mut(j)
|
||||||
.axpy(alpha.inlined_clone() * val, x, beta.inlined_clone());
|
.axpy(alpha.clone() * val, x, beta.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,12 +811,8 @@ where
|
||||||
|
|
||||||
for j1 in 0..ncols1 {
|
for j1 in 0..ncols1 {
|
||||||
// TODO: avoid bound checks.
|
// TODO: avoid bound checks.
|
||||||
self.column_mut(j1).gemv_tr(
|
self.column_mut(j1)
|
||||||
alpha.inlined_clone(),
|
.gemv_tr(alpha.clone(), a, &b.column(j1), beta.clone());
|
||||||
a,
|
|
||||||
&b.column(j1),
|
|
||||||
beta.inlined_clone(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -875,7 +869,8 @@ where
|
||||||
|
|
||||||
for j1 in 0..ncols1 {
|
for j1 in 0..ncols1 {
|
||||||
// TODO: avoid bound checks.
|
// TODO: avoid bound checks.
|
||||||
self.column_mut(j1).gemv_ad(alpha, a, &b.column(j1), beta);
|
self.column_mut(j1)
|
||||||
|
.gemv_ad(alpha.clone(), a, &b.column(j1), beta.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -909,13 +904,13 @@ where
|
||||||
assert!(dim1 == dim2 && dim1 == dim3, "ger: dimensions mismatch.");
|
assert!(dim1 == dim2 && dim1 == dim3, "ger: dimensions mismatch.");
|
||||||
|
|
||||||
for j in 0..dim1 {
|
for j in 0..dim1 {
|
||||||
let val = unsafe { conjugate(y.vget_unchecked(j).inlined_clone()) };
|
let val = unsafe { conjugate(y.vget_unchecked(j).clone()) };
|
||||||
let subdim = Dynamic::new(dim1 - j);
|
let subdim = Dynamic::new(dim1 - j);
|
||||||
// TODO: avoid bound checks.
|
// TODO: avoid bound checks.
|
||||||
self.generic_slice_mut((j, j), (subdim, Const::<1>)).axpy(
|
self.generic_slice_mut((j, j), (subdim, Const::<1>)).axpy(
|
||||||
alpha.inlined_clone() * val,
|
alpha.clone() * val,
|
||||||
&x.rows_range(j..),
|
&x.rows_range(j..),
|
||||||
beta.inlined_clone(),
|
beta.clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1076,11 +1071,11 @@ where
|
||||||
ShapeConstraint: DimEq<D1, D2> + DimEq<D1, R3> + DimEq<D2, R3> + DimEq<C3, D4>,
|
ShapeConstraint: DimEq<D1, D2> + DimEq<D1, R3> + DimEq<D2, R3> + DimEq<C3, D4>,
|
||||||
{
|
{
|
||||||
work.gemv(T::one(), lhs, &mid.column(0), T::zero());
|
work.gemv(T::one(), lhs, &mid.column(0), T::zero());
|
||||||
self.ger(alpha.inlined_clone(), work, &lhs.column(0), beta);
|
self.ger(alpha.clone(), work, &lhs.column(0), beta);
|
||||||
|
|
||||||
for j in 1..mid.ncols() {
|
for j in 1..mid.ncols() {
|
||||||
work.gemv(T::one(), lhs, &mid.column(j), T::zero());
|
work.gemv(T::one(), lhs, &mid.column(j), T::zero());
|
||||||
self.ger(alpha.inlined_clone(), work, &lhs.column(j), T::one());
|
self.ger(alpha.clone(), work, &lhs.column(j), T::one());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1170,12 +1165,12 @@ where
|
||||||
{
|
{
|
||||||
work.gemv(T::one(), mid, &rhs.column(0), T::zero());
|
work.gemv(T::one(), mid, &rhs.column(0), T::zero());
|
||||||
self.column_mut(0)
|
self.column_mut(0)
|
||||||
.gemv_tr(alpha.inlined_clone(), rhs, work, beta.inlined_clone());
|
.gemv_tr(alpha.clone(), rhs, work, beta.clone());
|
||||||
|
|
||||||
for j in 1..rhs.ncols() {
|
for j in 1..rhs.ncols() {
|
||||||
work.gemv(T::one(), mid, &rhs.column(j), T::zero());
|
work.gemv(T::one(), mid, &rhs.column(j), T::zero());
|
||||||
self.column_mut(j)
|
self.column_mut(j)
|
||||||
.gemv_tr(alpha.inlined_clone(), rhs, work, beta.inlined_clone());
|
.gemv_tr(alpha.clone(), rhs, work, beta.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,8 @@ unsafe fn array_axcpy<Status, T>(
|
||||||
{
|
{
|
||||||
for i in 0..len {
|
for i in 0..len {
|
||||||
let y = Status::assume_init_mut(y.get_unchecked_mut(i * stride1));
|
let y = Status::assume_init_mut(y.get_unchecked_mut(i * stride1));
|
||||||
*y = a.inlined_clone() * x.get_unchecked(i * stride2).inlined_clone() * c.inlined_clone()
|
*y =
|
||||||
+ beta.inlined_clone() * y.inlined_clone();
|
a.clone() * x.get_unchecked(i * stride2).clone() * c.clone() + beta.clone() * y.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,9 +66,7 @@ fn array_axc<Status, T>(
|
||||||
unsafe {
|
unsafe {
|
||||||
Status::init(
|
Status::init(
|
||||||
y.get_unchecked_mut(i * stride1),
|
y.get_unchecked_mut(i * stride1),
|
||||||
a.inlined_clone()
|
a.clone() * x.get_unchecked(i * stride2).clone() * c.clone(),
|
||||||
* x.get_unchecked(i * stride2).inlined_clone()
|
|
||||||
* c.inlined_clone(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,24 +148,24 @@ pub unsafe fn gemv_uninit<Status, T, D1: Dim, R2: Dim, C2: Dim, D3: Dim, SA, SB,
|
||||||
y.apply(|e| Status::init(e, T::zero()));
|
y.apply(|e| Status::init(e, T::zero()));
|
||||||
} else {
|
} else {
|
||||||
// SAFETY: this is UB if y is uninitialized.
|
// SAFETY: this is UB if y is uninitialized.
|
||||||
y.apply(|e| *Status::assume_init_mut(e) *= beta.inlined_clone());
|
y.apply(|e| *Status::assume_init_mut(e) *= beta.clone());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: avoid bound checks.
|
// TODO: avoid bound checks.
|
||||||
let col2 = a.column(0);
|
let col2 = a.column(0);
|
||||||
let val = x.vget_unchecked(0).inlined_clone();
|
let val = x.vget_unchecked(0).clone();
|
||||||
|
|
||||||
// SAFETY: this is the call that makes this method unsafe: it is UB if Status = Uninit and beta != 0.
|
// SAFETY: this is the call that makes this method unsafe: it is UB if Status = Uninit and beta != 0.
|
||||||
axcpy_uninit(status, y, alpha.inlined_clone(), &col2, val, beta);
|
axcpy_uninit(status, y, alpha.clone(), &col2, val, beta);
|
||||||
|
|
||||||
for j in 1..ncols2 {
|
for j in 1..ncols2 {
|
||||||
let col2 = a.column(j);
|
let col2 = a.column(j);
|
||||||
let val = x.vget_unchecked(j).inlined_clone();
|
let val = x.vget_unchecked(j).clone();
|
||||||
|
|
||||||
// SAFETY: safe because y was initialized above.
|
// SAFETY: safe because y was initialized above.
|
||||||
axcpy_uninit(status, y, alpha.inlined_clone(), &col2, val, T::one());
|
axcpy_uninit(status, y, alpha.clone(), &col2, val, T::one());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +252,7 @@ pub unsafe fn gemm_uninit<
|
||||||
y.apply(|e| Status::init(e, T::zero()));
|
y.apply(|e| Status::init(e, T::zero()));
|
||||||
} else {
|
} else {
|
||||||
// SAFETY: this is UB if Status = Uninit
|
// SAFETY: this is UB if Status = Uninit
|
||||||
y.apply(|e| *Status::assume_init_mut(e) *= beta.inlined_clone());
|
y.apply(|e| *Status::assume_init_mut(e) *= beta.clone());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -314,10 +312,10 @@ pub unsafe fn gemm_uninit<
|
||||||
gemv_uninit(
|
gemv_uninit(
|
||||||
status,
|
status,
|
||||||
&mut y.column_mut(j1),
|
&mut y.column_mut(j1),
|
||||||
alpha.inlined_clone(),
|
alpha.clone(),
|
||||||
a,
|
a,
|
||||||
&b.column(j1),
|
&b.column(j1),
|
||||||
beta.inlined_clone(),
|
beta.clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ where
|
||||||
{
|
{
|
||||||
let mut res = Self::identity();
|
let mut res = Self::identity();
|
||||||
for i in 0..scaling.len() {
|
for i in 0..scaling.len() {
|
||||||
res[(i, i)] = scaling[i].inlined_clone();
|
res[(i, i)] = scaling[i].clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -85,13 +85,13 @@ impl<T: RealField> Matrix3<T> {
|
||||||
let zero = T::zero();
|
let zero = T::zero();
|
||||||
let one = T::one();
|
let one = T::one();
|
||||||
Matrix3::new(
|
Matrix3::new(
|
||||||
scaling.x,
|
scaling.x.clone(),
|
||||||
zero,
|
zero.clone(),
|
||||||
pt.x - pt.x * scaling.x,
|
pt.x.clone() - pt.x.clone() * scaling.x.clone(),
|
||||||
zero,
|
zero.clone(),
|
||||||
scaling.y,
|
scaling.y.clone(),
|
||||||
pt.y - pt.y * scaling.y,
|
pt.y.clone() - pt.y.clone() * scaling.y.clone(),
|
||||||
zero,
|
zero.clone(),
|
||||||
zero,
|
zero,
|
||||||
one,
|
one,
|
||||||
)
|
)
|
||||||
|
@ -125,20 +125,20 @@ impl<T: RealField> Matrix4<T> {
|
||||||
let zero = T::zero();
|
let zero = T::zero();
|
||||||
let one = T::one();
|
let one = T::one();
|
||||||
Matrix4::new(
|
Matrix4::new(
|
||||||
scaling.x,
|
scaling.x.clone(),
|
||||||
zero,
|
zero.clone(),
|
||||||
zero,
|
zero.clone(),
|
||||||
pt.x - pt.x * scaling.x,
|
pt.x.clone() - pt.x.clone() * scaling.x.clone(),
|
||||||
zero,
|
zero.clone(),
|
||||||
scaling.y,
|
scaling.y.clone(),
|
||||||
zero,
|
zero.clone(),
|
||||||
pt.y - pt.y * scaling.y,
|
pt.y.clone() - pt.y.clone() * scaling.y.clone(),
|
||||||
zero,
|
zero.clone(),
|
||||||
zero,
|
zero.clone(),
|
||||||
scaling.z,
|
scaling.z.clone(),
|
||||||
pt.z - pt.z * scaling.z,
|
pt.z.clone() - pt.z.clone() * scaling.z.clone(),
|
||||||
zero,
|
zero.clone(),
|
||||||
zero,
|
zero.clone(),
|
||||||
zero,
|
zero,
|
||||||
one,
|
one,
|
||||||
)
|
)
|
||||||
|
@ -336,7 +336,7 @@ impl<T: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<T, D
|
||||||
{
|
{
|
||||||
for i in 0..scaling.len() {
|
for i in 0..scaling.len() {
|
||||||
let mut to_scale = self.fixed_rows_mut::<1>(i);
|
let mut to_scale = self.fixed_rows_mut::<1>(i);
|
||||||
to_scale *= scaling[i].inlined_clone();
|
to_scale *= scaling[i].clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,7 +352,7 @@ impl<T: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<T, D
|
||||||
{
|
{
|
||||||
for i in 0..scaling.len() {
|
for i in 0..scaling.len() {
|
||||||
let mut to_scale = self.fixed_columns_mut::<1>(i);
|
let mut to_scale = self.fixed_columns_mut::<1>(i);
|
||||||
to_scale *= scaling[i].inlined_clone();
|
to_scale *= scaling[i].clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,7 +366,7 @@ impl<T: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<T, D
|
||||||
{
|
{
|
||||||
for i in 0..D::dim() {
|
for i in 0..D::dim() {
|
||||||
for j in 0..D::dim() - 1 {
|
for j in 0..D::dim() - 1 {
|
||||||
let add = shift[j].inlined_clone() * self[(D::dim() - 1, i)].inlined_clone();
|
let add = shift[j].clone() * self[(D::dim() - 1, i)].clone();
|
||||||
self[(j, i)] += add;
|
self[(j, i)] += add;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -440,7 +440,7 @@ impl<T: RealField, S: Storage<T, Const<3>, Const<3>>> SquareMatrix<T, Const<3>,
|
||||||
let transform = self.fixed_slice::<2, 2>(0, 0);
|
let transform = self.fixed_slice::<2, 2>(0, 0);
|
||||||
let translation = self.fixed_slice::<2, 1>(0, 2);
|
let translation = self.fixed_slice::<2, 1>(0, 2);
|
||||||
let normalizer = self.fixed_slice::<1, 2>(2, 0);
|
let normalizer = self.fixed_slice::<1, 2>(2, 0);
|
||||||
let n = normalizer.tr_dot(&pt.coords) + unsafe { *self.get_unchecked((2, 2)) };
|
let n = normalizer.tr_dot(&pt.coords) + unsafe { self.get_unchecked((2, 2)).clone() };
|
||||||
|
|
||||||
if !n.is_zero() {
|
if !n.is_zero() {
|
||||||
(transform * pt + translation) / n
|
(transform * pt + translation) / n
|
||||||
|
@ -457,7 +457,7 @@ impl<T: RealField, S: Storage<T, Const<4>, Const<4>>> SquareMatrix<T, Const<4>,
|
||||||
let transform = self.fixed_slice::<3, 3>(0, 0);
|
let transform = self.fixed_slice::<3, 3>(0, 0);
|
||||||
let translation = self.fixed_slice::<3, 1>(0, 3);
|
let translation = self.fixed_slice::<3, 1>(0, 3);
|
||||||
let normalizer = self.fixed_slice::<1, 3>(3, 0);
|
let normalizer = self.fixed_slice::<1, 3>(3, 0);
|
||||||
let n = normalizer.tr_dot(&pt.coords) + unsafe { *self.get_unchecked((3, 3)) };
|
let n = normalizer.tr_dot(&pt.coords) + unsafe { self.get_unchecked((3, 3)).clone() };
|
||||||
|
|
||||||
if !n.is_zero() {
|
if !n.is_zero() {
|
||||||
(transform * pt + translation) / n
|
(transform * pt + translation) / n
|
||||||
|
|
|
@ -64,7 +64,7 @@ macro_rules! component_binop_impl(
|
||||||
for j in 0 .. res.ncols() {
|
for j in 0 .. res.ncols() {
|
||||||
for i in 0 .. res.nrows() {
|
for i in 0 .. res.nrows() {
|
||||||
unsafe {
|
unsafe {
|
||||||
res.get_unchecked_mut((i, j)).$op_assign(rhs.get_unchecked((i, j)).inlined_clone());
|
res.get_unchecked_mut((i, j)).$op_assign(rhs.get_unchecked((i, j)).clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ macro_rules! component_binop_impl(
|
||||||
for j in 0 .. self.ncols() {
|
for j in 0 .. self.ncols() {
|
||||||
for i in 0 .. self.nrows() {
|
for i in 0 .. self.nrows() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let res = alpha.inlined_clone() * a.get_unchecked((i, j)).inlined_clone().$op(b.get_unchecked((i, j)).inlined_clone());
|
let res = alpha.clone() * a.get_unchecked((i, j)).clone().$op(b.get_unchecked((i, j)).clone());
|
||||||
*self.get_unchecked_mut((i, j)) = res;
|
*self.get_unchecked_mut((i, j)) = res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,8 +101,8 @@ macro_rules! component_binop_impl(
|
||||||
for j in 0 .. self.ncols() {
|
for j in 0 .. self.ncols() {
|
||||||
for i in 0 .. self.nrows() {
|
for i in 0 .. self.nrows() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let res = alpha.inlined_clone() * a.get_unchecked((i, j)).inlined_clone().$op(b.get_unchecked((i, j)).inlined_clone());
|
let res = alpha.clone() * a.get_unchecked((i, j)).clone().$op(b.get_unchecked((i, j)).clone());
|
||||||
*self.get_unchecked_mut((i, j)) = beta.inlined_clone() * self.get_unchecked((i, j)).inlined_clone() + res;
|
*self.get_unchecked_mut((i, j)) = beta.clone() * self.get_unchecked((i, j)).clone() + res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ macro_rules! component_binop_impl(
|
||||||
for j in 0 .. self.ncols() {
|
for j in 0 .. self.ncols() {
|
||||||
for i in 0 .. self.nrows() {
|
for i in 0 .. self.nrows() {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.get_unchecked_mut((i, j)).$op_assign(rhs.get_unchecked((i, j)).inlined_clone());
|
self.get_unchecked_mut((i, j)).$op_assign(rhs.get_unchecked((i, j)).clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,7 +347,7 @@ impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA>
|
||||||
SA: StorageMut<T, R1, C1>,
|
SA: StorageMut<T, R1, C1>,
|
||||||
{
|
{
|
||||||
for e in self.iter_mut() {
|
for e in self.iter_mut() {
|
||||||
*e += rhs.inlined_clone()
|
*e += rhs.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,8 +104,7 @@ where
|
||||||
unsafe {
|
unsafe {
|
||||||
for i in 0..nrows.value() {
|
for i in 0..nrows.value() {
|
||||||
for j in 0..ncols.value() {
|
for j in 0..ncols.value() {
|
||||||
*res.get_unchecked_mut((i, j)) =
|
*res.get_unchecked_mut((i, j)) = MaybeUninit::new(iter.next().unwrap().clone())
|
||||||
MaybeUninit::new(iter.next().unwrap().inlined_clone())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +165,7 @@ where
|
||||||
let mut res = Self::zeros_generic(nrows, ncols);
|
let mut res = Self::zeros_generic(nrows, ncols);
|
||||||
|
|
||||||
for i in 0..crate::min(nrows.value(), ncols.value()) {
|
for i in 0..crate::min(nrows.value(), ncols.value()) {
|
||||||
unsafe { *res.get_unchecked_mut((i, i)) = elt.inlined_clone() }
|
unsafe { *res.get_unchecked_mut((i, i)) = elt.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -188,7 +187,7 @@ where
|
||||||
);
|
);
|
||||||
|
|
||||||
for (i, elt) in elts.iter().enumerate() {
|
for (i, elt) in elts.iter().enumerate() {
|
||||||
unsafe { *res.get_unchecked_mut((i, i)) = elt.inlined_clone() }
|
unsafe { *res.get_unchecked_mut((i, i)) = elt.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -232,7 +231,7 @@ where
|
||||||
|
|
||||||
// TODO: optimize that.
|
// TODO: optimize that.
|
||||||
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |i, j| {
|
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |i, j| {
|
||||||
rows[i][(0, j)].inlined_clone()
|
rows[i][(0, j)].clone()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +273,7 @@ where
|
||||||
|
|
||||||
// TODO: optimize that.
|
// TODO: optimize that.
|
||||||
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |i, j| {
|
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |i, j| {
|
||||||
columns[j][i].inlined_clone()
|
columns[j][i].clone()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,7 +357,7 @@ where
|
||||||
|
|
||||||
for i in 0..diag.len() {
|
for i in 0..diag.len() {
|
||||||
unsafe {
|
unsafe {
|
||||||
*res.get_unchecked_mut((i, i)) = diag.vget_unchecked(i).inlined_clone();
|
*res.get_unchecked_mut((i, i)) = diag.vget_unchecked(i).clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -509,11 +509,7 @@ where
|
||||||
let (nrows, ncols) = arr[0].shape_generic();
|
let (nrows, ncols) = arr[0].shape_generic();
|
||||||
|
|
||||||
Self::from_fn_generic(nrows, ncols, |i, j| {
|
Self::from_fn_generic(nrows, ncols, |i, j| {
|
||||||
[
|
[arr[0][(i, j)].clone(), arr[1][(i, j)].clone()].into()
|
||||||
arr[0][(i, j)].inlined_clone(),
|
|
||||||
arr[1][(i, j)].inlined_clone(),
|
|
||||||
]
|
|
||||||
.into()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -531,10 +527,10 @@ where
|
||||||
|
|
||||||
Self::from_fn_generic(nrows, ncols, |i, j| {
|
Self::from_fn_generic(nrows, ncols, |i, j| {
|
||||||
[
|
[
|
||||||
arr[0][(i, j)].inlined_clone(),
|
arr[0][(i, j)].clone(),
|
||||||
arr[1][(i, j)].inlined_clone(),
|
arr[1][(i, j)].clone(),
|
||||||
arr[2][(i, j)].inlined_clone(),
|
arr[2][(i, j)].clone(),
|
||||||
arr[3][(i, j)].inlined_clone(),
|
arr[3][(i, j)].clone(),
|
||||||
]
|
]
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
|
@ -554,14 +550,14 @@ where
|
||||||
|
|
||||||
Self::from_fn_generic(nrows, ncols, |i, j| {
|
Self::from_fn_generic(nrows, ncols, |i, j| {
|
||||||
[
|
[
|
||||||
arr[0][(i, j)].inlined_clone(),
|
arr[0][(i, j)].clone(),
|
||||||
arr[1][(i, j)].inlined_clone(),
|
arr[1][(i, j)].clone(),
|
||||||
arr[2][(i, j)].inlined_clone(),
|
arr[2][(i, j)].clone(),
|
||||||
arr[3][(i, j)].inlined_clone(),
|
arr[3][(i, j)].clone(),
|
||||||
arr[4][(i, j)].inlined_clone(),
|
arr[4][(i, j)].clone(),
|
||||||
arr[5][(i, j)].inlined_clone(),
|
arr[5][(i, j)].clone(),
|
||||||
arr[6][(i, j)].inlined_clone(),
|
arr[6][(i, j)].clone(),
|
||||||
arr[7][(i, j)].inlined_clone(),
|
arr[7][(i, j)].clone(),
|
||||||
]
|
]
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
|
@ -580,22 +576,22 @@ where
|
||||||
|
|
||||||
Self::from_fn_generic(nrows, ncols, |i, j| {
|
Self::from_fn_generic(nrows, ncols, |i, j| {
|
||||||
[
|
[
|
||||||
arr[0][(i, j)].inlined_clone(),
|
arr[0][(i, j)].clone(),
|
||||||
arr[1][(i, j)].inlined_clone(),
|
arr[1][(i, j)].clone(),
|
||||||
arr[2][(i, j)].inlined_clone(),
|
arr[2][(i, j)].clone(),
|
||||||
arr[3][(i, j)].inlined_clone(),
|
arr[3][(i, j)].clone(),
|
||||||
arr[4][(i, j)].inlined_clone(),
|
arr[4][(i, j)].clone(),
|
||||||
arr[5][(i, j)].inlined_clone(),
|
arr[5][(i, j)].clone(),
|
||||||
arr[6][(i, j)].inlined_clone(),
|
arr[6][(i, j)].clone(),
|
||||||
arr[7][(i, j)].inlined_clone(),
|
arr[7][(i, j)].clone(),
|
||||||
arr[8][(i, j)].inlined_clone(),
|
arr[8][(i, j)].clone(),
|
||||||
arr[9][(i, j)].inlined_clone(),
|
arr[9][(i, j)].clone(),
|
||||||
arr[10][(i, j)].inlined_clone(),
|
arr[10][(i, j)].clone(),
|
||||||
arr[11][(i, j)].inlined_clone(),
|
arr[11][(i, j)].clone(),
|
||||||
arr[12][(i, j)].inlined_clone(),
|
arr[12][(i, j)].clone(),
|
||||||
arr[13][(i, j)].inlined_clone(),
|
arr[13][(i, j)].clone(),
|
||||||
arr[14][(i, j)].inlined_clone(),
|
arr[14][(i, j)].clone(),
|
||||||
arr[15][(i, j)].inlined_clone(),
|
arr[15][(i, j)].clone(),
|
||||||
]
|
]
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
|
|
|
@ -70,7 +70,7 @@ impl<T: Scalar + Zero, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
// Safety: all indices are in range.
|
// Safety: all indices are in range.
|
||||||
unsafe {
|
unsafe {
|
||||||
*res.vget_unchecked_mut(destination) =
|
*res.vget_unchecked_mut(destination) =
|
||||||
MaybeUninit::new(src.vget_unchecked(*source).inlined_clone());
|
MaybeUninit::new(src.vget_unchecked(*source).clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ impl<T: Scalar + Zero, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
// NOTE: this is basically a copy_frow but wrapping the values insnide of MaybeUninit.
|
// NOTE: this is basically a copy_frow but wrapping the values insnide of MaybeUninit.
|
||||||
res.column_mut(destination)
|
res.column_mut(destination)
|
||||||
.zip_apply(&self.column(*source), |out, e| {
|
.zip_apply(&self.column(*source), |out, e| {
|
||||||
*out = MaybeUninit::new(e.inlined_clone())
|
*out = MaybeUninit::new(e.clone())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||||
assert_eq!(diag.len(), min_nrows_ncols, "Mismatched dimensions.");
|
assert_eq!(diag.len(), min_nrows_ncols, "Mismatched dimensions.");
|
||||||
|
|
||||||
for i in 0..min_nrows_ncols {
|
for i in 0..min_nrows_ncols {
|
||||||
unsafe { *self.get_unchecked_mut((i, i)) = diag.vget_unchecked(i).inlined_clone() }
|
unsafe { *self.get_unchecked_mut((i, i)) = diag.vget_unchecked(i).clone() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||||
T: Scalar,
|
T: Scalar,
|
||||||
{
|
{
|
||||||
for e in self.iter_mut() {
|
for e in self.iter_mut() {
|
||||||
*e = val.inlined_clone()
|
*e = val.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||||
let n = cmp::min(nrows, ncols);
|
let n = cmp::min(nrows, ncols);
|
||||||
|
|
||||||
for i in 0..n {
|
for i in 0..n {
|
||||||
unsafe { *self.get_unchecked_mut((i, i)) = val.inlined_clone() }
|
unsafe { *self.get_unchecked_mut((i, i)) = val.clone() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||||
{
|
{
|
||||||
assert!(i < self.nrows(), "Row index out of bounds.");
|
assert!(i < self.nrows(), "Row index out of bounds.");
|
||||||
for j in 0..self.ncols() {
|
for j in 0..self.ncols() {
|
||||||
unsafe { *self.get_unchecked_mut((i, j)) = val.inlined_clone() }
|
unsafe { *self.get_unchecked_mut((i, j)) = val.clone() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +225,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||||
{
|
{
|
||||||
assert!(j < self.ncols(), "Row index out of bounds.");
|
assert!(j < self.ncols(), "Row index out of bounds.");
|
||||||
for i in 0..self.nrows() {
|
for i in 0..self.nrows() {
|
||||||
unsafe { *self.get_unchecked_mut((i, j)) = val.inlined_clone() }
|
unsafe { *self.get_unchecked_mut((i, j)) = val.clone() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||||
{
|
{
|
||||||
for j in 0..self.ncols() {
|
for j in 0..self.ncols() {
|
||||||
for i in (j + shift)..self.nrows() {
|
for i in (j + shift)..self.nrows() {
|
||||||
unsafe { *self.get_unchecked_mut((i, j)) = val.inlined_clone() }
|
unsafe { *self.get_unchecked_mut((i, j)) = val.clone() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -264,7 +264,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||||
// TODO: is there a more efficient way to avoid the min ?
|
// TODO: is there a more efficient way to avoid the min ?
|
||||||
// (necessary for rectangular matrices)
|
// (necessary for rectangular matrices)
|
||||||
for i in 0..cmp::min(j + 1 - shift, self.nrows()) {
|
for i in 0..cmp::min(j + 1 - shift, self.nrows()) {
|
||||||
unsafe { *self.get_unchecked_mut((i, j)) = val.inlined_clone() }
|
unsafe { *self.get_unchecked_mut((i, j)) = val.clone() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,7 @@ impl<T: Scalar, D: Dim, S: RawStorageMut<T, D, D>> Matrix<T, D, D, S> {
|
||||||
for j in 0..dim {
|
for j in 0..dim {
|
||||||
for i in j + 1..dim {
|
for i in j + 1..dim {
|
||||||
unsafe {
|
unsafe {
|
||||||
*self.get_unchecked_mut((i, j)) = self.get_unchecked((j, i)).inlined_clone();
|
*self.get_unchecked_mut((i, j)) = self.get_unchecked((j, i)).clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,7 +296,7 @@ impl<T: Scalar, D: Dim, S: RawStorageMut<T, D, D>> Matrix<T, D, D, S> {
|
||||||
for j in 1..self.ncols() {
|
for j in 1..self.ncols() {
|
||||||
for i in 0..j {
|
for i in 0..j {
|
||||||
unsafe {
|
unsafe {
|
||||||
*self.get_unchecked_mut((i, j)) = self.get_unchecked((j, i)).inlined_clone();
|
*self.get_unchecked_mut((i, j)) = self.get_unchecked((j, i)).clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -647,7 +647,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
{
|
{
|
||||||
let mut res = unsafe { self.insert_columns_generic_uninitialized(i, Const::<D>) };
|
let mut res = unsafe { self.insert_columns_generic_uninitialized(i, Const::<D>) };
|
||||||
res.fixed_columns_mut::<D>(i)
|
res.fixed_columns_mut::<D>(i)
|
||||||
.fill_with(|| MaybeUninit::new(val.inlined_clone()));
|
.fill_with(|| MaybeUninit::new(val.clone()));
|
||||||
|
|
||||||
// Safety: the result is now fully initialized. The added columns have
|
// Safety: the result is now fully initialized. The added columns have
|
||||||
// been initialized by the `fill_with` above, and the rest have
|
// been initialized by the `fill_with` above, and the rest have
|
||||||
|
@ -665,7 +665,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
{
|
{
|
||||||
let mut res = unsafe { self.insert_columns_generic_uninitialized(i, Dynamic::new(n)) };
|
let mut res = unsafe { self.insert_columns_generic_uninitialized(i, Dynamic::new(n)) };
|
||||||
res.columns_mut(i, n)
|
res.columns_mut(i, n)
|
||||||
.fill_with(|| MaybeUninit::new(val.inlined_clone()));
|
.fill_with(|| MaybeUninit::new(val.clone()));
|
||||||
|
|
||||||
// Safety: the result is now fully initialized. The added columns have
|
// Safety: the result is now fully initialized. The added columns have
|
||||||
// been initialized by the `fill_with` above, and the rest have
|
// been initialized by the `fill_with` above, and the rest have
|
||||||
|
@ -740,7 +740,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
{
|
{
|
||||||
let mut res = unsafe { self.insert_rows_generic_uninitialized(i, Const::<D>) };
|
let mut res = unsafe { self.insert_rows_generic_uninitialized(i, Const::<D>) };
|
||||||
res.fixed_rows_mut::<D>(i)
|
res.fixed_rows_mut::<D>(i)
|
||||||
.fill_with(|| MaybeUninit::new(val.inlined_clone()));
|
.fill_with(|| MaybeUninit::new(val.clone()));
|
||||||
|
|
||||||
// Safety: the result is now fully initialized. The added rows have
|
// Safety: the result is now fully initialized. The added rows have
|
||||||
// been initialized by the `fill_with` above, and the rest have
|
// been initialized by the `fill_with` above, and the rest have
|
||||||
|
@ -758,7 +758,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
{
|
{
|
||||||
let mut res = unsafe { self.insert_rows_generic_uninitialized(i, Dynamic::new(n)) };
|
let mut res = unsafe { self.insert_rows_generic_uninitialized(i, Dynamic::new(n)) };
|
||||||
res.rows_mut(i, n)
|
res.rows_mut(i, n)
|
||||||
.fill_with(|| MaybeUninit::new(val.inlined_clone()));
|
.fill_with(|| MaybeUninit::new(val.clone()));
|
||||||
|
|
||||||
// Safety: the result is now fully initialized. The added rows have
|
// Safety: the result is now fully initialized. The added rows have
|
||||||
// been initialized by the `fill_with` above, and the rest have
|
// been initialized by the `fill_with` above, and the rest have
|
||||||
|
@ -896,7 +896,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
|
|
||||||
if new_ncols.value() > ncols {
|
if new_ncols.value() > ncols {
|
||||||
res.columns_range_mut(ncols..)
|
res.columns_range_mut(ncols..)
|
||||||
.fill_with(|| MaybeUninit::new(val.inlined_clone()));
|
.fill_with(|| MaybeUninit::new(val.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safety: the result is now fully initialized by `reallocate_copy` and
|
// Safety: the result is now fully initialized by `reallocate_copy` and
|
||||||
|
@ -933,12 +933,12 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
|
|
||||||
if new_ncols.value() > ncols {
|
if new_ncols.value() > ncols {
|
||||||
res.columns_range_mut(ncols..)
|
res.columns_range_mut(ncols..)
|
||||||
.fill_with(|| MaybeUninit::new(val.inlined_clone()));
|
.fill_with(|| MaybeUninit::new(val.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if new_nrows.value() > nrows {
|
if new_nrows.value() > nrows {
|
||||||
res.slice_range_mut(nrows.., ..cmp::min(ncols, new_ncols.value()))
|
res.slice_range_mut(nrows.., ..cmp::min(ncols, new_ncols.value()))
|
||||||
.fill_with(|| MaybeUninit::new(val.inlined_clone()));
|
.fill_with(|| MaybeUninit::new(val.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safety: the result is now fully initialized by `reallocate_copy` and
|
// Safety: the result is now fully initialized by `reallocate_copy` and
|
||||||
|
|
|
@ -26,7 +26,7 @@ impl<T: Scalar + Zero + One + ClosedAdd + ClosedSub + ClosedMul, D: Dim, S: Stor
|
||||||
DefaultAllocator: Allocator<T, D>,
|
DefaultAllocator: Allocator<T, D>,
|
||||||
{
|
{
|
||||||
let mut res = self.clone_owned();
|
let mut res = self.clone_owned();
|
||||||
res.axpy(t.inlined_clone(), rhs, T::one() - t);
|
res.axpy(t.clone(), rhs, T::one() - t);
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,14 +109,14 @@ impl<T: RealField, D: Dim, S: Storage<T, D>> Unit<Vector<T, D, S>> {
|
||||||
return Some(Unit::new_unchecked(self.clone_owned()));
|
return Some(Unit::new_unchecked(self.clone_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let hang = c_hang.acos();
|
let hang = c_hang.clone().acos();
|
||||||
let s_hang = (T::one() - c_hang * c_hang).sqrt();
|
let s_hang = (T::one() - c_hang.clone() * c_hang).sqrt();
|
||||||
|
|
||||||
// TODO: what if s_hang is 0.0 ? The result is not well-defined.
|
// TODO: what if s_hang is 0.0 ? The result is not well-defined.
|
||||||
if relative_eq!(s_hang, T::zero(), epsilon = epsilon) {
|
if relative_eq!(s_hang, T::zero(), epsilon = epsilon) {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let ta = ((T::one() - t) * hang).sin() / s_hang;
|
let ta = ((T::one() - t.clone()) * hang.clone()).sin() / s_hang.clone();
|
||||||
let tb = (t * hang).sin() / s_hang;
|
let tb = (t * hang).sin() / s_hang;
|
||||||
let mut res = self.scale(ta);
|
let mut res = self.scale(ta);
|
||||||
res.axpy(tb, &**rhs, T::one());
|
res.axpy(tb, &**rhs, T::one());
|
||||||
|
|
|
@ -567,13 +567,13 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
R2: Dim,
|
R2: Dim,
|
||||||
C2: Dim,
|
C2: Dim,
|
||||||
SB: Storage<T, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
|
ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
|
||||||
{
|
{
|
||||||
assert!(self.shape() == other.shape());
|
assert!(self.shape() == other.shape());
|
||||||
self.iter()
|
self.iter()
|
||||||
.zip(other.iter())
|
.zip(other.iter())
|
||||||
.all(|(a, b)| a.relative_eq(b, eps, max_relative))
|
.all(|(a, b)| a.relative_eq(b, eps.clone(), max_relative.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tests whether `self` and `rhs` are exactly equal.
|
/// Tests whether `self` and `rhs` are exactly equal.
|
||||||
|
@ -668,7 +668,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
for j in 0..res.ncols() {
|
for j in 0..res.ncols() {
|
||||||
for i in 0..res.nrows() {
|
for i in 0..res.nrows() {
|
||||||
*res.get_unchecked_mut((i, j)) =
|
*res.get_unchecked_mut((i, j)) =
|
||||||
MaybeUninit::new(self.get_unchecked((i, j)).inlined_clone());
|
MaybeUninit::new(self.get_unchecked((i, j)).clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,7 +704,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
unsafe {
|
unsafe {
|
||||||
Status::init(
|
Status::init(
|
||||||
out.get_unchecked_mut((j, i)),
|
out.get_unchecked_mut((j, i)),
|
||||||
self.get_unchecked((i, j)).inlined_clone(),
|
self.get_unchecked((i, j)).clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -758,7 +758,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
for i in 0..nrows.value() {
|
for i in 0..nrows.value() {
|
||||||
// Safety: all indices are in range.
|
// Safety: all indices are in range.
|
||||||
unsafe {
|
unsafe {
|
||||||
let a = self.data.get_unchecked(i, j).inlined_clone();
|
let a = self.data.get_unchecked(i, j).clone();
|
||||||
*res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(a));
|
*res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(a));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -827,7 +827,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
for i in 0..nrows.value() {
|
for i in 0..nrows.value() {
|
||||||
// Safety: all indices are in range.
|
// Safety: all indices are in range.
|
||||||
unsafe {
|
unsafe {
|
||||||
let a = self.data.get_unchecked(i, j).inlined_clone();
|
let a = self.data.get_unchecked(i, j).clone();
|
||||||
*res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(i, j, a));
|
*res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(i, j, a));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -863,8 +863,8 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
for i in 0..nrows.value() {
|
for i in 0..nrows.value() {
|
||||||
// Safety: all indices are in range.
|
// Safety: all indices are in range.
|
||||||
unsafe {
|
unsafe {
|
||||||
let a = self.data.get_unchecked(i, j).inlined_clone();
|
let a = self.data.get_unchecked(i, j).clone();
|
||||||
let b = rhs.data.get_unchecked(i, j).inlined_clone();
|
let b = rhs.data.get_unchecked(i, j).clone();
|
||||||
*res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(a, b))
|
*res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(a, b))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -912,9 +912,9 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
for i in 0..nrows.value() {
|
for i in 0..nrows.value() {
|
||||||
// Safety: all indices are in range.
|
// Safety: all indices are in range.
|
||||||
unsafe {
|
unsafe {
|
||||||
let a = self.data.get_unchecked(i, j).inlined_clone();
|
let a = self.data.get_unchecked(i, j).clone();
|
||||||
let b = b.data.get_unchecked(i, j).inlined_clone();
|
let b = b.data.get_unchecked(i, j).clone();
|
||||||
let c = c.data.get_unchecked(i, j).inlined_clone();
|
let c = c.data.get_unchecked(i, j).clone();
|
||||||
*res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(a, b, c))
|
*res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(a, b, c))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -939,7 +939,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
for i in 0..nrows.value() {
|
for i in 0..nrows.value() {
|
||||||
// Safety: all indices are in range.
|
// Safety: all indices are in range.
|
||||||
unsafe {
|
unsafe {
|
||||||
let a = self.data.get_unchecked(i, j).inlined_clone();
|
let a = self.data.get_unchecked(i, j).clone();
|
||||||
res = f(res, a)
|
res = f(res, a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -978,8 +978,8 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
for j in 0..ncols.value() {
|
for j in 0..ncols.value() {
|
||||||
for i in 0..nrows.value() {
|
for i in 0..nrows.value() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let a = self.data.get_unchecked(i, j).inlined_clone();
|
let a = self.data.get_unchecked(i, j).clone();
|
||||||
let b = rhs.data.get_unchecked(i, j).inlined_clone();
|
let b = rhs.data.get_unchecked(i, j).clone();
|
||||||
res = f(res, a, b)
|
res = f(res, a, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1033,7 +1033,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
for i in 0..nrows {
|
for i in 0..nrows {
|
||||||
unsafe {
|
unsafe {
|
||||||
let e = self.data.get_unchecked_mut(i, j);
|
let e = self.data.get_unchecked_mut(i, j);
|
||||||
let rhs = rhs.get_unchecked((i, j)).inlined_clone();
|
let rhs = rhs.get_unchecked((i, j)).clone();
|
||||||
f(e, rhs)
|
f(e, rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1078,8 +1078,8 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
for i in 0..nrows {
|
for i in 0..nrows {
|
||||||
unsafe {
|
unsafe {
|
||||||
let e = self.data.get_unchecked_mut(i, j);
|
let e = self.data.get_unchecked_mut(i, j);
|
||||||
let b = b.get_unchecked((i, j)).inlined_clone();
|
let b = b.get_unchecked((i, j)).clone();
|
||||||
let c = c.get_unchecked((i, j)).inlined_clone();
|
let c = c.get_unchecked((i, j)).clone();
|
||||||
f(e, b, c)
|
f(e, b, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1248,8 +1248,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||||
for j in 0..ncols {
|
for j in 0..ncols {
|
||||||
for i in 0..nrows {
|
for i in 0..nrows {
|
||||||
unsafe {
|
unsafe {
|
||||||
*self.get_unchecked_mut((i, j)) =
|
*self.get_unchecked_mut((i, j)) = slice.get_unchecked(i + j * nrows).clone();
|
||||||
slice.get_unchecked(i + j * nrows).inlined_clone();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1273,7 +1272,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||||
for j in 0..self.ncols() {
|
for j in 0..self.ncols() {
|
||||||
for i in 0..self.nrows() {
|
for i in 0..self.nrows() {
|
||||||
unsafe {
|
unsafe {
|
||||||
*self.get_unchecked_mut((i, j)) = other.get_unchecked((i, j)).inlined_clone();
|
*self.get_unchecked_mut((i, j)) = other.get_unchecked((i, j)).clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1298,7 +1297,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||||
for j in 0..ncols {
|
for j in 0..ncols {
|
||||||
for i in 0..nrows {
|
for i in 0..nrows {
|
||||||
unsafe {
|
unsafe {
|
||||||
*self.get_unchecked_mut((i, j)) = other.get_unchecked((j, i)).inlined_clone();
|
*self.get_unchecked_mut((i, j)) = other.get_unchecked((j, i)).clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1400,7 +1399,7 @@ impl<T: SimdComplexField, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C
|
||||||
unsafe {
|
unsafe {
|
||||||
Status::init(
|
Status::init(
|
||||||
out.get_unchecked_mut((j, i)),
|
out.get_unchecked_mut((j, i)),
|
||||||
self.get_unchecked((i, j)).simd_conjugate(),
|
self.get_unchecked((i, j)).clone().simd_conjugate(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1475,7 +1474,7 @@ impl<T: SimdComplexField, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, R, C>,
|
DefaultAllocator: Allocator<T, R, C>,
|
||||||
{
|
{
|
||||||
self.map(|e| e.simd_unscale(real))
|
self.map(|e| e.simd_unscale(real.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Multiplies each component of the complex matrix `self` by the given real.
|
/// Multiplies each component of the complex matrix `self` by the given real.
|
||||||
|
@ -1485,7 +1484,7 @@ impl<T: SimdComplexField, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, R, C>,
|
DefaultAllocator: Allocator<T, R, C>,
|
||||||
{
|
{
|
||||||
self.map(|e| e.simd_scale(real))
|
self.map(|e| e.simd_scale(real.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1493,19 +1492,19 @@ impl<T: SimdComplexField, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R
|
||||||
/// The conjugate of the complex matrix `self` computed in-place.
|
/// The conjugate of the complex matrix `self` computed in-place.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn conjugate_mut(&mut self) {
|
pub fn conjugate_mut(&mut self) {
|
||||||
self.apply(|e| *e = e.simd_conjugate())
|
self.apply(|e| *e = e.clone().simd_conjugate())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Divides each component of the complex matrix `self` by the given real.
|
/// Divides each component of the complex matrix `self` by the given real.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn unscale_mut(&mut self, real: T::SimdRealField) {
|
pub fn unscale_mut(&mut self, real: T::SimdRealField) {
|
||||||
self.apply(|e| *e = e.simd_unscale(real))
|
self.apply(|e| *e = e.clone().simd_unscale(real.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Multiplies each component of the complex matrix `self` by the given real.
|
/// Multiplies each component of the complex matrix `self` by the given real.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn scale_mut(&mut self, real: T::SimdRealField) {
|
pub fn scale_mut(&mut self, real: T::SimdRealField) {
|
||||||
self.apply(|e| *e = e.simd_scale(real))
|
self.apply(|e| *e = e.clone().simd_scale(real.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1528,18 +1527,18 @@ impl<T: SimdComplexField, D: Dim, S: RawStorageMut<T, D, D>> Matrix<T, D, D, S>
|
||||||
for i in 0..dim {
|
for i in 0..dim {
|
||||||
for j in 0..i {
|
for j in 0..i {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ref_ij = self.get_unchecked_mut((i, j)) as *mut T;
|
let ref_ij = self.get_unchecked((i, j)).clone();
|
||||||
let ref_ji = self.get_unchecked_mut((j, i)) as *mut T;
|
let ref_ji = self.get_unchecked((j, i)).clone();
|
||||||
let conj_ij = (*ref_ij).simd_conjugate();
|
let conj_ij = ref_ij.simd_conjugate();
|
||||||
let conj_ji = (*ref_ji).simd_conjugate();
|
let conj_ji = ref_ji.simd_conjugate();
|
||||||
*ref_ij = conj_ji;
|
*self.get_unchecked_mut((i, j)) = conj_ji;
|
||||||
*ref_ji = conj_ij;
|
*self.get_unchecked_mut((j, i)) = conj_ij;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let diag = unsafe { self.get_unchecked_mut((i, i)) };
|
let diag = unsafe { self.get_unchecked_mut((i, i)) };
|
||||||
*diag = diag.simd_conjugate();
|
*diag = diag.clone().simd_conjugate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1577,7 +1576,7 @@ impl<T: Scalar, D: Dim, S: RawStorage<T, D, D>> SquareMatrix<T, D, S> {
|
||||||
// Safety: all indices are in range.
|
// Safety: all indices are in range.
|
||||||
unsafe {
|
unsafe {
|
||||||
*res.vget_unchecked_mut(i) =
|
*res.vget_unchecked_mut(i) =
|
||||||
MaybeUninit::new(f(self.get_unchecked((i, i)).inlined_clone()));
|
MaybeUninit::new(f(self.get_unchecked((i, i)).clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1601,7 +1600,7 @@ impl<T: Scalar, D: Dim, S: RawStorage<T, D, D>> SquareMatrix<T, D, S> {
|
||||||
let mut res = T::zero();
|
let mut res = T::zero();
|
||||||
|
|
||||||
for i in 0..dim.value() {
|
for i in 0..dim.value() {
|
||||||
res += unsafe { self.get_unchecked((i, i)).inlined_clone() };
|
res += unsafe { self.get_unchecked((i, i)).clone() };
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -1723,7 +1722,7 @@ impl<T, R: Dim, C: Dim, S> AbsDiffEq for Matrix<T, R, C, S>
|
||||||
where
|
where
|
||||||
T: Scalar + AbsDiffEq,
|
T: Scalar + AbsDiffEq,
|
||||||
S: RawStorage<T, R, C>,
|
S: RawStorage<T, R, C>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
type Epsilon = T::Epsilon;
|
type Epsilon = T::Epsilon;
|
||||||
|
|
||||||
|
@ -1736,7 +1735,7 @@ where
|
||||||
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
|
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
|
||||||
self.iter()
|
self.iter()
|
||||||
.zip(other.iter())
|
.zip(other.iter())
|
||||||
.all(|(a, b)| a.abs_diff_eq(b, epsilon))
|
.all(|(a, b)| a.abs_diff_eq(b, epsilon.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1744,7 +1743,7 @@ impl<T, R: Dim, C: Dim, S> RelativeEq for Matrix<T, R, C, S>
|
||||||
where
|
where
|
||||||
T: Scalar + RelativeEq,
|
T: Scalar + RelativeEq,
|
||||||
S: Storage<T, R, C>,
|
S: Storage<T, R, C>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default_max_relative() -> Self::Epsilon {
|
fn default_max_relative() -> Self::Epsilon {
|
||||||
|
@ -1766,7 +1765,7 @@ impl<T, R: Dim, C: Dim, S> UlpsEq for Matrix<T, R, C, S>
|
||||||
where
|
where
|
||||||
T: Scalar + UlpsEq,
|
T: Scalar + UlpsEq,
|
||||||
S: RawStorage<T, R, C>,
|
S: RawStorage<T, R, C>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default_max_ulps() -> u32 {
|
fn default_max_ulps() -> u32 {
|
||||||
|
@ -1778,7 +1777,7 @@ where
|
||||||
assert!(self.shape() == other.shape());
|
assert!(self.shape() == other.shape());
|
||||||
self.iter()
|
self.iter()
|
||||||
.zip(other.iter())
|
.zip(other.iter())
|
||||||
.all(|(a, b)| a.ulps_eq(b, epsilon, max_ulps))
|
.all(|(a, b)| a.ulps_eq(b, epsilon.clone(), max_ulps.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2029,9 +2028,8 @@ impl<T: Scalar + ClosedAdd + ClosedSub + ClosedMul, R: Dim, C: Dim, S: RawStorag
|
||||||
);
|
);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
self.get_unchecked((0, 0)).inlined_clone() * b.get_unchecked((1, 0)).inlined_clone()
|
self.get_unchecked((0, 0)).clone() * b.get_unchecked((1, 0)).clone()
|
||||||
- self.get_unchecked((1, 0)).inlined_clone()
|
- self.get_unchecked((1, 0)).clone() * b.get_unchecked((0, 0)).clone()
|
||||||
* b.get_unchecked((0, 0)).inlined_clone()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2073,18 +2071,12 @@ impl<T: Scalar + ClosedAdd + ClosedSub + ClosedMul, R: Dim, C: Dim, S: RawStorag
|
||||||
let by = b.get_unchecked((1, 0));
|
let by = b.get_unchecked((1, 0));
|
||||||
let bz = b.get_unchecked((2, 0));
|
let bz = b.get_unchecked((2, 0));
|
||||||
|
|
||||||
*res.get_unchecked_mut((0, 0)) = MaybeUninit::new(
|
*res.get_unchecked_mut((0, 0)) =
|
||||||
ay.inlined_clone() * bz.inlined_clone()
|
MaybeUninit::new(ay.clone() * bz.clone() - az.clone() * by.clone());
|
||||||
- az.inlined_clone() * by.inlined_clone(),
|
*res.get_unchecked_mut((1, 0)) =
|
||||||
);
|
MaybeUninit::new(az.clone() * bx.clone() - ax.clone() * bz.clone());
|
||||||
*res.get_unchecked_mut((1, 0)) = MaybeUninit::new(
|
*res.get_unchecked_mut((2, 0)) =
|
||||||
az.inlined_clone() * bx.inlined_clone()
|
MaybeUninit::new(ax.clone() * by.clone() - ay.clone() * bx.clone());
|
||||||
- ax.inlined_clone() * bz.inlined_clone(),
|
|
||||||
);
|
|
||||||
*res.get_unchecked_mut((2, 0)) = MaybeUninit::new(
|
|
||||||
ax.inlined_clone() * by.inlined_clone()
|
|
||||||
- ay.inlined_clone() * bx.inlined_clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Safety: res is now fully initialized.
|
// Safety: res is now fully initialized.
|
||||||
res.assume_init()
|
res.assume_init()
|
||||||
|
@ -2104,18 +2096,12 @@ impl<T: Scalar + ClosedAdd + ClosedSub + ClosedMul, R: Dim, C: Dim, S: RawStorag
|
||||||
let by = b.get_unchecked((0, 1));
|
let by = b.get_unchecked((0, 1));
|
||||||
let bz = b.get_unchecked((0, 2));
|
let bz = b.get_unchecked((0, 2));
|
||||||
|
|
||||||
*res.get_unchecked_mut((0, 0)) = MaybeUninit::new(
|
*res.get_unchecked_mut((0, 0)) =
|
||||||
ay.inlined_clone() * bz.inlined_clone()
|
MaybeUninit::new(ay.clone() * bz.clone() - az.clone() * by.clone());
|
||||||
- az.inlined_clone() * by.inlined_clone(),
|
*res.get_unchecked_mut((0, 1)) =
|
||||||
);
|
MaybeUninit::new(az.clone() * bx.clone() - ax.clone() * bz.clone());
|
||||||
*res.get_unchecked_mut((0, 1)) = MaybeUninit::new(
|
*res.get_unchecked_mut((0, 2)) =
|
||||||
az.inlined_clone() * bx.inlined_clone()
|
MaybeUninit::new(ax.clone() * by.clone() - ay.clone() * bx.clone());
|
||||||
- ax.inlined_clone() * bz.inlined_clone(),
|
|
||||||
);
|
|
||||||
*res.get_unchecked_mut((0, 2)) = MaybeUninit::new(
|
|
||||||
ax.inlined_clone() * by.inlined_clone()
|
|
||||||
- ay.inlined_clone() * bx.inlined_clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Safety: res is now fully initialized.
|
// Safety: res is now fully initialized.
|
||||||
res.assume_init()
|
res.assume_init()
|
||||||
|
@ -2131,13 +2117,13 @@ impl<T: Scalar + Field, S: RawStorage<T, U3>> Vector<T, U3, S> {
|
||||||
pub fn cross_matrix(&self) -> OMatrix<T, U3, U3> {
|
pub fn cross_matrix(&self) -> OMatrix<T, U3, U3> {
|
||||||
OMatrix::<T, U3, U3>::new(
|
OMatrix::<T, U3, U3>::new(
|
||||||
T::zero(),
|
T::zero(),
|
||||||
-self[2].inlined_clone(),
|
-self[2].clone(),
|
||||||
self[1].inlined_clone(),
|
self[1].clone(),
|
||||||
self[2].inlined_clone(),
|
self[2].clone(),
|
||||||
T::zero(),
|
T::zero(),
|
||||||
-self[0].inlined_clone(),
|
-self[0].clone(),
|
||||||
-self[1].inlined_clone(),
|
-self[1].clone(),
|
||||||
self[0].inlined_clone(),
|
self[0].clone(),
|
||||||
T::zero(),
|
T::zero(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2170,7 +2156,7 @@ impl<T, R: Dim, C: Dim, S> AbsDiffEq for Unit<Matrix<T, R, C, S>>
|
||||||
where
|
where
|
||||||
T: Scalar + AbsDiffEq,
|
T: Scalar + AbsDiffEq,
|
||||||
S: RawStorage<T, R, C>,
|
S: RawStorage<T, R, C>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
type Epsilon = T::Epsilon;
|
type Epsilon = T::Epsilon;
|
||||||
|
|
||||||
|
@ -2189,7 +2175,7 @@ impl<T, R: Dim, C: Dim, S> RelativeEq for Unit<Matrix<T, R, C, S>>
|
||||||
where
|
where
|
||||||
T: Scalar + RelativeEq,
|
T: Scalar + RelativeEq,
|
||||||
S: Storage<T, R, C>,
|
S: Storage<T, R, C>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default_max_relative() -> Self::Epsilon {
|
fn default_max_relative() -> Self::Epsilon {
|
||||||
|
@ -2212,7 +2198,7 @@ impl<T, R: Dim, C: Dim, S> UlpsEq for Unit<Matrix<T, R, C, S>>
|
||||||
where
|
where
|
||||||
T: Scalar + UlpsEq,
|
T: Scalar + UlpsEq,
|
||||||
S: RawStorage<T, R, C>,
|
S: RawStorage<T, R, C>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default_max_ulps() -> u32 {
|
fn default_max_ulps() -> u32 {
|
||||||
|
|
|
@ -40,8 +40,8 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
T: SimdComplexField,
|
T: SimdComplexField,
|
||||||
{
|
{
|
||||||
self.fold_with(
|
self.fold_with(
|
||||||
|e| e.unwrap_or(&T::zero()).simd_norm1(),
|
|e| e.unwrap_or(&T::zero()).clone().simd_norm1(),
|
||||||
|a, b| a.simd_max(b.simd_norm1()),
|
|a, b| a.simd_max(b.clone().simd_norm1()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,8 +60,8 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
T: SimdPartialOrd + Zero,
|
T: SimdPartialOrd + Zero,
|
||||||
{
|
{
|
||||||
self.fold_with(
|
self.fold_with(
|
||||||
|e| e.map(|e| e.inlined_clone()).unwrap_or_else(T::zero),
|
|e| e.map(|e| e.clone()).unwrap_or_else(T::zero),
|
||||||
|a, b| a.simd_max(b.inlined_clone()),
|
|a, b| a.simd_max(b.clone()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,10 +101,10 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
{
|
{
|
||||||
self.fold_with(
|
self.fold_with(
|
||||||
|e| {
|
|e| {
|
||||||
e.map(|e| e.simd_norm1())
|
e.map(|e| e.clone().simd_norm1())
|
||||||
.unwrap_or_else(T::SimdRealField::zero)
|
.unwrap_or_else(T::SimdRealField::zero)
|
||||||
},
|
},
|
||||||
|a, b| a.simd_min(b.simd_norm1()),
|
|a, b| a.simd_min(b.clone().simd_norm1()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,8 +123,8 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
T: SimdPartialOrd + Zero,
|
T: SimdPartialOrd + Zero,
|
||||||
{
|
{
|
||||||
self.fold_with(
|
self.fold_with(
|
||||||
|e| e.map(|e| e.inlined_clone()).unwrap_or_else(T::zero),
|
|e| e.map(|e| e.clone()).unwrap_or_else(T::zero),
|
||||||
|a, b| a.simd_min(b.inlined_clone()),
|
|a, b| a.simd_min(b.clone()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,12 +149,12 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
{
|
{
|
||||||
assert!(!self.is_empty(), "The input matrix must not be empty.");
|
assert!(!self.is_empty(), "The input matrix must not be empty.");
|
||||||
|
|
||||||
let mut the_max = unsafe { self.get_unchecked((0, 0)).norm1() };
|
let mut the_max = unsafe { self.get_unchecked((0, 0)).clone().norm1() };
|
||||||
let mut the_ij = (0, 0);
|
let mut the_ij = (0, 0);
|
||||||
|
|
||||||
for j in 0..self.ncols() {
|
for j in 0..self.ncols() {
|
||||||
for i in 0..self.nrows() {
|
for i in 0..self.nrows() {
|
||||||
let val = unsafe { self.get_unchecked((i, j)).norm1() };
|
let val = unsafe { self.get_unchecked((i, j)).clone().norm1() };
|
||||||
|
|
||||||
if val > the_max {
|
if val > the_max {
|
||||||
the_max = val;
|
the_max = val;
|
||||||
|
@ -224,11 +224,11 @@ impl<T: Scalar, D: Dim, S: RawStorage<T, D>> Vector<T, D, S> {
|
||||||
{
|
{
|
||||||
assert!(!self.is_empty(), "The input vector must not be empty.");
|
assert!(!self.is_empty(), "The input vector must not be empty.");
|
||||||
|
|
||||||
let mut the_max = unsafe { self.vget_unchecked(0).norm1() };
|
let mut the_max = unsafe { self.vget_unchecked(0).clone().norm1() };
|
||||||
let mut the_i = 0;
|
let mut the_i = 0;
|
||||||
|
|
||||||
for i in 1..self.nrows() {
|
for i in 1..self.nrows() {
|
||||||
let val = unsafe { self.vget_unchecked(i).norm1() };
|
let val = unsafe { self.vget_unchecked(i).clone().norm1() };
|
||||||
|
|
||||||
if val > the_max {
|
if val > the_max {
|
||||||
the_max = val;
|
the_max = val;
|
||||||
|
@ -268,7 +268,7 @@ impl<T: Scalar, D: Dim, S: RawStorage<T, D>> Vector<T, D, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(the_i, the_max.inlined_clone())
|
(the_i, the_max.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the index of the vector component with the largest value.
|
/// Computes the index of the vector component with the largest value.
|
||||||
|
@ -350,7 +350,7 @@ impl<T: Scalar, D: Dim, S: RawStorage<T, D>> Vector<T, D, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(the_i, the_min.inlined_clone())
|
(the_i, the_min.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the index of the vector component with the smallest value.
|
/// Computes the index of the vector component with the smallest value.
|
||||||
|
|
|
@ -328,7 +328,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
|
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
|
||||||
{
|
{
|
||||||
let n = self.norm();
|
let n = self.norm();
|
||||||
let le = n.simd_le(min_norm);
|
let le = n.clone().simd_le(min_norm);
|
||||||
let val = self.unscale(n);
|
let val = self.unscale(n);
|
||||||
SimdOption::new(val, le)
|
SimdOption::new(val, le)
|
||||||
}
|
}
|
||||||
|
@ -377,7 +377,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
|
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
|
||||||
{
|
{
|
||||||
let n = self.norm();
|
let n = self.norm();
|
||||||
let scaled = self.scale(max / n);
|
let scaled = self.scale(max.clone() / n.clone());
|
||||||
let use_scaled = n.simd_gt(max);
|
let use_scaled = n.simd_gt(max);
|
||||||
scaled.select(use_scaled, self.clone_owned())
|
scaled.select(use_scaled, self.clone_owned())
|
||||||
}
|
}
|
||||||
|
@ -413,7 +413,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||||
T: SimdComplexField,
|
T: SimdComplexField,
|
||||||
{
|
{
|
||||||
let n = self.norm();
|
let n = self.norm();
|
||||||
self.unscale_mut(n);
|
self.unscale_mut(n.clone());
|
||||||
|
|
||||||
n
|
n
|
||||||
}
|
}
|
||||||
|
@ -433,8 +433,13 @@ impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||||
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
|
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
|
||||||
{
|
{
|
||||||
let n = self.norm();
|
let n = self.norm();
|
||||||
let le = n.simd_le(min_norm);
|
let le = n.clone().simd_le(min_norm);
|
||||||
self.apply(|e| *e = e.simd_unscale(n).select(le, *e));
|
self.apply(|e| {
|
||||||
|
*e = e
|
||||||
|
.clone()
|
||||||
|
.simd_unscale(n.clone())
|
||||||
|
.select(le.clone(), e.clone())
|
||||||
|
});
|
||||||
SimdOption::new(n, le)
|
SimdOption::new(n, le)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +456,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||||
if n <= min_norm {
|
if n <= min_norm {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
self.unscale_mut(n);
|
self.unscale_mut(n.clone());
|
||||||
Some(n)
|
Some(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -572,7 +577,7 @@ where
|
||||||
&& f(&Self::canonical_basis_element(1));
|
&& f(&Self::canonical_basis_element(1));
|
||||||
} else if vs.len() == 1 {
|
} else if vs.len() == 1 {
|
||||||
let v = &vs[0];
|
let v = &vs[0];
|
||||||
let res = Self::from_column_slice(&[-v[1], v[0]]);
|
let res = Self::from_column_slice(&[-v[1].clone(), v[0].clone()]);
|
||||||
|
|
||||||
let _ = f(&res.normalize());
|
let _ = f(&res.normalize());
|
||||||
}
|
}
|
||||||
|
@ -588,10 +593,10 @@ where
|
||||||
let v = &vs[0];
|
let v = &vs[0];
|
||||||
let mut a;
|
let mut a;
|
||||||
|
|
||||||
if v[0].norm1() > v[1].norm1() {
|
if v[0].clone().norm1() > v[1].clone().norm1() {
|
||||||
a = Self::from_column_slice(&[v[2], T::zero(), -v[0]]);
|
a = Self::from_column_slice(&[v[2].clone(), T::zero(), -v[0].clone()]);
|
||||||
} else {
|
} else {
|
||||||
a = Self::from_column_slice(&[T::zero(), -v[2], v[1]]);
|
a = Self::from_column_slice(&[T::zero(), -v[2].clone(), v[1].clone()]);
|
||||||
};
|
};
|
||||||
|
|
||||||
let _ = a.normalize_mut();
|
let _ = a.normalize_mut();
|
||||||
|
|
|
@ -116,7 +116,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn neg_mut(&mut self) {
|
pub fn neg_mut(&mut self) {
|
||||||
for e in self.iter_mut() {
|
for e in self.iter_mut() {
|
||||||
*e = -e.inlined_clone()
|
*e = -e.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,12 +163,12 @@ macro_rules! componentwise_binop_impl(
|
||||||
let arr2 = rhs.data.as_slice_unchecked();
|
let arr2 = rhs.data.as_slice_unchecked();
|
||||||
let out = out.data.as_mut_slice_unchecked();
|
let out = out.data.as_mut_slice_unchecked();
|
||||||
for i in 0 .. arr1.len() {
|
for i in 0 .. arr1.len() {
|
||||||
Status::init(out.get_unchecked_mut(i), arr1.get_unchecked(i).inlined_clone().$method(arr2.get_unchecked(i).inlined_clone()));
|
Status::init(out.get_unchecked_mut(i), arr1.get_unchecked(i).clone().$method(arr2.get_unchecked(i).clone()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for j in 0 .. self.ncols() {
|
for j in 0 .. self.ncols() {
|
||||||
for i in 0 .. self.nrows() {
|
for i in 0 .. self.nrows() {
|
||||||
let val = self.get_unchecked((i, j)).inlined_clone().$method(rhs.get_unchecked((i, j)).inlined_clone());
|
let val = self.get_unchecked((i, j)).clone().$method(rhs.get_unchecked((i, j)).clone());
|
||||||
Status::init(out.get_unchecked_mut((i, j)), val);
|
Status::init(out.get_unchecked_mut((i, j)), val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,12 +193,12 @@ macro_rules! componentwise_binop_impl(
|
||||||
let arr2 = rhs.data.as_slice_unchecked();
|
let arr2 = rhs.data.as_slice_unchecked();
|
||||||
|
|
||||||
for i in 0 .. arr2.len() {
|
for i in 0 .. arr2.len() {
|
||||||
arr1.get_unchecked_mut(i).$method_assign(arr2.get_unchecked(i).inlined_clone());
|
arr1.get_unchecked_mut(i).$method_assign(arr2.get_unchecked(i).clone());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for j in 0 .. rhs.ncols() {
|
for j in 0 .. rhs.ncols() {
|
||||||
for i in 0 .. rhs.nrows() {
|
for i in 0 .. rhs.nrows() {
|
||||||
self.get_unchecked_mut((i, j)).$method_assign(rhs.get_unchecked((i, j)).inlined_clone())
|
self.get_unchecked_mut((i, j)).$method_assign(rhs.get_unchecked((i, j)).clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,14 +221,14 @@ macro_rules! componentwise_binop_impl(
|
||||||
let arr2 = rhs.data.as_mut_slice_unchecked();
|
let arr2 = rhs.data.as_mut_slice_unchecked();
|
||||||
|
|
||||||
for i in 0 .. arr1.len() {
|
for i in 0 .. arr1.len() {
|
||||||
let res = arr1.get_unchecked(i).inlined_clone().$method(arr2.get_unchecked(i).inlined_clone());
|
let res = arr1.get_unchecked(i).clone().$method(arr2.get_unchecked(i).clone());
|
||||||
*arr2.get_unchecked_mut(i) = res;
|
*arr2.get_unchecked_mut(i) = res;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for j in 0 .. self.ncols() {
|
for j in 0 .. self.ncols() {
|
||||||
for i in 0 .. self.nrows() {
|
for i in 0 .. self.nrows() {
|
||||||
let r = rhs.get_unchecked_mut((i, j));
|
let r = rhs.get_unchecked_mut((i, j));
|
||||||
*r = self.get_unchecked((i, j)).inlined_clone().$method(r.inlined_clone())
|
*r = self.get_unchecked((i, j)).clone().$method(r.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -472,7 +472,7 @@ macro_rules! componentwise_scalarop_impl(
|
||||||
|
|
||||||
// for left in res.iter_mut() {
|
// for left in res.iter_mut() {
|
||||||
for left in res.as_mut_slice().iter_mut() {
|
for left in res.as_mut_slice().iter_mut() {
|
||||||
*left = left.inlined_clone().$method(rhs.inlined_clone())
|
*left = left.clone().$method(rhs.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -498,7 +498,7 @@ macro_rules! componentwise_scalarop_impl(
|
||||||
fn $method_assign(&mut self, rhs: T) {
|
fn $method_assign(&mut self, rhs: T) {
|
||||||
for j in 0 .. self.ncols() {
|
for j in 0 .. self.ncols() {
|
||||||
for i in 0 .. self.nrows() {
|
for i in 0 .. self.nrows() {
|
||||||
unsafe { self.get_unchecked_mut((i, j)).$method_assign(rhs.inlined_clone()) };
|
unsafe { self.get_unchecked_mut((i, j)).$method_assign(rhs.clone()) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -815,11 +815,11 @@ where
|
||||||
for j1 in 0..ncols1.value() {
|
for j1 in 0..ncols1.value() {
|
||||||
for j2 in 0..ncols2.value() {
|
for j2 in 0..ncols2.value() {
|
||||||
for i1 in 0..nrows1.value() {
|
for i1 in 0..nrows1.value() {
|
||||||
let coeff = self.get_unchecked((i1, j1)).inlined_clone();
|
let coeff = self.get_unchecked((i1, j1)).clone();
|
||||||
|
|
||||||
for i2 in 0..nrows2.value() {
|
for i2 in 0..nrows2.value() {
|
||||||
*data_res = MaybeUninit::new(
|
*data_res = MaybeUninit::new(
|
||||||
coeff.inlined_clone() * rhs.get_unchecked((i2, j2)).inlined_clone(),
|
coeff.clone() * rhs.get_unchecked((i2, j2)).clone(),
|
||||||
);
|
);
|
||||||
data_res = data_res.offset(1);
|
data_res = data_res.offset(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
pub fn is_identity(&self, eps: T::Epsilon) -> bool
|
pub fn is_identity(&self, eps: T::Epsilon) -> bool
|
||||||
where
|
where
|
||||||
T: Zero + One + RelativeEq,
|
T: Zero + One + RelativeEq,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
let (nrows, ncols) = self.shape();
|
let (nrows, ncols) = self.shape();
|
||||||
let d;
|
let d;
|
||||||
|
@ -70,7 +70,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
|
|
||||||
for i in d..nrows {
|
for i in d..nrows {
|
||||||
for j in 0..ncols {
|
for j in 0..ncols {
|
||||||
if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps) {
|
if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps.clone()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
|
|
||||||
for i in 0..nrows {
|
for i in 0..nrows {
|
||||||
for j in d..ncols {
|
for j in d..ncols {
|
||||||
if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps) {
|
if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps.clone()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,8 +92,8 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
for i in 1..d {
|
for i in 1..d {
|
||||||
for j in 0..i {
|
for j in 0..i {
|
||||||
// TODO: use unsafe indexing.
|
// TODO: use unsafe indexing.
|
||||||
if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps)
|
if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps.clone())
|
||||||
|| !relative_eq!(self[(j, i)], T::zero(), epsilon = eps)
|
|| !relative_eq!(self[(j, i)], T::zero(), epsilon = eps.clone())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
|
|
||||||
// Diagonal elements of the sub-square matrix.
|
// Diagonal elements of the sub-square matrix.
|
||||||
for i in 0..d {
|
for i in 0..d {
|
||||||
if !relative_eq!(self[(i, i)], T::one(), epsilon = eps) {
|
if !relative_eq!(self[(i, i)], T::one(), epsilon = eps.clone()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ impl<T: ComplexField, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
where
|
where
|
||||||
T: Zero + One + ClosedAdd + ClosedMul + RelativeEq,
|
T: Zero + One + ClosedAdd + ClosedMul + RelativeEq,
|
||||||
S: Storage<T, R, C>,
|
S: Storage<T, R, C>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
DefaultAllocator: Allocator<T, R, C> + Allocator<T, C, C>,
|
DefaultAllocator: Allocator<T, R, C> + Allocator<T, C, C>,
|
||||||
{
|
{
|
||||||
(self.ad_mul(self)).is_identity(eps)
|
(self.ad_mul(self)).is_identity(eps)
|
||||||
|
|
|
@ -1,20 +1,8 @@
|
||||||
use std::any::Any;
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
/// The basic scalar type for all structures of `nalgebra`.
|
/// The basic scalar type for all structures of `nalgebra`.
|
||||||
///
|
///
|
||||||
/// This does not make any assumption on the algebraic properties of `Self`.
|
/// This does not make any assumption on the algebraic properties of `Self`.
|
||||||
pub trait Scalar: 'static + Clone + PartialEq + Debug {
|
pub trait Scalar: 'static + Clone + PartialEq + Debug {}
|
||||||
#[inline(always)]
|
|
||||||
/// Performance hack: Clone doesn't get inlined for Copy types in debug mode, so make it inline anyway.
|
|
||||||
fn inlined_clone(&self) -> Self {
|
|
||||||
self.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Copy + PartialEq + Debug + Any> Scalar for T {
|
impl<T: 'static + Clone + PartialEq + Debug> Scalar for T {}
|
||||||
#[inline(always)]
|
|
||||||
fn inlined_clone(&self) -> T {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -216,11 +216,11 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
T::zero()
|
T::zero()
|
||||||
} else {
|
} else {
|
||||||
let val = self.iter().cloned().fold((T::zero(), T::zero()), |a, b| {
|
let val = self.iter().cloned().fold((T::zero(), T::zero()), |a, b| {
|
||||||
(a.0 + b.inlined_clone() * b.inlined_clone(), a.1 + b)
|
(a.0 + b.clone() * b.clone(), a.1 + b)
|
||||||
});
|
});
|
||||||
let denom = T::one() / crate::convert::<_, T>(self.len() as f64);
|
let denom = T::one() / crate::convert::<_, T>(self.len() as f64);
|
||||||
let vd = val.1 * denom.inlined_clone();
|
let vd = val.1 * denom.clone();
|
||||||
val.0 * denom - vd.inlined_clone() * vd
|
val.0 * denom - vd.clone() * vd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,15 +289,14 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
let (nrows, ncols) = self.shape_generic();
|
let (nrows, ncols) = self.shape_generic();
|
||||||
|
|
||||||
let mut mean = self.column_mean();
|
let mut mean = self.column_mean();
|
||||||
mean.apply(|e| *e = -(e.inlined_clone() * e.inlined_clone()));
|
mean.apply(|e| *e = -(e.clone() * e.clone()));
|
||||||
|
|
||||||
let denom = T::one() / crate::convert::<_, T>(ncols.value() as f64);
|
let denom = T::one() / crate::convert::<_, T>(ncols.value() as f64);
|
||||||
self.compress_columns(mean, |out, col| {
|
self.compress_columns(mean, |out, col| {
|
||||||
for i in 0..nrows.value() {
|
for i in 0..nrows.value() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let val = col.vget_unchecked(i);
|
let val = col.vget_unchecked(i);
|
||||||
*out.vget_unchecked_mut(i) +=
|
*out.vget_unchecked_mut(i) += denom.clone() * val.clone() * val.clone()
|
||||||
denom.inlined_clone() * val.inlined_clone() * val.inlined_clone()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -397,7 +396,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
let (nrows, ncols) = self.shape_generic();
|
let (nrows, ncols) = self.shape_generic();
|
||||||
let denom = T::one() / crate::convert::<_, T>(ncols.value() as f64);
|
let denom = T::one() / crate::convert::<_, T>(ncols.value() as f64);
|
||||||
self.compress_columns(OVector::zeros_generic(nrows, Const::<1>), |out, col| {
|
self.compress_columns(OVector::zeros_generic(nrows, Const::<1>), |out, col| {
|
||||||
out.axpy(denom.inlined_clone(), &col, T::one())
|
out.axpy(denom.clone(), &col, T::one())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ macro_rules! impl_swizzle {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn $name(&self) -> $Result<T>
|
pub fn $name(&self) -> $Result<T>
|
||||||
where D::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
|
where D::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
|
||||||
$Result::new($(self[$i].inlined_clone()),*)
|
$Result::new($(self[$i].clone()),*)
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
)*
|
)*
|
||||||
|
|
|
@ -170,7 +170,7 @@ impl<T: Normed> Unit<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_and_get(mut value: T) -> (Self, T::Norm) {
|
pub fn new_and_get(mut value: T) -> (Self, T::Norm) {
|
||||||
let n = value.norm();
|
let n = value.norm();
|
||||||
value.unscale_mut(n);
|
value.unscale_mut(n.clone());
|
||||||
(Unit { value }, n)
|
(Unit { value }, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,9 +184,9 @@ impl<T: Normed> Unit<T> {
|
||||||
{
|
{
|
||||||
let sq_norm = value.norm_squared();
|
let sq_norm = value.norm_squared();
|
||||||
|
|
||||||
if sq_norm > min_norm * min_norm {
|
if sq_norm > min_norm.clone() * min_norm {
|
||||||
let n = sq_norm.simd_sqrt();
|
let n = sq_norm.simd_sqrt();
|
||||||
value.unscale_mut(n);
|
value.unscale_mut(n.clone());
|
||||||
Some((Unit { value }, n))
|
Some((Unit { value }, n))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -201,7 +201,7 @@ impl<T: Normed> Unit<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn renormalize(&mut self) -> T::Norm {
|
pub fn renormalize(&mut self) -> T::Norm {
|
||||||
let n = self.norm();
|
let n = self.norm();
|
||||||
self.value.unscale_mut(n);
|
self.value.unscale_mut(n.clone());
|
||||||
n
|
n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,10 @@ where
|
||||||
pub fn normalize(&self) -> Self {
|
pub fn normalize(&self) -> Self {
|
||||||
let real_norm = self.real.norm();
|
let real_norm = self.real.norm();
|
||||||
|
|
||||||
Self::from_real_and_dual(self.real / real_norm, self.dual / real_norm)
|
Self::from_real_and_dual(
|
||||||
|
self.real.clone() / real_norm.clone(),
|
||||||
|
self.dual.clone() / real_norm,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Normalizes this quaternion.
|
/// Normalizes this quaternion.
|
||||||
|
@ -107,8 +110,8 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn normalize_mut(&mut self) -> T {
|
pub fn normalize_mut(&mut self) -> T {
|
||||||
let real_norm = self.real.norm();
|
let real_norm = self.real.norm();
|
||||||
self.real /= real_norm;
|
self.real /= real_norm.clone();
|
||||||
self.dual /= real_norm;
|
self.dual /= real_norm.clone();
|
||||||
real_norm
|
real_norm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +185,7 @@ where
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let mut res = *self;
|
let mut res = self.clone();
|
||||||
if res.try_inverse_mut() {
|
if res.try_inverse_mut() {
|
||||||
Some(res)
|
Some(res)
|
||||||
} else {
|
} else {
|
||||||
|
@ -216,7 +219,7 @@ where
|
||||||
{
|
{
|
||||||
let inverted = self.real.try_inverse_mut();
|
let inverted = self.real.try_inverse_mut();
|
||||||
if inverted {
|
if inverted {
|
||||||
self.dual = -self.real * self.dual * self.real;
|
self.dual = -self.real.clone() * self.dual.clone() * self.real.clone();
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -246,7 +249,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn lerp(&self, other: &Self, t: T) -> Self {
|
pub fn lerp(&self, other: &Self, t: T) -> Self {
|
||||||
self * (T::one() - t) + other * t
|
self * (T::one() - t.clone()) + other * t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,15 +296,15 @@ where
|
||||||
let dq: Dq<T> = Dq::<T>::deserialize(deserializer)?;
|
let dq: Dq<T> = Dq::<T>::deserialize(deserializer)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
real: Quaternion::new(dq[3], dq[0], dq[1], dq[2]),
|
real: Quaternion::new(dq[3].clone(), dq[0].clone(), dq[1].clone(), dq[2].clone()),
|
||||||
dual: Quaternion::new(dq[7], dq[4], dq[5], dq[6]),
|
dual: Quaternion::new(dq[7].clone(), dq[4].clone(), dq[5].clone(), dq[6].clone()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RealField> DualQuaternion<T> {
|
impl<T: RealField> DualQuaternion<T> {
|
||||||
fn to_vector(self) -> OVector<T, U8> {
|
fn to_vector(self) -> OVector<T, U8> {
|
||||||
(*self.as_ref()).into()
|
self.as_ref().clone().into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,9 +318,9 @@ impl<T: RealField + AbsDiffEq<Epsilon = T>> AbsDiffEq for DualQuaternion<T> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
|
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
|
||||||
self.to_vector().abs_diff_eq(&other.to_vector(), epsilon) ||
|
self.clone().to_vector().abs_diff_eq(&other.clone().to_vector(), epsilon.clone()) ||
|
||||||
// Account for the double-covering of S², i.e. q = -q
|
// Account for the double-covering of S², i.e. q = -q
|
||||||
self.to_vector().iter().zip(other.to_vector().iter()).all(|(a, b)| a.abs_diff_eq(&-*b, epsilon))
|
self.clone().to_vector().iter().zip(other.clone().to_vector().iter()).all(|(a, b)| a.abs_diff_eq(&-b.clone(), epsilon.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,9 +337,9 @@ impl<T: RealField + RelativeEq<Epsilon = T>> RelativeEq for DualQuaternion<T> {
|
||||||
epsilon: Self::Epsilon,
|
epsilon: Self::Epsilon,
|
||||||
max_relative: Self::Epsilon,
|
max_relative: Self::Epsilon,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
self.to_vector().relative_eq(&other.to_vector(), epsilon, max_relative) ||
|
self.clone().to_vector().relative_eq(&other.clone().to_vector(), epsilon.clone(), max_relative.clone()) ||
|
||||||
// Account for the double-covering of S², i.e. q = -q
|
// Account for the double-covering of S², i.e. q = -q
|
||||||
self.to_vector().iter().zip(other.to_vector().iter()).all(|(a, b)| a.relative_eq(&-*b, epsilon, max_relative))
|
self.clone().to_vector().iter().zip(other.clone().to_vector().iter()).all(|(a, b)| a.relative_eq(&-b.clone(), epsilon.clone(), max_relative.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,9 +351,9 @@ impl<T: RealField + UlpsEq<Epsilon = T>> UlpsEq for DualQuaternion<T> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
|
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
|
||||||
self.to_vector().ulps_eq(&other.to_vector(), epsilon, max_ulps) ||
|
self.clone().to_vector().ulps_eq(&other.clone().to_vector(), epsilon.clone(), max_ulps.clone()) ||
|
||||||
// Account for the double-covering of S², i.e. q = -q.
|
// Account for the double-covering of S², i.e. q = -q.
|
||||||
self.to_vector().iter().zip(other.to_vector().iter()).all(|(a, b)| a.ulps_eq(&-*b, epsilon, max_ulps))
|
self.clone().to_vector().iter().zip(other.clone().to_vector().iter()).all(|(a, b)| a.ulps_eq(&-b.clone(), epsilon.clone(), max_ulps.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,13 +384,13 @@ impl<T: SimdRealField> Normed for DualQuaternion<T> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scale_mut(&mut self, n: Self::Norm) {
|
fn scale_mut(&mut self, n: Self::Norm) {
|
||||||
self.real.scale_mut(n);
|
self.real.scale_mut(n.clone());
|
||||||
self.dual.scale_mut(n);
|
self.dual.scale_mut(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn unscale_mut(&mut self, n: Self::Norm) {
|
fn unscale_mut(&mut self, n: Self::Norm) {
|
||||||
self.real.unscale_mut(n);
|
self.real.unscale_mut(n.clone());
|
||||||
self.dual.unscale_mut(n);
|
self.dual.unscale_mut(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -471,10 +474,10 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use = "Did you mean to use inverse_mut()?"]
|
#[must_use = "Did you mean to use inverse_mut()?"]
|
||||||
pub fn inverse(&self) -> Self {
|
pub fn inverse(&self) -> Self {
|
||||||
let real = Unit::new_unchecked(self.as_ref().real)
|
let real = Unit::new_unchecked(self.as_ref().real.clone())
|
||||||
.inverse()
|
.inverse()
|
||||||
.into_inner();
|
.into_inner();
|
||||||
let dual = -real * self.as_ref().dual * real;
|
let dual = -real.clone() * self.as_ref().dual.clone() * real.clone();
|
||||||
UnitDualQuaternion::new_unchecked(DualQuaternion { real, dual })
|
UnitDualQuaternion::new_unchecked(DualQuaternion { real, dual })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,8 +498,10 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inverse_mut(&mut self) {
|
pub fn inverse_mut(&mut self) {
|
||||||
let quat = self.as_mut_unchecked();
|
let quat = self.as_mut_unchecked();
|
||||||
quat.real = Unit::new_unchecked(quat.real).inverse().into_inner();
|
quat.real = Unit::new_unchecked(quat.real.clone())
|
||||||
quat.dual = -quat.real * quat.dual * quat.real;
|
.inverse()
|
||||||
|
.into_inner();
|
||||||
|
quat.dual = -quat.real.clone() * quat.dual.clone() * quat.real.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The unit dual quaternion needed to make `self` and `other` coincide.
|
/// The unit dual quaternion needed to make `self` and `other` coincide.
|
||||||
|
@ -639,16 +644,16 @@ where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let two = T::one() + T::one();
|
let two = T::one() + T::one();
|
||||||
let half = T::one() / two;
|
let half = T::one() / two.clone();
|
||||||
|
|
||||||
// Invert one of the quaternions if we've got a longest-path
|
// Invert one of the quaternions if we've got a longest-path
|
||||||
// interpolation.
|
// interpolation.
|
||||||
let other = {
|
let other = {
|
||||||
let dot_product = self.as_ref().real.coords.dot(&other.as_ref().real.coords);
|
let dot_product = self.as_ref().real.coords.dot(&other.as_ref().real.coords);
|
||||||
if dot_product < T::zero() {
|
if dot_product < T::zero() {
|
||||||
-*other
|
-other.clone()
|
||||||
} else {
|
} else {
|
||||||
*other
|
other.clone()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -661,21 +666,21 @@ where
|
||||||
let inverse_norm_squared = T::one() / norm_squared;
|
let inverse_norm_squared = T::one() / norm_squared;
|
||||||
let inverse_norm = inverse_norm_squared.sqrt();
|
let inverse_norm = inverse_norm_squared.sqrt();
|
||||||
|
|
||||||
let mut angle = two * difference.real.scalar().acos();
|
let mut angle = two.clone() * difference.real.scalar().acos();
|
||||||
let mut pitch = -two * difference.dual.scalar() * inverse_norm;
|
let mut pitch = -two * difference.dual.scalar() * inverse_norm.clone();
|
||||||
let direction = difference.real.vector() * inverse_norm;
|
let direction = difference.real.vector() * inverse_norm.clone();
|
||||||
let moment = (difference.dual.vector()
|
let moment = (difference.dual.vector()
|
||||||
- direction * (pitch * difference.real.scalar() * half))
|
- direction.clone() * (pitch.clone() * difference.real.scalar() * half.clone()))
|
||||||
* inverse_norm;
|
* inverse_norm;
|
||||||
|
|
||||||
angle *= t;
|
angle *= t.clone();
|
||||||
pitch *= t;
|
pitch *= t;
|
||||||
|
|
||||||
let sin = (half * angle).sin();
|
let sin = (half.clone() * angle.clone()).sin();
|
||||||
let cos = (half * angle).cos();
|
let cos = (half.clone() * angle).cos();
|
||||||
let real = Quaternion::from_parts(cos, direction * sin);
|
let real = Quaternion::from_parts(cos.clone(), direction.clone() * sin.clone());
|
||||||
let dual = Quaternion::from_parts(
|
let dual = Quaternion::from_parts(
|
||||||
-pitch * half * sin,
|
-pitch.clone() * half.clone() * sin.clone(),
|
||||||
moment * sin + direction * (pitch * half * cos),
|
moment * sin + direction * (pitch * half * cos),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -703,7 +708,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn rotation(&self) -> UnitQuaternion<T> {
|
pub fn rotation(&self) -> UnitQuaternion<T> {
|
||||||
Unit::new_unchecked(self.as_ref().real)
|
Unit::new_unchecked(self.as_ref().real.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the translation part of this unit dual quaternion.
|
/// Return the translation part of this unit dual quaternion.
|
||||||
|
@ -725,7 +730,7 @@ where
|
||||||
pub fn translation(&self) -> Translation3<T> {
|
pub fn translation(&self) -> Translation3<T> {
|
||||||
let two = T::one() + T::one();
|
let two = T::one() + T::one();
|
||||||
Translation3::from(
|
Translation3::from(
|
||||||
((self.as_ref().dual * self.as_ref().real.conjugate()) * two)
|
((self.as_ref().dual.clone() * self.as_ref().real.clone().conjugate()) * two)
|
||||||
.vector()
|
.vector()
|
||||||
.into_owned(),
|
.into_owned(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -186,7 +186,7 @@ where
|
||||||
pub fn from_parts(translation: Translation3<T>, rotation: UnitQuaternion<T>) -> Self {
|
pub fn from_parts(translation: Translation3<T>, rotation: UnitQuaternion<T>) -> Self {
|
||||||
let half: T = crate::convert(0.5f64);
|
let half: T = crate::convert(0.5f64);
|
||||||
UnitDualQuaternion::new_unchecked(DualQuaternion {
|
UnitDualQuaternion::new_unchecked(DualQuaternion {
|
||||||
real: rotation.into_inner(),
|
real: rotation.clone().into_inner(),
|
||||||
dual: Quaternion::from_parts(T::zero(), translation.vector)
|
dual: Quaternion::from_parts(T::zero(), translation.vector)
|
||||||
* rotation.into_inner()
|
* rotation.into_inner()
|
||||||
* half,
|
* half,
|
||||||
|
@ -210,6 +210,8 @@ where
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_isometry(isometry: &Isometry3<T>) -> Self {
|
pub fn from_isometry(isometry: &Isometry3<T>) -> Self {
|
||||||
|
// TODO: take the isometry by-move instead of cloning it.
|
||||||
|
let isometry = isometry.clone();
|
||||||
UnitDualQuaternion::from_parts(isometry.translation, isometry.rotation)
|
UnitDualQuaternion::from_parts(isometry.translation, isometry.rotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,7 @@ where
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Transform<T2, C, 3> {
|
fn to_superset(&self) -> Transform<T2, C, 3> {
|
||||||
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
Transform::from_matrix_unchecked(self.clone().to_homogeneous().to_superset())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -141,7 +141,7 @@ impl<T1: RealField, T2: RealField + SupersetOf<T1>> SubsetOf<Matrix4<T2>>
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Matrix4<T2> {
|
fn to_superset(&self) -> Matrix4<T2> {
|
||||||
self.to_homogeneous().to_superset()
|
self.clone().to_homogeneous().to_superset()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -417,7 +417,7 @@ dual_quaternion_op_impl!(
|
||||||
(U4, U1), (U4, U1);
|
(U4, U1), (U4, U1);
|
||||||
self: &'a UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>,
|
self: &'a UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>,
|
||||||
Output = UnitDualQuaternion<T> => U1, U4;
|
Output = UnitDualQuaternion<T> => U1, U4;
|
||||||
self * UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(rhs.into_inner()));
|
self * UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(rhs.clone().into_inner()));
|
||||||
'a, 'b);
|
'a, 'b);
|
||||||
|
|
||||||
dual_quaternion_op_impl!(
|
dual_quaternion_op_impl!(
|
||||||
|
@ -433,7 +433,7 @@ dual_quaternion_op_impl!(
|
||||||
(U4, U1), (U4, U1);
|
(U4, U1), (U4, U1);
|
||||||
self: UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>,
|
self: UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>,
|
||||||
Output = UnitDualQuaternion<T> => U3, U3;
|
Output = UnitDualQuaternion<T> => U3, U3;
|
||||||
self * UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(rhs.into_inner()));
|
self * UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(rhs.clone().into_inner()));
|
||||||
'b);
|
'b);
|
||||||
|
|
||||||
dual_quaternion_op_impl!(
|
dual_quaternion_op_impl!(
|
||||||
|
@ -449,7 +449,7 @@ dual_quaternion_op_impl!(
|
||||||
(U4, U1), (U4, U1);
|
(U4, U1), (U4, U1);
|
||||||
self: &'a UnitQuaternion<T>, rhs: &'b UnitDualQuaternion<T>,
|
self: &'a UnitQuaternion<T>, rhs: &'b UnitDualQuaternion<T>,
|
||||||
Output = UnitDualQuaternion<T> => U1, U4;
|
Output = UnitDualQuaternion<T> => U1, U4;
|
||||||
UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(self.into_inner())) * rhs;
|
UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(self.clone().into_inner())) * rhs;
|
||||||
'a, 'b);
|
'a, 'b);
|
||||||
|
|
||||||
dual_quaternion_op_impl!(
|
dual_quaternion_op_impl!(
|
||||||
|
@ -457,7 +457,7 @@ dual_quaternion_op_impl!(
|
||||||
(U4, U1), (U4, U1);
|
(U4, U1), (U4, U1);
|
||||||
self: &'a UnitQuaternion<T>, rhs: UnitDualQuaternion<T>,
|
self: &'a UnitQuaternion<T>, rhs: UnitDualQuaternion<T>,
|
||||||
Output = UnitDualQuaternion<T> => U3, U3;
|
Output = UnitDualQuaternion<T> => U3, U3;
|
||||||
UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(self.into_inner())) * rhs;
|
UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(self.clone().into_inner())) * rhs;
|
||||||
'a);
|
'a);
|
||||||
|
|
||||||
dual_quaternion_op_impl!(
|
dual_quaternion_op_impl!(
|
||||||
|
@ -520,7 +520,7 @@ dual_quaternion_op_impl!(
|
||||||
#[allow(clippy::suspicious_arithmetic_impl)]
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
||||||
{
|
{
|
||||||
UnitDualQuaternion::<T>::new_unchecked(
|
UnitDualQuaternion::<T>::new_unchecked(
|
||||||
DualQuaternion::from_real(self.into_inner())
|
DualQuaternion::from_real(self.clone().into_inner())
|
||||||
) * rhs.inverse()
|
) * rhs.inverse()
|
||||||
}; 'a, 'b);
|
}; 'a, 'b);
|
||||||
|
|
||||||
|
@ -532,7 +532,7 @@ dual_quaternion_op_impl!(
|
||||||
#[allow(clippy::suspicious_arithmetic_impl)]
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
||||||
{
|
{
|
||||||
UnitDualQuaternion::<T>::new_unchecked(
|
UnitDualQuaternion::<T>::new_unchecked(
|
||||||
DualQuaternion::from_real(self.into_inner())
|
DualQuaternion::from_real(self.clone().into_inner())
|
||||||
) * rhs.inverse()
|
) * rhs.inverse()
|
||||||
}; 'a);
|
}; 'a);
|
||||||
|
|
||||||
|
@ -566,7 +566,7 @@ dual_quaternion_op_impl!(
|
||||||
(U4, U1), (U3, U1);
|
(U4, U1), (U3, U1);
|
||||||
self: &'a UnitDualQuaternion<T>, rhs: &'b Translation3<T>,
|
self: &'a UnitDualQuaternion<T>, rhs: &'b Translation3<T>,
|
||||||
Output = UnitDualQuaternion<T> => U3, U1;
|
Output = UnitDualQuaternion<T> => U3, U1;
|
||||||
self * UnitDualQuaternion::<T>::from_parts(*rhs, UnitQuaternion::identity());
|
self * UnitDualQuaternion::<T>::from_parts(rhs.clone(), UnitQuaternion::identity());
|
||||||
'a, 'b);
|
'a, 'b);
|
||||||
|
|
||||||
dual_quaternion_op_impl!(
|
dual_quaternion_op_impl!(
|
||||||
|
@ -582,7 +582,7 @@ dual_quaternion_op_impl!(
|
||||||
(U4, U1), (U3, U3);
|
(U4, U1), (U3, U3);
|
||||||
self: UnitDualQuaternion<T>, rhs: &'b Translation3<T>,
|
self: UnitDualQuaternion<T>, rhs: &'b Translation3<T>,
|
||||||
Output = UnitDualQuaternion<T> => U3, U1;
|
Output = UnitDualQuaternion<T> => U3, U1;
|
||||||
self * UnitDualQuaternion::<T>::from_parts(*rhs, UnitQuaternion::identity());
|
self * UnitDualQuaternion::<T>::from_parts(rhs.clone(), UnitQuaternion::identity());
|
||||||
'b);
|
'b);
|
||||||
|
|
||||||
dual_quaternion_op_impl!(
|
dual_quaternion_op_impl!(
|
||||||
|
@ -634,7 +634,7 @@ dual_quaternion_op_impl!(
|
||||||
(U3, U1), (U4, U1);
|
(U3, U1), (U4, U1);
|
||||||
self: &'b Translation3<T>, rhs: &'a UnitDualQuaternion<T>,
|
self: &'b Translation3<T>, rhs: &'a UnitDualQuaternion<T>,
|
||||||
Output = UnitDualQuaternion<T> => U3, U1;
|
Output = UnitDualQuaternion<T> => U3, U1;
|
||||||
UnitDualQuaternion::<T>::from_parts(*self, UnitQuaternion::identity()) * rhs;
|
UnitDualQuaternion::<T>::from_parts(self.clone(), UnitQuaternion::identity()) * rhs;
|
||||||
'a, 'b);
|
'a, 'b);
|
||||||
|
|
||||||
dual_quaternion_op_impl!(
|
dual_quaternion_op_impl!(
|
||||||
|
@ -642,7 +642,7 @@ dual_quaternion_op_impl!(
|
||||||
(U3, U1), (U4, U1);
|
(U3, U1), (U4, U1);
|
||||||
self: &'a Translation3<T>, rhs: UnitDualQuaternion<T>,
|
self: &'a Translation3<T>, rhs: UnitDualQuaternion<T>,
|
||||||
Output = UnitDualQuaternion<T> => U3, U1;
|
Output = UnitDualQuaternion<T> => U3, U1;
|
||||||
UnitDualQuaternion::<T>::from_parts(*self, UnitQuaternion::identity()) * rhs;
|
UnitDualQuaternion::<T>::from_parts(self.clone(), UnitQuaternion::identity()) * rhs;
|
||||||
'a);
|
'a);
|
||||||
|
|
||||||
dual_quaternion_op_impl!(
|
dual_quaternion_op_impl!(
|
||||||
|
@ -666,7 +666,7 @@ dual_quaternion_op_impl!(
|
||||||
(U3, U1), (U4, U1);
|
(U3, U1), (U4, U1);
|
||||||
self: &'b Translation3<T>, rhs: &'a UnitDualQuaternion<T>,
|
self: &'b Translation3<T>, rhs: &'a UnitDualQuaternion<T>,
|
||||||
Output = UnitDualQuaternion<T> => U3, U1;
|
Output = UnitDualQuaternion<T> => U3, U1;
|
||||||
UnitDualQuaternion::<T>::from_parts(*self, UnitQuaternion::identity()) / rhs;
|
UnitDualQuaternion::<T>::from_parts(self.clone(), UnitQuaternion::identity()) / rhs;
|
||||||
'a, 'b);
|
'a, 'b);
|
||||||
|
|
||||||
dual_quaternion_op_impl!(
|
dual_quaternion_op_impl!(
|
||||||
|
@ -674,7 +674,7 @@ dual_quaternion_op_impl!(
|
||||||
(U3, U1), (U4, U1);
|
(U3, U1), (U4, U1);
|
||||||
self: &'a Translation3<T>, rhs: UnitDualQuaternion<T>,
|
self: &'a Translation3<T>, rhs: UnitDualQuaternion<T>,
|
||||||
Output = UnitDualQuaternion<T> => U3, U1;
|
Output = UnitDualQuaternion<T> => U3, U1;
|
||||||
UnitDualQuaternion::<T>::from_parts(*self, UnitQuaternion::identity()) / rhs;
|
UnitDualQuaternion::<T>::from_parts(self.clone(), UnitQuaternion::identity()) / rhs;
|
||||||
'a);
|
'a);
|
||||||
|
|
||||||
dual_quaternion_op_impl!(
|
dual_quaternion_op_impl!(
|
||||||
|
@ -828,7 +828,7 @@ dual_quaternion_op_impl!(
|
||||||
(U4, U1), (U3, U1) for SB: Storage<T, U3> ;
|
(U4, U1), (U3, U1) for SB: Storage<T, U3> ;
|
||||||
self: &'a UnitDualQuaternion<T>, rhs: &'b Vector<T, U3, SB>,
|
self: &'a UnitDualQuaternion<T>, rhs: &'b Vector<T, U3, SB>,
|
||||||
Output = Vector3<T> => U3, U1;
|
Output = Vector3<T> => U3, U1;
|
||||||
Unit::new_unchecked(self.as_ref().real) * rhs;
|
Unit::new_unchecked(self.as_ref().real.clone()) * rhs;
|
||||||
'a, 'b);
|
'a, 'b);
|
||||||
|
|
||||||
dual_quaternion_op_impl!(
|
dual_quaternion_op_impl!(
|
||||||
|
@ -862,9 +862,9 @@ dual_quaternion_op_impl!(
|
||||||
Output = Point3<T> => U3, U1;
|
Output = Point3<T> => U3, U1;
|
||||||
{
|
{
|
||||||
let two: T = crate::convert(2.0f64);
|
let two: T = crate::convert(2.0f64);
|
||||||
let q_point = Quaternion::from_parts(T::zero(), rhs.coords);
|
let q_point = Quaternion::from_parts(T::zero(), rhs.coords.clone());
|
||||||
Point::from(
|
Point::from(
|
||||||
((self.as_ref().real * q_point + self.as_ref().dual * two) * self.as_ref().real.conjugate())
|
((self.as_ref().real.clone() * q_point + self.as_ref().dual.clone() * two) * self.as_ref().real.clone().conjugate())
|
||||||
.vector()
|
.vector()
|
||||||
.into_owned(),
|
.into_owned(),
|
||||||
)
|
)
|
||||||
|
@ -1117,7 +1117,7 @@ dual_quaternion_op_impl!(
|
||||||
MulAssign, mul_assign;
|
MulAssign, mul_assign;
|
||||||
(U4, U1), (U4, U1);
|
(U4, U1), (U4, U1);
|
||||||
self: UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>;
|
self: UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>;
|
||||||
*self *= *rhs; 'b);
|
*self *= rhs.clone(); 'b);
|
||||||
|
|
||||||
// UnitDualQuaternion ÷= UnitQuaternion
|
// UnitDualQuaternion ÷= UnitQuaternion
|
||||||
dual_quaternion_op_impl!(
|
dual_quaternion_op_impl!(
|
||||||
|
@ -1153,7 +1153,7 @@ dual_quaternion_op_impl!(
|
||||||
MulAssign, mul_assign;
|
MulAssign, mul_assign;
|
||||||
(U4, U1), (U4, U1);
|
(U4, U1), (U4, U1);
|
||||||
self: UnitDualQuaternion<T>, rhs: &'b Translation3<T>;
|
self: UnitDualQuaternion<T>, rhs: &'b Translation3<T>;
|
||||||
*self *= *rhs; 'b);
|
*self *= rhs.clone(); 'b);
|
||||||
|
|
||||||
// UnitDualQuaternion ÷= Translation3
|
// UnitDualQuaternion ÷= Translation3
|
||||||
dual_quaternion_op_impl!(
|
dual_quaternion_op_impl!(
|
||||||
|
@ -1219,8 +1219,8 @@ macro_rules! scalar_op_impl(
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $op(self, n: T) -> Self::Output {
|
fn $op(self, n: T) -> Self::Output {
|
||||||
DualQuaternion::from_real_and_dual(
|
DualQuaternion::from_real_and_dual(
|
||||||
self.real.$op(n),
|
self.real.clone().$op(n.clone()),
|
||||||
self.dual.$op(n)
|
self.dual.clone().$op(n)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1232,8 +1232,8 @@ macro_rules! scalar_op_impl(
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $op(self, n: T) -> Self::Output {
|
fn $op(self, n: T) -> Self::Output {
|
||||||
DualQuaternion::from_real_and_dual(
|
DualQuaternion::from_real_and_dual(
|
||||||
self.real.$op(n),
|
self.real.clone().$op(n.clone()),
|
||||||
self.dual.$op(n)
|
self.dual.clone().$op(n)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1243,7 +1243,7 @@ macro_rules! scalar_op_impl(
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $op_assign(&mut self, n: T) {
|
fn $op_assign(&mut self, n: T) {
|
||||||
self.real.$op_assign(n);
|
self.real.$op_assign(n.clone());
|
||||||
self.dual.$op_assign(n);
|
self.dual.$op_assign(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -272,7 +272,7 @@ where
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn inv_mul(&self, rhs: &Isometry<T, R, D>) -> Self {
|
pub fn inv_mul(&self, rhs: &Isometry<T, R, D>) -> Self {
|
||||||
let inv_rot1 = self.rotation.inverse();
|
let inv_rot1 = self.rotation.inverse();
|
||||||
let tr_12 = rhs.translation.vector - self.translation.vector;
|
let tr_12 = &rhs.translation.vector - &self.translation.vector;
|
||||||
Isometry::from_parts(
|
Isometry::from_parts(
|
||||||
inv_rot1.transform_vector(&tr_12).into(),
|
inv_rot1.transform_vector(&tr_12).into(),
|
||||||
inv_rot1 * rhs.rotation.clone(),
|
inv_rot1 * rhs.rotation.clone(),
|
||||||
|
@ -437,7 +437,7 @@ where
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
|
||||||
self.rotation
|
self.rotation
|
||||||
.inverse_transform_point(&(pt - self.translation.vector))
|
.inverse_transform_point(&(pt - &self.translation.vector))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transform the given vector by the inverse of this isometry, ignoring the
|
/// Transform the given vector by the inverse of this isometry, ignoring the
|
||||||
|
@ -574,7 +574,7 @@ where
|
||||||
impl<T: RealField, R, const D: usize> AbsDiffEq for Isometry<T, R, D>
|
impl<T: RealField, R, const D: usize> AbsDiffEq for Isometry<T, R, D>
|
||||||
where
|
where
|
||||||
R: AbstractRotation<T, D> + AbsDiffEq<Epsilon = T::Epsilon>,
|
R: AbstractRotation<T, D> + AbsDiffEq<Epsilon = T::Epsilon>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
type Epsilon = T::Epsilon;
|
type Epsilon = T::Epsilon;
|
||||||
|
|
||||||
|
@ -585,7 +585,8 @@ where
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
|
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
|
||||||
self.translation.abs_diff_eq(&other.translation, epsilon)
|
self.translation
|
||||||
|
.abs_diff_eq(&other.translation, epsilon.clone())
|
||||||
&& self.rotation.abs_diff_eq(&other.rotation, epsilon)
|
&& self.rotation.abs_diff_eq(&other.rotation, epsilon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -593,7 +594,7 @@ where
|
||||||
impl<T: RealField, R, const D: usize> RelativeEq for Isometry<T, R, D>
|
impl<T: RealField, R, const D: usize> RelativeEq for Isometry<T, R, D>
|
||||||
where
|
where
|
||||||
R: AbstractRotation<T, D> + RelativeEq<Epsilon = T::Epsilon>,
|
R: AbstractRotation<T, D> + RelativeEq<Epsilon = T::Epsilon>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default_max_relative() -> Self::Epsilon {
|
fn default_max_relative() -> Self::Epsilon {
|
||||||
|
@ -608,7 +609,7 @@ where
|
||||||
max_relative: Self::Epsilon,
|
max_relative: Self::Epsilon,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
self.translation
|
self.translation
|
||||||
.relative_eq(&other.translation, epsilon, max_relative)
|
.relative_eq(&other.translation, epsilon.clone(), max_relative.clone())
|
||||||
&& self
|
&& self
|
||||||
.rotation
|
.rotation
|
||||||
.relative_eq(&other.rotation, epsilon, max_relative)
|
.relative_eq(&other.rotation, epsilon, max_relative)
|
||||||
|
@ -618,7 +619,7 @@ where
|
||||||
impl<T: RealField, R, const D: usize> UlpsEq for Isometry<T, R, D>
|
impl<T: RealField, R, const D: usize> UlpsEq for Isometry<T, R, D>
|
||||||
where
|
where
|
||||||
R: AbstractRotation<T, D> + UlpsEq<Epsilon = T::Epsilon>,
|
R: AbstractRotation<T, D> + UlpsEq<Epsilon = T::Epsilon>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default_max_ulps() -> u32 {
|
fn default_max_ulps() -> u32 {
|
||||||
|
@ -628,7 +629,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
|
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
|
||||||
self.translation
|
self.translation
|
||||||
.ulps_eq(&other.translation, epsilon, max_ulps)
|
.ulps_eq(&other.translation, epsilon.clone(), max_ulps.clone())
|
||||||
&& self.rotation.ulps_eq(&other.rotation, epsilon, max_ulps)
|
&& self.rotation.ulps_eq(&other.rotation, epsilon, max_ulps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,10 @@ impl<T: SimdRealField> Isometry3<T> {
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let tr = self.translation.vector.lerp(&other.translation.vector, t);
|
let tr = self
|
||||||
|
.translation
|
||||||
|
.vector
|
||||||
|
.lerp(&other.translation.vector, t.clone());
|
||||||
let rot = self.rotation.slerp(&other.rotation, t);
|
let rot = self.rotation.slerp(&other.rotation, t);
|
||||||
Self::from_parts(tr.into(), rot)
|
Self::from_parts(tr.into(), rot)
|
||||||
}
|
}
|
||||||
|
@ -65,7 +68,10 @@ impl<T: SimdRealField> Isometry3<T> {
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let tr = self.translation.vector.lerp(&other.translation.vector, t);
|
let tr = self
|
||||||
|
.translation
|
||||||
|
.vector
|
||||||
|
.lerp(&other.translation.vector, t.clone());
|
||||||
let rot = self.rotation.try_slerp(&other.rotation, t, epsilon)?;
|
let rot = self.rotation.try_slerp(&other.rotation, t, epsilon)?;
|
||||||
Some(Self::from_parts(tr.into(), rot))
|
Some(Self::from_parts(tr.into(), rot))
|
||||||
}
|
}
|
||||||
|
@ -101,7 +107,10 @@ impl<T: SimdRealField> IsometryMatrix3<T> {
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let tr = self.translation.vector.lerp(&other.translation.vector, t);
|
let tr = self
|
||||||
|
.translation
|
||||||
|
.vector
|
||||||
|
.lerp(&other.translation.vector, t.clone());
|
||||||
let rot = self.rotation.slerp(&other.rotation, t);
|
let rot = self.rotation.slerp(&other.rotation, t);
|
||||||
Self::from_parts(tr.into(), rot)
|
Self::from_parts(tr.into(), rot)
|
||||||
}
|
}
|
||||||
|
@ -135,7 +144,10 @@ impl<T: SimdRealField> IsometryMatrix3<T> {
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let tr = self.translation.vector.lerp(&other.translation.vector, t);
|
let tr = self
|
||||||
|
.translation
|
||||||
|
.vector
|
||||||
|
.lerp(&other.translation.vector, t.clone());
|
||||||
let rot = self.rotation.try_slerp(&other.rotation, t, epsilon)?;
|
let rot = self.rotation.try_slerp(&other.rotation, t, epsilon)?;
|
||||||
Some(Self::from_parts(tr.into(), rot))
|
Some(Self::from_parts(tr.into(), rot))
|
||||||
}
|
}
|
||||||
|
@ -172,7 +184,10 @@ impl<T: SimdRealField> Isometry2<T> {
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let tr = self.translation.vector.lerp(&other.translation.vector, t);
|
let tr = self
|
||||||
|
.translation
|
||||||
|
.vector
|
||||||
|
.lerp(&other.translation.vector, t.clone());
|
||||||
let rot = self.rotation.slerp(&other.rotation, t);
|
let rot = self.rotation.slerp(&other.rotation, t);
|
||||||
Self::from_parts(tr.into(), rot)
|
Self::from_parts(tr.into(), rot)
|
||||||
}
|
}
|
||||||
|
@ -209,7 +224,10 @@ impl<T: SimdRealField> IsometryMatrix2<T> {
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let tr = self.translation.vector.lerp(&other.translation.vector, t);
|
let tr = self
|
||||||
|
.translation
|
||||||
|
.vector
|
||||||
|
.lerp(&other.translation.vector, t.clone());
|
||||||
let rot = self.rotation.slerp(&other.rotation, t);
|
let rot = self.rotation.slerp(&other.rotation, t);
|
||||||
Self::from_parts(tr.into(), rot)
|
Self::from_parts(tr.into(), rot)
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,7 +201,7 @@ md_assign_impl_all!(
|
||||||
const D; for; where;
|
const D; for; where;
|
||||||
self: Isometry<T, Rotation<T, D>, D>, rhs: Rotation<T, D>;
|
self: Isometry<T, Rotation<T, D>, D>, rhs: Rotation<T, D>;
|
||||||
[val] => self.rotation *= rhs;
|
[val] => self.rotation *= rhs;
|
||||||
[ref] => self.rotation *= *rhs;
|
[ref] => self.rotation *= rhs.clone();
|
||||||
);
|
);
|
||||||
|
|
||||||
md_assign_impl_all!(
|
md_assign_impl_all!(
|
||||||
|
@ -220,7 +220,7 @@ md_assign_impl_all!(
|
||||||
const; for; where;
|
const; for; where;
|
||||||
self: Isometry<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>;
|
self: Isometry<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>;
|
||||||
[val] => self.rotation *= rhs;
|
[val] => self.rotation *= rhs;
|
||||||
[ref] => self.rotation *= *rhs;
|
[ref] => self.rotation *= rhs.clone();
|
||||||
);
|
);
|
||||||
|
|
||||||
md_assign_impl_all!(
|
md_assign_impl_all!(
|
||||||
|
@ -239,7 +239,7 @@ md_assign_impl_all!(
|
||||||
const; for; where;
|
const; for; where;
|
||||||
self: Isometry<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>;
|
self: Isometry<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>;
|
||||||
[val] => self.rotation *= rhs;
|
[val] => self.rotation *= rhs;
|
||||||
[ref] => self.rotation *= *rhs;
|
[ref] => self.rotation *= rhs.clone();
|
||||||
);
|
);
|
||||||
|
|
||||||
md_assign_impl_all!(
|
md_assign_impl_all!(
|
||||||
|
@ -368,9 +368,9 @@ isometry_from_composition_impl_all!(
|
||||||
D;
|
D;
|
||||||
self: Rotation<T, D>, right: Translation<T, D>, Output = Isometry<T, Rotation<T, D>, D>;
|
self: Rotation<T, D>, right: Translation<T, D>, Output = Isometry<T, Rotation<T, D>, D>;
|
||||||
[val val] => Isometry::from_parts(Translation::from(&self * right.vector), self);
|
[val val] => Isometry::from_parts(Translation::from(&self * right.vector), self);
|
||||||
[ref val] => Isometry::from_parts(Translation::from(self * right.vector), *self);
|
[ref val] => Isometry::from_parts(Translation::from(self * right.vector), self.clone());
|
||||||
[val ref] => Isometry::from_parts(Translation::from(&self * &right.vector), self);
|
[val ref] => Isometry::from_parts(Translation::from(&self * &right.vector), self);
|
||||||
[ref ref] => Isometry::from_parts(Translation::from(self * &right.vector), *self);
|
[ref ref] => Isometry::from_parts(Translation::from(self * &right.vector), self.clone());
|
||||||
);
|
);
|
||||||
|
|
||||||
// UnitQuaternion × Translation
|
// UnitQuaternion × Translation
|
||||||
|
@ -380,9 +380,9 @@ isometry_from_composition_impl_all!(
|
||||||
self: UnitQuaternion<T>, right: Translation<T, 3>,
|
self: UnitQuaternion<T>, right: Translation<T, 3>,
|
||||||
Output = Isometry<T, UnitQuaternion<T>, 3>;
|
Output = Isometry<T, UnitQuaternion<T>, 3>;
|
||||||
[val val] => Isometry::from_parts(Translation::from(&self * right.vector), self);
|
[val val] => Isometry::from_parts(Translation::from(&self * right.vector), self);
|
||||||
[ref val] => Isometry::from_parts(Translation::from( self * right.vector), *self);
|
[ref val] => Isometry::from_parts(Translation::from( self * right.vector), self.clone());
|
||||||
[val ref] => Isometry::from_parts(Translation::from(&self * &right.vector), self);
|
[val ref] => Isometry::from_parts(Translation::from(&self * &right.vector), self);
|
||||||
[ref ref] => Isometry::from_parts(Translation::from( self * &right.vector), *self);
|
[ref ref] => Isometry::from_parts(Translation::from( self * &right.vector), self.clone());
|
||||||
);
|
);
|
||||||
|
|
||||||
// Isometry × Rotation
|
// Isometry × Rotation
|
||||||
|
@ -392,9 +392,9 @@ isometry_from_composition_impl_all!(
|
||||||
self: Isometry<T, Rotation<T, D>, D>, rhs: Rotation<T, D>,
|
self: Isometry<T, Rotation<T, D>, D>, rhs: Rotation<T, D>,
|
||||||
Output = Isometry<T, Rotation<T, D>, D>;
|
Output = Isometry<T, Rotation<T, D>, D>;
|
||||||
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
|
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
|
||||||
[ref val] => Isometry::from_parts(self.translation, self.rotation * rhs);
|
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs);
|
||||||
[val ref] => Isometry::from_parts(self.translation, self.rotation * *rhs);
|
[val ref] => Isometry::from_parts(self.translation, self.rotation * rhs.clone());
|
||||||
[ref ref] => Isometry::from_parts(self.translation, self.rotation * *rhs);
|
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs.clone());
|
||||||
);
|
);
|
||||||
|
|
||||||
// Rotation × Isometry
|
// Rotation × Isometry
|
||||||
|
@ -419,9 +419,9 @@ isometry_from_composition_impl_all!(
|
||||||
self: Isometry<T, Rotation<T, D>, D>, rhs: Rotation<T, D>,
|
self: Isometry<T, Rotation<T, D>, D>, rhs: Rotation<T, D>,
|
||||||
Output = Isometry<T, Rotation<T, D>, D>;
|
Output = Isometry<T, Rotation<T, D>, D>;
|
||||||
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
|
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
|
||||||
[ref val] => Isometry::from_parts(self.translation, self.rotation / rhs);
|
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs);
|
||||||
[val ref] => Isometry::from_parts(self.translation, self.rotation / *rhs);
|
[val ref] => Isometry::from_parts(self.translation, self.rotation / rhs.clone());
|
||||||
[ref ref] => Isometry::from_parts(self.translation, self.rotation / *rhs);
|
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs.clone());
|
||||||
);
|
);
|
||||||
|
|
||||||
// Rotation ÷ Isometry
|
// Rotation ÷ Isometry
|
||||||
|
@ -444,9 +444,9 @@ isometry_from_composition_impl_all!(
|
||||||
self: Isometry<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>,
|
self: Isometry<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>,
|
||||||
Output = Isometry<T, UnitQuaternion<T>, 3>;
|
Output = Isometry<T, UnitQuaternion<T>, 3>;
|
||||||
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
|
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
|
||||||
[ref val] => Isometry::from_parts(self.translation, self.rotation * rhs);
|
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs);
|
||||||
[val ref] => Isometry::from_parts(self.translation, self.rotation * *rhs);
|
[val ref] => Isometry::from_parts(self.translation, self.rotation * rhs.clone());
|
||||||
[ref ref] => Isometry::from_parts(self.translation, self.rotation * *rhs);
|
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs.clone());
|
||||||
);
|
);
|
||||||
|
|
||||||
// UnitQuaternion × Isometry
|
// UnitQuaternion × Isometry
|
||||||
|
@ -471,9 +471,9 @@ isometry_from_composition_impl_all!(
|
||||||
self: Isometry<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>,
|
self: Isometry<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>,
|
||||||
Output = Isometry<T, UnitQuaternion<T>, 3>;
|
Output = Isometry<T, UnitQuaternion<T>, 3>;
|
||||||
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
|
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
|
||||||
[ref val] => Isometry::from_parts(self.translation, self.rotation / rhs);
|
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs);
|
||||||
[val ref] => Isometry::from_parts(self.translation, self.rotation / *rhs);
|
[val ref] => Isometry::from_parts(self.translation, self.rotation / rhs.clone());
|
||||||
[ref ref] => Isometry::from_parts(self.translation, self.rotation / *rhs);
|
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs.clone());
|
||||||
);
|
);
|
||||||
|
|
||||||
// UnitQuaternion ÷ Isometry
|
// UnitQuaternion ÷ Isometry
|
||||||
|
@ -495,9 +495,9 @@ isometry_from_composition_impl_all!(
|
||||||
D;
|
D;
|
||||||
self: Translation<T, D>, right: Rotation<T, D>, Output = Isometry<T, Rotation<T, D>, D>;
|
self: Translation<T, D>, right: Rotation<T, D>, Output = Isometry<T, Rotation<T, D>, D>;
|
||||||
[val val] => Isometry::from_parts(self, right);
|
[val val] => Isometry::from_parts(self, right);
|
||||||
[ref val] => Isometry::from_parts(*self, right);
|
[ref val] => Isometry::from_parts(self.clone(), right);
|
||||||
[val ref] => Isometry::from_parts(self, *right);
|
[val ref] => Isometry::from_parts(self, right.clone());
|
||||||
[ref ref] => Isometry::from_parts(*self, *right);
|
[ref ref] => Isometry::from_parts(self.clone(), right.clone());
|
||||||
);
|
);
|
||||||
|
|
||||||
// Translation × UnitQuaternion
|
// Translation × UnitQuaternion
|
||||||
|
@ -506,9 +506,9 @@ isometry_from_composition_impl_all!(
|
||||||
;
|
;
|
||||||
self: Translation<T, 3>, right: UnitQuaternion<T>, Output = Isometry<T, UnitQuaternion<T>, 3>;
|
self: Translation<T, 3>, right: UnitQuaternion<T>, Output = Isometry<T, UnitQuaternion<T>, 3>;
|
||||||
[val val] => Isometry::from_parts(self, right);
|
[val val] => Isometry::from_parts(self, right);
|
||||||
[ref val] => Isometry::from_parts(*self, right);
|
[ref val] => Isometry::from_parts(self.clone(), right);
|
||||||
[val ref] => Isometry::from_parts(self, *right);
|
[val ref] => Isometry::from_parts(self, right.clone());
|
||||||
[ref ref] => Isometry::from_parts(*self, *right);
|
[ref ref] => Isometry::from_parts(self.clone(), right.clone());
|
||||||
);
|
);
|
||||||
|
|
||||||
// Isometry × UnitComplex
|
// Isometry × UnitComplex
|
||||||
|
@ -518,9 +518,9 @@ isometry_from_composition_impl_all!(
|
||||||
self: Isometry<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>,
|
self: Isometry<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>,
|
||||||
Output = Isometry<T, UnitComplex<T>, 2>;
|
Output = Isometry<T, UnitComplex<T>, 2>;
|
||||||
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
|
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
|
||||||
[ref val] => Isometry::from_parts(self.translation, self.rotation * rhs);
|
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs);
|
||||||
[val ref] => Isometry::from_parts(self.translation, self.rotation * *rhs);
|
[val ref] => Isometry::from_parts(self.translation, self.rotation * rhs.clone());
|
||||||
[ref ref] => Isometry::from_parts(self.translation, self.rotation * *rhs);
|
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs.clone());
|
||||||
);
|
);
|
||||||
|
|
||||||
// Isometry ÷ UnitComplex
|
// Isometry ÷ UnitComplex
|
||||||
|
@ -530,7 +530,7 @@ isometry_from_composition_impl_all!(
|
||||||
self: Isometry<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>,
|
self: Isometry<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>,
|
||||||
Output = Isometry<T, UnitComplex<T>, 2>;
|
Output = Isometry<T, UnitComplex<T>, 2>;
|
||||||
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
|
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
|
||||||
[ref val] => Isometry::from_parts(self.translation, self.rotation / rhs);
|
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs);
|
||||||
[val ref] => Isometry::from_parts(self.translation, self.rotation / *rhs);
|
[val ref] => Isometry::from_parts(self.translation, self.rotation / rhs.clone());
|
||||||
[ref ref] => Isometry::from_parts(self.translation, self.rotation / *rhs);
|
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs.clone());
|
||||||
);
|
);
|
||||||
|
|
|
@ -23,12 +23,12 @@ pub struct Orthographic3<T> {
|
||||||
matrix: Matrix4<T>,
|
matrix: Matrix4<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RealField> Copy for Orthographic3<T> {}
|
impl<T: RealField + Copy> Copy for Orthographic3<T> {}
|
||||||
|
|
||||||
impl<T: RealField> Clone for Orthographic3<T> {
|
impl<T: RealField> Clone for Orthographic3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self::from_matrix_unchecked(self.matrix)
|
Self::from_matrix_unchecked(self.matrix.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,13 +175,13 @@ impl<T: RealField> Orthographic3<T> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let half: T = crate::convert(0.5);
|
let half: T = crate::convert(0.5);
|
||||||
let width = zfar * (vfov * half).tan();
|
let width = zfar.clone() * (vfov.clone() * half.clone()).tan();
|
||||||
let height = width / aspect;
|
let height = width.clone() / aspect;
|
||||||
|
|
||||||
Self::new(
|
Self::new(
|
||||||
-width * half,
|
-width.clone() * half.clone(),
|
||||||
width * half,
|
width * half.clone(),
|
||||||
-height * half,
|
-height.clone() * half.clone(),
|
||||||
height * half,
|
height * half,
|
||||||
znear,
|
znear,
|
||||||
zfar,
|
zfar,
|
||||||
|
@ -208,19 +208,19 @@ impl<T: RealField> Orthographic3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn inverse(&self) -> Matrix4<T> {
|
pub fn inverse(&self) -> Matrix4<T> {
|
||||||
let mut res = self.to_homogeneous();
|
let mut res = self.clone().to_homogeneous();
|
||||||
|
|
||||||
let inv_m11 = T::one() / self.matrix[(0, 0)];
|
let inv_m11 = T::one() / self.matrix[(0, 0)].clone();
|
||||||
let inv_m22 = T::one() / self.matrix[(1, 1)];
|
let inv_m22 = T::one() / self.matrix[(1, 1)].clone();
|
||||||
let inv_m33 = T::one() / self.matrix[(2, 2)];
|
let inv_m33 = T::one() / self.matrix[(2, 2)].clone();
|
||||||
|
|
||||||
res[(0, 0)] = inv_m11;
|
res[(0, 0)] = inv_m11.clone();
|
||||||
res[(1, 1)] = inv_m22;
|
res[(1, 1)] = inv_m22.clone();
|
||||||
res[(2, 2)] = inv_m33;
|
res[(2, 2)] = inv_m33.clone();
|
||||||
|
|
||||||
res[(0, 3)] = -self.matrix[(0, 3)] * inv_m11;
|
res[(0, 3)] = -self.matrix[(0, 3)].clone() * inv_m11;
|
||||||
res[(1, 3)] = -self.matrix[(1, 3)] * inv_m22;
|
res[(1, 3)] = -self.matrix[(1, 3)].clone() * inv_m22;
|
||||||
res[(2, 3)] = -self.matrix[(2, 3)] * inv_m33;
|
res[(2, 3)] = -self.matrix[(2, 3)].clone() * inv_m33;
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
@ -335,7 +335,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn left(&self) -> T {
|
pub fn left(&self) -> T {
|
||||||
(-T::one() - self.matrix[(0, 3)]) / self.matrix[(0, 0)]
|
(-T::one() - self.matrix[(0, 3)].clone()) / self.matrix[(0, 0)].clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The right offset of the view cuboid.
|
/// The right offset of the view cuboid.
|
||||||
|
@ -352,7 +352,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn right(&self) -> T {
|
pub fn right(&self) -> T {
|
||||||
(T::one() - self.matrix[(0, 3)]) / self.matrix[(0, 0)]
|
(T::one() - self.matrix[(0, 3)].clone()) / self.matrix[(0, 0)].clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The bottom offset of the view cuboid.
|
/// The bottom offset of the view cuboid.
|
||||||
|
@ -369,7 +369,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn bottom(&self) -> T {
|
pub fn bottom(&self) -> T {
|
||||||
(-T::one() - self.matrix[(1, 3)]) / self.matrix[(1, 1)]
|
(-T::one() - self.matrix[(1, 3)].clone()) / self.matrix[(1, 1)].clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The top offset of the view cuboid.
|
/// The top offset of the view cuboid.
|
||||||
|
@ -386,7 +386,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn top(&self) -> T {
|
pub fn top(&self) -> T {
|
||||||
(T::one() - self.matrix[(1, 3)]) / self.matrix[(1, 1)]
|
(T::one() - self.matrix[(1, 3)].clone()) / self.matrix[(1, 1)].clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The near plane offset of the view cuboid.
|
/// The near plane offset of the view cuboid.
|
||||||
|
@ -403,7 +403,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn znear(&self) -> T {
|
pub fn znear(&self) -> T {
|
||||||
(T::one() + self.matrix[(2, 3)]) / self.matrix[(2, 2)]
|
(T::one() + self.matrix[(2, 3)].clone()) / self.matrix[(2, 2)].clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The far plane offset of the view cuboid.
|
/// The far plane offset of the view cuboid.
|
||||||
|
@ -420,7 +420,7 @@ impl<T: RealField> Orthographic3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn zfar(&self) -> T {
|
pub fn zfar(&self) -> T {
|
||||||
(-T::one() + self.matrix[(2, 3)]) / self.matrix[(2, 2)]
|
(-T::one() + self.matrix[(2, 3)].clone()) / self.matrix[(2, 2)].clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: when we get specialization, specialize the Mul impl instead.
|
// TODO: when we get specialization, specialize the Mul impl instead.
|
||||||
|
@ -454,9 +454,9 @@ impl<T: RealField> Orthographic3<T> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn project_point(&self, p: &Point3<T>) -> Point3<T> {
|
pub fn project_point(&self, p: &Point3<T>) -> Point3<T> {
|
||||||
Point3::new(
|
Point3::new(
|
||||||
self.matrix[(0, 0)] * p[0] + self.matrix[(0, 3)],
|
self.matrix[(0, 0)].clone() * p[0].clone() + self.matrix[(0, 3)].clone(),
|
||||||
self.matrix[(1, 1)] * p[1] + self.matrix[(1, 3)],
|
self.matrix[(1, 1)].clone() * p[1].clone() + self.matrix[(1, 3)].clone(),
|
||||||
self.matrix[(2, 2)] * p[2] + self.matrix[(2, 3)],
|
self.matrix[(2, 2)].clone() * p[2].clone() + self.matrix[(2, 3)].clone(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,9 +490,9 @@ impl<T: RealField> Orthographic3<T> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn unproject_point(&self, p: &Point3<T>) -> Point3<T> {
|
pub fn unproject_point(&self, p: &Point3<T>) -> Point3<T> {
|
||||||
Point3::new(
|
Point3::new(
|
||||||
(p[0] - self.matrix[(0, 3)]) / self.matrix[(0, 0)],
|
(p[0].clone() - self.matrix[(0, 3)].clone()) / self.matrix[(0, 0)].clone(),
|
||||||
(p[1] - self.matrix[(1, 3)]) / self.matrix[(1, 1)],
|
(p[1].clone() - self.matrix[(1, 3)].clone()) / self.matrix[(1, 1)].clone(),
|
||||||
(p[2] - self.matrix[(2, 3)]) / self.matrix[(2, 2)],
|
(p[2].clone() - self.matrix[(2, 3)].clone()) / self.matrix[(2, 2)].clone(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,9 +522,9 @@ impl<T: RealField> Orthographic3<T> {
|
||||||
SB: Storage<T, U3>,
|
SB: Storage<T, U3>,
|
||||||
{
|
{
|
||||||
Vector3::new(
|
Vector3::new(
|
||||||
self.matrix[(0, 0)] * p[0],
|
self.matrix[(0, 0)].clone() * p[0].clone(),
|
||||||
self.matrix[(1, 1)] * p[1],
|
self.matrix[(1, 1)].clone() * p[1].clone(),
|
||||||
self.matrix[(2, 2)] * p[2],
|
self.matrix[(2, 2)].clone() * p[2].clone(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,8 +663,8 @@ impl<T: RealField> Orthographic3<T> {
|
||||||
left != right,
|
left != right,
|
||||||
"The left corner must not be equal to the right corner."
|
"The left corner must not be equal to the right corner."
|
||||||
);
|
);
|
||||||
self.matrix[(0, 0)] = crate::convert::<_, T>(2.0) / (right - left);
|
self.matrix[(0, 0)] = crate::convert::<_, T>(2.0) / (right.clone() - left.clone());
|
||||||
self.matrix[(0, 3)] = -(right + left) / (right - left);
|
self.matrix[(0, 3)] = -(right.clone() + left.clone()) / (right - left);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the view cuboid offsets along the `y` axis.
|
/// Sets the view cuboid offsets along the `y` axis.
|
||||||
|
@ -684,12 +684,12 @@ impl<T: RealField> Orthographic3<T> {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_bottom_and_top(&mut self, bottom: T, top: T) {
|
pub fn set_bottom_and_top(&mut self, bottom: T, top: T) {
|
||||||
assert!(
|
assert_ne!(
|
||||||
bottom != top,
|
bottom, top,
|
||||||
"The top corner must not be equal to the bottom corner."
|
"The top corner must not be equal to the bottom corner."
|
||||||
);
|
);
|
||||||
self.matrix[(1, 1)] = crate::convert::<_, T>(2.0) / (top - bottom);
|
self.matrix[(1, 1)] = crate::convert::<_, T>(2.0) / (top.clone() - bottom.clone());
|
||||||
self.matrix[(1, 3)] = -(top + bottom) / (top - bottom);
|
self.matrix[(1, 3)] = -(top.clone() + bottom.clone()) / (top - bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the near and far plane offsets of the view cuboid.
|
/// Sets the near and far plane offsets of the view cuboid.
|
||||||
|
@ -713,8 +713,8 @@ impl<T: RealField> Orthographic3<T> {
|
||||||
zfar != znear,
|
zfar != znear,
|
||||||
"The near-plane and far-plane must not be superimposed."
|
"The near-plane and far-plane must not be superimposed."
|
||||||
);
|
);
|
||||||
self.matrix[(2, 2)] = -crate::convert::<_, T>(2.0) / (zfar - znear);
|
self.matrix[(2, 2)] = -crate::convert::<_, T>(2.0) / (zfar.clone() - znear.clone());
|
||||||
self.matrix[(2, 3)] = -(zfar + znear) / (zfar - znear);
|
self.matrix[(2, 3)] = -(zfar.clone() + znear.clone()) / (zfar - znear);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,12 +24,12 @@ pub struct Perspective3<T> {
|
||||||
matrix: Matrix4<T>,
|
matrix: Matrix4<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RealField> Copy for Perspective3<T> {}
|
impl<T: RealField + Copy> Copy for Perspective3<T> {}
|
||||||
|
|
||||||
impl<T: RealField> Clone for Perspective3<T> {
|
impl<T: RealField> Clone for Perspective3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self::from_matrix_unchecked(self.matrix)
|
Self::from_matrix_unchecked(self.matrix.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ impl<T: RealField> Perspective3<T> {
|
||||||
/// Creates a new perspective matrix from the aspect ratio, y field of view, and near/far planes.
|
/// Creates a new perspective matrix from the aspect ratio, y field of view, and near/far planes.
|
||||||
pub fn new(aspect: T, fovy: T, znear: T, zfar: T) -> Self {
|
pub fn new(aspect: T, fovy: T, znear: T, zfar: T) -> Self {
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(zfar - znear, T::zero()),
|
relative_ne!(zfar, znear),
|
||||||
"The near-plane and far-plane must not be superimposed."
|
"The near-plane and far-plane must not be superimposed."
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
|
@ -124,18 +124,18 @@ impl<T: RealField> Perspective3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn inverse(&self) -> Matrix4<T> {
|
pub fn inverse(&self) -> Matrix4<T> {
|
||||||
let mut res = self.to_homogeneous();
|
let mut res = self.clone().to_homogeneous();
|
||||||
|
|
||||||
res[(0, 0)] = T::one() / self.matrix[(0, 0)];
|
res[(0, 0)] = T::one() / self.matrix[(0, 0)].clone();
|
||||||
res[(1, 1)] = T::one() / self.matrix[(1, 1)];
|
res[(1, 1)] = T::one() / self.matrix[(1, 1)].clone();
|
||||||
res[(2, 2)] = T::zero();
|
res[(2, 2)] = T::zero();
|
||||||
|
|
||||||
let m23 = self.matrix[(2, 3)];
|
let m23 = self.matrix[(2, 3)].clone();
|
||||||
let m32 = self.matrix[(3, 2)];
|
let m32 = self.matrix[(3, 2)].clone();
|
||||||
|
|
||||||
res[(2, 3)] = T::one() / m32;
|
res[(2, 3)] = T::one() / m32.clone();
|
||||||
res[(3, 2)] = T::one() / m23;
|
res[(3, 2)] = T::one() / m23.clone();
|
||||||
res[(3, 3)] = -self.matrix[(2, 2)] / (m23 * m32);
|
res[(3, 3)] = -self.matrix[(2, 2)].clone() / (m23 * m32);
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
@ -186,33 +186,35 @@ impl<T: RealField> Perspective3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn aspect(&self) -> T {
|
pub fn aspect(&self) -> T {
|
||||||
self.matrix[(1, 1)] / self.matrix[(0, 0)]
|
self.matrix[(1, 1)].clone() / self.matrix[(0, 0)].clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the y field of view of the view frustum.
|
/// Gets the y field of view of the view frustum.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn fovy(&self) -> T {
|
pub fn fovy(&self) -> T {
|
||||||
(T::one() / self.matrix[(1, 1)]).atan() * crate::convert(2.0)
|
(T::one() / self.matrix[(1, 1)].clone()).atan() * crate::convert(2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the near plane offset of the view frustum.
|
/// Gets the near plane offset of the view frustum.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn znear(&self) -> T {
|
pub fn znear(&self) -> T {
|
||||||
let ratio = (-self.matrix[(2, 2)] + T::one()) / (-self.matrix[(2, 2)] - T::one());
|
let ratio =
|
||||||
|
(-self.matrix[(2, 2)].clone() + T::one()) / (-self.matrix[(2, 2)].clone() - T::one());
|
||||||
|
|
||||||
self.matrix[(2, 3)] / (ratio * crate::convert(2.0))
|
self.matrix[(2, 3)].clone() / (ratio * crate::convert(2.0))
|
||||||
- self.matrix[(2, 3)] / crate::convert(2.0)
|
- self.matrix[(2, 3)].clone() / crate::convert(2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the far plane offset of the view frustum.
|
/// Gets the far plane offset of the view frustum.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn zfar(&self) -> T {
|
pub fn zfar(&self) -> T {
|
||||||
let ratio = (-self.matrix[(2, 2)] + T::one()) / (-self.matrix[(2, 2)] - T::one());
|
let ratio =
|
||||||
|
(-self.matrix[(2, 2)].clone() + T::one()) / (-self.matrix[(2, 2)].clone() - T::one());
|
||||||
|
|
||||||
(self.matrix[(2, 3)] - ratio * self.matrix[(2, 3)]) / crate::convert(2.0)
|
(self.matrix[(2, 3)].clone() - ratio * self.matrix[(2, 3)].clone()) / crate::convert(2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add a method to retrieve znear and zfar simultaneously?
|
// TODO: add a method to retrieve znear and zfar simultaneously?
|
||||||
|
@ -222,11 +224,12 @@ impl<T: RealField> Perspective3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn project_point(&self, p: &Point3<T>) -> Point3<T> {
|
pub fn project_point(&self, p: &Point3<T>) -> Point3<T> {
|
||||||
let inverse_denom = -T::one() / p[2];
|
let inverse_denom = -T::one() / p[2].clone();
|
||||||
Point3::new(
|
Point3::new(
|
||||||
self.matrix[(0, 0)] * p[0] * inverse_denom,
|
self.matrix[(0, 0)].clone() * p[0].clone() * inverse_denom.clone(),
|
||||||
self.matrix[(1, 1)] * p[1] * inverse_denom,
|
self.matrix[(1, 1)].clone() * p[1].clone() * inverse_denom.clone(),
|
||||||
(self.matrix[(2, 2)] * p[2] + self.matrix[(2, 3)]) * inverse_denom,
|
(self.matrix[(2, 2)].clone() * p[2].clone() + self.matrix[(2, 3)].clone())
|
||||||
|
* inverse_denom,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,11 +237,12 @@ impl<T: RealField> Perspective3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn unproject_point(&self, p: &Point3<T>) -> Point3<T> {
|
pub fn unproject_point(&self, p: &Point3<T>) -> Point3<T> {
|
||||||
let inverse_denom = self.matrix[(2, 3)] / (p[2] + self.matrix[(2, 2)]);
|
let inverse_denom =
|
||||||
|
self.matrix[(2, 3)].clone() / (p[2].clone() + self.matrix[(2, 2)].clone());
|
||||||
|
|
||||||
Point3::new(
|
Point3::new(
|
||||||
p[0] * inverse_denom / self.matrix[(0, 0)],
|
p[0].clone() * inverse_denom.clone() / self.matrix[(0, 0)].clone(),
|
||||||
p[1] * inverse_denom / self.matrix[(1, 1)],
|
p[1].clone() * inverse_denom.clone() / self.matrix[(1, 1)].clone(),
|
||||||
-inverse_denom,
|
-inverse_denom,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -251,11 +255,11 @@ impl<T: RealField> Perspective3<T> {
|
||||||
where
|
where
|
||||||
SB: Storage<T, U3>,
|
SB: Storage<T, U3>,
|
||||||
{
|
{
|
||||||
let inverse_denom = -T::one() / p[2];
|
let inverse_denom = -T::one() / p[2].clone();
|
||||||
Vector3::new(
|
Vector3::new(
|
||||||
self.matrix[(0, 0)] * p[0] * inverse_denom,
|
self.matrix[(0, 0)].clone() * p[0].clone() * inverse_denom.clone(),
|
||||||
self.matrix[(1, 1)] * p[1] * inverse_denom,
|
self.matrix[(1, 1)].clone() * p[1].clone() * inverse_denom,
|
||||||
self.matrix[(2, 2)],
|
self.matrix[(2, 2)].clone(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,15 +271,15 @@ impl<T: RealField> Perspective3<T> {
|
||||||
!relative_eq!(aspect, T::zero()),
|
!relative_eq!(aspect, T::zero()),
|
||||||
"The aspect ratio must not be zero."
|
"The aspect ratio must not be zero."
|
||||||
);
|
);
|
||||||
self.matrix[(0, 0)] = self.matrix[(1, 1)] / aspect;
|
self.matrix[(0, 0)] = self.matrix[(1, 1)].clone() / aspect;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates this perspective with a new y field of view of the view frustum.
|
/// Updates this perspective with a new y field of view of the view frustum.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_fovy(&mut self, fovy: T) {
|
pub fn set_fovy(&mut self, fovy: T) {
|
||||||
let old_m22 = self.matrix[(1, 1)];
|
let old_m22 = self.matrix[(1, 1)].clone();
|
||||||
let new_m22 = T::one() / (fovy / crate::convert(2.0)).tan();
|
let new_m22 = T::one() / (fovy / crate::convert(2.0)).tan();
|
||||||
self.matrix[(1, 1)] = new_m22;
|
self.matrix[(1, 1)] = new_m22.clone();
|
||||||
self.matrix[(0, 0)] *= new_m22 / old_m22;
|
self.matrix[(0, 0)] *= new_m22 / old_m22;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,8 +300,8 @@ impl<T: RealField> Perspective3<T> {
|
||||||
/// Updates this perspective matrix with new near and far plane offsets of the view frustum.
|
/// Updates this perspective matrix with new near and far plane offsets of the view frustum.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_znear_and_zfar(&mut self, znear: T, zfar: T) {
|
pub fn set_znear_and_zfar(&mut self, znear: T, zfar: T) {
|
||||||
self.matrix[(2, 2)] = (zfar + znear) / (znear - zfar);
|
self.matrix[(2, 2)] = (zfar.clone() + znear.clone()) / (znear.clone() - zfar.clone());
|
||||||
self.matrix[(2, 3)] = zfar * znear * crate::convert(2.0) / (znear - zfar);
|
self.matrix[(2, 3)] = zfar.clone() * znear.clone() * crate::convert(2.0) / (znear - zfar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,8 +314,8 @@ where
|
||||||
fn sample<R: Rng + ?Sized>(&self, r: &mut R) -> Perspective3<T> {
|
fn sample<R: Rng + ?Sized>(&self, r: &mut R) -> Perspective3<T> {
|
||||||
use crate::base::helper;
|
use crate::base::helper;
|
||||||
let znear = r.gen();
|
let znear = r.gen();
|
||||||
let zfar = helper::reject_rand(r, |&x: &T| !(x - znear).is_zero());
|
let zfar = helper::reject_rand(r, |x: &T| !(x.clone() - znear.clone()).is_zero());
|
||||||
let aspect = helper::reject_rand(r, |&x: &T| !x.is_zero());
|
let aspect = helper::reject_rand(r, |x: &T| !x.is_zero());
|
||||||
|
|
||||||
Perspective3::new(aspect, r.gen(), znear, zfar)
|
Perspective3::new(aspect, r.gen(), znear, zfar)
|
||||||
}
|
}
|
||||||
|
@ -321,9 +325,9 @@ where
|
||||||
impl<T: RealField + Arbitrary> Arbitrary for Perspective3<T> {
|
impl<T: RealField + Arbitrary> Arbitrary for Perspective3<T> {
|
||||||
fn arbitrary(g: &mut Gen) -> Self {
|
fn arbitrary(g: &mut Gen) -> Self {
|
||||||
use crate::base::helper;
|
use crate::base::helper;
|
||||||
let znear = Arbitrary::arbitrary(g);
|
let znear: T = Arbitrary::arbitrary(g);
|
||||||
let zfar = helper::reject(g, |&x: &T| !(x - znear).is_zero());
|
let zfar = helper::reject(g, |x: &T| !(x.clone() - znear.clone()).is_zero());
|
||||||
let aspect = helper::reject(g, |&x: &T| !x.is_zero());
|
let aspect = helper::reject(g, |x: &T| !x.is_zero());
|
||||||
|
|
||||||
Self::new(aspect, Arbitrary::arbitrary(g), znear, zfar)
|
Self::new(aspect, Arbitrary::arbitrary(g), znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,7 +323,7 @@ where
|
||||||
|
|
||||||
impl<T: Scalar + AbsDiffEq, D: DimName> AbsDiffEq for OPoint<T, D>
|
impl<T: Scalar + AbsDiffEq, D: DimName> AbsDiffEq for OPoint<T, D>
|
||||||
where
|
where
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
DefaultAllocator: Allocator<T, D>,
|
DefaultAllocator: Allocator<T, D>,
|
||||||
{
|
{
|
||||||
type Epsilon = T::Epsilon;
|
type Epsilon = T::Epsilon;
|
||||||
|
@ -341,7 +341,7 @@ where
|
||||||
|
|
||||||
impl<T: Scalar + RelativeEq, D: DimName> RelativeEq for OPoint<T, D>
|
impl<T: Scalar + RelativeEq, D: DimName> RelativeEq for OPoint<T, D>
|
||||||
where
|
where
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
DefaultAllocator: Allocator<T, D>,
|
DefaultAllocator: Allocator<T, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -363,7 +363,7 @@ where
|
||||||
|
|
||||||
impl<T: Scalar + UlpsEq, D: DimName> UlpsEq for OPoint<T, D>
|
impl<T: Scalar + UlpsEq, D: DimName> UlpsEq for OPoint<T, D>
|
||||||
where
|
where
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
DefaultAllocator: Allocator<T, D>,
|
DefaultAllocator: Allocator<T, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -104,8 +104,7 @@ where
|
||||||
DefaultAllocator: Allocator<T, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<T, DimNameSum<D, U1>>,
|
||||||
{
|
{
|
||||||
if !v[D::dim()].is_zero() {
|
if !v[D::dim()].is_zero() {
|
||||||
let coords =
|
let coords = v.generic_slice((0, 0), (D::name(), Const::<1>)) / v[D::dim()].clone();
|
||||||
v.generic_slice((0, 0), (D::name(), Const::<1>)) / v[D::dim()].inlined_clone();
|
|
||||||
Some(Self::from(coords))
|
Some(Self::from(coords))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -66,7 +66,7 @@ where
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(v: &OVector<T2, DimNameSum<D, U1>>) -> Self {
|
fn from_superset_unchecked(v: &OVector<T2, DimNameSum<D, U1>>) -> Self {
|
||||||
let coords = v.generic_slice((0, 0), (D::name(), Const::<1>)) / v[D::dim()].inlined_clone();
|
let coords = v.generic_slice((0, 0), (D::name(), Const::<1>)) / v[D::dim()].clone();
|
||||||
Self {
|
Self {
|
||||||
coords: crate::convert_unchecked(coords),
|
coords: crate::convert_unchecked(coords),
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,7 +208,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use = "Did you mean to use conjugate_mut()?"]
|
#[must_use = "Did you mean to use conjugate_mut()?"]
|
||||||
pub fn conjugate(&self) -> Self {
|
pub fn conjugate(&self) -> Self {
|
||||||
Self::from_parts(self.w, -self.imag())
|
Self::from_parts(self.w.clone(), -self.imag())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Linear interpolation between two quaternion.
|
/// Linear interpolation between two quaternion.
|
||||||
|
@ -226,7 +226,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn lerp(&self, other: &Self, t: T) -> Self {
|
pub fn lerp(&self, other: &Self, t: T) -> Self {
|
||||||
self * (T::one() - t) + other * t
|
self * (T::one() - t.clone()) + other * t
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The vector part `(i, j, k)` of this quaternion.
|
/// The vector part `(i, j, k)` of this quaternion.
|
||||||
|
@ -256,7 +256,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn scalar(&self) -> T {
|
pub fn scalar(&self) -> T {
|
||||||
self.coords[3]
|
self.coords[3].clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reinterprets this quaternion as a 4D vector.
|
/// Reinterprets this quaternion as a 4D vector.
|
||||||
|
@ -385,7 +385,7 @@ where
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let mut res = *self;
|
let mut res = self.clone();
|
||||||
|
|
||||||
if res.try_inverse_mut() {
|
if res.try_inverse_mut() {
|
||||||
Some(res)
|
Some(res)
|
||||||
|
@ -401,7 +401,7 @@ where
|
||||||
#[must_use = "Did you mean to use try_inverse_mut()?"]
|
#[must_use = "Did you mean to use try_inverse_mut()?"]
|
||||||
pub fn simd_try_inverse(&self) -> SimdOption<Self> {
|
pub fn simd_try_inverse(&self) -> SimdOption<Self> {
|
||||||
let norm_squared = self.norm_squared();
|
let norm_squared = self.norm_squared();
|
||||||
let ge = norm_squared.simd_ge(T::simd_default_epsilon());
|
let ge = norm_squared.clone().simd_ge(T::simd_default_epsilon());
|
||||||
SimdOption::new(self.conjugate() / norm_squared, ge)
|
SimdOption::new(self.conjugate() / norm_squared, ge)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,7 +511,7 @@ where
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
if let Some((q, n)) = Unit::try_new_and_get(*self, T::zero()) {
|
if let Some((q, n)) = Unit::try_new_and_get(self.clone(), T::zero()) {
|
||||||
if let Some(axis) = Unit::try_new(self.vector().clone_owned(), T::zero()) {
|
if let Some(axis) = Unit::try_new(self.vector().clone_owned(), T::zero()) {
|
||||||
let angle = q.angle() / crate::convert(2.0f64);
|
let angle = q.angle() / crate::convert(2.0f64);
|
||||||
|
|
||||||
|
@ -540,7 +540,7 @@ where
|
||||||
let v = self.vector();
|
let v = self.vector();
|
||||||
let s = self.scalar();
|
let s = self.scalar();
|
||||||
|
|
||||||
Self::from_parts(n.simd_ln(), v.normalize() * (s / n).simd_acos())
|
Self::from_parts(n.clone().simd_ln(), v.normalize() * (s / n).simd_acos())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the exponential of a quaternion.
|
/// Compute the exponential of a quaternion.
|
||||||
|
@ -577,11 +577,11 @@ where
|
||||||
pub fn exp_eps(&self, eps: T) -> Self {
|
pub fn exp_eps(&self, eps: T) -> Self {
|
||||||
let v = self.vector();
|
let v = self.vector();
|
||||||
let nn = v.norm_squared();
|
let nn = v.norm_squared();
|
||||||
let le = nn.simd_le(eps * eps);
|
let le = nn.clone().simd_le(eps.clone() * eps);
|
||||||
le.if_else(Self::identity, || {
|
le.if_else(Self::identity, || {
|
||||||
let w_exp = self.scalar().simd_exp();
|
let w_exp = self.scalar().simd_exp();
|
||||||
let n = nn.simd_sqrt();
|
let n = nn.simd_sqrt();
|
||||||
let nv = v * (w_exp * n.simd_sin() / n);
|
let nv = v * (w_exp.clone() * n.clone().simd_sin() / n.clone());
|
||||||
|
|
||||||
Self::from_parts(w_exp * n.simd_cos(), nv)
|
Self::from_parts(w_exp * n.simd_cos(), nv)
|
||||||
})
|
})
|
||||||
|
@ -648,9 +648,9 @@ where
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn conjugate_mut(&mut self) {
|
pub fn conjugate_mut(&mut self) {
|
||||||
self.coords[0] = -self.coords[0];
|
self.coords[0] = -self.coords[0].clone();
|
||||||
self.coords[1] = -self.coords[1];
|
self.coords[1] = -self.coords[1].clone();
|
||||||
self.coords[2] = -self.coords[2];
|
self.coords[2] = -self.coords[2].clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inverts this quaternion in-place if it is not zero.
|
/// Inverts this quaternion in-place if it is not zero.
|
||||||
|
@ -671,8 +671,8 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn try_inverse_mut(&mut self) -> T::SimdBool {
|
pub fn try_inverse_mut(&mut self) -> T::SimdBool {
|
||||||
let norm_squared = self.norm_squared();
|
let norm_squared = self.norm_squared();
|
||||||
let ge = norm_squared.simd_ge(T::simd_default_epsilon());
|
let ge = norm_squared.clone().simd_ge(T::simd_default_epsilon());
|
||||||
*self = ge.if_else(|| self.conjugate() / norm_squared, || *self);
|
*self = ge.if_else(|| self.conjugate() / norm_squared, || self.clone());
|
||||||
ge
|
ge
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -778,8 +778,8 @@ where
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn cos(&self) -> Self {
|
pub fn cos(&self) -> Self {
|
||||||
let z = self.imag().magnitude();
|
let z = self.imag().magnitude();
|
||||||
let w = -self.w.simd_sin() * z.simd_sinhc();
|
let w = -self.w.clone().simd_sin() * z.clone().simd_sinhc();
|
||||||
Self::from_parts(self.w.simd_cos() * z.simd_cosh(), self.imag() * w)
|
Self::from_parts(self.w.clone().simd_cos() * z.simd_cosh(), self.imag() * w)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates the quaternionic arccosinus.
|
/// Calculates the quaternionic arccosinus.
|
||||||
|
@ -818,8 +818,8 @@ where
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn sin(&self) -> Self {
|
pub fn sin(&self) -> Self {
|
||||||
let z = self.imag().magnitude();
|
let z = self.imag().magnitude();
|
||||||
let w = self.w.simd_cos() * z.simd_sinhc();
|
let w = self.w.clone().simd_cos() * z.clone().simd_sinhc();
|
||||||
Self::from_parts(self.w.simd_sin() * z.simd_cosh(), self.imag() * w)
|
Self::from_parts(self.w.clone().simd_sin() * z.simd_cosh(), self.imag() * w)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates the quaternionic arcsinus.
|
/// Calculates the quaternionic arcsinus.
|
||||||
|
@ -838,7 +838,7 @@ where
|
||||||
let u = Self::from_imag(self.imag().normalize());
|
let u = Self::from_imag(self.imag().normalize());
|
||||||
let identity = Self::identity();
|
let identity = Self::identity();
|
||||||
|
|
||||||
let z = ((u * self) + (identity - self.squared()).sqrt()).ln();
|
let z = ((u.clone() * self) + (identity - self.squared()).sqrt()).ln();
|
||||||
|
|
||||||
-(u * z)
|
-(u * z)
|
||||||
}
|
}
|
||||||
|
@ -880,8 +880,8 @@ where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let u = Self::from_imag(self.imag().normalize());
|
let u = Self::from_imag(self.imag().normalize());
|
||||||
let num = u + self;
|
let num = u.clone() + self;
|
||||||
let den = u - self;
|
let den = u.clone() - self;
|
||||||
let fr = num.right_div(&den).unwrap();
|
let fr = num.right_div(&den).unwrap();
|
||||||
let ln = fr.ln();
|
let ln = fr.ln();
|
||||||
(u.half()) * ln
|
(u.half()) * ln
|
||||||
|
@ -954,7 +954,7 @@ where
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn acosh(&self) -> Self {
|
pub fn acosh(&self) -> Self {
|
||||||
let identity = Self::identity();
|
let identity = Self::identity();
|
||||||
(self + (self + identity).sqrt() * (self - identity).sqrt()).ln()
|
(self + (self + identity.clone()).sqrt() * (self - identity).sqrt()).ln()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates the hyperbolic quaternionic tangent.
|
/// Calculates the hyperbolic quaternionic tangent.
|
||||||
|
@ -992,7 +992,7 @@ where
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn atanh(&self) -> Self {
|
pub fn atanh(&self) -> Self {
|
||||||
let identity = Self::identity();
|
let identity = Self::identity();
|
||||||
((identity + self).ln() - (identity - self).ln()).half()
|
((identity.clone() + self).ln() - (identity - self).ln()).half()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1006,9 +1006,9 @@ impl<T: RealField + AbsDiffEq<Epsilon = T>> AbsDiffEq for Quaternion<T> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
|
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
|
||||||
self.as_vector().abs_diff_eq(other.as_vector(), epsilon) ||
|
self.as_vector().abs_diff_eq(other.as_vector(), epsilon.clone()) ||
|
||||||
// Account for the double-covering of S², i.e. q = -q
|
// Account for the double-covering of S², i.e. q = -q
|
||||||
self.as_vector().iter().zip(other.as_vector().iter()).all(|(a, b)| a.abs_diff_eq(&-*b, epsilon))
|
self.as_vector().iter().zip(other.as_vector().iter()).all(|(a, b)| a.abs_diff_eq(&-b.clone(), epsilon.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1025,9 +1025,9 @@ impl<T: RealField + RelativeEq<Epsilon = T>> RelativeEq for Quaternion<T> {
|
||||||
epsilon: Self::Epsilon,
|
epsilon: Self::Epsilon,
|
||||||
max_relative: Self::Epsilon,
|
max_relative: Self::Epsilon,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
self.as_vector().relative_eq(other.as_vector(), epsilon, max_relative) ||
|
self.as_vector().relative_eq(other.as_vector(), epsilon.clone(), max_relative.clone()) ||
|
||||||
// Account for the double-covering of S², i.e. q = -q
|
// Account for the double-covering of S², i.e. q = -q
|
||||||
self.as_vector().iter().zip(other.as_vector().iter()).all(|(a, b)| a.relative_eq(&-*b, epsilon, max_relative))
|
self.as_vector().iter().zip(other.as_vector().iter()).all(|(a, b)| a.relative_eq(&-b.clone(), epsilon.clone(), max_relative.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1039,9 +1039,9 @@ impl<T: RealField + UlpsEq<Epsilon = T>> UlpsEq for Quaternion<T> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
|
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
|
||||||
self.as_vector().ulps_eq(other.as_vector(), epsilon, max_ulps) ||
|
self.as_vector().ulps_eq(other.as_vector(), epsilon.clone(), max_ulps.clone()) ||
|
||||||
// Account for the double-covering of S², i.e. q = -q.
|
// Account for the double-covering of S², i.e. q = -q.
|
||||||
self.as_vector().iter().zip(other.as_vector().iter()).all(|(a, b)| a.ulps_eq(&-*b, epsilon, max_ulps))
|
self.as_vector().iter().zip(other.as_vector().iter()).all(|(a, b)| a.ulps_eq(&-b.clone(), epsilon.clone(), max_ulps.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1063,7 +1063,7 @@ impl<T: Scalar + ClosedNeg + PartialEq> PartialEq for UnitQuaternion<T> {
|
||||||
fn eq(&self, rhs: &Self) -> bool {
|
fn eq(&self, rhs: &Self) -> bool {
|
||||||
self.coords == rhs.coords ||
|
self.coords == rhs.coords ||
|
||||||
// Account for the double-covering of S², i.e. q = -q
|
// Account for the double-covering of S², i.e. q = -q
|
||||||
self.coords.iter().zip(rhs.coords.iter()).all(|(a, b)| *a == -b.inlined_clone())
|
self.coords.iter().zip(rhs.coords.iter()).all(|(a, b)| *a == -b.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1279,14 +1279,14 @@ where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let coords = if self.coords.dot(&other.coords) < T::zero() {
|
let coords = if self.coords.dot(&other.coords) < T::zero() {
|
||||||
Unit::new_unchecked(self.coords).try_slerp(
|
Unit::new_unchecked(self.coords.clone()).try_slerp(
|
||||||
&Unit::new_unchecked(-other.coords),
|
&Unit::new_unchecked(-other.coords.clone()),
|
||||||
t,
|
t,
|
||||||
epsilon,
|
epsilon,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Unit::new_unchecked(self.coords).try_slerp(
|
Unit::new_unchecked(self.coords.clone()).try_slerp(
|
||||||
&Unit::new_unchecked(other.coords),
|
&Unit::new_unchecked(other.coords.clone()),
|
||||||
t,
|
t,
|
||||||
epsilon,
|
epsilon,
|
||||||
)
|
)
|
||||||
|
@ -1479,31 +1479,31 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn to_rotation_matrix(self) -> Rotation<T, 3> {
|
pub fn to_rotation_matrix(self) -> Rotation<T, 3> {
|
||||||
let i = self.as_ref()[0];
|
let i = self.as_ref()[0].clone();
|
||||||
let j = self.as_ref()[1];
|
let j = self.as_ref()[1].clone();
|
||||||
let k = self.as_ref()[2];
|
let k = self.as_ref()[2].clone();
|
||||||
let w = self.as_ref()[3];
|
let w = self.as_ref()[3].clone();
|
||||||
|
|
||||||
let ww = w * w;
|
let ww = w.clone() * w.clone();
|
||||||
let ii = i * i;
|
let ii = i.clone() * i.clone();
|
||||||
let jj = j * j;
|
let jj = j.clone() * j.clone();
|
||||||
let kk = k * k;
|
let kk = k.clone() * k.clone();
|
||||||
let ij = i * j * crate::convert(2.0f64);
|
let ij = i.clone() * j.clone() * crate::convert(2.0f64);
|
||||||
let wk = w * k * crate::convert(2.0f64);
|
let wk = w.clone() * k.clone() * crate::convert(2.0f64);
|
||||||
let wj = w * j * crate::convert(2.0f64);
|
let wj = w.clone() * j.clone() * crate::convert(2.0f64);
|
||||||
let ik = i * k * crate::convert(2.0f64);
|
let ik = i.clone() * k.clone() * crate::convert(2.0f64);
|
||||||
let jk = j * k * crate::convert(2.0f64);
|
let jk = j.clone() * k.clone() * crate::convert(2.0f64);
|
||||||
let wi = w * i * crate::convert(2.0f64);
|
let wi = w.clone() * i.clone() * crate::convert(2.0f64);
|
||||||
|
|
||||||
Rotation::from_matrix_unchecked(Matrix3::new(
|
Rotation::from_matrix_unchecked(Matrix3::new(
|
||||||
ww + ii - jj - kk,
|
ww.clone() + ii.clone() - jj.clone() - kk.clone(),
|
||||||
ij - wk,
|
ij.clone() - wk.clone(),
|
||||||
wj + ik,
|
wj.clone() + ik.clone(),
|
||||||
wk + ij,
|
wk.clone() + ij.clone(),
|
||||||
ww - ii + jj - kk,
|
ww.clone() - ii.clone() + jj.clone() - kk.clone(),
|
||||||
jk - wi,
|
jk.clone() - wi.clone(),
|
||||||
ik - wj,
|
ik.clone() - wj.clone(),
|
||||||
wi + jk,
|
wi.clone() + jk.clone(),
|
||||||
ww - ii - jj + kk,
|
ww - ii - jj + kk,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -1540,7 +1540,7 @@ where
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
self.to_rotation_matrix().euler_angles()
|
self.clone().to_rotation_matrix().euler_angles()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts this unit quaternion into its equivalent homogeneous transformation matrix.
|
/// Converts this unit quaternion into its equivalent homogeneous transformation matrix.
|
||||||
|
@ -1679,9 +1679,9 @@ where
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn append_axisangle_linearized(&self, axisangle: &Vector3<T>) -> Self {
|
pub fn append_axisangle_linearized(&self, axisangle: &Vector3<T>) -> Self {
|
||||||
let half: T = crate::convert(0.5);
|
let half: T = crate::convert(0.5);
|
||||||
let q1 = self.into_inner();
|
let q1 = self.clone().into_inner();
|
||||||
let q2 = Quaternion::from_imag(axisangle * half);
|
let q2 = Quaternion::from_imag(axisangle * half);
|
||||||
Unit::new_normalize(q1 + q2 * q1)
|
Unit::new_normalize(&q1 + q2 * &q1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,12 @@ impl<T: SimdRealField> Quaternion<T> {
|
||||||
where
|
where
|
||||||
SB: Storage<T, U3>,
|
SB: Storage<T, U3>,
|
||||||
{
|
{
|
||||||
Self::new(scalar, vector[0], vector[1], vector[2])
|
Self::new(
|
||||||
|
scalar,
|
||||||
|
vector[0].clone(),
|
||||||
|
vector[1].clone(),
|
||||||
|
vector[2].clone(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a real quaternion.
|
/// Constructs a real quaternion.
|
||||||
|
@ -296,9 +301,9 @@ where
|
||||||
let (sy, cy) = (yaw * crate::convert(0.5f64)).simd_sin_cos();
|
let (sy, cy) = (yaw * crate::convert(0.5f64)).simd_sin_cos();
|
||||||
|
|
||||||
let q = Quaternion::new(
|
let q = Quaternion::new(
|
||||||
cr * cp * cy + sr * sp * sy,
|
cr.clone() * cp.clone() * cy.clone() + sr.clone() * sp.clone() * sy.clone(),
|
||||||
sr * cp * cy - cr * sp * sy,
|
sr.clone() * cp.clone() * cy.clone() - cr.clone() * sp.clone() * sy.clone(),
|
||||||
cr * sp * cy + sr * cp * sy,
|
cr.clone() * sp.clone() * cy.clone() + sr.clone() * cp.clone() * sy.clone(),
|
||||||
cr * cp * sy - sr * sp * cy,
|
cr * cp * sy - sr * sp * cy,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -334,56 +339,65 @@ where
|
||||||
pub fn from_rotation_matrix(rotmat: &Rotation3<T>) -> Self {
|
pub fn from_rotation_matrix(rotmat: &Rotation3<T>) -> Self {
|
||||||
// Robust matrix to quaternion transformation.
|
// Robust matrix to quaternion transformation.
|
||||||
// See https://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion
|
// See https://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion
|
||||||
let tr = rotmat[(0, 0)] + rotmat[(1, 1)] + rotmat[(2, 2)];
|
let tr = rotmat[(0, 0)].clone() + rotmat[(1, 1)].clone() + rotmat[(2, 2)].clone();
|
||||||
let quarter: T = crate::convert(0.25);
|
let quarter: T = crate::convert(0.25);
|
||||||
|
|
||||||
let res = tr.simd_gt(T::zero()).if_else3(
|
let res = tr.clone().simd_gt(T::zero()).if_else3(
|
||||||
|| {
|
|| {
|
||||||
let denom = (tr + T::one()).simd_sqrt() * crate::convert(2.0);
|
let denom = (tr.clone() + T::one()).simd_sqrt() * crate::convert(2.0);
|
||||||
Quaternion::new(
|
Quaternion::new(
|
||||||
quarter * denom,
|
quarter.clone() * denom.clone(),
|
||||||
(rotmat[(2, 1)] - rotmat[(1, 2)]) / denom,
|
(rotmat[(2, 1)].clone() - rotmat[(1, 2)].clone()) / denom.clone(),
|
||||||
(rotmat[(0, 2)] - rotmat[(2, 0)]) / denom,
|
(rotmat[(0, 2)].clone() - rotmat[(2, 0)].clone()) / denom.clone(),
|
||||||
(rotmat[(1, 0)] - rotmat[(0, 1)]) / denom,
|
(rotmat[(1, 0)].clone() - rotmat[(0, 1)].clone()) / denom,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
(
|
(
|
||||||
|| rotmat[(0, 0)].simd_gt(rotmat[(1, 1)]) & rotmat[(0, 0)].simd_gt(rotmat[(2, 2)]),
|
|
||||||
|| {
|
|| {
|
||||||
let denom = (T::one() + rotmat[(0, 0)] - rotmat[(1, 1)] - rotmat[(2, 2)])
|
rotmat[(0, 0)].clone().simd_gt(rotmat[(1, 1)].clone())
|
||||||
|
& rotmat[(0, 0)].clone().simd_gt(rotmat[(2, 2)].clone())
|
||||||
|
},
|
||||||
|
|| {
|
||||||
|
let denom = (T::one() + rotmat[(0, 0)].clone()
|
||||||
|
- rotmat[(1, 1)].clone()
|
||||||
|
- rotmat[(2, 2)].clone())
|
||||||
.simd_sqrt()
|
.simd_sqrt()
|
||||||
* crate::convert(2.0);
|
* crate::convert(2.0);
|
||||||
Quaternion::new(
|
Quaternion::new(
|
||||||
(rotmat[(2, 1)] - rotmat[(1, 2)]) / denom,
|
(rotmat[(2, 1)].clone() - rotmat[(1, 2)].clone()) / denom.clone(),
|
||||||
quarter * denom,
|
quarter.clone() * denom.clone(),
|
||||||
(rotmat[(0, 1)] + rotmat[(1, 0)]) / denom,
|
(rotmat[(0, 1)].clone() + rotmat[(1, 0)].clone()) / denom.clone(),
|
||||||
(rotmat[(0, 2)] + rotmat[(2, 0)]) / denom,
|
(rotmat[(0, 2)].clone() + rotmat[(2, 0)].clone()) / denom,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|| rotmat[(1, 1)].simd_gt(rotmat[(2, 2)]),
|
|| rotmat[(1, 1)].clone().simd_gt(rotmat[(2, 2)].clone()),
|
||||||
|| {
|
|| {
|
||||||
let denom = (T::one() + rotmat[(1, 1)] - rotmat[(0, 0)] - rotmat[(2, 2)])
|
let denom = (T::one() + rotmat[(1, 1)].clone()
|
||||||
|
- rotmat[(0, 0)].clone()
|
||||||
|
- rotmat[(2, 2)].clone())
|
||||||
.simd_sqrt()
|
.simd_sqrt()
|
||||||
* crate::convert(2.0);
|
* crate::convert(2.0);
|
||||||
Quaternion::new(
|
Quaternion::new(
|
||||||
(rotmat[(0, 2)] - rotmat[(2, 0)]) / denom,
|
(rotmat[(0, 2)].clone() - rotmat[(2, 0)].clone()) / denom.clone(),
|
||||||
(rotmat[(0, 1)] + rotmat[(1, 0)]) / denom,
|
(rotmat[(0, 1)].clone() + rotmat[(1, 0)].clone()) / denom.clone(),
|
||||||
quarter * denom,
|
quarter.clone() * denom.clone(),
|
||||||
(rotmat[(1, 2)] + rotmat[(2, 1)]) / denom,
|
(rotmat[(1, 2)].clone() + rotmat[(2, 1)].clone()) / denom,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|| {
|
|| {
|
||||||
let denom = (T::one() + rotmat[(2, 2)] - rotmat[(0, 0)] - rotmat[(1, 1)])
|
let denom = (T::one() + rotmat[(2, 2)].clone()
|
||||||
|
- rotmat[(0, 0)].clone()
|
||||||
|
- rotmat[(1, 1)].clone())
|
||||||
.simd_sqrt()
|
.simd_sqrt()
|
||||||
* crate::convert(2.0);
|
* crate::convert(2.0);
|
||||||
Quaternion::new(
|
Quaternion::new(
|
||||||
(rotmat[(1, 0)] - rotmat[(0, 1)]) / denom,
|
(rotmat[(1, 0)].clone() - rotmat[(0, 1)].clone()) / denom.clone(),
|
||||||
(rotmat[(0, 2)] + rotmat[(2, 0)]) / denom,
|
(rotmat[(0, 2)].clone() + rotmat[(2, 0)].clone()) / denom.clone(),
|
||||||
(rotmat[(1, 2)] + rotmat[(2, 1)]) / denom,
|
(rotmat[(1, 2)].clone() + rotmat[(2, 1)].clone()) / denom.clone(),
|
||||||
quarter * denom,
|
quarter.clone() * denom,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -833,10 +847,10 @@ where
|
||||||
|
|
||||||
let max_eigenvector = eigen_matrix.eigenvectors.column(max_eigenvalue_index);
|
let max_eigenvector = eigen_matrix.eigenvectors.column(max_eigenvalue_index);
|
||||||
UnitQuaternion::from_quaternion(Quaternion::new(
|
UnitQuaternion::from_quaternion(Quaternion::new(
|
||||||
max_eigenvector[0],
|
max_eigenvector[0].clone(),
|
||||||
max_eigenvector[1],
|
max_eigenvector[1].clone(),
|
||||||
max_eigenvector[2],
|
max_eigenvector[2].clone(),
|
||||||
max_eigenvector[3],
|
max_eigenvector[3].clone(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -868,13 +882,18 @@ where
|
||||||
let twopi = Uniform::new(T::zero(), T::simd_two_pi());
|
let twopi = Uniform::new(T::zero(), T::simd_two_pi());
|
||||||
let theta1 = rng.sample(&twopi);
|
let theta1 = rng.sample(&twopi);
|
||||||
let theta2 = rng.sample(&twopi);
|
let theta2 = rng.sample(&twopi);
|
||||||
let s1 = theta1.simd_sin();
|
let s1 = theta1.clone().simd_sin();
|
||||||
let c1 = theta1.simd_cos();
|
let c1 = theta1.simd_cos();
|
||||||
let s2 = theta2.simd_sin();
|
let s2 = theta2.clone().simd_sin();
|
||||||
let c2 = theta2.simd_cos();
|
let c2 = theta2.simd_cos();
|
||||||
let r1 = (T::one() - x0).simd_sqrt();
|
let r1 = (T::one() - x0.clone()).simd_sqrt();
|
||||||
let r2 = x0.simd_sqrt();
|
let r2 = x0.simd_sqrt();
|
||||||
Unit::new_unchecked(Quaternion::new(s1 * r1, c1 * r1, s2 * r2, c2 * r2))
|
Unit::new_unchecked(Quaternion::new(
|
||||||
|
s1 * r1.clone(),
|
||||||
|
c1 * r1,
|
||||||
|
s2 * r2.clone(),
|
||||||
|
c2 * r2,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -167,7 +167,7 @@ where
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Transform<T2, C, 3> {
|
fn to_superset(&self) -> Transform<T2, C, 3> {
|
||||||
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
Transform::from_matrix_unchecked(self.clone().to_homogeneous().to_superset())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -184,7 +184,7 @@ where
|
||||||
impl<T1: RealField, T2: RealField + SupersetOf<T1>> SubsetOf<Matrix4<T2>> for UnitQuaternion<T1> {
|
impl<T1: RealField, T2: RealField + SupersetOf<T1>> SubsetOf<Matrix4<T2>> for UnitQuaternion<T1> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Matrix4<T2> {
|
fn to_superset(&self) -> Matrix4<T2> {
|
||||||
self.to_homogeneous().to_superset()
|
self.clone().to_homogeneous().to_superset()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -159,10 +159,10 @@ quaternion_op_impl!(
|
||||||
;
|
;
|
||||||
self: &'a Quaternion<T>, rhs: &'b Quaternion<T>, Output = Quaternion<T>;
|
self: &'a Quaternion<T>, rhs: &'b Quaternion<T>, Output = Quaternion<T>;
|
||||||
Quaternion::new(
|
Quaternion::new(
|
||||||
self[3] * rhs[3] - self[0] * rhs[0] - self[1] * rhs[1] - self[2] * rhs[2],
|
self[3].clone() * rhs[3].clone() - self[0].clone() * rhs[0].clone() - self[1].clone() * rhs[1].clone() - self[2].clone() * rhs[2].clone(),
|
||||||
self[3] * rhs[0] + self[0] * rhs[3] + self[1] * rhs[2] - self[2] * rhs[1],
|
self[3].clone() * rhs[0].clone() + self[0].clone() * rhs[3].clone() + self[1].clone() * rhs[2].clone() - self[2].clone() * rhs[1].clone(),
|
||||||
self[3] * rhs[1] - self[0] * rhs[2] + self[1] * rhs[3] + self[2] * rhs[0],
|
self[3].clone() * rhs[1].clone() - self[0].clone() * rhs[2].clone() + self[1].clone() * rhs[3].clone() + self[2].clone() * rhs[0].clone(),
|
||||||
self[3] * rhs[2] + self[0] * rhs[1] - self[1] * rhs[0] + self[2] * rhs[3]);
|
self[3].clone() * rhs[2].clone() + self[0].clone() * rhs[1].clone() - self[1].clone() * rhs[0].clone() + self[2].clone() * rhs[3].clone());
|
||||||
'a, 'b);
|
'a, 'b);
|
||||||
|
|
||||||
quaternion_op_impl!(
|
quaternion_op_impl!(
|
||||||
|
|
|
@ -45,7 +45,7 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D>> Reflection<T, D, S> {
|
||||||
/// represents a plane that passes through the origin.
|
/// represents a plane that passes through the origin.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn bias(&self) -> T {
|
pub fn bias(&self) -> T {
|
||||||
self.bias
|
self.bias.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: naming convention: reflect_to, reflect_assign ?
|
// TODO: naming convention: reflect_to, reflect_assign ?
|
||||||
|
@ -60,7 +60,7 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D>> Reflection<T, D, S> {
|
||||||
// dot product, and then mutably. Somehow, this allows significantly
|
// dot product, and then mutably. Somehow, this allows significantly
|
||||||
// better optimizations of the dot product from the compiler.
|
// better optimizations of the dot product from the compiler.
|
||||||
let m_two: T = crate::convert(-2.0f64);
|
let m_two: T = crate::convert(-2.0f64);
|
||||||
let factor = (self.axis.dotc(&rhs.column(i)) - self.bias) * m_two;
|
let factor = (self.axis.dotc(&rhs.column(i)) - self.bias.clone()) * m_two;
|
||||||
rhs.column_mut(i).axpy(factor, &self.axis, T::one());
|
rhs.column_mut(i).axpy(factor, &self.axis, T::one());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,9 +76,9 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D>> Reflection<T, D, S> {
|
||||||
// NOTE: we borrow the column twice here. First it is borrowed immutably for the
|
// NOTE: we borrow the column twice here. First it is borrowed immutably for the
|
||||||
// dot product, and then mutably. Somehow, this allows significantly
|
// dot product, and then mutably. Somehow, this allows significantly
|
||||||
// better optimizations of the dot product from the compiler.
|
// better optimizations of the dot product from the compiler.
|
||||||
let m_two = sign.scale(crate::convert(-2.0f64));
|
let m_two = sign.clone().scale(crate::convert(-2.0f64));
|
||||||
let factor = (self.axis.dotc(&rhs.column(i)) - self.bias) * m_two;
|
let factor = (self.axis.dotc(&rhs.column(i)) - self.bias.clone()) * m_two;
|
||||||
rhs.column_mut(i).axpy(factor, &self.axis, sign);
|
rhs.column_mut(i).axpy(factor, &self.axis, sign.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D>> Reflection<T, D, S> {
|
||||||
lhs.mul_to(&self.axis, work);
|
lhs.mul_to(&self.axis, work);
|
||||||
|
|
||||||
if !self.bias.is_zero() {
|
if !self.bias.is_zero() {
|
||||||
work.add_scalar_mut(-self.bias);
|
work.add_scalar_mut(-self.bias.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let m_two: T = crate::convert(-2.0f64);
|
let m_two: T = crate::convert(-2.0f64);
|
||||||
|
@ -116,10 +116,10 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D>> Reflection<T, D, S> {
|
||||||
lhs.mul_to(&self.axis, work);
|
lhs.mul_to(&self.axis, work);
|
||||||
|
|
||||||
if !self.bias.is_zero() {
|
if !self.bias.is_zero() {
|
||||||
work.add_scalar_mut(-self.bias);
|
work.add_scalar_mut(-self.bias.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let m_two = sign.scale(crate::convert(-2.0f64));
|
let m_two = sign.clone().scale(crate::convert(-2.0f64));
|
||||||
lhs.gerc(m_two, work, &self.axis, sign);
|
lhs.gerc(m_two, work, &self.axis, sign);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -514,7 +514,7 @@ impl<T: Scalar + PartialEq, const D: usize> PartialEq for Rotation<T, D> {
|
||||||
impl<T, const D: usize> AbsDiffEq for Rotation<T, D>
|
impl<T, const D: usize> AbsDiffEq for Rotation<T, D>
|
||||||
where
|
where
|
||||||
T: Scalar + AbsDiffEq,
|
T: Scalar + AbsDiffEq,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
type Epsilon = T::Epsilon;
|
type Epsilon = T::Epsilon;
|
||||||
|
|
||||||
|
@ -532,7 +532,7 @@ where
|
||||||
impl<T, const D: usize> RelativeEq for Rotation<T, D>
|
impl<T, const D: usize> RelativeEq for Rotation<T, D>
|
||||||
where
|
where
|
||||||
T: Scalar + RelativeEq,
|
T: Scalar + RelativeEq,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default_max_relative() -> Self::Epsilon {
|
fn default_max_relative() -> Self::Epsilon {
|
||||||
|
@ -554,7 +554,7 @@ where
|
||||||
impl<T, const D: usize> UlpsEq for Rotation<T, D>
|
impl<T, const D: usize> UlpsEq for Rotation<T, D>
|
||||||
where
|
where
|
||||||
T: Scalar + UlpsEq,
|
T: Scalar + UlpsEq,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default_max_ulps() -> u32 {
|
fn default_max_ulps() -> u32 {
|
||||||
|
|
|
@ -23,8 +23,8 @@ impl<T: SimdRealField> Rotation2<T> {
|
||||||
where
|
where
|
||||||
T::Element: SimdRealField,
|
T::Element: SimdRealField,
|
||||||
{
|
{
|
||||||
let c1 = UnitComplex::from(*self);
|
let c1 = UnitComplex::from(self.clone());
|
||||||
let c2 = UnitComplex::from(*other);
|
let c2 = UnitComplex::from(other.clone());
|
||||||
c1.slerp(&c2, t).into()
|
c1.slerp(&c2, t).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,8 @@ impl<T: SimdRealField> Rotation3<T> {
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let q1 = UnitQuaternion::from(*self);
|
let q1 = UnitQuaternion::from(self.clone());
|
||||||
let q2 = UnitQuaternion::from(*other);
|
let q2 = UnitQuaternion::from(other.clone());
|
||||||
q1.slerp(&q2, t).into()
|
q1.slerp(&q2, t).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,8 +74,8 @@ impl<T: SimdRealField> Rotation3<T> {
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let q1 = UnitQuaternion::from(*self);
|
let q1 = UnitQuaternion::from(self.clone());
|
||||||
let q2 = UnitQuaternion::from(*other);
|
let q2 = UnitQuaternion::from(other.clone());
|
||||||
q1.try_slerp(&q2, t, epsilon).map(|q| q.into())
|
q1.try_slerp(&q2, t, epsilon).map(|q| q.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ impl<T: SimdRealField> Rotation2<T> {
|
||||||
/// ```
|
/// ```
|
||||||
pub fn new(angle: T) -> Self {
|
pub fn new(angle: T) -> Self {
|
||||||
let (sia, coa) = angle.simd_sin_cos();
|
let (sia, coa) = angle.simd_sin_cos();
|
||||||
Self::from_matrix_unchecked(Matrix2::new(coa, -sia, sia, coa))
|
Self::from_matrix_unchecked(Matrix2::new(coa.clone(), -sia.clone(), sia, coa))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a 2 dimensional rotation matrix from an angle in radian wrapped in a 1-dimensional vector.
|
/// Builds a 2 dimensional rotation matrix from an angle in radian wrapped in a 1-dimensional vector.
|
||||||
|
@ -52,7 +52,7 @@ impl<T: SimdRealField> Rotation2<T> {
|
||||||
/// the `::new(angle)` method instead is more common.
|
/// the `::new(angle)` method instead is more common.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_scaled_axis<SB: Storage<T, U1>>(axisangle: Vector<T, U1, SB>) -> Self {
|
pub fn from_scaled_axis<SB: Storage<T, U1>>(axisangle: Vector<T, U1, SB>) -> Self {
|
||||||
Self::new(axisangle[0])
|
Self::new(axisangle[0].clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ impl<T: SimdRealField> Rotation2<T> {
|
||||||
let denom = rot.column(0).dot(&m.column(0)) + rot.column(1).dot(&m.column(1));
|
let denom = rot.column(0).dot(&m.column(0)) + rot.column(1).dot(&m.column(1));
|
||||||
|
|
||||||
let angle = axis / (denom.abs() + T::default_epsilon());
|
let angle = axis / (denom.abs() + T::default_epsilon());
|
||||||
if angle.abs() > eps {
|
if angle.clone().abs() > eps {
|
||||||
rot = Self::new(angle) * rot;
|
rot = Self::new(angle) * rot;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -198,7 +198,7 @@ impl<T: SimdRealField> Rotation2<T> {
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let mut c = UnitComplex::from(*self);
|
let mut c = UnitComplex::from(self.clone());
|
||||||
let _ = c.renormalize();
|
let _ = c.renormalize();
|
||||||
|
|
||||||
*self = Self::from_matrix_eps(self.matrix(), T::default_epsilon(), 0, c.into())
|
*self = Self::from_matrix_eps(self.matrix(), T::default_epsilon(), 0, c.into())
|
||||||
|
@ -236,7 +236,9 @@ impl<T: SimdRealField> Rotation2<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn angle(&self) -> T {
|
pub fn angle(&self) -> T {
|
||||||
self.matrix()[(1, 0)].simd_atan2(self.matrix()[(0, 0)])
|
self.matrix()[(1, 0)]
|
||||||
|
.clone()
|
||||||
|
.simd_atan2(self.matrix()[(0, 0)].clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The rotation angle needed to make `self` and `other` coincide.
|
/// The rotation angle needed to make `self` and `other` coincide.
|
||||||
|
@ -382,27 +384,27 @@ where
|
||||||
where
|
where
|
||||||
SB: Storage<T, U3>,
|
SB: Storage<T, U3>,
|
||||||
{
|
{
|
||||||
angle.simd_ne(T::zero()).if_else(
|
angle.clone().simd_ne(T::zero()).if_else(
|
||||||
|| {
|
|| {
|
||||||
let ux = axis.as_ref()[0];
|
let ux = axis.as_ref()[0].clone();
|
||||||
let uy = axis.as_ref()[1];
|
let uy = axis.as_ref()[1].clone();
|
||||||
let uz = axis.as_ref()[2];
|
let uz = axis.as_ref()[2].clone();
|
||||||
let sqx = ux * ux;
|
let sqx = ux.clone() * ux.clone();
|
||||||
let sqy = uy * uy;
|
let sqy = uy.clone() * uy.clone();
|
||||||
let sqz = uz * uz;
|
let sqz = uz.clone() * uz.clone();
|
||||||
let (sin, cos) = angle.simd_sin_cos();
|
let (sin, cos) = angle.simd_sin_cos();
|
||||||
let one_m_cos = T::one() - cos;
|
let one_m_cos = T::one() - cos.clone();
|
||||||
|
|
||||||
Self::from_matrix_unchecked(SMatrix::<T, 3, 3>::new(
|
Self::from_matrix_unchecked(SMatrix::<T, 3, 3>::new(
|
||||||
sqx + (T::one() - sqx) * cos,
|
sqx.clone() + (T::one() - sqx) * cos.clone(),
|
||||||
ux * uy * one_m_cos - uz * sin,
|
ux.clone() * uy.clone() * one_m_cos.clone() - uz.clone() * sin.clone(),
|
||||||
ux * uz * one_m_cos + uy * sin,
|
ux.clone() * uz.clone() * one_m_cos.clone() + uy.clone() * sin.clone(),
|
||||||
ux * uy * one_m_cos + uz * sin,
|
ux.clone() * uy.clone() * one_m_cos.clone() + uz.clone() * sin.clone(),
|
||||||
sqy + (T::one() - sqy) * cos,
|
sqy.clone() + (T::one() - sqy) * cos.clone(),
|
||||||
uy * uz * one_m_cos - ux * sin,
|
uy.clone() * uz.clone() * one_m_cos.clone() - ux.clone() * sin.clone(),
|
||||||
ux * uz * one_m_cos - uy * sin,
|
ux.clone() * uz.clone() * one_m_cos.clone() - uy.clone() * sin.clone(),
|
||||||
uy * uz * one_m_cos + ux * sin,
|
uy * uz * one_m_cos + ux * sin,
|
||||||
sqz + (T::one() - sqz) * cos,
|
sqz.clone() + (T::one() - sqz) * cos,
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
Self::identity,
|
Self::identity,
|
||||||
|
@ -429,14 +431,14 @@ where
|
||||||
let (sy, cy) = yaw.simd_sin_cos();
|
let (sy, cy) = yaw.simd_sin_cos();
|
||||||
|
|
||||||
Self::from_matrix_unchecked(SMatrix::<T, 3, 3>::new(
|
Self::from_matrix_unchecked(SMatrix::<T, 3, 3>::new(
|
||||||
cy * cp,
|
cy.clone() * cp.clone(),
|
||||||
cy * sp * sr - sy * cr,
|
cy.clone() * sp.clone() * sr.clone() - sy.clone() * cr.clone(),
|
||||||
cy * sp * cr + sy * sr,
|
cy.clone() * sp.clone() * cr.clone() + sy.clone() * sr.clone(),
|
||||||
sy * cp,
|
sy.clone() * cp.clone(),
|
||||||
sy * sp * sr + cy * cr,
|
sy.clone() * sp.clone() * sr.clone() + cy.clone() * cr.clone(),
|
||||||
sy * sp * cr - cy * sr,
|
sy * sp.clone() * cr.clone() - cy * sr.clone(),
|
||||||
-sp,
|
-sp,
|
||||||
cp * sr,
|
cp.clone() * sr,
|
||||||
cp * cr,
|
cp * cr,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -479,7 +481,15 @@ where
|
||||||
let yaxis = zaxis.cross(&xaxis).normalize();
|
let yaxis = zaxis.cross(&xaxis).normalize();
|
||||||
|
|
||||||
Self::from_matrix_unchecked(SMatrix::<T, 3, 3>::new(
|
Self::from_matrix_unchecked(SMatrix::<T, 3, 3>::new(
|
||||||
xaxis.x, yaxis.x, zaxis.x, xaxis.y, yaxis.y, zaxis.y, xaxis.z, yaxis.z, zaxis.z,
|
xaxis.x.clone(),
|
||||||
|
yaxis.x.clone(),
|
||||||
|
zaxis.x.clone(),
|
||||||
|
xaxis.y.clone(),
|
||||||
|
yaxis.y.clone(),
|
||||||
|
zaxis.y.clone(),
|
||||||
|
xaxis.z.clone(),
|
||||||
|
yaxis.z.clone(),
|
||||||
|
zaxis.z.clone(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -735,7 +745,7 @@ where
|
||||||
|
|
||||||
let axisangle = axis / (denom.abs() + T::default_epsilon());
|
let axisangle = axis / (denom.abs() + T::default_epsilon());
|
||||||
|
|
||||||
if let Some((axis, angle)) = Unit::try_new_and_get(axisangle, eps) {
|
if let Some((axis, angle)) = Unit::try_new_and_get(axisangle, eps.clone()) {
|
||||||
rot = Rotation3::from_axis_angle(&axis, angle) * rot;
|
rot = Rotation3::from_axis_angle(&axis, angle) * rot;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -752,7 +762,7 @@ where
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let mut c = UnitQuaternion::from(*self);
|
let mut c = UnitQuaternion::from(self.clone());
|
||||||
let _ = c.renormalize();
|
let _ = c.renormalize();
|
||||||
|
|
||||||
*self = Self::from_matrix_eps(self.matrix(), T::default_epsilon(), 0, c.into())
|
*self = Self::from_matrix_eps(self.matrix(), T::default_epsilon(), 0, c.into())
|
||||||
|
@ -774,7 +784,10 @@ impl<T: SimdRealField> Rotation3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn angle(&self) -> T {
|
pub fn angle(&self) -> T {
|
||||||
((self.matrix()[(0, 0)] + self.matrix()[(1, 1)] + self.matrix()[(2, 2)] - T::one())
|
((self.matrix()[(0, 0)].clone()
|
||||||
|
+ self.matrix()[(1, 1)].clone()
|
||||||
|
+ self.matrix()[(2, 2)].clone()
|
||||||
|
- T::one())
|
||||||
/ crate::convert(2.0))
|
/ crate::convert(2.0))
|
||||||
.simd_acos()
|
.simd_acos()
|
||||||
}
|
}
|
||||||
|
@ -800,10 +813,11 @@ impl<T: SimdRealField> Rotation3<T> {
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
|
let rotmat = self.matrix();
|
||||||
let axis = SVector::<T, 3>::new(
|
let axis = SVector::<T, 3>::new(
|
||||||
self.matrix()[(2, 1)] - self.matrix()[(1, 2)],
|
rotmat[(2, 1)].clone() - rotmat[(1, 2)].clone(),
|
||||||
self.matrix()[(0, 2)] - self.matrix()[(2, 0)],
|
rotmat[(0, 2)].clone() - rotmat[(2, 0)].clone(),
|
||||||
self.matrix()[(1, 0)] - self.matrix()[(0, 1)],
|
rotmat[(1, 0)].clone() - rotmat[(0, 1)].clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Unit::try_new(axis, T::default_epsilon())
|
Unit::try_new(axis, T::default_epsilon())
|
||||||
|
@ -911,16 +925,22 @@ impl<T: SimdRealField> Rotation3<T> {
|
||||||
{
|
{
|
||||||
// Implementation informed by "Computing Euler angles from a rotation matrix", by Gregory G. Slabaugh
|
// Implementation informed by "Computing Euler angles from a rotation matrix", by Gregory G. Slabaugh
|
||||||
// https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.371.6578
|
// https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.371.6578
|
||||||
if self[(2, 0)].abs() < T::one() {
|
if self[(2, 0)].clone().abs() < T::one() {
|
||||||
let yaw = -self[(2, 0)].asin();
|
let yaw = -self[(2, 0)].clone().asin();
|
||||||
let roll = (self[(2, 1)] / yaw.cos()).atan2(self[(2, 2)] / yaw.cos());
|
let roll = (self[(2, 1)].clone() / yaw.clone().cos())
|
||||||
let pitch = (self[(1, 0)] / yaw.cos()).atan2(self[(0, 0)] / yaw.cos());
|
.atan2(self[(2, 2)].clone() / yaw.clone().cos());
|
||||||
|
let pitch = (self[(1, 0)].clone() / yaw.clone().cos())
|
||||||
|
.atan2(self[(0, 0)].clone() / yaw.clone().cos());
|
||||||
(roll, yaw, pitch)
|
(roll, yaw, pitch)
|
||||||
} else if self[(2, 0)] <= -T::one() {
|
} else if self[(2, 0)].clone() <= -T::one() {
|
||||||
(self[(0, 1)].atan2(self[(0, 2)]), T::frac_pi_2(), T::zero())
|
(
|
||||||
|
self[(0, 1)].clone().atan2(self[(0, 2)].clone()),
|
||||||
|
T::frac_pi_2(),
|
||||||
|
T::zero(),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
-self[(0, 1)].atan2(-self[(0, 2)]),
|
-self[(0, 1)].clone().atan2(-self[(0, 2)].clone()),
|
||||||
-T::frac_pi_2(),
|
-T::frac_pi_2(),
|
||||||
T::zero(),
|
T::zero(),
|
||||||
)
|
)
|
||||||
|
@ -947,8 +967,8 @@ where
|
||||||
let theta = rng.sample(&twopi);
|
let theta = rng.sample(&twopi);
|
||||||
let (ts, tc) = theta.simd_sin_cos();
|
let (ts, tc) = theta.simd_sin_cos();
|
||||||
let a = SMatrix::<T, 3, 3>::new(
|
let a = SMatrix::<T, 3, 3>::new(
|
||||||
tc,
|
tc.clone(),
|
||||||
ts,
|
ts.clone(),
|
||||||
T::zero(),
|
T::zero(),
|
||||||
-ts,
|
-ts,
|
||||||
tc,
|
tc,
|
||||||
|
@ -962,10 +982,10 @@ where
|
||||||
let phi = rng.sample(&twopi);
|
let phi = rng.sample(&twopi);
|
||||||
let z = rng.sample(OpenClosed01);
|
let z = rng.sample(OpenClosed01);
|
||||||
let (ps, pc) = phi.simd_sin_cos();
|
let (ps, pc) = phi.simd_sin_cos();
|
||||||
let sqrt_z = z.simd_sqrt();
|
let sqrt_z = z.clone().simd_sqrt();
|
||||||
let v = Vector3::new(pc * sqrt_z, ps * sqrt_z, (T::one() - z).simd_sqrt());
|
let v = Vector3::new(pc * sqrt_z.clone(), ps * sqrt_z, (T::one() - z).simd_sqrt());
|
||||||
let mut b = v * v.transpose();
|
let mut b = v.clone() * v.transpose();
|
||||||
b += b;
|
b += b.clone();
|
||||||
b -= SMatrix::<T, 3, 3>::identity();
|
b -= SMatrix::<T, 3, 3>::identity();
|
||||||
|
|
||||||
Rotation3::from_matrix_unchecked(b * a)
|
Rotation3::from_matrix_unchecked(b * a)
|
||||||
|
|
|
@ -124,7 +124,7 @@ impl<T: Scalar, R, const D: usize> Similarity<T, R, D> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn scaling(&self) -> T {
|
pub fn scaling(&self) -> T {
|
||||||
self.scaling.inlined_clone()
|
self.scaling.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,9 +151,9 @@ where
|
||||||
/// Inverts `self` in-place.
|
/// Inverts `self` in-place.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inverse_mut(&mut self) {
|
pub fn inverse_mut(&mut self) {
|
||||||
self.scaling = T::one() / self.scaling;
|
self.scaling = T::one() / self.scaling.clone();
|
||||||
self.isometry.inverse_mut();
|
self.isometry.inverse_mut();
|
||||||
self.isometry.translation.vector *= self.scaling;
|
self.isometry.translation.vector *= self.scaling.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The similarity transformation that applies a scaling factor `scaling` before `self`.
|
/// The similarity transformation that applies a scaling factor `scaling` before `self`.
|
||||||
|
@ -165,7 +165,7 @@ where
|
||||||
"The similarity scaling factor must not be zero."
|
"The similarity scaling factor must not be zero."
|
||||||
);
|
);
|
||||||
|
|
||||||
Self::from_isometry(self.isometry.clone(), self.scaling * scaling)
|
Self::from_isometry(self.isometry.clone(), self.scaling.clone() * scaling)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The similarity transformation that applies a scaling factor `scaling` after `self`.
|
/// The similarity transformation that applies a scaling factor `scaling` after `self`.
|
||||||
|
@ -178,9 +178,9 @@ where
|
||||||
);
|
);
|
||||||
|
|
||||||
Self::from_parts(
|
Self::from_parts(
|
||||||
Translation::from(self.isometry.translation.vector * scaling),
|
Translation::from(&self.isometry.translation.vector * scaling.clone()),
|
||||||
self.isometry.rotation.clone(),
|
self.isometry.rotation.clone(),
|
||||||
self.scaling * scaling,
|
self.scaling.clone() * scaling,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ where
|
||||||
"The similarity scaling factor must not be zero."
|
"The similarity scaling factor must not be zero."
|
||||||
);
|
);
|
||||||
|
|
||||||
self.isometry.translation.vector *= scaling;
|
self.isometry.translation.vector *= scaling.clone();
|
||||||
self.scaling *= scaling;
|
self.scaling *= scaling;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ impl<T: SimdRealField, R, const D: usize> Similarity<T, R, D> {
|
||||||
let mut res = self.isometry.to_homogeneous();
|
let mut res = self.isometry.to_homogeneous();
|
||||||
|
|
||||||
for e in res.fixed_slice_mut::<D, D>(0, 0).iter_mut() {
|
for e in res.fixed_slice_mut::<D, D>(0, 0).iter_mut() {
|
||||||
*e *= self.scaling
|
*e *= self.scaling.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -361,7 +361,7 @@ where
|
||||||
impl<T: RealField, R, const D: usize> AbsDiffEq for Similarity<T, R, D>
|
impl<T: RealField, R, const D: usize> AbsDiffEq for Similarity<T, R, D>
|
||||||
where
|
where
|
||||||
R: AbstractRotation<T, D> + AbsDiffEq<Epsilon = T::Epsilon>,
|
R: AbstractRotation<T, D> + AbsDiffEq<Epsilon = T::Epsilon>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
type Epsilon = T::Epsilon;
|
type Epsilon = T::Epsilon;
|
||||||
|
|
||||||
|
@ -372,7 +372,7 @@ where
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
|
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
|
||||||
self.isometry.abs_diff_eq(&other.isometry, epsilon)
|
self.isometry.abs_diff_eq(&other.isometry, epsilon.clone())
|
||||||
&& self.scaling.abs_diff_eq(&other.scaling, epsilon)
|
&& self.scaling.abs_diff_eq(&other.scaling, epsilon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -380,7 +380,7 @@ where
|
||||||
impl<T: RealField, R, const D: usize> RelativeEq for Similarity<T, R, D>
|
impl<T: RealField, R, const D: usize> RelativeEq for Similarity<T, R, D>
|
||||||
where
|
where
|
||||||
R: AbstractRotation<T, D> + RelativeEq<Epsilon = T::Epsilon>,
|
R: AbstractRotation<T, D> + RelativeEq<Epsilon = T::Epsilon>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default_max_relative() -> Self::Epsilon {
|
fn default_max_relative() -> Self::Epsilon {
|
||||||
|
@ -395,7 +395,7 @@ where
|
||||||
max_relative: Self::Epsilon,
|
max_relative: Self::Epsilon,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
self.isometry
|
self.isometry
|
||||||
.relative_eq(&other.isometry, epsilon, max_relative)
|
.relative_eq(&other.isometry, epsilon.clone(), max_relative.clone())
|
||||||
&& self
|
&& self
|
||||||
.scaling
|
.scaling
|
||||||
.relative_eq(&other.scaling, epsilon, max_relative)
|
.relative_eq(&other.scaling, epsilon, max_relative)
|
||||||
|
@ -405,7 +405,7 @@ where
|
||||||
impl<T: RealField, R, const D: usize> UlpsEq for Similarity<T, R, D>
|
impl<T: RealField, R, const D: usize> UlpsEq for Similarity<T, R, D>
|
||||||
where
|
where
|
||||||
R: AbstractRotation<T, D> + UlpsEq<Epsilon = T::Epsilon>,
|
R: AbstractRotation<T, D> + UlpsEq<Epsilon = T::Epsilon>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default_max_ulps() -> u32 {
|
fn default_max_ulps() -> u32 {
|
||||||
|
@ -414,7 +414,8 @@ where
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
|
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
|
||||||
self.isometry.ulps_eq(&other.isometry, epsilon, max_ulps)
|
self.isometry
|
||||||
|
.ulps_eq(&other.isometry, epsilon.clone(), max_ulps.clone())
|
||||||
&& self.scaling.ulps_eq(&other.scaling, epsilon, max_ulps)
|
&& self.scaling.ulps_eq(&other.scaling, epsilon, max_ulps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,7 +222,7 @@ md_assign_impl_all!(
|
||||||
const D; for; where;
|
const D; for; where;
|
||||||
self: Similarity<T, Rotation<T, D>, D>, rhs: Rotation<T, D>;
|
self: Similarity<T, Rotation<T, D>, D>, rhs: Rotation<T, D>;
|
||||||
[val] => self.isometry.rotation *= rhs;
|
[val] => self.isometry.rotation *= rhs;
|
||||||
[ref] => self.isometry.rotation *= *rhs;
|
[ref] => self.isometry.rotation *= rhs.clone();
|
||||||
);
|
);
|
||||||
|
|
||||||
md_assign_impl_all!(
|
md_assign_impl_all!(
|
||||||
|
@ -241,7 +241,7 @@ md_assign_impl_all!(
|
||||||
const; for; where;
|
const; for; where;
|
||||||
self: Similarity<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>;
|
self: Similarity<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>;
|
||||||
[val] => self.isometry.rotation *= rhs;
|
[val] => self.isometry.rotation *= rhs;
|
||||||
[ref] => self.isometry.rotation *= *rhs;
|
[ref] => self.isometry.rotation *= rhs.clone();
|
||||||
);
|
);
|
||||||
|
|
||||||
md_assign_impl_all!(
|
md_assign_impl_all!(
|
||||||
|
@ -260,7 +260,7 @@ md_assign_impl_all!(
|
||||||
const; for; where;
|
const; for; where;
|
||||||
self: Similarity<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>;
|
self: Similarity<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>;
|
||||||
[val] => self.isometry.rotation *= rhs;
|
[val] => self.isometry.rotation *= rhs;
|
||||||
[ref] => self.isometry.rotation *= *rhs;
|
[ref] => self.isometry.rotation *= rhs.clone();
|
||||||
);
|
);
|
||||||
|
|
||||||
md_assign_impl_all!(
|
md_assign_impl_all!(
|
||||||
|
|
|
@ -11,7 +11,7 @@ macro_rules! impl_swizzle {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn $name(&self) -> $Result<T>
|
pub fn $name(&self) -> $Result<T>
|
||||||
where <Const<D> as ToTypenum>::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
|
where <Const<D> as ToTypenum>::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
|
||||||
$Result::new($(self[$i].inlined_clone()),*)
|
$Result::new($(self[$i].clone()),*)
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
)*
|
)*
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub trait TCategory: Any + Debug + Copy + PartialEq + Send {
|
||||||
/// category `Self`.
|
/// category `Self`.
|
||||||
fn check_homogeneous_invariants<T: RealField, D: DimName>(mat: &OMatrix<T, D, D>) -> bool
|
fn check_homogeneous_invariants<T: RealField, D: DimName>(mat: &OMatrix<T, D, D>) -> bool
|
||||||
where
|
where
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
DefaultAllocator: Allocator<T, D, D>;
|
DefaultAllocator: Allocator<T, D, D>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ impl TCategory for TGeneral {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn check_homogeneous_invariants<T: RealField, D: DimName>(_: &OMatrix<T, D, D>) -> bool
|
fn check_homogeneous_invariants<T: RealField, D: DimName>(_: &OMatrix<T, D, D>) -> bool
|
||||||
where
|
where
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
DefaultAllocator: Allocator<T, D, D>,
|
DefaultAllocator: Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
true
|
true
|
||||||
|
@ -85,7 +85,7 @@ impl TCategory for TProjective {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn check_homogeneous_invariants<T: RealField, D: DimName>(mat: &OMatrix<T, D, D>) -> bool
|
fn check_homogeneous_invariants<T: RealField, D: DimName>(mat: &OMatrix<T, D, D>) -> bool
|
||||||
where
|
where
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
DefaultAllocator: Allocator<T, D, D>,
|
DefaultAllocator: Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
mat.is_invertible()
|
mat.is_invertible()
|
||||||
|
@ -101,7 +101,7 @@ impl TCategory for TAffine {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn check_homogeneous_invariants<T: RealField, D: DimName>(mat: &OMatrix<T, D, D>) -> bool
|
fn check_homogeneous_invariants<T: RealField, D: DimName>(mat: &OMatrix<T, D, D>) -> bool
|
||||||
where
|
where
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
DefaultAllocator: Allocator<T, D, D>,
|
DefaultAllocator: Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
let last = D::dim() - 1;
|
let last = D::dim() - 1;
|
||||||
|
@ -178,7 +178,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RealField, C: TCategory, const D: usize> Copy for Transform<T, C, D>
|
impl<T: RealField + Copy, C: TCategory, const D: usize> Copy for Transform<T, C, D>
|
||||||
where
|
where
|
||||||
Const<D>: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
|
@ -583,7 +583,7 @@ where
|
||||||
impl<T: RealField, C: TCategory, const D: usize> AbsDiffEq for Transform<T, C, D>
|
impl<T: RealField, C: TCategory, const D: usize> AbsDiffEq for Transform<T, C, D>
|
||||||
where
|
where
|
||||||
Const<D>: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
type Epsilon = T::Epsilon;
|
type Epsilon = T::Epsilon;
|
||||||
|
@ -602,7 +602,7 @@ where
|
||||||
impl<T: RealField, C: TCategory, const D: usize> RelativeEq for Transform<T, C, D>
|
impl<T: RealField, C: TCategory, const D: usize> RelativeEq for Transform<T, C, D>
|
||||||
where
|
where
|
||||||
Const<D>: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -625,7 +625,7 @@ where
|
||||||
impl<T: RealField, C: TCategory, const D: usize> UlpsEq for Transform<T, C, D>
|
impl<T: RealField, C: TCategory, const D: usize> UlpsEq for Transform<T, C, D>
|
||||||
where
|
where
|
||||||
Const<D>: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -154,7 +154,7 @@ md_impl_all!(
|
||||||
if C::has_normalizer() {
|
if C::has_normalizer() {
|
||||||
let normalizer = self.matrix().fixed_slice::<1, D>(D, 0);
|
let normalizer = self.matrix().fixed_slice::<1, D>(D, 0);
|
||||||
#[allow(clippy::suspicious_arithmetic_impl)]
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
||||||
let n = normalizer.tr_dot(&rhs.coords) + unsafe { *self.matrix().get_unchecked((D, D)) };
|
let n = normalizer.tr_dot(&rhs.coords) + unsafe { self.matrix().get_unchecked((D, D)).clone() };
|
||||||
|
|
||||||
if !n.is_zero() {
|
if !n.is_zero() {
|
||||||
return (transform * rhs + translation) / n;
|
return (transform * rhs + translation) / n;
|
||||||
|
@ -221,8 +221,8 @@ md_impl_all!(
|
||||||
self: Transform<T, C, 3>, rhs: UnitQuaternion<T>, Output = Transform<T, C::Representative, 3>;
|
self: Transform<T, C, 3>, rhs: UnitQuaternion<T>, Output = Transform<T, C::Representative, 3>;
|
||||||
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
||||||
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
||||||
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.clone().to_homogeneous());
|
||||||
[ref ref] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
[ref ref] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.clone().to_homogeneous());
|
||||||
);
|
);
|
||||||
|
|
||||||
// Transform × UnitComplex
|
// Transform × UnitComplex
|
||||||
|
@ -235,8 +235,8 @@ md_impl_all!(
|
||||||
self: Transform<T, C, 2>, rhs: UnitComplex<T>, Output = Transform<T, C::Representative, 2>;
|
self: Transform<T, C, 2>, rhs: UnitComplex<T>, Output = Transform<T, C::Representative, 2>;
|
||||||
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
||||||
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
||||||
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.clone().to_homogeneous());
|
||||||
[ref ref] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
[ref ref] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.clone().to_homogeneous());
|
||||||
);
|
);
|
||||||
|
|
||||||
// UnitQuaternion × Transform
|
// UnitQuaternion × Transform
|
||||||
|
@ -248,9 +248,9 @@ md_impl_all!(
|
||||||
where C: TCategoryMul<TAffine>;
|
where C: TCategoryMul<TAffine>;
|
||||||
self: UnitQuaternion<T>, rhs: Transform<T, C, 3>, Output = Transform<T, C::Representative, 3>;
|
self: UnitQuaternion<T>, rhs: Transform<T, C, 3>, Output = Transform<T, C::Representative, 3>;
|
||||||
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
||||||
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
[ref val] => Self::Output::from_matrix_unchecked(self.clone().to_homogeneous() * rhs.into_inner());
|
||||||
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
||||||
[ref ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
[ref ref] => Self::Output::from_matrix_unchecked(self.clone().to_homogeneous() * rhs.matrix());
|
||||||
);
|
);
|
||||||
|
|
||||||
// UnitComplex × Transform
|
// UnitComplex × Transform
|
||||||
|
@ -262,9 +262,9 @@ md_impl_all!(
|
||||||
where C: TCategoryMul<TAffine>;
|
where C: TCategoryMul<TAffine>;
|
||||||
self: UnitComplex<T>, rhs: Transform<T, C, 2>, Output = Transform<T, C::Representative, 2>;
|
self: UnitComplex<T>, rhs: Transform<T, C, 2>, Output = Transform<T, C::Representative, 2>;
|
||||||
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
||||||
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
[ref val] => Self::Output::from_matrix_unchecked(self.clone().to_homogeneous() * rhs.into_inner());
|
||||||
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
||||||
[ref ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
[ref ref] => Self::Output::from_matrix_unchecked(self.clone().to_homogeneous() * rhs.matrix());
|
||||||
);
|
);
|
||||||
|
|
||||||
// Transform × Isometry
|
// Transform × Isometry
|
||||||
|
@ -604,7 +604,7 @@ md_assign_impl_all!(
|
||||||
where C: TCategory;
|
where C: TCategory;
|
||||||
self: Transform<T, C, 3>, rhs: UnitQuaternion<T>;
|
self: Transform<T, C, 3>, rhs: UnitQuaternion<T>;
|
||||||
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
||||||
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
[ref] => *self.matrix_mut_unchecked() *= rhs.clone().to_homogeneous();
|
||||||
);
|
);
|
||||||
|
|
||||||
// Transform ×= UnitComplex
|
// Transform ×= UnitComplex
|
||||||
|
@ -616,7 +616,7 @@ md_assign_impl_all!(
|
||||||
where C: TCategory;
|
where C: TCategory;
|
||||||
self: Transform<T, C, 2>, rhs: UnitComplex<T>;
|
self: Transform<T, C, 2>, rhs: UnitComplex<T>;
|
||||||
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
||||||
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
[ref] => *self.matrix_mut_unchecked() *= rhs.clone().to_homogeneous();
|
||||||
);
|
);
|
||||||
|
|
||||||
// Transform ÷= Transform
|
// Transform ÷= Transform
|
||||||
|
|
|
@ -291,7 +291,7 @@ impl<T: Scalar + PartialEq, const D: usize> PartialEq for Translation<T, D> {
|
||||||
|
|
||||||
impl<T: Scalar + AbsDiffEq, const D: usize> AbsDiffEq for Translation<T, D>
|
impl<T: Scalar + AbsDiffEq, const D: usize> AbsDiffEq for Translation<T, D>
|
||||||
where
|
where
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
type Epsilon = T::Epsilon;
|
type Epsilon = T::Epsilon;
|
||||||
|
|
||||||
|
@ -308,7 +308,7 @@ where
|
||||||
|
|
||||||
impl<T: Scalar + RelativeEq, const D: usize> RelativeEq for Translation<T, D>
|
impl<T: Scalar + RelativeEq, const D: usize> RelativeEq for Translation<T, D>
|
||||||
where
|
where
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default_max_relative() -> Self::Epsilon {
|
fn default_max_relative() -> Self::Epsilon {
|
||||||
|
@ -329,7 +329,7 @@ where
|
||||||
|
|
||||||
impl<T: Scalar + UlpsEq, const D: usize> UlpsEq for Translation<T, D>
|
impl<T: Scalar + UlpsEq, const D: usize> UlpsEq for Translation<T, D>
|
||||||
where
|
where
|
||||||
T::Epsilon: Copy,
|
T::Epsilon: Clone,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default_max_ulps() -> u32 {
|
fn default_max_ulps() -> u32 {
|
||||||
|
|
|
@ -77,7 +77,7 @@ where
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> UnitDualQuaternion<T2> {
|
fn to_superset(&self) -> UnitDualQuaternion<T2> {
|
||||||
let dq = UnitDualQuaternion::<T1>::from_parts(*self, UnitQuaternion::identity());
|
let dq = UnitDualQuaternion::<T1>::from_parts(self.clone(), UnitQuaternion::identity());
|
||||||
dq.to_superset()
|
dq.to_superset()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,25 +47,25 @@ impl<T: SimdRealField> Normed for Complex<T> {
|
||||||
fn norm(&self) -> T::SimdRealField {
|
fn norm(&self) -> T::SimdRealField {
|
||||||
// We don't use `.norm_sqr()` because it requires
|
// We don't use `.norm_sqr()` because it requires
|
||||||
// some very strong Num trait requirements.
|
// some very strong Num trait requirements.
|
||||||
(self.re * self.re + self.im * self.im).simd_sqrt()
|
(self.re.clone() * self.re.clone() + self.im.clone() * self.im.clone()).simd_sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn norm_squared(&self) -> T::SimdRealField {
|
fn norm_squared(&self) -> T::SimdRealField {
|
||||||
// We don't use `.norm_sqr()` because it requires
|
// We don't use `.norm_sqr()` because it requires
|
||||||
// some very strong Num trait requirements.
|
// some very strong Num trait requirements.
|
||||||
self.re * self.re + self.im * self.im
|
self.re.clone() * self.re.clone() + self.im.clone() * self.im.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scale_mut(&mut self, n: Self::Norm) {
|
fn scale_mut(&mut self, n: Self::Norm) {
|
||||||
self.re *= n;
|
self.re *= n.clone();
|
||||||
self.im *= n;
|
self.im *= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn unscale_mut(&mut self, n: Self::Norm) {
|
fn unscale_mut(&mut self, n: Self::Norm) {
|
||||||
self.re /= n;
|
self.re /= n.clone();
|
||||||
self.im /= n;
|
self.im /= n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn angle(&self) -> T {
|
pub fn angle(&self) -> T {
|
||||||
self.im.simd_atan2(self.re)
|
self.im.clone().simd_atan2(self.re.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The sine of the rotation angle.
|
/// The sine of the rotation angle.
|
||||||
|
@ -101,7 +101,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn sin_angle(&self) -> T {
|
pub fn sin_angle(&self) -> T {
|
||||||
self.im
|
self.im.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The cosine of the rotation angle.
|
/// The cosine of the rotation angle.
|
||||||
|
@ -116,7 +116,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn cos_angle(&self) -> T {
|
pub fn cos_angle(&self) -> T {
|
||||||
self.re
|
self.re.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The rotation angle returned as a 1-dimensional vector.
|
/// The rotation angle returned as a 1-dimensional vector.
|
||||||
|
@ -145,7 +145,7 @@ where
|
||||||
if ang.is_zero() {
|
if ang.is_zero() {
|
||||||
None
|
None
|
||||||
} else if ang.is_sign_negative() {
|
} else if ang.is_sign_negative() {
|
||||||
Some((Unit::new_unchecked(Vector1::x()), -ang))
|
Some((Unit::new_unchecked(Vector1::x()), -ang.clone()))
|
||||||
} else {
|
} else {
|
||||||
Some((Unit::new_unchecked(-Vector1::<T>::x()), ang))
|
Some((Unit::new_unchecked(-Vector1::<T>::x()), ang))
|
||||||
}
|
}
|
||||||
|
@ -223,7 +223,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn conjugate_mut(&mut self) {
|
pub fn conjugate_mut(&mut self) {
|
||||||
let me = self.as_mut_unchecked();
|
let me = self.as_mut_unchecked();
|
||||||
me.im = -me.im;
|
me.im = -me.im.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inverts in-place this unit complex number.
|
/// Inverts in-place this unit complex number.
|
||||||
|
@ -262,10 +262,10 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn to_rotation_matrix(self) -> Rotation2<T> {
|
pub fn to_rotation_matrix(self) -> Rotation2<T> {
|
||||||
let r = self.re;
|
let r = self.re.clone();
|
||||||
let i = self.im;
|
let i = self.im.clone();
|
||||||
|
|
||||||
Rotation2::from_matrix_unchecked(Matrix2::new(r, -i, i, r))
|
Rotation2::from_matrix_unchecked(Matrix2::new(r.clone(), -i.clone(), i, r))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts this unit complex number into its equivalent homogeneous transformation matrix.
|
/// Converts this unit complex number into its equivalent homogeneous transformation matrix.
|
||||||
|
@ -407,7 +407,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn slerp(&self, other: &Self, t: T) -> Self {
|
pub fn slerp(&self, other: &Self, t: T) -> Self {
|
||||||
Self::new(self.angle() * (T::one() - t) + other.angle() * t)
|
Self::new(self.angle() * (T::one() - t.clone()) + other.angle() * t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,7 +427,7 @@ impl<T: RealField> AbsDiffEq for UnitComplex<T> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
|
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
|
||||||
self.re.abs_diff_eq(&other.re, epsilon) && self.im.abs_diff_eq(&other.im, epsilon)
|
self.re.abs_diff_eq(&other.re, epsilon.clone()) && self.im.abs_diff_eq(&other.im, epsilon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +444,8 @@ impl<T: RealField> RelativeEq for UnitComplex<T> {
|
||||||
epsilon: Self::Epsilon,
|
epsilon: Self::Epsilon,
|
||||||
max_relative: Self::Epsilon,
|
max_relative: Self::Epsilon,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
self.re.relative_eq(&other.re, epsilon, max_relative)
|
self.re
|
||||||
|
.relative_eq(&other.re, epsilon.clone(), max_relative.clone())
|
||||||
&& self.im.relative_eq(&other.im, epsilon, max_relative)
|
&& self.im.relative_eq(&other.im, epsilon, max_relative)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -457,7 +458,8 @@ impl<T: RealField> UlpsEq for UnitComplex<T> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
|
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
|
||||||
self.re.ulps_eq(&other.re, epsilon, max_ulps)
|
self.re
|
||||||
|
.ulps_eq(&other.re, epsilon.clone(), max_ulps.clone())
|
||||||
&& self.im.ulps_eq(&other.im, epsilon, max_ulps)
|
&& self.im.ulps_eq(&other.im, epsilon, max_ulps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ where
|
||||||
/// the `::new(angle)` method instead is more common.
|
/// the `::new(angle)` method instead is more common.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_scaled_axis<SB: Storage<T, U1>>(axisangle: Vector<T, U1, SB>) -> Self {
|
pub fn from_scaled_axis<SB: Storage<T, U1>>(axisangle: Vector<T, U1, SB>) -> Self {
|
||||||
Self::from_angle(axisangle[0])
|
Self::from_angle(axisangle[0].clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,8 +166,8 @@ where
|
||||||
/// The input complex number will be normalized. Returns the norm of the complex number as well.
|
/// The input complex number will be normalized. Returns the norm of the complex number as well.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_complex_and_get(q: Complex<T>) -> (Self, T) {
|
pub fn from_complex_and_get(q: Complex<T>) -> (Self, T) {
|
||||||
let norm = (q.im * q.im + q.re * q.re).simd_sqrt();
|
let norm = (q.im.clone() * q.im.clone() + q.re.clone() * q.re.clone()).simd_sqrt();
|
||||||
(Self::new_unchecked(q / norm), norm)
|
(Self::new_unchecked(q / norm.clone()), norm)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds the unit complex number from the corresponding 2D rotation matrix.
|
/// Builds the unit complex number from the corresponding 2D rotation matrix.
|
||||||
|
@ -182,7 +182,7 @@ where
|
||||||
// TODO: add UnitComplex::from(...) instead?
|
// TODO: add UnitComplex::from(...) instead?
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_rotation_matrix(rotmat: &Rotation2<T>) -> Self {
|
pub fn from_rotation_matrix(rotmat: &Rotation2<T>) -> Self {
|
||||||
Self::new_unchecked(Complex::new(rotmat[(0, 0)], rotmat[(1, 0)]))
|
Self::new_unchecked(Complex::new(rotmat[(0, 0)].clone(), rotmat[(1, 0)].clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a rotation from a basis assumed to be orthonormal.
|
/// Builds a rotation from a basis assumed to be orthonormal.
|
||||||
|
@ -410,7 +410,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<'a, R: Rng + ?Sized>(&self, rng: &mut R) -> UnitComplex<T> {
|
fn sample<'a, R: Rng + ?Sized>(&self, rng: &mut R) -> UnitComplex<T> {
|
||||||
let x = rng.sample(rand_distr::UnitCircle);
|
let x = rng.sample(rand_distr::UnitCircle);
|
||||||
UnitComplex::new_unchecked(Complex::new(x[0], x[1]))
|
UnitComplex::new_unchecked(Complex::new(x[0].clone(), x[1].clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ where
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Transform<T2, C, 2> {
|
fn to_superset(&self) -> Transform<T2, C, 2> {
|
||||||
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
Transform::from_matrix_unchecked(self.clone().to_homogeneous().to_superset())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -138,7 +138,7 @@ where
|
||||||
impl<T1: RealField, T2: RealField + SupersetOf<T1>> SubsetOf<Matrix3<T2>> for UnitComplex<T1> {
|
impl<T1: RealField, T2: RealField + SupersetOf<T1>> SubsetOf<Matrix3<T2>> for UnitComplex<T1> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Matrix3<T2> {
|
fn to_superset(&self) -> Matrix3<T2> {
|
||||||
self.to_homogeneous().to_superset()
|
self.clone().to_homogeneous().to_superset()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -255,9 +255,9 @@ complex_op_impl_all!(
|
||||||
[ref val] => self * &rhs;
|
[ref val] => self * &rhs;
|
||||||
[val ref] => &self * rhs;
|
[val ref] => &self * rhs;
|
||||||
[ref ref] => {
|
[ref ref] => {
|
||||||
let i = self.as_ref().im;
|
let i = self.as_ref().im.clone();
|
||||||
let r = self.as_ref().re;
|
let r = self.as_ref().re.clone();
|
||||||
Vector2::new(r * rhs[0] - i * rhs[1], i * rhs[0] + r * rhs[1])
|
Vector2::new(r.clone() * rhs[0].clone() - i.clone() * rhs[1].clone(), i * rhs[0].clone() + r * rhs[1].clone())
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -306,9 +306,9 @@ complex_op_impl_all!(
|
||||||
self: UnitComplex<T>, rhs: Translation<T, 2>,
|
self: UnitComplex<T>, rhs: Translation<T, 2>,
|
||||||
Output = Isometry<T, UnitComplex<T>, 2>;
|
Output = Isometry<T, UnitComplex<T>, 2>;
|
||||||
[val val] => Isometry::from_parts(Translation::from(&self * rhs.vector), self);
|
[val val] => Isometry::from_parts(Translation::from(&self * rhs.vector), self);
|
||||||
[ref val] => Isometry::from_parts(Translation::from( self * rhs.vector), *self);
|
[ref val] => Isometry::from_parts(Translation::from( self * rhs.vector), self.clone());
|
||||||
[val ref] => Isometry::from_parts(Translation::from(&self * &rhs.vector), self);
|
[val ref] => Isometry::from_parts(Translation::from(&self * &rhs.vector), self);
|
||||||
[ref ref] => Isometry::from_parts(Translation::from( self * &rhs.vector), *self);
|
[ref ref] => Isometry::from_parts(Translation::from( self * &rhs.vector), self.clone());
|
||||||
);
|
);
|
||||||
|
|
||||||
// Translation × UnitComplex
|
// Translation × UnitComplex
|
||||||
|
@ -318,9 +318,9 @@ complex_op_impl_all!(
|
||||||
self: Translation<T, 2>, right: UnitComplex<T>,
|
self: Translation<T, 2>, right: UnitComplex<T>,
|
||||||
Output = Isometry<T, UnitComplex<T>, 2>;
|
Output = Isometry<T, UnitComplex<T>, 2>;
|
||||||
[val val] => Isometry::from_parts(self, right);
|
[val val] => Isometry::from_parts(self, right);
|
||||||
[ref val] => Isometry::from_parts(*self, right);
|
[ref val] => Isometry::from_parts(self.clone(), right);
|
||||||
[val ref] => Isometry::from_parts(self, *right);
|
[val ref] => Isometry::from_parts(self, right.clone());
|
||||||
[ref ref] => Isometry::from_parts(*self, *right);
|
[ref ref] => Isometry::from_parts(self.clone(), right.clone());
|
||||||
);
|
);
|
||||||
|
|
||||||
// UnitComplex ×= UnitComplex
|
// UnitComplex ×= UnitComplex
|
||||||
|
@ -330,7 +330,7 @@ where
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_assign(&mut self, rhs: UnitComplex<T>) {
|
fn mul_assign(&mut self, rhs: UnitComplex<T>) {
|
||||||
*self = *self * rhs
|
*self = self.clone() * rhs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,7 +340,7 @@ where
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_assign(&mut self, rhs: &'b UnitComplex<T>) {
|
fn mul_assign(&mut self, rhs: &'b UnitComplex<T>) {
|
||||||
*self = *self * rhs
|
*self = self.clone() * rhs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +351,7 @@ where
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn div_assign(&mut self, rhs: UnitComplex<T>) {
|
fn div_assign(&mut self, rhs: UnitComplex<T>) {
|
||||||
*self = *self / rhs
|
*self = self.clone() / rhs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,7 +361,7 @@ where
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn div_assign(&mut self, rhs: &'b UnitComplex<T>) {
|
fn div_assign(&mut self, rhs: &'b UnitComplex<T>) {
|
||||||
*self = *self / rhs
|
*self = self.clone() / rhs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,7 +372,7 @@ where
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_assign(&mut self, rhs: Rotation<T, 2>) {
|
fn mul_assign(&mut self, rhs: Rotation<T, 2>) {
|
||||||
*self = *self * rhs
|
*self = self.clone() * rhs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +382,7 @@ where
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_assign(&mut self, rhs: &'b Rotation<T, 2>) {
|
fn mul_assign(&mut self, rhs: &'b Rotation<T, 2>) {
|
||||||
*self = *self * rhs
|
*self = self.clone() * rhs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,7 +393,7 @@ where
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn div_assign(&mut self, rhs: Rotation<T, 2>) {
|
fn div_assign(&mut self, rhs: Rotation<T, 2>) {
|
||||||
*self = *self / rhs
|
*self = self.clone() / rhs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +403,7 @@ where
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn div_assign(&mut self, rhs: &'b Rotation<T, 2>) {
|
fn div_assign(&mut self, rhs: &'b Rotation<T, 2>) {
|
||||||
*self = *self / rhs
|
*self = self.clone() / rhs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,7 +424,7 @@ where
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_assign(&mut self, rhs: &'b UnitComplex<T>) {
|
fn mul_assign(&mut self, rhs: &'b UnitComplex<T>) {
|
||||||
self.mul_assign(rhs.to_rotation_matrix())
|
self.mul_assign(rhs.clone().to_rotation_matrix())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,6 +445,6 @@ where
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn div_assign(&mut self, rhs: &'b UnitComplex<T>) {
|
fn div_assign(&mut self, rhs: &'b UnitComplex<T>) {
|
||||||
self.div_assign(rhs.to_rotation_matrix())
|
self.div_assign(rhs.clone().to_rotation_matrix())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -390,7 +390,7 @@ pub fn center<T: SimdComplexField, const D: usize>(
|
||||||
p1: &Point<T, D>,
|
p1: &Point<T, D>,
|
||||||
p2: &Point<T, D>,
|
p2: &Point<T, D>,
|
||||||
) -> Point<T, D> {
|
) -> Point<T, D> {
|
||||||
((p1.coords + p2.coords) * convert::<_, T>(0.5)).into()
|
((&p1.coords + &p2.coords) * convert::<_, T>(0.5)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The distance between two points.
|
/// The distance between two points.
|
||||||
|
@ -404,7 +404,7 @@ pub fn distance<T: SimdComplexField, const D: usize>(
|
||||||
p1: &Point<T, D>,
|
p1: &Point<T, D>,
|
||||||
p2: &Point<T, D>,
|
p2: &Point<T, D>,
|
||||||
) -> T::SimdRealField {
|
) -> T::SimdRealField {
|
||||||
(p2.coords - p1.coords).norm()
|
(&p2.coords - &p1.coords).norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The squared distance between two points.
|
/// The squared distance between two points.
|
||||||
|
@ -418,7 +418,7 @@ pub fn distance_squared<T: SimdComplexField, const D: usize>(
|
||||||
p1: &Point<T, D>,
|
p1: &Point<T, D>,
|
||||||
p2: &Point<T, D>,
|
p2: &Point<T, D>,
|
||||||
) -> T::SimdRealField {
|
) -> T::SimdRealField {
|
||||||
(p2.coords - p1.coords).norm_squared()
|
(&p2.coords - &p1.coords).norm_squared()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -31,33 +31,33 @@ where
|
||||||
let mut n_row = matrix.row(i).norm_squared();
|
let mut n_row = matrix.row(i).norm_squared();
|
||||||
let mut f = T::one();
|
let mut f = T::one();
|
||||||
|
|
||||||
let s = n_col + n_row;
|
let s = n_col.clone() + n_row.clone();
|
||||||
n_col = n_col.sqrt();
|
n_col = n_col.sqrt();
|
||||||
n_row = n_row.sqrt();
|
n_row = n_row.sqrt();
|
||||||
|
|
||||||
if n_col.is_zero() || n_row.is_zero() {
|
if n_col.clone().is_zero() || n_row.clone().is_zero() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
while n_col < n_row / radix {
|
while n_col.clone() < n_row.clone() / radix.clone() {
|
||||||
n_col *= radix;
|
n_col *= radix.clone();
|
||||||
n_row /= radix;
|
n_row /= radix.clone();
|
||||||
f *= radix;
|
f *= radix.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
while n_col >= n_row * radix {
|
while n_col.clone() >= n_row.clone() * radix.clone() {
|
||||||
n_col /= radix;
|
n_col /= radix.clone();
|
||||||
n_row *= radix;
|
n_row *= radix.clone();
|
||||||
f /= radix;
|
f /= radix.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
let eps: T = crate::convert(0.95);
|
let eps: T = crate::convert(0.95);
|
||||||
#[allow(clippy::suspicious_operation_groupings)]
|
#[allow(clippy::suspicious_operation_groupings)]
|
||||||
if n_col * n_col + n_row * n_row < eps * s {
|
if n_col.clone() * n_col + n_row.clone() * n_row < eps * s {
|
||||||
converged = false;
|
converged = false;
|
||||||
d[i] *= f;
|
d[i] *= f.clone();
|
||||||
matrix.column_mut(i).mul_assign(f);
|
matrix.column_mut(i).mul_assign(f.clone());
|
||||||
matrix.row_mut(i).div_assign(f);
|
matrix.row_mut(i).div_assign(f.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,10 +75,10 @@ where
|
||||||
|
|
||||||
for j in 0..d.len() {
|
for j in 0..d.len() {
|
||||||
let mut col = m.column_mut(j);
|
let mut col = m.column_mut(j);
|
||||||
let denom = T::one() / d[j];
|
let denom = T::one() / d[j].clone();
|
||||||
|
|
||||||
for i in 0..d.len() {
|
for i in 0..d.len() {
|
||||||
col[i] *= d[i] * denom;
|
col[i] *= d[i].clone() * denom.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,11 +195,19 @@ where
|
||||||
|
|
||||||
let d = nrows.min(ncols);
|
let d = nrows.min(ncols);
|
||||||
let mut res = OMatrix::identity_generic(d, d);
|
let mut res = OMatrix::identity_generic(d, d);
|
||||||
res.set_partial_diagonal(self.diagonal.iter().map(|e| T::from_real(e.modulus())));
|
res.set_partial_diagonal(
|
||||||
|
self.diagonal
|
||||||
|
.iter()
|
||||||
|
.map(|e| T::from_real(e.clone().modulus())),
|
||||||
|
);
|
||||||
|
|
||||||
let start = self.axis_shift();
|
let start = self.axis_shift();
|
||||||
res.slice_mut(start, (d.value() - 1, d.value() - 1))
|
res.slice_mut(start, (d.value() - 1, d.value() - 1))
|
||||||
.set_partial_diagonal(self.off_diagonal.iter().map(|e| T::from_real(e.modulus())));
|
.set_partial_diagonal(
|
||||||
|
self.off_diagonal
|
||||||
|
.iter()
|
||||||
|
.map(|e| T::from_real(e.clone().modulus())),
|
||||||
|
);
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,9 +233,9 @@ where
|
||||||
let mut res_rows = res.slice_range_mut(i + shift.., i..);
|
let mut res_rows = res.slice_range_mut(i + shift.., i..);
|
||||||
|
|
||||||
let sign = if self.upper_diagonal {
|
let sign = if self.upper_diagonal {
|
||||||
self.diagonal[i].signum()
|
self.diagonal[i].clone().signum()
|
||||||
} else {
|
} else {
|
||||||
self.off_diagonal[i].signum()
|
self.off_diagonal[i].clone().signum()
|
||||||
};
|
};
|
||||||
|
|
||||||
refl.reflect_with_sign(&mut res_rows, sign);
|
refl.reflect_with_sign(&mut res_rows, sign);
|
||||||
|
@ -261,9 +269,9 @@ where
|
||||||
let mut res_rows = res.slice_range_mut(i.., i + shift..);
|
let mut res_rows = res.slice_range_mut(i.., i + shift..);
|
||||||
|
|
||||||
let sign = if self.upper_diagonal {
|
let sign = if self.upper_diagonal {
|
||||||
self.off_diagonal[i].signum()
|
self.off_diagonal[i].clone().signum()
|
||||||
} else {
|
} else {
|
||||||
self.diagonal[i].signum()
|
self.diagonal[i].clone().signum()
|
||||||
};
|
};
|
||||||
|
|
||||||
refl.reflect_rows_with_sign(&mut res_rows, &mut work.rows_range_mut(i..), sign);
|
refl.reflect_rows_with_sign(&mut res_rows, &mut work.rows_range_mut(i..), sign);
|
||||||
|
|
|
@ -52,7 +52,7 @@ where
|
||||||
|
|
||||||
for j in 0..n {
|
for j in 0..n {
|
||||||
for k in 0..j {
|
for k in 0..j {
|
||||||
let factor = unsafe { -*matrix.get_unchecked((j, k)) };
|
let factor = unsafe { -matrix.get_unchecked((j, k)).clone() };
|
||||||
|
|
||||||
let (mut col_j, col_k) = matrix.columns_range_pair_mut(j, k);
|
let (mut col_j, col_k) = matrix.columns_range_pair_mut(j, k);
|
||||||
let mut col_j = col_j.rows_range_mut(j..);
|
let mut col_j = col_j.rows_range_mut(j..);
|
||||||
|
@ -60,11 +60,11 @@ where
|
||||||
col_j.axpy(factor.simd_conjugate(), &col_k, T::one());
|
col_j.axpy(factor.simd_conjugate(), &col_k, T::one());
|
||||||
}
|
}
|
||||||
|
|
||||||
let diag = unsafe { *matrix.get_unchecked((j, j)) };
|
let diag = unsafe { matrix.get_unchecked((j, j)).clone() };
|
||||||
let denom = diag.simd_sqrt();
|
let denom = diag.simd_sqrt();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
*matrix.get_unchecked_mut((j, j)) = denom;
|
*matrix.get_unchecked_mut((j, j)) = denom.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut col = matrix.slice_range_mut(j + 1.., j);
|
let mut col = matrix.slice_range_mut(j + 1.., j);
|
||||||
|
@ -149,7 +149,7 @@ where
|
||||||
let dim = self.chol.nrows();
|
let dim = self.chol.nrows();
|
||||||
let mut prod_diag = T::one();
|
let mut prod_diag = T::one();
|
||||||
for i in 0..dim {
|
for i in 0..dim {
|
||||||
prod_diag *= unsafe { *self.chol.get_unchecked((i, i)) };
|
prod_diag *= unsafe { self.chol.get_unchecked((i, i)).clone() };
|
||||||
}
|
}
|
||||||
prod_diag.simd_modulus_squared()
|
prod_diag.simd_modulus_squared()
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ where
|
||||||
|
|
||||||
for j in 0..n {
|
for j in 0..n {
|
||||||
for k in 0..j {
|
for k in 0..j {
|
||||||
let factor = unsafe { -*matrix.get_unchecked((j, k)) };
|
let factor = unsafe { -matrix.get_unchecked((j, k)).clone() };
|
||||||
|
|
||||||
let (mut col_j, col_k) = matrix.columns_range_pair_mut(j, k);
|
let (mut col_j, col_k) = matrix.columns_range_pair_mut(j, k);
|
||||||
let mut col_j = col_j.rows_range_mut(j..);
|
let mut col_j = col_j.rows_range_mut(j..);
|
||||||
|
@ -179,11 +179,11 @@ where
|
||||||
col_j.axpy(factor.conjugate(), &col_k, T::one());
|
col_j.axpy(factor.conjugate(), &col_k, T::one());
|
||||||
}
|
}
|
||||||
|
|
||||||
let diag = unsafe { *matrix.get_unchecked((j, j)) };
|
let diag = unsafe { matrix.get_unchecked((j, j)).clone() };
|
||||||
if !diag.is_zero() {
|
if !diag.is_zero() {
|
||||||
if let Some(denom) = diag.try_sqrt() {
|
if let Some(denom) = diag.try_sqrt() {
|
||||||
unsafe {
|
unsafe {
|
||||||
*matrix.get_unchecked_mut((j, j)) = denom;
|
*matrix.get_unchecked_mut((j, j)) = denom.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut col = matrix.slice_range_mut(j + 1.., j);
|
let mut col = matrix.slice_range_mut(j + 1.., j);
|
||||||
|
@ -254,7 +254,7 @@ where
|
||||||
// update the jth row
|
// update the jth row
|
||||||
let top_left_corner = self.chol.slice_range(..j, ..j);
|
let top_left_corner = self.chol.slice_range(..j, ..j);
|
||||||
|
|
||||||
let col_j = col[j];
|
let col_j = col[j].clone();
|
||||||
let (mut new_rowj_adjoint, mut new_colj) = col.rows_range_pair_mut(..j, j + 1..);
|
let (mut new_rowj_adjoint, mut new_colj) = col.rows_range_pair_mut(..j, j + 1..);
|
||||||
assert!(
|
assert!(
|
||||||
top_left_corner.solve_lower_triangular_mut(&mut new_rowj_adjoint),
|
top_left_corner.solve_lower_triangular_mut(&mut new_rowj_adjoint),
|
||||||
|
@ -265,13 +265,13 @@ where
|
||||||
|
|
||||||
// update the center element
|
// update the center element
|
||||||
let center_element = T::sqrt(col_j - T::from_real(new_rowj_adjoint.norm_squared()));
|
let center_element = T::sqrt(col_j - T::from_real(new_rowj_adjoint.norm_squared()));
|
||||||
chol[(j, j)] = center_element;
|
chol[(j, j)] = center_element.clone();
|
||||||
|
|
||||||
// update the jth column
|
// update the jth column
|
||||||
let bottom_left_corner = self.chol.slice_range(j.., ..j);
|
let bottom_left_corner = self.chol.slice_range(j.., ..j);
|
||||||
// new_colj = (col_jplus - bottom_left_corner * new_rowj.adjoint()) / center_element;
|
// new_colj = (col_jplus - bottom_left_corner * new_rowj.adjoint()) / center_element;
|
||||||
new_colj.gemm(
|
new_colj.gemm(
|
||||||
-T::one() / center_element,
|
-T::one() / center_element.clone(),
|
||||||
&bottom_left_corner,
|
&bottom_left_corner,
|
||||||
&new_rowj_adjoint,
|
&new_rowj_adjoint,
|
||||||
T::one() / center_element,
|
T::one() / center_element,
|
||||||
|
@ -353,23 +353,23 @@ where
|
||||||
|
|
||||||
for j in 0..n {
|
for j in 0..n {
|
||||||
// updates the diagonal
|
// updates the diagonal
|
||||||
let diag = T::real(unsafe { *chol.get_unchecked((j, j)) });
|
let diag = T::real(unsafe { chol.get_unchecked((j, j)).clone() });
|
||||||
let diag2 = diag * diag;
|
let diag2 = diag.clone() * diag.clone();
|
||||||
let xj = unsafe { *x.get_unchecked(j) };
|
let xj = unsafe { x.get_unchecked(j).clone() };
|
||||||
let sigma_xj2 = sigma * T::modulus_squared(xj);
|
let sigma_xj2 = sigma.clone() * T::modulus_squared(xj.clone());
|
||||||
let gamma = diag2 * beta + sigma_xj2;
|
let gamma = diag2.clone() * beta.clone() + sigma_xj2.clone();
|
||||||
let new_diag = (diag2 + sigma_xj2 / beta).sqrt();
|
let new_diag = (diag2.clone() + sigma_xj2.clone() / beta.clone()).sqrt();
|
||||||
unsafe { *chol.get_unchecked_mut((j, j)) = T::from_real(new_diag) };
|
unsafe { *chol.get_unchecked_mut((j, j)) = T::from_real(new_diag.clone()) };
|
||||||
beta += sigma_xj2 / diag2;
|
beta += sigma_xj2 / diag2;
|
||||||
// updates the terms of L
|
// updates the terms of L
|
||||||
let mut xjplus = x.rows_range_mut(j + 1..);
|
let mut xjplus = x.rows_range_mut(j + 1..);
|
||||||
let mut col_j = chol.slice_range_mut(j + 1.., j);
|
let mut col_j = chol.slice_range_mut(j + 1.., j);
|
||||||
// temp_jplus -= (wj / T::from_real(diag)) * col_j;
|
// temp_jplus -= (wj / T::from_real(diag)) * col_j;
|
||||||
xjplus.axpy(-xj / T::from_real(diag), &col_j, T::one());
|
xjplus.axpy(-xj.clone() / T::from_real(diag.clone()), &col_j, T::one());
|
||||||
if gamma != crate::zero::<T::RealField>() {
|
if gamma != crate::zero::<T::RealField>() {
|
||||||
// col_j = T::from_real(nljj / diag) * col_j + (T::from_real(nljj * sigma / gamma) * T::conjugate(wj)) * temp_jplus;
|
// col_j = T::from_real(nljj / diag) * col_j + (T::from_real(nljj * sigma / gamma) * T::conjugate(wj)) * temp_jplus;
|
||||||
col_j.axpy(
|
col_j.axpy(
|
||||||
T::from_real(new_diag * sigma / gamma) * T::conjugate(xj),
|
T::from_real(new_diag.clone() * sigma.clone() / gamma) * T::conjugate(xj),
|
||||||
&xjplus,
|
&xjplus,
|
||||||
T::from_real(new_diag / diag),
|
T::from_real(new_diag / diag),
|
||||||
);
|
);
|
||||||
|
|
|
@ -109,7 +109,7 @@ where
|
||||||
.col_piv_qr
|
.col_piv_qr
|
||||||
.rows_generic(0, nrows.min(ncols))
|
.rows_generic(0, nrows.min(ncols))
|
||||||
.upper_triangle();
|
.upper_triangle();
|
||||||
res.set_partial_diagonal(self.diag.iter().map(|e| T::from_real(e.modulus())));
|
res.set_partial_diagonal(self.diag.iter().map(|e| T::from_real(e.clone().modulus())));
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ where
|
||||||
.col_piv_qr
|
.col_piv_qr
|
||||||
.resize_generic(nrows.min(ncols), ncols, T::zero());
|
.resize_generic(nrows.min(ncols), ncols, T::zero());
|
||||||
res.fill_lower_triangle(T::zero(), 1);
|
res.fill_lower_triangle(T::zero(), 1);
|
||||||
res.set_partial_diagonal(self.diag.iter().map(|e| T::from_real(e.modulus())));
|
res.set_partial_diagonal(self.diag.iter().map(|e| T::from_real(e.clone().modulus())));
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ where
|
||||||
let refl = Reflection::new(Unit::new_unchecked(axis), T::zero());
|
let refl = Reflection::new(Unit::new_unchecked(axis), T::zero());
|
||||||
|
|
||||||
let mut res_rows = res.slice_range_mut(i.., i..);
|
let mut res_rows = res.slice_range_mut(i.., i..);
|
||||||
refl.reflect_with_sign(&mut res_rows, self.diag[i].signum());
|
refl.reflect_with_sign(&mut res_rows, self.diag[i].clone().signum());
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -195,7 +195,7 @@ where
|
||||||
let refl = Reflection::new(Unit::new_unchecked(axis), T::zero());
|
let refl = Reflection::new(Unit::new_unchecked(axis), T::zero());
|
||||||
|
|
||||||
let mut rhs_rows = rhs.rows_range_mut(i..);
|
let mut rhs_rows = rhs.rows_range_mut(i..);
|
||||||
refl.reflect_with_sign(&mut rhs_rows, self.diag[i].signum().conjugate());
|
refl.reflect_with_sign(&mut rhs_rows, self.diag[i].clone().signum().conjugate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,14 +270,14 @@ where
|
||||||
let coeff;
|
let coeff;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let diag = self.diag.vget_unchecked(i).modulus();
|
let diag = self.diag.vget_unchecked(i).clone().modulus();
|
||||||
|
|
||||||
if diag.is_zero() {
|
if diag.is_zero() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
coeff = b.vget_unchecked(i).unscale(diag);
|
coeff = b.vget_unchecked(i).clone().unscale(diag);
|
||||||
*b.vget_unchecked_mut(i) = coeff;
|
*b.vget_unchecked_mut(i) = coeff.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
b.rows_range_mut(..i)
|
b.rows_range_mut(..i)
|
||||||
|
@ -337,7 +337,7 @@ where
|
||||||
|
|
||||||
let mut res = T::one();
|
let mut res = T::one();
|
||||||
for i in 0..dim {
|
for i in 0..dim {
|
||||||
res *= unsafe { *self.diag.vget_unchecked(i) };
|
res *= unsafe { self.diag.vget_unchecked(i).clone() };
|
||||||
}
|
}
|
||||||
|
|
||||||
res * self.p.determinant()
|
res * self.p.determinant()
|
||||||
|
|
|
@ -47,11 +47,11 @@ impl<T: RealField, D1: Dim, S1: Storage<T, D1>> Vector<T, D1, S1> {
|
||||||
let u_f = cmp::min(i, vec - 1);
|
let u_f = cmp::min(i, vec - 1);
|
||||||
|
|
||||||
if u_i == u_f {
|
if u_i == u_f {
|
||||||
conv[i] += self[u_i] * kernel[(i - u_i)];
|
conv[i] += self[u_i].clone() * kernel[(i - u_i)].clone();
|
||||||
} else {
|
} else {
|
||||||
for u in u_i..(u_f + 1) {
|
for u in u_i..(u_f + 1) {
|
||||||
if i - u < ker {
|
if i - u < ker {
|
||||||
conv[i] += self[u] * kernel[(i - u)];
|
conv[i] += self[u].clone() * kernel[(i - u)].clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ impl<T: RealField, D1: Dim, S1: Storage<T, D1>> Vector<T, D1, S1> {
|
||||||
|
|
||||||
for i in 0..(vec - ker + 1) {
|
for i in 0..(vec - ker + 1) {
|
||||||
for j in 0..ker {
|
for j in 0..ker {
|
||||||
conv[i] += self[i + j] * kernel[ker - j - 1];
|
conv[i] += self[i + j].clone() * kernel[ker - j - 1].clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conv
|
conv
|
||||||
|
@ -133,9 +133,9 @@ impl<T: RealField, D1: Dim, S1: Storage<T, D1>> Vector<T, D1, S1> {
|
||||||
let val = if i + j < 1 || i + j >= vec + 1 {
|
let val = if i + j < 1 || i + j >= vec + 1 {
|
||||||
zero::<T>()
|
zero::<T>()
|
||||||
} else {
|
} else {
|
||||||
self[i + j - 1]
|
self[i + j - 1].clone()
|
||||||
};
|
};
|
||||||
conv[i] += val * kernel[ker - j - 1];
|
conv[i] += val * kernel[ker - j - 1].clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,30 +26,30 @@ impl<T: ComplexField, D: DimMin<D, Output = D>, S: Storage<T, D, D>> SquareMatri
|
||||||
unsafe {
|
unsafe {
|
||||||
match dim {
|
match dim {
|
||||||
0 => T::one(),
|
0 => T::one(),
|
||||||
1 => *self.get_unchecked((0, 0)),
|
1 => self.get_unchecked((0, 0)).clone(),
|
||||||
2 => {
|
2 => {
|
||||||
let m11 = *self.get_unchecked((0, 0));
|
let m11 = self.get_unchecked((0, 0)).clone();
|
||||||
let m12 = *self.get_unchecked((0, 1));
|
let m12 = self.get_unchecked((0, 1)).clone();
|
||||||
let m21 = *self.get_unchecked((1, 0));
|
let m21 = self.get_unchecked((1, 0)).clone();
|
||||||
let m22 = *self.get_unchecked((1, 1));
|
let m22 = self.get_unchecked((1, 1)).clone();
|
||||||
|
|
||||||
m11 * m22 - m21 * m12
|
m11 * m22 - m21 * m12
|
||||||
}
|
}
|
||||||
3 => {
|
3 => {
|
||||||
let m11 = *self.get_unchecked((0, 0));
|
let m11 = self.get_unchecked((0, 0)).clone();
|
||||||
let m12 = *self.get_unchecked((0, 1));
|
let m12 = self.get_unchecked((0, 1)).clone();
|
||||||
let m13 = *self.get_unchecked((0, 2));
|
let m13 = self.get_unchecked((0, 2)).clone();
|
||||||
|
|
||||||
let m21 = *self.get_unchecked((1, 0));
|
let m21 = self.get_unchecked((1, 0)).clone();
|
||||||
let m22 = *self.get_unchecked((1, 1));
|
let m22 = self.get_unchecked((1, 1)).clone();
|
||||||
let m23 = *self.get_unchecked((1, 2));
|
let m23 = self.get_unchecked((1, 2)).clone();
|
||||||
|
|
||||||
let m31 = *self.get_unchecked((2, 0));
|
let m31 = self.get_unchecked((2, 0)).clone();
|
||||||
let m32 = *self.get_unchecked((2, 1));
|
let m32 = self.get_unchecked((2, 1)).clone();
|
||||||
let m33 = *self.get_unchecked((2, 2));
|
let m33 = self.get_unchecked((2, 2)).clone();
|
||||||
|
|
||||||
let minor_m12_m23 = m22 * m33 - m32 * m23;
|
let minor_m12_m23 = m22.clone() * m33.clone() - m32.clone() * m23.clone();
|
||||||
let minor_m11_m23 = m21 * m33 - m31 * m23;
|
let minor_m11_m23 = m21.clone() * m33.clone() - m31.clone() * m23.clone();
|
||||||
let minor_m11_m22 = m21 * m32 - m31 * m22;
|
let minor_m11_m22 = m21 * m32 - m31 * m22;
|
||||||
|
|
||||||
m11 * minor_m12_m23 - m12 * minor_m11_m23 + m13 * minor_m11_m22
|
m11 * minor_m12_m23 - m12 * minor_m11_m23 + m13 * minor_m11_m22
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue