Add vector conversion traits

This commit is contained in:
Brendan Zabarauskas 2013-07-12 13:41:03 +10:00
parent 4159a214da
commit eb75d34636
5 changed files with 108 additions and 42 deletions

View file

@ -20,7 +20,9 @@ pub use self::swap::Swap;
pub use self::mat::{Mat2, ToMat2, Mat3, ToMat3, Mat4, ToMat4}; pub use self::mat::{Mat2, ToMat2, Mat3, ToMat3, Mat4, ToMat4};
pub use self::quat::{Quat, ToQuat}; pub use self::quat::{Quat, ToQuat};
pub use self::vec::{Vec2, Vec3, Vec4}; pub use self::vec::{Vec2, ToVec2, AsVec2};
pub use self::vec::{Vec3, ToVec3, AsVec3};
pub use self::vec::{Vec4, ToVec4, AsVec4};
pub mod dim; pub mod dim;
pub mod swap; pub mod swap;

View file

@ -46,6 +46,15 @@ pub type Vec2u32 = Vec2<u32>;
pub type Vec2u64 = Vec2<u64>; pub type Vec2u64 = Vec2<u64>;
pub type Vec2b = Vec2<bool>; pub type Vec2b = Vec2<bool>;
pub trait ToVec2<T> {
pub fn to_vec2(&self) -> Vec2<T>;
}
pub trait AsVec2<T> {
pub fn as_vec2<'a>(&'a self) -> &'a Vec2<T>;
pub fn as_mut_vec2<'a>(&'a mut self) -> &'a mut Vec2<T>;
}
impl_approx!(Vec2 { x, y }) impl_approx!(Vec2 { x, y })
impl<T> Vec2<T> { impl<T> Vec2<T> {
@ -81,6 +90,16 @@ impl<T:Clone> Vec2<T> {
} }
} }
impl<T:Clone + Num> ToVec3<T> for Vec2<T> {
/// Converts the vector to a three-dimensional homogeneous vector:
/// `[x, y] -> [x, y, 0]`
pub fn to_vec3(&self) -> Vec3<T> {
Vec3::new((*self).index(0).clone(),
(*self).index(1).clone(),
zero!(T))
}
}
impl<T:Num> Vec2<T> { impl<T:Num> Vec2<T> {
#[inline] #[inline]
pub fn identity() -> Vec2<T> { pub fn identity() -> Vec2<T> {
@ -567,6 +586,15 @@ pub type Vec3u32 = Vec3<u32>;
pub type Vec3u64 = Vec3<u64>; pub type Vec3u64 = Vec3<u64>;
pub type Vec3b = Vec3<bool>; pub type Vec3b = Vec3<bool>;
pub trait ToVec3<T> {
pub fn to_vec3(&self) -> Vec3<T>;
}
pub trait AsVec3<T> {
pub fn as_vec3<'a>(&'a self) -> &'a Vec3<T>;
pub fn as_mut_vec3<'a>(&'a mut self) -> &'a mut Vec3<T>;
}
impl_approx!(Vec3 { x, y, z }) impl_approx!(Vec3 { x, y, z })
impl<T> Vec3<T> { impl<T> Vec3<T> {
@ -603,6 +631,17 @@ impl<T:Clone> Vec3<T> {
} }
} }
impl<T:Clone + Num> ToVec4<T> for Vec3<T> {
/// Converts the vector to a four-dimensional homogeneous vector:
/// `[x, y, z] -> [x, y, z, 0]`
pub fn to_vec4(&self) -> Vec4<T> {
Vec4::new((*self).index(0).clone(),
(*self).index(1).clone(),
(*self).index(2).clone(),
zero!(T))
}
}
impl<T:Num> Vec3<T> { impl<T:Num> Vec3<T> {
#[inline] #[inline]
pub fn identity() -> Vec3<T> { pub fn identity() -> Vec3<T> {
@ -1152,6 +1191,15 @@ pub type Vec4u32 = Vec4<u32>;
pub type Vec4u64 = Vec4<u64>; pub type Vec4u64 = Vec4<u64>;
pub type Vec4b = Vec4<bool>; pub type Vec4b = Vec4<bool>;
pub trait ToVec4<T> {
pub fn to_vec4(&self) -> Vec4<T>;
}
pub trait AsVec4<T> {
pub fn as_vec4<'a>(&'a self) -> &'a Vec4<T>;
pub fn as_mut_vec4<'a>(&'a mut self) -> &'a mut Vec4<T>;
}
impl_approx!(Vec4 { x, y, z, w }) impl_approx!(Vec4 { x, y, z, w })
impl<T> Vec4<T> { impl<T> Vec4<T> {

View file

@ -15,7 +15,7 @@
//! Axis-aligned bounding boxes //! Axis-aligned bounding boxes
use core::{Vec2, Vec3}; use core::{Vec2, AsVec2, Vec3, AsVec3};
use geom::{Point2, Point3}; use geom::{Point2, Point3};
pub struct AABB2<T> { pub struct AABB2<T> {
@ -36,9 +36,7 @@ impl<T:Clone + Float> AABB2<T> {
#[inline] #[inline]
pub fn from_bounds(mn: Point2<T>, mx: Point2<T>) -> AABB2<T> { pub fn from_bounds(mn: Point2<T>, mx: Point2<T>) -> AABB2<T> {
AABB2 { AABB2 {
center: Point2::from_vec(mn.as_vec() center: Point2::from_vec2(mn.as_vec2().add_v(mx.as_vec2()).div_t(two!(T))),
.add_v(mx.as_vec())
.div_t(two!(T))),
size: mx - mn, size: mx - mn,
} }
} }
@ -62,9 +60,7 @@ impl<T:Clone + Float> AABB3<T> {
#[inline] #[inline]
pub fn from_bounds(mn: Point3<T>, mx: Point3<T>) -> AABB3<T> { pub fn from_bounds(mn: Point3<T>, mx: Point3<T>) -> AABB3<T> {
AABB3 { AABB3 {
center: Point3::from_vec(mn.as_vec() center: Point3::from_vec3(mn.as_vec3().add_v(mx.as_vec3()).div_t(two!(T))),
.add_v(mx.as_vec())
.div_t(two!(T))),
size: mx - mn, size: mx - mn,
} }
} }

View file

@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use core::{Vec3, Vec4, Mat3}; use core::{Vec3, AsVec3, Vec4, Mat3};
use geom::{Point, Point3, Ray3}; use geom::{Point, Point3, Ray3};
/// A plane formed from the equation: `Ax + Bx + Cx + D = 0` /// A plane formed from the equation: `Ax + Bx + Cx + D = 0`
@ -59,7 +59,7 @@ impl<T:Clone + Float> Plane3<T> {
/// Compute the distance from the plane to the point /// Compute the distance from the plane to the point
pub fn distance(&self, pos: &Point3<T>) -> T { pub fn distance(&self, pos: &Point3<T>) -> T {
self.normal.dot(pos.as_vec()) + self.distance self.normal.dot(pos.as_vec3()) + self.distance
} }
/// Computes the point at which `ray` intersects the plane /// Computes the point at which `ray` intersects the plane
@ -94,7 +94,7 @@ impl<T:Clone + Float> Plane3<T> {
} else { } else {
// compute the normal and the distance to the plane // compute the normal and the distance to the plane
normal.normalize_self(); normal.normalize_self();
let distance = -a.as_vec().dot(&normal); let distance = -a.as_vec3().dot(&normal);
Some(Plane3::from_nd(normal, distance)) Some(Plane3::from_nd(normal, distance))
} }

View file

@ -22,7 +22,10 @@
use std::cast; use std::cast;
use core::{Mat2, Mat3, Quat, Vec2, Vec3, Vec4}; use core::{Mat2, Mat3, Quat};
use core::{Vec2, ToVec2, AsVec2};
use core::{Vec3, ToVec3, AsVec3};
use core::{Vec4, ToVec4};
/// A geometric point /// A geometric point
pub trait Point<T, Vec>: Eq pub trait Point<T, Vec>: Eq
@ -31,9 +34,6 @@ pub trait Point<T, Vec>: Eq
+ Mul<Vec, Self> + Mul<Vec, Self>
+ ApproxEq<T> + ApproxEq<T>
+ ToStr { + ToStr {
pub fn as_vec<'a>(&'a self) -> &'a Vec;
pub fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec;
pub fn translate(&self, offset: &Vec) -> Self; pub fn translate(&self, offset: &Vec) -> Self;
pub fn scale(&self, factor: &Vec) -> Self; pub fn scale(&self, factor: &Vec) -> Self;
pub fn distance2(&self, other: &Self) -> T; pub fn distance2(&self, other: &Self) -> T;
@ -54,7 +54,7 @@ impl<T:Num> Point2<T> {
} }
#[inline] #[inline]
pub fn from_vec(vec: Vec2<T>) -> Point2<T> { pub fn from_vec2(vec: Vec2<T>) -> Point2<T> {
unsafe { cast::transmute(vec) } unsafe { cast::transmute(vec) }
} }
@ -64,7 +64,26 @@ impl<T:Num> Point2<T> {
} }
} }
impl<T:Clone + 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: /// Converts the point to a three-dimensional homogeneous vector:
/// `[x, y] -> [x, y, 1]` /// `[x, y] -> [x, y, 1]`
#[inline] #[inline]
@ -84,21 +103,11 @@ impl<T:Clone + Float> Point2<T> {
#[inline] #[inline]
pub fn rotate_m(&self, mat: &Mat2<T>) -> Point2<T> { pub fn rotate_m(&self, mat: &Mat2<T>) -> Point2<T> {
Point2::from_vec(mat.mul_v(self.as_vec())) Point2::from_vec2(mat.mul_v(self.as_vec2()))
} }
} }
impl<T:Clone + Float> Point<T, Vec2<T>> for Point2<T> { impl<T:Clone + Float> Point<T, Vec2<T>> for Point2<T> {
#[inline]
pub fn as_vec<'a>(&'a self) -> &'a Vec2<T> {
unsafe { cast::transmute(self) }
}
#[inline]
pub fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec2<T> {
unsafe { cast::transmute(self) }
}
#[inline] #[inline]
pub fn translate(&self, offset: &Vec2<T>) -> Point2<T> { pub fn translate(&self, offset: &Vec2<T>) -> Point2<T> {
(*self) + (*offset) (*self) + (*offset)
@ -177,7 +186,7 @@ impl<T:Num> Point3<T> {
} }
#[inline] #[inline]
pub fn from_vec(vec: Vec3<T>) -> Point3<T> { pub fn from_vec3(vec: Vec3<T>) -> Point3<T> {
unsafe { cast::transmute(vec) } unsafe { cast::transmute(vec) }
} }
@ -187,7 +196,28 @@ impl<T:Num> Point3<T> {
} }
} }
impl<T:Clone + 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: /// Converts the point to a four-dimensional homogeneous vector:
/// `[x, y, z] -> [x, y, z, 1]` /// `[x, y, z] -> [x, y, z, 1]`
#[inline] #[inline]
@ -202,26 +232,16 @@ impl<T:Clone + Num> Point3<T> {
impl<T:Clone + Float> Point3<T> { impl<T:Clone + Float> Point3<T> {
#[inline] #[inline]
pub fn rotate_q(&self, quat: &Quat<T>) -> Point3<T> { pub fn rotate_q(&self, quat: &Quat<T>) -> Point3<T> {
Point3::from_vec(quat.mul_v(self.as_vec())) Point3::from_vec3(quat.mul_v(self.as_vec3()))
} }
#[inline] #[inline]
pub fn rotate_m(&self, mat: &Mat3<T>) -> Point3<T> { pub fn rotate_m(&self, mat: &Mat3<T>) -> Point3<T> {
Point3::from_vec(mat.mul_v(self.as_vec())) Point3::from_vec3(mat.mul_v(self.as_vec3()))
} }
} }
impl<T:Clone + Float> Point<T, Vec3<T>> for Point3<T> { impl<T:Clone + Float> Point<T, Vec3<T>> for Point3<T> {
#[inline]
pub fn as_vec<'a>(&'a self) -> &'a Vec3<T> {
unsafe { cast::transmute(self) }
}
#[inline]
pub fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec3<T> {
unsafe { cast::transmute(self) }
}
#[inline] #[inline]
pub fn translate(&self, offset: &Vec3<T>) -> Point3<T> { pub fn translate(&self, offset: &Vec3<T>) -> Point3<T> {
(*self) + (*offset) (*self) + (*offset)