Restore boolean vectors in gltypes module and relational traits

I forgot that these would be useful for the AABB struct that will be implemented in the future.
This commit is contained in:
Brendan Zabarauskas 2012-12-03 11:24:24 +10:00
parent ecc91acbbe
commit e1ed642f76
4 changed files with 328 additions and 0 deletions

218
src/funs/relational.rs Normal file
View file

@ -0,0 +1,218 @@
/**
* Vector Relational Functions
*
* This module corresponds to Section 8.7 of the [GLSL 4.30.6 specification]
* (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
*/
use core::cmp::{Eq, Ord};
use vec::{Vector, Vec2, Vec3, Vec4};
pub trait RelVector<BVec> {
pure fn less_than(&self, other: &self) -> BVec;
pure fn less_than_equal(&self, other: &self) -> BVec;
pure fn greater_than(&self, other: &self) -> BVec;
pure fn greater_than_equal(&self, other: &self) -> BVec;
pure fn equal(&self, other: &self) -> BVec;
pure fn not_equal(&self, other: &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(&self, other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] < other[0],
self[1] < other[1])
}
#[inline(always)]
pure fn less_than_equal(&self, other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] <= other[0],
self[1] <= other[1])
}
#[inline(always)]
pure fn greater_than(&self, other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] > other[0],
self[1] > other[1])
}
#[inline(always)]
pure fn greater_than_equal(&self, other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] >= other[0],
self[1] >= other[1])
}
#[inline(always)]
pure fn equal(&self, other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] == other[0],
self[1] == other[1])
}
#[inline(always)]
pure fn not_equal(&self, other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] != other[0],
self[1] != other[1])
}
}
pub impl<T:Copy Ord Eq> Vec3<T>: RelVector<Vec3<bool>> {
#[inline(always)]
pure fn less_than(&self, 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(&self, 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(&self, 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(&self, other: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] >= other[0],
self[1] >= other[1],
self[2] >= other[2])
}
#[inline(always)]
pure fn equal(&self, 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(&self, other: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] != other[0],
self[1] != other[1],
self[2] != other[2])
}
}
pub impl<T:Copy Ord Eq> Vec4<T>: RelVector<Vec4<bool>> {
#[inline(always)]
pure fn less_than(&self, 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(&self, 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(&self, 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(&self, 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(&self, 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(&self, other: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] != other[0],
self[1] != other[1],
self[2] != other[2],
self[3] != other[3])
}
}
pub trait BooleanVector: Vector<bool> {
pure fn any(&self) -> bool;
pure fn all(&self) -> bool;
pure fn not(&self) -> self;
}
#[inline(always)] pub pure fn any<T:BooleanVector>(x: &T) -> bool { x.any() }
#[inline(always)] pub pure fn all<T:BooleanVector>(x: &T) -> bool { x.all() }
#[inline(always)] pub pure fn not<T:BooleanVector>(x: &T) -> T { x.not() }
pub impl Vec2<bool>: BooleanVector {
#[inline(always)]
pure fn any(&self) -> bool {
self[0] || self[1]
}
#[inline(always)]
pure fn all(&self) -> bool {
self[0] && self[1]
}
#[inline(always)]
pure fn not(&self) -> Vec2<bool> {
Vec2::new(!self[0], !self[1])
}
}
pub impl Vec3<bool>: BooleanVector {
#[inline(always)]
pure fn any(&self) -> bool {
self[0] || self[1] || self[2]
}
#[inline(always)]
pure fn all(&self) -> bool {
self[0] && self[1] && self[2]
}
#[inline(always)]
pure fn not(&self) -> Vec3<bool> {
Vec3::new(!self[0], !self[1], !self[2])
}
}
pub impl Vec4<bool>: BooleanVector {
#[inline(always)]
pure fn any(&self) -> bool {
self[0] || self[1] || self[2] || self[3]
}
#[inline(always)]
pure fn all(&self) -> bool {
self[0] && self[1] && self[2] && self[3]
}
#[inline(always)]
pure fn not(&self) -> Vec4<bool> {
Vec4::new(!self[0], !self[1], !self[2], !self[3])
}
}

View file

@ -0,0 +1,72 @@
use vec::*;
use relational::*;
#[test]
fn test_boolv2() {
let tf = Vec2::new(true, false);
let ff = Vec2::new(false, false);
let tt = Vec2::new(true, true);
assert tf.any() == true;
assert tf.all() == false;
assert tf.not() == Vec2::new(false, true);
assert ff.any() == false;
assert ff.all() == false;
assert ff.not() == Vec2::new(true, true);
assert tt.any() == true;
assert tt.all() == true;
assert tt.not() == Vec2::new(false, false);
}
#[test]
fn test_boolv3() {
let tft = Vec3::new(true, false, true);
let fff = Vec3::new(false, false, false);
let ttt = Vec3::new(true, true, true);
assert tft.any() == true;
assert tft.all() == false;
assert tft.not() == Vec3::new(false, true, false);
assert fff.any() == false;
assert fff.all() == false;
assert fff.not() == Vec3::new(true, true, true);
assert ttt.any() == true;
assert ttt.all() == true;
assert ttt.not() == Vec3::new(false, false, false);
}
#[test]
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);
assert tftf.any() == true;
assert tftf.all() == false;
assert tftf.not() == Vec4::new(false, true, false, true);
assert ffff.any() == false;
assert ffff.all() == false;
assert ffff.not() == Vec4::new(true, true, true, true);
assert tttt.any() == true;
assert tttt.all() == true;
assert tttt.not() == Vec4::new(false, false, false, false);
}
#[test]
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);
// FIXME: These tests won't compile! D:
// assert any(&tf) == true;
// assert all(&ftf) == false;
// assert not(&tftf) == Vec4::new(false, true, false, true);
}

View file

@ -40,6 +40,10 @@ pub type dvec2 = Vec2<f64>; /// a two-component double-precision flo
pub type dvec3 = Vec3<f64>; /// a three-component double-precision floating-point vector
pub type dvec4 = Vec4<f64>; /// a four-component double-precision floating-point vector
pub type bvec2 = Vec2<bool>; /// a two-component Boolean vector
pub type bvec3 = Vec3<bool>; /// a three-component Boolean vector
pub type bvec4 = Vec4<bool>; /// a four-component Boolean vector
pub type ivec2 = Vec2<i32>; /// a two-component signed integer vector
pub type ivec3 = Vec3<i32>; /// a three-component signed integer vector
pub type ivec4 = Vec4<i32>; /// a four-component signed integer vector
@ -113,6 +117,33 @@ pub impl dvec4 {
}
pub impl bvec2 {
#[inline(always)] static pure fn new(x: bool, y: bool) -> bvec2 { Vec2::new(x, y) }
#[inline(always)] static pure fn from_value(v: bool) -> bvec2 { Vector::from_value(v) }
#[inline(always)] static pure fn dim() -> uint { 2 }
#[inline(always)] static pure fn size_of() -> uint { size_of::<bvec2>() }
}
pub impl bvec3 {
#[inline(always)] static pure fn new(x: bool, y: bool, z: bool) -> bvec3 { Vec3::new(x, y, z) }
#[inline(always)] static pure fn from_value(v: bool) -> bvec3 { Vector::from_value(v) }
#[inline(always)] static pure fn dim() -> uint { 3 }
#[inline(always)] static pure fn size_of() -> uint { size_of::<bvec3>() }
}
pub impl bvec4 {
#[inline(always)] static pure fn new(x: bool, y: bool, z: bool, w: bool) -> bvec4 { Vec4::new(x, y, z, w) }
#[inline(always)] static pure fn from_value(v: bool) -> bvec4 { Vector::from_value(v) }
// #[inline(always)] static pure fn identity() -> bvec4 { NumericVector::identity() }
// #[inline(always)] static pure fn zero() -> bvec4 { NumericVector::zero() }
#[inline(always)] static pure fn dim() -> uint { 4 }
#[inline(always)] static pure fn size_of() -> uint { size_of::<bvec4>() }
}
pub impl ivec2 {
#[inline(always)] static pure fn new(x: i32, y: i32) -> ivec2 { Vec2::new(x, y) }
#[inline(always)] static pure fn from_value(v: i32) -> ivec2 { Vector::from_value(v) }

View file

@ -34,6 +34,13 @@ fn test_vec() {
assert dvec3::size_of() == dvec3::dim() * 8;
assert dvec4::size_of() == dvec4::dim() * 8;
assert bvec2::dim() == 2;
assert bvec3::dim() == 3;
assert bvec4::dim() == 4;
assert bvec2::size_of() == bvec2::dim() * 1;
assert bvec3::size_of() == bvec3::dim() * 1;
assert bvec4::size_of() == bvec4::dim() * 1;
assert ivec2::identity() == ivec2::from_value(1i32);
assert ivec3::identity() == ivec3::from_value(1i32);
assert ivec4::identity() == ivec4::from_value(1i32);