From e1ed642f76d2119ec00402dc268ccffaf27e53c3 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Mon, 3 Dec 2012 11:24:24 +1000 Subject: [PATCH] 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. --- src/funs/relational.rs | 218 +++++++++++++++++++++++++++++++ src/funs/test/test_relational.rs | 72 ++++++++++ src/gltypes.rs | 31 +++++ src/test/test_gltypes.rs | 7 + 4 files changed, 328 insertions(+) create mode 100644 src/funs/relational.rs create mode 100644 src/funs/test/test_relational.rs diff --git a/src/funs/relational.rs b/src/funs/relational.rs new file mode 100644 index 0000000..64616bc --- /dev/null +++ b/src/funs/relational.rs @@ -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 { + 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 , BV>(x: &T, y: &T) -> BV { x.less_than(y) } +#[inline(always)] pub pure fn less_than_equal , BV>(x: &T, y: &T) -> BV { x.less_than_equal(y) } +#[inline(always)] pub pure fn greater_than , BV>(x: &T, y: &T) -> BV { x.greater_than(y) } +#[inline(always)] pub pure fn greater_than_equal, BV>(x: &T, y: &T) -> BV { x.greater_than_equal(y) } +#[inline(always)] pub pure fn equal , BV>(x: &T, y: &T) -> BV { x.equal(y) } +#[inline(always)] pub pure fn not_equal , BV>(x: &T, y: &T) -> BV { x.not_equal(y) } + +pub impl Vec2: RelVector> { + #[inline(always)] + pure fn less_than(&self, other: &Vec2) -> Vec2 { + Vec2::new(self[0] < other[0], + self[1] < other[1]) + } + + #[inline(always)] + pure fn less_than_equal(&self, other: &Vec2) -> Vec2 { + Vec2::new(self[0] <= other[0], + self[1] <= other[1]) + } + + #[inline(always)] + pure fn greater_than(&self, other: &Vec2) -> Vec2 { + Vec2::new(self[0] > other[0], + self[1] > other[1]) + } + + #[inline(always)] + pure fn greater_than_equal(&self, other: &Vec2) -> Vec2 { + Vec2::new(self[0] >= other[0], + self[1] >= other[1]) + } + + #[inline(always)] + pure fn equal(&self, other: &Vec2) -> Vec2 { + Vec2::new(self[0] == other[0], + self[1] == other[1]) + } + + #[inline(always)] + pure fn not_equal(&self, other: &Vec2) -> Vec2 { + Vec2::new(self[0] != other[0], + self[1] != other[1]) + } +} + +pub impl Vec3: RelVector> { + #[inline(always)] + pure fn less_than(&self, other: &Vec3) -> Vec3 { + Vec3::new(self[0] < other[0], + self[1] < other[1], + self[2] < other[2]) + } + + #[inline(always)] + pure fn less_than_equal(&self, other: &Vec3) -> Vec3 { + Vec3::new(self[0] <= other[0], + self[1] <= other[1], + self[2] <= other[2]) + } + + #[inline(always)] + pure fn greater_than(&self, other: &Vec3) -> Vec3 { + Vec3::new(self[0] > other[0], + self[1] > other[1], + self[2] > other[2]) + } + + #[inline(always)] + pure fn greater_than_equal(&self, other: &Vec3) -> Vec3 { + Vec3::new(self[0] >= other[0], + self[1] >= other[1], + self[2] >= other[2]) + } + + #[inline(always)] + pure fn equal(&self, other: &Vec3) -> Vec3 { + Vec3::new(self[0] == other[0], + self[1] == other[1], + self[2] == other[2]) + } + + #[inline(always)] + pure fn not_equal(&self, other: &Vec3) -> Vec3 { + Vec3::new(self[0] != other[0], + self[1] != other[1], + self[2] != other[2]) + } +} + +pub impl Vec4: RelVector> { + #[inline(always)] + pure fn less_than(&self, other: &Vec4) -> Vec4 { + 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) -> Vec4 { + 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) -> Vec4 { + 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) -> Vec4 { + 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) -> Vec4 { + 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) -> Vec4 { + Vec4::new(self[0] != other[0], + self[1] != other[1], + self[2] != other[2], + self[3] != other[3]) + } +} + +pub trait BooleanVector: Vector { + pure fn any(&self) -> bool; + pure fn all(&self) -> bool; + pure fn not(&self) -> self; +} + +#[inline(always)] pub pure fn any(x: &T) -> bool { x.any() } +#[inline(always)] pub pure fn all(x: &T) -> bool { x.all() } +#[inline(always)] pub pure fn not(x: &T) -> T { x.not() } + +pub impl Vec2: 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 { + Vec2::new(!self[0], !self[1]) + } +} + +pub impl Vec3: 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 { + Vec3::new(!self[0], !self[1], !self[2]) + } +} + +pub impl Vec4: 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 { + Vec4::new(!self[0], !self[1], !self[2], !self[3]) + } +} \ No newline at end of file diff --git a/src/funs/test/test_relational.rs b/src/funs/test/test_relational.rs new file mode 100644 index 0000000..fa6d758 --- /dev/null +++ b/src/funs/test/test_relational.rs @@ -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); +} \ No newline at end of file diff --git a/src/gltypes.rs b/src/gltypes.rs index e1d310b..337bb7a 100644 --- a/src/gltypes.rs +++ b/src/gltypes.rs @@ -40,6 +40,10 @@ pub type dvec2 = Vec2; /// a two-component double-precision flo pub type dvec3 = Vec3; /// a three-component double-precision floating-point vector pub type dvec4 = Vec4; /// a four-component double-precision floating-point vector +pub type bvec2 = Vec2; /// a two-component Boolean vector +pub type bvec3 = Vec3; /// a three-component Boolean vector +pub type bvec4 = Vec4; /// a four-component Boolean vector + pub type ivec2 = Vec2; /// a two-component signed integer vector pub type ivec3 = Vec3; /// a three-component signed integer vector pub type ivec4 = Vec4; /// a four-component signed integer vector @@ -111,6 +115,33 @@ pub impl dvec4 { #[inline(always)] static pure fn dim() -> uint { 4 } #[inline(always)] static pure fn size_of() -> uint { size_of::() } } + + +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::() } +} + +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::() } +} + +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::() } +} pub impl ivec2 { diff --git a/src/test/test_gltypes.rs b/src/test/test_gltypes.rs index 4c40cff..b701ae4 100644 --- a/src/test/test_gltypes.rs +++ b/src/test/test_gltypes.rs @@ -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);