diff --git a/src/gltypes.rs b/src/gltypes.rs index 3e7f564..309ffa4 100644 --- a/src/gltypes.rs +++ b/src/gltypes.rs @@ -2,6 +2,8 @@ pub use mat::{Mat2, Mat3, Mat4}; pub use vec::{Vec2, Vec3, Vec4}; pub use quat::Quat; +use vec::NumericVector; +use mat::{NumericMatrix, NumericMatrix_NxN}; // Vector aliases @@ -26,6 +28,93 @@ pub type uvec3 = Vec3; /// a three-component unsigned integer v pub type uvec4 = Vec4; /// a four-component unsigned integer vector +// +// Wrappers to make working with static functions cleaner +// +// For example: let v = dvec::identity(); +// as opposed to: let v: dvec4 = NumericVector::identity(); +// + +pub impl vec2 { + #[inline(always)] static pure fn identity() -> vec2 { NumericVector::identity() } + #[inline(always)] static pure fn zero() -> vec2 { NumericVector::zero() } +} + +pub impl vec3 { + #[inline(always)] static pure fn identity() -> vec3 { NumericVector::identity() } + #[inline(always)] static pure fn zero() -> vec3 { NumericVector::zero() } +} + +pub impl vec4 { + #[inline(always)] static pure fn identity() -> vec4 { NumericVector::identity() } + #[inline(always)] static pure fn zero() -> vec4 { NumericVector::zero() } +} + + +pub impl dvec2 { + #[inline(always)] static pure fn identity() -> dvec2 { NumericVector::identity() } + #[inline(always)] static pure fn zero() -> dvec2 { NumericVector::zero() } +} + +pub impl dvec3 { + #[inline(always)] static pure fn identity() -> dvec3 { NumericVector::identity() } + #[inline(always)] static pure fn zero() -> dvec3 { NumericVector::zero() } +} + +pub impl dvec4 { + #[inline(always)] static pure fn identity() -> dvec4 { NumericVector::identity() } + #[inline(always)] static pure fn zero() -> dvec4 { NumericVector::zero() } +} + + +pub impl bvec2 { + // #[inline(always)] static pure fn identity() -> bvec2 { NumericVector::identity() } + // #[inline(always)] static pure fn zero() -> bvec2 { NumericVector::zero() } +} + +pub impl bvec3 { + // #[inline(always)] static pure fn identity() -> bvec3 { NumericVector::identity() } + // #[inline(always)] static pure fn zero() -> bvec3 { NumericVector::zero() } +} + +pub impl bvec4 { + // #[inline(always)] static pure fn identity() -> bvec4 { NumericVector::identity() } + // #[inline(always)] static pure fn zero() -> bvec4 { NumericVector::zero() } +} + + +pub impl ivec2 { + #[inline(always)] static pure fn identity() -> ivec2 { NumericVector::identity() } + #[inline(always)] static pure fn zero() -> ivec2 { NumericVector::zero() } +} + +pub impl ivec3 { + #[inline(always)] static pure fn identity() -> ivec3 { NumericVector::identity() } + #[inline(always)] static pure fn zero() -> ivec3 { NumericVector::zero() } +} + +pub impl ivec4 { + #[inline(always)] static pure fn identity() -> ivec4 { NumericVector::identity() } + #[inline(always)] static pure fn zero() -> ivec4 { NumericVector::zero() } +} + + +pub impl uvec2 { + #[inline(always)] static pure fn identity() -> uvec2 { NumericVector::identity() } + #[inline(always)] static pure fn zero() -> uvec2 { NumericVector::zero() } +} + +pub impl uvec3 { + #[inline(always)] static pure fn identity() -> uvec3 { NumericVector::identity() } + #[inline(always)] static pure fn zero() -> uvec3 { NumericVector::zero() } +} + +pub impl uvec4 { + #[inline(always)] static pure fn identity() -> uvec4 { NumericVector::identity() } + #[inline(always)] static pure fn zero() -> uvec4 { NumericVector::zero() } +} + + // Matrix aliases pub type mat2 = Mat2; /// a 2×2 single-precision floating-point matrix @@ -55,6 +144,45 @@ pub type dmat3x3 = Mat3; /// same as a `dmat3` pub type dmat4x4 = Mat4; /// same as a `dmat4` +// +// Wrappers to make working with static functions cleaner +// +// For example: let m = dmat::identity(); +// as opposed to: let m: dmat4 = NumericMatrix_NxN::identity(); +// + +pub impl mat2 { + #[inline(always)] static pure fn identity() -> mat2 { NumericMatrix_NxN::identity() } + #[inline(always)] static pure fn zero() -> mat2 { NumericMatrix::zero() } +} + +pub impl mat3 { + #[inline(always)] static pure fn identity() -> mat3 { NumericMatrix_NxN::identity() } + #[inline(always)] static pure fn zero() -> mat3 { NumericMatrix::zero() } +} + +pub impl mat4 { + #[inline(always)] static pure fn identity() -> mat4 { NumericMatrix_NxN::identity() } + #[inline(always)] static pure fn zero() -> mat4 { NumericMatrix::zero() } +} + + +pub impl dmat2 { + #[inline(always)] static pure fn identity() -> dmat2 { NumericMatrix_NxN::identity() } + #[inline(always)] static pure fn zero() -> dmat2 { NumericMatrix::zero() } +} + +pub impl dmat3 { + #[inline(always)] static pure fn identity() -> dmat3 { NumericMatrix_NxN::identity() } + #[inline(always)] static pure fn zero() -> dmat3 { NumericMatrix::zero() } +} + +pub impl dmat4 { + #[inline(always)] static pure fn identity() -> dmat4 { NumericMatrix_NxN::identity() } + #[inline(always)] static pure fn zero() -> dmat4 { NumericMatrix::zero() } +} + + // Quaternion types // These quaternion type aliases are not actually specified in the GLSL spec diff --git a/src/mat.rs b/src/mat.rs index c5d4bf7..d244f9a 100644 --- a/src/mat.rs +++ b/src/mat.rs @@ -11,7 +11,7 @@ use funs::exp::*; use num::cast::*; use num::default_eq::DefaultEq; use quat::{Quat, ToQuat}; -use vec::{Vec2, Vec3, Vec4}; +use vec::{NumericVector, Vec2, Vec3, Vec4}; pub trait Matrix: Dimensional, Eq, DefaultEq { @@ -25,6 +25,8 @@ pub trait Matrix: Dimensional, Eq, DefaultEq { } pub trait NumericMatrix: Matrix, Neg { + static pure fn zero() -> self; + pure fn mul_t(value: T) -> self; pure fn mul_v(other: &Col) -> Col; pure fn add_m(other: &self) -> self; @@ -32,6 +34,8 @@ pub trait NumericMatrix: Matrix, Neg { } pub trait NumericMatrix_NxN: NumericMatrix { + static pure fn identity() -> self; + pure fn mul_m(other: &self) -> self; pure fn det() -> T; @@ -146,7 +150,13 @@ pub impl Mat2: Matrix, Vec2> { } } -pub impl Mat2: NumericMatrix, Vec2> { +pub impl Mat2: NumericMatrix, Vec2> { + #[inline(always)] + static pure fn zero() -> Mat2 { + Mat2::from_cols(NumericVector::zero(), + NumericVector::zero()) + } + #[inline(always)] pure fn neg() -> Mat2 { Mat2::from_cols(-self[0], -self[1]) @@ -178,6 +188,12 @@ pub impl Mat2: NumericMatrix, Vec2> { } pub impl Mat2: NumericMatrix_NxN> { + #[inline(always)] + static pure fn identity() -> Mat2 { + Mat2::new(NumCast::one() , NumCast::zero(), + NumCast::zero(), NumCast::one()) + } + #[inline(always)] pure fn mul_m(other: &Mat2) -> Mat2 { Mat2::new(self.row(0).dot(&other.col(0)), self.row(1).dot(&other.col(0)), @@ -379,7 +395,14 @@ pub impl Mat3: Matrix, Vec3> { } } -pub impl Mat3: NumericMatrix, Vec3> { +pub impl Mat3: NumericMatrix, Vec3> { + #[inline(always)] + static pure fn zero() -> Mat3 { + Mat3::from_cols(NumericVector::zero(), + NumericVector::zero(), + NumericVector::zero()) + } + #[inline(always)] pure fn neg() -> Mat3 { Mat3::from_cols(-self[0], -self[1], -self[2]) @@ -415,6 +438,13 @@ pub impl Mat3: NumericMatrix, Vec3> { } pub impl Mat3: NumericMatrix_NxN> { + #[inline(always)] + static pure fn identity() -> Mat3 { + Mat3::new(NumCast::one() , NumCast::zero(), NumCast::zero(), + NumCast::zero(), NumCast::one() , NumCast::zero(), + NumCast::zero(), NumCast::zero(), NumCast::one()) + } + #[inline(always)] pure fn mul_m(other: &Mat3) -> Mat3 { Mat3::new(self.row(0).dot(&other.col(0)), self.row(1).dot(&other.col(0)), self.row(2).dot(&other.col(0)), @@ -690,7 +720,15 @@ pub impl Mat4: Matrix, Vec4> { } } -pub impl Mat4: NumericMatrix, Vec4> { +pub impl Mat4: NumericMatrix, Vec4> { + #[inline(always)] + static pure fn zero() -> Mat4 { + Mat4::from_cols(NumericVector::zero(), + NumericVector::zero(), + NumericVector::zero(), + NumericVector::zero()) + } + #[inline(always)] pure fn neg() -> Mat4 { Mat4::from_cols(-self[0], -self[1], -self[2], -self[3]) @@ -730,6 +768,14 @@ pub impl Mat4: NumericMatrix, Vec4> { } pub impl Mat4: NumericMatrix_NxN> { + #[inline(always)] + static pure fn identity() -> Mat4 { + Mat4::new(NumCast::one() , NumCast::zero(), NumCast::zero(), NumCast::zero(), + NumCast::zero(), NumCast::one() , NumCast::zero(), NumCast::zero(), + NumCast::zero(), NumCast::zero(), NumCast::one() , NumCast::zero(), + NumCast::zero(), NumCast::zero(), NumCast::zero(), NumCast::one()) + } + #[inline(always)] pure fn mul_m(other: &Mat4) -> Mat4 { // Surprisingly when building with optimisation turned on this is actually diff --git a/src/num/cast.rs b/src/num/cast.rs index 1665ceb..797a7d4 100644 --- a/src/num/cast.rs +++ b/src/num/cast.rs @@ -8,6 +8,9 @@ trait NumCast { static pure fn from(n: T) -> self; pure fn cast() -> T; + static pure fn zero() -> self; + static pure fn one() -> self; + pure fn to_u8() -> u8; pure fn to_u16() -> u16; pure fn to_u32() -> u32; @@ -32,6 +35,9 @@ pub impl u8: NumCast { #[inline(always)] static pure fn from(n: T) -> u8 { move n.to_u8() } #[inline(always)] pure fn cast() -> T { move from(self) } + static pure fn zero() -> u8 { 0u8 } + static pure fn one() -> u8 { 1u8 } + #[inline(always)] pure fn to_u8() -> u8 { self } #[inline(always)] pure fn to_u16() -> u16 { self as u16 } #[inline(always)] pure fn to_u32() -> u32 { self as u32 } @@ -53,6 +59,9 @@ pub impl u16: NumCast { #[inline(always)] static pure fn from(n: T) -> u16 { move n.to_u16() } #[inline(always)] pure fn cast() -> T { move from(self) } + static pure fn zero() -> u16 { 0u16 } + static pure fn one() -> u16 { 1u16 } + #[inline(always)] pure fn to_u8() -> u8 { self as u8 } #[inline(always)] pure fn to_u16() -> u16 { self } #[inline(always)] pure fn to_u32() -> u32 { self as u32 } @@ -74,6 +83,9 @@ pub impl u32: NumCast { #[inline(always)] static pure fn from(n: T) -> u32 { move n.to_u32() } #[inline(always)] pure fn cast() -> T { move from(self) } + static pure fn zero() -> u32 { 0u32 } + static pure fn one() -> u32 { 1u32 } + #[inline(always)] pure fn to_u8() -> u8 { self as u8 } #[inline(always)] pure fn to_u16() -> u16 { self as u16 } #[inline(always)] pure fn to_u32() -> u32 { self } @@ -95,6 +107,9 @@ pub impl u64: NumCast { #[inline(always)] static pure fn from(n: T) -> u64 { move n.to_u64() } #[inline(always)] pure fn cast() -> T { move from(self) } + static pure fn zero() -> u64 { 0u64 } + static pure fn one() -> u64 { 1u64 } + #[inline(always)] pure fn to_u8() -> u8 { self as u8 } #[inline(always)] pure fn to_u16() -> u16 { self as u16 } #[inline(always)] pure fn to_u32() -> u32 { self as u32 } @@ -116,6 +131,9 @@ pub impl uint: NumCast { #[inline(always)] static pure fn from(n: T) -> uint { move n.to_uint() } #[inline(always)] pure fn cast() -> T { move from(self) } + static pure fn zero() -> uint { 0u } + static pure fn one() -> uint { 1u } + #[inline(always)] pure fn to_u8() -> u8 { self as u8 } #[inline(always)] pure fn to_u16() -> u16 { self as u16 } #[inline(always)] pure fn to_u32() -> u32 { self as u32 } @@ -137,6 +155,9 @@ pub impl i8: NumCast { #[inline(always)] static pure fn from(n: T) -> i8 { move n.to_i8() } #[inline(always)] pure fn cast() -> T { move from(self) } + static pure fn zero() -> i8 { 0i8 } + static pure fn one() -> i8 { 1i8 } + #[inline(always)] pure fn to_u8() -> u8 { self as u8 } #[inline(always)] pure fn to_u16() -> u16 { self as u16 } #[inline(always)] pure fn to_u32() -> u32 { self as u32 } @@ -158,6 +179,9 @@ pub impl i16: NumCast { #[inline(always)] static pure fn from(n: T) -> i16 { move n.to_i16() } #[inline(always)] pure fn cast() -> T { move from(self) } + static pure fn zero() -> i16 { 0i16 } + static pure fn one() -> i16 { 1i16 } + #[inline(always)] pure fn to_u8() -> u8 { self as u8 } #[inline(always)] pure fn to_u16() -> u16 { self as u16 } #[inline(always)] pure fn to_u32() -> u32 { self as u32 } @@ -179,6 +203,9 @@ pub impl i32: NumCast { #[inline(always)] static pure fn from(n: T) -> i32 { move n.to_i32() } #[inline(always)] pure fn cast() -> T { move from(self) } + static pure fn zero() -> i32 { 0i32 } + static pure fn one() -> i32 { 1i32 } + #[inline(always)] pure fn to_u8() -> u8 { self as u8 } #[inline(always)] pure fn to_u16() -> u16 { self as u16 } #[inline(always)] pure fn to_u32() -> u32 { self as u32 } @@ -200,6 +227,9 @@ pub impl i64: NumCast { #[inline(always)] static pure fn from(n: T) -> i64 { move n.to_i64() } #[inline(always)] pure fn cast() -> T { move from(self) } + static pure fn zero() -> i64 { 0i64 } + static pure fn one() -> i64 { 1i64 } + #[inline(always)] pure fn to_u8() -> u8 { self as u8 } #[inline(always)] pure fn to_u16() -> u16 { self as u16 } #[inline(always)] pure fn to_u32() -> u32 { self as u32 } @@ -221,6 +251,9 @@ pub impl int: NumCast { #[inline(always)] static pure fn from(n: T) -> int { move n.to_int() } #[inline(always)] pure fn cast() -> T { move from(self) } + static pure fn zero() -> int { 0 } + static pure fn one() -> int { 1 } + #[inline(always)] pure fn to_u8() -> u8 { self as u8 } #[inline(always)] pure fn to_u16() -> u16 { self as u16 } #[inline(always)] pure fn to_u32() -> u32 { self as u32 } @@ -242,6 +275,9 @@ pub impl f32: NumCast { #[inline(always)] static pure fn from(n: T) -> f32 { move n.to_f32() } #[inline(always)] pure fn cast() -> T { move from(self) } + static pure fn zero() -> f32 { 0f32 } + static pure fn one() -> f32 { 1f32 } + #[inline(always)] pure fn to_u8() -> u8 { self as u8 } #[inline(always)] pure fn to_u16() -> u16 { self as u16 } #[inline(always)] pure fn to_u32() -> u32 { self as u32 } @@ -263,6 +299,9 @@ pub impl f64: NumCast { #[inline(always)] static pure fn from(n: T) -> f64 { move n.to_f64() } #[inline(always)] pure fn cast() -> T { move from(self) } + static pure fn zero() -> f64 { 0f64 } + static pure fn one() -> f64 { 1f64 } + #[inline(always)] pure fn to_u8() -> u8 { self as u8 } #[inline(always)] pure fn to_u16() -> u16 { self as u16 } #[inline(always)] pure fn to_u32() -> u32 { self as u32 } @@ -284,6 +323,9 @@ pub impl float: NumCast { #[inline(always)] static pure fn from(n: T) -> float { move n.to_float() } #[inline(always)] pure fn cast() -> T { move from(self) } + static pure fn zero() -> float { 0f } + static pure fn one() -> float { 1f } + #[inline(always)] pure fn to_u8() -> u8 { self as u8 } #[inline(always)] pure fn to_u16() -> u16 { self as u16 } #[inline(always)] pure fn to_u32() -> u32 { self as u32 } diff --git a/src/quat.rs b/src/quat.rs index 432bc03..772aa0b 100644 --- a/src/quat.rs +++ b/src/quat.rs @@ -19,6 +19,9 @@ use vec::Vec3; // Quaternion // pub trait Quaternion: Dimensional, Eq, DefaultEq, Neg { + static pure fn identity() -> self; + static pure fn zero() -> self; + pure fn mul_t(value: T) -> self; pure fn div_t(value: T) -> self; @@ -85,6 +88,22 @@ pub mod Quat { } pub impl Quat: Quaternion { + #[inline(always)] + static pure fn identity() -> Quat { + Quat::new(NumCast::one(), + NumCast::one(), + NumCast::one(), + NumCast::one()) + } + + #[inline(always)] + static pure fn zero() -> Quat { + Quat::new(NumCast::zero(), + NumCast::zero(), + NumCast::zero(), + NumCast::zero()) + } + #[inline(always)] static pure fn dim() -> uint { 4 } diff --git a/src/vec.rs b/src/vec.rs index a0f59f4..8a87c65 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -14,6 +14,9 @@ use num::default_eq::DefaultEq; pub trait Vector: Dimensional, Eq, DefaultEq {} pub trait NumericVector: Vector, Neg{ + static pure fn identity() -> self; + static pure fn zero() -> self; + pure fn mul_t(value: T) -> self; pure fn div_t(value: T) -> self; @@ -115,7 +118,19 @@ pub impl Vec2: Vector { } } -pub impl Vec2: NumericVector { +pub impl Vec2: NumericVector { + #[inline(always)] + static pure fn identity() -> Vec2 { + Vec2::new(NumCast::one(), + NumCast::one()) + } + + #[inline(always)] + static pure fn zero() -> Vec2 { + Vec2::new(NumCast::zero(), + NumCast::zero()) + } + #[inline(always)] pure fn neg() -> Vec2 { Vec2::new(-self[0], -self[1]) @@ -297,7 +312,21 @@ pub impl Vec3: Vector { } } -pub impl Vec3: NumericVector { +pub impl Vec3: NumericVector { + #[inline(always)] + static pure fn identity() -> Vec3 { + Vec3::new(NumCast::one(), + NumCast::one(), + NumCast::one()) + } + + #[inline(always)] + static pure fn zero() -> Vec3 { + Vec3::new(NumCast::zero(), + NumCast::zero(), + NumCast::zero()) + } + #[inline(always)] pure fn neg() -> Vec3 { Vec3::new(-self[0], -self[1], -self[2]) @@ -483,7 +512,23 @@ pub impl Vec4: Vector { } } -pub impl Vec4: NumericVector { +pub impl Vec4: NumericVector { + #[inline(always)] + static pure fn identity() -> Vec4 { + Vec4::new(NumCast::one(), + NumCast::one(), + NumCast::one(), + NumCast::one()) + } + + #[inline(always)] + static pure fn zero() -> Vec4 { + Vec4::new(NumCast::zero(), + NumCast::zero(), + NumCast::zero(), + NumCast::zero()) + } + #[inline(always)] pure fn neg() -> Vec4 { Vec4::new(-self[0], -self[1], -self[2], -self[3])