Merge pull request #31 from kvark/try-look-at
look_at() implemented as a part of Transform trait
This commit is contained in:
commit
a7c2ddf2ca
8 changed files with 70 additions and 31 deletions
|
@ -13,7 +13,7 @@ The library provides:
|
||||||
- angle units: `Rad`, `Deg`
|
- angle units: `Rad`, `Deg`
|
||||||
- points: `Point2`, `Point3`
|
- points: `Point2`, `Point3`
|
||||||
- rays: `Ray2`, `Ray3`
|
- rays: `Ray2`, `Ray3`
|
||||||
- a plane: `Plane`
|
- a plane type: `Plane`
|
||||||
- perspective projections: `Perspective`, `PerspectiveFov`, `Ortho`
|
- perspective projections: `Perspective`, `PerspectiveFov`, `Ortho`
|
||||||
- a view frustum: `Frustrum`
|
- a view frustum: `Frustrum`
|
||||||
- spatial transformations: `AffineMatrix3`, `Transform3D`
|
- spatial transformations: `AffineMatrix3`, `Transform3D`
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
// Copyright 2014 The CGMath Developers. For a full listing of the authors,
|
||||||
// refer to the AUTHORS file at the top-level directory of this distribution.
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -68,7 +68,12 @@ impl<S: Primitive> Mat2<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Mat2<S> {
|
impl<S: Float + ApproxEq<S>> Mat2<S> {
|
||||||
|
pub fn look_at(dir: &Vec2<S>, up: &Vec2<S>) -> Mat2<S> {
|
||||||
|
//TODO: verify look_at 2D
|
||||||
|
Mat2::from_cols(up.clone(), dir.clone()).transpose()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_angle(theta: Rad<S>) -> Mat2<S> {
|
pub fn from_angle(theta: Rad<S>) -> Mat2<S> {
|
||||||
let cos_theta = cos(theta.clone());
|
let cos_theta = cos(theta.clone());
|
||||||
|
@ -115,11 +120,11 @@ impl<S: Primitive> Mat3<S> {
|
||||||
impl<S: Float + ApproxEq<S>>
|
impl<S: Float + ApproxEq<S>>
|
||||||
Mat3<S> {
|
Mat3<S> {
|
||||||
pub fn look_at(dir: &Vec3<S>, up: &Vec3<S>) -> Mat3<S> {
|
pub fn look_at(dir: &Vec3<S>, up: &Vec3<S>) -> Mat3<S> {
|
||||||
let dir = dir.normalize();
|
let dir = dir.normalize();
|
||||||
let side = dir.cross(&up.normalize());
|
let side = up.cross(&dir).normalize();
|
||||||
let up = side.cross(&dir).normalize();
|
let up = dir.cross(&side).normalize();
|
||||||
|
|
||||||
Mat3::from_cols(up, side, dir)
|
Mat3::from_cols(side, up, dir).transpose()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a matrix from a rotation around the `x` axis (pitch).
|
/// Create a matrix from a rotation around the `x` axis (pitch).
|
||||||
|
@ -672,7 +677,7 @@ impl<S: Float + ApproxEq<S>>
|
||||||
ToQuat<S> for Mat3<S> {
|
ToQuat<S> for Mat3<S> {
|
||||||
/// Convert the matrix to a quaternion
|
/// Convert the matrix to a quaternion
|
||||||
fn to_quat(&self) -> Quat<S> {
|
fn to_quat(&self) -> Quat<S> {
|
||||||
// http://www.cs.ucr.edu/~vbz/resources/Quatut.pdf
|
// http://www.cs.ucr.edu/~vbz/resources/quatut.pdf
|
||||||
let trace = self.trace();
|
let trace = self.trace();
|
||||||
let half: S = cast(0.5).unwrap();
|
let half: S = cast(0.5).unwrap();
|
||||||
match () {
|
match () {
|
||||||
|
|
|
@ -37,11 +37,6 @@ impl<S: Num> Point2<S> {
|
||||||
pub fn new(x: S, y: S) -> Point2<S> {
|
pub fn new(x: S, y: S) -> Point2<S> {
|
||||||
Point2 { x: x, y: y }
|
Point2 { x: x, y: y }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn origin() -> Point2<S> {
|
|
||||||
Point2 { x: zero(), y: zero() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Num> Point3<S> {
|
impl<S: Num> Point3<S> {
|
||||||
|
@ -49,11 +44,6 @@ impl<S: Num> Point3<S> {
|
||||||
pub fn new(x: S, y: S, z: S) -> Point3<S> {
|
pub fn new(x: S, y: S, z: S) -> Point3<S> {
|
||||||
Point3 { x: x, y: y, z: z }
|
Point3 { x: x, y: y, z: z }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn origin() -> Point3<S> {
|
|
||||||
Point3 { x: zero(), y: zero(), z: zero() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Clone + Num + Primitive> Point3<S> {
|
impl<S: Clone + Num + Primitive> Point3<S> {
|
||||||
|
@ -78,6 +68,8 @@ pub trait Point
|
||||||
>
|
>
|
||||||
: Array<S, Slice>
|
: Array<S, Slice>
|
||||||
{
|
{
|
||||||
|
#[inline] fn origin() -> Self{ build(|_i| zero::<S>()) }
|
||||||
|
|
||||||
#[inline] fn from_vec(v: &V) -> Self { build(|i| v.i(i).clone()) }
|
#[inline] fn from_vec(v: &V) -> Self { build(|i| v.i(i).clone()) }
|
||||||
#[inline] fn to_vec(&self) -> V { build(|i| self.i(i).clone()) }
|
#[inline] fn to_vec(&self) -> V { build(|i| self.i(i).clone()) }
|
||||||
|
|
||||||
|
|
|
@ -47,11 +47,6 @@ Quat<S> {
|
||||||
Quat { s: s, v: v }
|
Quat { s: s, v: v }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn look_at(dir: &Vec3<S>, up: &Vec3<S>) -> Quat<S> {
|
|
||||||
Mat3::look_at(dir, up).to_quat()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a matrix from a rotation around the `x` axis (pitch).
|
/// Create a matrix from a rotation around the `x` axis (pitch).
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_angle_x(theta: Rad<S>) -> Quat<S> {
|
pub fn from_angle_x(theta: Rad<S>) -> Quat<S> {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
// Copyright 2014 The CGMath Developers. For a full listing of the authors,
|
||||||
// refer to the AUTHORS file at the top-level directory of this distribution.
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -36,6 +36,8 @@ pub trait Rotation
|
||||||
+ ApproxEq<S>
|
+ ApproxEq<S>
|
||||||
{
|
{
|
||||||
fn identity() -> Self;
|
fn identity() -> Self;
|
||||||
|
fn look_at(dir: &V, up: &V) -> Self;
|
||||||
|
|
||||||
fn rotate_vec(&self, vec: &V) -> V;
|
fn rotate_vec(&self, vec: &V) -> V;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -120,6 +122,16 @@ impl<S: Float + ApproxEq<S>>
|
||||||
Rotation<S, [S, ..2], Vec2<S>, Point2<S>> for Basis2<S> {
|
Rotation<S, [S, ..2], Vec2<S>, Point2<S>> for Basis2<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn identity() -> Basis2<S> { Basis2{ mat: Mat2::identity() } }
|
fn identity() -> Basis2<S> { Basis2{ mat: Mat2::identity() } }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn look_at(dir: &Vec2<S>, up: &Vec2<S>) -> Basis2<S> {
|
||||||
|
Basis2 { mat: Mat2::look_at(dir, up) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn look_at(dir: &Vec2<S>, up: &Vec2<S>) -> Basis2<S> {
|
||||||
|
Basis2 { mat: Mat2::look_at(dir, up) }
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate_vec(&self, vec: &Vec2<S>) -> Vec2<S> { self.mat.mul_v(vec) }
|
fn rotate_vec(&self, vec: &Vec2<S>) -> Vec2<S> { self.mat.mul_v(vec) }
|
||||||
|
@ -165,11 +177,6 @@ pub struct Basis3<S> {
|
||||||
|
|
||||||
impl<S: Float + ApproxEq<S>>
|
impl<S: Float + ApproxEq<S>>
|
||||||
Basis3<S> {
|
Basis3<S> {
|
||||||
#[inline]
|
|
||||||
pub fn look_at(dir: &Vec3<S>, up: &Vec3<S>) -> Basis3<S> {
|
|
||||||
Basis3 { mat: Mat3::look_at(dir, up) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a rotation matrix from a rotation around the `x` axis (pitch).
|
/// Create a rotation matrix from a rotation around the `x` axis (pitch).
|
||||||
pub fn from_angle_x(theta: Rad<S>) -> Basis3<S> {
|
pub fn from_angle_x(theta: Rad<S>) -> Basis3<S> {
|
||||||
Basis3 { mat: Mat3::from_angle_x(theta) }
|
Basis3 { mat: Mat3::from_angle_x(theta) }
|
||||||
|
@ -229,6 +236,11 @@ impl<S: Float + ApproxEq<S>>
|
||||||
Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Basis3<S> {
|
Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Basis3<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn identity() -> Basis3<S> { Basis3{ mat: Mat3::identity() } }
|
fn identity() -> Basis3<S> { Basis3{ mat: Mat3::identity() } }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn look_at(dir: &Vec3<S>, up: &Vec3<S>) -> Basis3<S> {
|
||||||
|
Basis3 { mat: Mat3::look_at(dir, up) }
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate_vec(&self, vec: &Vec3<S>) -> Vec3<S> { self.mat.mul_v(vec) }
|
fn rotate_vec(&self, vec: &Vec3<S>) -> Vec3<S> { self.mat.mul_v(vec) }
|
||||||
|
@ -278,6 +290,11 @@ impl<S: Float + ApproxEq<S>>
|
||||||
Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Quat<S> {
|
Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Quat<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn identity() -> Quat<S> { Quat::identity() }
|
fn identity() -> Quat<S> { Quat::identity() }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn look_at(dir: &Vec3<S>, up: &Vec3<S>) -> Quat<S> {
|
||||||
|
Mat3::look_at(dir, up).to_quat()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate_vec(&self, vec: &Vec3<S>) -> Vec3<S> { self.mul_v(vec) }
|
fn rotate_vec(&self, vec: &Vec3<S>) -> Vec3<S> { self.mul_v(vec) }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
// Copyright 2014 The CGMath Developers. For a full listing of the authors,
|
||||||
// refer to the AUTHORS file at the top-level directory of this distribution.
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -33,6 +33,7 @@ pub trait Transform
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
fn identity() -> Self;
|
fn identity() -> Self;
|
||||||
|
fn look_at(eye: &P, center: &P, up: &V) -> Self;
|
||||||
|
|
||||||
fn transform_vec(&self, vec: &V) -> V;
|
fn transform_vec(&self, vec: &V) -> V;
|
||||||
fn transform_point(&self, point: &P) -> P;
|
fn transform_point(&self, point: &P) -> P;
|
||||||
|
@ -90,6 +91,18 @@ Transform<S, Slice, V, P> for Decomposed<S,V,R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn look_at(eye: &P, center: &P, up: &V) -> Decomposed<S,V,R> {
|
||||||
|
let origin :P = Point::origin();
|
||||||
|
let rot :R = Rotation::look_at( ¢er.sub_p(eye), up );
|
||||||
|
let disp :V = rot.rotate_vec( &origin.sub_p(eye) );
|
||||||
|
Decomposed {
|
||||||
|
scale: num::one(),
|
||||||
|
rot: rot,
|
||||||
|
disp: disp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transform_vec(&self, vec: &V) -> V {
|
fn transform_vec(&self, vec: &V) -> V {
|
||||||
self.rot.rotate_vec( &vec.mul_s( self.scale.clone() ))
|
self.rot.rotate_vec( &vec.mul_s( self.scale.clone() ))
|
||||||
|
@ -162,6 +175,11 @@ Transform<S, [S, ..3], Vec3<S>, Point3<S>> for AffineMatrix3<S> {
|
||||||
fn identity() -> AffineMatrix3<S> {
|
fn identity() -> AffineMatrix3<S> {
|
||||||
AffineMatrix3 { mat: Mat4::identity() }
|
AffineMatrix3 { mat: Mat4::identity() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn look_at(eye: &Point3<S>, center: &Point3<S>, up: &Vec3<S>) -> AffineMatrix3<S> {
|
||||||
|
AffineMatrix3 { mat: Mat4::look_at(eye, center, up) }
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transform_vec(&self, vec: &Vec3<S>) -> Vec3<S> {
|
fn transform_vec(&self, vec: &Vec3<S>) -> Vec3<S> {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
// Copyright 2014 The CGMath Developers. For a full listing of the authors,
|
||||||
// refer to the AUTHORS file at the top-level directory of this distribution.
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
use cgmath::quaternion::*;
|
use cgmath::quaternion::*;
|
||||||
use cgmath::transform::*;
|
use cgmath::transform::*;
|
||||||
|
use cgmath::point::*;
|
||||||
use cgmath::vector::*;
|
use cgmath::vector::*;
|
||||||
use cgmath::approx::ApproxEq;
|
use cgmath::approx::ApproxEq;
|
||||||
|
|
||||||
|
@ -26,3 +27,14 @@ fn test_invert() {
|
||||||
let vt = t.get().transform_vec( &v );
|
let vt = t.get().transform_vec( &v );
|
||||||
assert!(v.approx_eq( &ti.transform_vec( &vt ) ));
|
assert!(v.approx_eq( &ti.transform_vec( &vt ) ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_look_at() {
|
||||||
|
let eye = Point3::new(0.0, 0.0, -5.0);
|
||||||
|
let center = Point3::new(0.0, 0.0, 0.0);
|
||||||
|
let up = Vec3::new(1.0, 0.0, 0.0);
|
||||||
|
let t: Decomposed<f64,Vec3<f64>,Quat<f64>> = Transform::look_at(&eye, ¢er, &up);
|
||||||
|
let point = Point3::new(1.0, 0.0, 0.0);
|
||||||
|
let view_point = Point3::new(0.0, 1.0, 5.0);
|
||||||
|
assert!( t.transform_point(&point).approx_eq(&view_point) );
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue