texpresso/math/
vec3.rs

1// Copyright (c) 2006 Simon Brown <si@sjbrown.co.uk>
2// Copyright (c) 2018-2021 Jan Solanti <jhs@psonet.com>
3//
4// Permission is hereby granted, free of charge, to any person obtaining
5// a copy of this software and associated documentation files (the
6// "Software"), to	deal in the Software without restriction, including
7// without limitation the rights to use, copy, modify, merge, publish,
8// distribute, sublicense, and/or sell copies of the Software, and to
9// permit persons to whom the Software is furnished to do so, subject to
10// the following conditions:
11//
12// The above copyright notice and this permission notice shall be included
13// in all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23use core::iter::Sum;
24use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
25
26/// A 3-dimensional vector type
27#[derive(Copy, Clone, PartialEq)]
28pub struct Vec3 {
29    x: f32,
30    y: f32,
31    z: f32,
32}
33
34impl Vec3 {
35    pub fn new(x: f32, y: f32, z: f32) -> Self {
36        Self { x, y, z }
37    }
38
39    pub fn x(&self) -> f32 {
40        self.x
41    }
42
43    pub fn y(&self) -> f32 {
44        self.y
45    }
46
47    pub fn z(&self) -> f32 {
48        self.z
49    }
50
51    pub fn dot(&self, other: &Vec3) -> f32 {
52        self.x * other.x + self.y * other.y + self.z * other.z
53    }
54
55    pub fn length2(&self) -> f32 {
56        self.x * self.x + self.y * self.y + self.z * self.z
57    }
58
59    pub fn max(&self, other: Vec3) -> Vec3 {
60        Vec3::new(
61            self.x.max(other.x),
62            self.y.max(other.y),
63            self.z.max(other.z),
64        )
65    }
66
67    pub fn min(&self, other: Vec3) -> Vec3 {
68        Vec3::new(
69            self.x.min(other.x),
70            self.y.min(other.y),
71            self.z.min(other.z),
72        )
73    }
74
75    pub fn truncate(&self) -> Vec3 {
76        Vec3::new(
77            libm::truncf(self.x),
78            libm::truncf(self.y),
79            libm::truncf(self.z),
80        )
81    }
82}
83
84impl<'a> Add for &'a Vec3 {
85    type Output = Vec3;
86
87    fn add(self, other: &'a Vec3) -> Vec3 {
88        Vec3::new(self.x + other.x, self.y + other.y, self.z + other.z)
89    }
90}
91
92impl Add for Vec3 {
93    type Output = Vec3;
94
95    fn add(self, other: Vec3) -> Vec3 {
96        Vec3::new(self.x + other.x, self.y + other.y, self.z + other.z)
97    }
98}
99
100impl AddAssign<Vec3> for Vec3 {
101    fn add_assign(&mut self, other: Vec3) {
102        self.x += other.x;
103        self.y += other.y;
104        self.z += other.z;
105    }
106}
107
108impl<'a> Add<&'a Vec3> for Vec3 {
109    type Output = Vec3;
110
111    fn add(self, other: &'a Vec3) -> Vec3 {
112        Vec3::new(self.x + other.x, self.y + other.y, self.z + other.z)
113    }
114}
115
116impl<'a> AddAssign<&'a Vec3> for Vec3 {
117    fn add_assign(&mut self, other: &'a Vec3) {
118        self.x += other.x;
119        self.y += other.y;
120        self.z += other.z;
121    }
122}
123
124impl Add<f32> for Vec3 {
125    type Output = Vec3;
126
127    fn add(self, other: f32) -> Vec3 {
128        Vec3::new(self.x + other, self.y + other, self.z + other)
129    }
130}
131
132impl<'a> Add<f32> for &'a Vec3 {
133    type Output = Vec3;
134
135    fn add(self, other: f32) -> Vec3 {
136        Vec3::new(self.x + other, self.y + other, self.z + other)
137    }
138}
139
140impl AddAssign<f32> for Vec3 {
141    fn add_assign(&mut self, other: f32) {
142        self.x += other;
143        self.y += other;
144        self.z += other;
145    }
146}
147
148impl Sub for Vec3 {
149    type Output = Vec3;
150
151    fn sub(self, other: Vec3) -> Vec3 {
152        Vec3::new(self.x - other.x, self.y - other.y, self.z - other.z)
153    }
154}
155
156impl SubAssign<Vec3> for Vec3 {
157    fn sub_assign(&mut self, other: Vec3) {
158        self.x -= other.x;
159        self.y -= other.y;
160        self.z -= other.z;
161    }
162}
163
164impl<'a> Sub<&'a Vec3> for Vec3 {
165    type Output = Vec3;
166
167    fn sub(self, other: &'a Vec3) -> Vec3 {
168        Vec3::new(self.x - other.x, self.y - other.y, self.z - other.z)
169    }
170}
171
172impl<'a> Sub for &'a Vec3 {
173    type Output = Vec3;
174
175    fn sub(self, other: &'a Vec3) -> Vec3 {
176        Vec3::new(self.x - other.x, self.y - other.y, self.z - other.z)
177    }
178}
179
180impl<'a> SubAssign<&'a Vec3> for Vec3 {
181    fn sub_assign(&mut self, other: &'a Vec3) {
182        self.x -= other.x;
183        self.y -= other.y;
184        self.z -= other.z;
185    }
186}
187
188impl Sub<f32> for Vec3 {
189    type Output = Vec3;
190
191    fn sub(self, other: f32) -> Vec3 {
192        Vec3::new(self.x - other, self.y - other, self.z - other)
193    }
194}
195
196impl<'a> Sub<f32> for &'a Vec3 {
197    type Output = Vec3;
198
199    fn sub(self, other: f32) -> Vec3 {
200        Vec3::new(self.x - other, self.y - other, self.z - other)
201    }
202}
203
204impl SubAssign<f32> for Vec3 {
205    fn sub_assign(&mut self, other: f32) {
206        self.x -= other;
207        self.y -= other;
208        self.z -= other;
209    }
210}
211
212impl<'a> Mul for &'a Vec3 {
213    type Output = Vec3;
214
215    fn mul(self, other: &'a Vec3) -> Vec3 {
216        Vec3::new(self.x * other.x, self.y * other.y, self.z * other.z)
217    }
218}
219
220impl Mul for Vec3 {
221    type Output = Vec3;
222
223    fn mul(self, other: Vec3) -> Vec3 {
224        Vec3::new(self.x * other.x, self.y * other.y, self.z * other.z)
225    }
226}
227
228impl MulAssign for Vec3 {
229    fn mul_assign(&mut self, other: Vec3) {
230        self.x *= other.x;
231        self.y *= other.y;
232        self.z *= other.z;
233    }
234}
235
236impl<'a> Mul<&'a Vec3> for Vec3 {
237    type Output = Vec3;
238
239    fn mul(self, other: &'a Vec3) -> Vec3 {
240        Vec3::new(self.x * other.x, self.y * other.y, self.z * other.z)
241    }
242}
243
244impl<'a> MulAssign<&'a Vec3> for Vec3 {
245    fn mul_assign(&mut self, other: &'a Vec3) {
246        self.x *= other.x;
247        self.y *= other.y;
248        self.z *= other.z;
249    }
250}
251
252impl Mul<f32> for Vec3 {
253    type Output = Vec3;
254
255    fn mul(self, other: f32) -> Vec3 {
256        Vec3::new(self.x * other, self.y * other, self.z * other)
257    }
258}
259
260impl<'a> Mul<f32> for &'a Vec3 {
261    type Output = Vec3;
262
263    fn mul(self, other: f32) -> Vec3 {
264        Vec3::new(self.x * other, self.y * other, self.z * other)
265    }
266}
267
268impl MulAssign<f32> for Vec3 {
269    fn mul_assign(&mut self, other: f32) {
270        self.x *= other;
271        self.y *= other;
272        self.z *= other;
273    }
274}
275
276impl Div for Vec3 {
277    type Output = Vec3;
278
279    fn div(self, other: Vec3) -> Vec3 {
280        Vec3::new(self.x / other.x, self.y / other.y, self.z / other.z)
281    }
282}
283
284impl DivAssign for Vec3 {
285    fn div_assign(&mut self, other: Vec3) {
286        self.x /= other.x;
287        self.y /= other.y;
288        self.z /= other.z;
289    }
290}
291
292impl<'a> Div<&'a Vec3> for Vec3 {
293    type Output = Vec3;
294
295    fn div(self, other: &'a Vec3) -> Vec3 {
296        Vec3::new(self.x / other.x, self.y / other.y, self.z / other.z)
297    }
298}
299
300impl<'a> Div for &'a Vec3 {
301    type Output = Vec3;
302
303    fn div(self, other: &'a Vec3) -> Vec3 {
304        Vec3::new(self.x / other.x, self.y / other.y, self.z / other.z)
305    }
306}
307
308impl<'a> DivAssign<&'a Vec3> for Vec3 {
309    fn div_assign(&mut self, other: &'a Vec3) {
310        self.x /= other.x;
311        self.y /= other.y;
312        self.z /= other.z;
313    }
314}
315
316impl Div<f32> for Vec3 {
317    type Output = Vec3;
318
319    fn div(self, other: f32) -> Vec3 {
320        Vec3::new(self.x / other, self.y / other, self.z / other)
321    }
322}
323
324impl<'a> Div<f32> for &'a Vec3 {
325    type Output = Vec3;
326
327    fn div(self, other: f32) -> Vec3 {
328        Vec3::new(self.x / other, self.y / other, self.z / other)
329    }
330}
331
332impl DivAssign<f32> for Vec3 {
333    fn div_assign(&mut self, other: f32) {
334        let t = 1.0 / other;
335        self.x *= t;
336        self.y *= t;
337        self.z *= t;
338    }
339}
340
341impl Sum<Vec3> for Vec3 {
342    fn sum<I: Iterator<Item = Vec3>>(iter: I) -> Self {
343        iter.fold(Vec3::new(0.0, 0.0, 0.0), |a, b| a + b)
344    }
345}