diff --git a/src/mat_spec.rs b/src/mat_spec.rs index 4becb24a..99305e0a 100644 --- a/src/mat_spec.rs +++ b/src/mat_spec.rs @@ -1,6 +1,7 @@ use std::num::{Zero, One}; use vec::Vec3; use mat::{Mat1, Mat2, Mat3, Inv, Row}; +use mat; // some specializations: impl @@ -142,3 +143,25 @@ impl Row> for Mat3 { } } } + +// FIXME: move this to another file? +impl mat::Mat4 { + /// Computes a projection matrix given the frustrum near plane width, height, the field of + /// view, and the distance to the clipping planes (`znear` and `zfar`). + pub fn projection(width: N, height: N, fov: N, znear: N, zfar: N) -> mat::Mat4 { + let aspect = width / height; + + let _1: N = One::one(); + let sy = _1 / (fov * NumCast::from(0.5)).tan(); + let sx = -sy / aspect; + let sz = -(zfar + znear) / (znear - zfar); + let tz = zfar * znear * NumCast::from(2.0) / (znear - zfar); + + mat::Mat4::new( + sx, Zero::zero(), Zero::zero(), Zero::zero(), + Zero::zero(), sy, Zero::zero(), Zero::zero(), + Zero::zero(), Zero::zero(), sz, tz, + Zero::zero(), Zero::zero(), One::one(), Zero::zero() + ) + } +}