look_at() implemented as a part of Transform trait
This commit is contained in:
parent
39b6bd2a5c
commit
1789f26ea1
8 changed files with 70 additions and 31 deletions
|
@ -13,7 +13,7 @@ The library provides:
|
|||
- angle units: `Rad`, `Deg`
|
||||
- points: `Point2`, `Point3`
|
||||
- rays: `Ray2`, `Ray3`
|
||||
- a plane: `Plane`
|
||||
- a plane type: `Plane`
|
||||
- perspective projections: `Perspective`, `PerspectiveFov`, `Ortho`
|
||||
- a view frustum: `Frustrum`
|
||||
- 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.
|
||||
//
|
||||
// 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]
|
||||
pub fn from_angle(theta: Rad<S>) -> Mat2<S> {
|
||||
let cos_theta = cos(theta.clone());
|
||||
|
@ -115,11 +120,11 @@ impl<S: Primitive> Mat3<S> {
|
|||
impl<S: Float + ApproxEq<S>>
|
||||
Mat3<S> {
|
||||
pub fn look_at(dir: &Vec3<S>, up: &Vec3<S>) -> Mat3<S> {
|
||||
let dir = dir.normalize();
|
||||
let side = dir.cross(&up.normalize());
|
||||
let up = side.cross(&dir).normalize();
|
||||
let dir = dir.normalize();
|
||||
let side = up.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).
|
||||
|
@ -672,7 +677,7 @@ impl<S: Float + ApproxEq<S>>
|
|||
ToQuat<S> for Mat3<S> {
|
||||
/// Convert the matrix to a quaternion
|
||||
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 half: S = cast(0.5).unwrap();
|
||||
match () {
|
||||
|
|
|
@ -37,11 +37,6 @@ impl<S: Num> Point2<S> {
|
|||
pub fn new(x: S, y: S) -> Point2<S> {
|
||||
Point2 { x: x, y: y }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn origin() -> Point2<S> {
|
||||
Point2 { x: zero(), y: zero() }
|
||||
}
|
||||
}
|
||||
|
||||
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> {
|
||||
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> {
|
||||
|
@ -78,6 +68,8 @@ pub trait Point
|
|||
>
|
||||
: 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 to_vec(&self) -> V { build(|i| self.i(i).clone()) }
|
||||
|
||||
|
|
|
@ -47,11 +47,6 @@ Quat<S> {
|
|||
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).
|
||||
#[inline]
|
||||
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.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -36,6 +36,8 @@ pub trait Rotation
|
|||
+ ApproxEq<S>
|
||||
{
|
||||
fn identity() -> Self;
|
||||
fn look_at(dir: &V, up: &V) -> Self;
|
||||
|
||||
fn rotate_vec(&self, vec: &V) -> V;
|
||||
|
||||
#[inline]
|
||||
|
@ -120,6 +122,16 @@ impl<S: Float + ApproxEq<S>>
|
|||
Rotation<S, [S, ..2], Vec2<S>, Point2<S>> for Basis2<S> {
|
||||
#[inline]
|
||||
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]
|
||||
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>>
|
||||
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).
|
||||
pub fn from_angle_x(theta: Rad<S>) -> Basis3<S> {
|
||||
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> {
|
||||
#[inline]
|
||||
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]
|
||||
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> {
|
||||
#[inline]
|
||||
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]
|
||||
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.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -33,6 +33,7 @@ pub trait Transform
|
|||
>
|
||||
{
|
||||
fn identity() -> Self;
|
||||
fn look_at(eye: &P, center: &P, up: &V) -> Self;
|
||||
|
||||
fn transform_vec(&self, vec: &V) -> V;
|
||||
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]
|
||||
fn transform_vec(&self, vec: &V) -> V {
|
||||
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> {
|
||||
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]
|
||||
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.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -15,6 +15,7 @@
|
|||
|
||||
use cgmath::quaternion::*;
|
||||
use cgmath::transform::*;
|
||||
use cgmath::point::*;
|
||||
use cgmath::vector::*;
|
||||
use cgmath::approx::ApproxEq;
|
||||
|
||||
|
@ -26,3 +27,14 @@ fn test_invert() {
|
|||
let vt = t.get().transform_vec( &v );
|
||||
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