From bf6bf8b3e6c590af2a0038abb736d3a5447e5f1b Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Thu, 1 Nov 2012 11:34:38 +1000 Subject: [PATCH] Make library generic --- src/math.rs | 141 +++-------- src/matrix.rs | 469 +++++++++++++++++++----------------- src/num_util.rs | 428 ++++++++++++++++++++++++++++++++ src/omath.rc | 1 + src/projection.rs | 38 +-- src/quaternion.rs | 95 ++++---- src/test/test_matrix.rs | 24 +- src/test/test_quaternion.rs | 4 +- src/test/test_vector.rs | 32 ++- src/vector.rs | 329 ++++++++++++------------- 10 files changed, 963 insertions(+), 598 deletions(-) create mode 100644 src/num_util.rs diff --git a/src/math.rs b/src/math.rs index ec19ef6..6a205d4 100644 --- a/src/math.rs +++ b/src/math.rs @@ -1,6 +1,8 @@ use cmp::Ord; use num::{Num, from_int}; +use num_util::*; + // TODO: move to a more appropriate module pub trait ToPtr { pure fn to_ptr() -> *T; @@ -10,24 +12,29 @@ pub trait ExactEq { pure fn exact_eq(other: &self) -> bool; } -// -// Min -// -#[inline(always)] -pure fn min(a: &T, b: &T) -> T { - if a < b { *a } - else { *b } +trait MinMax { + pure fn min(other: &self) -> self; + pure fn max(other: &self) -> self; } -// -// Max -// -#[inline(always)] -pure fn max(a: &T, b: &T) -> T { - if a > b { *a } - else { *b } +#[inline(always)] pure fn min(a: &T, b: &T) -> T { a.min(b) } +#[inline(always)] pure fn max(a: &T, b: &T) -> T { a.max(b) } + +impl float: MinMax { + pure fn min(other: &float) -> float { + if self < *other { self } + else { *other } + } + + pure fn max(other: &float) -> float { + if self > *other { self } + else { *other } + } + } + + // #[inline(always)] // pure fn abs(x: &T) -> T { // if x >= &from_int(0) { *x } else {-x } @@ -85,14 +92,6 @@ impl int: Abs { } } -impl float: Abs { - #[inline(always)] - pure fn abs() -> float { - if self >= 0f { self } - else {-self } - } -} - impl f32: Abs { #[inline(always)] pure fn abs() -> f32 { @@ -109,6 +108,14 @@ impl f64: Abs { } } +impl float: Abs { + #[inline(always)] + pure fn abs() -> float { + if self >= 0f { self } + else {-self } + } +} + // // Sqrt // @@ -121,93 +128,9 @@ pure fn sqrt(x: T) -> T { x.sqrt() } -impl u8: Sqrt { +pub impl T: Sqrt { #[inline(always)] - pure fn sqrt() -> u8 { - (self as float).sqrt() as u8 - } -} - -impl u16: Sqrt { - #[inline(always)] - pure fn sqrt() -> u16 { - (self as float).sqrt() as u16 - } -} - -impl u32: Sqrt { - #[inline(always)] - pure fn sqrt() -> u32 { - (self as float).sqrt() as u32 - } -} - -impl u64: Sqrt { - #[inline(always)] - pure fn sqrt() -> u64 { - (self as float).sqrt() as u64 - } -} - -impl uint: Sqrt { - #[inline(always)] - pure fn sqrt() -> uint { - (self as float).sqrt() as uint - } -} - -impl i8: Sqrt { - #[inline(always)] - pure fn sqrt() -> i8 { - (self as float).sqrt() as i8 - } -} - -impl i16: Sqrt { - #[inline(always)] - pure fn sqrt() -> i16 { - (self as float).sqrt() as i16 - } -} - -impl i32: Sqrt { - #[inline(always)] - pure fn sqrt() -> i32 { - (self as float).sqrt() as i32 - } -} - -impl i64: Sqrt { - #[inline(always)] - pure fn sqrt() -> i64 { - (self as float).sqrt() as i64 - } -} - -impl int: Sqrt { - #[inline(always)] - pure fn sqrt() -> int { - (self as float).sqrt() as int - } -} - -impl float: Sqrt { - #[inline(always)] - pure fn sqrt() -> float { - float::sqrt(self) - } -} - -impl f32: Sqrt { - #[inline(always)] - pure fn sqrt() -> f32 { - f32::sqrt(self) - } -} - -impl f64: Sqrt { - #[inline(always)] - pure fn sqrt() -> f64 { - f64::sqrt(self) + pure fn sqrt() -> T { + f64::sqrt(self.cast()).cast() } } \ No newline at end of file diff --git a/src/matrix.rs b/src/matrix.rs index 02d8167..3f5be45 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -1,7 +1,10 @@ use std::cmp::FuzzyEq; use cmp::Eq; -use math::{ToPtr, ExactEq, Sqrt}; -use quaternion::Quat; +use num::from_int; + +use math::*; +use num_util::*; +use quaternion::{Quat, ToQuat}; use vector::{Vec2, Vec3, Vec4}; // @@ -33,18 +36,17 @@ pub trait Matrix { // // 3x3 Matrix // -pub trait Matrix3 { - pure fn scale(vec: &V3) -> self; - pure fn to_Mat4() -> Mat4; - pure fn to_Quat() -> Quat; +pub trait Matrix3 { + pure fn scale(vec: &Vec3) -> self; + pure fn to_Mat4() -> Mat4; } // // 4x4 Matrix // -pub trait Matrix4 { - pure fn scale(vec: &V3) -> self; - pure fn translate(vec: &V3) -> self; +pub trait Matrix4 { + pure fn scale(vec: &Vec3) -> self; + pure fn translate(vec: &Vec3) -> self; } @@ -55,19 +57,14 @@ pub trait Matrix4 { // // Mat2: A 2x2, column major matrix // -pub struct Mat2 { data:[Vec2 * 2] } - -pub const mat2_zero :Mat2 = Mat2 { data: [ Vec2::zero, - Vec2::zero ] }; -pub const mat2_identity :Mat2 = Mat2 { data: [ Vec2::unit_x, - Vec2::unit_y ] }; +pub struct Mat2 { data:[Vec2 * 2] } // // Mat2 Constructor // #[inline(always)] -pub pure fn Mat2(m00:float, m01:float, - m10:float, m11:float) -> Mat2 { +pub pure fn Mat2(m00: T, m01: T, + m10: T, m11: T) -> Mat2 { Mat2 { data: [ Vec2(m00, m01), Vec2(m10, m11) ] } } @@ -76,21 +73,28 @@ pub pure fn Mat2(m00:float, m01:float, // Construct Mat2 from column vectors // #[inline(always)] -pub pure fn Mat2_v(col0: &Vec2, col1: &Vec2) -> Mat2 { - Mat2 { data: [ *col0, *col1 ] } +pub pure fn Mat2_v(col0: &Vec2, col1: &Vec2) -> Mat2 { + Mat2 { data: [ *move col0, *move col1 ] } } pub mod Mat2 { - pub const zero :Mat2 = Mat2 { data: [ Vec2::zero, - Vec2::zero ] }; - pub const identity :Mat2 = Mat2 { data: [ Vec2::unit_x, - Vec2::unit_y ] }; + #[inline(always)] + pub pure fn zero() -> Mat2 { + Mat2 { data: [ Vec2::zero(), + Vec2::zero() ] } + } + + #[inline(always)] + pub pure fn identity() -> Mat2 { + Mat2 { data: [ Vec2::unit_x(), + Vec2::unit_y() ] } + } } // // Matrix2x2 Implementation // -pub impl Mat2: Matrix { +pub impl Mat2: Matrix> { #[inline(always)] pure fn rows() -> uint { 2 } @@ -101,62 +105,62 @@ pub impl Mat2: Matrix { pure fn is_col_major() -> bool { true } #[inline(always)] - pure fn row(i: uint) -> Vec2 { + pure fn row(i: uint) -> Vec2 { Vec2(self[0][i], self[1][i]) } #[inline(always)] - pure fn col(i: uint) -> Vec2 { + pure fn col(i: uint) -> Vec2 { self.data[i] } #[inline(always)] - pure fn mul_t(value: float) -> Mat2 { + pure fn mul_t(value: T) -> Mat2 { Mat2_v(&self[0].mul_t(value), &self[1].mul_t(value)) } #[inline(always)] - pure fn mul_v(other: &Vec2) -> Vec2 { - Vec2(self[0][0]*other[0] + self[1][0]*other[1], - self[0][1]*other[0] + self[1][1]*other[1]) + pure fn mul_v(other: &Vec2) -> Vec2 { + Vec2(self[0][0] * other[0] + self[1][0] * other[1], + self[0][1] * other[0] + self[1][1] * other[1]) } #[inline(always)] - pure fn add_m(other: &Mat2) -> Mat2 { + pure fn add_m(other: &Mat2) -> Mat2 { Mat2_v(&self[0].add_v(&other[0]), &self[1].add_v(&other[1])) } #[inline(always)] - pure fn sub_m(other: &Mat2) -> Mat2 { + pure fn sub_m(other: &Mat2) -> Mat2 { Mat2_v(&self[0].sub_v(&other[0]), &self[1].sub_v(&other[1])) } #[inline(always)] - pure fn mul_m(other: &Mat2) -> Mat2 { - Mat2(self[0][0]*other[0][0] + self[1][0]*other[0][1], - self[0][1]*other[0][0] + self[1][1]*other[0][1], + pure fn mul_m(other: &Mat2) -> Mat2 { + Mat2(self[0][0] * other[0][0] + self[1][0] * other[0][1], + self[0][1] * other[0][0] + self[1][1] * other[0][1], - self[0][0]*other[1][0] + self[1][0]*other[1][1], - self[0][1]*other[1][0] + self[1][1]*other[1][1]) + self[0][0] * other[1][0] + self[1][0] * other[1][1], + self[0][1] * other[1][0] + self[1][1] * other[1][1]) } // TODO - inversion is harrrd D: // #[inline(always)] - // pure fn invert(other: &Mat2) -> Mat2 {} + // pure fn invert(other: &Mat2) -> Mat2 {} #[inline(always)] - pure fn transpose() -> Mat2 { + pure fn transpose() -> Mat2 { Mat2(self[0][0], self[1][0], self[0][1], self[1][1]) } #[inline(always)] pure fn is_identity() -> bool { - self.fuzzy_eq(&Mat2::identity) + self.fuzzy_eq(&Mat2::identity()) } #[inline(always)] @@ -167,65 +171,59 @@ pub impl Mat2: Matrix { #[inline(always)] pure fn is_diagonal() -> bool { - self[0][1].fuzzy_eq(&0f) && - self[1][0].fuzzy_eq(&0f) + self[0][1].fuzzy_eq(&from_int(0)) && + self[1][0].fuzzy_eq(&from_int(0)) } #[inline(always)] pure fn is_rotated() -> bool { - !self.fuzzy_eq(&Mat2::identity) + !self.fuzzy_eq(&Mat2::identity()) } } -pub impl Mat2: Index { +pub impl Mat2: Index> { #[inline(always)] - pure fn index(i: uint) -> Vec2 { + pure fn index(i: uint) -> Vec2 { self.data[i] } } -pub impl Mat2: Neg { +pub impl> Mat2: Neg> { #[inline(always)] - pure fn neg() -> Mat2 { + pure fn neg() -> Mat2 { Mat2_v(&-self[0], &-self[1]) } } -pub impl Mat2: Eq { +// TODO: make work for T:Integer +pub impl Mat2: Eq { #[inline(always)] - pure fn eq(other: &Mat2) -> bool { + pure fn eq(other: &Mat2) -> bool { self.fuzzy_eq(other) } #[inline(always)] - pure fn ne(other: &Mat2) -> bool { + pure fn ne(other: &Mat2) -> bool { !(self == *other) } } -impl Mat2: ExactEq { +impl Mat2: ExactEq { #[inline(always)] - pure fn exact_eq(other: &Mat2) -> bool { + pure fn exact_eq(other: &Mat2) -> bool { self[0].exact_eq(&other[0]) && self[1].exact_eq(&other[1]) } } -pub impl Mat2: FuzzyEq { +pub impl Mat2: FuzzyEq { #[inline(always)] - pure fn fuzzy_eq(other: &Mat2) -> bool { + pure fn fuzzy_eq(other: &Mat2) -> bool { self[0].fuzzy_eq(&other[0]) && self[1].fuzzy_eq(&other[1]) } } -pub impl Mat2: ToPtr { - #[inline(always)] - pure fn to_ptr() -> *float { - self[0].to_ptr() - } -} - @@ -234,15 +232,15 @@ pub impl Mat2: ToPtr { // // Mat3: A 3x3, column major matrix // -pub struct Mat3 { data:[Vec3 * 3] } +pub struct Mat3 { data:[Vec3 * 3] } // // Mat3 Constructor // #[inline(always)] -pub pure fn Mat3(m00:float, m01:float, m02:float, - m10:float, m11:float, m12:float, - m20:float, m21:float, m22:float) -> Mat3 { +pub pure fn Mat3(m00:T, m01:T, m02:T, + m10:T, m11:T, m12:T, + m20:T, m21:T, m22:T) -> Mat3 { Mat3 { data: [ Vec3(m00, m01, m02), Vec3(m10, m11, m12), Vec3(m20, m21, m22) ] } @@ -252,23 +250,30 @@ pub pure fn Mat3(m00:float, m01:float, m02:float, // Construct Mat3 from column vectors // #[inline(always)] -pub pure fn Mat3_v(col0: &Vec3, col1: &Vec3, col2: &Vec3) -> Mat3 { - Mat3 { data: [ *col0, *col1, *col2 ] } +pub pure fn Mat3_v(col0: &Vec3, col1: &Vec3, col2: &Vec3) -> Mat3 { + Mat3 { data: [ *move col0, *move col1, *move col2 ] } } pub mod Mat3 { - pub const zero :Mat3 = Mat3 { data: [ Vec3::zero, - Vec3::zero, - Vec3::zero ] }; - pub const identity :Mat3 = Mat3 { data: [ Vec3::unit_x, - Vec3::unit_y, - Vec3::unit_z ] }; + #[inline(always)] + pub pure fn zero() -> Mat3 { + Mat3 { data: [ Vec3::zero(), + Vec3::zero(), + Vec3::zero() ] } + } + + #[inline(always)] + pub pure fn identity() -> Mat3 { + Mat3 { data: [ Vec3::unit_x(), + Vec3::unit_y(), + Vec3::unit_z() ] } + } } // // Matrix3x3 Implementation // -pub impl Mat3: Matrix { +pub impl Mat3: Matrix> { #[inline(always)] pure fn rows() -> uint { 3 } @@ -279,58 +284,58 @@ pub impl Mat3: Matrix { pure fn is_col_major() -> bool { true } #[inline(always)] - pure fn row(i: uint) -> Vec3 { + pure fn row(i: uint) -> Vec3 { Vec3(self[0][i], self[1][i], self[2][i]) } #[inline(always)] - pure fn col(i: uint) -> Vec3 { + pure fn col(i: uint) -> Vec3 { self.data[i] } #[inline(always)] - pure fn mul_t(value: float) -> Mat3 { + pure fn mul_t(value: T) -> Mat3 { Mat3_v(&self[0].mul_t(value), &self[1].mul_t(value), &self[2].mul_t(value)) } #[inline(always)] - pure fn mul_v(other: &Vec3) -> Vec3 { - Vec3(self[0][0]*other[0] + self[1][0]*other[1] + self[2][0]*other[2], - self[0][1]*other[0] + self[1][1]*other[1] + self[2][1]*other[2], - self[0][2]*other[0] + self[1][2]*other[1] + self[2][2]*other[2]) + pure fn mul_v(other: &Vec3) -> Vec3 { + Vec3(self[0][0] * other[0] + self[1][0] * other[1] + self[2][0] * other[2], + self[0][1] * other[0] + self[1][1] * other[1] + self[2][1] * other[2], + self[0][2] * other[0] + self[1][2] * other[1] + self[2][2] * other[2]) } #[inline(always)] - pure fn add_m(other: &Mat3) -> Mat3 { + pure fn add_m(other: &Mat3) -> Mat3 { Mat3_v(&self[0].add_v(&other[0]), &self[1].add_v(&other[1]), &self[2].add_v(&other[2])) } #[inline(always)] - pure fn sub_m(other: &Mat3) -> Mat3 { + pure fn sub_m(other: &Mat3) -> Mat3 { Mat3_v(&self[0].sub_v(&other[0]), &self[1].sub_v(&other[1]), &self[2].sub_v(&other[2])) } #[inline(always)] - pure fn mul_m(other: &Mat3) -> Mat3 { - Mat3(self[0][0]*other[0][0] + self[1][0]*other[0][1] + self[2][0]*other[0][2], - self[0][1]*other[0][0] + self[1][1]*other[0][1] + self[2][1]*other[0][2], - self[0][2]*other[0][0] + self[1][2]*other[0][1] + self[2][2]*other[0][2], + pure fn mul_m(other: &Mat3) -> Mat3 { + Mat3(self[0][0] * other[0][0] + self[1][0] * other[0][1] + self[2][0] * other[0][2], + self[0][1] * other[0][0] + self[1][1] * other[0][1] + self[2][1] * other[0][2], + self[0][2] * other[0][0] + self[1][2] * other[0][1] + self[2][2] * other[0][2], - self[0][0]*other[1][0] + self[1][0]*other[1][1] + self[2][0]*other[1][2], - self[0][1]*other[1][0] + self[1][1]*other[1][1] + self[2][1]*other[1][2], - self[0][2]*other[1][0] + self[1][2]*other[1][1] + self[2][2]*other[1][2], + self[0][0] * other[1][0] + self[1][0] * other[1][1] + self[2][0] * other[1][2], + self[0][1] * other[1][0] + self[1][1] * other[1][1] + self[2][1] * other[1][2], + self[0][2] * other[1][0] + self[1][2] * other[1][1] + self[2][2] * other[1][2], - self[0][0]*other[2][0] + self[1][0]*other[2][1] + self[2][0]*other[2][2], - self[0][1]*other[2][0] + self[1][1]*other[2][1] + self[2][1]*other[2][2], - self[0][2]*other[2][0] + self[1][2]*other[2][1] + self[2][2]*other[2][2]) + self[0][0] * other[2][0] + self[1][0] * other[2][1] + self[2][0] * other[2][2], + self[0][1] * other[2][0] + self[1][1] * other[2][1] + self[2][1] * other[2][2], + self[0][2] * other[2][0] + self[1][2] * other[2][1] + self[2][2] * other[2][2]) } // TODO - inversion is harrrd D: @@ -338,7 +343,7 @@ pub impl Mat3: Matrix { // pure fn invert(other: &Mat3) -> Mat3 {} #[inline(always)] - pure fn transpose() -> Mat3 { + pure fn transpose() -> Mat3 { Mat3(self[0][0], self[1][0], self[2][0], self[0][1], self[1][1], self[2][1], self[0][2], self[1][2], self[2][2]) @@ -346,7 +351,7 @@ pub impl Mat3: Matrix { #[inline(always)] pure fn is_identity() -> bool { - self.fuzzy_eq(&Mat3::identity) + self.fuzzy_eq(&Mat3::identity()) } #[inline(always)] @@ -363,126 +368,130 @@ pub impl Mat3: Matrix { #[inline(always)] pure fn is_diagonal() -> bool { - self[0][1].fuzzy_eq(&0f) && - self[0][2].fuzzy_eq(&0f) && + self[0][1].fuzzy_eq(&from_int(0)) && + self[0][2].fuzzy_eq(&from_int(0)) && - self[1][0].fuzzy_eq(&0f) && - self[1][2].fuzzy_eq(&0f) && + self[1][0].fuzzy_eq(&from_int(0)) && + self[1][2].fuzzy_eq(&from_int(0)) && - self[2][0].fuzzy_eq(&0f) && - self[2][1].fuzzy_eq(&0f) + self[2][0].fuzzy_eq(&from_int(0)) && + self[2][1].fuzzy_eq(&from_int(0)) } #[inline(always)] pure fn is_rotated() -> bool { - !self.fuzzy_eq(&Mat3::identity) + !self.fuzzy_eq(&Mat3::identity()) } } -pub impl Mat3: Matrix3 { +pub impl Mat3: Matrix3 { #[inline(always)] - pure fn scale(vec: &Vec3) -> Mat3 { - self.mul_m(&Mat3(vec.x, 0f, 0f, - 0f, vec.y, 0f, - 0f, 0f, vec.z)) + pure fn scale(vec: &Vec3) -> Mat3 { + self.mul_m(&Mat3( vec.x, from_int(0), from_int(0), + from_int(0), vec.y, from_int(0), + from_int(0), from_int(0), vec.z)) } #[inline(always)] - pure fn to_Mat4() -> Mat4 { - Mat4(self[0][0], self[0][1], self[0][2], 0f, - self[1][0], self[1][1], self[1][2], 0f, - self[2][0], self[2][1], self[2][2], 0f, - 0f, 0f, 0f, 1f) + pure fn to_Mat4() -> Mat4 { + Mat4( self[0][0], self[0][1], self[0][2], from_int(0), + self[1][0], self[1][1], self[1][2], from_int(0), + self[2][0], self[2][1], self[2][2], from_int(0), + from_int(0), from_int(0), from_int(0), from_int(1)) } - - pure fn to_Quat() -> Quat { +} + +pub impl Mat3: ToQuat { + pure fn to_Quat() -> Quat { // Implemented using a mix of ideas from jMonkeyEngine and Ken Shoemake's // paper on Quaternions: http://www.cs.ucr.edu/~vbz/resources/Quatut.pdf - let mut s:float; - let w:float, x:float, y:float, z:float; - let trace:float = self[0][0] + self[1][1] + self[2][2]; + let mut s: float; + let w: float, x: float, y: float, z: float; + let trace: float = cast(self[0][0] + self[1][1] + self[2][2]); - if trace >= 0f { + if trace >= from_int(0) { s = (trace + 1f).sqrt(); w = 0.5 * s; s = 0.5 / s; - x = self[1][2] - self[2][1] * s; - y = self[2][0] - self[0][2] * s; - z = self[0][1] - self[1][0] * s; + x = (self[1][2] - self[2][1]).cast::() * s; + y = (self[2][0] - self[0][2]).cast::() * s; + z = (self[0][1] - self[1][0]).cast::() * s; } else if (self[0][0] > self[1][1]) && (self[0][0] > self[2][2]) { - s = (1f + self[0][0] - self[1][1] - self[2][2]).sqrt(); + s = (1f + (self[0][0] - self[1][1] - self[2][2]).cast::()).sqrt(); w = 0.5 * s; s = 0.5 / s; - x = self[0][1] - self[1][0] * s; - y = self[2][0] - self[0][2] * s; - z = self[1][2] - self[2][1] * s; + x = (self[0][1] - self[1][0]).cast::() * s; + y = (self[2][0] - self[0][2]).cast::() * s; + z = (self[1][2] - self[2][1]).cast::() * s; } else if self[1][1] > self[2][2] { - s = (1f + self[1][1] - self[0][0] - self[2][2]).sqrt(); + s = (1f + (self[1][1] - self[0][0] - self[2][2]).cast::()).sqrt(); w = 0.5 * s; s = 0.5 / s; - x = self[0][1] - self[1][0] * s; - y = self[1][2] - self[2][1] * s; - z = self[2][0] - self[0][2] * s; + x = (self[0][1] - self[1][0]).cast::() * s; + y = (self[1][2] - self[2][1]).cast::() * s; + z = (self[2][0] - self[0][2]).cast::() * s; } else { - s = (1f + self[2][2] - self[0][0] - self[1][1]).sqrt(); + s = (1f + (self[2][2] - self[0][0] - self[1][1]).cast::()).sqrt(); w = 0.5 * s; s = 0.5 / s; - x = self[2][0] - self[0][2] * s; - y = self[1][2] - self[2][1] * s; - z = self[0][1] - self[1][0] * s; + x = (self[2][0] - self[0][2]).cast::() * s; + y = (self[1][2] - self[2][1]).cast::() * s; + z = (self[0][1] - self[1][0]).cast::() * s; } - return Quat(w, x, y, z); + + Quat(from(w), from(x), from(y), from(z)) } } -pub impl Mat3: Index { +pub impl Mat3: Index> { #[inline(always)] - pure fn index(i: uint) -> Vec3 { + pure fn index(i: uint) -> Vec3 { self.data[i] } } -pub impl Mat3: Neg { +pub impl> Mat3: Neg> { #[inline(always)] - pure fn neg() -> Mat3 { + pure fn neg() -> Mat3 { Mat3_v(&-self[0], &-self[1], &-self[2]) } } -pub impl Mat3: Eq { +// TODO: make work for T:Integer +pub impl Mat3: Eq { #[inline(always)] - pure fn eq(other: &Mat3) -> bool { + pure fn eq(other: &Mat3) -> bool { self.fuzzy_eq(other) } #[inline(always)] - pure fn ne(other: &Mat3) -> bool { + pure fn ne(other: &Mat3) -> bool { !(self == *other) } } -impl Mat3: ExactEq { +pub impl Mat3: ExactEq { #[inline(always)] - pure fn exact_eq(other: &Mat3) -> bool { + pure fn exact_eq(other: &Mat3) -> bool { self[0].exact_eq(&other[0]) && self[1].exact_eq(&other[1]) && self[2].exact_eq(&other[2]) } } -pub impl Mat3: FuzzyEq { +pub impl Mat3: FuzzyEq { #[inline(always)] - pure fn fuzzy_eq(other: &Mat3) -> bool { + pure fn fuzzy_eq(other: &Mat3) -> bool { self[0].fuzzy_eq(&other[0]) && self[1].fuzzy_eq(&other[1]) && self[2].fuzzy_eq(&other[2]) } } -pub impl Mat3: ToPtr { +pub impl Mat3: ToPtr { #[inline(always)] - pure fn to_ptr() -> *float { + pure fn to_ptr() -> *T { self[0].to_ptr() } } @@ -495,16 +504,16 @@ pub impl Mat3: ToPtr { // // Mat4: A 4x4, column major matrix // -pub struct Mat4 { data:[Vec4 * 4] } +pub struct Mat4 { data:[Vec4 * 4] } // // Mat4 Constructor // #[inline(always)] -pub pure fn Mat4(m00:float, m01:float, m02:float, m03:float, - m10:float, m11:float, m12:float, m13:float, - m20:float, m21:float, m22:float, m23:float, - m30:float, m31:float, m32:float, m33:float) -> Mat4 { +pub pure fn Mat4(m00: T, m01: T, m02: T, m03: T, + m10: T, m11: T, m12: T, m13: T, + m20: T, m21: T, m22: T, m23: T, + m30: T, m31: T, m32: T, m33: T) -> Mat4 { Mat4 { data: [ Vec4(m00, m01, m02, m03), Vec4(m10, m11, m12, m13), Vec4(m20, m21, m22, m23), @@ -515,25 +524,32 @@ pub pure fn Mat4(m00:float, m01:float, m02:float, m03:float, // Construct Mat4 from column vectors // #[inline(always)] -pub pure fn Mat4_v(col0: &Vec4, col1: &Vec4, col2: &Vec4, col3: &Vec4) -> Mat4 { - Mat4 { data: [ *col0, *col1, *col2, *col3 ] } +pub pure fn Mat4_v(col0: &Vec4, col1: &Vec4, col2: &Vec4, col3: &Vec4) -> Mat4 { + Mat4 { data: [ *move col0, *move col1, *move col2, *move col3 ] } } pub mod Mat4 { - pub const zero :Mat4 = Mat4 { data: [ Vec4::zero, - Vec4::zero, - Vec4::zero, - Vec4::zero ] }; - pub const identity :Mat4 = Mat4 { data: [ Vec4::unit_x, - Vec4::unit_y, - Vec4::unit_z, - Vec4::unit_w ] }; + #[inline(always)] + pub pure fn zero() -> Mat4 { + Mat4 { data: [ Vec4::zero(), + Vec4::zero(), + Vec4::zero(), + Vec4::zero() ] } + } + + #[inline(always)] + pub pure fn identity() -> Mat4 { + Mat4 { data: [ Vec4::unit_x(), + Vec4::unit_y(), + Vec4::unit_z(), + Vec4::unit_w() ] } + } } // // Matrix4x4 Implementation // -pub impl Mat4: Matrix { +pub impl Mat4: Matrix> { #[inline(always)] pure fn rows() -> uint { 4 } @@ -544,7 +560,7 @@ pub impl Mat4: Matrix { pure fn is_col_major() -> bool { true } #[inline(always)] - pure fn row(i: uint) -> Vec4 { + pure fn row(i: uint) -> Vec4 { Vec4(self[0][i], self[1][i], self[2][i], @@ -552,12 +568,12 @@ pub impl Mat4: Matrix { } #[inline(always)] - pure fn col(i: uint) -> Vec4 { + pure fn col(i: uint) -> Vec4 { self.data[i] } #[inline(always)] - pure fn mul_t(value: float) -> Mat4 { + pure fn mul_t(value: T) -> Mat4 { Mat4_v(&self[0].mul_t(value), &self[1].mul_t(value), &self[2].mul_t(value), @@ -565,15 +581,15 @@ pub impl Mat4: Matrix { } #[inline(always)] - pure fn mul_v(other: &Vec4) -> Vec4 { - Vec4(self[0][0]*other[0] + self[1][0]*other[1] + self[2][0]*other[2] + self[3][0]*other[3], - self[0][1]*other[0] + self[1][1]*other[1] + self[2][1]*other[2] + self[3][1]*other[3], - self[0][2]*other[0] + self[1][2]*other[1] + self[2][2]*other[2] + self[3][2]*other[3], - self[0][3]*other[0] + self[1][3]*other[1] + self[2][3]*other[2] + self[3][3]*other[3]) + pure fn mul_v(other: &Vec4) -> Vec4 { + Vec4(self[0][0] * other[0] + self[1][0] * other[1] + self[2][0] * other[2] + self[3][0] * other[3], + self[0][1] * other[0] + self[1][1] * other[1] + self[2][1] * other[2] + self[3][1] * other[3], + self[0][2] * other[0] + self[1][2] * other[1] + self[2][2] * other[2] + self[3][2] * other[3], + self[0][3] * other[0] + self[1][3] * other[1] + self[2][3] * other[2] + self[3][3] * other[3]) } #[inline(always)] - pure fn add_m(other: &Mat4) -> Mat4 { + pure fn add_m(other: &Mat4) -> Mat4 { Mat4_v(&self[0].add_v(&other[0]), &self[1].add_v(&other[1]), &self[2].add_v(&other[2]), @@ -581,7 +597,7 @@ pub impl Mat4: Matrix { } #[inline(always)] - pure fn sub_m(other: &Mat4) -> Mat4 { + pure fn sub_m(other: &Mat4) -> Mat4 { Mat4_v(&self[0].sub_v(&other[0]), &self[1].sub_v(&other[1]), &self[2].sub_v(&other[2]), @@ -589,34 +605,34 @@ pub impl Mat4: Matrix { } #[inline(always)] - pure fn mul_m(other: &Mat4) -> Mat4 { - Mat4(self[0][0]*other[0][0] + self[1][0]*other[0][1] + self[2][0]*other[0][2] + self[3][0]*other[0][3], - self[0][1]*other[0][0] + self[1][1]*other[0][1] + self[2][1]*other[0][2] + self[3][1]*other[0][3], - self[0][2]*other[0][0] + self[1][2]*other[0][1] + self[2][2]*other[0][2] + self[3][2]*other[0][3], - self[0][3]*other[0][0] + self[1][3]*other[0][1] + self[2][3]*other[0][2] + self[3][3]*other[0][3], + pure fn mul_m(other: &Mat4) -> Mat4 { + Mat4(self[0][0] * other[0][0] + self[1][0] * other[0][1] + self[2][0] * other[0][2] + self[3][0] * other[0][3], + self[0][1] * other[0][0] + self[1][1] * other[0][1] + self[2][1] * other[0][2] + self[3][1] * other[0][3], + self[0][2] * other[0][0] + self[1][2] * other[0][1] + self[2][2] * other[0][2] + self[3][2] * other[0][3], + self[0][3] * other[0][0] + self[1][3] * other[0][1] + self[2][3] * other[0][2] + self[3][3] * other[0][3], - self[0][0]*other[1][0] + self[1][0]*other[1][1] + self[2][0]*other[1][2] + self[3][0]*other[1][3], - self[0][1]*other[1][0] + self[1][1]*other[1][1] + self[2][1]*other[1][2] + self[3][1]*other[1][3], - self[0][2]*other[1][0] + self[1][2]*other[1][1] + self[2][2]*other[1][2] + self[3][2]*other[1][3], - self[0][3]*other[1][0] + self[1][3]*other[1][1] + self[2][3]*other[1][2] + self[3][3]*other[1][3], + self[0][0] * other[1][0] + self[1][0] * other[1][1] + self[2][0] * other[1][2] + self[3][0] * other[1][3], + self[0][1] * other[1][0] + self[1][1] * other[1][1] + self[2][1] * other[1][2] + self[3][1] * other[1][3], + self[0][2] * other[1][0] + self[1][2] * other[1][1] + self[2][2] * other[1][2] + self[3][2] * other[1][3], + self[0][3] * other[1][0] + self[1][3] * other[1][1] + self[2][3] * other[1][2] + self[3][3] * other[1][3], - self[0][0]*other[2][0] + self[1][0]*other[2][1] + self[2][0]*other[2][2] + self[3][0]*other[2][3], - self[0][1]*other[2][0] + self[1][1]*other[2][1] + self[2][1]*other[2][2] + self[3][1]*other[2][3], - self[0][2]*other[2][0] + self[1][2]*other[2][1] + self[2][2]*other[2][2] + self[3][2]*other[2][3], - self[0][3]*other[2][0] + self[1][3]*other[2][1] + self[2][3]*other[2][2] + self[3][3]*other[2][3], + self[0][0] * other[2][0] + self[1][0] * other[2][1] + self[2][0] * other[2][2] + self[3][0] * other[2][3], + self[0][1] * other[2][0] + self[1][1] * other[2][1] + self[2][1] * other[2][2] + self[3][1] * other[2][3], + self[0][2] * other[2][0] + self[1][2] * other[2][1] + self[2][2] * other[2][2] + self[3][2] * other[2][3], + self[0][3] * other[2][0] + self[1][3] * other[2][1] + self[2][3] * other[2][2] + self[3][3] * other[2][3], - self[0][0]*other[3][0] + self[1][0]*other[3][1] + self[2][0]*other[3][2] + self[3][0]*other[3][3], - self[0][1]*other[3][0] + self[1][1]*other[3][1] + self[2][1]*other[3][2] + self[3][1]*other[3][3], - self[0][2]*other[3][0] + self[1][2]*other[3][1] + self[2][2]*other[3][2] + self[3][2]*other[3][3], - self[0][3]*other[3][0] + self[1][3]*other[3][1] + self[2][3]*other[3][2] + self[3][3]*other[3][3]) + self[0][0] * other[3][0] + self[1][0] * other[3][1] + self[2][0] * other[3][2] + self[3][0] * other[3][3], + self[0][1] * other[3][0] + self[1][1] * other[3][1] + self[2][1] * other[3][2] + self[3][1] * other[3][3], + self[0][2] * other[3][0] + self[1][2] * other[3][1] + self[2][2] * other[3][2] + self[3][2] * other[3][3], + self[0][3] * other[3][0] + self[1][3] * other[3][1] + self[2][3] * other[3][2] + self[3][3] * other[3][3]) } // TODO - inversion is harrrd D: // #[inline(always)] - // pure fn invert(other: &Mat4) -> Mat4 {} + // pure fn invert(other: &Mat4) -> Mat4 {} #[inline(always)] - pure fn transpose() -> Mat4 { + pure fn transpose() -> Mat4 { Mat4(self[0][0], self[1][0], self[2][0], self[3][0], self[0][1], self[1][1], self[2][1], self[3][1], self[0][2], self[1][2], self[2][2], self[3][2], @@ -625,7 +641,7 @@ pub impl Mat4: Matrix { #[inline(always)] pure fn is_identity() -> bool { - self.fuzzy_eq(&Mat4::identity) + self.fuzzy_eq(&Mat4::identity()) } #[inline(always)] @@ -649,40 +665,40 @@ pub impl Mat4: Matrix { #[inline(always)] pure fn is_diagonal() -> bool { - self[0][1].fuzzy_eq(&0f) && - self[0][2].fuzzy_eq(&0f) && - self[0][3].fuzzy_eq(&0f) && + self[0][1].fuzzy_eq(&from_int(0)) && + self[0][2].fuzzy_eq(&from_int(0)) && + self[0][3].fuzzy_eq(&from_int(0)) && - self[1][0].fuzzy_eq(&0f) && - self[1][2].fuzzy_eq(&0f) && - self[1][3].fuzzy_eq(&0f) && + self[1][0].fuzzy_eq(&from_int(0)) && + self[1][2].fuzzy_eq(&from_int(0)) && + self[1][3].fuzzy_eq(&from_int(0)) && - self[2][0].fuzzy_eq(&0f) && - self[2][1].fuzzy_eq(&0f) && - self[2][3].fuzzy_eq(&0f) && + self[2][0].fuzzy_eq(&from_int(0)) && + self[2][1].fuzzy_eq(&from_int(0)) && + self[2][3].fuzzy_eq(&from_int(0)) && - self[3][0].fuzzy_eq(&0f) && - self[3][1].fuzzy_eq(&0f) && - self[3][2].fuzzy_eq(&0f) + self[3][0].fuzzy_eq(&from_int(0)) && + self[3][1].fuzzy_eq(&from_int(0)) && + self[3][2].fuzzy_eq(&from_int(0)) } #[inline(always)] pure fn is_rotated() -> bool { - !self.fuzzy_eq(&Mat4::identity) + !self.fuzzy_eq(&Mat4::identity()) } } -pub impl Mat4: Matrix4 { +pub impl Mat4: Matrix4 { #[inline(always)] - pure fn scale(vec: &Vec3) -> Mat4 { - self.mul_m(&Mat4(vec.x, 0f, 0f, 0f, - 0f, vec.y, 0f, 0f, - 0f, 0f, vec.z, 0f, - 0f, 0f, 0f, 1f)) + pure fn scale(vec: &Vec3) -> Mat4 { + self.mul_m(&Mat4( vec.x, from_int(0), from_int(0), from_int(0), + from_int(0), vec.y, from_int(0), from_int(0), + from_int(0), from_int(0), vec.z, from_int(0), + from_int(0), from_int(0), from_int(0), from_int(1))) } #[inline(always)] - pure fn translate(vec: &Vec3) -> Mat4 { + pure fn translate(vec: &Vec3) -> Mat4 { Mat4_v(&self[0], &self[1], &self[2], @@ -693,35 +709,36 @@ pub impl Mat4: Matrix4 { } } -pub impl Mat4: Index { +pub impl Mat4: Index> { #[inline(always)] - pure fn index(i: uint) -> Vec4 { + pure fn index(i: uint) -> Vec4 { self.data[i] } } -pub impl Mat4: Neg { +pub impl> Mat4: Neg> { #[inline(always)] - pure fn neg() -> Mat4 { + pure fn neg() -> Mat4 { Mat4_v(&-self[0], &-self[1], &-self[2], &-self[3]) } } -pub impl Mat4: Eq { +// TODO: make work for T:Integer +pub impl Mat4: Eq { #[inline(always)] - pure fn eq(other: &Mat4) -> bool { + pure fn eq(other: &Mat4) -> bool { self.fuzzy_eq(other) } #[inline(always)] - pure fn ne(other: &Mat4) -> bool { + pure fn ne(other: &Mat4) -> bool { !(self == *other) } } -impl Mat4: ExactEq { +pub impl Mat4: ExactEq { #[inline(always)] - pure fn exact_eq(other: &Mat4) -> bool { + pure fn exact_eq(other: &Mat4) -> bool { self[0].exact_eq(&other[0]) && self[1].exact_eq(&other[1]) && self[2].exact_eq(&other[2]) && @@ -729,9 +746,9 @@ impl Mat4: ExactEq { } } -pub impl Mat4: FuzzyEq { +pub impl Mat4: FuzzyEq { #[inline(always)] - pure fn fuzzy_eq(other: &Mat4) -> bool { + pure fn fuzzy_eq(other: &Mat4) -> bool { self[0].fuzzy_eq(&other[0]) && self[1].fuzzy_eq(&other[1]) && self[2].fuzzy_eq(&other[2]) && @@ -739,9 +756,9 @@ pub impl Mat4: FuzzyEq { } } -pub impl Mat4: ToPtr { +pub impl Mat4: ToPtr { #[inline(always)] - pure fn to_ptr() -> *float { + pure fn to_ptr() -> *T { self[0].to_ptr() } } \ No newline at end of file diff --git a/src/num_util.rs b/src/num_util.rs new file mode 100644 index 0000000..d562f66 --- /dev/null +++ b/src/num_util.rs @@ -0,0 +1,428 @@ +trait UnSigned {} // Needs trait inheritence to work properly + +pub impl u8: UnSigned {} +pub impl u16: UnSigned {} +pub impl u32: UnSigned {} +pub impl u64: UnSigned {} +pub impl uint: UnSigned {} + + +trait Signed {} // Needs trait inheritence to work properly + +pub impl> T: Signed {} + + +trait Integer {} // Needs trait inheritence to work properly + +pub impl u8: Integer {} +pub impl u16: Integer {} +pub impl u32: Integer {} +pub impl u64: Integer {} +pub impl uint: Integer {} + +pub impl i8: Integer {} +pub impl i16: Integer {} +pub impl i32: Integer {} +pub impl i64: Integer {} +pub impl int: Integer {} + + +trait FloatingPoint {} // Needs trait inheritence to work properly + +pub impl f32: FloatingPoint {} +pub impl f64: FloatingPoint {} +pub impl float: FloatingPoint {} + + +pub impl u8 : Add { #[inline(always)] pure fn add(rhs: &u8) -> u8 { self + *rhs } } +pub impl u16 : Add { #[inline(always)] pure fn add(rhs: &u16) -> u16 { self + *rhs } } +pub impl u32 : Add { #[inline(always)] pure fn add(rhs: &u32) -> u32 { self + *rhs } } +pub impl u64 : Add { #[inline(always)] pure fn add(rhs: &u64) -> u64 { self + *rhs } } +pub impl uint : Add { #[inline(always)] pure fn add(rhs: &uint) -> uint { self + *rhs } } + +pub impl i8 : Add { #[inline(always)] pure fn add(rhs: &i8) -> i8 { self + *rhs } } +pub impl i16 : Add { #[inline(always)] pure fn add(rhs: &i16) -> i16 { self + *rhs } } +pub impl i32 : Add { #[inline(always)] pure fn add(rhs: &i32) -> i32 { self + *rhs } } +pub impl i64 : Add { #[inline(always)] pure fn add(rhs: &i64) -> i64 { self + *rhs } } +pub impl int : Add { #[inline(always)] pure fn add(rhs: &int) -> int { self + *rhs } } + +pub impl f32 : Add { #[inline(always)] pure fn add(rhs: &f32) -> f32 { self + *rhs } } +pub impl f64 : Add { #[inline(always)] pure fn add(rhs: &f64) -> f64 { self + *rhs } } +pub impl float : Add { #[inline(always)] pure fn add(rhs: &float) -> float { self + *rhs } } + + +pub impl u8 : Sub { #[inline(always)] pure fn sub(rhs: &u8) -> u8 { self - *rhs } } +pub impl u16 : Sub { #[inline(always)] pure fn sub(rhs: &u16) -> u16 { self - *rhs } } +pub impl u32 : Sub { #[inline(always)] pure fn sub(rhs: &u32) -> u32 { self - *rhs } } +pub impl u64 : Sub { #[inline(always)] pure fn sub(rhs: &u64) -> u64 { self - *rhs } } +pub impl uint : Sub { #[inline(always)] pure fn sub(rhs: &uint) -> uint { self - *rhs } } + +pub impl i8 : Sub { #[inline(always)] pure fn sub(rhs: &i8) -> i8 { self - *rhs } } +pub impl i16 : Sub { #[inline(always)] pure fn sub(rhs: &i16) -> i16 { self - *rhs } } +pub impl i32 : Sub { #[inline(always)] pure fn sub(rhs: &i32) -> i32 { self - *rhs } } +pub impl i64 : Sub { #[inline(always)] pure fn sub(rhs: &i64) -> i64 { self - *rhs } } +pub impl int : Sub { #[inline(always)] pure fn sub(rhs: &int) -> int { self - *rhs } } + +pub impl f32 : Sub { #[inline(always)] pure fn sub(rhs: &f32) -> f32 { self - *rhs } } +pub impl f64 : Sub { #[inline(always)] pure fn sub(rhs: &f64) -> f64 { self - *rhs } } +pub impl float : Sub { #[inline(always)] pure fn sub(rhs: &float) -> float { self - *rhs } } + + +pub impl u8 : Mul { #[inline(always)] pure fn mul(rhs: &u8) -> u8 { self * *rhs } } +pub impl u16 : Mul { #[inline(always)] pure fn mul(rhs: &u16) -> u16 { self * *rhs } } +pub impl u32 : Mul { #[inline(always)] pure fn mul(rhs: &u32) -> u32 { self * *rhs } } +pub impl u64 : Mul { #[inline(always)] pure fn mul(rhs: &u64) -> u64 { self * *rhs } } +pub impl uint : Mul { #[inline(always)] pure fn mul(rhs: &uint) -> uint { self * *rhs } } + +pub impl i8 : Mul { #[inline(always)] pure fn mul(rhs: &i8) -> i8 { self * *rhs } } +pub impl i16 : Mul { #[inline(always)] pure fn mul(rhs: &i16) -> i16 { self * *rhs } } +pub impl i32 : Mul { #[inline(always)] pure fn mul(rhs: &i32) -> i32 { self * *rhs } } +pub impl i64 : Mul { #[inline(always)] pure fn mul(rhs: &i64) -> i64 { self * *rhs } } +pub impl int : Mul { #[inline(always)] pure fn mul(rhs: &int) -> int { self * *rhs } } + +pub impl f32 : Mul { #[inline(always)] pure fn mul(rhs: &f32) -> f32 { self * *rhs } } +pub impl f64 : Mul { #[inline(always)] pure fn mul(rhs: &f64) -> f64 { self * *rhs } } +pub impl float : Mul { #[inline(always)] pure fn mul(rhs: &float) -> float { self * *rhs } } + + +pub impl u8 : Div { #[inline(always)] pure fn div(rhs: &u8) -> u8 { self / *rhs } } +pub impl u16 : Div { #[inline(always)] pure fn div(rhs: &u16) -> u16 { self / *rhs } } +pub impl u32 : Div { #[inline(always)] pure fn div(rhs: &u32) -> u32 { self / *rhs } } +pub impl u64 : Div { #[inline(always)] pure fn div(rhs: &u64) -> u64 { self / *rhs } } +pub impl uint : Div { #[inline(always)] pure fn div(rhs: &uint) -> uint { self / *rhs } } + +pub impl i8 : Div { #[inline(always)] pure fn div(rhs: &i8) -> i8 { self / *rhs } } +pub impl i16 : Div { #[inline(always)] pure fn div(rhs: &i16) -> i16 { self / *rhs } } +pub impl i32 : Div { #[inline(always)] pure fn div(rhs: &i32) -> i32 { self / *rhs } } +pub impl i64 : Div { #[inline(always)] pure fn div(rhs: &i64) -> i64 { self / *rhs } } +pub impl int : Div { #[inline(always)] pure fn div(rhs: &int) -> int { self / *rhs } } + +pub impl f32 : Div { #[inline(always)] pure fn div(rhs: &f32) -> f32 { self / *rhs } } +pub impl f64 : Div { #[inline(always)] pure fn div(rhs: &f64) -> f64 { self / *rhs } } +pub impl float : Div { #[inline(always)] pure fn div(rhs: &float) -> float { self / *rhs } } + + +pub impl u8 : Modulo { #[inline(always)] pure fn modulo(rhs: &u8) -> u8 { self % *rhs } } +pub impl u16 : Modulo { #[inline(always)] pure fn modulo(rhs: &u16) -> u16 { self % *rhs } } +pub impl u32 : Modulo { #[inline(always)] pure fn modulo(rhs: &u32) -> u32 { self % *rhs } } +pub impl u64 : Modulo { #[inline(always)] pure fn modulo(rhs: &u64) -> u64 { self % *rhs } } +pub impl uint : Modulo { #[inline(always)] pure fn modulo(rhs: &uint) -> uint { self % *rhs } } + +pub impl i8 : Modulo { #[inline(always)] pure fn modulo(rhs: &i8) -> i8 { self % *rhs } } +pub impl i16 : Modulo { #[inline(always)] pure fn modulo(rhs: &i16) -> i16 { self % *rhs } } +pub impl i32 : Modulo { #[inline(always)] pure fn modulo(rhs: &i32) -> i32 { self % *rhs } } +pub impl i64 : Modulo { #[inline(always)] pure fn modulo(rhs: &i64) -> i64 { self % *rhs } } +pub impl int : Modulo { #[inline(always)] pure fn modulo(rhs: &int) -> int { self % *rhs } } + +pub impl f32 : Modulo { #[inline(always)] pure fn modulo(rhs: &f32) -> f32 { self % *rhs } } +pub impl f64 : Modulo { #[inline(always)] pure fn modulo(rhs: &f64) -> f64 { self % *rhs } } +pub impl float : Modulo { #[inline(always)] pure fn modulo(rhs: &float) -> float { self % *rhs } } + + +pub impl i8 : Neg { #[inline(always)] pure fn neg() -> i8 { -self } } +pub impl i16 : Neg { #[inline(always)] pure fn neg() -> i16 { -self } } +pub impl i32 : Neg { #[inline(always)] pure fn neg() -> i32 { -self } } +pub impl i64 : Neg { #[inline(always)] pure fn neg() -> i64 { -self } } +pub impl int : Neg { #[inline(always)] pure fn neg() -> int { -self } } + +pub impl f32 : Neg { #[inline(always)] pure fn neg() -> f32 { -self } } +pub impl f64 : Neg { #[inline(always)] pure fn neg() -> f64 { -self } } +pub impl float : Neg { #[inline(always)] pure fn neg() -> float { -self } } + + +trait NumCast { + static pure fn from(n: T) -> self; + pure fn cast() -> T; + + pure fn cast_u8() -> u8; + pure fn cast_u16() -> u16; + pure fn cast_u32() -> u32; + pure fn cast_u64() -> u64; + pure fn cast_uint() -> uint; + + pure fn cast_i8() -> i8; + pure fn cast_i16() -> i16; + pure fn cast_i32() -> i32; + pure fn cast_i64() -> i64; + pure fn cast_int() -> int; + + pure fn cast_f32() -> f32; + pure fn cast_f64() -> f64; + pure fn cast_float() -> float; +} + +#[inline(always)] +pub pure fn cast(n: T) -> U { n.cast() } + +pub impl u8: NumCast { + #[inline(always)] static pure fn from(n: T) -> u8 { n.cast_u8() } + #[inline(always)] pure fn cast() -> T { from(self) } + + #[inline(always)] pure fn cast_u8() -> u8 { self } + #[inline(always)] pure fn cast_u16() -> u16 { self as u16 } + #[inline(always)] pure fn cast_u32() -> u32 { self as u32 } + #[inline(always)] pure fn cast_u64() -> u64 { self as u64 } + #[inline(always)] pure fn cast_uint() -> uint { self as uint } + + #[inline(always)] pure fn cast_i8() -> i8 { self as i8 } + #[inline(always)] pure fn cast_i16() -> i16 { self as i16 } + #[inline(always)] pure fn cast_i32() -> i32 { self as i32 } + #[inline(always)] pure fn cast_i64() -> i64 { self as i64 } + #[inline(always)] pure fn cast_int() -> int { self as int } + + #[inline(always)] pure fn cast_f32() -> f32 { self as f32 } + #[inline(always)] pure fn cast_f64() -> f64 { self as f64 } + #[inline(always)] pure fn cast_float() -> float { self as float } +} + +pub impl u16: NumCast { + #[inline(always)] static pure fn from(n: T) -> u16 { n.cast_u16() } + #[inline(always)] pure fn cast() -> T { from(self) } + + #[inline(always)] pure fn cast_u8() -> u8 { self as u8 } + #[inline(always)] pure fn cast_u16() -> u16 { self } + #[inline(always)] pure fn cast_u32() -> u32 { self as u32 } + #[inline(always)] pure fn cast_u64() -> u64 { self as u64 } + #[inline(always)] pure fn cast_uint() -> uint { self as uint } + + #[inline(always)] pure fn cast_i8() -> i8 { self as i8 } + #[inline(always)] pure fn cast_i16() -> i16 { self as i16 } + #[inline(always)] pure fn cast_i32() -> i32 { self as i32 } + #[inline(always)] pure fn cast_i64() -> i64 { self as i64 } + #[inline(always)] pure fn cast_int() -> int { self as int } + + #[inline(always)] pure fn cast_f32() -> f32 { self as f32 } + #[inline(always)] pure fn cast_f64() -> f64 { self as f64 } + #[inline(always)] pure fn cast_float() -> float { self as float } +} + +pub impl u32: NumCast { + #[inline(always)] static pure fn from(n: T) -> u32 { n.cast_u32() } + #[inline(always)] pure fn cast() -> T { from(self) } + + #[inline(always)] pure fn cast_u8() -> u8 { self as u8 } + #[inline(always)] pure fn cast_u16() -> u16 { self as u16 } + #[inline(always)] pure fn cast_u32() -> u32 { self } + #[inline(always)] pure fn cast_u64() -> u64 { self as u64 } + #[inline(always)] pure fn cast_uint() -> uint { self as uint } + + #[inline(always)] pure fn cast_i8() -> i8 { self as i8 } + #[inline(always)] pure fn cast_i16() -> i16 { self as i16 } + #[inline(always)] pure fn cast_i32() -> i32 { self as i32 } + #[inline(always)] pure fn cast_i64() -> i64 { self as i64 } + #[inline(always)] pure fn cast_int() -> int { self as int } + + #[inline(always)] pure fn cast_f32() -> f32 { self as f32 } + #[inline(always)] pure fn cast_f64() -> f64 { self as f64 } + #[inline(always)] pure fn cast_float() -> float { self as float } +} + +pub impl u64: NumCast { + #[inline(always)] static pure fn from(n: T) -> u64 { n.cast_u64() } + #[inline(always)] pure fn cast() -> T { from(self) } + + #[inline(always)] pure fn cast_u8() -> u8 { self as u8 } + #[inline(always)] pure fn cast_u16() -> u16 { self as u16 } + #[inline(always)] pure fn cast_u32() -> u32 { self as u32 } + #[inline(always)] pure fn cast_u64() -> u64 { self } + #[inline(always)] pure fn cast_uint() -> uint { self as uint } + + #[inline(always)] pure fn cast_i8() -> i8 { self as i8 } + #[inline(always)] pure fn cast_i16() -> i16 { self as i16 } + #[inline(always)] pure fn cast_i32() -> i32 { self as i32 } + #[inline(always)] pure fn cast_i64() -> i64 { self as i64 } + #[inline(always)] pure fn cast_int() -> int { self as int } + + #[inline(always)] pure fn cast_f32() -> f32 { self as f32 } + #[inline(always)] pure fn cast_f64() -> f64 { self as f64 } + #[inline(always)] pure fn cast_float() -> float { self as float } +} + +pub impl uint: NumCast { + #[inline(always)] static pure fn from(n: T) -> uint { n.cast_uint() } + #[inline(always)] pure fn cast() -> T { from(self) } + + #[inline(always)] pure fn cast_u8() -> u8 { self as u8 } + #[inline(always)] pure fn cast_u16() -> u16 { self as u16 } + #[inline(always)] pure fn cast_u32() -> u32 { self as u32 } + #[inline(always)] pure fn cast_u64() -> u64 { self as u64 } + #[inline(always)] pure fn cast_uint() -> uint { self } + + #[inline(always)] pure fn cast_i8() -> i8 { self as i8 } + #[inline(always)] pure fn cast_i16() -> i16 { self as i16 } + #[inline(always)] pure fn cast_i32() -> i32 { self as i32 } + #[inline(always)] pure fn cast_i64() -> i64 { self as i64 } + #[inline(always)] pure fn cast_int() -> int { self as int } + + #[inline(always)] pure fn cast_f32() -> f32 { self as f32 } + #[inline(always)] pure fn cast_f64() -> f64 { self as f64 } + #[inline(always)] pure fn cast_float() -> float { self as float } +} + +pub impl i8: NumCast { + #[inline(always)] static pure fn from(n: T) -> i8 { n.cast_i8() } + #[inline(always)] pure fn cast() -> T { from(self) } + + #[inline(always)] pure fn cast_u8() -> u8 { self as u8 } + #[inline(always)] pure fn cast_u16() -> u16 { self as u16 } + #[inline(always)] pure fn cast_u32() -> u32 { self as u32 } + #[inline(always)] pure fn cast_u64() -> u64 { self as u64 } + #[inline(always)] pure fn cast_uint() -> uint { self as uint } + + #[inline(always)] pure fn cast_i8() -> i8 { self } + #[inline(always)] pure fn cast_i16() -> i16 { self as i16 } + #[inline(always)] pure fn cast_i32() -> i32 { self as i32 } + #[inline(always)] pure fn cast_i64() -> i64 { self as i64 } + #[inline(always)] pure fn cast_int() -> int { self as int } + + #[inline(always)] pure fn cast_f32() -> f32 { self as f32 } + #[inline(always)] pure fn cast_f64() -> f64 { self as f64 } + #[inline(always)] pure fn cast_float() -> float { self as float } +} + +pub impl i16: NumCast { + #[inline(always)] static pure fn from(n: T) -> i16 { n.cast_i16() } + #[inline(always)] pure fn cast() -> T { from(self) } + + #[inline(always)] pure fn cast_u8() -> u8 { self as u8 } + #[inline(always)] pure fn cast_u16() -> u16 { self as u16 } + #[inline(always)] pure fn cast_u32() -> u32 { self as u32 } + #[inline(always)] pure fn cast_u64() -> u64 { self as u64 } + #[inline(always)] pure fn cast_uint() -> uint { self as uint } + + #[inline(always)] pure fn cast_i8() -> i8 { self as i8 } + #[inline(always)] pure fn cast_i16() -> i16 { self } + #[inline(always)] pure fn cast_i32() -> i32 { self as i32 } + #[inline(always)] pure fn cast_i64() -> i64 { self as i64 } + #[inline(always)] pure fn cast_int() -> int { self as int } + + #[inline(always)] pure fn cast_f32() -> f32 { self as f32 } + #[inline(always)] pure fn cast_f64() -> f64 { self as f64 } + #[inline(always)] pure fn cast_float() -> float { self as float } +} + +pub impl i32: NumCast { + #[inline(always)] static pure fn from(n: T) -> i32 { n.cast_i32() } + #[inline(always)] pure fn cast() -> T { from(self) } + + #[inline(always)] pure fn cast_u8() -> u8 { self as u8 } + #[inline(always)] pure fn cast_u16() -> u16 { self as u16 } + #[inline(always)] pure fn cast_u32() -> u32 { self as u32 } + #[inline(always)] pure fn cast_u64() -> u64 { self as u64 } + #[inline(always)] pure fn cast_uint() -> uint { self as uint } + + #[inline(always)] pure fn cast_i8() -> i8 { self as i8 } + #[inline(always)] pure fn cast_i16() -> i16 { self as i16 } + #[inline(always)] pure fn cast_i32() -> i32 { self } + #[inline(always)] pure fn cast_i64() -> i64 { self as i64 } + #[inline(always)] pure fn cast_int() -> int { self as int } + + #[inline(always)] pure fn cast_f32() -> f32 { self as f32 } + #[inline(always)] pure fn cast_f64() -> f64 { self as f64 } + #[inline(always)] pure fn cast_float() -> float { self as float } +} + +pub impl i64: NumCast { + #[inline(always)] static pure fn from(n: T) -> i64 { n.cast_i64() } + #[inline(always)] pure fn cast() -> T { from(self) } + + #[inline(always)] pure fn cast_u8() -> u8 { self as u8 } + #[inline(always)] pure fn cast_u16() -> u16 { self as u16 } + #[inline(always)] pure fn cast_u32() -> u32 { self as u32 } + #[inline(always)] pure fn cast_u64() -> u64 { self as u64 } + #[inline(always)] pure fn cast_uint() -> uint { self as uint } + + #[inline(always)] pure fn cast_i8() -> i8 { self as i8 } + #[inline(always)] pure fn cast_i16() -> i16 { self as i16 } + #[inline(always)] pure fn cast_i32() -> i32 { self as i32 } + #[inline(always)] pure fn cast_i64() -> i64 { self } + #[inline(always)] pure fn cast_int() -> int { self as int } + + #[inline(always)] pure fn cast_f32() -> f32 { self as f32 } + #[inline(always)] pure fn cast_f64() -> f64 { self as f64 } + #[inline(always)] pure fn cast_float() -> float { self as float } +} + +pub impl int: NumCast { + #[inline(always)] static pure fn from(n: T) -> int { n.cast_int() } + #[inline(always)] pure fn cast() -> T { from(self) } + + #[inline(always)] pure fn cast_u8() -> u8 { self as u8 } + #[inline(always)] pure fn cast_u16() -> u16 { self as u16 } + #[inline(always)] pure fn cast_u32() -> u32 { self as u32 } + #[inline(always)] pure fn cast_u64() -> u64 { self as u64 } + #[inline(always)] pure fn cast_uint() -> uint { self as uint } + + #[inline(always)] pure fn cast_i8() -> i8 { self as i8 } + #[inline(always)] pure fn cast_i16() -> i16 { self as i16 } + #[inline(always)] pure fn cast_i32() -> i32 { self as i32 } + #[inline(always)] pure fn cast_i64() -> i64 { self as i64 } + #[inline(always)] pure fn cast_int() -> int { self } + + #[inline(always)] pure fn cast_f32() -> f32 { self as f32 } + #[inline(always)] pure fn cast_f64() -> f64 { self as f64 } + #[inline(always)] pure fn cast_float() -> float { self as float } +} + +pub impl f32: NumCast { + #[inline(always)] static pure fn from(n: T) -> f32 { n.cast_f32() } + #[inline(always)] pure fn cast() -> T { from(self) } + + #[inline(always)] pure fn cast_u8() -> u8 { self as u8 } + #[inline(always)] pure fn cast_u16() -> u16 { self as u16 } + #[inline(always)] pure fn cast_u32() -> u32 { self as u32 } + #[inline(always)] pure fn cast_u64() -> u64 { self as u64 } + #[inline(always)] pure fn cast_uint() -> uint { self as uint } + + #[inline(always)] pure fn cast_i8() -> i8 { self as i8 } + #[inline(always)] pure fn cast_i16() -> i16 { self as i16 } + #[inline(always)] pure fn cast_i32() -> i32 { self as i32 } + #[inline(always)] pure fn cast_i64() -> i64 { self as i64 } + #[inline(always)] pure fn cast_int() -> int { self as int } + + #[inline(always)] pure fn cast_f32() -> f32 { self } + #[inline(always)] pure fn cast_f64() -> f64 { self as f64 } + #[inline(always)] pure fn cast_float() -> float { self as float } +} + +pub impl f64: NumCast { + #[inline(always)] static pure fn from(n: T) -> f64 { n.cast_f64() } + #[inline(always)] pure fn cast() -> T { from(self) } + + #[inline(always)] pure fn cast_u8() -> u8 { self as u8 } + #[inline(always)] pure fn cast_u16() -> u16 { self as u16 } + #[inline(always)] pure fn cast_u32() -> u32 { self as u32 } + #[inline(always)] pure fn cast_u64() -> u64 { self as u64 } + #[inline(always)] pure fn cast_uint() -> uint { self as uint } + + #[inline(always)] pure fn cast_i8() -> i8 { self as i8 } + #[inline(always)] pure fn cast_i16() -> i16 { self as i16 } + #[inline(always)] pure fn cast_i32() -> i32 { self as i32 } + #[inline(always)] pure fn cast_i64() -> i64 { self as i64 } + #[inline(always)] pure fn cast_int() -> int { self as int } + + #[inline(always)] pure fn cast_f32() -> f32 { self as f32 } + #[inline(always)] pure fn cast_f64() -> f64 { self } + #[inline(always)] pure fn cast_float() -> float { self as float } +} + +pub impl float: NumCast { + #[inline(always)] static pure fn from(n: T) -> float { n.cast_float() } + #[inline(always)] pure fn cast() -> T { from(self) } + + #[inline(always)] pure fn cast_u8() -> u8 { self as u8 } + #[inline(always)] pure fn cast_u16() -> u16 { self as u16 } + #[inline(always)] pure fn cast_u32() -> u32 { self as u32 } + #[inline(always)] pure fn cast_u64() -> u64 { self as u64 } + #[inline(always)] pure fn cast_uint() -> uint { self as uint } + + #[inline(always)] pure fn cast_i8() -> i8 { self as i8 } + #[inline(always)] pure fn cast_i16() -> i16 { self as i16 } + #[inline(always)] pure fn cast_i32() -> i32 { self as i32 } + #[inline(always)] pure fn cast_i64() -> i64 { self as i64 } + #[inline(always)] pure fn cast_int() -> int { self as int } + + #[inline(always)] pure fn cast_f32() -> f32 { self as f32 } + #[inline(always)] pure fn cast_f64() -> f64 { self as f64 } + #[inline(always)] pure fn cast_float() -> float { self } +} \ No newline at end of file diff --git a/src/omath.rc b/src/omath.rc index d077675..784dd31 100644 --- a/src/omath.rc +++ b/src/omath.rc @@ -9,6 +9,7 @@ extern mod std; pub mod matrix; pub mod math; +pub mod num_util; pub mod projection; pub mod quaternion; pub mod vector; diff --git a/src/projection.rs b/src/projection.rs index 5aa5e49..d8421ae 100644 --- a/src/projection.rs +++ b/src/projection.rs @@ -1,6 +1,8 @@ use float::consts::pi; use float::tan; + use matrix::Mat4; +use num_util::*; // // Create a perspective projection matrix @@ -9,7 +11,7 @@ use matrix::Mat4; // http://www.opengl.org/wiki/GluPerspective_code // #[inline(always)] -pure fn perspective(fovy:float, aspectRatio:float, near:float, far:float) -> Mat4 { +pure fn perspective>(fovy: float, aspectRatio: float, near: float, far: float) -> Mat4 { let ymax = near * tan(fovy * pi / 360f); let xmax = ymax * aspectRatio; return frustum(-xmax, xmax, -ymax, ymax, near, far); @@ -23,23 +25,23 @@ pure fn perspective(fovy:float, aspectRatio:float, near:float, far:float) -> Mat // TODO: double check algorithm // #[inline(always)] -pure fn frustum(left:float, right:float, bottom:float, top:float, near:float, far:float) -> Mat4 { - let m00 = (2f * near) / (right - left); - let m01 = 0f; - let m02 = 0f; - let m03 = 0f; - let m10 = 0f; - let m11 = (2f * near)/(top - bottom); - let m12 = 0f; - let m13 = 0f; - let m20 = (right + left) / (right - left); - let m21 = (top + bottom) / (top - bottom); - let m22 = -(far + near) / (far - near); - let m23 = -1f; - let m30 = 0f; - let m31 = 0f; - let m32 = -(2f * far * near) / (far - near); - let m33 = 0f; +pure fn frustum>(left: float, right: float, bottom: float, top: float, near: float, far: float) -> Mat4 { + let m00 = cast((2f * near) / (right - left)); + let m01 = cast(0f); + let m02 = cast(0f); + let m03 = cast(0f); + let m10 = cast(0f); + let m11 = cast((2f * near) / (top - bottom)); + let m12 = cast(0f); + let m13 = cast(0f); + let m20 = cast((right + left) / (right - left)); + let m21 = cast((top + bottom) / (top - bottom)); + let m22 = cast(-(far + near) / (far - near)); + let m23 = cast(-1f); + let m30 = cast(0f); + let m31 = cast(0f); + let m32 = cast(-(2f * far * near) / (far - near)); + let m33 = cast(0f); return Mat4(m00, m01, m02, m03, m10, m11, m12, m13, diff --git a/src/quaternion.rs b/src/quaternion.rs index a93a574..08933bb 100644 --- a/src/quaternion.rs +++ b/src/quaternion.rs @@ -1,8 +1,10 @@ use cast::transmute; -use vec::raw::buf_as_slice; -use ptr::to_unsafe_ptr; use cmp::Eq; +use num::from_int; +use ptr::to_unsafe_ptr; +use vec::raw::buf_as_slice; use std::cmp::FuzzyEq; + use math::{ToPtr, ExactEq, Sqrt}; use matrix::{Mat3, Mat4}; use vector::Vec3; @@ -27,8 +29,12 @@ pub trait Quaternion { pure fn magnitude2() -> T; pure fn magnitude() -> T; - pure fn to_Mat3() -> Mat3; - pure fn to_Mat4() -> Mat4; + pure fn to_Mat3() -> Mat3; + pure fn to_Mat4() -> Mat4; +} + +pub trait ToQuat { + pure fn to_Quat() -> Quat; } @@ -39,30 +45,30 @@ pub trait Quaternion { // // Quat struct definition // -pub struct Quat { w: float, x: float, y: float, z: float } +pub struct Quat { w: T, x: T, y: T, z: T } // // Quat Constructor // #[inline(always)] -pub pure fn Quat(w: float, x: float, y: float, z: float) -> Quat { - Quat { w: w, x: x, y: y, z: z } +pub pure fn Quat(w: T, x: T, y: T, z: T) -> Quat { + Quat { w: move w, x: move x, y: move y, z: move z } } pub mod Quat { - pub const zero :Quat = Quat { w: 0f, x: 0f, y: 0f, z: 0f }; - pub const identity :Quat = Quat { w: 1f, x: 0f, y: 0f, z: 0f }; + #[inline(always)] pub pure fn zero () -> Quat { Quat { w: from_int(0), x: from_int(0), y: from_int(0), z: from_int(0) } } + #[inline(always)] pub pure fn identity () -> Quat { Quat { w: from_int(1), x: from_int(0), y: from_int(0), z: from_int(0) } } } // // Quaternion Implementation // -pub impl Quat: Quaternion { +pub impl Quat: Quaternion { #[inline(always)] pure fn dim() -> uint { 4 } #[inline(always)] - pure fn mul_t(value: float) -> Quat { + pure fn mul_t(value: T) -> Quat { Quat(self[0] * value, self[1] * value, self[2] * value, @@ -70,7 +76,7 @@ pub impl Quat: Quaternion { } #[inline(always)] - pure fn div_t(value: float) -> Quat { + pure fn div_t(value: T) -> Quat { Quat(self[0] / value, self[1] / value, self[2] / value, @@ -78,7 +84,7 @@ pub impl Quat: Quaternion { } #[inline(always)] - pure fn add_q(other: &Quat) -> Quat{ + pure fn add_q(other: &Quat) -> Quat { Quat(self[0] + other[0], self[1] + other[1], self[2] + other[2], @@ -86,7 +92,7 @@ pub impl Quat: Quaternion { } #[inline(always)] - pure fn sub_q(other: &Quat) -> Quat{ + pure fn sub_q(other: &Quat) -> Quat { Quat(self[0] - other[0], self[1] - other[1], self[2] - other[2], @@ -94,7 +100,7 @@ pub impl Quat: Quaternion { } #[inline(always)] - pure fn mul_q(other: &Quat) -> Quat { + pure fn mul_q(other: &Quat) -> Quat { Quat(self.w * other.w - self.x * other.x - self.y * other.y - self.z * other.z, self.w * other.x + self.x * other.w + self.y * other.z - self.z * other.y, self.w * other.y + self.y * other.w + self.z * other.x - self.x * other.z, @@ -102,17 +108,19 @@ pub impl Quat: Quaternion { } #[inline(always)] - pure fn conjugate() -> Quat { + pure fn conjugate() -> Quat { Quat(self.w, -self.x, -self.y, -self.z) } #[inline(always)] - pure fn inverse() -> Quat { - self.conjugate().mul_t((1f / self.magnitude2())) + pure fn inverse() -> Quat { + let mut n: T = from_int(1); + n /= self.magnitude2(); + self.conjugate().mul_t(n) } #[inline(always)] - pure fn magnitude2() -> float { + pure fn magnitude2() -> T { self.w * self.w + self.x * self.x + self.y * self.y + @@ -120,12 +128,12 @@ pub impl Quat: Quaternion { } #[inline(always)] - pure fn magnitude() -> float { + pure fn magnitude() -> T { self.magnitude2().sqrt() } #[inline(always)] - pure fn to_Mat3() -> Mat3 { + pure fn to_Mat3() -> Mat3 { let x2 = self.x + self.x; let y2 = self.y + self.y; let z2 = self.z + self.z; @@ -142,50 +150,53 @@ pub impl Quat: Quaternion { let wz2 = z2 * self.w; let wx2 = x2 * self.w; - return Mat3(1f - yy2 - zz2, xy2 - wz2, xz2 + wy2, - xy2 + wz2, 1f - xx2 - zz2, yz2 - wx2, - xz2 - wy2, yz2 + wx2, 1f - xx2 - yy2); + let _1: T = from_int(1); + + Mat3(_1 - yy2 - zz2, xy2 - wz2, xz2 + wy2, + xy2 + wz2, _1 - xx2 - zz2, yz2 - wx2, + xz2 - wy2, yz2 + wx2, _1 - xx2 - yy2) } #[inline(always)] - pure fn to_Mat4() -> Mat4 { + pure fn to_Mat4() -> Mat4 { self.to_Mat3().to_Mat4() } } -pub impl Quat: Index { +pub impl Quat: Index { #[inline(always)] - pure fn index(i: uint) -> float { + pure fn index(i: uint) -> T { unsafe { do buf_as_slice( - transmute::<*Quat, *float>( + transmute::<*Quat, *T>( to_unsafe_ptr(&self)), 4) |slice| { slice[i] } } } } -pub impl Quat: Neg { +pub impl> Quat: Neg> { #[inline(always)] - pure fn neg() -> Quat { + pure fn neg() -> Quat { Quat(-self[0], -self[1], -self[2], -self[3]) } } -pub impl Quat: Eq { +// TODO: make work for T:Integer +pub impl Quat: Eq { #[inline(always)] - pure fn eq(other: &Quat) -> bool { + pure fn eq(other: &Quat) -> bool { self.fuzzy_eq(other) } #[inline(always)] - pure fn ne(other: &Quat) -> bool { + pure fn ne(other: &Quat) -> bool { !(self == *other) } } -impl Quat: ExactEq { +pub impl Quat: ExactEq { #[inline(always)] - pure fn exact_eq(other: &Quat) -> bool { + pure fn exact_eq(other: &Quat) -> bool { self[0] == other[0] && self[1] == other[1] && self[2] == other[2] && @@ -193,9 +204,9 @@ impl Quat: ExactEq { } } -pub impl Quat: FuzzyEq { +pub impl Quat: FuzzyEq { #[inline(always)] - pure fn fuzzy_eq(other: &Quat) -> bool { + pure fn fuzzy_eq(other: &Quat) -> bool { self[0].fuzzy_eq(&other[0]) && self[1].fuzzy_eq(&other[1]) && self[2].fuzzy_eq(&other[2]) && @@ -203,15 +214,9 @@ pub impl Quat: FuzzyEq { } } -pub impl Quat: ToPtr { +pub impl Quat: ToPtr { #[inline(always)] - pure fn to_ptr() -> *float { + pure fn to_ptr() -> *T { to_unsafe_ptr(&self[0]) } -} - -pub impl Quat: ToStr { - pure fn to_str() -> ~str { - fmt!("Quat[ %f, %f, %f, %f ]", self.w, self.x, self.y, self.z) - } } \ No newline at end of file diff --git a/src/test/test_matrix.rs b/src/test/test_matrix.rs index eb1c473..bf21c6e 100644 --- a/src/test/test_matrix.rs +++ b/src/test/test_matrix.rs @@ -49,10 +49,10 @@ fn test_Mat2() { // fuzzy_eq // eq - assert Mat2::identity.is_identity(); - assert Mat2::identity.is_symmetric(); - assert Mat2::identity.is_diagonal(); - assert !Mat2::identity.is_rotated(); + assert Mat2::identity::().is_identity(); + assert Mat2::identity::().is_symmetric(); + assert Mat2::identity::().is_diagonal(); + assert !Mat2::identity::().is_rotated(); assert !a.is_identity(); assert !a.is_symmetric(); @@ -126,10 +126,10 @@ fn test_Mat3() { // fuzzy_eq // eq - assert Mat3::identity.is_identity(); - assert Mat3::identity.is_symmetric(); - assert Mat3::identity.is_diagonal(); - assert !Mat3::identity.is_rotated(); + assert Mat3::identity::().is_identity(); + assert Mat3::identity::().is_symmetric(); + assert Mat3::identity::().is_diagonal(); + assert !Mat3::identity::().is_rotated(); assert !a.is_identity(); assert !a.is_symmetric(); @@ -224,10 +224,10 @@ fn test_Mat4() { // fuzzy_eq // eq - assert Mat4::identity.is_identity(); - assert Mat4::identity.is_symmetric(); - assert Mat4::identity.is_diagonal(); - assert !Mat4::identity.is_rotated(); + assert Mat4::identity::().is_identity(); + assert Mat4::identity::().is_symmetric(); + assert Mat4::identity::().is_diagonal(); + assert !Mat4::identity::().is_rotated(); assert !a.is_identity(); assert !a.is_symmetric(); diff --git a/src/test/test_quaternion.rs b/src/test/test_quaternion.rs index a27afc2..da0244e 100644 --- a/src/test/test_quaternion.rs +++ b/src/test/test_quaternion.rs @@ -13,8 +13,8 @@ fn test_Quat() { assert a == Quat(1f, 2f, 3f, 4f); - assert Quat::zero == Quat(0f, 0f, 0f, 0f); - assert Quat::identity == Quat(1f, 0f, 0f, 0f); + assert Quat::zero() == Quat(0f, 0f, 0f, 0f); + assert Quat::identity() == Quat(1f, 0f, 0f, 0f); assert a.w == 1f; assert a.x == 2f; diff --git a/src/test/test_vector.rs b/src/test/test_vector.rs index 8412a71..373d725 100644 --- a/src/test/test_vector.rs +++ b/src/test/test_vector.rs @@ -12,12 +12,10 @@ fn test_Vec2() { let f1 = 1.5f; let f2 = 0.5f; - assert a == Vec2(1f, 2f); - - assert Vec2::zero == Vec2(0f, 0f); - assert Vec2::unit_x == Vec2(1f, 0f); - assert Vec2::unit_y == Vec2(0f, 1f); - assert Vec2::identity == Vec2(1f, 1f); + assert Vec2::zero() == Vec2(0f, 0f); + assert Vec2::unit_x() == Vec2(1f, 0f); + assert Vec2::unit_y() == Vec2(0f, 1f); + assert Vec2::identity() == Vec2(1f, 1f); assert a.x == 1f; assert a.y == 2f; @@ -63,11 +61,11 @@ fn test_Vec3() { assert a == Vec3(1f, 2f, 3f); - assert Vec3::zero == Vec3(0f, 0f, 0f); - assert Vec3::unit_x == Vec3(1f, 0f, 0f); - assert Vec3::unit_y == Vec3(0f, 1f, 0f); - assert Vec3::unit_z == Vec3(0f, 0f, 1f); - assert Vec3::identity == Vec3(1f, 1f, 1f); + assert Vec3::zero() == Vec3(0f, 0f, 0f); + assert Vec3::unit_x() == Vec3(1f, 0f, 0f); + assert Vec3::unit_y() == Vec3(0f, 1f, 0f); + assert Vec3::unit_z() == Vec3(0f, 0f, 1f); + assert Vec3::identity() == Vec3(1f, 1f, 1f); assert a.x == 1f; assert a.y == 2f; @@ -117,12 +115,12 @@ fn test_Vec4() { assert a == Vec4(1f, 2f, 3f, 4f); - assert Vec4::zero == Vec4(0f, 0f, 0f, 0f); - assert Vec4::unit_x == Vec4(1f, 0f, 0f, 0f); - assert Vec4::unit_y == Vec4(0f, 1f, 0f, 0f); - assert Vec4::unit_z == Vec4(0f, 0f, 1f, 0f); - assert Vec4::unit_w == Vec4(0f, 0f, 0f, 1f); - assert Vec4::identity == Vec4(1f, 1f, 1f, 1f); + assert Vec4::zero() == Vec4(0f, 0f, 0f, 0f); + assert Vec4::unit_x() == Vec4(1f, 0f, 0f, 0f); + assert Vec4::unit_y() == Vec4(0f, 1f, 0f, 0f); + assert Vec4::unit_z() == Vec4(0f, 0f, 1f, 0f); + assert Vec4::unit_w() == Vec4(0f, 0f, 0f, 1f); + assert Vec4::identity() == Vec4(1f, 1f, 1f, 1f); assert a.x == 1f; assert a.y == 2f; diff --git a/src/vector.rs b/src/vector.rs index 0d7c953..b4b324f 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -1,9 +1,11 @@ use cast::transmute; use vec::raw::buf_as_slice; use ptr::to_unsafe_ptr; -use cmp::Eq; +use cmp::{Eq, Ord}; +use num::from_int; use std::cmp::FuzzyEq; -use math::{ToPtr, Abs, abs, ExactEq, max, min, Sqrt}; + +use math::*; // // N-dimensional Vector @@ -26,8 +28,6 @@ pub trait Vector { pure fn normalize() -> self; pure fn lerp(other: &self, value: T) -> self; - pure fn min(other: &self) -> self; - pure fn max(other: &self) -> self; } pub trait Vector3 { @@ -37,177 +37,172 @@ pub trait Vector3 { - - // // Vec2 // -pub struct Vec2 { x: float, y: float } +pub struct Vec2 { x: T, y: T } // // Constructor // #[inline(always)] -pub pure fn Vec2(x: float, y: float) -> Vec2 { - Vec2 { x: x, y: y } +pub pure fn Vec2(x: T, y: T) -> Vec2 { + Vec2 { x: move x, y: move y } } pub mod Vec2 { - pub const zero :Vec2 = Vec2 { x: 0f, y: 0f }; - pub const unit_x :Vec2 = Vec2 { x: 1f, y: 0f }; - pub const unit_y :Vec2 = Vec2 { x: 0f, y: 1f }; - pub const identity :Vec2 = Vec2 { x: 1f, y: 1f }; + #[inline(always)] pub pure fn zero () -> Vec2 { Vec2 { x: from_int(0), y: from_int(0) } } + #[inline(always)] pub pure fn unit_x () -> Vec2 { Vec2 { x: from_int(1), y: from_int(0) } } + #[inline(always)] pub pure fn unit_y () -> Vec2 { Vec2 { x: from_int(0), y: from_int(1) } } + #[inline(always)] pub pure fn identity () -> Vec2 { Vec2 { x: from_int(1), y: from_int(1) } } } -pub impl Vec2: Vector { +pub impl Vec2: Vector { #[inline(always)] static pure fn dim() -> uint { 2 } #[inline(always)] - pure fn add_t(value: float) -> Vec2 { + pure fn add_t(value: T) -> Vec2 { Vec2(self[0] + value, self[1] + value) } #[inline(always)] - pure fn sub_t(value: float) -> Vec2 { + pure fn sub_t(value: T) -> Vec2 { Vec2(self[0] - value, self[1] - value) } #[inline(always)] - pure fn mul_t(value: float) -> Vec2 { + pure fn mul_t(value: T) -> Vec2 { Vec2(self[0] * value, self[1] * value) } #[inline(always)] - pure fn div_t(value: float) -> Vec2 { + pure fn div_t(value: T) -> Vec2 { Vec2(self[0] / value, self[1] / value) } #[inline(always)] - pure fn add_v(other: &Vec2) -> Vec2{ + pure fn add_v(other: &Vec2) -> Vec2 { Vec2(self[0] + other[0], self[1] + other[1]) } #[inline(always)] - pure fn sub_v(other: &Vec2) -> Vec2{ + pure fn sub_v(other: &Vec2) -> Vec2 { Vec2(self[0] - other[0], self[1] - other[1]) } #[inline(always)] - pure fn dot(other: &Vec2) -> float { + pure fn dot(other: &Vec2) -> T { self[0] * other[0] + self[1] * other[1] } #[inline(always)] - pure fn magnitude2() -> float { + pure fn magnitude2() -> T { self[0] * self[0] + self[1] * self[1] } #[inline(always)] - pure fn magnitude() -> float { + pure fn magnitude() -> T { self.magnitude2().sqrt() } #[inline(always)] - pure fn normalize() -> Vec2 { - let n = 1f / self.magnitude(); + pure fn normalize() -> Vec2 { + let mut n: T = from_int(1); + n /= self.magnitude(); return self.mul_t(n); } #[inline(always)] - pure fn lerp(other: &Vec2, value: float) -> Vec2 { + pure fn lerp(other: &Vec2, value: T) -> Vec2 { self.add_v(&other.sub_v(&self).mul_t(value)) } - +} + +pub impl Vec2: Index { #[inline(always)] - pure fn min(other: &Vec2) -> Vec2 { + pure fn index(i: uint) -> T { + unsafe { do buf_as_slice( + transmute::<*Vec2, *T>( + to_unsafe_ptr(&self)), 2) |slice| { slice[i] } + } + } +} + +pub impl Vec2: MinMax { + #[inline(always)] + pure fn min(other: &Vec2) -> Vec2 { Vec2(min(&self[0], &other[0]), min(&self[1], &other[1])) } #[inline(always)] - pure fn max(other: &Vec2) -> Vec2 { + pure fn max(other: &Vec2) -> Vec2 { Vec2(max(&self[0], &other[0]), max(&self[1], &other[1])) } } -pub impl Vec2: Index { +pub impl Vec2: Abs { #[inline(always)] - pure fn index(i: uint) -> float { - unsafe { - do buf_as_slice( - transmute::<*Vec2, *float>( - to_unsafe_ptr(&self)), 2) |slice| { slice[i] } - } - } -} - -pub impl Vec2: Abs { - #[inline(always)] - pure fn abs() -> Vec2 { + pure fn abs() -> Vec2 { Vec2(abs(&self[0]), abs(&self[1])) } } -pub impl Vec2: Neg { +pub impl> Vec2: Neg> { #[inline(always)] - pure fn neg() -> Vec2 { + pure fn neg() -> Vec2 { Vec2(-self[0], -self[1]) } } -pub impl Vec2: Eq { +// TODO: make work for T:Integer +pub impl Vec2: Eq { #[inline(always)] - pure fn eq(other: &Vec2) -> bool { + pure fn eq(other: &Vec2) -> bool { self.fuzzy_eq(other) } #[inline(always)] - pure fn ne(other: &Vec2) -> bool { + pure fn ne(other: &Vec2) -> bool { !(self == *other) } } -impl Vec2: ExactEq { +impl Vec2: ExactEq { #[inline(always)] - pure fn exact_eq(other: &Vec2) -> bool { + pure fn exact_eq(other: &Vec2) -> bool { self[0] == other[0] && self[1] == other[1] } } -pub impl Vec2: FuzzyEq { +pub impl Vec2: FuzzyEq { #[inline(always)] - pure fn fuzzy_eq(other: &Vec2) -> bool { + pure fn fuzzy_eq(other: &Vec2) -> bool { self[0].fuzzy_eq(&other[0]) && self[1].fuzzy_eq(&other[1]) } } -pub impl Vec2: ToPtr { +pub impl Vec2: ToPtr { #[inline(always)] - pure fn to_ptr() -> *float { + pure fn to_ptr() -> *T { to_unsafe_ptr(&self[0]) } } -pub impl Vec2: ToStr { - pure fn to_str() -> ~str { - fmt!("Vec2[ %f, %f ]", self[0], self[1]) - } -} - @@ -216,193 +211,191 @@ pub impl Vec2: ToStr { // // Vec3 // -pub struct Vec3 { x: float, y: float, z: float } +pub struct Vec3 { x: T, y: T, z: T } // // Constructor // #[inline(always)] -pub pure fn Vec3(x: float, y: float, z: float) -> Vec3 { - Vec3 { x: x, y: y, z: z } +pub pure fn Vec3(x: T, y: T, z: T) -> Vec3 { + Vec3 { x: move x, y: move y, z: move z } } pub mod Vec3 { - pub const zero :Vec3 = Vec3 { x: 0f, y: 0f, z: 0f }; - pub const unit_x :Vec3 = Vec3 { x: 1f, y: 0f, z: 0f }; - pub const unit_y :Vec3 = Vec3 { x: 0f, y: 1f, z: 0f }; - pub const unit_z :Vec3 = Vec3 { x: 0f, y: 0f, z: 1f }; - pub const identity :Vec3 = Vec3 { x: 1f, y: 1f, z: 1f }; + #[inline(always)] pub pure fn zero () -> Vec3 { Vec3 { x: from_int(0), y: from_int(0), z: from_int(0) } } + #[inline(always)] pub pure fn unit_x () -> Vec3 { Vec3 { x: from_int(1), y: from_int(0), z: from_int(0) } } + #[inline(always)] pub pure fn unit_y () -> Vec3 { Vec3 { x: from_int(0), y: from_int(1), z: from_int(0) } } + #[inline(always)] pub pure fn unit_z () -> Vec3 { Vec3 { x: from_int(0), y: from_int(0), z: from_int(1) } } + #[inline(always)] pub pure fn identity () -> Vec3 { Vec3 { x: from_int(1), y: from_int(1), z: from_int(1) } } } -pub impl Vec3: Vector3 { +pub impl Vec3: Vector3 { #[inline(always)] - fn cross(other: &Vec3) -> Vec3 { + fn cross(other: &Vec3) -> Vec3 { Vec3((self[1] * other[2]) - (self[2] * other[1]), (self[2] * other[0]) - (self[0] * other[2]), (self[0] * other[1]) - (self[1] * other[0])) } } -pub impl Vec3: Vector { +pub impl Vec3: Vector { #[inline(always)] static pure fn dim() -> uint { 3 } #[inline(always)] - pure fn add_t(value: float) -> Vec3 { + pure fn add_t(value: T) -> Vec3 { Vec3(self[0] + value, self[1] + value, self[2] + value) } #[inline(always)] - pure fn sub_t(value: float) -> Vec3 { + pure fn sub_t(value: T) -> Vec3 { Vec3(self[0] - value, self[1] - value, self[2] - value) } #[inline(always)] - pure fn mul_t(value: float) -> Vec3 { + pure fn mul_t(value: T) -> Vec3 { Vec3(self[0] * value, self[1] * value, self[2] * value) } #[inline(always)] - pure fn div_t(value: float) -> Vec3 { + pure fn div_t(value: T) -> Vec3 { Vec3(self[0] / value, self[1] / value, self[2] / value) } #[inline(always)] - pure fn add_v(other: &Vec3) -> Vec3{ + pure fn add_v(other: &Vec3) -> Vec3{ Vec3(self[0] + other[0], self[1] + other[1], self[2] + other[2]) } #[inline(always)] - pure fn sub_v(other: &Vec3) -> Vec3{ + pure fn sub_v(other: &Vec3) -> Vec3{ Vec3(self[0] - other[0], self[1] - other[1], self[2] - other[2]) } #[inline(always)] - pure fn dot(other: &Vec3) -> float { + pure fn dot(other: &Vec3) -> T { self[0] * other[0] + self[1] * other[1] + self[2] * other[2] } #[inline(always)] - pure fn magnitude2() -> float { + pure fn magnitude2() -> T { self[0] * self[0] + self[1] * self[1] + self[2] * self[2] } #[inline(always)] - pure fn magnitude() -> float { + pure fn magnitude() -> T { self.magnitude2().sqrt() } #[inline(always)] - pure fn normalize() -> Vec3 { - let n = 1f / self.magnitude(); + pure fn normalize() -> Vec3 { + let mut n: T = from_int(1); + n /= self.magnitude(); return self.mul_t(n); } #[inline(always)] - pure fn lerp(other: &Vec3, value: float) -> Vec3 { + pure fn lerp(other: &Vec3, value: T) -> Vec3 { self.add_v(&other.sub_v(&self).mul_t(value)) } - +} + +pub impl Vec3: Index { #[inline(always)] - pure fn min(other: &Vec3) -> Vec3 { + pure fn index(i: uint) -> T { + unsafe { do buf_as_slice( + transmute::<*Vec3, *T>( + to_unsafe_ptr(&self)), 3) |slice| { slice[i] } + } + } +} + +pub impl Vec3: MinMax { + #[inline(always)] + pure fn min(other: &Vec3) -> Vec3 { Vec3(min(&self[0], &other[0]), min(&self[1], &other[1]), min(&self[2], &other[2])) } #[inline(always)] - pure fn max(other: &Vec3) -> Vec3 { + pure fn max(other: &Vec3) -> Vec3 { Vec3(max(&self[0], &other[0]), max(&self[1], &other[1]), max(&self[2], &other[2])) } } -pub impl Vec3: Index { +pub impl Vec3: Abs { #[inline(always)] - pure fn index(i: uint) -> float { - unsafe { do buf_as_slice( - transmute::<*Vec3, *float>( - to_unsafe_ptr(&self)), 3) |slice| { slice[i] } - } - } -} - -pub impl Vec3: Abs { - #[inline(always)] - pure fn abs() -> Vec3 { + pure fn abs() -> Vec3 { Vec3(abs(&self[0]), abs(&self[1]), abs(&self[2])) } } -pub impl Vec3: Neg { +pub impl> Vec3: Neg> { #[inline(always)] - pure fn neg() -> Vec3 { + pure fn neg() -> Vec3 { Vec3(-self[0], -self[1], -self[2]) } } -pub impl Vec3: Eq { +// TODO: make work for T:Integer +pub impl Vec3: Eq { #[inline(always)] - pure fn eq(other: &Vec3) -> bool { + pure fn eq(other: &Vec3) -> bool { self.fuzzy_eq(other) } #[inline(always)] - pure fn ne(other: &Vec3) -> bool { + pure fn ne(other: &Vec3) -> bool { !(self == *other) } } -impl Vec3: ExactEq { +pub impl Vec3: ExactEq { #[inline(always)] - pure fn exact_eq(other: &Vec3) -> bool { + pure fn exact_eq(other: &Vec3) -> bool { self[0] == other[0] && self[1] == other[1] && self[2] == other[2] } } -pub impl Vec3: FuzzyEq { +pub impl Vec3: FuzzyEq { #[inline(always)] - pure fn fuzzy_eq(other: &Vec3) -> bool { + pure fn fuzzy_eq(other: &Vec3) -> bool { self[0].fuzzy_eq(&other[0]) && self[1].fuzzy_eq(&other[1]) && self[2].fuzzy_eq(&other[2]) } } -pub impl Vec3: ToPtr { +pub impl Vec3: ToPtr { #[inline(always)] - pure fn to_ptr() -> *float { + pure fn to_ptr() -> *T { to_unsafe_ptr(&self[0]) } } -pub impl Vec3: ToStr { - pure fn to_str() -> ~str { - fmt!("Vec3[ %f, %f, %f ]", self[0], self[1], self[2]) - } -} - @@ -411,31 +404,31 @@ pub impl Vec3: ToStr { // // Vec4 // -pub struct Vec4 { x: float, y: float, z: float, w: float } +pub struct Vec4 { x: T, y: T, z: T, w: T } pub mod Vec4 { - pub const zero :Vec4 = Vec4 { x: 0f, y: 0f, z: 0f, w: 0f }; - pub const unit_x :Vec4 = Vec4 { x: 1f, y: 0f, z: 0f, w: 0f }; - pub const unit_y :Vec4 = Vec4 { x: 0f, y: 1f, z: 0f, w: 0f }; - pub const unit_z :Vec4 = Vec4 { x: 0f, y: 0f, z: 1f, w: 0f }; - pub const unit_w :Vec4 = Vec4 { x: 0f, y: 0f, z: 0f, w: 1f }; - pub const identity :Vec4 = Vec4 { x: 1f, y: 1f, z: 1f, w: 1f }; + #[inline(always)] pub pure fn zero () -> Vec4 { Vec4 { x: from_int(0), y: from_int(0), z: from_int(0), w: from_int(0) } } + #[inline(always)] pub pure fn unit_x () -> Vec4 { Vec4 { x: from_int(1), y: from_int(0), z: from_int(0), w: from_int(0) } } + #[inline(always)] pub pure fn unit_y () -> Vec4 { Vec4 { x: from_int(0), y: from_int(1), z: from_int(0), w: from_int(0) } } + #[inline(always)] pub pure fn unit_z () -> Vec4 { Vec4 { x: from_int(0), y: from_int(0), z: from_int(1), w: from_int(0) } } + #[inline(always)] pub pure fn unit_w () -> Vec4 { Vec4 { x: from_int(0), y: from_int(0), z: from_int(0), w: from_int(1) } } + #[inline(always)] pub pure fn identity () -> Vec4 { Vec4 { x: from_int(1), y: from_int(1), z: from_int(1), w: from_int(1) } } } // // Constructor // #[inline(always)] -pub pure fn Vec4(x: float, y: float, z: float, w: float) -> Vec4 { - Vec4 { x: x, y: y, z: z, w: w } +pub pure fn Vec4(x: T, y: T, z: T, w: T) -> Vec4 { + Vec4 { x: move x, y: move y, z: move z, w: move w } } -pub impl Vec4: Vector { +pub impl Vec4: Vector { #[inline(always)] static pure fn dim() -> uint { 4 } #[inline(always)] - pure fn add_t(value: float) -> Vec4 { + pure fn add_t(value: T) -> Vec4 { Vec4(self[0] + value, self[1] + value, self[2] + value, @@ -443,7 +436,7 @@ pub impl Vec4: Vector { } #[inline(always)] - pure fn sub_t(value: float) -> Vec4 { + pure fn sub_t(value: T) -> Vec4 { Vec4(self[0] - value, self[1] - value, self[2] - value, @@ -451,7 +444,7 @@ pub impl Vec4: Vector { } #[inline(always)] - pure fn mul_t(value: float) -> Vec4 { + pure fn mul_t(value: T) -> Vec4 { Vec4(self[0] * value, self[1] * value, self[2] * value, @@ -459,7 +452,7 @@ pub impl Vec4: Vector { } #[inline(always)] - pure fn div_t(value: float) -> Vec4 { + pure fn div_t(value: T) -> Vec4 { Vec4(self[0] / value, self[1] / value, self[2] / value, @@ -467,7 +460,7 @@ pub impl Vec4: Vector { } #[inline(always)] - pure fn add_v(other: &Vec4) -> Vec4{ + pure fn add_v(other: &Vec4) -> Vec4 { Vec4(self[0] + other[0], self[1] + other[1], self[2] + other[2], @@ -475,7 +468,7 @@ pub impl Vec4: Vector { } #[inline(always)] - pure fn sub_v(other: &Vec4) -> Vec4{ + pure fn sub_v(other: &Vec4) -> Vec4 { Vec4(self[0] - other[0], self[1] - other[1], self[2] - other[2], @@ -483,7 +476,7 @@ pub impl Vec4: Vector { } #[inline(always)] - pure fn dot(other: &Vec4) -> float { + pure fn dot(other: &Vec4) -> T { self[0] * other[0] + self[1] * other[1] + self[2] * other[2] + @@ -491,7 +484,7 @@ pub impl Vec4: Vector { } #[inline(always)] - pure fn magnitude2() -> float { + pure fn magnitude2() -> T { self[0] * self[0] + self[1] * self[1] + self[2] * self[2] + @@ -499,23 +492,37 @@ pub impl Vec4: Vector { } #[inline(always)] - pure fn magnitude() -> float { + pure fn magnitude() -> T { self.magnitude2().sqrt() } #[inline(always)] - pure fn normalize() -> Vec4 { - let n = 1f / self.magnitude(); + pure fn normalize() -> Vec4 { + let mut n: T = from_int(1); + n /= self.magnitude(); return self.mul_t(n); } #[inline(always)] - pure fn lerp(other: &Vec4, value: float) -> Vec4 { + pure fn lerp(other: &Vec4, value: T) -> Vec4 { self.add_v(&other.sub_v(&self).mul_t(value)) } - +} + +pub impl Vec4: Index { #[inline(always)] - pure fn min(other: &Vec4) -> Vec4 { + pure fn index(i: uint) -> T { + unsafe { + do buf_as_slice( + transmute::<*Vec4, *T>( + to_unsafe_ptr(&self)), 4) |slice| { slice[i] } + } + } +} + +pub impl Vec4: MinMax { + #[inline(always)] + pure fn min(other: &Vec4) -> Vec4 { Vec4(min(&self[0], &other[0]), min(&self[1], &other[1]), min(&self[2], &other[2]), @@ -523,7 +530,7 @@ pub impl Vec4: Vector { } #[inline(always)] - pure fn max(other: &Vec4) -> Vec4 { + pure fn max(other: &Vec4) -> Vec4 { Vec4(max(&self[0], &other[0]), max(&self[1], &other[1]), max(&self[2], &other[2]), @@ -531,20 +538,9 @@ pub impl Vec4: Vector { } } -pub impl Vec4: Index { +pub impl Vec4: Abs { #[inline(always)] - pure fn index(i: uint) -> float { - unsafe { - do buf_as_slice( - transmute::<*Vec4, *float>( - to_unsafe_ptr(&self)), 4) |slice| { slice[i] } - } - } -} - -pub impl Vec4: Abs { - #[inline(always)] - pure fn abs() -> Vec4 { + pure fn abs() -> Vec4 { Vec4(abs(&self[0]), abs(&self[1]), abs(&self[2]), @@ -552,28 +548,29 @@ pub impl Vec4: Abs { } } -pub impl Vec4: Neg { +pub impl> Vec4: Neg> { #[inline(always)] - pure fn neg() -> Vec4 { + pure fn neg() -> Vec4 { Vec4(-self[0], -self[1], -self[2], -self[3]) } } -pub impl Vec4: Eq { +pub impl Vec4: Eq { #[inline(always)] - pure fn eq(other: &Vec4) -> bool { + pure fn eq(other: &Vec4) -> bool { self.fuzzy_eq(other) } #[inline(always)] - pure fn ne(other: &Vec4) -> bool { + pure fn ne(other: &Vec4) -> bool { !(self == *other) } } -impl Vec4: ExactEq { +// TODO: make work for T:Integer +pub impl Vec4: ExactEq { #[inline(always)] - pure fn exact_eq(other: &Vec4) -> bool { + pure fn exact_eq(other: &Vec4) -> bool { self[0] == other[0] && self[1] == other[1] && self[2] == other[2] && @@ -581,9 +578,9 @@ impl Vec4: ExactEq { } } -pub impl Vec4: FuzzyEq { +pub impl Vec4: FuzzyEq { #[inline(always)] - pure fn fuzzy_eq(other: &Vec4) -> bool { + pure fn fuzzy_eq(other: &Vec4) -> bool { self[0].fuzzy_eq(&other[0]) && self[1].fuzzy_eq(&other[1]) && self[2].fuzzy_eq(&other[2]) && @@ -591,15 +588,9 @@ pub impl Vec4: FuzzyEq { } } -pub impl Vec4: ToPtr { +pub impl Vec4: ToPtr { #[inline(always)] - pure fn to_ptr() -> *float { + pure fn to_ptr() -> *T { to_unsafe_ptr(&self[0]) } -} - -pub impl Vec4: ToStr { - pure fn to_str() -> ~str { - fmt!("Vec4[ %f, %f, %f, %f ]", self[0], self[1], self[2], self[3]) - } } \ No newline at end of file