use na::{Real, Unit, Rotation3, Vector4, UnitQuaternion, U3, U4}; use aliases::{Qua, Vec, Mat}; /// Rotate the vector `v` by the quaternion `q` assumed to be normalized. pub fn quat_cross(q: &Qua, v: &Vec) -> Vec { UnitQuaternion::new_unchecked(*q) * v } /// Rotate the vector `v` by the inverse of the quaternion `q` assumed to be normalized. pub fn quat_inv_cross(v: &Vec, q: &Qua) -> Vec { UnitQuaternion::new_unchecked(*q).inverse() * v } /// The quaternion `w` component. pub fn quat_extract_real_component(q: &Qua) -> N { q.w } /// Normalized linear interpolation between two quaternions. pub fn quat_fast_mix(x: &Qua, y: &Qua, a: N) -> Qua { Unit::new_unchecked(*x).nlerp(&Unit::new_unchecked(*y), a).unwrap() } //pub fn quat_intermediate(prev: &Qua, curr: &Qua, next: &Qua) -> Qua { // unimplemented!() //} /// The squared magnitude of a quaternion `q`. pub fn quat_length2(q: &Qua) -> N { q.norm_squared() } /// The squared magnitude of a quaternion `q`. pub fn quat_magnitude2(q: &Qua) -> N { q.norm_squared() } /// The quaternion representing the identity rotation. pub fn quat_quat_identity() -> Qua { UnitQuaternion::identity().unwrap() } /// Rotates a vector by a quaternion assumed to be normalized. pub fn quat_rotate_vec3(q: &Qua, v: &Vec) -> Vec { UnitQuaternion::new_unchecked(*q) * v } /// Rotates a vector in homogeneous coordinates by a quaternion assumed to be normalized. pub fn quat_rotate(q: &Qua, v: &Vec) -> Vec { // UnitQuaternion::new_unchecked(*q) * v let rotated = Unit::new_unchecked(*q) * v.fixed_rows::(0); Vector4::new(rotated.x, rotated.y, rotated.z, v.w) } /// The rotation required to align `orig` to `dest`. pub fn quat_rotation(orig: &Vec, dest: &Vec) -> Qua { UnitQuaternion::rotation_between(orig, dest).unwrap_or(UnitQuaternion::identity()).unwrap() } /// The spherical linear interpolation between two quaternions. pub fn quat_short_mix(x: &Qua, y: &Qua, a: N) -> Qua { Unit::new_normalize(*x).slerp(&Unit::new_normalize(*y), a).unwrap() } //pub fn quat_squad(q1: &Qua, q2: &Qua, s1: &Qua, s2: &Qua, h: N) -> Qua { // unimplemented!() //} /// Converts a quaternion to a rotation matrix. pub fn quat_to_mat3(x: &Qua) -> Mat { UnitQuaternion::new_unchecked(*x).to_rotation_matrix().unwrap() } /// Converts a quaternion to a rotation matrix in homogenous coordinates. pub fn quat_to_mat4(x: &Qua) -> Mat { UnitQuaternion::new_unchecked(*x).to_homogeneous() } /// Converts a rotation matrix to a quaternion. pub fn mat3_to_quat(x: &Mat) -> Qua { let r = Rotation3::from_matrix_unchecked(*x); UnitQuaternion::from_rotation_matrix(&r).unwrap() } /// Converts a rotation matrix in homogeneous coordinates to a quaternion. pub fn to_quat(x: &Mat) -> Qua { let rot = x.fixed_slice::(0, 0).into_owned(); to_quat(&rot) }