pub use nalgebra as na; // TODO generalize and unify pub type V2 = na::Vector2; pub type V3 = na::Vector3; pub type V4 = na::Vector4; pub type M2 = na::Matrix2; pub type M3 = na::Matrix3; pub type M4 = na::Matrix4; pub type Q = na::UnitQuaternion; pub fn identity() -> M4 { M4::identity() } pub fn inverse3(m: M3) -> M3 { m.try_inverse().unwrap_or_else(M3::identity) } pub fn inverse4(m: M4) -> M4 { m.try_inverse().unwrap_or_else(M4::identity) } pub fn crop_3x3(m: &M4) -> M3 { m.fixed_resize(0.) } pub fn normal(p1: V3, p2: V3, p3: V3) -> V3 { (p2 - p1).cross(&(p3 - p1)).normalize() } pub fn translate(m: M4, v: V3) -> M4 { m.prepend_translation(&v) } pub fn rotate(m: M4, angle: f32, axis: na::Unit) -> M4 { let r: M4 = Q::from_axis_angle(&axis, angle).to_rotation_matrix().into(); m * r } pub fn scale(m: M4, v: V3) -> M4 { m.prepend_nonuniform_scaling(&v) } pub fn iL(pos: V3) -> M4 { na::Translation3::new(-pos.x, -pos.y, -pos.z).to_homogeneous() } pub fn perspective(aspect: f32, fovy: f32, near: f32, far: f32) -> M4 { assert!((far - near).abs() > 0.0001, "The near-plane and far-plane must not be superimposed"); let mut mat = M4::zeros(); let tan_half_fovy = (fovy / 2.).tan(); mat[(0, 0)] = 1. / (aspect * tan_half_fovy); mat[(1, 1)] = 1. / tan_half_fovy; mat[(2, 2)] = -(far + near) / (far - near); mat[(2, 3)] = -(2. * far * near) / (far - near); mat[(3, 2)] = -1.; mat }