De-traitify types, fix tests

This commit is contained in:
Brendan Zabarauskas 2013-06-11 09:02:25 +10:00
parent 3721167cdc
commit 17975b798d
9 changed files with 2291 additions and 2575 deletions

View file

@ -25,8 +25,6 @@
extern mod std; extern mod std;
pub mod num;
pub mod mat; pub mod mat;
pub mod quat; pub mod quat;
pub mod vec; pub mod vec;

2160
src/mat.rs

File diff suppressed because it is too large Load diff

View file

@ -1,50 +0,0 @@
// Copyright 2013 The Lmath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
pub trait NumAssign {
fn add_assign(&mut self, other: &Self);
fn sub_assign(&mut self, other: &Self);
fn mul_assign(&mut self, other: &Self);
fn div_assign(&mut self, other: &Self);
fn rem_assign(&mut self, other: &Self);
}
macro_rules! impl_NumAssign(
($T:ty) => (
impl NumAssign for $T {
#[inline(always)] fn add_assign(&mut self, other: &$T) { *self += *other }
#[inline(always)] fn sub_assign(&mut self, other: &$T) { *self -= *other }
#[inline(always)] fn mul_assign(&mut self, other: &$T) { *self *= *other }
#[inline(always)] fn div_assign(&mut self, other: &$T) { *self /= *other }
#[inline(always)] fn rem_assign(&mut self, other: &$T) { *self %= *other }
}
)
)
impl_NumAssign!(float)
impl_NumAssign!(f32)
impl_NumAssign!(f64)
impl_NumAssign!(int)
impl_NumAssign!(i8)
impl_NumAssign!(i16)
impl_NumAssign!(i32)
impl_NumAssign!(i64)
impl_NumAssign!(uint)
impl_NumAssign!(u8)
impl_NumAssign!(u16)
impl_NumAssign!(u32)
impl_NumAssign!(u64)

View file

@ -13,99 +13,94 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use std::num::cast; use std::num::{Zero, One};
use mat::{Mat4, BaseMat4}; use mat::Mat4;
use num::NumAssign;
/** // FIXME: We can remove this once we have numeric conversions in std
* Create a perspective projection matrix
*
* Note: the fovy parameter should be specified in degrees.
*
* This is the equivalent of the gluPerspective function, the algorithm of which
* can be found [here](http://www.opengl.org/wiki/GluPerspective_code).
*/
#[inline(always)] #[inline(always)]
pub fn perspective<T:Copy + Float + NumAssign>(fovy: T, aspectRatio: T, near: T, far: T) -> Mat4<T> { priv fn two<T:Num>() -> T {
let _2: T = cast(2); One::one::<T>() + One::one::<T>()
}
let ymax = near * (fovy / _2).to_radians().tan(); ///
/// Create a perspective projection matrix
///
/// Note: the fovy parameter should be specified in degrees.
///
/// This is the equivalent of the gluPerspective function, the algorithm of which
/// can be found [here](http://www.opengl.org/wiki/GluPerspective_code).
///
#[inline(always)]
pub fn perspective<T:Copy + Real>(fovy: T, aspectRatio: T, near: T, far: T) -> Mat4<T> {
let ymax = near * (fovy / two::<T>()).to_radians().tan();
let xmax = ymax * aspectRatio; let xmax = ymax * aspectRatio;
frustum(-xmax, xmax, -ymax, ymax, near, far) frustum(-xmax, xmax, -ymax, ymax, near, far)
} }
/** ///
* Define a view frustrum /// Define a view frustrum
* ///
* This is the equivalent of the now deprecated [glFrustrum] /// This is the equivalent of the now deprecated [glFrustrum]
* (http://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml) function. /// (http://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml) function.
*/ ///
#[inline(always)] #[inline(always)]
pub fn frustum<T:Copy + Float + NumAssign>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> { pub fn frustum<T:Copy + Real>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> {
let _0: T = cast(0); let c0r0 = (two::<T>() * near) / (right - left);
let _1: T = cast(1); let c0r1 = Zero::zero();
let _2: T = cast(2); let c0r2 = Zero::zero();
let c0r3 = Zero::zero();
let c0r0 = (_2 * near) / (right - left); let c1r0 = Zero::zero();
let c0r1 = _0; let c1r1 = (two::<T>() * near) / (top - bottom);
let c0r2 = _0; let c1r2 = Zero::zero();
let c0r3 = _0; let c1r3 = Zero::zero();
let c1r0 = _0;
let c1r1 = (_2 * near) / (top - bottom);
let c1r2 = _0;
let c1r3 = _0;
let c2r0 = (right + left) / (right - left); let c2r0 = (right + left) / (right - left);
let c2r1 = (top + bottom) / (top - bottom); let c2r1 = (top + bottom) / (top - bottom);
let c2r2 = -(far + near) / (far - near); let c2r2 = -(far + near) / (far - near);
let c2r3 = -_1; let c2r3 = -One::one::<T>();
let c3r0 = _0; let c3r0 = Zero::zero();
let c3r1 = _0; let c3r1 = Zero::zero();
let c3r2 = -(_2 * far * near) / (far - near); let c3r2 = -(two::<T>() * far * near) / (far - near);
let c3r3 = _0; let c3r3 = Zero::zero();
BaseMat4::new(c0r0, c0r1, c0r2, c0r3, Mat4::new(c0r0, c0r1, c0r2, c0r3,
c1r0, c1r1, c1r2, c1r3, c1r0, c1r1, c1r2, c1r3,
c2r0, c2r1, c2r2, c2r3, c2r0, c2r1, c2r2, c2r3,
c3r0, c3r1, c3r2, c3r3) c3r0, c3r1, c3r2, c3r3)
} }
/** ///
* Create an orthographic projection matrix /// Create an orthographic projection matrix
* ///
* This is the equivalent of the now deprecated [glOrtho] /// This is the equivalent of the now deprecated [glOrtho]
* (http://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml) function. /// (http://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml) function.
*/ ///
#[inline(always)] #[inline(always)]
pub fn ortho<T:Copy + Float + NumAssign>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> { pub fn ortho<T:Copy + Real>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> {
let _0: T = cast(0); let c0r0 = two::<T>() / (right - left);
let _1: T = cast(1); let c0r1 = Zero::zero();
let _2: T = cast(2); let c0r2 = Zero::zero();
let c0r3 = Zero::zero();
let c0r0 = _2 / (right - left); let c1r0 = Zero::zero();
let c0r1 = _0; let c1r1 = two::<T>() / (top - bottom);
let c0r2 = _0; let c1r2 = Zero::zero();
let c0r3 = _0; let c1r3 = Zero::zero();
let c1r0 = _0; let c2r0 = Zero::zero();
let c1r1 = _2 / (top - bottom); let c2r1 = Zero::zero();
let c1r2 = _0; let c2r2 = -two::<T>() / (far - near);
let c1r3 = _0; let c2r3 = Zero::zero();
let c2r0 = _0;
let c2r1 = _0;
let c2r2 = -_2 / (far - near);
let c2r3 = _0;
let c3r0 = -(right + left) / (right - left); let c3r0 = -(right + left) / (right - left);
let c3r1 = -(top + bottom) / (top - bottom); let c3r1 = -(top + bottom) / (top - bottom);
let c3r2 = -(far + near) / (far - near); let c3r2 = -(far + near) / (far - near);
let c3r3 = _1; let c3r3 = One::one();
BaseMat4::new(c0r0, c0r1, c0r2, c0r3, Mat4::new(c0r0, c0r1, c0r2, c0r3,
c1r0, c1r1, c1r2, c1r3, c1r0, c1r1, c1r2, c1r3,
c2r0, c2r1, c2r2, c2r3, c2r0, c2r1, c2r2, c2r3,
c3r0, c3r1, c3r2, c3r3) c3r0, c3r1, c3r2, c3r3)

View file

@ -17,10 +17,14 @@ use std::cast::transmute;
use std::cmp::ApproxEq; use std::cmp::ApproxEq;
use std::num::{Zero, One, cast}; use std::num::{Zero, One, cast};
use mat::{Mat3, BaseMat3}; use mat::Mat3;
use vec::{Vec3, BaseVec3, AffineVec, NumVec, NumVec3}; use vec::Vec3;
use num::NumAssign; // FIXME: We can remove this once we have numeric conversions in std
#[inline(always)]
priv fn two<T:Num>() -> T {
One::one::<T>() + One::one::<T>()
}
/// A quaternion in scalar/vector form /// A quaternion in scalar/vector form
/// ///
@ -35,7 +39,29 @@ use num::NumAssign;
#[deriving(Eq)] #[deriving(Eq)]
pub struct Quat<T> { s: T, v: Vec3<T> } pub struct Quat<T> { s: T, v: Vec3<T> }
pub impl<T:Copy + Float + NumAssign> Quat<T> { impl<T> Quat<T> {
#[inline(always)]
pub fn index<'a>(&'a self, i: uint) -> &'a T {
&'a self.as_slice()[i]
}
#[inline(always)]
pub fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
&'a mut self.as_mut_slice()[i]
}
#[inline(always)]
pub fn as_slice<'a>(&'a self) -> &'a [T,..4] {
unsafe { transmute(self) }
}
#[inline(always)]
pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T,..4] {
unsafe { transmute(self) }
}
}
impl<T:Copy> Quat<T> {
/// Construct the quaternion from one scalar component and three /// Construct the quaternion from one scalar component and three
/// imaginary components /// imaginary components
/// ///
@ -46,8 +72,8 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
/// - `yj`: the second imaginary component /// - `yj`: the second imaginary component
/// - `zk`: the third imaginary component /// - `zk`: the third imaginary component
#[inline(always)] #[inline(always)]
fn new(w: T, xi: T, yj: T, zk: T) -> Quat<T> { pub fn new(w: T, xi: T, yj: T, zk: T) -> Quat<T> {
Quat::from_sv(w, BaseVec3::new(xi, yj, zk)) Quat::from_sv(w, Vec3::new(xi, yj, zk))
} }
/// Construct the quaternion from a scalar and a vector /// Construct the quaternion from a scalar and a vector
@ -57,13 +83,30 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
/// - `s`: the scalar component /// - `s`: the scalar component
/// - `v`: a vector containing the three imaginary components /// - `v`: a vector containing the three imaginary components
#[inline(always)] #[inline(always)]
fn from_sv(s: T, v: Vec3<T>) -> Quat<T> { pub fn from_sv(s: T, v: Vec3<T>) -> Quat<T> {
Quat { s: s, v: v } Quat { s: s, v: v }
} }
#[inline(always)]
pub fn swap(&mut self, a: uint, b: uint) {
let tmp = *self.index(a);
*self.index_mut(a) = *self.index(b);
*self.index_mut(b) = tmp;
}
#[inline(always)]
pub fn map(&self, f: &fn(&T) -> T) -> Quat<T> {
Quat::new(f(self.index(0)),
f(self.index(1)),
f(self.index(2)),
f(self.index(3)))
}
}
impl<T:Copy + Real> Quat<T> {
/// The multiplicative identity, ie: `q = 1 + 0i + 0j + 0i` /// The multiplicative identity, ie: `q = 1 + 0i + 0j + 0i`
#[inline(always)] #[inline(always)]
fn identity() -> Quat<T> { pub fn identity() -> Quat<T> {
Quat::new(One::one(), Quat::new(One::one(),
Zero::zero(), Zero::zero(),
Zero::zero(), Zero::zero(),
@ -72,7 +115,7 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
/// The additive identity, ie: `q = 0 + 0i + 0j + 0i` /// The additive identity, ie: `q = 0 + 0i + 0j + 0i`
#[inline(always)] #[inline(always)]
fn zero() -> Quat<T> { pub fn zero() -> Quat<T> {
Quat::new(Zero::zero(), Quat::new(Zero::zero(),
Zero::zero(), Zero::zero(),
Zero::zero(), Zero::zero(),
@ -80,39 +123,35 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
} }
#[inline(always)] #[inline(always)]
fn from_angle_x(radians: T) -> Quat<T> { pub fn from_angle_x(radians: T) -> Quat<T> {
let _2 = cast(2); Quat::new((radians / two()).cos(),
Quat::new((radians / _2).cos(),
radians.sin(), radians.sin(),
Zero::zero(), Zero::zero(),
Zero::zero()) Zero::zero())
} }
#[inline(always)] #[inline(always)]
fn from_angle_y(radians: T) -> Quat<T> { pub fn from_angle_y(radians: T) -> Quat<T> {
let _2 = cast(2); Quat::new((radians / two()).cos(),
Quat::new((radians / _2).cos(),
Zero::zero(), Zero::zero(),
radians.sin(), radians.sin(),
Zero::zero()) Zero::zero())
} }
#[inline(always)] #[inline(always)]
fn from_angle_z(radians: T) -> Quat<T> { pub fn from_angle_z(radians: T) -> Quat<T> {
let _2 = cast(2); Quat::new((radians / two()).cos(),
Quat::new((radians / _2).cos(),
Zero::zero(), Zero::zero(),
Zero::zero(), Zero::zero(),
radians.sin()) radians.sin())
} }
#[inline(always)] #[inline(always)]
fn from_angle_xyz(radians_x: T, radians_y: T, radians_z: T) -> Quat<T> { pub fn from_angle_xyz(radians_x: T, radians_y: T, radians_z: T) -> Quat<T> {
// http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles#Conversion // http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles#Conversion
let _2 = cast(2); let xdiv2 = radians_x / two();
let xdiv2 = radians_x / _2; let ydiv2 = radians_y / two();
let ydiv2 = radians_y / _2; let zdiv2 = radians_z / two();
let zdiv2 = radians_z / _2;
Quat::new(zdiv2.cos() * xdiv2.cos() * ydiv2.cos() + zdiv2.sin() * xdiv2.sin() * ydiv2.sin(), Quat::new(zdiv2.cos() * xdiv2.cos() * ydiv2.cos() + zdiv2.sin() * xdiv2.sin() * ydiv2.sin(),
zdiv2.sin() * xdiv2.cos() * ydiv2.cos() - zdiv2.cos() * xdiv2.sin() * ydiv2.sin(), zdiv2.sin() * xdiv2.cos() * ydiv2.cos() - zdiv2.cos() * xdiv2.sin() * ydiv2.sin(),
zdiv2.cos() * xdiv2.sin() * ydiv2.cos() + zdiv2.sin() * xdiv2.cos() * ydiv2.sin(), zdiv2.cos() * xdiv2.sin() * ydiv2.cos() + zdiv2.sin() * xdiv2.cos() * ydiv2.sin(),
@ -120,38 +159,18 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
} }
#[inline(always)] #[inline(always)]
fn from_angle_axis(radians: T, axis: &Vec3<T>) -> Quat<T> { pub fn from_angle_axis(radians: T, axis: &Vec3<T>) -> Quat<T> {
let half = radians / cast(2); let half = radians / two();
Quat::from_sv(half.cos(), axis.mul_t(half.sin())) Quat::from_sv(half.cos(), axis.mul_t(half.sin()))
} }
#[inline(always)] pub fn get_angle_axis(&self) -> (T, Vec3<T>) {
fn from_axes(x: Vec3<T>, y: Vec3<T>, z: Vec3<T>) -> Quat<T> {
let m: Mat3<T> = BaseMat3::from_axes(x, y, z); m.to_quat()
}
#[inline(always)]
fn index<'a>(&'a self, i: uint) -> &'a T {
unsafe { &'a transmute::<&'a Quat<T>, &'a [T,..4]>(self)[i] }
}
#[inline(always)]
fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
unsafe { &'a mut transmute::< &'a mut Quat<T>, &'a mut [T,..4]>(self)[i] }
}
fn get_angle_axis(&self) -> (T, Vec3<T>) {
fail!(~"Not yet implemented.") fail!(~"Not yet implemented.")
} }
#[inline(always)]
fn look_at(dir: &Vec3<T>, up: &Vec3<T>) -> Quat<T> {
let m: Mat3<T> = BaseMat3::look_at(dir, up); m.to_quat()
}
/// The result of multiplying the quaternion a scalar /// The result of multiplying the quaternion a scalar
#[inline(always)] #[inline(always)]
fn mul_t(&self, value: T) -> Quat<T> { pub fn mul_t(&self, value: T) -> Quat<T> {
Quat::new(*self.index(0) * value, Quat::new(*self.index(0) * value,
*self.index(1) * value, *self.index(1) * value,
*self.index(2) * value, *self.index(2) * value,
@ -160,7 +179,7 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
/// The result of dividing the quaternion a scalar /// The result of dividing the quaternion a scalar
#[inline(always)] #[inline(always)]
fn div_t(&self, value: T) -> Quat<T> { pub fn div_t(&self, value: T) -> Quat<T> {
Quat::new(*self.index(0) / value, Quat::new(*self.index(0) / value,
*self.index(1) / value, *self.index(1) / value,
*self.index(2) / value, *self.index(2) / value,
@ -169,14 +188,14 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
/// The result of multiplying the quaternion by a vector /// The result of multiplying the quaternion by a vector
#[inline(always)] #[inline(always)]
fn mul_v(&self, vec: &Vec3<T>) -> Vec3<T> { pub fn mul_v(&self, vec: &Vec3<T>) -> Vec3<T> {
let tmp = self.v.cross(vec).add_v(&vec.mul_t(self.s)); let tmp = self.v.cross(vec).add_v(&vec.mul_t(self.s));
self.v.cross(&tmp).mul_t(cast(2)).add_v(vec) self.v.cross(&tmp).mul_t(two()).add_v(vec)
} }
/// The sum of this quaternion and `other` /// The sum of this quaternion and `other`
#[inline(always)] #[inline(always)]
fn add_q(&self, other: &Quat<T>) -> Quat<T> { pub fn add_q(&self, other: &Quat<T>) -> Quat<T> {
Quat::new(*self.index(0) + *other.index(0), Quat::new(*self.index(0) + *other.index(0),
*self.index(1) + *other.index(1), *self.index(1) + *other.index(1),
*self.index(2) + *other.index(2), *self.index(2) + *other.index(2),
@ -185,7 +204,7 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
/// The sum of this quaternion and `other` /// The sum of this quaternion and `other`
#[inline(always)] #[inline(always)]
fn sub_q(&self, other: &Quat<T>) -> Quat<T> { pub fn sub_q(&self, other: &Quat<T>) -> Quat<T> {
Quat::new(*self.index(0) - *other.index(0), Quat::new(*self.index(0) - *other.index(0),
*self.index(1) - *other.index(1), *self.index(1) - *other.index(1),
*self.index(2) - *other.index(2), *self.index(2) - *other.index(2),
@ -194,7 +213,7 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
/// The the result of multipliplying the quaternion by `other` /// The the result of multipliplying the quaternion by `other`
#[inline(always)] #[inline(always)]
fn mul_q(&self, other: &Quat<T>) -> Quat<T> { pub fn mul_q(&self, other: &Quat<T>) -> Quat<T> {
Quat::new(self.s * other.s - self.v.x * other.v.x - self.v.y * other.v.y - self.v.z * other.v.z, Quat::new(self.s * other.s - self.v.x * other.v.x - self.v.y * other.v.y - self.v.z * other.v.z,
self.s * other.v.x + self.v.x * other.s + self.v.y * other.v.z - self.v.z * other.v.y, self.s * other.v.x + self.v.x * other.s + self.v.y * other.v.z - self.v.z * other.v.y,
self.s * other.v.y + self.v.y * other.s + self.v.z * other.v.x - self.v.x * other.v.z, self.s * other.v.y + self.v.y * other.s + self.v.z * other.v.x - self.v.x * other.v.z,
@ -203,19 +222,19 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
/// The dot product of the quaternion and `other` /// The dot product of the quaternion and `other`
#[inline(always)] #[inline(always)]
fn dot(&self, other: &Quat<T>) -> T { pub fn dot(&self, other: &Quat<T>) -> T {
self.s * other.s + self.v.dot(&other.v) self.s * other.s + self.v.dot(&other.v)
} }
/// The conjugate of the quaternion /// The conjugate of the quaternion
#[inline(always)] #[inline(always)]
fn conjugate(&self) -> Quat<T> { pub fn conjugate(&self) -> Quat<T> {
Quat::from_sv(self.s, -self.v) Quat::from_sv(self.s, -self.v)
} }
/// The multiplicative inverse of the quaternion /// The multiplicative inverse of the quaternion
#[inline(always)] #[inline(always)]
fn inverse(&self) -> Quat<T> { pub fn inverse(&self) -> Quat<T> {
self.conjugate().div_t(self.magnitude2()) self.conjugate().div_t(self.magnitude2())
} }
@ -223,7 +242,7 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
/// magnitude comparisons where the exact magnitude does not need to be /// magnitude comparisons where the exact magnitude does not need to be
/// calculated. /// calculated.
#[inline(always)] #[inline(always)]
fn magnitude2(&self) -> T { pub fn magnitude2(&self) -> T {
self.s * self.s + self.v.length2() self.s * self.s + self.v.length2()
} }
@ -235,25 +254,73 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
/// to be known, for example for quaternion-quaternion magnitude comparisons, /// to be known, for example for quaternion-quaternion magnitude comparisons,
/// it is advisable to use the `magnitude2` method instead. /// it is advisable to use the `magnitude2` method instead.
#[inline(always)] #[inline(always)]
fn magnitude(&self) -> T { pub fn magnitude(&self) -> T {
self.magnitude2().sqrt() self.magnitude2().sqrt()
} }
/// The normalized quaternion /// The normalized quaternion
#[inline(always)] #[inline(always)]
fn normalize(&self) -> Quat<T> { pub fn normalize(&self) -> Quat<T> {
self.mul_t(One::one::<T>() / self.magnitude()) self.mul_t(One::one::<T>() / self.magnitude())
} }
/// Convert the quaternion to a 3 x 3 rotation matrix
#[inline(always)]
pub fn to_mat3(&self) -> Mat3<T> {
let x2 = self.v.x + self.v.x;
let y2 = self.v.y + self.v.y;
let z2 = self.v.z + self.v.z;
let xx2 = x2 * self.v.x;
let xy2 = x2 * self.v.y;
let xz2 = x2 * self.v.z;
let yy2 = y2 * self.v.y;
let yz2 = y2 * self.v.z;
let zz2 = z2 * self.v.z;
let sy2 = y2 * self.s;
let sz2 = z2 * self.s;
let sx2 = x2 * self.s;
let _1: T = One::one();
Mat3::new(_1 - yy2 - zz2, xy2 + sz2, xz2 - sy2,
xy2 - sz2, _1 - xx2 - zz2, yz2 + sx2,
xz2 + sy2, yz2 - sx2, _1 - xx2 - yy2)
}
/// Normalised linear interpolation /// Normalised linear interpolation
/// ///
/// # Return value /// # Return value
/// ///
/// The intoperlated quaternion /// The intoperlated quaternion
#[inline(always)] #[inline(always)]
fn nlerp(&self, other: &Quat<T>, amount: T) -> Quat<T> { pub fn nlerp(&self, other: &Quat<T>, amount: T) -> Quat<T> {
self.mul_t(One::one::<T>() - amount).add_q(&other.mul_t(amount)).normalize() self.mul_t(One::one::<T>() - amount).add_q(&other.mul_t(amount)).normalize()
} }
}
impl<T:Copy + Float> Neg<Quat<T>> for Quat<T> {
#[inline(always)]
pub fn neg(&self) -> Quat<T> {
Quat::new(-*self.index(0),
-*self.index(1),
-*self.index(2),
-*self.index(3))
}
}
impl<T:Copy + Float> Quat<T> {
#[inline(always)]
pub fn look_at(dir: &Vec3<T>, up: &Vec3<T>) -> Quat<T> {
Mat3::look_at(dir, up).to_quat()
}
#[inline(always)]
pub fn from_axes(x: Vec3<T>, y: Vec3<T>, z: Vec3<T>) -> Quat<T> {
Mat3::from_axes(x, y, z).to_quat()
}
/// Spherical Linear Intoperlation /// Spherical Linear Intoperlation
/// ///
@ -275,13 +342,12 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
/// - [Arcsynthesis OpenGL tutorial] /// - [Arcsynthesis OpenGL tutorial]
/// (http://www.arcsynthesis.org/gltut/Positioning/Tut08%20Interpolation.html) /// (http://www.arcsynthesis.org/gltut/Positioning/Tut08%20Interpolation.html)
#[inline(always)] #[inline(always)]
fn slerp(&self, other: &Quat<T>, amount: T) -> Quat<T> { pub fn slerp(&self, other: &Quat<T>, amount: T) -> Quat<T> {
let dot = self.dot(other); let dot = self.dot(other);
let dot_threshold = cast(0.9995); let dot_threshold = cast(0.9995);
if dot > dot_threshold { if dot > dot_threshold {
return self.nlerp(other, amount); // if quaternions are close together use `nlerp` self.nlerp(other, amount) // if quaternions are close together use `nlerp`
} else { } else {
let robust_dot = dot.clamp(&-One::one::<T>(), let robust_dot = dot.clamp(&-One::one::<T>(),
&One::one()); // stay within the domain of acos() &One::one()); // stay within the domain of acos()
@ -292,67 +358,25 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
let q = other.sub_q(&self.mul_t(robust_dot)) let q = other.sub_q(&self.mul_t(robust_dot))
.normalize(); .normalize();
return self.mul_t(theta.cos()) self.mul_t(theta.cos())
.add_q(&q.mul_t(theta.sin())); .add_q(&q.mul_t(theta.sin()))
}
} }
} }
/// A pointer to the first component of the quaternion impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Quat<T> {
#[inline(always)] #[inline(always)]
fn to_ptr(&self) -> *T { pub fn approx_epsilon() -> T {
unsafe { transmute(self) }
}
/// Convert the quaternion to a 3 x 3 rotation matrix
#[inline(always)]
fn to_mat3(&self) -> Mat3<T> {
let x2 = self.v.x + self.v.x;
let y2 = self.v.y + self.v.y;
let z2 = self.v.z + self.v.z;
let xx2 = x2 * self.v.x;
let xy2 = x2 * self.v.y;
let xz2 = x2 * self.v.z;
let yy2 = y2 * self.v.y;
let yz2 = y2 * self.v.z;
let zz2 = z2 * self.v.z;
let sy2 = y2 * self.s;
let sz2 = z2 * self.s;
let sx2 = x2 * self.s;
let _1: T = One::one();
BaseMat3::new(_1 - yy2 - zz2, xy2 + sz2, xz2 - sy2,
xy2 - sz2, _1 - xx2 - zz2, yz2 + sx2,
xz2 + sy2, yz2 - sx2, _1 - xx2 - yy2)
}
}
impl<T:Copy + Float + NumAssign> Neg<Quat<T>> for Quat<T> {
#[inline(always)]
fn neg(&self) -> Quat<T> {
Quat::new(-*self.index(0),
-*self.index(1),
-*self.index(2),
-*self.index(3))
}
}
impl<T:Copy + Eq + Float + NumAssign> ApproxEq<T> for Quat<T> {
#[inline(always)]
fn approx_epsilon() -> T {
ApproxEq::approx_epsilon::<T,T>() ApproxEq::approx_epsilon::<T,T>()
} }
#[inline(always)] #[inline(always)]
fn approx_eq(&self, other: &Quat<T>) -> bool { pub fn approx_eq(&self, other: &Quat<T>) -> bool {
self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<T,T>()) self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<T,T>())
} }
#[inline(always)] #[inline(always)]
fn approx_eq_eps(&self, other: &Quat<T>, epsilon: &T) -> bool { pub fn approx_eq_eps(&self, other: &Quat<T>, epsilon: &T) -> bool {
self.index(0).approx_eq_eps(other.index(0), epsilon) && self.index(0).approx_eq_eps(other.index(0), epsilon) &&
self.index(1).approx_eq_eps(other.index(1), epsilon) && self.index(1).approx_eq_eps(other.index(1), epsilon) &&
self.index(2).approx_eq_eps(other.index(2), epsilon) && self.index(2).approx_eq_eps(other.index(2), epsilon) &&
@ -360,12 +384,8 @@ impl<T:Copy + Eq + Float + NumAssign> ApproxEq<T> for Quat<T> {
} }
} }
// GLSL-style type aliases for quaternions. These are not present in the GLSL // GLSL-style type aliases
// specification, but they roughly follow the same nomenclature.
/// a single-precision floating-point quaternion
type quat = Quat<f32>; type quat = Quat<f32>;
/// a double-precision floating-point quaternion
type dquat = Quat<f64>; type dquat = Quat<f64>;
// Rust-style type aliases // Rust-style type aliases

View file

@ -16,8 +16,6 @@
use mat::*; use mat::*;
use vec::*; use vec::*;
// TODO
#[test] #[test]
fn test_mat2() { fn test_mat2() {
let a = Mat2 { x: Vec2 { x: 1.0, y: 3.0 }, let a = Mat2 { x: Vec2 { x: 1.0, y: 3.0 },
@ -25,62 +23,70 @@ fn test_mat2() {
let b = Mat2 { x: Vec2 { x: 2.0, y: 4.0 }, let b = Mat2 { x: Vec2 { x: 2.0, y: 4.0 },
y: Vec2 { x: 3.0, y: 5.0 } }; y: Vec2 { x: 3.0, y: 5.0 } };
let v1 = vec2::new(1.0, 2.0); let v1 = Vec2::new::<float>(1.0, 2.0);
let f1 = 0.5; let f1 = 0.5;
assert_eq!(a, mat2::new(1.0, 3.0, assert_eq!(a, Mat2::new::<float>(1.0, 3.0,
2.0, 4.0)); 2.0, 4.0));
assert_eq!(a, mat2::from_cols(vec2::new(1.0, 3.0), assert_eq!(a, Mat2::from_cols::<float>(Vec2::new::<float>(1.0, 3.0),
vec2::new(2.0, 4.0))); Vec2::new::<float>(2.0, 4.0)));
assert_eq!(mat2::from_value(4.0), mat2::new(4.0, 0.0, assert_eq!(Mat2::from_value::<float>(4.0),
Mat2::new::<float>(4.0, 0.0,
0.0, 4.0)); 0.0, 4.0));
assert_eq!(*a.col(0), vec2::new(1.0, 3.0)); assert_eq!(*a.col(0), Vec2::new::<float>(1.0, 3.0));
assert_eq!(*a.col(1), vec2::new(2.0, 4.0)); assert_eq!(*a.col(1), Vec2::new::<float>(2.0, 4.0));
assert_eq!(a.row(0), vec2::new(1.0, 2.0)); assert_eq!(a.row(0), Vec2::new::<float>(1.0, 2.0));
assert_eq!(a.row(1), vec2::new(3.0, 4.0)); assert_eq!(a.row(1), Vec2::new::<float>(3.0, 4.0));
assert_eq!(*a.col(0), vec2::new(1.0, 3.0)); assert_eq!(*a.col(0), Vec2::new::<float>(1.0, 3.0));
assert_eq!(*a.col(1), vec2::new(2.0, 4.0)); assert_eq!(*a.col(1), Vec2::new::<float>(2.0, 4.0));
assert_eq!(mat2::identity(), mat2::new(1.0, 0.0, assert_eq!(Mat2::identity::<float>(),
Mat2::new::<float>(1.0, 0.0,
0.0, 1.0)); 0.0, 1.0));
assert_eq!(mat2::zero(), mat2::new(0.0, 0.0, assert_eq!(Mat2::zero::<float>(),
Mat2::new::<float>(0.0, 0.0,
0.0, 0.0)); 0.0, 0.0));
assert_eq!(a.determinant(), -2.0); assert_eq!(a.determinant(), -2.0);
assert_eq!(a.trace(), 5.0); assert_eq!(a.trace(), 5.0);
assert_eq!(a.neg(), mat2::new(-1.0, -3.0, assert_eq!(a.neg(),
Mat2::new::<float>(-1.0, -3.0,
-2.0, -4.0)); -2.0, -4.0));
assert_eq!(-a, a.neg()); assert_eq!(-a, a.neg());
assert_eq!(a.mul_t(f1),
assert_eq!(a.mul_t(f1), mat2::new(0.5, 1.5, Mat2::new::<float>(0.5, 1.5,
1.0, 2.0)); 1.0, 2.0));
assert_eq!(a.mul_v(&v1), vec2::new(5.0, 11.0)); assert_eq!(a.mul_v(&v1), Vec2::new::<float>(5.0, 11.0));
assert_eq!(a.add_m(&b),
assert_eq!(a.add_m(&b), mat2::new(3.0, 7.0, Mat2::new::<float>(3.0, 7.0,
5.0, 9.0)); 5.0, 9.0));
assert_eq!(a.sub_m(&b), mat2::new(-1.0, -1.0, assert_eq!(a.sub_m(&b),
Mat2::new::<float>(-1.0, -1.0,
-1.0, -1.0)); -1.0, -1.0));
assert_eq!(a.mul_m(&b), mat2::new(10.0, 22.0, assert_eq!(a.mul_m(&b),
Mat2::new::<float>(10.0, 22.0,
13.0, 29.0)); 13.0, 29.0));
assert_eq!(a.dot(&b), 40.0); assert_eq!(a.dot(&b), 40.0);
assert_eq!(a.transpose(), mat2::new(1.0, 2.0, assert_eq!(a.transpose(),
Mat2::new::<float>(1.0, 2.0,
3.0, 4.0)); 3.0, 4.0));
assert_eq!(a.inverse().unwrap(), mat2::new(-2.0, 1.5, assert_eq!(a.inverse().unwrap(),
Mat2::new::<float>(-2.0, 1.5,
1.0, -0.5)); 1.0, -0.5));
assert!(mat2::new(0.0, 2.0, assert!(Mat2::new::<float>(0.0, 2.0,
0.0, 5.0).inverse().is_none()); 0.0, 5.0).inverse().is_none());
let ident = mat2::identity(); let ident = Mat2::identity::<float>();
assert!(ident.is_identity()); assert!(ident.is_identity());
assert!(ident.is_symmetric()); assert!(ident.is_symmetric());
@ -94,7 +100,7 @@ fn test_mat2() {
assert!(a.is_rotated()); assert!(a.is_rotated());
assert!(a.is_invertible()); assert!(a.is_invertible());
let c = mat2::new(2.0, 1.0, let c = Mat2::new::<float>(2.0, 1.0,
1.0, 2.0); 1.0, 2.0);
assert!(!c.is_identity()); assert!(!c.is_identity());
assert!(c.is_symmetric()); assert!(c.is_symmetric());
@ -102,13 +108,15 @@ fn test_mat2() {
assert!(c.is_rotated()); assert!(c.is_rotated());
assert!(c.is_invertible()); assert!(c.is_invertible());
assert!(mat2::from_value(6.0).is_diagonal()); assert!(Mat2::from_value::<float>(6.0).is_diagonal());
assert_eq!(a.to_mat3(), mat3::new(1.0, 3.0, 0.0, assert_eq!(a.to_mat3(),
Mat3::new::<float>(1.0, 3.0, 0.0,
2.0, 4.0, 0.0, 2.0, 4.0, 0.0,
0.0, 0.0, 1.0)); 0.0, 0.0, 1.0));
assert_eq!(a.to_mat4(), mat4::new(1.0, 3.0, 0.0, 0.0, assert_eq!(a.to_mat4(),
Mat4::new::<float>(1.0, 3.0, 0.0, 0.0,
2.0, 4.0, 0.0, 0.0, 2.0, 4.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0)); 0.0, 0.0, 0.0, 1.0));
@ -122,7 +130,7 @@ fn test_mat2_mut() {
let f1 = 0.5; let f1 = 0.5;
let mut mut_a: mat2 = a; let mut mut_a = a;
mut_a.swap_cols(0, 1); mut_a.swap_cols(0, 1);
assert_eq!(mut_a.col(0), a.col(1)); assert_eq!(mut_a.col(0), a.col(1));
@ -134,16 +142,12 @@ fn test_mat2_mut() {
assert_eq!(mut_a.row(1), a.row(0)); assert_eq!(mut_a.row(1), a.row(0));
mut_a = a; mut_a = a;
mut_a.set(&b);
assert_eq!(mut_a, b);
mut_a = a;
mut_a.to_identity(); mut_a.to_identity();
assert!(mut_a.is_identity()); assert!(mut_a.is_identity());
mut_a = a; mut_a = a;
mut_a.to_zero(); mut_a.to_zero();
assert_eq!(mut_a, mat2::zero()); assert_eq!(mut_a, Mat2::zero::<float>());
mut_a = a; mut_a = a;
mut_a.mul_self_t(f1); mut_a.mul_self_t(f1);
@ -169,10 +173,10 @@ fn test_mat2_mut() {
#[test] #[test]
fn test_mat2_approx_eq() { fn test_mat2_approx_eq() {
assert!(!mat2::new(0.000001, 0.000001, assert!(!Mat2::new::<float>(0.000001, 0.000001,
0.000001, 0.000001).approx_eq(&mat2::zero())); 0.000001, 0.000001).approx_eq(&Mat2::zero::<float>()));
assert!(mat2::new(0.0000001, 0.0000001, assert!(Mat2::new::<float>(0.0000001, 0.0000001,
0.0000001, 0.0000001).approx_eq(&mat2::zero())); 0.0000001, 0.0000001).approx_eq(&Mat2::zero::<float>()));
} }
#[test] #[test]
@ -184,75 +188,83 @@ fn test_mat3() {
y: Vec3 { x: 3.0, y: 6.0, z: 9.0 }, y: Vec3 { x: 3.0, y: 6.0, z: 9.0 },
z: Vec3 { x: 4.0, y: 7.0, z: 10.0 } }; z: Vec3 { x: 4.0, y: 7.0, z: 10.0 } };
let v1 = vec3::new(1.0, 2.0, 3.0); let v1 = Vec3::new::<float>(1.0, 2.0, 3.0);
let f1 = 0.5; let f1 = 0.5;
assert_eq!(a, mat3::new(1.0, 4.0, 7.0, assert_eq!(a, Mat3::new::<float>(1.0, 4.0, 7.0,
2.0, 5.0, 8.0, 2.0, 5.0, 8.0,
3.0, 6.0, 9.0)); 3.0, 6.0, 9.0));
assert_eq!(a, mat3::from_cols(vec3::new(1.0, 4.0, 7.0), assert_eq!(a, Mat3::from_cols::<float>(Vec3::new::<float>(1.0, 4.0, 7.0),
vec3::new(2.0, 5.0, 8.0), Vec3::new::<float>(2.0, 5.0, 8.0),
vec3::new(3.0, 6.0, 9.0))); Vec3::new::<float>(3.0, 6.0, 9.0)));
assert_eq!(*a.col(0), vec3::new(1.0, 4.0, 7.0)); assert_eq!(*a.col(0), Vec3::new::<float>(1.0, 4.0, 7.0));
assert_eq!(*a.col(1), vec3::new(2.0, 5.0, 8.0)); assert_eq!(*a.col(1), Vec3::new::<float>(2.0, 5.0, 8.0));
assert_eq!(*a.col(2), vec3::new(3.0, 6.0, 9.0)); assert_eq!(*a.col(2), Vec3::new::<float>(3.0, 6.0, 9.0));
assert_eq!(a.row(0), vec3::new(1.0, 2.0, 3.0)); assert_eq!(a.row(0), Vec3::new::<float>(1.0, 2.0, 3.0));
assert_eq!(a.row(1), vec3::new(4.0, 5.0, 6.0)); assert_eq!(a.row(1), Vec3::new::<float>(4.0, 5.0, 6.0));
assert_eq!(a.row(2), vec3::new(7.0, 8.0, 9.0)); assert_eq!(a.row(2), Vec3::new::<float>(7.0, 8.0, 9.0));
assert_eq!(*a.col(0), vec3::new(1.0, 4.0, 7.0)); assert_eq!(*a.col(0), Vec3::new::<float>(1.0, 4.0, 7.0));
assert_eq!(*a.col(1), vec3::new(2.0, 5.0, 8.0)); assert_eq!(*a.col(1), Vec3::new::<float>(2.0, 5.0, 8.0));
assert_eq!(*a.col(2), vec3::new(3.0, 6.0, 9.0)); assert_eq!(*a.col(2), Vec3::new::<float>(3.0, 6.0, 9.0));
assert_eq!(mat3::identity(), mat3::new(1.0, 0.0, 0.0, assert_eq!(Mat3::identity::<float>(),
Mat3::new::<float>(1.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 1.0)); 0.0, 0.0, 1.0));
assert_eq!(mat3::zero(), mat3::new(0.0, 0.0, 0.0, assert_eq!(Mat3::zero::<float>(),
Mat3::new::<float>(0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0)); 0.0, 0.0, 0.0));
assert_eq!(a.determinant(), 0.0); assert_eq!(a.determinant(), 0.0);
assert_eq!(a.trace(), 15.0); assert_eq!(a.trace(), 15.0);
assert_eq!(a.neg(), mat3::new(-1.0, -4.0, -7.0, assert_eq!(a.neg(),
Mat3::new::<float>(-1.0, -4.0, -7.0,
-2.0, -5.0, -8.0, -2.0, -5.0, -8.0,
-3.0, -6.0, -9.0)); -3.0, -6.0, -9.0));
assert_eq!(-a, a.neg()); assert_eq!(-a, a.neg());
assert_eq!(a.mul_t(f1), mat3::new(0.5, 2.0, 3.5, assert_eq!(a.mul_t(f1),
Mat3::new::<float>(0.5, 2.0, 3.5,
1.0, 2.5, 4.0, 1.0, 2.5, 4.0,
1.5, 3.0, 4.5)); 1.5, 3.0, 4.5));
assert_eq!(a.mul_v(&v1), vec3::new(14.0, 32.0, 50.0)); assert_eq!(a.mul_v(&v1), Vec3::new::<float>(14.0, 32.0, 50.0));
assert_eq!(a.add_m(&b), mat3::new(3.0, 9.0, 15.0, assert_eq!(a.add_m(&b),
Mat3::new::<float>(3.0, 9.0, 15.0,
5.0, 11.0, 17.0, 5.0, 11.0, 17.0,
7.0, 13.0, 19.0)); 7.0, 13.0, 19.0));
assert_eq!(a.sub_m(&b), mat3::new(-1.0, -1.0, -1.0, assert_eq!(a.sub_m(&b),
Mat3::new::<float>(-1.0, -1.0, -1.0,
-1.0, -1.0, -1.0, -1.0, -1.0, -1.0,
-1.0, -1.0, -1.0)); -1.0, -1.0, -1.0));
assert_eq!(a.mul_m(&b), mat3::new(36.0, 81.0, 126.0, assert_eq!(a.mul_m(&b),
Mat3::new::<float>(36.0, 81.0, 126.0,
42.0, 96.0, 150.0, 42.0, 96.0, 150.0,
48.0, 111.0, 174.0)); 48.0, 111.0, 174.0));
assert_eq!(a.dot(&b), 330.0); assert_eq!(a.dot(&b), 330.0);
assert_eq!(a.transpose(), mat3::new(1.0, 2.0, 3.0, assert_eq!(a.transpose(),
Mat3::new::<float>(1.0, 2.0, 3.0,
4.0, 5.0, 6.0, 4.0, 5.0, 6.0,
7.0, 8.0, 9.0)); 7.0, 8.0, 9.0));
assert!(a.inverse().is_none()); assert!(a.inverse().is_none());
assert_eq!(mat3::new(2.0, 4.0, 6.0, assert_eq!(Mat3::new::<float>(2.0, 4.0, 6.0,
0.0, 2.0, 4.0, 0.0, 2.0, 4.0,
0.0, 0.0, 1.0).inverse().unwrap(), 0.0, 0.0, 1.0).inverse().unwrap(),
mat3::new(0.5, -1.0, 1.0, Mat3::new::<float>(0.5, -1.0, 1.0,
0.0, 0.5, -2.0, 0.0, 0.5, -2.0,
0.0, 0.0, 1.0)); 0.0, 0.0, 1.0));
let ident: Mat3<float> = BaseMat::identity(); let ident = Mat3::identity::<float>();
assert_eq!(ident.inverse().unwrap(), ident); assert_eq!(ident.inverse().unwrap(), ident);
@ -268,7 +280,7 @@ fn test_mat3() {
assert!(a.is_rotated()); assert!(a.is_rotated());
assert!(!a.is_invertible()); assert!(!a.is_invertible());
let c = mat3::new(3.0, 2.0, 1.0, let c = Mat3::new::<float>(3.0, 2.0, 1.0,
2.0, 3.0, 2.0, 2.0, 3.0, 2.0,
1.0, 2.0, 3.0); 1.0, 2.0, 3.0);
assert!(!c.is_identity()); assert!(!c.is_identity());
@ -277,9 +289,10 @@ fn test_mat3() {
assert!(c.is_rotated()); assert!(c.is_rotated());
assert!(c.is_invertible()); assert!(c.is_invertible());
assert!(mat3::from_value(6.0).is_diagonal()); assert!(Mat3::from_value::<float>(6.0).is_diagonal());
assert_eq!(a.to_mat4(), mat4::new(1.0, 4.0, 7.0, 0.0, assert_eq!(a.to_mat4(),
Mat4::new::<float>(1.0, 4.0, 7.0, 0.0,
2.0, 5.0, 8.0, 0.0, 2.0, 5.0, 8.0, 0.0,
3.0, 6.0, 9.0, 0.0, 3.0, 6.0, 9.0, 0.0,
0.0, 0.0, 0.0, 1.0)); 0.0, 0.0, 0.0, 1.0));
@ -300,8 +313,8 @@ fn test_mat3_mut() {
let f1 = 0.5; let f1 = 0.5;
let mut mut_a: mat3 = a; let mut mut_a = a;
let mut mut_c: mat3 = c; let mut mut_c = c;
mut_a.swap_cols(0, 2); mut_a.swap_cols(0, 2);
assert_eq!(mut_a.col(0), a.col(2)); assert_eq!(mut_a.col(0), a.col(2));
@ -323,16 +336,12 @@ fn test_mat3_mut() {
assert_eq!(mut_a.row(2), a.row(1)); assert_eq!(mut_a.row(2), a.row(1));
mut_a = a; mut_a = a;
mut_a.set(&b);
assert_eq!(mut_a, b);
mut_a = a;
mut_a.to_identity(); mut_a.to_identity();
assert!(mut_a.is_identity()); assert!(mut_a.is_identity());
mut_a = a; mut_a = a;
mut_a.to_zero(); mut_a.to_zero();
assert_eq!(mut_a, mat3::zero()); assert_eq!(mut_a, Mat3::zero::<float>());
mut_a = a; mut_a = a;
mut_a.mul_self_t(f1); mut_a.mul_self_t(f1);
@ -358,68 +367,73 @@ fn test_mat3_mut() {
#[test] #[test]
fn test_mat3_approx_eq() { fn test_mat3_approx_eq() {
assert!(!mat3::new(0.000001, 0.000001, 0.000001, assert!(!Mat3::new::<float>(0.000001, 0.000001, 0.000001,
0.000001, 0.000001, 0.000001, 0.000001, 0.000001, 0.000001,
0.000001, 0.000001, 0.000001).approx_eq(&mat3::zero())); 0.000001, 0.000001, 0.000001)
assert!(mat3::new(0.0000001, 0.0000001, 0.0000001, .approx_eq(&Mat3::zero::<float>()));
assert!(Mat3::new::<float>(0.0000001, 0.0000001, 0.0000001,
0.0000001, 0.0000001, 0.0000001, 0.0000001, 0.0000001, 0.0000001,
0.0000001, 0.0000001, 0.0000001).approx_eq(&mat3::zero())); 0.0000001, 0.0000001, 0.0000001)
.approx_eq(&Mat3::zero::<float>()));
} }
#[test] #[test]
fn test_mat4() { fn test_mat4() {
let a: mat4 = Mat4 { x: Vec4 { x: 1.0, y: 5.0, z: 9.0, w: 13.0 }, let a = Mat4 { x: Vec4 { x: 1.0, y: 5.0, z: 9.0, w: 13.0 },
y: Vec4 { x: 2.0, y: 6.0, z: 10.0, w: 14.0 }, y: Vec4 { x: 2.0, y: 6.0, z: 10.0, w: 14.0 },
z: Vec4 { x: 3.0, y: 7.0, z: 11.0, w: 15.0 }, z: Vec4 { x: 3.0, y: 7.0, z: 11.0, w: 15.0 },
w: Vec4 { x: 4.0, y: 8.0, z: 12.0, w: 16.0 } }; w: Vec4 { x: 4.0, y: 8.0, z: 12.0, w: 16.0 } };
let b: mat4 = Mat4 { x: Vec4 { x: 2.0, y: 6.0, z: 10.0, w: 14.0 }, let b = Mat4 { x: Vec4 { x: 2.0, y: 6.0, z: 10.0, w: 14.0 },
y: Vec4 { x: 3.0, y: 7.0, z: 11.0, w: 15.0 }, y: Vec4 { x: 3.0, y: 7.0, z: 11.0, w: 15.0 },
z: Vec4 { x: 4.0, y: 8.0, z: 12.0, w: 16.0 }, z: Vec4 { x: 4.0, y: 8.0, z: 12.0, w: 16.0 },
w: Vec4 { x: 5.0, y: 9.0, z: 13.0, w: 17.0 } }; w: Vec4 { x: 5.0, y: 9.0, z: 13.0, w: 17.0 } };
let c: mat4 = Mat4 { x: Vec4 { x: 3.0, y: 2.0, z: 1.0, w: 1.0 }, let c = Mat4 { x: Vec4 { x: 3.0, y: 2.0, z: 1.0, w: 1.0 },
y: Vec4 { x: 2.0, y: 3.0, z: 2.0, w: 2.0 }, y: Vec4 { x: 2.0, y: 3.0, z: 2.0, w: 2.0 },
z: Vec4 { x: 1.0, y: 2.0, z: 3.0, w: 3.0 }, z: Vec4 { x: 1.0, y: 2.0, z: 3.0, w: 3.0 },
w: Vec4 { x: 0.0, y: 1.0, z: 1.0, w: 0.0 } }; w: Vec4 { x: 0.0, y: 1.0, z: 1.0, w: 0.0 } };
let v1 = vec4::new(1.0, 2.0, 3.0, 4.0); let v1 = Vec4::new::<float>(1.0, 2.0, 3.0, 4.0);
let f1 = 0.5; let f1 = 0.5;
assert_eq!(a, mat4::new(1.0, 5.0, 9.0, 13.0, assert_eq!(a, Mat4::new::<float>(1.0, 5.0, 9.0, 13.0,
2.0, 6.0, 10.0, 14.0, 2.0, 6.0, 10.0, 14.0,
3.0, 7.0, 11.0, 15.0, 3.0, 7.0, 11.0, 15.0,
4.0, 8.0, 12.0, 16.0)); 4.0, 8.0, 12.0, 16.0));
assert_eq!(a, mat4::from_cols(vec4::new(1.0, 5.0, 9.0, 13.0), assert_eq!(a, Mat4::from_cols::<float>(Vec4::new::<float>(1.0, 5.0, 9.0, 13.0),
vec4::new(2.0, 6.0, 10.0, 14.0), Vec4::new::<float>(2.0, 6.0, 10.0, 14.0),
vec4::new(3.0, 7.0, 11.0, 15.0), Vec4::new::<float>(3.0, 7.0, 11.0, 15.0),
vec4::new(4.0, 8.0, 12.0, 16.0))); Vec4::new::<float>(4.0, 8.0, 12.0, 16.0)));
assert_eq!(mat4::from_value(4.0), mat4::new(4.0, 0.0, 0.0, 0.0, assert_eq!(Mat4::from_value::<float>(4.0),
Mat4::new::<float>(4.0, 0.0, 0.0, 0.0,
0.0, 4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0,
0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 4.0, 0.0,
0.0, 0.0, 0.0, 4.0)); 0.0, 0.0, 0.0, 4.0));
assert_eq!(*a.col(0), vec4::new(1.0, 5.0, 9.0, 13.0)); assert_eq!(*a.col(0), Vec4::new::<float>(1.0, 5.0, 9.0, 13.0));
assert_eq!(*a.col(1), vec4::new(2.0, 6.0, 10.0, 14.0)); assert_eq!(*a.col(1), Vec4::new::<float>(2.0, 6.0, 10.0, 14.0));
assert_eq!(*a.col(2), vec4::new(3.0, 7.0, 11.0, 15.0)); assert_eq!(*a.col(2), Vec4::new::<float>(3.0, 7.0, 11.0, 15.0));
assert_eq!(*a.col(3), vec4::new(4.0, 8.0, 12.0, 16.0)); assert_eq!(*a.col(3), Vec4::new::<float>(4.0, 8.0, 12.0, 16.0));
assert_eq!(a.row(0), vec4::new( 1.0, 2.0, 3.0, 4.0)); assert_eq!(a.row(0), Vec4::new::<float>( 1.0, 2.0, 3.0, 4.0));
assert_eq!(a.row(1), vec4::new( 5.0, 6.0, 7.0, 8.0)); assert_eq!(a.row(1), Vec4::new::<float>( 5.0, 6.0, 7.0, 8.0));
assert_eq!(a.row(2), vec4::new( 9.0, 10.0, 11.0, 12.0)); assert_eq!(a.row(2), Vec4::new::<float>( 9.0, 10.0, 11.0, 12.0));
assert_eq!(a.row(3), vec4::new(13.0, 14.0, 15.0, 16.0)); assert_eq!(a.row(3), Vec4::new::<float>(13.0, 14.0, 15.0, 16.0));
assert_eq!(*a.col(0), vec4::new(1.0, 5.0, 9.0, 13.0)); assert_eq!(*a.col(0), Vec4::new::<float>(1.0, 5.0, 9.0, 13.0));
assert_eq!(*a.col(1), vec4::new(2.0, 6.0, 10.0, 14.0)); assert_eq!(*a.col(1), Vec4::new::<float>(2.0, 6.0, 10.0, 14.0));
assert_eq!(*a.col(2), vec4::new(3.0, 7.0, 11.0, 15.0)); assert_eq!(*a.col(2), Vec4::new::<float>(3.0, 7.0, 11.0, 15.0));
assert_eq!(*a.col(3), vec4::new(4.0, 8.0, 12.0, 16.0)); assert_eq!(*a.col(3), Vec4::new::<float>(4.0, 8.0, 12.0, 16.0));
assert_eq!(mat4::identity(), mat4::new(1.0, 0.0, 0.0, 0.0, assert_eq!(Mat4::identity::<float>(),
Mat4::new::<float>(1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0)); 0.0, 0.0, 0.0, 1.0));
assert_eq!(mat4::zero(), mat4::new(0.0, 0.0, 0.0, 0.0, assert_eq!(Mat4::zero::<float>(),
Mat4::new::<float>(0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0)); 0.0, 0.0, 0.0, 0.0));
@ -427,45 +441,48 @@ fn test_mat4() {
assert_eq!(a.determinant(), 0.0); assert_eq!(a.determinant(), 0.0);
assert_eq!(a.trace(), 34.0); assert_eq!(a.trace(), 34.0);
assert_eq!(a.neg(), mat4::new(-1.0, -5.0, -9.0, -13.0, assert_eq!(a.neg(),
Mat4::new::<float>(-1.0, -5.0, -9.0, -13.0,
-2.0, -6.0, -10.0, -14.0, -2.0, -6.0, -10.0, -14.0,
-3.0, -7.0, -11.0, -15.0, -3.0, -7.0, -11.0, -15.0,
-4.0, -8.0, -12.0, -16.0)); -4.0, -8.0, -12.0, -16.0));
assert_eq!(-a, a.neg()); assert_eq!(-a, a.neg());
assert_eq!(a.mul_t(f1),
assert_eq!(a.mul_t(f1), mat4::new(0.5, 2.5, 4.5, 6.5, Mat4::new::<float>(0.5, 2.5, 4.5, 6.5,
1.0, 3.0, 5.0, 7.0, 1.0, 3.0, 5.0, 7.0,
1.5, 3.5, 5.5, 7.5, 1.5, 3.5, 5.5, 7.5,
2.0, 4.0, 6.0, 8.0)); 2.0, 4.0, 6.0, 8.0));
assert_eq!(a.mul_v(&v1), vec4::new(30.0, 70.0, 110.0, 150.0)); assert_eq!(a.mul_v(&v1),
Vec4::new::<float>(30.0, 70.0, 110.0, 150.0));
assert_eq!(a.add_m(&b), mat4::new(3.0, 11.0, 19.0, 27.0, assert_eq!(a.add_m(&b),
Mat4::new::<float>(3.0, 11.0, 19.0, 27.0,
5.0, 13.0, 21.0, 29.0, 5.0, 13.0, 21.0, 29.0,
7.0, 15.0, 23.0, 31.0, 7.0, 15.0, 23.0, 31.0,
9.0, 17.0, 25.0, 33.0)); 9.0, 17.0, 25.0, 33.0));
assert_eq!(a.sub_m(&b), mat4::new(-1.0, -1.0, -1.0, -1.0, assert_eq!(a.sub_m(&b),
Mat4::new::<float>(-1.0, -1.0, -1.0, -1.0,
-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0,
-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0,
-1.0, -1.0, -1.0, -1.0)); -1.0, -1.0, -1.0, -1.0));
assert_eq!(a.mul_m(&b), mat4::new(100.0, 228.0, 356.0, 484.0, assert_eq!(a.mul_m(&b),
Mat4::new::<float>(100.0, 228.0, 356.0, 484.0,
110.0, 254.0, 398.0, 542.0, 110.0, 254.0, 398.0, 542.0,
120.0, 280.0, 440.0, 600.0, 120.0, 280.0, 440.0, 600.0,
130.0, 306.0, 482.0, 658.0)); 130.0, 306.0, 482.0, 658.0));
assert_eq!(a.dot(&b), 1632.0); assert_eq!(a.dot(&b), 1632.0);
assert_eq!(a.transpose(),
assert_eq!(a.transpose(), mat4::new( 1.0, 2.0, 3.0, 4.0, Mat4::new::<float>( 1.0, 2.0, 3.0, 4.0,
5.0, 6.0, 7.0, 8.0, 5.0, 6.0, 7.0, 8.0,
9.0, 10.0, 11.0, 12.0, 9.0, 10.0, 11.0, 12.0,
13.0, 14.0, 15.0, 16.0)); 13.0, 14.0, 15.0, 16.0));
assert!(c.inverse().unwrap().approx_eq( assert_approx_eq!(c.inverse().unwrap(),
&mat4::new( 5.0, -4.0, 1.0, 0.0, Mat4::new::<float>( 5.0, -4.0, 1.0, 0.0,
-4.0, 8.0, -4.0, 0.0, -4.0, 8.0, -4.0, 0.0,
4.0, -8.0, 4.0, 8.0, 4.0, -8.0, 4.0, 8.0,
-3.0, 4.0, 1.0, -8.0).mul_t(0.125)) -3.0, 4.0, 1.0, -8.0).mul_t(0.125));
);
let ident = mat4::identity(); let ident = Mat4::identity::<float>();
assert_eq!(ident.inverse().unwrap(), ident); assert_eq!(ident.inverse().unwrap(), ident);
@ -481,7 +498,7 @@ fn test_mat4() {
assert!(a.is_rotated()); assert!(a.is_rotated());
assert!(!a.is_invertible()); assert!(!a.is_invertible());
let c = mat4::new(4.0, 3.0, 2.0, 1.0, let c = Mat4::new::<float>(4.0, 3.0, 2.0, 1.0,
3.0, 4.0, 3.0, 2.0, 3.0, 4.0, 3.0, 2.0,
2.0, 3.0, 4.0, 3.0, 2.0, 3.0, 4.0, 3.0,
1.0, 2.0, 3.0, 4.0); 1.0, 2.0, 3.0, 4.0);
@ -491,7 +508,7 @@ fn test_mat4() {
assert!(c.is_rotated()); assert!(c.is_rotated());
assert!(c.is_invertible()); assert!(c.is_invertible());
assert!(mat4::from_value(6.0).is_diagonal()); assert!(Mat4::from_value::<float>(6.0).is_diagonal());
} }
fn test_mat4_mut() { fn test_mat4_mut() {
@ -510,8 +527,8 @@ fn test_mat4_mut() {
let f1 = 0.5; let f1 = 0.5;
let mut mut_a: mat4 = a; let mut mut_a = a;
let mut mut_c: mat4 = c; let mut mut_c = c;
mut_a.swap_cols(0, 3); mut_a.swap_cols(0, 3);
assert_eq!(mut_a.col(0), a.col(3)); assert_eq!(mut_a.col(0), a.col(3));
@ -533,16 +550,12 @@ fn test_mat4_mut() {
assert_eq!(mut_a.row(2), a.row(1)); assert_eq!(mut_a.row(2), a.row(1));
mut_a = a; mut_a = a;
mut_a.set(&b);
assert_eq!(mut_a, b);
mut_a = a;
mut_a.to_identity(); mut_a.to_identity();
assert!(mut_a.is_identity()); assert!(mut_a.is_identity());
mut_a = a; mut_a = a;
mut_a.to_zero(); mut_a.to_zero();
assert_eq!(mut_a, mat4::zero()); assert_eq!(mut_a, Mat4::zero::<float>());
mut_a = a; mut_a = a;
mut_a.mul_self_t(f1); mut_a.mul_self_t(f1);
@ -568,12 +581,14 @@ fn test_mat4_mut() {
#[test] #[test]
fn test_mat4_approx_eq() { fn test_mat4_approx_eq() {
assert!(!mat4::new(0.000001, 0.000001, 0.000001, 0.000001, assert!(!Mat4::new::<float>(0.000001, 0.000001, 0.000001, 0.000001,
0.000001, 0.000001, 0.000001, 0.000001, 0.000001, 0.000001, 0.000001, 0.000001,
0.000001, 0.000001, 0.000001, 0.000001, 0.000001, 0.000001, 0.000001, 0.000001,
0.000001, 0.000001, 0.000001, 0.000001).approx_eq(&mat4::zero())); 0.000001, 0.000001, 0.000001, 0.000001)
assert!(mat4::new(0.0000001, 0.0000001, 0.0000001, 0.0000001, .approx_eq(&Mat4::zero::<float>()));
assert!(Mat4::new::<float>(0.0000001, 0.0000001, 0.0000001, 0.0000001,
0.0000001, 0.0000001, 0.0000001, 0.0000001, 0.0000001, 0.0000001, 0.0000001, 0.0000001,
0.0000001, 0.0000001, 0.0000001, 0.0000001, 0.0000001, 0.0000001, 0.0000001, 0.0000001,
0.0000001, 0.0000001, 0.0000001, 0.0000001).approx_eq(&mat4::zero())); 0.0000001, 0.0000001, 0.0000001, 0.0000001)
.approx_eq(&Mat4::zero::<float>()));
} }

View file

@ -23,11 +23,11 @@ use vec::*;
fn test_quat() { fn test_quat() {
let a = Quat { s: 1.0, v: Vec3 { x: 2.0, y: 3.0, z: 4.0 } }; let a = Quat { s: 1.0, v: Vec3 { x: 2.0, y: 3.0, z: 4.0 } };
assert_eq!(a, quat::from_sv(1.0, vec3::new(2.0, 3.0, 4.0))); assert_eq!(a, Quat::from_sv::<float>(1.0, Vec3::new::<float>(2.0, 3.0, 4.0)));
assert_eq!(a, quat::new(1.0, 2.0, 3.0, 4.0)); assert_eq!(a, Quat::new::<float>(1.0, 2.0, 3.0, 4.0));
assert_eq!(quat::zero(), quat::new(0.0, 0.0, 0.0, 0.0)); assert_eq!(Quat::zero::<float>(), Quat::new::<float>(0.0, 0.0, 0.0, 0.0));
assert_eq!(quat::identity(), quat::new(1.0, 0.0, 0.0, 0.0)); assert_eq!(Quat::identity::<float>(), Quat::new::<float>(1.0, 0.0, 0.0, 0.0));
assert_eq!(a.s, 1.0); assert_eq!(a.s, 1.0);
assert_eq!(a.v.x, 2.0); assert_eq!(a.v.x, 2.0);
@ -42,20 +42,22 @@ fn test_quat() {
#[test] #[test]
fn test_quat_2() { fn test_quat_2() {
let v = vec3::new(1f32, 0f32, 0f32); let v = Vec3::new(1f32, 0f32, 0f32);
let q = quat::from_angle_axis((-45f32).to_radians(), &vec3::new(0f32, 0f32, -1f32)); let q = Quat::from_angle_axis((-45f32).to_radians(), &Vec3::new(0f32, 0f32, -1f32));
// http://www.wolframalpha.com/input/?i={1,0}+rotate+-45+degrees // http://www.wolframalpha.com/input/?i={1,0}+rotate+-45+degrees
assert_approx_eq!(q.mul_v(&v), vec3::new(1f32/2f32.sqrt(), 1f32/2f32.sqrt(), 0f32)); assert_approx_eq!(q.mul_v(&v), Vec3::new(1f32/2f32.sqrt(), 1f32/2f32.sqrt(), 0f32));
assert_eq!(q.mul_v(&v).length(), v.length()); assert_eq!(q.mul_v(&v).length(), v.length());
assert_approx_eq!(q.to_mat3(), mat3::new(1f32/2f32.sqrt(), 1f32/2f32.sqrt(), 0f32, assert_approx_eq!(q.to_mat3(), Mat3::new( 1f32/2f32.sqrt(), 1f32/2f32.sqrt(), 0f32,
-1f32/2f32.sqrt(), 1f32/2f32.sqrt(), 0f32, -1f32/2f32.sqrt(), 1f32/2f32.sqrt(), 0f32,
0f32, 0f32, 1f32)); 0f32, 0f32, 1f32));
} }
#[test] #[test]
fn test_quat_approx_eq() { fn test_quat_approx_eq() {
assert!(!quat::new(0.000001, 0.000001, 0.000001, 0.000001).approx_eq(&quat::new(0.0, 0.0, 0.0, 0.0))); assert!(!Quat::new::<float>(0.000001, 0.000001, 0.000001, 0.000001)
assert!(quat::new(0.0000001, 0.0000001, 0.0000001, 0.0000001).approx_eq(&quat::new(0.0, 0.0, 0.0, 0.0))); .approx_eq(&Quat::new::<float>(0.0, 0.0, 0.0, 0.0)));
assert!(Quat::new::<float>(0.0000001, 0.0000001, 0.0000001, 0.0000001)
.approx_eq(&Quat::new::<float>(0.0, 0.0, 0.0, 0.0)));
} }

View file

@ -19,8 +19,6 @@ use vec::*;
#[test] #[test]
fn test_vec2() { fn test_vec2() {
// assert_eq!(vec2::dim, 2);
let a = Vec2 { x: 1.0, y: 2.0 }; let a = Vec2 { x: 1.0, y: 2.0 };
let b = Vec2 { x: 3.0, y: 4.0 }; let b = Vec2 { x: 3.0, y: 4.0 };
let f1 = 1.5; let f1 = 1.5;
@ -28,17 +26,17 @@ fn test_vec2() {
let mut mut_a = a; let mut mut_a = a;
assert_eq!(vec2::new(1.0, 2.0), a); assert_eq!(Vec2::new::<float>(1.0, 2.0), a);
assert_eq!(vec2::from_value(1.0), vec2::new(1.0, 1.0)); assert_eq!(Vec2::from_value(1.0), Vec2::new::<float>(1.0, 1.0));
assert_eq!(vec2::zero(), vec2::new(0.0, 0.0)); assert_eq!(Vec2::zero(), Vec2::new::<float>(0.0, 0.0));
assert_eq!(vec2::unit_x(), vec2::new(1.0, 0.0)); assert_eq!(Vec2::unit_x(), Vec2::new::<float>(1.0, 0.0));
assert_eq!(vec2::unit_y(), vec2::new(0.0, 1.0)); assert_eq!(Vec2::unit_y(), Vec2::new::<float>(0.0, 1.0));
assert_eq!(vec2::identity(), vec2::new(1.0, 1.0)); assert_eq!(Vec2::identity(), Vec2::new::<float>(1.0, 1.0));
*mut_a.index_mut(0) = 42.0; *mut_a.index_mut(0) = 42.0;
*mut_a.index_mut(1) = 43.0; *mut_a.index_mut(1) = 43.0;
assert_eq!(mut_a, vec2::new(42.0, 43.0)); assert_eq!(mut_a, Vec2::new::<float>(42.0, 43.0));
mut_a = a; mut_a = a;
mut_a.swap(0, 1); mut_a.swap(0, 1);
@ -51,19 +49,19 @@ fn test_vec2() {
assert_eq!(*a.index(0), 1.0); assert_eq!(*a.index(0), 1.0);
assert_eq!(*a.index(1), 2.0); assert_eq!(*a.index(1), 2.0);
assert_eq!(-a, vec2::new(-1.0, -2.0)); assert_eq!(-a, Vec2::new::<float>(-1.0, -2.0));
assert_eq!(a.neg(), vec2::new(-1.0, -2.0)); assert_eq!(a.neg(), Vec2::new::<float>(-1.0, -2.0));
assert!(vec2::new(0.0, 0.0).is_zero()); assert!(Vec2::new::<float>(0.0, 0.0).is_zero());
assert!(!vec2::new(1.0, 1.0).is_zero()); assert!(!Vec2::new::<float>(1.0, 1.0).is_zero());
assert_eq!(a.mul_t(f1), vec2::new( 1.5, 3.0)); assert_eq!(a.mul_t(f1), Vec2::new::<float>( 1.5, 3.0));
assert_eq!(a.div_t(f2), vec2::new( 2.0, 4.0)); assert_eq!(a.div_t(f2), Vec2::new::<float>( 2.0, 4.0));
assert_eq!(a.add_v(&b), vec2::new( 4.0, 6.0)); assert_eq!(a.add_v(&b), Vec2::new::<float>( 4.0, 6.0));
assert_eq!(a.sub_v(&b), vec2::new( -2.0, -2.0)); assert_eq!(a.sub_v(&b), Vec2::new::<float>( -2.0, -2.0));
assert_eq!(a.mul_v(&b), vec2::new( 3.0, 8.0)); assert_eq!(a.mul_v(&b), Vec2::new::<float>( 3.0, 8.0));
assert_eq!(a.div_v(&b), vec2::new(1.0/3.0, 2.0/4.0)); assert_eq!(a.div_v(&b), Vec2::new::<float>(1.0/3.0, 2.0/4.0));
mut_a.neg_self(); mut_a.neg_self();
assert_eq!(mut_a, -a); assert_eq!(mut_a, -a);
@ -91,23 +89,18 @@ fn test_vec2() {
mut_a.div_self_v(&b); mut_a.div_self_v(&b);
assert_eq!(mut_a, a.div_v(&b)); assert_eq!(mut_a, a.div_v(&b));
// mut_a = a;
// assert_eq!(c.abs(), vec2::new( 2.0, 1.0));
// assert_eq!(c.min(&d), vec2::new(-2.0, -1.0));
// assert_eq!(c.max(&d), vec2::new( 1.0, 0.0));
} }
#[test] #[test]
fn test_vec2_approx_eq() { fn test_vec2_approx_eq() {
assert!(!vec2::new(0.000001, 0.000001).approx_eq(&vec2::new(0.0, 0.0))); assert!(!Vec2::new::<float>(0.000001, 0.000001).approx_eq(&Vec2::new::<float>(0.0, 0.0)));
assert!(vec2::new(0.0000001, 0.0000001).approx_eq(&vec2::new(0.0, 0.0))); assert!(Vec2::new::<float>(0.0000001, 0.0000001).approx_eq(&Vec2::new::<float>(0.0, 0.0)));
} }
#[test] #[test]
fn test_vec2_euclidean() { fn test_vec2_euclidean() {
let a = vec2::new(5.0, 12.0); // (5, 12, 13) Pythagorean triple let a = Vec2::new::<float>(5.0, 12.0); // (5, 12, 13) Pythagorean triple
let b0 = vec2::new(3.0, 4.0); // (3, 4, 5) Pythagorean triple let b0 = Vec2::new::<float>(3.0, 4.0); // (3, 4, 5) Pythagorean triple
let b = a.add_v(&b0); let b = a.add_v(&b0);
assert_eq!(a.length(), 13.0); assert_eq!(a.length(), 13.0);
@ -119,17 +112,17 @@ fn test_vec2_euclidean() {
assert_eq!(a.distance(&b), 5.0); assert_eq!(a.distance(&b), 5.0);
assert_eq!(a.distance2(&b), 5.0 * 5.0); assert_eq!(a.distance2(&b), 5.0 * 5.0);
assert!(vec2::new(1.0, 0.0).angle(&vec2::new(0.0, 1.0)).approx_eq(&Real::frac_pi_2())); assert!(Vec2::new::<float>(1.0, 0.0).angle(&Vec2::new::<float>(0.0, 1.0)).approx_eq(&Real::frac_pi_2()));
assert!(vec2::new(10.0, 0.0).angle(&vec2::new(0.0, 5.0)).approx_eq(&Real::frac_pi_2())); assert!(Vec2::new::<float>(10.0, 0.0).angle(&Vec2::new::<float>(0.0, 5.0)).approx_eq(&Real::frac_pi_2()));
assert!(vec2::new(-1.0, 0.0).angle(&vec2::new(0.0, 1.0)).approx_eq(&-Real::frac_pi_2::<f32>())); assert!(Vec2::new::<float>(-1.0, 0.0).angle(&Vec2::new::<float>(0.0, 1.0)).approx_eq(&-Real::frac_pi_2::<float>()));
assert!(vec2::new(3.0, 4.0).normalize().approx_eq(&vec2::new(3.0/5.0, 4.0/5.0))); assert!(Vec2::new::<float>(3.0, 4.0).normalize().approx_eq(&Vec2::new::<float>(3.0/5.0, 4.0/5.0)));
// TODO: test normalize_to, normalize_self, and normalize_self_to // TODO: test normalize_to, normalize_self, and normalize_self_to
let c = vec2::new(-2.0, -1.0); let c = Vec2::new::<float>(-2.0, -1.0);
let d = vec2::new( 1.0, 0.0); let d = Vec2::new::<float>( 1.0, 0.0);
assert_eq!(c.lerp(&d, 0.75), vec2::new(0.250, -0.250)); assert_eq!(c.lerp(&d, 0.75), Vec2::new::<float>(0.250, -0.250));
let mut mut_c = c; let mut mut_c = c;
mut_c.lerp_self(&d, 0.75); mut_c.lerp_self(&d, 0.75);
@ -138,27 +131,25 @@ fn test_vec2_euclidean() {
#[test] #[test]
fn test_vec2_boolean() { fn test_vec2_boolean() {
let tf = bvec2::new(true, false); let tf = Vec2::new(true, false);
let ff = bvec2::new(false, false); let ff = Vec2::new(false, false);
let tt = bvec2::new(true, true); let tt = Vec2::new(true, true);
assert_eq!(tf.any(), true); assert_eq!(tf.any(), true);
assert_eq!(tf.all(), false); assert_eq!(tf.all(), false);
assert_eq!(tf.not(), bvec2::new(false, true)); assert_eq!(tf.not(), Vec2::new(false, true));
assert_eq!(ff.any(), false); assert_eq!(ff.any(), false);
assert_eq!(ff.all(), false); assert_eq!(ff.all(), false);
assert_eq!(ff.not(), bvec2::new(true, true)); assert_eq!(ff.not(), Vec2::new(true, true));
assert_eq!(tt.any(), true); assert_eq!(tt.any(), true);
assert_eq!(tt.all(), true); assert_eq!(tt.all(), true);
assert_eq!(tt.not(), bvec2::new(false, false)); assert_eq!(tt.not(), Vec2::new(false, false));
} }
#[test] #[test]
fn test_vec3() { fn test_vec3() {
// assert_eq!(Vec3::dim, 3);
let a = Vec3 { x: 1.0, y: 2.0, z: 3.0 }; let a = Vec3 { x: 1.0, y: 2.0, z: 3.0 };
let b = Vec3 { x: 4.0, y: 5.0, z: 6.0 }; let b = Vec3 { x: 4.0, y: 5.0, z: 6.0 };
let f1 = 1.5; let f1 = 1.5;
@ -166,19 +157,19 @@ fn test_vec3() {
let mut mut_a = a; let mut mut_a = a;
assert_eq!(vec3::new(1.0, 2.0, 3.0), a); assert_eq!(Vec3::new::<float>(1.0, 2.0, 3.0), a);
assert_eq!(vec3::from_value(1.0), vec3::new(1.0, 1.0, 1.0)); assert_eq!(Vec3::from_value(1.0), Vec3::new::<float>(1.0, 1.0, 1.0));
assert_eq!(vec3::zero(), vec3::new(0.0, 0.0, 0.0)); assert_eq!(Vec3::zero(), Vec3::new::<float>(0.0, 0.0, 0.0));
assert_eq!(vec3::unit_x(), vec3::new(1.0, 0.0, 0.0)); assert_eq!(Vec3::unit_x(), Vec3::new::<float>(1.0, 0.0, 0.0));
assert_eq!(vec3::unit_y(), vec3::new(0.0, 1.0, 0.0)); assert_eq!(Vec3::unit_y(), Vec3::new::<float>(0.0, 1.0, 0.0));
assert_eq!(vec3::unit_z(), vec3::new(0.0, 0.0, 1.0)); assert_eq!(Vec3::unit_z(), Vec3::new::<float>(0.0, 0.0, 1.0));
assert_eq!(vec3::identity(), vec3::new(1.0, 1.0, 1.0)); assert_eq!(Vec3::identity(), Vec3::new::<float>(1.0, 1.0, 1.0));
*mut_a.index_mut(0) = 42.0; *mut_a.index_mut(0) = 42.0;
*mut_a.index_mut(1) = 43.0; *mut_a.index_mut(1) = 43.0;
*mut_a.index_mut(2) = 44.0; *mut_a.index_mut(2) = 44.0;
assert_eq!(mut_a, vec3::new(42.0, 43.0, 44.0)); assert_eq!(mut_a, Vec3::new::<float>(42.0, 43.0, 44.0));
mut_a = a; mut_a = a;
mut_a.swap(0, 2); mut_a.swap(0, 2);
@ -198,25 +189,25 @@ fn test_vec3() {
assert_eq!(*a.index(1), 2.0); assert_eq!(*a.index(1), 2.0);
assert_eq!(*a.index(2), 3.0); assert_eq!(*a.index(2), 3.0);
assert_eq!(a.cross(&b), vec3::new(-3.0, 6.0, -3.0)); assert_eq!(a.cross(&b), Vec3::new::<float>(-3.0, 6.0, -3.0));
mut_a.cross_self(&b); mut_a.cross_self(&b);
assert_eq!(mut_a, a.cross(&b)); assert_eq!(mut_a, a.cross(&b));
mut_a = a; mut_a = a;
assert_eq!(-a, vec3::new(-1.0, -2.0, -3.0)); assert_eq!(-a, Vec3::new::<float>(-1.0, -2.0, -3.0));
assert_eq!(a.neg(), vec3::new(-1.0, -2.0, -3.0)); assert_eq!(a.neg(), Vec3::new::<float>(-1.0, -2.0, -3.0));
assert!(vec3::new(0.0, 0.0, 0.0).is_zero()); assert!(Vec3::new::<float>(0.0, 0.0, 0.0).is_zero());
assert!(!vec3::new(1.0, 1.0, 1.0).is_zero()); assert!(!Vec3::new::<float>(1.0, 1.0, 1.0).is_zero());
assert_eq!(a.mul_t(f1), vec3::new( 1.5, 3.0, 4.5)); assert_eq!(a.mul_t(f1), Vec3::new::<float>( 1.5, 3.0, 4.5));
assert_eq!(a.div_t(f2), vec3::new( 2.0, 4.0, 6.0)); assert_eq!(a.div_t(f2), Vec3::new::<float>( 2.0, 4.0, 6.0));
assert_eq!(a.add_v(&b), vec3::new( 5.0, 7.0, 9.0)); assert_eq!(a.add_v(&b), Vec3::new::<float>( 5.0, 7.0, 9.0));
assert_eq!(a.sub_v(&b), vec3::new( -3.0, -3.0, -3.0)); assert_eq!(a.sub_v(&b), Vec3::new::<float>( -3.0, -3.0, -3.0));
assert_eq!(a.mul_v(&b), vec3::new( 4.0, 10.0, 18.0)); assert_eq!(a.mul_v(&b), Vec3::new::<float>( 4.0, 10.0, 18.0));
assert_eq!(a.div_v(&b), vec3::new(1.0/4.0, 2.0/5.0, 3.0/6.0)); assert_eq!(a.div_v(&b), Vec3::new::<float>(1.0/4.0, 2.0/5.0, 3.0/6.0));
mut_a.neg_self(); mut_a.neg_self();
assert_eq!(mut_a, -a); assert_eq!(mut_a, -a);
@ -244,27 +235,18 @@ fn test_vec3() {
mut_a.div_self_v(&b); mut_a.div_self_v(&b);
assert_eq!(mut_a, a.div_v(&b)); assert_eq!(mut_a, a.div_v(&b));
// mut_a = a;
// exact_eq
// approx_eq
// eq
// assert_eq!(c.abs(), vec3::new( 2.0, 1.0, 1.0));
// assert_eq!(c.min(&d), vec3::new(-2.0, -1.0, 0.5));
// assert_eq!(c.max(&d), vec3::new( 1.0, 0.0, 1.0));
} }
#[test] #[test]
fn test_vec3_approx_eq() { fn test_vec3_approx_eq() {
assert!(!vec3::new(0.000001, 0.000001, 0.000001).approx_eq(&vec3::new(0.0, 0.0, 0.0))); assert!(!Vec3::new::<float>(0.000001, 0.000001, 0.000001).approx_eq(&Vec3::new::<float>(0.0, 0.0, 0.0)));
assert!(vec3::new(0.0000001, 0.0000001, 0.0000001).approx_eq(&vec3::new(0.0, 0.0, 0.0))); assert!(Vec3::new::<float>(0.0000001, 0.0000001, 0.0000001).approx_eq(&Vec3::new::<float>(0.0, 0.0, 0.0)));
} }
#[test] #[test]
fn test_vec3_euclidean() { fn test_vec3_euclidean() {
let a = vec3::new(2.0, 3.0, 6.0); // (2, 3, 6, 7) Pythagorean quadruple let a = Vec3::new::<float>(2.0, 3.0, 6.0); // (2, 3, 6, 7) Pythagorean quadruple
let b0 = vec3::new(1.0, 4.0, 8.0); // (1, 4, 8, 9) Pythagorean quadruple let b0 = Vec3::new::<float>(1.0, 4.0, 8.0); // (1, 4, 8, 9) Pythagorean quadruple
let b = a.add_v(&b0); let b = a.add_v(&b0);
assert_eq!(a.length(), 7.0); assert_eq!(a.length(), 7.0);
@ -276,17 +258,17 @@ fn test_vec3_euclidean() {
assert_eq!(a.distance(&b), 9.0); assert_eq!(a.distance(&b), 9.0);
assert_eq!(a.distance2(&b), 9.0 * 9.0); assert_eq!(a.distance2(&b), 9.0 * 9.0);
assert!(vec3::new(1.0, 0.0, 1.0).angle(&vec3::new(1.0, 1.0, 0.0)).approx_eq(&Real::frac_pi_3())); assert!(Vec3::new::<float>(1.0, 0.0, 1.0).angle(&Vec3::new::<float>(1.0, 1.0, 0.0)).approx_eq(&Real::frac_pi_3()));
assert!(vec3::new(10.0, 0.0, 10.0).angle(&vec3::new(5.0, 5.0, 0.0)).approx_eq(&Real::frac_pi_3())); assert!(Vec3::new::<float>(10.0, 0.0, 10.0).angle(&Vec3::new::<float>(5.0, 5.0, 0.0)).approx_eq(&Real::frac_pi_3()));
assert!(vec3::new(-1.0, 0.0, -1.0).angle(&vec3::new(1.0, -1.0, 0.0)).approx_eq(&(2.0 * Real::frac_pi_3()))); assert!(Vec3::new::<float>(-1.0, 0.0, -1.0).angle(&Vec3::new::<float>(1.0, -1.0, 0.0)).approx_eq(&(2.0 * Real::frac_pi_3())));
assert!(vec3::new(2.0, 3.0, 6.0).normalize().approx_eq(&vec3::new(2.0/7.0, 3.0/7.0, 6.0/7.0))); assert!(Vec3::new::<float>(2.0, 3.0, 6.0).normalize().approx_eq(&Vec3::new::<float>(2.0/7.0, 3.0/7.0, 6.0/7.0)));
// TODO: test normalize_to, normalize_self, and normalize_self_to // TODO: test normalize_to, normalize_self, and normalize_self_to
let c = vec3::new(-2.0, -1.0, 1.0); let c = Vec3::new::<float>(-2.0, -1.0, 1.0);
let d = vec3::new( 1.0, 0.0, 0.5); let d = Vec3::new::<float>( 1.0, 0.0, 0.5);
assert_eq!(c.lerp(&d, 0.75), vec3::new(0.250, -0.250, 0.625)); assert_eq!(c.lerp(&d, 0.75), Vec3::new::<float>(0.250, -0.250, 0.625));
let mut mut_c = c; let mut mut_c = c;
mut_c.lerp_self(&d, 0.75); mut_c.lerp_self(&d, 0.75);
@ -295,27 +277,25 @@ fn test_vec3_euclidean() {
#[test] #[test]
fn test_vec3_boolean() { fn test_vec3_boolean() {
let tft = bvec3::new(true, false, true); let tft = Vec3::new(true, false, true);
let fff = bvec3::new(false, false, false); let fff = Vec3::new(false, false, false);
let ttt = bvec3::new(true, true, true); let ttt = Vec3::new(true, true, true);
assert_eq!(tft.any(), true); assert_eq!(tft.any(), true);
assert_eq!(tft.all(), false); assert_eq!(tft.all(), false);
assert_eq!(tft.not(), bvec3::new(false, true, false)); assert_eq!(tft.not(), Vec3::new(false, true, false));
assert_eq!(fff.any(), false); assert_eq!(fff.any(), false);
assert_eq!(fff.all(), false); assert_eq!(fff.all(), false);
assert_eq!(fff.not(), bvec3::new(true, true, true)); assert_eq!(fff.not(), Vec3::new(true, true, true));
assert_eq!(ttt.any(), true); assert_eq!(ttt.any(), true);
assert_eq!(ttt.all(), true); assert_eq!(ttt.all(), true);
assert_eq!(ttt.not(), bvec3::new(false, false, false)); assert_eq!(ttt.not(), Vec3::new(false, false, false));
} }
#[test] #[test]
fn test_vec4() { fn test_vec4() {
// assert_eq!(Vec4::dim, 4);
let a = Vec4 { x: 1.0, y: 2.0, z: 3.0, w: 4.0 }; let a = Vec4 { x: 1.0, y: 2.0, z: 3.0, w: 4.0 };
let b = Vec4 { x: 5.0, y: 6.0, z: 7.0, w: 8.0 }; let b = Vec4 { x: 5.0, y: 6.0, z: 7.0, w: 8.0 };
let f1 = 1.5; let f1 = 1.5;
@ -323,14 +303,14 @@ fn test_vec4() {
let mut mut_a = a; let mut mut_a = a;
assert_eq!(vec4::new(1.0, 2.0, 3.0, 4.0), a); assert_eq!(Vec4::new::<float>(1.0, 2.0, 3.0, 4.0), a);
assert_eq!(vec4::from_value(1.0), vec4::new(1.0, 1.0, 1.0, 1.0)); assert_eq!(Vec4::from_value(1.0), Vec4::new::<float>(1.0, 1.0, 1.0, 1.0));
*mut_a.index_mut(0) = 42.0; *mut_a.index_mut(0) = 42.0;
*mut_a.index_mut(1) = 43.0; *mut_a.index_mut(1) = 43.0;
*mut_a.index_mut(2) = 44.0; *mut_a.index_mut(2) = 44.0;
*mut_a.index_mut(3) = 45.0; *mut_a.index_mut(3) = 45.0;
assert_eq!(mut_a, vec4::new(42.0, 43.0, 44.0, 45.0)); assert_eq!(mut_a, Vec4::new::<float>(42.0, 43.0, 44.0, 45.0));
mut_a = a; mut_a = a;
mut_a.swap(0, 3); mut_a.swap(0, 3);
@ -343,12 +323,12 @@ fn test_vec4() {
assert_eq!(*mut_a.index(2), *a.index(1)); assert_eq!(*mut_a.index(2), *a.index(1));
mut_a = a; mut_a = a;
assert_eq!(vec4::zero(), vec4::new(0.0, 0.0, 0.0, 0.0)); assert_eq!(Vec4::zero(), Vec4::new::<float>(0.0, 0.0, 0.0, 0.0));
assert_eq!(vec4::unit_x(), vec4::new(1.0, 0.0, 0.0, 0.0)); assert_eq!(Vec4::unit_x(), Vec4::new::<float>(1.0, 0.0, 0.0, 0.0));
assert_eq!(vec4::unit_y(), vec4::new(0.0, 1.0, 0.0, 0.0)); assert_eq!(Vec4::unit_y(), Vec4::new::<float>(0.0, 1.0, 0.0, 0.0));
assert_eq!(vec4::unit_z(), vec4::new(0.0, 0.0, 1.0, 0.0)); assert_eq!(Vec4::unit_z(), Vec4::new::<float>(0.0, 0.0, 1.0, 0.0));
assert_eq!(vec4::unit_w(), vec4::new(0.0, 0.0, 0.0, 1.0)); assert_eq!(Vec4::unit_w(), Vec4::new::<float>(0.0, 0.0, 0.0, 1.0));
assert_eq!(vec4::identity(), vec4::new(1.0, 1.0, 1.0, 1.0)); assert_eq!(Vec4::identity(), Vec4::new::<float>(1.0, 1.0, 1.0, 1.0));
assert_eq!(a.x, 1.0); assert_eq!(a.x, 1.0);
assert_eq!(a.y, 2.0); assert_eq!(a.y, 2.0);
@ -359,19 +339,19 @@ fn test_vec4() {
assert_eq!(*a.index(2), 3.0); assert_eq!(*a.index(2), 3.0);
assert_eq!(*a.index(3), 4.0); assert_eq!(*a.index(3), 4.0);
assert_eq!(-a, vec4::new(-1.0, -2.0, -3.0, -4.0)); assert_eq!(-a, Vec4::new::<float>(-1.0, -2.0, -3.0, -4.0));
assert_eq!(a.neg(), vec4::new(-1.0, -2.0, -3.0, -4.0)); assert_eq!(a.neg(), Vec4::new::<float>(-1.0, -2.0, -3.0, -4.0));
assert!(vec4::new(0.0, 0.0, 0.0, 0.0).is_zero()); assert!(Vec4::new::<float>(0.0, 0.0, 0.0, 0.0).is_zero());
assert!(!vec4::new(1.0, 1.0, 1.0, 1.0).is_zero()); assert!(!Vec4::new::<float>(1.0, 1.0, 1.0, 1.0).is_zero());
assert_eq!(a.mul_t(f1), vec4::new( 1.5, 3.0, 4.5, 6.0)); assert_eq!(a.mul_t(f1), Vec4::new::<float>( 1.5, 3.0, 4.5, 6.0));
assert_eq!(a.div_t(f2), vec4::new( 2.0, 4.0, 6.0, 8.0)); assert_eq!(a.div_t(f2), Vec4::new::<float>( 2.0, 4.0, 6.0, 8.0));
assert_eq!(a.add_v(&b), vec4::new( 6.0, 8.0, 10.0, 12.0)); assert_eq!(a.add_v(&b), Vec4::new::<float>( 6.0, 8.0, 10.0, 12.0));
assert_eq!(a.sub_v(&b), vec4::new( -4.0, -4.0, -4.0, -4.0)); assert_eq!(a.sub_v(&b), Vec4::new::<float>( -4.0, -4.0, -4.0, -4.0));
assert_eq!(a.mul_v(&b), vec4::new( 5.0, 12.0, 21.0, 32.0)); assert_eq!(a.mul_v(&b), Vec4::new::<float>( 5.0, 12.0, 21.0, 32.0));
assert_eq!(a.div_v(&b), vec4::new(1.0/5.0, 2.0/6.0, 3.0/7.0, 4.0/8.0)); assert_eq!(a.div_v(&b), Vec4::new::<float>(1.0/5.0, 2.0/6.0, 3.0/7.0, 4.0/8.0));
assert_eq!(a.dot(&b), 70.0); assert_eq!(a.dot(&b), 70.0);
@ -401,23 +381,18 @@ fn test_vec4() {
mut_a.div_self_v(&b); mut_a.div_self_v(&b);
assert_eq!(mut_a, a.div_v(&b)); assert_eq!(mut_a, a.div_v(&b));
// mut_a = a;
// assert_eq!(c.abs(), vec4::new( 2.0, 1.0, 1.0, 2.0));
// assert_eq!(c.min(&d), vec4::new(-2.0, -1.0, 0.5, 1.0));
// assert_eq!(c.max(&d), vec4::new( 1.0, 0.0, 1.0, 2.0));
} }
#[test] #[test]
fn test_vec4_approx_eq() { fn test_vec4_approx_eq() {
assert!(!vec4::new(0.000001, 0.000001, 0.000001, 0.000001).approx_eq(&vec4::new(0.0, 0.0, 0.0, 0.0))); assert!(!Vec4::new::<float>(0.000001, 0.000001, 0.000001, 0.000001).approx_eq(&Vec4::new::<float>(0.0, 0.0, 0.0, 0.0)));
assert!(vec4::new(0.0000001, 0.0000001, 0.0000001, 0.0000001).approx_eq(&vec4::new(0.0, 0.0, 0.0, 0.0))); assert!(Vec4::new::<float>(0.0000001, 0.0000001, 0.0000001, 0.0000001).approx_eq(&Vec4::new::<float>(0.0, 0.0, 0.0, 0.0)));
} }
#[test] #[test]
fn test_vec4_euclidean() { fn test_vec4_euclidean() {
let a = vec4::new(1.0, 2.0, 4.0, 10.0); // (1, 2, 4, 10, 11) Pythagorean quintuple let a = Vec4::new::<float>(1.0, 2.0, 4.0, 10.0); // (1, 2, 4, 10, 11) Pythagorean quintuple
let b0 = vec4::new(1.0, 2.0, 8.0, 10.0); // (1, 2, 8, 10, 13) Pythagorean quintuple let b0 = Vec4::new::<float>(1.0, 2.0, 8.0, 10.0); // (1, 2, 8, 10, 13) Pythagorean quintuple
let b = a.add_v(&b0); let b = a.add_v(&b0);
assert_eq!(a.length(), 11.0); assert_eq!(a.length(), 11.0);
@ -429,17 +404,17 @@ fn test_vec4_euclidean() {
assert_eq!(a.distance(&b), 13.0); assert_eq!(a.distance(&b), 13.0);
assert_eq!(a.distance2(&b), 13.0 * 13.0); assert_eq!(a.distance2(&b), 13.0 * 13.0);
assert!(vec4::new(1.0, 0.0, 1.0, 0.0).angle(&vec4::new(0.0, 1.0, 0.0, 1.0)).approx_eq(&Real::frac_pi_2())); assert!(Vec4::new::<float>(1.0, 0.0, 1.0, 0.0).angle(&Vec4::new::<float>(0.0, 1.0, 0.0, 1.0)).approx_eq(&Real::frac_pi_2()));
assert!(vec4::new(10.0, 0.0, 10.0, 0.0).angle(&vec4::new(0.0, 5.0, 0.0, 5.0)).approx_eq(&Real::frac_pi_2())); assert!(Vec4::new::<float>(10.0, 0.0, 10.0, 0.0).angle(&Vec4::new::<float>(0.0, 5.0, 0.0, 5.0)).approx_eq(&Real::frac_pi_2()));
assert!(vec4::new(-1.0, 0.0, -1.0, 0.0).angle(&vec4::new(0.0, 1.0, 0.0, 1.0)).approx_eq(&Real::frac_pi_2())); assert!(Vec4::new::<float>(-1.0, 0.0, -1.0, 0.0).angle(&Vec4::new::<float>(0.0, 1.0, 0.0, 1.0)).approx_eq(&Real::frac_pi_2()));
assert!(vec4::new(1.0, 2.0, 4.0, 10.0).normalize().approx_eq(&vec4::new(1.0/11.0, 2.0/11.0, 4.0/11.0, 10.0/11.0))); assert!(Vec4::new::<float>(1.0, 2.0, 4.0, 10.0).normalize().approx_eq(&Vec4::new::<float>(1.0/11.0, 2.0/11.0, 4.0/11.0, 10.0/11.0)));
// TODO: test normalize_to, normalize_self, and normalize_self_to // TODO: test normalize_to, normalize_self, and normalize_self_to
let c = vec4::new(-2.0, -1.0, 1.0, 2.0); let c = Vec4::new::<float>(-2.0, -1.0, 1.0, 2.0);
let d = vec4::new( 1.0, 0.0, 0.5, 1.0); let d = Vec4::new::<float>( 1.0, 0.0, 0.5, 1.0);
assert_eq!(c.lerp(&d, 0.75), vec4::new(0.250, -0.250, 0.625, 1.250)); assert_eq!(c.lerp(&d, 0.75), Vec4::new::<float>(0.250, -0.250, 0.625, 1.250));
let mut mut_c = c; let mut mut_c = c;
mut_c.lerp_self(&d, 0.75); mut_c.lerp_self(&d, 0.75);
@ -448,19 +423,19 @@ fn test_vec4_euclidean() {
#[test] #[test]
fn test_vec4_boolean() { fn test_vec4_boolean() {
let tftf = bvec4::new(true, false, true, false); let tftf = Vec4::new(true, false, true, false);
let ffff = bvec4::new(false, false, false, false); let ffff = Vec4::new(false, false, false, false);
let tttt = bvec4::new(true, true, true, true); let tttt = Vec4::new(true, true, true, true);
assert_eq!(tftf.any(), true); assert_eq!(tftf.any(), true);
assert_eq!(tftf.all(), false); assert_eq!(tftf.all(), false);
assert_eq!(tftf.not(), bvec4::new(false, true, false, true)); assert_eq!(tftf.not(), Vec4::new(false, true, false, true));
assert_eq!(ffff.any(), false); assert_eq!(ffff.any(), false);
assert_eq!(ffff.all(), false); assert_eq!(ffff.all(), false);
assert_eq!(ffff.not(), bvec4::new(true, true, true, true)); assert_eq!(ffff.not(), Vec4::new(true, true, true, true));
assert_eq!(tttt.any(), true); assert_eq!(tttt.any(), true);
assert_eq!(tttt.all(), true); assert_eq!(tttt.all(), true);
assert_eq!(tttt.not(), bvec4::new(false, false, false, false)); assert_eq!(tttt.not(), Vec4::new(false, false, false, false));
} }

1569
src/vec.rs

File diff suppressed because it is too large Load diff