72 lines
2.2 KiB
Rust
72 lines
2.2 KiB
Rust
use crate::{
|
|
matrices::Matrix4x4,
|
|
tuples::{cross, Tuple},
|
|
};
|
|
|
|
/// Create a matrix representing a eye at `from` looking at `to`, with an `up`
|
|
/// as the up vector.
|
|
pub fn view_transform(from: Tuple, to: Tuple, up: Tuple) -> Matrix4x4 {
|
|
let forward = (to - from).normalize();
|
|
let left = cross(forward, up.normalize());
|
|
let true_up = cross(left, forward);
|
|
Matrix4x4::new(
|
|
[left.x, left.y, left.z, 0.],
|
|
[true_up.x, true_up.y, true_up.z, 0.],
|
|
[-forward.x, -forward.y, -forward.z, 0.],
|
|
[0., 0., 0., 1.],
|
|
) * Matrix4x4::translation(-from.x, -from.y, -from.z)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use crate::{
|
|
matrices::{identity, scaling, translation, Matrix4x4},
|
|
transformations::view_transform,
|
|
tuples::{point, vector},
|
|
};
|
|
#[test]
|
|
fn default_orientation() {
|
|
// The transformation matrix for the default orientation.
|
|
let from = point(0., 0., 0.);
|
|
let to = point(0., 0., -1.);
|
|
let up = vector(0., 1., 0.);
|
|
let t = view_transform(from, to, up);
|
|
assert_eq!(t, identity());
|
|
}
|
|
#[test]
|
|
fn looking_positive_z() {
|
|
// A view transformation matrix looking in positive z direction.
|
|
let from = point(0., 0., 0.);
|
|
let to = point(0., 0., 1.);
|
|
let up = vector(0., 1., 0.);
|
|
let t = view_transform(from, to, up);
|
|
assert_eq!(t, scaling(-1., 1., -1.));
|
|
}
|
|
#[test]
|
|
fn transformation_moves_world() {
|
|
// The view transformation moves the world.
|
|
let from = point(0., 0., 8.);
|
|
let to = point(0., 0., 0.);
|
|
let up = vector(0., 1., 0.);
|
|
let t = view_transform(from, to, up);
|
|
assert_eq!(t, translation(0., 0., -8.));
|
|
}
|
|
#[test]
|
|
fn arbitrary_view() {
|
|
// An arbitrary view transformation.
|
|
let from = point(1., 3., 2.);
|
|
let to = point(4., -2., 8.);
|
|
let up = vector(1., 1., 0.);
|
|
let t = view_transform(from, to, up);
|
|
assert_eq!(
|
|
t,
|
|
Matrix4x4::new(
|
|
[-0.50709, 0.50709, 0.67612, -2.36643],
|
|
[0.76772, 0.60609, 0.12122, -2.82843],
|
|
[-0.35857, 0.59761, -0.71714, 0.],
|
|
[0., 0., 0., 1.],
|
|
)
|
|
);
|
|
}
|
|
}
|