openbim_ifcx_geometry/math.rs
1//! Small vector helpers shared by the decoders.
2//!
3//! Coordinates are `f64` throughout. IFCX files carry georeferenced
4//! coordinates (upstream samples reach several million metres), where `f32`
5//! keeps only about half a metre of precision. Convert to `f32` for a
6//! renderer only after world transforms have been applied and, if needed, a
7//! local origin has been subtracted.
8
9/// A point or direction in 3D, `[x, y, z]`.
10pub type Vec3 = [f64; 3];
11
12pub(crate) fn sub(a: Vec3, b: Vec3) -> Vec3 {
13 [a[0] - b[0], a[1] - b[1], a[2] - b[2]]
14}
15
16pub(crate) fn cross(a: Vec3, b: Vec3) -> Vec3 {
17 [
18 a[1] * b[2] - a[2] * b[1],
19 a[2] * b[0] - a[0] * b[2],
20 a[0] * b[1] - a[1] * b[0],
21 ]
22}
23
24/// Unit vector in the direction of `v`, or zero if `v` has no length.
25pub(crate) fn normalize_or_zero(v: Vec3) -> Vec3 {
26 let len = (v[0] * v[0] + v[1] * v[1] + v[2] * v[2]).sqrt();
27 if len > 0.0 && len.is_finite() {
28 [v[0] / len, v[1] / len, v[2] / len]
29 } else {
30 [0.0; 3]
31 }
32}