Add impl_to_vec! and impl_as_vec! macros and use for points and colors

This commit is contained in:
Brendan Zabarauskas 2013-07-12 19:10:39 +10:00
parent ad59c9b16f
commit 8973179b0d
7 changed files with 66 additions and 41 deletions

View file

@ -17,6 +17,8 @@ use std::num;
use std::cast;
use core::{Dimensional, Swap};
use core::{Vec3, ToVec3, AsVec3};
use core::{Vec4, ToVec4, AsVec4};
use color::{Color, FloatColor};
use color::{Channel, FloatChannel};
use color::{RGB, ToRGB, RGBA, ToRGBA};
@ -25,6 +27,8 @@ use color::{RGB, ToRGB, RGBA, ToRGBA};
pub struct HSV<T> { h: T, s: T, v: T }
impl_dimensional!(HSV, T, 3)
impl_to_vec!(HSV, 3)
impl_as_vec!(HSV, 3)
impl_swap!(HSV)
impl_approx!(HSV { h, s, v })
@ -126,6 +130,8 @@ impl<T:Clone + FloatChannel> ToRGB for HSV<T> {
pub struct HSVA<T> { h: T, s: T, v: T, a: T }
impl_dimensional!(HSVA, T, 4)
impl_to_vec!(HSVA, 4)
impl_as_vec!(HSVA, 4)
impl_swap!(HSVA)
impl_approx!(HSVA { h, s, v, a })

View file

@ -17,6 +17,8 @@ use std::num;
use std::cast;
use core::{Dimensional, Swap};
use core::{Vec3, ToVec3, AsVec3};
use core::{Vec4, ToVec4, AsVec4};
use color::{Color, FloatColor};
use color::{Channel, FloatChannel};
use color::{HSV, ToHSV, HSVA, ToHSVA};
@ -25,6 +27,8 @@ use color::{HSV, ToHSV, HSVA, ToHSVA};
pub struct RGB<T> { r: T, g: T, b: T }
impl_dimensional!(RGB, T, 3)
impl_to_vec!(RGB, 3)
impl_as_vec!(RGB, 3)
impl_swap!(RGB)
impl_approx!(RGB { r, g, b })
@ -123,6 +127,8 @@ impl<T:Clone + Channel> ToHSV for RGB<T> {
pub struct RGBA<T> { r: T, g: T, b: T, a: T }
impl_dimensional!(RGBA, T, 4)
impl_to_vec!(RGBA, 4)
impl_as_vec!(RGBA, 4)
impl_swap!(RGBA)
impl_approx!(RGBA { r, g, b, a })

View file

@ -14,6 +14,8 @@
// limitations under the License.
use core::{Dimensional, Swap};
use core::{Vec3, ToVec3, AsVec3};
use core::{Vec4, ToVec4, AsVec4};
#[deriving(Clone, Eq)]
pub struct SRGB<T> { r: T, g: T, b: T }
@ -26,6 +28,8 @@ impl<T> SRGB<T> {
}
impl_dimensional!(SRGB, T, 3)
impl_to_vec!(SRGB, 3)
impl_as_vec!(SRGB, 3)
impl_swap!(SRGB)
impl_approx!(SRGB { r, g, b })
@ -33,6 +37,8 @@ impl_approx!(SRGB { r, g, b })
pub struct SRGBA<T> { r: T, g: T, b: T, a: T }
impl_dimensional!(SRGBA, T, 4)
impl_to_vec!(SRGBA, 4)
impl_as_vec!(SRGBA, 4)
impl_swap!(SRGBA)
impl_approx!(SRGBA { r, g, b, a })

View file

@ -16,11 +16,14 @@
// http://en.wikipedia.org/wiki/YCbCr
use core::{Dimensional, Swap};
use core::{Vec3, ToVec3, AsVec3};
#[deriving(Clone, Eq)]
pub struct YCbCr<T> { y: T, cb: T, cr: T }
impl_dimensional!(YCbCr, T, 3)
impl_to_vec!(YCbCr, 3)
impl_as_vec!(YCbCr, 3)
impl_swap!(YCbCr)
impl_approx!(YCbCr { y, cb, cr })

View file

@ -43,6 +43,47 @@ macro_rules! impl_dimensional(
)
)
macro_rules! impl_to_vec(
($Self:ident, 2) => (impl_to_vec_helper!(ToVec2, $Self, Vec2, to_vec2, as_vec2));
($Self:ident, 3) => (impl_to_vec_helper!(ToVec3, $Self, Vec3, to_vec3, as_vec3));
($Self:ident, 4) => (impl_to_vec_helper!(ToVec4, $Self, Vec4, to_vec4, as_vec4));
)
macro_rules! impl_to_vec_helper(
($ToVec:ident, $Self:ident, $Vec:ident, $to_vec:ident, $as_vec:ident) => (
impl<T:Clone> $ToVec<T> for $Self<T> {
#[inline]
pub fn $to_vec(&self) -> $Vec<T> {
self.$as_vec().clone()
}
}
)
)
macro_rules! impl_as_vec(
($Self:ident, 2) => (impl_as_vec_helper!(AsVec2, $Self, Vec2, as_vec2, as_mut_vec2));
($Self:ident, 3) => (impl_as_vec_helper!(AsVec3, $Self, Vec3, as_vec3, as_mut_vec3));
($Self:ident, 4) => (impl_as_vec_helper!(AsVec4, $Self, Vec4, as_vec4, as_mut_vec4));
)
macro_rules! impl_as_vec_helper(
($AsVec:ident, $Self:ident, $Vec:ident, $as_vec:ident, $as_mut_vec:ident) => (
impl<T> $AsVec<T> for $Self<T> {
#[inline]
pub fn $as_vec<'a>(&'a self) -> &'a $Vec<T> {
use std::cast::transmute;
unsafe { transmute(self) }
}
#[inline]
pub fn $as_mut_vec<'a>(&'a mut self) -> &'a mut $Vec<T> {
use std::cast::transmute;
unsafe { transmute(self) }
}
}
)
)
macro_rules! impl_swap(
($Self:ident) => (
impl<T:Clone> Swap for $Self<T> {

View file

@ -49,6 +49,8 @@ pub trait Point<T, Vec, Ray>: Eq
pub struct Point2<T> { x: T, y: T }
impl_dimensional!(Point2, T, 2)
impl_to_vec!(Point2, 2)
impl_as_vec!(Point2, 2)
impl_swap!(Point2)
impl_approx!(Point2 { x, y })
@ -86,25 +88,6 @@ impl<T:Num> Point2<T> {
}
}
impl<T:Clone + Num> ToVec2<T> for Point2<T> {
#[inline]
pub fn to_vec2(&self) -> Vec2<T> {
self.as_vec2().clone()
}
}
impl<T:Num> AsVec2<T> for Point2<T> {
#[inline]
pub fn as_vec2<'a>(&'a self) -> &'a Vec2<T> {
unsafe { cast::transmute(self) }
}
#[inline]
pub fn as_mut_vec2<'a>(&'a mut self) -> &'a mut Vec2<T> {
unsafe { cast::transmute(self) }
}
}
impl<T:Clone + Num> ToVec3<T> for Point2<T> {
/// Converts the point to a three-dimensional homogeneous vector:
/// `[x, y] -> [x, y, 1]`
@ -206,6 +189,8 @@ mod test_point2 {
pub struct Point3<T> { x: T, y: T, z: T }
impl_dimensional!(Point3, T, 3)
impl_to_vec!(Point3, 3)
impl_as_vec!(Point3, 3)
impl_swap!(Point3)
impl_approx!(Point3 { x, y, z })
@ -243,27 +228,6 @@ impl<T:Num> Point3<T> {
}
}
impl<T:Clone + Num> ToVec3<T> for Point3<T> {
/// Converts the point to a three-dimensional homogeneous vector:
/// `[x, y] -> [x, y, 1]`
#[inline]
pub fn to_vec3(&self) -> Vec3<T> {
self.as_vec3().clone()
}
}
impl<T:Num> AsVec3<T> for Point3<T> {
#[inline]
pub fn as_vec3<'a>(&'a self) -> &'a Vec3<T> {
unsafe { cast::transmute(self) }
}
#[inline]
pub fn as_mut_vec3<'a>(&'a mut self) -> &'a mut Vec3<T> {
unsafe { cast::transmute(self) }
}
}
impl<T:Clone + Num> ToVec4<T> for Point3<T> {
/// Converts the point to a four-dimensional homogeneous vector:
/// `[x, y, z] -> [x, y, z, 1]`

View file

@ -26,7 +26,6 @@
// Macros
mod macros;
#[path = "core/macros.rs"]
mod core_macros;