Move functions to funs module. Add additional functions as per the GLSL spec

This commit is contained in:
Brendan Zabarauskas 2012-11-06 11:57:15 +10:00
parent 75a94dd745
commit 40e847f34f
14 changed files with 786 additions and 481 deletions

View file

@ -1,8 +1,6 @@
use cmp::Ord;
use num::*;
use ncast::*;
// TODO: move to a more appropriate module
pub trait ToPtr<T> {
pure fn to_ptr() -> *T;
@ -10,172 +8,4 @@ pub trait ToPtr<T> {
pub trait ExactEq {
pure fn exact_eq(other: &self) -> bool;
}
/**
* TODO: This trait will be implemented for <T:Num Ord> when generic trait
* support is improved. At the moment this would cause a conflict between the
* implementations in lmath::vector.
*/
trait MinMax {
pure fn min(other: &self) -> self;
pure fn max(other: &self) -> self;
}
#[inline(always)] pure fn min<T:MinMax>(a: &T, b: &T) -> T { a.min(b) }
#[inline(always)] pure fn max<T:MinMax>(a: &T, b: &T) -> T { a.max(b) }
impl u8: MinMax {
#[inline(always)] pure fn min(other: &u8) -> u8 { if self < *other { self } else { *other } }
#[inline(always)] pure fn max(other: &u8) -> u8 { if self > *other { self } else { *other } }
}
impl u16: MinMax {
#[inline(always)] pure fn min(other: &u16) -> u16 { if self < *other { self } else { *other } }
#[inline(always)] pure fn max(other: &u16) -> u16 { if self > *other { self } else { *other } }
}
impl u32: MinMax {
#[inline(always)] pure fn min(other: &u32) -> u32 { if self < *other { self } else { *other } }
#[inline(always)] pure fn max(other: &u32) -> u32 { if self > *other { self } else { *other } }
}
impl u64: MinMax {
#[inline(always)] pure fn min(other: &u64) -> u64 { if self < *other { self } else { *other } }
#[inline(always)] pure fn max(other: &u64) -> u64 { if self > *other { self } else { *other } }
}
impl uint: MinMax {
#[inline(always)] pure fn min(other: &uint) -> uint { if self < *other { self } else { *other } }
#[inline(always)] pure fn max(other: &uint) -> uint { if self > *other { self } else { *other } }
}
impl i8: MinMax {
#[inline(always)] pure fn min(other: &i8) -> i8 { if self < *other { self } else { *other } }
#[inline(always)] pure fn max(other: &i8) -> i8 { if self > *other { self } else { *other } }
}
impl i16: MinMax {
#[inline(always)] pure fn min(other: &i16) -> i16 { if self < *other { self } else { *other } }
#[inline(always)] pure fn max(other: &i16) -> i16 { if self > *other { self } else { *other } }
}
impl i32: MinMax {
#[inline(always)] pure fn min(other: &i32) -> i32 { if self < *other { self } else { *other } }
#[inline(always)] pure fn max(other: &i32) -> i32 { if self > *other { self } else { *other } }
}
impl i64: MinMax {
#[inline(always)] pure fn min(other: &i64) -> i64 { if self < *other { self } else { *other } }
#[inline(always)] pure fn max(other: &i64) -> i64 { if self > *other { self } else { *other } }
}
impl int: MinMax {
#[inline(always)] pure fn min(other: &int) -> int { if self < *other { self } else { *other } }
#[inline(always)] pure fn max(other: &int) -> int { if self > *other { self } else { *other } }
}
impl f32: MinMax {
#[inline(always)] pure fn min(other: &f32) -> f32 { if self < *other { self } else { *other } }
#[inline(always)] pure fn max(other: &f32) -> f32 { if self > *other { self } else { *other } }
}
impl f64: MinMax {
#[inline(always)] pure fn min(other: &f64) -> f64 { if self < *other { self } else { *other } }
#[inline(always)] pure fn max(other: &f64) -> f64 { if self > *other { self } else { *other } }
}
impl float: MinMax {
#[inline(always)] pure fn min(other: &float) -> float { if self < *other { self } else { *other } }
#[inline(always)] pure fn max(other: &float) -> float { if self > *other { self } else { *other } }
}
/**
* TODO: This trait will be implemented for <T:NumCast Ord> when generic trait
* support is improved. At the moment this would cause a conflict between the
* implementations in lmath::vector.
*/
trait Abs {
pure fn abs() -> self;
}
#[inline(always)]
pure fn abs<T:Abs>(x: &T) -> T {
x.abs()
}
impl i8: Abs { #[inline(always)] pure fn abs() -> i8 { if self >= 0 { self } else {-self } } }
impl i16: Abs { #[inline(always)] pure fn abs() -> i16 { if self >= 0 { self } else {-self } } }
impl i32: Abs { #[inline(always)] pure fn abs() -> i32 { if self >= 0 { self } else {-self } } }
impl i64: Abs { #[inline(always)] pure fn abs() -> i64 { if self >= 0 { self } else {-self } } }
impl int: Abs { #[inline(always)] pure fn abs() -> int { if self >= 0 { self } else {-self } } }
impl f32: Abs { #[inline(always)] pure fn abs() -> f32 { if self >= 0f32 { self } else {-self } } }
impl f64: Abs { #[inline(always)] pure fn abs() -> f64 { if self >= 0f64 { self } else {-self } } }
impl float: Abs { #[inline(always)] pure fn abs() -> float { if self >= 0f { self } else {-self } } }
pub trait Sqrt {
pure fn sqrt() -> self;
}
#[inline(always)]
pure fn sqrt<T:Sqrt>(n: T) -> T {
n.sqrt()
}
pub impl<T: NumCast> T: Sqrt {
#[inline(always)]
pure fn sqrt() -> T {
f64::sqrt(self.cast()).cast()
}
}
pub trait Trig {
pure fn sin() -> self;
pure fn cos() -> self;
pure fn tan() -> self;
pure fn asin() -> self;
pure fn acos() -> self;
pure fn atan() -> self;
pure fn sinh() -> self;
pure fn cosh() -> self;
pure fn tanh() -> self;
pure fn atan2(n: self) -> self;
}
#[inline(always)] pub pure fn sin<T:Trig>(n: T) -> T { n.sin() }
#[inline(always)] pub pure fn cos<T:Trig>(n: T) -> T { n.cos() }
#[inline(always)] pub pure fn tan<T:Trig>(n: T) -> T { n.tan() }
#[inline(always)] pub pure fn asin<T:Trig>(n: T) -> T { n.asin() }
#[inline(always)] pub pure fn acos<T:Trig>(n: T) -> T { n.acos() }
#[inline(always)] pub pure fn atan<T:Trig>(n: T) -> T { n.atan() }
#[inline(always)] pub pure fn sinh<T:Trig>(n: T) -> T { n.sinh() }
#[inline(always)] pub pure fn cosh<T:Trig>(n: T) -> T { n.cosh() }
#[inline(always)] pub pure fn tanh<T:Trig>(n: T) -> T { n.tanh() }
#[inline(always)] pub pure fn atan2<T:Trig>(a: T, b: T) -> T { a.atan2(move b) }
pub impl<T:NumCast> T: Trig {
#[inline(always)] pure fn sin() -> T { f64::sin(self.cast()).cast() }
#[inline(always)] pure fn cos() -> T { f64::cos(self.cast()).cast() }
#[inline(always)] pure fn tan() -> T { f64::tan(self.cast()).cast() }
#[inline(always)] pure fn asin() -> T { f64::asin(self.cast()).cast() }
#[inline(always)] pure fn acos() -> T { f64::acos(self.cast()).cast() }
#[inline(always)] pure fn atan() -> T { f64::atan(self.cast()).cast() }
#[inline(always)] pure fn sinh() -> T { f64::sinh(self.cast()).cast() }
#[inline(always)] pure fn cosh() -> T { f64::cosh(self.cast()).cast() }
#[inline(always)] pure fn tanh() -> T { f64::tanh(self.cast()).cast() }
#[inline(always)] pure fn atan2(n: T) -> T { f64::atan2(self.cast(), move n.cast()).cast() }
}
pub trait AngleUnits {
pure fn to_radians() -> self;
pure fn to_degrees() -> self;
}
#[inline(always)] pub pure fn radians<T:AngleUnits>(degrees: T) -> T { degrees.to_radians() }
#[inline(always)] pub pure fn degrees<T:AngleUnits>(radians: T) -> T { radians.to_degrees() }
pub impl<T:Num NumCast> T: AngleUnits {
#[inline(always)] pure fn to_radians() -> T { self * cast(f64::consts::pi / 180f64) }
#[inline(always)] pure fn to_degrees() -> T { self * cast(180f64 / f64::consts::pi) }
}

View file

@ -1,211 +0,0 @@
use cmp::{Eq, Ord};
use vector::{Vec2, Vec3, Vec4};
pub trait RelationalVector<BVec> {
pure fn less_than(other: &self) -> BVec;
pure fn less_than_equal(other: &self) -> BVec;
pure fn greater_than(other: &self) -> BVec;
pure fn greater_than_equal(other: &self) -> BVec;
pure fn equal(other: &self) -> BVec;
pure fn not_equal(other: &self) -> BVec;
}
#[inline(always)] pub pure fn less_than <T:RelationalVector<BVec>, BVec>(x: &T, y: &T) -> BVec { x.less_than(y) }
#[inline(always)] pub pure fn less_than_equal <T:RelationalVector<BVec>, BVec>(x: &T, y: &T) -> BVec { x.less_than_equal(y) }
#[inline(always)] pub pure fn greater_than <T:RelationalVector<BVec>, BVec>(x: &T, y: &T) -> BVec { x.greater_than(y) }
#[inline(always)] pub pure fn greater_than_equal<T:RelationalVector<BVec>, BVec>(x: &T, y: &T) -> BVec { x.greater_than_equal(y) }
#[inline(always)] pub pure fn equal <T:RelationalVector<BVec>, BVec>(x: &T, y: &T) -> BVec { x.equal(y) }
#[inline(always)] pub pure fn not_equal <T:RelationalVector<BVec>, BVec>(x: &T, y: &T) -> BVec { x.not_equal(y) }
pub trait BooleanVector {
pub fn any() -> bool;
pub fn all() -> bool;
pub fn not() -> self;
}
#[inline(always)] pub fn any<T:BooleanVector>(x: &T) -> bool { x.any() }
#[inline(always)] pub fn all<T:BooleanVector>(x: &T) -> bool { x.all() }
#[inline(always)] pub fn not<T:BooleanVector>(x: &T) -> T { x.not() }
pub impl<T:Copy Ord Eq> Vec2<T>: RelationalVector<Vec2<bool>> {
#[inline(always)]
pure fn less_than(other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] < other[0],
self[1] < other[1])
}
#[inline(always)]
pure fn less_than_equal(other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] <= other[0],
self[1] <= other[1])
}
#[inline(always)]
pure fn greater_than(other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] > other[0],
self[1] > other[1])
}
#[inline(always)]
pure fn greater_than_equal(other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] >= other[0],
self[1] >= other[1])
}
#[inline(always)]
pure fn equal(other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] == other[0],
self[1] == other[1])
}
#[inline(always)]
pure fn not_equal(other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] != other[0],
self[1] != other[1])
}
}
pub impl Vec2<bool>: BooleanVector {
pub fn any() -> bool {
self[0] || self[1]
}
pub fn all() -> bool {
self[0] && self[1]
}
pub fn not() -> Vec2<bool> {
Vec2::new(!self[0], !self[1])
}
}
pub impl<T:Copy Ord Eq> Vec3<T>: RelationalVector<Vec3<bool>> {
#[inline(always)]
pure fn less_than(other: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] < other[0],
self[1] < other[1],
self[2] < other[2])
}
#[inline(always)]
pure fn less_than_equal(other: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] <= other[0],
self[1] <= other[1],
self[2] <= other[2])
}
#[inline(always)]
pure fn greater_than(other: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] > other[0],
self[1] > other[1],
self[2] > other[2])
}
#[inline(always)]
pure fn greater_than_equal(other: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] >= other[0],
self[1] >= other[1],
self[2] >= other[2])
}
#[inline(always)]
pure fn equal(other: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] == other[0],
self[1] == other[1],
self[2] == other[2])
}
#[inline(always)]
pure fn not_equal(other: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] != other[0],
self[1] != other[1],
self[2] != other[2])
}
}
pub impl Vec3<bool>: BooleanVector {
pub fn any() -> bool {
self[0] || self[1] || self[2]
}
pub fn all() -> bool {
self[0] && self[1] && self[2]
}
pub fn not() -> Vec3<bool> {
Vec3::new(!self[0], !self[1], !self[2])
}
}
pub impl<T:Copy Ord Eq> Vec4<T>: RelationalVector<Vec4<bool>> {
#[inline(always)]
pure fn less_than(other: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] < other[0],
self[1] < other[1],
self[2] < other[2],
self[3] < other[3])
}
#[inline(always)]
pure fn less_than_equal(other: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] <= other[0],
self[1] <= other[1],
self[2] <= other[2],
self[3] <= other[3])
}
#[inline(always)]
pure fn greater_than(other: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] > other[0],
self[1] > other[1],
self[2] > other[2],
self[3] > other[3])
}
#[inline(always)]
pure fn greater_than_equal(other: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] >= other[0],
self[1] >= other[1],
self[2] >= other[2],
self[3] >= other[3])
}
#[inline(always)]
pure fn equal(other: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] == other[0],
self[1] == other[1],
self[2] == other[2],
self[3] == other[3])
}
#[inline(always)]
pure fn not_equal(other: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] != other[0],
self[1] != other[1],
self[2] != other[2],
self[3] != other[3])
}
}
pub impl Vec4<bool>: BooleanVector {
pub fn any() -> bool {
self[0] || self[1] || self[2] || self[3]
}
pub fn all() -> bool {
self[0] && self[1] && self[2] && self[3]
}
pub fn not() -> Vec4<bool> {
Vec4::new(!self[0], !self[1], !self[2], !self[3])
}
}

53
src/funs/boolv.rs Normal file
View file

@ -0,0 +1,53 @@
use vector::{Vec2, Vec3, Vec4};
pub trait BooleanVector {
pub fn any() -> bool;
pub fn all() -> bool;
pub fn not() -> self;
}
#[inline(always)] pub fn any<T:BooleanVector>(x: &T) -> bool { x.any() }
#[inline(always)] pub fn all<T:BooleanVector>(x: &T) -> bool { x.all() }
#[inline(always)] pub fn not<T:BooleanVector>(x: &T) -> T { x.not() }
pub impl Vec2<bool>: BooleanVector {
pub fn any() -> bool {
self[0] || self[1]
}
pub fn all() -> bool {
self[0] && self[1]
}
pub fn not() -> Vec2<bool> {
Vec2::new(!self[0], !self[1])
}
}
pub impl Vec3<bool>: BooleanVector {
pub fn any() -> bool {
self[0] || self[1] || self[2]
}
pub fn all() -> bool {
self[0] && self[1] && self[2]
}
pub fn not() -> Vec3<bool> {
Vec3::new(!self[0], !self[1], !self[2])
}
}
pub impl Vec4<bool>: BooleanVector {
pub fn any() -> bool {
self[0] || self[1] || self[2] || self[3]
}
pub fn all() -> bool {
self[0] && self[1] && self[2] && self[3]
}
pub fn not() -> Vec4<bool> {
Vec4::new(!self[0], !self[1], !self[2], !self[3])
}
}

214
src/funs/common.rs Normal file
View file

@ -0,0 +1,214 @@
use cmp::{Eq, Ord};
use num::Num;
use ncast::*;
use vector::*;
/**
* Common Functions for all numeric types
*/
pub trait Numeric {
pure fn min(y: &self) -> self;
pure fn max(y: &self) -> self;
pure fn clamp(minv: &self, maxv: &self) -> self;
}
#[inline(always)] pub pure fn min<T:Numeric>(x: &T, y: &T) -> T { x.min(y) }
#[inline(always)] pub pure fn max<T:Numeric>(x: &T, y: &T) -> T { x.max(y) }
#[inline(always)] pub pure fn clamp<T:Numeric>(x: &T, minv: &T, maxv: &T) -> T { x.clamp(minv, maxv) }
pub impl u8: Numeric {
#[inline(always)] pure fn min(y: &u8) -> u8 { if self < *y { self } else { *y } }
#[inline(always)] pure fn max(y: &u8) -> u8 { if self > *y { self } else { *y } }
#[inline(always)] pure fn clamp(minv: &u8, maxv: &u8) -> u8 { min(&max(&self, minv), maxv) }
}
pub impl u16: Numeric {
#[inline(always)] pure fn min(y: &u16) -> u16 { if self < *y { self } else { *y } }
#[inline(always)] pure fn max(y: &u16) -> u16 { if self > *y { self } else { *y } }
#[inline(always)] pure fn clamp(minv: &u16, maxv: &u16) -> u16 { min(&max(&self, minv), maxv) }
}
pub impl u32: Numeric {
#[inline(always)] pure fn min(y: &u32) -> u32 { if self < *y { self } else { *y } }
#[inline(always)] pure fn max(y: &u32) -> u32 { if self > *y { self } else { *y } }
#[inline(always)] pure fn clamp(minv: &u32, maxv: &u32) -> u32 { min(&max(&self, minv), maxv) }
}
pub impl u64: Numeric {
#[inline(always)] pure fn min(y: &u64) -> u64 { if self < *y { self } else { *y } }
#[inline(always)] pure fn max(y: &u64) -> u64 { if self > *y { self } else { *y } }
#[inline(always)] pure fn clamp(minv: &u64, maxv: &u64) -> u64 { min(&max(&self, minv), maxv) }
}
pub impl uint: Numeric {
#[inline(always)] pure fn min(y: &uint) -> uint { if self < *y { self } else { *y } }
#[inline(always)] pure fn max(y: &uint) -> uint { if self > *y { self } else { *y } }
#[inline(always)] pure fn clamp(minv: &uint, maxv: &uint) -> uint { min(&max(&self, minv), maxv) }
}
pub impl i8: Numeric {
#[inline(always)] pure fn min(y: &i8) -> i8 { if self < *y { self } else { *y } }
#[inline(always)] pure fn max(y: &i8) -> i8 { if self > *y { self } else { *y } }
#[inline(always)] pure fn clamp(minv: &i8, maxv: &i8) -> i8 { min(&max(&self, minv), maxv) }
}
pub impl i16: Numeric {
#[inline(always)] pure fn min(y: &i16) -> i16 { if self < *y { self } else { *y } }
#[inline(always)] pure fn max(y: &i16) -> i16 { if self > *y { self } else { *y } }
#[inline(always)] pure fn clamp(minv: &i16, maxv: &i16) -> i16 { min(&max(&self, minv), maxv) }
}
pub impl i32: Numeric {
#[inline(always)] pure fn min(y: &i32) -> i32 { if self < *y { self } else { *y } }
#[inline(always)] pure fn max(y: &i32) -> i32 { if self > *y { self } else { *y } }
#[inline(always)] pure fn clamp(minv: &i32, maxv: &i32) -> i32 { min(&max(&self, minv), maxv) }
}
pub impl i64: Numeric {
#[inline(always)] pure fn min(y: &i64) -> i64 { if self < *y { self } else { *y } }
#[inline(always)] pure fn max(y: &i64) -> i64 { if self > *y { self } else { *y } }
#[inline(always)] pure fn clamp(minv: &i64, maxv: &i64) -> i64 { min(&max(&self, minv), maxv) }
}
pub impl int: Numeric {
#[inline(always)] pure fn min(y: &int) -> int { if self < *y { self } else { *y } }
#[inline(always)] pure fn max(y: &int) -> int { if self > *y { self } else { *y } }
#[inline(always)] pure fn clamp(minv: &int, maxv: &int) -> int { min(&max(&self, minv), maxv) }
}
pub impl f32: Numeric {
#[inline(always)] pure fn min(y: &f32) -> f32 { if self < *y { self } else { *y } }
#[inline(always)] pure fn max(y: &f32) -> f32 { if self > *y { self } else { *y } }
#[inline(always)] pure fn clamp(minv: &f32, maxv: &f32) -> f32 { min(&max(&self, minv), maxv) }
}
pub impl f64: Numeric {
#[inline(always)] pure fn min(y: &f64) -> f64 { if self < *y { self } else { *y } }
#[inline(always)] pure fn max(y: &f64) -> f64 { if self > *y { self } else { *y } }
#[inline(always)] pure fn clamp(minv: &f64, maxv: &f64) -> f64 { min(&max(&self, minv), maxv) }
}
pub impl float: Numeric {
#[inline(always)] pure fn min(y: &float) -> float { if self < *y { self } else { *y } }
#[inline(always)] pure fn max(y: &float) -> float { if self > *y { self } else { *y } }
#[inline(always)] pure fn clamp(minv: &float, maxv: &float) -> float { min(&max(&self, minv), maxv) }
}
/**
* Common Functions for signed numeric types
*/
pub trait Signed {
pure fn abs() -> self;
pure fn sign() -> self;
pure fn mod_(y: &self) -> self;
}
#[inline(always)] pub pure fn abs<T:Signed>(x: &T) -> T { x.abs() }
#[inline(always)] pub pure fn sign<T:Signed>(x: &T) -> T { x.sign() }
#[inline(always)] pub pure fn mod_<T:Signed>(x: &T, y: &T) -> T { x.mod_(y) }
pub impl i8: Signed {
#[inline(always)] pure fn abs() -> i8 { if self >= 0 { self } else {-self } }
#[inline(always)] pure fn sign() -> i8 { if self > 0 { 1 } else if self == 0 { 0 } else { -1 } }
#[inline(always)] pure fn mod_(y: &i8) -> i8 { self % *y }
}
pub impl i16: Signed {
#[inline(always)] pure fn abs() -> i16 { if self >= 0 { self } else {-self } }
#[inline(always)] pure fn sign() -> i16 { if self > 0 { 1 } else if self == 0 { 0 } else { -1 } }
#[inline(always)] pure fn mod_(y: &i16) -> i16 { self % *y }
}
pub impl i32: Signed {
#[inline(always)] pure fn abs() -> i32 { if self >= 0 { self } else {-self } }
#[inline(always)] pure fn sign() -> i32 { if self > 0 { 1 } else if self == 0 { 0 } else { -1 } }
#[inline(always)] pure fn mod_(y: &i32) -> i32 { self % *y }
}
pub impl i64: Signed {
#[inline(always)] pure fn abs() -> i64 { if self >= 0 { self } else {-self } }
#[inline(always)] pure fn sign() -> i64 { if self > 0 { 1 } else if self == 0 { 0 } else { -1 } }
#[inline(always)] pure fn mod_(y: &i64) -> i64 { self % *y }
}
pub impl int: Signed {
#[inline(always)] pure fn abs() -> int { if self >= 0 { self } else {-self } }
#[inline(always)] pure fn sign() -> int { if self > 0 { 1 } else if self == 0 { 0 } else { -1 } }
#[inline(always)] pure fn mod_(y: &int) -> int { self % *y }
}
pub impl f32: Signed {
#[inline(always)] pure fn abs() -> f32 { if self >= 0f32 { self } else {-self } }
#[inline(always)] pure fn sign() -> f32 { if self > 0f32 { 1f32 } else if self == 0f32 { 0f32 } else { -1f32 } }
#[inline(always)] pure fn mod_(y: &f32) -> f32 { self % *y }
}
pub impl f64: Signed {
#[inline(always)] pure fn abs() -> f64 { if self >= 0f64 { self } else {-self } }
#[inline(always)] pure fn sign() -> f64 { if self > 0f64 { 1f64 } else if self == 0f64 { 0f64 } else { -1f64 } }
#[inline(always)] pure fn mod_(y: &f64) -> f64 { self % *y }
}
pub impl float: Signed {
#[inline(always)] pure fn abs() -> float { if self >= 0f { self } else {-self } }
#[inline(always)] pure fn sign() -> float { if self > 0f { 1f } else if self == 0f { 0f } else { -1f } }
#[inline(always)] pure fn mod_(y: &float) -> float { self % *y }
}
/**
* Common Functions for floating point types
*/
pub trait Float<B> {
pure fn floor() -> self;
pure fn trunc() -> self;
pure fn round() -> self;
// pure fn roundEven() -> self;
pure fn ceil() -> self;
// pure fn fract() -> self;
pure fn mix(y: &self, a: &self) -> self;
pure fn mixb(y: &self, a: &B) -> self;
}
#[inline(always)] pub pure fn floor<T:Float<B>, B>(x: T) -> T { x.floor() }
#[inline(always)] pub pure fn trunc<T:Float<B>, B>(x: T) -> T { x.trunc() }
#[inline(always)] pub pure fn round<T:Float<B>, B>(x: T) -> T { x.round() }
// #[inline(always)] pub pure fn roundEven<T:Float<B>, B>(x: T) -> T { x.roundEven() }
#[inline(always)] pub pure fn ceil<T:Float<B>, B>(x: T) -> T { x.ceil() }
// #[inline(always)] pub pure fn fract<T:Float<B>, B>(x: T) -> T { x.fract() }
#[inline(always)] pub pure fn mix<T:Float<B>, B>(x: &T, y: &T, a: &T) -> T { x.mix(y, a) }
#[inline(always)] pub pure fn mixb<T:Float<B>, B>(x: &T, y: &T, a: &B) -> T { x.mixb(y, a) }
pub impl f32: Float<bool> {
#[inline(always)] pure fn floor() -> f32 { f32::floor(self) }
#[inline(always)] pure fn trunc() -> f32 { f32::trunc(self) }
#[inline(always)] pure fn round() -> f32 { f32::round(self) }
// #[inline(always)] pure fn roundEven() -> f32 {}
#[inline(always)] pure fn ceil() -> f32 { f32::ceil(self) }
// #[inline(always)] pure fn fract() -> f32 {}
#[inline(always)] pure fn mix(y: &f32, a: &f32) -> f32 { self * (1f32 - (*a)) + y * (*a) }
#[inline(always)] pure fn mixb(y: &f32, a: &bool) -> f32 { if *a { *y } else { self } }
}
pub impl f64: Float<bool> {
#[inline(always)] pure fn floor() -> f64 { f64::floor(self) }
#[inline(always)] pure fn trunc() -> f64 { f64::trunc(self) }
#[inline(always)] pure fn round() -> f64 { f64::round(self) }
// #[inline(always)] pure fn roundEven() -> f64 {}
#[inline(always)] pure fn ceil() -> f64 { f64::ceil(self) }
// #[inline(always)] pure fn fract() -> f64 {}
#[inline(always)] pure fn mix(y: &f64, a: &f64) -> f64 { self * (1f64 - (*a)) + y * (*a) }
#[inline(always)] pure fn mixb(y: &f64, a: &bool) -> f64 { if *a { *y } else { self } }
}
pub impl float: Float<bool> {
#[inline(always)] pure fn floor() -> float { cast(float::floor(cast(self))) }
#[inline(always)] pure fn trunc() -> float { cast(float::trunc(cast(self))) }
#[inline(always)] pure fn round() -> float { cast(float::round(cast(self))) }
// #[inline(always)] pure fn roundEven() -> float {}
#[inline(always)] pure fn ceil() -> float { cast(float::ceil(cast(self))) }
// #[inline(always)] pure fn fract() -> float {}
#[inline(always)] pure fn mix(y: &float, a: &float) -> float { self * (1f - (*a)) + y * (*a) }
#[inline(always)] pure fn mixb(y: &float, a: &bool) -> float { if *a { *y } else { self } }
}

55
src/funs/exp.rs Normal file
View file

@ -0,0 +1,55 @@
/**
* Exponential Functions
*/
use num::Num;
use ncast::*;
pub trait Exp {
pure fn pow(n: self) -> self;
pure fn exp() -> self;
pure fn log_() -> self;
pure fn exp2() -> self;
pure fn log2() -> self;
pure fn sqrt() -> self;
pure fn inv_sqrt() -> self;
}
#[inline(always)] pub pure fn pow<T:Exp>(x: T, y: T) -> T { x.pow(move y) }
#[inline(always)] pub pure fn exp<T:Exp>(x: T) -> T { x.exp() }
#[inline(always)] pub pure fn log_<T:Exp>(x: T) -> T { x.log_() }
#[inline(always)] pub pure fn exp2<T:Exp>(x: T) -> T { x.exp2() }
#[inline(always)] pub pure fn log2<T:Exp>(x: T) -> T { x.log2() }
#[inline(always)] pub pure fn sqrt<T:Exp>(x: T) -> T { x.sqrt() }
#[inline(always)] pub pure fn inv_sqrt<T:Exp>(x: T) -> T { x.inv_sqrt() }
pub impl f32: Exp {
#[inline(always)] pure fn pow(y: f32) -> f32 { f32::pow(self, y) }
#[inline(always)] pure fn exp() -> f32 { f32::exp(self) }
#[inline(always)] pure fn log_() -> f32 { f32::ln(self) }
#[inline(always)] pure fn exp2() -> f32 { f32::exp2(self) }
#[inline(always)] pure fn log2() -> f32 { f32::log2(self) }
#[inline(always)] pure fn sqrt() -> f32 { f32::sqrt(self) }
#[inline(always)] pure fn inv_sqrt() -> f32 { 1f32 / self.sqrt() } // TODO: optimise? need a wizard
}
pub impl f64: Exp {
#[inline(always)] pure fn pow(y: f64) -> f64 { f64::pow(self, y) }
#[inline(always)] pure fn exp() -> f64 { f64::exp(self) }
#[inline(always)] pure fn log_() -> f64 { f64::ln(self) }
#[inline(always)] pure fn exp2() -> f64 { f64::exp2(self) }
#[inline(always)] pure fn log2() -> f64 { f64::log2(self) }
#[inline(always)] pure fn sqrt() -> f64 { f64::sqrt(self) }
#[inline(always)] pure fn inv_sqrt() -> f64 { 1f64 / self.sqrt() } // TODO: optimise? need a wizard
}
pub impl float: Exp {
#[inline(always)] pure fn pow(y: float) -> float { cast(float::pow(cast(self), cast(y))) }
#[inline(always)] pure fn exp() -> float { cast(float::exp(cast(self))) }
#[inline(always)] pure fn log_() -> float { cast(float::ln(cast(self))) }
#[inline(always)] pure fn exp2() -> float { cast(float::exp2(cast(self))) }
#[inline(always)] pure fn log2() -> float { cast(float::log2(cast(self))) }
#[inline(always)] pure fn sqrt() -> float { cast(float::sqrt(cast(self))) }
#[inline(always)] pure fn inv_sqrt() -> float { 1f / self.sqrt() } // TODO: optimise? need a wizard
}

155
src/funs/relv.rs Normal file
View file

@ -0,0 +1,155 @@
/**
* Vector Relational Functions
*/
use cmp::{Eq, Ord};
use vector::{Vec2, Vec3, Vec4};
pub trait RelVector<BVec> {
pure fn less_than(y: &self) -> BVec;
pure fn less_than_equal(y: &self) -> BVec;
pure fn greater_than(y: &self) -> BVec;
pure fn greater_than_equal(y: &self) -> BVec;
pure fn equal(y: &self) -> BVec;
pure fn not_equal(y: &self) -> BVec;
}
#[inline(always)] pub pure fn less_than <T:RelVector<BV>, BV>(x: &T, y: &T) -> BV { x.less_than(y) }
#[inline(always)] pub pure fn less_than_equal <T:RelVector<BV>, BV>(x: &T, y: &T) -> BV { x.less_than_equal(y) }
#[inline(always)] pub pure fn greater_than <T:RelVector<BV>, BV>(x: &T, y: &T) -> BV { x.greater_than(y) }
#[inline(always)] pub pure fn greater_than_equal<T:RelVector<BV>, BV>(x: &T, y: &T) -> BV { x.greater_than_equal(y) }
#[inline(always)] pub pure fn equal <T:RelVector<BV>, BV>(x: &T, y: &T) -> BV { x.equal(y) }
#[inline(always)] pub pure fn not_equal <T:RelVector<BV>, BV>(x: &T, y: &T) -> BV { x.not_equal(y) }
pub impl<T:Copy Ord Eq> Vec2<T>: RelVector<Vec2<bool>> {
#[inline(always)]
pure fn less_than(y: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] < y[0],
self[1] < y[1])
}
#[inline(always)]
pure fn less_than_equal(y: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] <= y[0],
self[1] <= y[1])
}
#[inline(always)]
pure fn greater_than(y: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] > y[0],
self[1] > y[1])
}
#[inline(always)]
pure fn greater_than_equal(y: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] >= y[0],
self[1] >= y[1])
}
#[inline(always)]
pure fn equal(y: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] == y[0],
self[1] == y[1])
}
#[inline(always)]
pure fn not_equal(y: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] != y[0],
self[1] != y[1])
}
}
pub impl<T:Copy Ord Eq> Vec3<T>: RelVector<Vec3<bool>> {
#[inline(always)]
pure fn less_than(y: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] < y[0],
self[1] < y[1],
self[2] < y[2])
}
#[inline(always)]
pure fn less_than_equal(y: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] <= y[0],
self[1] <= y[1],
self[2] <= y[2])
}
#[inline(always)]
pure fn greater_than(y: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] > y[0],
self[1] > y[1],
self[2] > y[2])
}
#[inline(always)]
pure fn greater_than_equal(y: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] >= y[0],
self[1] >= y[1],
self[2] >= y[2])
}
#[inline(always)]
pure fn equal(y: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] == y[0],
self[1] == y[1],
self[2] == y[2])
}
#[inline(always)]
pure fn not_equal(y: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] != y[0],
self[1] != y[1],
self[2] != y[2])
}
}
pub impl<T:Copy Ord Eq> Vec4<T>: RelVector<Vec4<bool>> {
#[inline(always)]
pure fn less_than(y: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] < y[0],
self[1] < y[1],
self[2] < y[2],
self[3] < y[3])
}
#[inline(always)]
pure fn less_than_equal(y: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] <= y[0],
self[1] <= y[1],
self[2] <= y[2],
self[3] <= y[3])
}
#[inline(always)]
pure fn greater_than(y: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] > y[0],
self[1] > y[1],
self[2] > y[2],
self[3] > y[3])
}
#[inline(always)]
pure fn greater_than_equal(y: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] >= y[0],
self[1] >= y[1],
self[2] >= y[2],
self[3] >= y[3])
}
#[inline(always)]
pure fn equal(y: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] == y[0],
self[1] == y[1],
self[2] == y[2],
self[3] == y[3])
}
#[inline(always)]
pure fn not_equal(y: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] != y[0],
self[1] != y[1],
self[2] != y[2],
self[3] != y[3])
}
}

View file

@ -1,8 +1,8 @@
use vector::*;
use relational::*;
use boolv::*;
#[test]
fn test_BooleanVec2_trait() {
fn test_boolv2() {
let tf = Vec2::new(true, false);
let ff = Vec2::new(false, false);
let tt = Vec2::new(true, true);
@ -21,7 +21,7 @@ fn test_BooleanVec2_trait() {
}
#[test]
fn test_BooleanVec3_trait() {
fn test_boolv3() {
let tft = Vec3::new(true, false, true);
let fff = Vec3::new(false, false, false);
let ttt = Vec3::new(true, true, true);
@ -40,7 +40,7 @@ fn test_BooleanVec3_trait() {
}
#[test]
fn test_BooleanVec4_trait() {
fn test_boolv4() {
let tftf = Vec4::new(true, false, true, false);
let ffff = Vec4::new(false, false, false, false);
let tttt = Vec4::new(true, true, true, true);
@ -59,7 +59,7 @@ fn test_BooleanVec4_trait() {
}
#[test]
fn test_BooleanVec_fns() {
fn test_boolv_fns() {
let tf = Vec2::new(true, false);
let ftf = Vec3::new(false, true, false);
let tftf = Vec4::new(true, false, true, false);

277
src/funs/trig.rs Normal file
View file

@ -0,0 +1,277 @@
use ncast::*;
use vector::*;
/**
* Angle and Trigonometry Functions
*/
pub trait Trig {
pure fn radians() -> self;
pure fn degrees() -> self;
pure fn sin() -> self;
pure fn cos() -> self;
pure fn tan() -> self;
pure fn asin() -> self;
pure fn acos() -> self;
pure fn atan() -> self;
pure fn sinh() -> self;
pure fn cosh() -> self;
pure fn tanh() -> self;
}
#[inline(always)] pub pure fn radians<T:Trig>(degrees: &T) -> T { degrees.radians() }
#[inline(always)] pub pure fn degrees<T:Trig>(radians: &T) -> T { radians.degrees() }
#[inline(always)] pub pure fn sin<T:Trig>(angle: &T) -> T { angle.sin() }
#[inline(always)] pub pure fn cos<T:Trig>(angle: &T) -> T { angle.cos() }
#[inline(always)] pub pure fn tan<T:Trig>(angle: &T) -> T { angle.tan() }
#[inline(always)] pub pure fn asin<T:Trig>(x: &T) -> T { x.asin() }
#[inline(always)] pub pure fn acos<T:Trig>(x: &T) -> T { x.acos() }
#[inline(always)] pub pure fn atan<T:Trig>(x: &T) -> T { x.atan() }
#[inline(always)] pub pure fn sinh<T:Trig>(x: &T) -> T { x.sinh() }
#[inline(always)] pub pure fn cosh<T:Trig>(x: &T) -> T { x.cosh() }
#[inline(always)] pub pure fn tanh<T:Trig>(x: &T) -> T { x.tanh() }
pub impl f32: Trig {
#[inline(always)] pure fn radians() -> f32 { self * (f32::consts::pi / 180f32) }
#[inline(always)] pure fn degrees() -> f32 { self * (180f32 / f32::consts::pi) }
#[inline(always)] pure fn sin() -> f32 { f32::sin(self) }
#[inline(always)] pure fn cos() -> f32 { f32::cos(self) }
#[inline(always)] pure fn tan() -> f32 { f32::tan(self) }
#[inline(always)] pure fn asin() -> f32 { f32::asin(self) }
#[inline(always)] pure fn acos() -> f32 { f32::acos(self) }
#[inline(always)] pure fn atan() -> f32 { f32::atan(self) }
#[inline(always)] pure fn sinh() -> f32 { f32::sinh(self) }
#[inline(always)] pure fn cosh() -> f32 { f32::cosh(self) }
#[inline(always)] pure fn tanh() -> f32 { f32::tanh(self) }
}
pub impl f64: Trig {
#[inline(always)] pure fn radians() -> f64 { self * (f64::consts::pi / 180f64) }
#[inline(always)] pure fn degrees() -> f64 { self * (180f64 / f64::consts::pi) }
#[inline(always)] pure fn sin() -> f64 { f64::sin(self) }
#[inline(always)] pure fn cos() -> f64 { f64::cos(self) }
#[inline(always)] pure fn tan() -> f64 { f64::tan(self) }
#[inline(always)] pure fn asin() -> f64 { f64::asin(self) }
#[inline(always)] pure fn acos() -> f64 { f64::acos(self) }
#[inline(always)] pure fn atan() -> f64 { f64::atan(self) }
#[inline(always)] pure fn sinh() -> f64 { f64::sinh(self) }
#[inline(always)] pure fn cosh() -> f64 { f64::cosh(self) }
#[inline(always)] pure fn tanh() -> f64 { f64::tanh(self) }
}
pub impl float: Trig {
#[inline(always)] pure fn radians() -> float { self * (float::consts::pi / 180f) }
#[inline(always)] pure fn degrees() -> float { self * (180f / float::consts::pi) }
#[inline(always)] pure fn sin() -> float { cast(float::sin(cast(self))) }
#[inline(always)] pure fn cos() -> float { cast(float::cos(cast(self))) }
#[inline(always)] pure fn tan() -> float { cast(float::tan(cast(self))) }
#[inline(always)] pure fn asin() -> float { cast(float::asin(cast(self))) }
#[inline(always)] pure fn acos() -> float { cast(float::acos(cast(self))) }
#[inline(always)] pure fn atan() -> float { cast(float::atan(cast(self))) }
#[inline(always)] pure fn sinh() -> float { cast(float::sinh(cast(self))) }
#[inline(always)] pure fn cosh() -> float { cast(float::cosh(cast(self))) }
#[inline(always)] pure fn tanh() -> float { cast(float::tanh(cast(self))) }
}
pub impl<T:Copy Trig> Vec2<T>: Trig {
#[inline(always)] pure fn radians() -> Vec2<T> {
Vec2::new(radians(&self[0]),
radians(&self[1]))
}
#[inline(always)] pure fn degrees() -> Vec2<T> {
Vec2::new(degrees(&self[0]),
degrees(&self[1]))
}
#[inline(always)] pure fn sin() -> Vec2<T> {
Vec2::new(sin(&self[0]),
sin(&self[1]))
}
#[inline(always)] pure fn cos() -> Vec2<T> {
Vec2::new(cos(&self[0]),
cos(&self[1]))
}
#[inline(always)] pure fn tan() -> Vec2<T> {
Vec2::new(tan(&self[0]),
tan(&self[1]))
}
#[inline(always)] pure fn asin() -> Vec2<T> {
Vec2::new(asin(&self[0]),
asin(&self[1]))
}
#[inline(always)] pure fn acos() -> Vec2<T> {
Vec2::new(acos(&self[0]),
acos(&self[1]))
}
#[inline(always)] pure fn atan() -> Vec2<T> {
Vec2::new(atan(&self[0]),
atan(&self[1]))
}
#[inline(always)] pure fn sinh() -> Vec2<T> {
Vec2::new(sinh(&self[0]),
sinh(&self[1]))
}
#[inline(always)] pure fn cosh() -> Vec2<T> {
Vec2::new(cosh(&self[0]),
cosh(&self[1]))
}
#[inline(always)] pure fn tanh() -> Vec2<T> {
Vec2::new(tanh(&self[0]),
tanh(&self[1]))
}
}
pub impl<T:Copy Trig> Vec3<T>: Trig {
#[inline(always)] pure fn radians() -> Vec3<T> {
Vec3::new(radians(&self[0]),
radians(&self[1]),
radians(&self[2]))
}
#[inline(always)] pure fn degrees() -> Vec3<T> {
Vec3::new(degrees(&self[0]),
degrees(&self[1]),
degrees(&self[2]))
}
#[inline(always)] pure fn sin() -> Vec3<T> {
Vec3::new(sin(&self[0]),
sin(&self[1]),
sin(&self[2]))
}
#[inline(always)] pure fn cos() -> Vec3<T> {
Vec3::new(cos(&self[0]),
cos(&self[1]),
cos(&self[2]))
}
#[inline(always)] pure fn tan() -> Vec3<T> {
Vec3::new(tan(&self[0]),
tan(&self[1]),
tan(&self[2]))
}
#[inline(always)] pure fn asin() -> Vec3<T> {
Vec3::new(asin(&self[0]),
asin(&self[1]),
asin(&self[2]))
}
#[inline(always)] pure fn acos() -> Vec3<T> {
Vec3::new(acos(&self[0]),
acos(&self[1]),
acos(&self[2]))
}
#[inline(always)] pure fn atan() -> Vec3<T> {
Vec3::new(atan(&self[0]),
atan(&self[1]),
atan(&self[2]))
}
#[inline(always)] pure fn sinh() -> Vec3<T> {
Vec3::new(sinh(&self[0]),
sinh(&self[1]),
sinh(&self[2]))
}
#[inline(always)] pure fn cosh() -> Vec3<T> {
Vec3::new(cosh(&self[0]),
cosh(&self[1]),
cosh(&self[2]))
}
#[inline(always)] pure fn tanh() -> Vec3<T> {
Vec3::new(tanh(&self[0]),
tanh(&self[1]),
tanh(&self[2]))
}
}
pub impl<T:Copy Trig> Vec4<T>: Trig {
#[inline(always)] pure fn radians() -> Vec4<T> {
Vec4::new(radians(&self[0]),
radians(&self[1]),
radians(&self[2]),
radians(&self[3]))
}
#[inline(always)] pure fn degrees() -> Vec4<T> {
Vec4::new(degrees(&self[0]),
degrees(&self[1]),
degrees(&self[2]),
degrees(&self[3]))
}
#[inline(always)] pure fn sin() -> Vec4<T> {
Vec4::new(sin(&self[0]),
sin(&self[1]),
sin(&self[2]),
sin(&self[3]))
}
#[inline(always)] pure fn cos() -> Vec4<T> {
Vec4::new(cos(&self[0]),
cos(&self[1]),
cos(&self[2]),
cos(&self[3]))
}
#[inline(always)] pure fn tan() -> Vec4<T> {
Vec4::new(tan(&self[0]),
tan(&self[1]),
tan(&self[2]),
tan(&self[3]))
}
#[inline(always)] pure fn asin() -> Vec4<T> {
Vec4::new(asin(&self[0]),
asin(&self[1]),
asin(&self[2]),
asin(&self[3]))
}
#[inline(always)] pure fn acos() -> Vec4<T> {
Vec4::new(acos(&self[0]),
acos(&self[1]),
acos(&self[2]),
acos(&self[3]))
}
#[inline(always)] pure fn atan() -> Vec4<T> {
Vec4::new(atan(&self[0]),
atan(&self[1]),
atan(&self[2]),
atan(&self[3]))
}
#[inline(always)] pure fn sinh() -> Vec4<T> {
Vec4::new(sinh(&self[0]),
sinh(&self[1]),
sinh(&self[2]),
sinh(&self[3]))
}
#[inline(always)] pure fn cosh() -> Vec4<T> {
Vec4::new(cosh(&self[0]),
cosh(&self[1]),
cosh(&self[2]),
cosh(&self[3]))
}
#[inline(always)] pure fn tanh() -> Vec4<T> {
Vec4::new(tanh(&self[0]),
tanh(&self[1]),
tanh(&self[2]),
tanh(&self[3]))
}
}

View file

@ -30,11 +30,15 @@ pub mod common {
pub mod ntrait;
}
pub mod functions {
pub mod relational;
pub mod funs {
pub mod boolv;
pub mod common;
pub mod exp;
pub mod relv;
pub mod trig;
#[test]
mod test {
mod test_relational;
mod test_boolv;
}
}

View file

@ -5,6 +5,7 @@ use ptr::to_unsafe_ptr;
use vec::raw::buf_as_slice;
use std::cmp::FuzzyEq;
use funs::exp::Exp;
use math::*;
use ncast::*;
use quaternion::{Quat, ToQuat};
@ -228,7 +229,7 @@ pub impl<T:Copy Num NumCast FuzzyEq> Mat2<T>: SquareMatrix<T> {
}
}
pub impl<T:Copy Num NumCast Sqrt FuzzyEq> Mat2<T>: Matrix2<T> {
pub impl<T:Copy Num NumCast FuzzyEq> Mat2<T>: Matrix2<T> {
#[inline(always)]
pure fn to_Mat3() -> Mat3<T> {
Mat3::from_Mat2(&self)
@ -464,7 +465,7 @@ pub impl<T:Copy Num NumCast FuzzyEq> Mat3<T>: SquareMatrix<T> {
}
}
pub impl<T:Copy Num NumCast Sqrt FuzzyEq> Mat3<T>: Matrix3<T> {
pub impl<T:Copy Num NumCast FuzzyEq> Mat3<T>: Matrix3<T> {
#[inline(always)]
pure fn to_Mat4() -> Mat4<T> {
Mat4::from_Mat3(&self)

View file

@ -5,8 +5,10 @@ use ptr::to_unsafe_ptr;
use vec::raw::buf_as_slice;
use std::cmp::FuzzyEq;
use funs::exp::Exp;
use math::*;
use matrix::{Mat3, Mat4};
use ncast::*;
use vector::Vec3;
@ -76,7 +78,7 @@ pub mod Quat {
}
}
pub impl<T:Copy Num NumCast Sqrt FuzzyEq> Quat<T>: Quaternion<T> {
pub impl<T:Copy Num NumCast Exp FuzzyEq> Quat<T>: Quaternion<T> {
#[inline(always)]
pure fn dim() -> uint { 4 }

View file

@ -1 +0,0 @@
// TODO

View file

@ -48,9 +48,9 @@ fn test_Vec2() {
let f3 = 0.75f;
assert c.lerp(&d, f3) == Vec2::new(0.250f, -0.250f);
assert c.abs() == Vec2::new( 2.0f, 1.0f);
assert c.min(&d) == Vec2::new(-2.0f, -1.0f);
assert c.max(&d) == Vec2::new( 1.0f, 0.0f);
// assert c.abs() == Vec2::new( 2.0f, 1.0f);
// assert c.min(&d) == Vec2::new(-2.0f, -1.0f);
// assert c.max(&d) == Vec2::new( 1.0f, 0.0f);
}
#[test]
@ -103,9 +103,9 @@ fn test_Vec3() {
let f3 = 0.75f;
assert c.lerp(&d, f3) == Vec3::new(0.250f, -0.250f, 0.625f);
assert c.abs() == Vec3::new( 2.0f, 1.0f, 1.0f);
assert c.min(&d) == Vec3::new(-2.0f, -1.0f, 0.5f);
assert c.max(&d) == Vec3::new( 1.0f, 0.0f, 1.0f);
// assert c.abs() == Vec3::new( 2.0f, 1.0f, 1.0f);
// assert c.min(&d) == Vec3::new(-2.0f, -1.0f, 0.5f);
// assert c.max(&d) == Vec3::new( 1.0f, 0.0f, 1.0f);
}
#[test]
@ -161,7 +161,7 @@ fn test_Vec4() {
let f3 = 0.75f;
assert c.lerp(&d, f3) == Vec4::new(0.250f, -0.250f, 0.625f, 1.250f);
assert c.abs() == Vec4::new( 2.0f, 1.0f, 1.0f, 2.0f);
assert c.min(&d) == Vec4::new(-2.0f, -1.0f, 0.5f, 1.0f);
assert c.max(&d) == Vec4::new( 1.0f, 0.0f, 1.0f, 2.0f);
// assert c.abs() == Vec4::new( 2.0f, 1.0f, 1.0f, 2.0f);
// assert c.min(&d) == Vec4::new(-2.0f, -1.0f, 0.5f, 1.0f);
// assert c.max(&d) == Vec4::new( 1.0f, 0.0f, 1.0f, 2.0f);
}

View file

@ -5,9 +5,10 @@ use vec::raw::buf_as_slice;
use ptr::to_unsafe_ptr;
use std::cmp::FuzzyEq;
use funs::exp::Exp;
use ncast::*;
use math::*;
// GLSL equivalent type aliases
type vec2 = Vec2<f32>; /// a two-component single-precision floating-point vector
@ -167,7 +168,7 @@ pub impl<T:Copy Num> Vec2<T>: NumericVector<T> {
}
}
pub impl<T:Copy Num Sqrt> Vec2<T>: GeometricVector<T> {
pub impl<T:Copy Num Exp> Vec2<T>: GeometricVector<T> {
#[inline(always)]
pure fn length2() -> T {
self[0] * self[0] +
@ -202,28 +203,6 @@ pub impl<T:Copy> Vec2<T>: Index<uint, T> {
}
}
pub impl<T:Copy MinMax> Vec2<T>: MinMax {
#[inline(always)]
pure fn min(other: &Vec2<T>) -> Vec2<T> {
Vec2::new(min(&self[0], &other[0]),
min(&self[1], &other[1]))
}
#[inline(always)]
pure fn max(other: &Vec2<T>) -> Vec2<T> {
Vec2::new(max(&self[0], &other[0]),
max(&self[1], &other[1]))
}
}
pub impl<T:Copy Abs> Vec2<T>: Abs {
#[inline(always)]
pure fn abs() -> Vec2<T> {
Vec2::new(abs(&self[0]),
abs(&self[1]))
}
}
pub impl<T:Copy Neg<T>> Vec2<T>: Neg<Vec2<T>> {
#[inline(always)]
pure fn neg() -> Vec2<T> {
@ -388,7 +367,7 @@ pub impl<T:Copy Num> Vec3<T>: NumericVector<T> {
}
}
pub impl<T:Copy Num Sqrt> Vec3<T>: GeometricVector<T> {
pub impl<T:Copy Num Exp> Vec3<T>: GeometricVector<T> {
#[inline(always)]
pure fn length2() -> T {
self[0] * self[0] +
@ -424,31 +403,6 @@ pub impl<T:Copy> Vec3<T>: Index<uint, T> {
}
}
pub impl<T:Copy MinMax> Vec3<T>: MinMax {
#[inline(always)]
pure fn min(other: &Vec3<T>) -> Vec3<T> {
Vec3::new(min(&self[0], &other[0]),
min(&self[1], &other[1]),
min(&self[2], &other[2]))
}
#[inline(always)]
pure fn max(other: &Vec3<T>) -> Vec3<T> {
Vec3::new(max(&self[0], &other[0]),
max(&self[1], &other[1]),
max(&self[2], &other[2]))
}
}
pub impl<T:Copy Abs> Vec3<T>: Abs {
#[inline(always)]
pure fn abs() -> Vec3<T> {
Vec3::new(abs(&self[0]),
abs(&self[1]),
abs(&self[2]))
}
}
pub impl<T:Copy Neg<T>> Vec3<T>: Neg<Vec3<T>> {
#[inline(always)]
pure fn neg() -> Vec3<T> {
@ -620,7 +574,7 @@ pub impl<T:Copy Num> Vec4<T>: NumericVector<T> {
}
}
pub impl<T:Copy Num Sqrt> Vec4<T>: GeometricVector<T> {
pub impl<T:Copy Num Exp> Vec4<T>: GeometricVector<T> {
#[inline(always)]
pure fn length2() -> T {
self[0] * self[0] +
@ -658,34 +612,6 @@ pub impl<T:Copy> Vec4<T>: Index<uint, T> {
}
}
pub impl<T:Copy MinMax> Vec4<T>: MinMax {
#[inline(always)]
pure fn min(other: &Vec4<T>) -> Vec4<T> {
Vec4::new(min(&self[0], &other[0]),
min(&self[1], &other[1]),
min(&self[2], &other[2]),
min(&self[3], &other[3]))
}
#[inline(always)]
pure fn max(other: &Vec4<T>) -> Vec4<T> {
Vec4::new(max(&self[0], &other[0]),
max(&self[1], &other[1]),
max(&self[2], &other[2]),
max(&self[3], &other[3]))
}
}
pub impl<T:Copy Abs> Vec4<T>: Abs {
#[inline(always)]
pure fn abs() -> Vec4<T> {
Vec4::new(abs(&self[0]),
abs(&self[1]),
abs(&self[2]),
abs(&self[3]))
}
}
pub impl<T:Copy Neg<T>> Vec4<T>: Neg<Vec4<T>> {
#[inline(always)]
pure fn neg() -> Vec4<T> {