Homogeneous transformations added for Point3; extend/truncate added for vectors; Transform3 is implemented for AffineMatrix3
This commit is contained in:
parent
6dd06103fc
commit
04b257e217
6 changed files with 115 additions and 20 deletions
|
@ -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
|
||||
|
|
|
@ -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<S: Num> Point3<S> {
|
|||
pub fn origin() -> Point3<S> { zero() }
|
||||
}
|
||||
|
||||
impl<S: Clone + Num + Primitive> Point3<S> {
|
||||
#[inline]
|
||||
pub fn from_homogeneous(v: &Vec4<S>) -> Point3<S> {
|
||||
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<S> {
|
||||
Vec4::new(self.x.clone(), self.y.clone(), self.z.clone(), one())
|
||||
}
|
||||
}
|
||||
|
||||
/// Specifies the numeric operations for point types.
|
||||
pub trait Point
|
||||
<
|
||||
|
|
|
@ -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<S> {
|
||||
mat: Mat4<S>,
|
||||
}
|
||||
|
||||
/// A generic transformation consisting of a rotation,
|
||||
/// displacement vector and scale amount.
|
||||
pub struct Decomposed<S,V,R> {
|
||||
|
@ -71,14 +68,56 @@ Transform<S, Slice, V, P> for Decomposed<S,V,R> {
|
|||
}
|
||||
}
|
||||
|
||||
/// A transformation in three dimensions consisting of a rotation,
|
||||
/// displacement vector and scale amount.
|
||||
pub struct Transform3<S>( Decomposed<S,Vec3<S>,Quat<S>> );
|
||||
pub trait Transform3<S>
|
||||
: Transform<S, [S, ..3], Vec3<S>, Point3<S>>
|
||||
+ ToMat4<S>
|
||||
{}
|
||||
|
||||
impl<S: Float> Transform3<S> {
|
||||
#[inline]
|
||||
pub fn new(scale: S, rot: Quat<S>, disp: Vec3<S>) -> Transform3<S> {
|
||||
Transform3( Decomposed { scale: scale, rot: rot, disp: disp })
|
||||
impl<S: Float + Clone, R: Rotation3<S>>
|
||||
ToMat4<S> for Decomposed<S, Vec3<S>, R> {
|
||||
fn to_mat4(&self) -> Mat4<S> {
|
||||
let mut m = self.rot.to_mat3().mul_s( self.scale.clone() ).to_mat4();
|
||||
m.w = self.disp.extend( num::one() );
|
||||
m
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Float, R: Rotation3<S>>
|
||||
Transform3<S> for Decomposed<S,Vec3<S>,R> {}
|
||||
|
||||
/// A homogeneous transformation matrix.
|
||||
pub struct AffineMatrix3<S> {
|
||||
mat: Mat4<S>,
|
||||
}
|
||||
|
||||
impl<S : Clone + Float>
|
||||
Transform<S, [S, ..3], Vec3<S>, Point3<S>> for AffineMatrix3<S> {
|
||||
#[inline]
|
||||
fn transform_vec(&self, vec: &Vec3<S>) -> Vec3<S> {
|
||||
self.mat.mul_v( &vec.extend(num::zero()) ).truncate()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn transform_point(&self, point: &Point3<S>) -> Point3<S> {
|
||||
Point3::from_homogeneous( &self.mat.mul_v( &point.to_homogeneous() ))
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Clone + Primitive>
|
||||
ToMat4<S> for AffineMatrix3<S> {
|
||||
#[inline] fn to_mat4(&self) -> Mat4<S> { self.mat.clone() }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// A transformation in three dimensions consisting of a rotation,
|
||||
/// displacement vector and scale amount.
|
||||
pub struct Transform3D<S>( Decomposed<S,Vec3<S>,Quat<S>> );
|
||||
|
||||
impl<S: Float> Transform3D<S> {
|
||||
#[inline]
|
||||
pub fn new(scale: S, rot: Quat<S>, disp: Vec3<S>) -> Transform3D<S> {
|
||||
Transform3D( Decomposed { scale: scale, rot: rot, disp: disp })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ pub struct Vec3<S> { x: S, y: S, z: S }
|
|||
#[deriving(Eq, Clone, Zero)]
|
||||
pub struct Vec4<S> { x: S, y: S, z: S, w: S }
|
||||
|
||||
// Conversion traits
|
||||
// Conversion traits //FIXME: not used anywhere?
|
||||
pub trait ToVec2<S: Primitive> { fn to_vec2(&self) -> Vec2<S>; }
|
||||
pub trait ToVec3<S: Primitive> { fn to_vec3(&self) -> Vec3<S>; }
|
||||
pub trait ToVec4<S: Primitive> { fn to_vec4(&self) -> Vec4<S>; }
|
||||
|
@ -70,12 +70,28 @@ impl<S: Primitive> Vec2<S> {
|
|||
#[inline] pub fn unit_x() -> Vec2<S> { Vec2::new(one(), zero()) }
|
||||
#[inline] pub fn unit_y() -> Vec2<S> { Vec2::new(zero(), one()) }
|
||||
}
|
||||
impl<S: Primitive + Clone> Vec2<S> {
|
||||
#[inline]
|
||||
pub fn extend(&self, z: S)-> Vec3<S> {
|
||||
Vec3::new(self.x.clone(), self.y.clone(), z)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Primitive> Vec3<S> {
|
||||
#[inline] pub fn unit_x() -> Vec3<S> { Vec3::new(one(), zero(), zero()) }
|
||||
#[inline] pub fn unit_y() -> Vec3<S> { Vec3::new(zero(), one(), zero()) }
|
||||
#[inline] pub fn unit_z() -> Vec3<S> { Vec3::new(zero(), zero(), one()) }
|
||||
}
|
||||
impl<S: Primitive + Clone> Vec3<S> {
|
||||
#[inline]
|
||||
pub fn extend(&self, w: S)-> Vec4<S> {
|
||||
Vec4::new(self.x.clone(), self.y.clone(), self.z.clone(), w)
|
||||
}
|
||||
#[inline]
|
||||
pub fn truncate(&self)-> Vec2<S> {
|
||||
Vec2::new(self.x.clone(), self.y.clone()) //ignore Z
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Primitive> Vec4<S> {
|
||||
#[inline] pub fn unit_x() -> Vec4<S> { Vec4::new(one(), zero(), zero(), zero()) }
|
||||
|
@ -83,6 +99,12 @@ impl<S: Primitive> Vec4<S> {
|
|||
#[inline] pub fn unit_z() -> Vec4<S> { Vec4::new(zero(), zero(), one(), zero()) }
|
||||
#[inline] pub fn unit_w() -> Vec4<S> { Vec4::new(zero(), zero(), zero(), one()) }
|
||||
}
|
||||
impl<S: Primitive + Clone> Vec4<S> {
|
||||
#[inline]
|
||||
pub fn truncate(&self)-> Vec3<S> {
|
||||
Vec3::new(self.x.clone(), self.y.clone(), self.z.clone()) //ignore W
|
||||
}
|
||||
}
|
||||
|
||||
array!(impl<S> Vec2<S> -> [S, ..2] _2)
|
||||
array!(impl<S> Vec3<S> -> [S, ..3] _3)
|
||||
|
|
22
src/tests/point.rs
Normal file
22
src/tests/point.rs
Normal file
|
@ -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() ));
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue