use na::{Real, DefaultAllocator}; use traits::{Number, Alloc, Dimension}; use aliases::{TVec, TVec3}; /// The cross product of two vectors. pub fn cross(x: &TVec3, y: &TVec3) -> TVec3 { x.cross(y) } /// The distance between two points. pub fn distance(p0: &TVec, p1: &TVec) -> N where DefaultAllocator: Alloc { (p1 - p0).norm() } /// The dot product of two vectors. pub fn dot(x: &TVec, y: &TVec) -> N where DefaultAllocator: Alloc { x.dot(y) } /// If `dot(nref, i) < 0.0`, return `n`, otherwise, return `-n`. pub fn faceforward(n: &TVec, i: &TVec, nref: &TVec) -> TVec where DefaultAllocator: Alloc { if nref.dot(i) < N::zero() { n.clone() } else { -n.clone() } } /// The magnitude of a vector. pub fn length(x: &TVec) -> N where DefaultAllocator: Alloc { x.norm() } /// The magnitude of a vector. pub fn magnitude(x: &TVec) -> N where DefaultAllocator: Alloc { x.norm() } /// Normalizes a vector. pub fn normalize(x: &TVec) -> TVec 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: &TVec, n: &TVec) -> TVec 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: &TVec, n: &TVec, eta: N) -> TVec where DefaultAllocator: Alloc { let ni = n.dot(i); let k = N::one() - eta * eta * (N::one() - ni * ni); if k < N::zero() { TVec::<_, D>::zeros() } else { i * eta - n * (eta * dot(n, i) + k.sqrt()) } }