diff --git a/src/cgmath/plane.rs b/src/cgmath/plane.rs index 85ee3a2..b744a08 100644 --- a/src/cgmath/plane.rs +++ b/src/cgmath/plane.rs @@ -14,6 +14,7 @@ // limitations under the License. use std::cast::transmute; +use std::fmt; use intersect::Intersect; use point::{Point, Point3}; @@ -21,8 +22,6 @@ use ray::Ray3; use vector::{Vec3, Vec4}; use vector::{Vector, EuclideanVector}; -use std::fmt; - /// A 3-dimendional plane formed from the equation: `a*x + b*y + c*z - d = 0`. /// /// # Fields diff --git a/src/cgmath/point.rs b/src/cgmath/point.rs index bc2cfb6..388d7be 100644 --- a/src/cgmath/point.rs +++ b/src/cgmath/point.rs @@ -18,7 +18,7 @@ //! not have a fixed position. use std::fmt; -use std::num::zero; +use std::num::{one,zero}; use array::*; use vector::*; @@ -54,6 +54,19 @@ impl Point3 { pub fn origin() -> Point3 { zero() } } +impl Point3 { + #[inline] + pub fn from_homogeneous(v: &Vec4) -> Point3 { + let _1 :S = one(); + let e = v.truncate().mul_s( _1 / v.w ); + Point3::new(e.x.clone(), e.y.clone(), e.z.clone()) //FIXME + } + #[inline] + pub fn to_homogeneous(&self) -> Vec4 { + Vec4::new(self.x.clone(), self.y.clone(), self.z.clone(), one()) + } +} + /// Specifies the numeric operations for point types. pub trait Point < diff --git a/src/cgmath/transform.rs b/src/cgmath/transform.rs index 1fd94af..613f12c 100644 --- a/src/cgmath/transform.rs +++ b/src/cgmath/transform.rs @@ -13,10 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use matrix::Mat4; -use point::Point; +use std::num; + +use matrix::{Matrix, Mat4, ToMat4}; +use point::{Point, Point3}; use ray::Ray; -use rotation::Rotation; +use rotation::{Rotation, Rotation3}; use quaternion::Quat; use vector::{Vector, Vec3}; @@ -38,11 +40,6 @@ pub trait Transform } } -/// A homogeneous transformation matrix. -pub struct AffineMatrix3 { - mat: Mat4, -} - /// A generic transformation consisting of a rotation, /// displacement vector and scale amount. pub struct Decomposed { @@ -71,14 +68,56 @@ Transform for Decomposed { } } -/// A transformation in three dimensions consisting of a rotation, -/// displacement vector and scale amount. -pub struct Transform3( Decomposed,Quat> ); +pub trait Transform3 +: Transform, Point3> ++ ToMat4 +{} -impl Transform3 { - #[inline] - pub fn new(scale: S, rot: Quat, disp: Vec3) -> Transform3 { - Transform3( Decomposed { scale: scale, rot: rot, disp: disp }) +impl> +ToMat4 for Decomposed, R> { + fn to_mat4(&self) -> Mat4 { + let mut m = self.rot.to_mat3().mul_s( self.scale.clone() ).to_mat4(); + m.w = self.disp.extend( num::one() ); + m + } +} + +impl> +Transform3 for Decomposed,R> {} + +/// A homogeneous transformation matrix. +pub struct AffineMatrix3 { + mat: Mat4, +} + +impl +Transform, Point3> for AffineMatrix3 { + #[inline] + fn transform_vec(&self, vec: &Vec3) -> Vec3 { + self.mat.mul_v( &vec.extend(num::zero()) ).truncate() + } + + #[inline] + fn transform_point(&self, point: &Point3) -> Point3 { + Point3::from_homogeneous( &self.mat.mul_v( &point.to_homogeneous() )) + } +} + +impl +ToMat4 for AffineMatrix3 { + #[inline] fn to_mat4(&self) -> Mat4 { self.mat.clone() } +} + + + +/// A transformation in three dimensions consisting of a rotation, +/// displacement vector and scale amount. +pub struct Transform3D( Decomposed,Quat> ); + +impl Transform3D { + #[inline] + pub fn new(scale: S, rot: Quat, disp: Vec3) -> Transform3D { + Transform3D( Decomposed { scale: scale, rot: rot, disp: disp }) } } diff --git a/src/cgmath/vector.rs b/src/cgmath/vector.rs index bc8f8b5..9ff3ed3 100644 --- a/src/cgmath/vector.rs +++ b/src/cgmath/vector.rs @@ -31,7 +31,7 @@ pub struct Vec3 { x: S, y: S, z: S } #[deriving(Eq, Clone, Zero)] pub struct Vec4 { x: S, y: S, z: S, w: S } -// Conversion traits +// Conversion traits //FIXME: not used anywhere? pub trait ToVec2 { fn to_vec2(&self) -> Vec2; } pub trait ToVec3 { fn to_vec3(&self) -> Vec3; } pub trait ToVec4 { fn to_vec4(&self) -> Vec4; } @@ -70,12 +70,28 @@ impl Vec2 { #[inline] pub fn unit_x() -> Vec2 { Vec2::new(one(), zero()) } #[inline] pub fn unit_y() -> Vec2 { Vec2::new(zero(), one()) } } +impl Vec2 { + #[inline] + pub fn extend(&self, z: S)-> Vec3 { + Vec3::new(self.x.clone(), self.y.clone(), z) + } +} impl Vec3 { #[inline] pub fn unit_x() -> Vec3 { Vec3::new(one(), zero(), zero()) } #[inline] pub fn unit_y() -> Vec3 { Vec3::new(zero(), one(), zero()) } #[inline] pub fn unit_z() -> Vec3 { Vec3::new(zero(), zero(), one()) } } +impl Vec3 { + #[inline] + pub fn extend(&self, w: S)-> Vec4 { + Vec4::new(self.x.clone(), self.y.clone(), self.z.clone(), w) + } + #[inline] + pub fn truncate(&self)-> Vec2 { + Vec2::new(self.x.clone(), self.y.clone()) //ignore Z + } +} impl Vec4 { #[inline] pub fn unit_x() -> Vec4 { Vec4::new(one(), zero(), zero(), zero()) } @@ -83,6 +99,12 @@ impl Vec4 { #[inline] pub fn unit_z() -> Vec4 { Vec4::new(zero(), zero(), one(), zero()) } #[inline] pub fn unit_w() -> Vec4 { Vec4::new(zero(), zero(), zero(), one()) } } +impl Vec4 { + #[inline] + pub fn truncate(&self)-> Vec3 { + Vec3::new(self.x.clone(), self.y.clone(), self.z.clone()) //ignore W + } +} array!(impl Vec2 -> [S, ..2] _2) array!(impl Vec3 -> [S, ..3] _3) diff --git a/src/tests/point.rs b/src/tests/point.rs new file mode 100644 index 0000000..2079c64 --- /dev/null +++ b/src/tests/point.rs @@ -0,0 +1,22 @@ +// Copyright 2013 The CGMath Developers. For a full listing of the authors, +// refer to the AUTHORS file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use cgmath::point::*; + +#[test] +fn test_homogeneous() { + let p = Point3::new(1.0, 2.0, 3.0); + assert_eq!(p, Point3::from_homogeneous( &p.to_homogeneous() )); +} diff --git a/src/tests/test.rs b/src/tests/test.rs index 693cedf..223ff9d 100644 --- a/src/tests/test.rs +++ b/src/tests/test.rs @@ -22,7 +22,7 @@ pub mod vector; pub mod angle; pub mod plane; -// pub mod point; +pub mod point; // pub mod ray; // pub mod rotation;