From 0cb3314bf84741fa96d120282f59ccc3bf70c9a2 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Mon, 6 May 2013 13:52:22 +1000 Subject: [PATCH] Use the new core::num traits and remove numeric dependency --- Makefile | 4 +- README.md | 4 - extern/.gitkeep | 0 src/lmath.rs | 3 +- src/mat.rs | 224 ++++++++--------------------------- src/num.rs | 35 ++++++ src/projection.rs | 12 +- src/quat.rs | 76 +++--------- src/vec.rs | 289 +++++----------------------------------------- 9 files changed, 139 insertions(+), 508 deletions(-) delete mode 100644 extern/.gitkeep create mode 100644 src/num.rs diff --git a/Makefile b/Makefile index 087644e..1b4f0e4 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ TEST_BUILD_DIR = $(ROOT_DIR)/test $(TARGET): @echo "Building $(TARGET)..." @mkdir -p $(BUILD_DIR) - @rustc $(SRC_DIR)/$(SRC_CRATE) -L $(EXTERN_DIR) --out-dir=$(BUILD_DIR) + @rustc $(SRC_DIR)/$(SRC_CRATE) --out-dir=$(BUILD_DIR) @echo "Success" all: $(TARGET) @@ -23,7 +23,7 @@ all: $(TARGET) test: @echo "Building unit tests for $(TARGET)..." @mkdir -p $(TEST_BUILD_DIR) - @rustc $(SRC_DIR)/$(SRC_CRATE) --test -L $(EXTERN_DIR) --out-dir=$(TEST_BUILD_DIR) + @rustc $(SRC_DIR)/$(SRC_CRATE) --test --out-dir=$(TEST_BUILD_DIR) @echo "Success" @$(TEST_BUILD_DIR)/$(TARGET) diff --git a/README.md b/README.md index 62475c3..f86f97b 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,6 @@ A linear algebra library for Rust, targeted at computer graphics. -## Dependencies - -[numeric-rs](https://github.com/bjz/numeric-rs/) (drop the library binary into lmath/extern) - ## Examples diff --git a/extern/.gitkeep b/extern/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/lmath.rs b/src/lmath.rs index f97350e..09f5de4 100644 --- a/src/lmath.rs +++ b/src/lmath.rs @@ -9,7 +9,8 @@ #[crate_type = "lib"]; extern mod std; -extern mod numeric; + +pub mod num; pub mod mat; pub mod quat; diff --git a/src/mat.rs b/src/mat.rs index 073e92e..3afb7df 100644 --- a/src/mat.rs +++ b/src/mat.rs @@ -1,11 +1,12 @@ use core::num::Zero::zero; use core::num::One::one; use std::cmp::{FuzzyEq, FUZZY_EPSILON}; -use numeric::*; use vec::*; use quat::Quat; +use num::NumAssign; + /** * The base square matrix trait * @@ -312,7 +313,7 @@ pub trait BaseMat4: BaseMat { #[deriving(Eq)] pub struct Mat2 { x: Vec2, y: Vec2 } -impl BaseMat> for Mat2 { +impl> BaseMat> for Mat2 { #[inline(always)] fn col(&self, i: uint) -> Vec2 { self[i] } @@ -537,7 +538,7 @@ impl BaseMat> for Mat2 { } } -impl BaseMat2> for Mat2 { +impl> BaseMat2> for Mat2 { /** * Construct a 2 x 2 matrix * @@ -586,8 +587,8 @@ impl BaseMat2> for Mat2 { #[inline(always)] fn from_angle(radians: T) -> Mat2 { - let cos_theta = cos(radians); - let sin_theta = sin(radians); + let cos_theta = radians.cos(); + let sin_theta = radians.sin(); BaseMat2::new(cos_theta, -sin_theta, sin_theta, cos_theta) @@ -644,14 +645,14 @@ impl Index> for Mat2 { } } -impl Neg> for Mat2 { +impl> Neg> for Mat2 { #[inline(always)] fn neg(&self) -> Mat2 { BaseMat2::from_cols(-self[0], -self[1]) } } -impl FuzzyEq for Mat2 { +impl> FuzzyEq for Mat2 { #[inline(always)] fn fuzzy_eq(&self, other: &Mat2) -> bool { self.fuzzy_eq_eps(other, &num::cast(FUZZY_EPSILON)) @@ -664,48 +665,6 @@ impl FuzzyEq for Mat2 { } } -macro_rules! mat2_type( - ($name:ident <$T:ty, $V:ty>) => ( - pub impl $name { - #[inline(always)] fn new(c0r0: $T, c0r1: $T, c1r0: $T, c1r1: $T) - -> $name { BaseMat2::new(c0r0, c0r1, c1r0, c1r1) } - #[inline(always)] fn from_cols(c0: $V, c1: $V) - -> $name { BaseMat2::from_cols(c0, c1) } - #[inline(always)] fn from_value(v: $T) -> $name { BaseMat::from_value(v) } - - #[inline(always)] fn identity() -> $name { BaseMat::identity() } - #[inline(always)] fn zero() -> $name { BaseMat::zero() } - - #[inline(always)] fn from_angle(radians: $T) -> $name { BaseMat2::from_angle(radians) } - - #[inline(always)] fn dim() -> uint { 2 } - #[inline(always)] fn rows() -> uint { 2 } - #[inline(always)] fn cols() -> uint { 2 } - #[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() } - } - ) -) - -// GLSL-style type aliases, corresponding to Section 4.1.6 of the [GLSL 4.30.6 specification] -// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf). - -// a 2×2 single-precision floating-point matrix -pub type mat2 = Mat2; -// a 2×2 double-precision floating-point matrix -pub type dmat2 = Mat2; - -mat2_type!(mat2) -mat2_type!(dmat2) - -// Rust-style type aliases -pub type Mat2f = Mat2; -pub type Mat2f32 = Mat2; -pub type Mat2f64 = Mat2; - -mat2_type!(Mat2f) -mat2_type!(Mat2f32) -mat2_type!(Mat2f64) - /** * A 3 x 3 column major matrix * @@ -722,15 +681,15 @@ mat2_type!(Mat2f64) #[deriving(Eq)] pub struct Mat3 { x: Vec3, y: Vec3, z: Vec3 } -impl BaseMat> for Mat3 { +impl> BaseMat> for Mat3 { #[inline(always)] fn col(&self, i: uint) -> Vec3 { self[i] } #[inline(always)] fn row(&self, i: uint) -> Vec3 { BaseVec3::new(self[0][i], - self[1][i], - self[2][i]) + self[1][i], + self[2][i]) } /** @@ -808,8 +767,8 @@ impl BaseMat> for Mat3 { #[inline(always)] fn mul_v(&self, vec: &Vec3) -> Vec3 { BaseVec3::new(self.row(0).dot(vec), - self.row(1).dot(vec), - self.row(2).dot(vec)) + self.row(1).dot(vec), + self.row(2).dot(vec)) } #[inline(always)] @@ -996,7 +955,7 @@ impl BaseMat> for Mat3 { } } -impl BaseMat3> for Mat3 { +impl> BaseMat3> for Mat3 { /** * Construct a 3 x 3 matrix * @@ -1057,8 +1016,8 @@ impl BaseMat3> for Mat3 { #[inline(always)] fn from_angle_x(radians: T) -> Mat3 { // http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations - let cos_theta = cos(radians); - let sin_theta = sin(radians); + let cos_theta = radians.cos(); + let sin_theta = radians.sin(); BaseMat3::new( one(), zero(), zero(), zero(), cos_theta, sin_theta, @@ -1071,8 +1030,8 @@ impl BaseMat3> for Mat3 { #[inline(always)] fn from_angle_y(radians: T) -> Mat3 { // http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations - let cos_theta = cos(radians); - let sin_theta = sin(radians); + let cos_theta = radians.cos(); + let sin_theta = radians.sin(); BaseMat3::new(cos_theta, zero(), -sin_theta, zero(), one(), zero(), @@ -1085,8 +1044,8 @@ impl BaseMat3> for Mat3 { #[inline(always)] fn from_angle_z(radians: T) -> Mat3 { // http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations - let cos_theta = cos(radians); - let sin_theta = sin(radians); + let cos_theta = radians.cos(); + let sin_theta = radians.sin(); BaseMat3::new( cos_theta, sin_theta, zero(), -sin_theta, cos_theta, zero(), @@ -1105,12 +1064,12 @@ impl BaseMat3> for Mat3 { #[inline(always)] fn from_angle_xyz(radians_x: T, radians_y: T, radians_z: T) -> Mat3 { // http://en.wikipedia.org/wiki/Rotation_matrix#General_rotations - let cx = cos(radians_x); - let sx = sin(radians_x); - let cy = cos(radians_y); - let sy = sin(radians_y); - let cz = cos(radians_z); - let sz = sin(radians_z); + let cx = radians_x.cos(); + let sx = radians_x.sin(); + let cy = radians_y.cos(); + let sy = radians_y.sin(); + let cz = radians_z.cos(); + let sz = radians_z.sin(); BaseMat3::new( cy*cz, cy*sz, -sy, -cx*sz + sx*sy*cz, cx*cz + sx*sy*sz, sx*cy, @@ -1122,8 +1081,8 @@ impl BaseMat3> for Mat3 { */ #[inline(always)] fn from_angle_axis(radians: T, axis: &Vec3) -> Mat3 { - let c = cos(radians); - let s = sin(radians); + let c = radians.cos(); + let s = radians.sin(); let _1_c = one::() - c; let x = axis.x; @@ -1228,14 +1187,14 @@ impl Index> for Mat3 { } } -impl Neg> for Mat3 { +impl> Neg> for Mat3 { #[inline(always)] fn neg(&self) -> Mat3 { BaseMat3::from_cols(-self[0], -self[1], -self[2]) } } -impl FuzzyEq for Mat3 { +impl> FuzzyEq for Mat3 { #[inline(always)] fn fuzzy_eq(&self, other: &Mat3) -> bool { self.fuzzy_eq_eps(other, &num::cast(FUZZY_EPSILON)) @@ -1249,51 +1208,6 @@ impl FuzzyEq for Mat3 { } } -macro_rules! mat3_type( - ($name:ident <$T:ty, $V:ty>) => ( - pub impl $name { - #[inline(always)] fn new(c0r0: $T, c0r1: $T, c0r2: $T, c1r0: $T, c1r1: $T, c1r2: $T, c2r0: $T, c2r1: $T, c2r2: $T) - -> $name { BaseMat3::new(c0r0, c0r1, c0r2, c1r0, c1r1, c1r2, c2r0, c2r1, c2r2) } - #[inline(always)] fn from_cols(c0: $V, c1: $V, c2: $V) - -> $name { BaseMat3::from_cols(c0, c1, c2) } - #[inline(always)] fn from_value(v: $T) -> $name { BaseMat::from_value(v) } - - #[inline(always)] fn identity() -> $name { BaseMat::identity() } - #[inline(always)] fn zero() -> $name { BaseMat::zero() } - - #[inline(always)] fn from_angle_x(radians: $T) -> $name { BaseMat3::from_angle_x(radians) } - #[inline(always)] fn from_angle_y(radians: $T) -> $name { BaseMat3::from_angle_y(radians) } - #[inline(always)] fn from_angle_z(radians: $T) -> $name { BaseMat3::from_angle_z(radians) } - #[inline(always)] fn from_angle_xyz(radians_x: $T, radians_y: $T, radians_z: $T) -> $name { BaseMat3::from_angle_xyz(radians_x, radians_y, radians_z) } - #[inline(always)] fn from_angle_axis(radians: $T, axis: &$V) -> $name { BaseMat3::from_angle_axis(radians, axis) } - #[inline(always)] fn from_axes(x: $V, y: $V, z: $V) -> $name { BaseMat3::from_axes(x, y, z) } - #[inline(always)] fn look_at(dir: &$V, up: &$V) -> $name { BaseMat3::look_at(dir, up) } - - #[inline(always)] fn dim() -> uint { 3 } - #[inline(always)] fn rows() -> uint { 3 } - #[inline(always)] fn cols() -> uint { 3 } - #[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() } - } - ) -) - -// a 3×3 single-precision floating-point matrix -pub type mat3 = Mat3; -// a 3×3 double-precision floating-point matrix -pub type dmat3 = Mat3; - -mat3_type!(mat3) -mat3_type!(dmat3) - -// Rust-style type aliases -pub type Mat3f = Mat3; -pub type Mat3f32 = Mat3; -pub type Mat3f64 = Mat3; - -mat3_type!(Mat3f) -mat3_type!(Mat3f32) -mat3_type!(Mat3f64) - /** * A 4 x 4 column major matrix * @@ -1311,7 +1225,7 @@ mat3_type!(Mat3f64) #[deriving(Eq)] pub struct Mat4 { x: Vec4, y: Vec4, z: Vec4, w: Vec4 } -impl BaseMat> for Mat4 { +impl> BaseMat> for Mat4 { #[inline(always)] fn col(&self, i: uint) -> Vec4 { self[i] } @@ -1498,28 +1412,26 @@ impl BaseMat> for Mat4 { // Find largest element in col j let mut i1 = j; for uint::range(j + 1, 4) |i| { - if abs(A[j][i]) > abs(A[j][i1]) { + if A[j][i].abs() > A[j][i1].abs() { i1 = i; } } - unsafe { - // Swap columns i1 and j in A and I to - // put pivot on diagonal - A.swap_cols(i1, j); - I.swap_cols(i1, j); + // Swap columns i1 and j in A and I to + // put pivot on diagonal + A.swap_cols(i1, j); + I.swap_cols(i1, j); - // Scale col j to have a unit diagonal - I.col_mut(j).div_self_t(A[j][j]); - A.col_mut(j).div_self_t(A[j][j]); + // Scale col j to have a unit diagonal + I.col_mut(j).div_self_t(A[j][j]); + A.col_mut(j).div_self_t(A[j][j]); - // Eliminate off-diagonal elems in col j of A, - // doing identical ops to I - for uint::range(0, 4) |i| { - if i != j { - I.col_mut(i).sub_self_v(&I[j].mul_t(A[i][j])); - A.col_mut(i).sub_self_v(&A[j].mul_t(A[i][j])); - } + // Eliminate off-diagonal elems in col j of A, + // doing identical ops to I + for uint::range(0, 4) |i| { + if i != j { + I.col_mut(i).sub_self_v(&I[j].mul_t(A[i][j])); + A.col_mut(i).sub_self_v(&A[j].mul_t(A[i][j])); } } } @@ -1684,7 +1596,7 @@ impl BaseMat> for Mat4 { } } -impl BaseMat4> for Mat4 { +impl> BaseMat4> for Mat4 { /** * Construct a 4 x 4 matrix * @@ -1748,7 +1660,7 @@ impl BaseMat4> for Mat4 { } } -impl Neg> for Mat4 { +impl> Neg> for Mat4 { #[inline(always)] fn neg(&self) -> Mat4 { BaseMat4::from_cols(-self[0], -self[1], -self[2], -self[3]) @@ -1762,7 +1674,7 @@ impl Index> for Mat4 { } } -impl FuzzyEq for Mat4 { +impl> FuzzyEq for Mat4 { #[inline(always)] fn fuzzy_eq(&self, other: &Mat4) -> bool { self.fuzzy_eq_eps(other, &num::cast(FUZZY_EPSILON)) @@ -1776,43 +1688,3 @@ impl FuzzyEq for Mat4 { self[3].fuzzy_eq_eps(&other[3], epsilon) } } - -macro_rules! mat4_type( - ($name:ident <$T:ty, $V:ty>) => ( - pub impl $name { - #[inline(always)] fn new(c0r0: $T, c0r1: $T, c0r2: $T, c0r3: $T, c1r0: $T, c1r1: $T, c1r2: $T, c1r3: $T, c2r0: $T, c2r1: $T, c2r2: $T, c2r3: $T, c3r0: $T, c3r1: $T, c3r2: $T, c3r3: $T) - -> $name { BaseMat4::new(c0r0, c0r1, c0r2, c0r3, c1r0, c1r1, c1r2, c1r3, c2r0, c2r1, c2r2, c2r3, c3r0, c3r1, c3r2, c3r3) } - #[inline(always)] fn from_cols(c0: $V, c1: $V, c2: $V, c3: $V) - -> $name { BaseMat4::from_cols(c0, c1, c2, c3) } - #[inline(always)] fn from_value(v: $T) -> $name { BaseMat::from_value(v) } - - #[inline(always)] fn identity() -> $name { BaseMat::identity() } - #[inline(always)] fn zero() -> $name { BaseMat::zero() } - - #[inline(always)] fn dim() -> uint { 4 } - #[inline(always)] fn rows() -> uint { 4 } - #[inline(always)] fn cols() -> uint { 4 } - #[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() } - } - ) -) - -// GLSL-style type aliases, corresponding to Section 4.1.6 of the [GLSL 4.30.6 specification] -// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf). - -// a 4×4 single-precision floating-point matrix -pub type mat4 = Mat4; -// a 4×4 double-precision floating-point matrix -pub type dmat4 = Mat4; - -mat4_type!(mat4) -mat4_type!(dmat4) - -// Rust-style type aliases -pub type Mat4f = Mat4; -pub type Mat4f32 = Mat4; -pub type Mat4f64 = Mat4; - -mat4_type!(Mat4f) -mat4_type!(Mat4f32) -mat4_type!(Mat4f64) \ No newline at end of file diff --git a/src/num.rs b/src/num.rs new file mode 100644 index 0000000..9064eda --- /dev/null +++ b/src/num.rs @@ -0,0 +1,35 @@ +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) \ No newline at end of file diff --git a/src/projection.rs b/src/projection.rs index 646f2c3..3c10efa 100644 --- a/src/projection.rs +++ b/src/projection.rs @@ -1,7 +1,9 @@ -use numeric::*; +use std::cmp::FuzzyEq; use mat::{Mat4, BaseMat4}; +use num::NumAssign; + /** * Create a perspective projection matrix * @@ -11,10 +13,10 @@ use mat::{Mat4, BaseMat4}; * can be found [here](http://www.opengl.org/wiki/GluPerspective_code). */ #[inline(always)] -pub fn perspective(fovy: T, aspectRatio: T, near: T, far: T) -> Mat4 { +pub fn perspective>(fovy: T, aspectRatio: T, near: T, far: T) -> Mat4 { let _2: T = num::cast(2); - let ymax = near * tan(radians(fovy / _2)); + let ymax = near * (fovy / _2).to_radians().tan(); let xmax = ymax * aspectRatio; frustum(-xmax, xmax, -ymax, ymax, near, far) @@ -27,7 +29,7 @@ pub fn perspective(fovy: T, aspectRatio: T, near: T, far: T) -> * (http://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml) function. */ #[inline(always)] -pub fn frustum(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4 { +pub fn frustum>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4 { let _0: T = num::cast(0); let _1: T = num::cast(1); let _2: T = num::cast(2); @@ -65,7 +67,7 @@ pub fn frustum(left: T, right: T, bottom: T, top: T, near: T, fa * (http://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml) function. */ #[inline(always)] -pub fn ortho(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4 { +pub fn ortho>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4 { let _0: T = num::cast(0); let _1: T = num::cast(1); let _2: T = num::cast(2); diff --git a/src/quat.rs b/src/quat.rs index 021926d..107b7b8 100644 --- a/src/quat.rs +++ b/src/quat.rs @@ -10,11 +10,11 @@ use core::num::Zero::zero; use core::num::One::one; use std::cmp::{FuzzyEq, FUZZY_EPSILON}; -use numeric::*; use mat::{Mat3, BaseMat3}; use vec::{Vec3, BaseVec3, AffineVec, NumVec, NumVec3}; -use vec::{vec3, dvec3, Vec3f, Vec3f32, Vec3f64}; + +use num::NumAssign; /** * A quaternion in scalar/vector form @@ -31,7 +31,7 @@ use vec::{vec3, dvec3, Vec3f, Vec3f32, Vec3f64}; #[deriving(Eq)] pub struct Quat { s: T, v: Vec3 } -pub impl Quat { +pub impl> Quat { /** * Construct the quaternion from one scalar component and three * imaginary components @@ -84,19 +84,19 @@ pub impl Quat { #[inline(always)] fn from_angle_x(radians: T) -> Quat { let _2 = num::cast(2); - Quat::new(cos(radians / _2), sin(radians), zero(), zero()) + Quat::new((radians / _2).cos(), radians.sin(), zero(), zero()) } #[inline(always)] fn from_angle_y(radians: T) -> Quat { let _2 = num::cast(2); - Quat::new(cos(radians / _2), zero(), sin(radians), zero()) + Quat::new((radians / _2).cos(), zero(), radians.sin(), zero()) } #[inline(always)] fn from_angle_z(radians: T) -> Quat { let _2 = num::cast(2); - Quat::new(cos(radians / _2), zero(), zero(), sin(radians)) + Quat::new((radians / _2).cos(), zero(), zero(), radians.sin()) } #[inline(always)] @@ -106,16 +106,16 @@ pub impl Quat { let xdiv2 = radians_x / _2; let ydiv2 = radians_y / _2; let zdiv2 = radians_z / _2; - Quat::new(cos(zdiv2) * cos(xdiv2) * cos(ydiv2) + sin(zdiv2) * sin(xdiv2) * sin(ydiv2), - sin(zdiv2) * cos(xdiv2) * cos(ydiv2) - cos(zdiv2) * sin(xdiv2) * sin(ydiv2), - cos(zdiv2) * sin(xdiv2) * cos(ydiv2) + sin(zdiv2) * cos(xdiv2) * sin(ydiv2), - cos(zdiv2) * cos(xdiv2) * sin(ydiv2) - sin(zdiv2) * sin(xdiv2) * cos(ydiv2)) + 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.cos() * xdiv2.sin() * ydiv2.cos() + zdiv2.sin() * xdiv2.cos() * ydiv2.sin(), + zdiv2.cos() * xdiv2.cos() * ydiv2.sin() - zdiv2.sin() * xdiv2.sin() * ydiv2.cos()) } #[inline(always)] fn from_angle_axis(radians: T, axis: &Vec3) -> Quat { let half = radians / num::cast(2); - Quat::from_sv(cos(half), axis.mul_t(sin(half))) + Quat::from_sv(half.cos(), axis.mul_t(half.sin())) } #[inline(always)] @@ -318,15 +318,16 @@ pub impl Quat { if dot > dot_threshold { return self.nlerp(other, amount); // if quaternions are close together use `nlerp` } else { - let robust_dot = dot.clamp(-one::(), one()); // stay within the domain of acos() + let robust_dot = dot.clamp(&-one::(), &one()); // stay within the domain of acos() - let theta_0 = acos(robust_dot); // the angle between the quaternions + let theta_0 = robust_dot.acos(); // the angle between the quaternions let theta = theta_0 * amount; // the fraction of theta specified by `amount` let q = other.sub_q(&self.mul_t(robust_dot)) .normalize(); - return self.mul_t(cos(theta)).add_q(&q.mul_t(sin(theta))); + return self.mul_t(theta.cos()) + .add_q(&q.mul_t(theta.sin())); } } @@ -376,14 +377,14 @@ impl Index for Quat { } } -impl Neg> for Quat { +impl> Neg> for Quat { #[inline(always)] fn neg(&self) -> Quat { Quat::new(-self[0], -self[1], -self[2], -self[3]) } } -impl FuzzyEq for Quat { +impl> FuzzyEq for Quat { #[inline(always)] fn fuzzy_eq(&self, other: &Quat) -> bool { self.fuzzy_eq_eps(other, &num::cast(FUZZY_EPSILON)) @@ -397,46 +398,3 @@ impl FuzzyEq for Quat { self[3].fuzzy_eq_eps(&other[3], epsilon) } } - -macro_rules! quat_type( - ($name:ident <$T:ty, $V:ty>) => ( - pub impl $name { - #[inline(always)] fn new(w: $T, xi: $T, yj: $T, zk: $T) -> $name { Quat::new(w, xi, yj, zk) } - #[inline(always)] fn from_sv(s: $T, v: $V) -> $name { Quat::from_sv(s, v) } - #[inline(always)] fn identity() -> $name { Quat::identity() } - #[inline(always)] fn zero() -> $name { Quat::zero() } - - #[inline(always)] fn from_angle_x(radians: $T) -> $name { Quat::from_angle_x(radians) } - #[inline(always)] fn from_angle_y(radians: $T) -> $name { Quat::from_angle_y(radians) } - #[inline(always)] fn from_angle_z(radians: $T) -> $name { Quat::from_angle_z(radians) } - #[inline(always)] fn from_angle_xyz(radians_x: $T, radians_y: $T, radians_z: $T) - -> $name { Quat::from_angle_xyz(radians_x, radians_y, radians_z) } - #[inline(always)] fn from_angle_axis(radians: $T, axis: &$V) -> $name { Quat::from_angle_axis(radians, axis) } - #[inline(always)] fn from_axes(x: $V, y: $V, z: $V) -> $name { Quat::from_axes(x, y, z) } - #[inline(always)] fn look_at(dir: &$V, up: &$V) -> $name { Quat::look_at(dir, up) } - - #[inline(always)] fn dim() -> uint { 4 } - #[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() } - } - ); -) - -// GLSL-style type aliases for quaternions. These are not present in the GLSL -// specification, but they roughly follow the same nomenclature. - -/// a single-precision floating-point quaternion -type quat = Quat; -/// a double-precision floating-point quaternion -type dquat = Quat; - -quat_type!(quat) -quat_type!(dquat) - -// Rust-style type aliases -type Quatf = Quat; -type Quatf32 = Quat; -type Quatf64 = Quat; - -quat_type!(Quatf) -quat_type!(Quatf32) -quat_type!(Quatf64) \ No newline at end of file diff --git a/src/vec.rs b/src/vec.rs index 4ca7918..93339c8 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -1,7 +1,8 @@ use core::num::Zero::zero; use core::num::One::one; use std::cmp::{FuzzyEq, FUZZY_EPSILON}; -use numeric::*; + +use num::NumAssign; /** * The base generic vector trait. @@ -496,13 +497,13 @@ macro_rules! zip_vec4( ) macro_rules! zip_assign( - ($a:ident[] $method:ident $b:ident[] ..2) => ({ $a.index_mut(0).$method($b[0]); $a.index_mut(1).$method($b[1]); }); - ($a:ident[] $method:ident $b:ident[] ..3) => ({ zip_assign!($a[] $method $b[] ..2); $a.index_mut(2).$method($b[2]); }); - ($a:ident[] $method:ident $b:ident[] ..4) => ({ zip_assign!($a[] $method $b[] ..3); $a.index_mut(3).$method($b[3]); }); + ($a:ident[] $method:ident $b:ident[] ..2) => ({ $a.index_mut(0).$method(&$b[0]); $a.index_mut(1).$method(&$b[1]); }); + ($a:ident[] $method:ident $b:ident[] ..3) => ({ zip_assign!($a[] $method $b[] ..2); $a.index_mut(2).$method(&$b[2]); }); + ($a:ident[] $method:ident $b:ident[] ..4) => ({ zip_assign!($a[] $method $b[] ..3); $a.index_mut(3).$method(&$b[3]); }); - ($a:ident[] $method:ident $b:ident ..2) => ({ $a.index_mut(0).$method($b); $a.index_mut(1).$method($b); }); - ($a:ident[] $method:ident $b:ident ..3) => ({ zip_assign!($a[] $method $b ..2); $a.index_mut(2).$method($b); }); - ($a:ident[] $method:ident $b:ident ..4) => ({ zip_assign!($a[] $method $b ..3); $a.index_mut(3).$method($b); }); + ($a:ident[] $method:ident $b:ident ..2) => ({ $a.index_mut(0).$method(&$b); $a.index_mut(1).$method(&$b); }); + ($a:ident[] $method:ident $b:ident ..3) => ({ zip_assign!($a[] $method $b ..2); $a.index_mut(2).$method(&$b); }); + ($a:ident[] $method:ident $b:ident ..4) => ({ zip_assign!($a[] $method $b ..3); $a.index_mut(3).$method(&$b); }); ) /** @@ -561,7 +562,7 @@ impl Index for Vec2 { } } -impl NumVec for Vec2 { +impl NumVec for Vec2 { #[inline(always)] fn identity() -> Vec2 { BaseVec2::new(one::(), one::()) @@ -651,14 +652,14 @@ impl NumVec for Vec2 { } } -impl Neg> for Vec2 { +impl Neg> for Vec2 { #[inline(always)] fn neg(&self) -> Vec2 { BaseVec2::new(-self[0], -self[1]) } } -impl NumVec2 for Vec2 { +impl NumVec2 for Vec2 { #[inline(always)] fn unit_x() -> Vec2 { BaseVec2::new(one::(), zero::()) @@ -675,14 +676,14 @@ impl NumVec2 for Vec2 { } } -impl ToHomogeneous> for Vec2 { +impl ToHomogeneous> for Vec2 { #[inline(always)] fn to_homogeneous(&self) -> Vec3 { BaseVec3::new(self.x, self.y, zero()) } } -impl AffineVec for Vec2 { +impl AffineVec for Vec2 { #[inline(always)] fn length2(&self) -> T { self.dot(self) @@ -705,7 +706,7 @@ impl AffineVec for Vec2 { #[inline(always)] fn angle(&self, other: &Vec2) -> T { - atan2(self.perp_dot(other), self.dot(other)) + self.perp_dot(other).atan2(self.dot(other)) } #[inline(always)] @@ -741,7 +742,7 @@ impl AffineVec for Vec2 { } } -impl> FuzzyEq for Vec2 { +impl> FuzzyEq for Vec2 { #[inline(always)] fn fuzzy_eq(&self, other: &Vec2) -> bool { self.fuzzy_eq_eps(other, &num::cast(FUZZY_EPSILON)) @@ -805,83 +806,6 @@ impl BoolVec for Vec2 { } } -macro_rules! vec2_type( - ($name:ident ) => ( - pub impl $name { - #[inline(always)] fn new(x: bool, y: bool) -> $name { BaseVec2::new(x, y) } - #[inline(always)] fn from_value(v: bool) -> $name { BaseVec::from_value(v) } - - #[inline(always)] fn dim() -> uint { 2 } - #[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() } - } - ); - ($name:ident <$T:ty>) => ( - pub impl $name { - #[inline(always)] fn new(x: $T, y: $T) -> $name { BaseVec2::new(x, y) } - #[inline(always)] fn from_value(v: $T) -> $name { BaseVec::from_value(v) } - #[inline(always)] fn identity() -> $name { NumVec::identity() } - #[inline(always)] fn zero() -> $name { NumVec::zero() } - - #[inline(always)] fn unit_x() -> $name { NumVec2::unit_x() } - #[inline(always)] fn unit_y() -> $name { NumVec2::unit_y() } - - #[inline(always)] fn dim() -> uint { 2 } - #[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() } - } - ); -) - -// GLSL-style type aliases, corresponding to Section 4.1.5 of the [GLSL 4.30.6 specification] -// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf). - -// a two-component single-precision floating-point vector -pub type vec2 = Vec2; -// a two-component double-precision floating-point vector -pub type dvec2 = Vec2; -// a two-component Boolean vector -pub type bvec2 = Vec2; -// a two-component signed integer vector -pub type ivec2 = Vec2; -// a two-component unsigned integer vector -pub type uvec2 = Vec2; - -vec2_type!(vec2) -vec2_type!(dvec2) -vec2_type!(bvec2) -vec2_type!(ivec2) -vec2_type!(uvec2) - -// Rust-style type aliases -pub type Vec2f = Vec2; -pub type Vec2f32 = Vec2; -pub type Vec2f64 = Vec2; -pub type Vec2i = Vec2; -pub type Vec2i8 = Vec2; -pub type Vec2i16 = Vec2; -pub type Vec2i32 = Vec2; -pub type Vec2i64 = Vec2; -pub type Vec2u = Vec2; -pub type Vec2u8 = Vec2; -pub type Vec2u16 = Vec2; -pub type Vec2u32 = Vec2; -pub type Vec2u64 = Vec2; -pub type Vec2b = Vec2; - -vec2_type!(Vec2f) -vec2_type!(Vec2f32) -vec2_type!(Vec2f64) -vec2_type!(Vec2i) -vec2_type!(Vec2i8) -vec2_type!(Vec2i16) -vec2_type!(Vec2i32) -vec2_type!(Vec2i64) -vec2_type!(Vec2u) -vec2_type!(Vec2u8) -vec2_type!(Vec2u16) -vec2_type!(Vec2u32) -vec2_type!(Vec2u64) -vec2_type!(Vec2b) - /** * A 3-dimensional vector * @@ -940,7 +864,7 @@ impl Index for Vec3 { } } -impl NumVec for Vec3 { +impl NumVec for Vec3 { #[inline(always)] fn identity() -> Vec3 { BaseVec3::new(one::(), one::(), one::()) @@ -1033,14 +957,14 @@ impl NumVec for Vec3 { } } -impl Neg> for Vec3 { +impl Neg> for Vec3 { #[inline(always)] fn neg(&self) -> Vec3 { BaseVec3::new(-self[0], -self[1], -self[2]) } } -impl NumVec3 for Vec3 { +impl NumVec3 for Vec3 { #[inline(always)] fn unit_x() -> Vec3 { BaseVec3::new(one::(), zero::(), zero::()) @@ -1069,14 +993,14 @@ impl NumVec3 for Vec3 { } } -impl ToHomogeneous> for Vec3 { +impl ToHomogeneous> for Vec3 { #[inline(always)] fn to_homogeneous(&self) -> Vec4 { BaseVec4::new(self.x, self.y, self.z, zero()) } } -impl AffineVec for Vec3 { +impl AffineVec for Vec3 { #[inline(always)] fn length2(&self) -> T { self.dot(self) @@ -1099,7 +1023,7 @@ impl AffineVec for Vec3 { #[inline(always)] fn angle(&self, other: &Vec3) -> T { - atan2(self.cross(other).length(), self.dot(other)) + self.cross(other).length().atan2(self.dot(other)) } #[inline(always)] @@ -1135,7 +1059,7 @@ impl AffineVec for Vec3 { } } -impl> FuzzyEq for Vec3 { +impl> FuzzyEq for Vec3 { #[inline(always)] fn fuzzy_eq(&self, other: &Vec3) -> bool { self.fuzzy_eq_eps(other, &num::cast(FUZZY_EPSILON)) @@ -1200,84 +1124,6 @@ impl BoolVec for Vec3 { } } -macro_rules! vec3_type( - ($name:ident ) => ( - pub impl $name { - #[inline(always)] fn new(x: bool, y: bool, z: bool) -> $name { BaseVec3::new(x, y, z) } - #[inline(always)] fn from_value(v: bool) -> $name { BaseVec::from_value(v) } - - #[inline(always)] fn dim() -> uint { 3 } - #[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() } - } - ); - ($name:ident <$T:ty>) => ( - pub impl $name { - #[inline(always)] fn new(x: $T, y: $T, z: $T) -> $name { BaseVec3::new(x, y, z) } - #[inline(always)] fn from_value(v: $T) -> $name { BaseVec::from_value(v) } - #[inline(always)] fn identity() -> $name { NumVec::identity() } - #[inline(always)] fn zero() -> $name { NumVec::zero() } - - #[inline(always)] fn unit_x() -> $name { NumVec3::unit_x() } - #[inline(always)] fn unit_y() -> $name { NumVec3::unit_y() } - #[inline(always)] fn unit_z() -> $name { NumVec3::unit_z() } - - #[inline(always)] fn dim() -> uint { 3 } - #[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() } - } - ); -) - -// GLSL-style type aliases, corresponding to Section 4.1.5 of the [GLSL 4.30.6 specification] -// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf). - -// a three-component single-precision floating-point vector -pub type vec3 = Vec3; -// a three-component double-precision floating-point vector -pub type dvec3 = Vec3; -// a three-component Boolean vector -pub type bvec3 = Vec3; -// a three-component signed integer vector -pub type ivec3 = Vec3; -// a three-component unsigned integer vector -pub type uvec3 = Vec3; - -vec3_type!(vec3) -vec3_type!(dvec3) -vec3_type!(bvec3) -vec3_type!(ivec3) -vec3_type!(uvec3) - -// Rust-style type aliases -pub type Vec3f = Vec3; -pub type Vec3f32 = Vec3; -pub type Vec3f64 = Vec3; -pub type Vec3i = Vec3; -pub type Vec3i8 = Vec3; -pub type Vec3i16 = Vec3; -pub type Vec3i32 = Vec3; -pub type Vec3i64 = Vec3; -pub type Vec3u = Vec3; -pub type Vec3u8 = Vec3; -pub type Vec3u16 = Vec3; -pub type Vec3u32 = Vec3; -pub type Vec3u64 = Vec3; -pub type Vec3b = Vec3; - -vec3_type!(Vec3f) -vec3_type!(Vec3f32) -vec3_type!(Vec3f64) -vec3_type!(Vec3i) -vec3_type!(Vec3i8) -vec3_type!(Vec3i16) -vec3_type!(Vec3i32) -vec3_type!(Vec3i64) -vec3_type!(Vec3u) -vec3_type!(Vec3u8) -vec3_type!(Vec3u16) -vec3_type!(Vec3u32) -vec3_type!(Vec3u64) -vec3_type!(Vec3b) - /** * A 4-dimensional vector * @@ -1338,7 +1184,7 @@ impl Index for Vec4 { } } -impl NumVec for Vec4 { +impl NumVec for Vec4 { #[inline(always)] fn identity() -> Vec4 { BaseVec4::new(one::(), one::(), one::(), one::()) @@ -1434,14 +1280,14 @@ impl NumVec for Vec4 { } } -impl Neg> for Vec4 { +impl Neg> for Vec4 { #[inline(always)] fn neg(&self) -> Vec4 { BaseVec4::new(-self[0], -self[1], -self[2], -self[3]) } } -impl NumVec4 for Vec4 { +impl NumVec4 for Vec4 { #[inline(always)] fn unit_x() -> Vec4 { BaseVec4::new(one::(), zero::(), zero::(), zero::()) @@ -1463,7 +1309,7 @@ impl NumVec4 for Vec4 { } } -impl AffineVec for Vec4 { +impl AffineVec for Vec4 { #[inline(always)] fn length2(&self) -> T { self.dot(self) @@ -1486,7 +1332,7 @@ impl AffineVec for Vec4 { #[inline(always)] fn angle(&self, other: &Vec4) -> T { - acos(self.dot(other) / (self.length() * other.length())) + (self.dot(other) / (self.length() * other.length())).acos() } #[inline(always)] @@ -1522,7 +1368,7 @@ impl AffineVec for Vec4 { } } -impl> FuzzyEq for Vec4 { +impl> FuzzyEq for Vec4 { #[inline(always)] fn fuzzy_eq(&self, other: &Vec4) -> bool { self.fuzzy_eq_eps(other, &num::cast(FUZZY_EPSILON)) @@ -1587,82 +1433,3 @@ impl BoolVec for Vec4 { BaseVec4::new(!self[0], !self[1], !self[2], !self[3]) } } - -macro_rules! vec4_type( - ($name:ident ) => ( - pub impl $name { - #[inline(always)] fn new(x: bool, y: bool, z: bool, w: bool) -> $name { BaseVec4::new(x, y, z, w) } - #[inline(always)] fn from_value(v: bool) -> $name { BaseVec::from_value(v) } - - #[inline(always)] fn dim() -> uint { 4 } - #[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() } - } - ); - ($name:ident <$T:ty>) => ( - pub impl $name { - #[inline(always)] fn new(x: $T, y: $T, z: $T, w: $T) -> $name { BaseVec4::new(x, y, z, w) } - #[inline(always)] fn from_value(v: $T) -> $name { BaseVec::from_value(v) } - #[inline(always)] fn identity() -> $name { NumVec::identity() } - #[inline(always)] fn zero() -> $name { NumVec::zero() } - - #[inline(always)] fn unit_x() -> $name { NumVec4::unit_x() } - #[inline(always)] fn unit_y() -> $name { NumVec4::unit_y() } - #[inline(always)] fn unit_z() -> $name { NumVec4::unit_z() } - #[inline(always)] fn unit_w() -> $name { NumVec4::unit_w() } - - #[inline(always)] fn dim() -> uint { 4 } - #[inline(always)] fn size_of() -> uint { sys::size_of::<$name>() } - } - ); -) - -// GLSL-style type aliases, corresponding to Section 4.1.5 of the [GLSL 4.30.6 specification] -// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf). - -// a four-component single-precision floating-point vector -pub type vec4 = Vec4; -// a four-component double-precision floating-point vector -pub type dvec4 = Vec4; -// a four-component Boolean vector -pub type bvec4 = Vec4; -// a four-component signed integer vector -pub type ivec4 = Vec4; -// a four-component unsigned integer vector -pub type uvec4 = Vec4; - -vec4_type!(vec4) -vec4_type!(dvec4) -vec4_type!(bvec4) -vec4_type!(ivec4) -vec4_type!(uvec4) - -// Rust-style type aliases -pub type Vec4f = Vec4; -pub type Vec4f32 = Vec4; -pub type Vec4f64 = Vec4; -pub type Vec4i = Vec4; -pub type Vec4i8 = Vec4; -pub type Vec4i16 = Vec4; -pub type Vec4i32 = Vec4; -pub type Vec4i64 = Vec4; -pub type Vec4u = Vec4; -pub type Vec4u8 = Vec4; -pub type Vec4u16 = Vec4; -pub type Vec4u32 = Vec4; -pub type Vec4u64 = Vec4; -pub type Vec4b = Vec4; - -vec4_type!(Vec4f) -vec4_type!(Vec4f32) -vec4_type!(Vec4f64) -vec4_type!(Vec4i) -vec4_type!(Vec4i8) -vec4_type!(Vec4i16) -vec4_type!(Vec4i32) -vec4_type!(Vec4i64) -vec4_type!(Vec4u) -vec4_type!(Vec4u8) -vec4_type!(Vec4u16) -vec4_type!(Vec4u32) -vec4_type!(Vec4u64) -vec4_type!(Vec4b) \ No newline at end of file