1use core::f64::consts::PI;
2
3#[derive(Clone, Copy, Debug)]
4pub struct Vec3(pub f64, pub f64, pub f64);
5pub struct Vec4(pub f64, pub f64, pub f64, pub f64);
6
7#[must_use]
8pub fn vec3_length(v: Vec3) -> f64 {
9 (v.0 * v.0 + v.1 * v.1 + v.2 * v.2).sqrt()
10}
11
12#[must_use]
13pub fn vec3_dot(v: Vec3, u: Vec3) -> f64 {
14 v.0 * u.0 + v.1 * u.1 + v.2 * u.2
15}
16
17#[must_use]
18pub fn vec3_mul_scalar(v: Vec3, a: f64) -> Vec3 {
19 Vec3(v.0 * a, v.1 * a, v.2 * a)
20}
21
22#[must_use]
23pub fn vec3_sub(v1: Vec3, v2: Vec3) -> Vec3 {
24 Vec3(v1.0 - v2.0, v1.1 - v2.1, v1.2 - v2.2)
25}
26
27#[must_use]
29pub fn fmod2p(x: f64) -> f64 {
30 let mut ret_val = x % (2.0 * PI);
31 if ret_val < 0.0 {
32 ret_val += 2.0 * PI;
33 }
34 ret_val
35}
36
37#[must_use]
38pub fn acos_clamped(arg: f64) -> f64 {
39 let arg = arg.clamp(-1.0, 1.0);
40 arg.acos()
41}
42
43#[must_use]
44pub fn asin_clamped(arg: f64) -> f64 {
45 let arg = arg.clamp(-1.0, 1.0);
46 arg.asin()
47}
48
49#[must_use]
51pub fn modf(x: f64) -> (f64, f64) {
52 if !x.is_finite() {
53 if x.is_infinite() {
54 return (0.0_f64.copysign(x), x);
55 } else if x.is_nan() {
56 return (x, x);
57 }
58 }
59
60 (x.fract(), x.trunc())
61}