Implemented a more efficient orthonormal basis function.
Algorithm taken from the paper "Building an Orthonormal Basis, Revisited" by Duff et al.
This commit is contained in:
parent
4a86c4122a
commit
7223f69151
|
@ -130,16 +130,14 @@ pub fn log2_64(value: u64) -> u64 {
|
||||||
/// The input vector, v, becomes the first vector of the
|
/// The input vector, v, becomes the first vector of the
|
||||||
/// returned tuple, with the other two vectors in the returned
|
/// returned tuple, with the other two vectors in the returned
|
||||||
/// tuple defining the orthoganal axes.
|
/// tuple defining the orthoganal axes.
|
||||||
|
///
|
||||||
|
/// Algorithm taken from "Building an Orthonormal Basis, Revisited" by Duff et al.
|
||||||
pub fn coordinate_system_from_vector(v: Vector) -> (Vector, Vector, Vector) {
|
pub fn coordinate_system_from_vector(v: Vector) -> (Vector, Vector, Vector) {
|
||||||
let v2 = if v.x().abs() > v.y().abs() {
|
let sign = v.z().signum();
|
||||||
let invlen = 1.0 / ((v.x() * v.x()) + (v.z() * v.z())).sqrt();
|
let a = -1.0 / (sign + v.z());
|
||||||
Vector::new(-v.z() * invlen, 0.0, v.x() * invlen)
|
let b = v.x() * v.y() * a;
|
||||||
} else {
|
let v2 = Vector::new(1.0 + sign * v.x() * v.x() * a, sign * b, -sign * v.x());
|
||||||
let invlen = 1.0 / ((v.y() * v.y()) + (v.z() * v.z())).sqrt();
|
let v3 = Vector::new(b, sign + v.y() * v.y() * a, -v.y());
|
||||||
Vector::new(0.0, v.z() * invlen, -v.y() * invlen)
|
|
||||||
};
|
|
||||||
|
|
||||||
let v3 = cross(v, v2);
|
|
||||||
|
|
||||||
(v, v2, v3)
|
(v, v2, v3)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user