use na::{Real, U3, DefaultAllocator}; use traits::{Number, Alloc, Dimension}; use aliases::Vec; /// The cross product of two vectors. pub fn cross(x: &Vec, y: &Vec) -> Vec { x.cross(y) } /// The distance between two points. pub fn distance(p0: &Vec, p1: &Vec) -> N where DefaultAllocator: Alloc { (p1 - p0).norm() } /// The dot product of two vectors. pub fn dot(x: &Vec, y: &Vec) -> N where DefaultAllocator: Alloc { x.dot(y) } /// If `dot(nref, i) < 0.0`, return `n`, otherwise, return `-n`. pub fn faceforward(n: &Vec, i: &Vec, nref: &Vec) -> Vec where DefaultAllocator: Alloc { if nref.dot(i) < N::zero() { n.clone() } else { -n.clone() } } /// The magnitude of a vector. pub fn length(x: &Vec) -> N where DefaultAllocator: Alloc { x.norm() } /// The magnitude of a vector. pub fn magnitude(x: &Vec) -> N where DefaultAllocator: Alloc { x.norm() } /// Normalizes a vector. pub fn normalize(x: &Vec) -> Vec where DefaultAllocator: Alloc { x.normalize() } /// For the incident vector `i` and surface orientation `n`, returns the reflection direction : `result = i - 2.0 * dot(n, i) * n`. pub fn reflect_vec(i: &Vec, n: &Vec) -> Vec where DefaultAllocator: Alloc { let _2 = N::one() + N::one(); i - n * (n.dot(i) * _2) } /// For the incident vector `i` and surface normal `n`, and the ratio of indices of refraction `eta`, return the refraction vector. pub fn refract_vec(i: &Vec, n: &Vec, eta: N) -> Vec where DefaultAllocator: Alloc { let ni = n.dot(i); let k = N::one() - eta * eta * (N::one() - ni * ni); if k < N::zero() { Vec::<_, D>::zeros() } else { i * eta - n * (eta * dot(n, i) + k.sqrt()) } }