box3d_rust/math_functions/
vector.rs1use super::*;
5
6pub fn add(a: Vec3, b: Vec3) -> Vec3 {
8 Vec3 {
9 x: a.x + b.x,
10 y: a.y + b.y,
11 z: a.z + b.z,
12 }
13}
14
15pub fn sub(a: Vec3, b: Vec3) -> Vec3 {
17 Vec3 {
18 x: a.x - b.x,
19 y: a.y - b.y,
20 z: a.z - b.z,
21 }
22}
23
24pub fn mul(a: Vec3, b: Vec3) -> Vec3 {
26 Vec3 {
27 x: a.x * b.x,
28 y: a.y * b.y,
29 z: a.z * b.z,
30 }
31}
32
33pub fn neg(a: Vec3) -> Vec3 {
35 Vec3 {
36 x: -a.x,
37 y: -a.y,
38 z: -a.z,
39 }
40}
41
42pub fn dot(a: Vec3, b: Vec3) -> f32 {
44 a.x * b.x + a.y * b.y + a.z * b.z
45}
46
47pub fn length(v: Vec3) -> f32 {
49 dot(v, v).sqrt()
50}
51
52pub fn length_squared(a: Vec3) -> f32 {
54 a.x * a.x + a.y * a.y + a.z * a.z
55}
56
57pub fn distance(a: Vec3, b: Vec3) -> f32 {
59 let dv = Vec3 {
60 x: b.x - a.x,
61 y: b.y - a.y,
62 z: b.z - a.z,
63 };
64 length(dv)
65}
66
67pub fn distance_squared(a: Vec3, b: Vec3) -> f32 {
69 let dv = Vec3 {
70 x: b.x - a.x,
71 y: b.y - a.y,
72 z: b.z - a.z,
73 };
74 dv.x * dv.x + dv.y * dv.y + dv.z * dv.z
75}
76
77pub fn normalize(a: Vec3) -> Vec3 {
79 let length_squared = a.x * a.x + a.y * a.y + a.z * a.z;
80
81 if length_squared > 1000.0 * f32::MIN_POSITIVE {
82 let s = 1.0 / length_squared.sqrt();
83 Vec3 {
84 x: s * a.x,
85 y: s * a.y,
86 z: s * a.z,
87 }
88 } else {
89 Vec3 {
90 x: 0.0,
91 y: 0.0,
92 z: 0.0,
93 }
94 }
95}
96
97pub fn get_length_and_normalize(length_out: &mut f32, a: Vec3) -> Vec3 {
100 *length_out = length(a);
101 if *length_out < f32::EPSILON {
102 return VEC3_ZERO;
103 }
104
105 let inv_length = 1.0 / *length_out;
106 Vec3 {
107 x: inv_length * a.x,
108 y: inv_length * a.y,
109 z: inv_length * a.z,
110 }
111}
112
113pub fn perp(a: Vec3) -> Vec3 {
115 let p = if a.x < -0.5 || 0.5 < a.x {
119 Vec3 {
120 x: a.y,
121 y: -a.x,
122 z: 0.0,
123 }
124 } else {
125 Vec3 {
126 x: 0.0,
127 y: a.z,
128 z: -a.y,
129 }
130 };
131
132 normalize(p)
133}
134
135pub fn is_normalized(a: Vec3) -> bool {
137 let aa = dot(a, a);
138 abs_float(1.0 - aa) < 100.0 * f32::EPSILON
139}
140
141pub fn mul_add(a: Vec3, s: f32, b: Vec3) -> Vec3 {
143 Vec3 {
144 x: a.x + s * b.x,
145 y: a.y + s * b.y,
146 z: a.z + s * b.z,
147 }
148}
149
150pub fn mul_sub(a: Vec3, s: f32, b: Vec3) -> Vec3 {
152 Vec3 {
153 x: a.x - s * b.x,
154 y: a.y - s * b.y,
155 z: a.z - s * b.z,
156 }
157}
158
159pub fn mul_sv(s: f32, a: Vec3) -> Vec3 {
161 Vec3 {
162 x: s * a.x,
163 y: s * a.y,
164 z: s * a.z,
165 }
166}
167
168pub fn cross(a: Vec3, b: Vec3) -> Vec3 {
170 Vec3 {
171 x: a.y * b.z - a.z * b.y,
172 y: a.z * b.x - a.x * b.z,
173 z: a.x * b.y - a.y * b.x,
174 }
175}
176
177pub fn lerp(a: Vec3, b: Vec3, alpha: f32) -> Vec3 {
179 debug_assert!((0.0..=1.0).contains(&alpha));
180
181 Vec3 {
182 x: (1.0 - alpha) * a.x + alpha * b.x,
183 y: (1.0 - alpha) * a.y + alpha * b.y,
184 z: (1.0 - alpha) * a.z + alpha * b.z,
185 }
186}
187
188pub fn blend2(s: f32, a: Vec3, t: f32, b: Vec3) -> Vec3 {
190 Vec3 {
191 x: s * a.x + t * b.x,
192 y: s * a.y + t * b.y,
193 z: s * a.z + t * b.z,
194 }
195}
196
197pub fn blend3(s: f32, a: Vec3, t: f32, b: Vec3, u: f32, c: Vec3) -> Vec3 {
199 Vec3 {
200 x: s * a.x + t * b.x + u * c.x,
201 y: s * a.y + t * b.y + u * c.y,
202 z: s * a.z + t * b.z + u * c.z,
203 }
204}
205
206pub fn abs(a: Vec3) -> Vec3 {
208 Vec3 {
209 x: abs_float(a.x),
210 y: abs_float(a.y),
211 z: abs_float(a.z),
212 }
213}
214
215pub fn sign(a: Vec3) -> Vec3 {
217 Vec3 {
218 x: if a.x >= 0.0 { 1.0 } else { -1.0 },
219 y: if a.y >= 0.0 { 1.0 } else { -1.0 },
220 z: if a.z >= 0.0 { 1.0 } else { -1.0 },
221 }
222}
223
224pub fn min(a: Vec3, b: Vec3) -> Vec3 {
226 Vec3 {
227 x: min_float(a.x, b.x),
228 y: min_float(a.y, b.y),
229 z: min_float(a.z, b.z),
230 }
231}
232
233pub fn max(a: Vec3, b: Vec3) -> Vec3 {
235 Vec3 {
236 x: max_float(a.x, b.x),
237 y: max_float(a.y, b.y),
238 z: max_float(a.z, b.z),
239 }
240}
241
242pub fn clamp(a: Vec3, lower: Vec3, upper: Vec3) -> Vec3 {
244 Vec3 {
245 x: clamp_float(a.x, lower.x, upper.x),
246 y: clamp_float(a.y, lower.y, upper.y),
247 z: clamp_float(a.z, lower.z, upper.z),
248 }
249}
250
251pub fn safe_scale(a: Vec3) -> Vec3 {
254 let abs_scale = abs(a);
255 let min_scale = Vec3 {
256 x: MIN_SCALE,
257 y: MIN_SCALE,
258 z: MIN_SCALE,
259 };
260 mul(sign(a), max(abs_scale, min_scale))
261}