diff --git a/src/color/color.rs b/src/color/color.rs index 56306f6..45687ef 100644 --- a/src/color/color.rs +++ b/src/color/color.rs @@ -30,6 +30,10 @@ pub mod ycbcr; pub trait Color { pub fn clamp(&self, lo: T, hi: T) -> Self; pub fn inverse(&self) -> Self; + // pub fn mix(&self, other: &Self, value: T) -> Self; + // pub fn saturation(&self, value: T) -> Self; + // pub fn exposure(&self, value: T) -> Self; + // pub fn brightness(&self, value: T) -> Self; } pub trait FloatColor: Color { diff --git a/src/color/hsv.rs b/src/color/hsv.rs index c5cd5d0..9ada9e4 100644 --- a/src/color/hsv.rs +++ b/src/color/hsv.rs @@ -20,12 +20,11 @@ use color::{Color, FloatColor}; use color::{Channel, FloatChannel}; use color::{RGB, ToRGB, RGBA, ToRGBA}; -#[path = "../num_macros.rs"] -mod num_macros; - #[deriving(Clone, Eq)] pub struct HSV { h: T, s: T, v: T } +impl_approx!(HSV { h, s, v }) + impl HSV { pub fn new(h: T, s: T, v: T) -> HSV { HSV { h: h, s: s, v: v } @@ -123,6 +122,8 @@ impl ToRGB for HSV { #[deriving(Clone, Eq)] pub struct HSVA { h: T, s: T, v: T, a: T } +impl_approx!(HSVA { h, s, v, a }) + impl HSVA { #[inline] pub fn new(h: T, s: T, v: T, a: T) -> HSVA { diff --git a/src/color/rgb.rs b/src/color/rgb.rs index f4e0639..2c28388 100644 --- a/src/color/rgb.rs +++ b/src/color/rgb.rs @@ -20,12 +20,11 @@ use color::{Color, FloatColor}; use color::{Channel, FloatChannel}; use color::{HSV, ToHSV, HSVA, ToHSVA}; -#[path = "../num_macros.rs"] -mod num_macros; - #[deriving(Clone, Eq)] pub struct RGB { r: T, g: T, b: T } +impl_approx!(RGB { r, g, b }) + impl RGB { #[inline] pub fn new(r: T, g: T, b: T) -> RGB { @@ -120,6 +119,8 @@ impl ToHSV for RGB { #[deriving(Clone, Eq)] pub struct RGBA { r: T, g: T, b: T, a: T } +impl_approx!(RGBA { r, g, b, a }) + impl RGBA { #[inline] pub fn new(r: T, g: T, b: T, a: T) -> RGBA { diff --git a/src/color/srgb.rs b/src/color/srgb.rs index 6702a6f..52f1176 100644 --- a/src/color/srgb.rs +++ b/src/color/srgb.rs @@ -23,9 +23,13 @@ impl SRGB { } } +impl_approx!(SRGB { r, g, b }) + #[deriving(Clone, Eq)] pub struct SRGBA { r: T, g: T, b: T, a: T } +impl_approx!(SRGBA { r, g, b, a }) + impl SRGBA { #[inline] pub fn new(r: T, g: T, b: T, a: T) -> SRGBA { diff --git a/src/color/ycbcr.rs b/src/color/ycbcr.rs index 2311760..a7280e4 100644 --- a/src/color/ycbcr.rs +++ b/src/color/ycbcr.rs @@ -18,6 +18,8 @@ #[deriving(Clone, Eq)] pub struct YCbCr { y: T, cb: T, cr: T } +impl_approx!(YCbCr { y, cb, cr }) + impl YCbCr { #[inline] pub fn new(y: T, cb: T, cr: T) -> YCbCr { diff --git a/src/core/mat.rs b/src/core/mat.rs index 1e6f1de..5fd3a9a 100644 --- a/src/core/mat.rs +++ b/src/core/mat.rs @@ -17,9 +17,6 @@ use core::{Dimensional, Swap}; use core::{Quat, ToQuat}; use core::{Vec2, Vec3, Vec4}; -#[path = "../num_macros.rs"] -mod num_macros; - macro_rules! impl_mat( ($Mat:ident, $Vec:ident) => ( impl $Mat { @@ -126,6 +123,7 @@ pub type Mat2f64 = Mat2; impl_mat!(Mat2, Vec2) impl_mat_swap!(Mat2, Vec2) +impl_approx!(Mat3 { x, y, z }) pub trait ToMat2 { pub fn to_mat2(&self) -> Mat2; @@ -330,24 +328,6 @@ impl> Mat2 { } } -impl> ApproxEq for Mat2 { - #[inline] - pub fn approx_epsilon() -> T { - ApproxEq::approx_epsilon::() - } - - #[inline] - pub fn approx_eq(&self, other: &Mat2) -> bool { - self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) - } - - #[inline] - pub fn approx_eq_eps(&self, other: &Mat2, epsilon: &T) -> bool { - self.col(0).approx_eq_eps(other.col(0), epsilon) && - self.col(1).approx_eq_eps(other.col(1), epsilon) - } -} - #[cfg(test)] mod mat2_tests{ use core::mat::*; @@ -554,6 +534,7 @@ pub type Mat3f64 = Mat3; impl_mat!(Mat3, Vec3) impl_mat_swap!(Mat3, Vec3) +impl_approx!(Mat2 { x, y }) pub trait ToMat3 { pub fn to_mat3(&self) -> Mat3; @@ -909,25 +890,6 @@ impl> Mat3 { } } -impl> ApproxEq for Mat3 { - #[inline] - pub fn approx_epsilon() -> T { - ApproxEq::approx_epsilon::() - } - - #[inline] - pub fn approx_eq(&self, other: &Mat3) -> bool { - self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) - } - - #[inline] - pub fn approx_eq_eps(&self, other: &Mat3, epsilon: &T) -> bool { - self.col(0).approx_eq_eps(other.col(0), epsilon) && - self.col(1).approx_eq_eps(other.col(1), epsilon) && - self.col(2).approx_eq_eps(other.col(2), epsilon) - } -} - #[cfg(test)] mod mat3_tests{ use core::mat::*; @@ -1159,6 +1121,7 @@ pub type Mat4f64 = Mat4; impl_mat!(Mat4, Vec4) impl_mat_swap!(Mat4, Vec4) +impl_approx!(Mat4 { x, y, z, w }) pub trait ToMat4 { pub fn to_mat4(&self) -> Mat4; @@ -1454,26 +1417,6 @@ impl> Mat4 { } } -impl> ApproxEq for Mat4 { - #[inline] - pub fn approx_epsilon() -> T { - ApproxEq::approx_epsilon::() - } - - #[inline] - pub fn approx_eq(&self, other: &Mat4) -> bool { - self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) - } - - #[inline] - pub fn approx_eq_eps(&self, other: &Mat4, epsilon: &T) -> bool { - self.col(0).approx_eq_eps(other.col(0), epsilon) && - self.col(1).approx_eq_eps(other.col(1), epsilon) && - self.col(2).approx_eq_eps(other.col(2), epsilon) && - self.col(3).approx_eq_eps(other.col(3), epsilon) - } -} - #[cfg(test)] mod mat4_tests { use core::mat::*; diff --git a/src/core/quat.rs b/src/core/quat.rs index 365e7a2..993db72 100644 --- a/src/core/quat.rs +++ b/src/core/quat.rs @@ -17,9 +17,6 @@ use core::Dimensional; use core::{Mat3, ToMat3}; use core::Vec3; -#[path = "../num_macros.rs"] -mod num_macros; - // GLSL-style type aliases pub type quat = Quat; diff --git a/src/core/vec.rs b/src/core/vec.rs index ff123c7..f064878 100644 --- a/src/core/vec.rs +++ b/src/core/vec.rs @@ -20,9 +20,6 @@ use core::Dimensional; #[cfg(geom)] use geom::{Point2, Point3}; -#[path = "../num_macros.rs"] -mod num_macros; - #[deriving(Clone, Eq)] pub struct Vec2 { x: T, y: T } @@ -49,6 +46,8 @@ pub type Vec2u32 = Vec2; pub type Vec2u64 = Vec2; pub type Vec2b = Vec2; +impl_approx!(Vec2 { x, y }) + impl Vec2 { #[inline] pub fn new(x: T, y: T) -> Vec2 { @@ -586,6 +585,8 @@ pub type Vec3u32 = Vec3; pub type Vec3u64 = Vec3; pub type Vec3b = Vec3; +impl_approx!(Vec3 { x, y, z }) + impl Vec3 { #[inline] pub fn new(x: T, y: T, z: T) -> Vec3 { @@ -1188,6 +1189,8 @@ pub type Vec4u32 = Vec4; pub type Vec4u64 = Vec4; pub type Vec4b = Vec4; +impl_approx!(Vec4 { x, y, z, w }) + impl Vec4 { #[inline] pub fn new(x: T, y: T, z: T, w: T) -> Vec4 { diff --git a/src/geom/aabb.rs b/src/geom/aabb.rs index df8fbf5..a02a8fc 100644 --- a/src/geom/aabb.rs +++ b/src/geom/aabb.rs @@ -18,14 +18,13 @@ use core::{Vec2, Vec3}; use geom::{Point2, Point3}; -#[path = "../num_macros.rs"] -mod num_macros; - pub struct AABB2 { center: Point2, size: Vec2, } +impl_approx!(AABB2 { center, size }) + impl AABB2 { #[inline] pub fn new(center: Point2, size: Vec2) -> AABB2 { @@ -50,6 +49,8 @@ pub struct AABB3 { size: Vec3, } +impl_approx!(AABB3 { center, size }) + impl AABB3 { #[inline] pub fn new(center: Point3, size: Vec3) -> AABB3 { diff --git a/src/geom/frustum.rs b/src/geom/frustum.rs index d316bef..572ec6b 100644 --- a/src/geom/frustum.rs +++ b/src/geom/frustum.rs @@ -16,9 +16,6 @@ use core::Mat4; use geom::{Plane3, Point3}; -#[path = "../num_macros.rs"] -mod num_macros; - #[deriving(Clone, Eq)] pub struct Frustum { left: Plane3, @@ -29,6 +26,12 @@ pub struct Frustum { far: Plane3, } +impl_approx!(Frustum { + left, right, + top, bottom, + near, far +}) + #[deriving(Clone, Eq)] pub struct FrustumPoints { near_top_left: Point3, @@ -41,6 +44,17 @@ pub struct FrustumPoints { far_bottom_right: Point3, } +impl_approx!(FrustumPoints { + near_top_left, + near_top_right, + near_bottom_left, + near_bottom_right, + far_top_left, + far_top_right, + far_bottom_left, + far_bottom_right +}) + impl Frustum { /// Constructs a frustum pub fn from_planes(left: Plane3, right: Plane3, @@ -96,25 +110,3 @@ impl Frustum { } } } - -impl> ApproxEq for Frustum { - #[inline] - pub fn approx_epsilon() -> T { - ApproxEq::approx_epsilon::() - } - - #[inline] - pub fn approx_eq(&self, other: &Frustum) -> bool { - self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) - } - - #[inline] - pub fn approx_eq_eps(&self, other: &Frustum, epsilon: &T) -> bool { - self.left.approx_eq_eps(&other.left, epsilon) && - self.right.approx_eq_eps(&other.right, epsilon) && - self.bottom.approx_eq_eps(&other.bottom, epsilon) && - self.top.approx_eq_eps(&other.top, epsilon) && - self.near.approx_eq_eps(&other.near, epsilon) && - self.far.approx_eq_eps(&other.far, epsilon) - } -} diff --git a/src/geom/plane.rs b/src/geom/plane.rs index b8ee7d3..3849710 100644 --- a/src/geom/plane.rs +++ b/src/geom/plane.rs @@ -16,9 +16,6 @@ use core::{Vec3, Vec4, Mat3}; use geom::{Point, Point3, Ray3}; -#[path = "../num_macros.rs"] -mod num_macros; - /// A plane formed from the equation: `Ax + Bx + Cx + D = 0` /// /// # Fields @@ -34,6 +31,8 @@ pub struct Plane3 { distance: T, } +impl_approx!(Plane3 { normal, distance }) + impl Plane3 { /// # Arguments /// @@ -143,24 +142,6 @@ impl Plane3 { } } -impl> ApproxEq for Plane3 { - #[inline] - pub fn approx_epsilon() -> T { - ApproxEq::approx_epsilon::() - } - - #[inline] - pub fn approx_eq(&self, other: &Plane3) -> bool { - self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) - } - - #[inline] - pub fn approx_eq_eps(&self, other: &Plane3, epsilon: &T) -> bool { - self.normal.approx_eq_eps(&other.normal, epsilon) && - self.distance.approx_eq_eps(&other.distance, epsilon) - } -} - impl ToStr for Plane3 { pub fn to_str(&self) -> ~str { fmt!("%?x + %?y + %?z + %? = 0", diff --git a/src/geom/point.rs b/src/geom/point.rs index 8d0b6ca..1c84d07 100644 --- a/src/geom/point.rs +++ b/src/geom/point.rs @@ -24,9 +24,6 @@ use std::cast; use core::{Mat2, Mat3, Quat, Vec2, Vec3, Vec4}; -#[path = "../num_macros.rs"] -mod num_macros; - /// A geometric point pub trait Point: Eq + Add @@ -48,6 +45,8 @@ pub trait Point: Eq #[deriving(Clone, Eq)] pub struct Point2 { x: T, y: T } +impl_approx!(Point2 { x, y }) + impl Point2 { #[inline] pub fn new(x: T, y: T) -> Point2 { @@ -149,24 +148,6 @@ impl Mul, Point2> for Point2 { } } -impl> ApproxEq for Point2 { - #[inline] - pub fn approx_epsilon() -> T { - ApproxEq::approx_epsilon::() - } - - #[inline] - pub fn approx_eq(&self, other: &Point2) -> bool { - self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) - } - - #[inline] - pub fn approx_eq_eps(&self, other: &Point2, epsilon: &T) -> bool { - self.x.approx_eq_eps(&other.x, epsilon) && - self.y.approx_eq_eps(&other.y, epsilon) - } -} - impl ToStr for Point2 { pub fn to_str(&self) -> ~str { fmt!("[%?, %?]", self.x, self.y) @@ -187,6 +168,8 @@ mod test_point2 { #[deriving(Clone, Eq)] pub struct Point3 { x: T, y: T, z: T } +impl_approx!(Point3 { x, y, z }) + impl Point3 { #[inline] pub fn new(x: T, y: T, z: T) -> Point3 { @@ -291,25 +274,6 @@ impl Mul, Point3> for Point3 { } } -impl> ApproxEq for Point3 { - #[inline] - pub fn approx_epsilon() -> T { - ApproxEq::approx_epsilon::() - } - - #[inline] - pub fn approx_eq(&self, other: &Point3) -> bool { - self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) - } - - #[inline] - pub fn approx_eq_eps(&self, other: &Point3, epsilon: &T) -> bool { - self.x.approx_eq_eps(&other.x, epsilon) && - self.y.approx_eq_eps(&other.y, epsilon) && - self.z.approx_eq_eps(&other.z, epsilon) - } -} - impl ToStr for Point3 { pub fn to_str(&self) -> ~str { fmt!("[%?, %?, %?]", self.x, self.y, self.z) diff --git a/src/geom/ray.rs b/src/geom/ray.rs index 643ae1a..128f98c 100644 --- a/src/geom/ray.rs +++ b/src/geom/ray.rs @@ -22,27 +22,11 @@ pub struct Ray3 { direction: Vec3, } +impl_approx!(Ray3 { origin, direction }) + impl Ray3 { #[inline] pub fn new(origin: Point3, direction: Vec3) -> Ray3 { Ray3 { origin: origin, direction: direction } } } - -impl> ApproxEq for Ray3 { - #[inline] - pub fn approx_epsilon() -> T { - ApproxEq::approx_epsilon::() - } - - #[inline] - pub fn approx_eq(&self, other: &Ray3) -> bool { - self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) - } - - #[inline] - pub fn approx_eq_eps(&self, other: &Ray3, epsilon: &T) -> bool { - self.origin.approx_eq_eps(&other.origin, epsilon) && - self.direction.approx_eq_eps(&other.direction, epsilon) - } -} diff --git a/src/geom/sphere.rs b/src/geom/sphere.rs index 862e1ca..1faea1b 100644 --- a/src/geom/sphere.rs +++ b/src/geom/sphere.rs @@ -22,6 +22,8 @@ pub struct Sphere { radius: T, } +impl_approx!(Sphere { center, radius }) + impl Sphere { #[inline] pub fn new(center: Point3, radius: T) -> Sphere { diff --git a/src/lmath.rs b/src/lmath.rs index a01ad87..e97c4fa 100644 --- a/src/lmath.rs +++ b/src/lmath.rs @@ -23,6 +23,8 @@ #[license = "ASL2"]; #[crate_type = "lib"]; +mod macros; + #[path = "core/core.rs"] pub mod core; diff --git a/src/num_macros.rs b/src/macros.rs similarity index 60% rename from src/num_macros.rs rename to src/macros.rs index 86dd893..d81afa0 100644 --- a/src/num_macros.rs +++ b/src/macros.rs @@ -32,3 +32,24 @@ macro_rules! one( macro_rules! two( ($T:ty) => (one!(T) + one!(T)); ) + +macro_rules! impl_approx( + ($T:ident { $($field:ident),+ }) => ( + impl> ApproxEq for $T { + #[inline] + pub fn approx_epsilon() -> T { + ApproxEq::approx_epsilon::() + } + + #[inline] + pub fn approx_eq(&self, other: &$T) -> bool { + self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) + } + + #[inline] + pub fn approx_eq_eps(&self, other: &$T, epsilon: &T) -> bool { + $( self.$field.approx_eq_eps(&other.$field, epsilon) )&&+ + } + } + ) +) diff --git a/src/transform/projection.rs b/src/transform/projection.rs index fb5b619..176668c 100644 --- a/src/transform/projection.rs +++ b/src/transform/projection.rs @@ -16,9 +16,6 @@ use core::Mat4; use geom::{Plane3, Frustum}; -#[path = "../num_macros.rs"] -mod num_macros; - /// /// Create a perspective projection matrix ///