texpresso/math/
vec4.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::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};
24
25use super::Vec3;
26
27#[derive(Copy, Clone, PartialEq)]
28pub struct Vec4 {
29    x: f32,
30    y: f32,
31    z: f32,
32    w: f32,
33}
34
35impl Vec4 {
36    pub fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
37        Self { x, y, z, w }
38    }
39
40    pub fn x(&self) -> f32 {
41        self.x
42    }
43
44    pub fn y(&self) -> f32 {
45        self.y
46    }
47
48    pub fn z(&self) -> f32 {
49        self.z
50    }
51
52    pub fn w(&self) -> f32 {
53        self.w
54    }
55
56    pub fn to_vec3(&self) -> Vec3 {
57        Vec3::new(self.x, self.y, self.z)
58    }
59
60    pub fn splat_x(&self) -> Vec4 {
61        Vec4::new(self.x, self.x, self.x, self.x)
62    }
63
64    pub fn splat_y(&self) -> Vec4 {
65        Vec4::new(self.y, self.y, self.y, self.y)
66    }
67
68    pub fn splat_z(&self) -> Vec4 {
69        Vec4::new(self.z, self.z, self.z, self.z)
70    }
71
72    pub fn splat_w(&self) -> Vec4 {
73        Vec4::new(self.w, self.w, self.w, self.w)
74    }
75
76    pub fn max(&self, other: Vec4) -> Vec4 {
77        Vec4::new(
78            self.x.max(other.x),
79            self.y.max(other.y),
80            self.z.max(other.z),
81            self.w.max(other.w),
82        )
83    }
84
85    pub fn min(&self, other: Vec4) -> Vec4 {
86        Vec4::new(
87            self.x.min(other.x),
88            self.y.min(other.y),
89            self.z.min(other.z),
90            self.w.min(other.w),
91        )
92    }
93
94    pub fn reciprocal(&self) -> Vec4 {
95        Vec4::new(1.0 / self.x, 1.0 / self.y, 1.0 / self.z, 1.0 / self.w)
96    }
97
98    pub fn any_less_than(&self, other: &Vec4) -> bool {
99        self.x < other.x || self.y < other.y || self.z < other.z || self.w < other.w
100    }
101
102    pub fn truncate(&self) -> Vec4 {
103        Vec4::new(
104            libm::truncf(self.x),
105            libm::truncf(self.y),
106            libm::truncf(self.z),
107            libm::truncf(self.w),
108        )
109    }
110}
111
112impl Add for Vec4 {
113    type Output = Vec4;
114
115    fn add(self, other: Vec4) -> Vec4 {
116        Vec4::new(
117            self.x + other.x,
118            self.y + other.y,
119            self.z + other.z,
120            self.w + other.w,
121        )
122    }
123}
124
125impl<'a> Add for &'a Vec4 {
126    type Output = Vec4;
127
128    fn add(self, other: &'a Vec4) -> Vec4 {
129        Vec4::new(
130            self.x + other.x,
131            self.y + other.y,
132            self.z + other.z,
133            self.w + other.w,
134        )
135    }
136}
137
138impl<'a> Add<Vec4> for &'a Vec4 {
139    type Output = Vec4;
140
141    fn add(self, other: Vec4) -> Vec4 {
142        Vec4::new(
143            self.x + other.x,
144            self.y + other.y,
145            self.z + other.z,
146            self.w + other.w,
147        )
148    }
149}
150
151impl<'a> Add<&'a Vec4> for Vec4 {
152    type Output = Vec4;
153
154    fn add(self, other: &'a Vec4) -> Vec4 {
155        Vec4::new(
156            self.x + other.x,
157            self.y + other.y,
158            self.z + other.z,
159            self.w + other.w,
160        )
161    }
162}
163
164impl Add<f32> for Vec4 {
165    type Output = Vec4;
166
167    fn add(self, other: f32) -> Vec4 {
168        Vec4::new(
169            self.x + other,
170            self.y + other,
171            self.z + other,
172            self.w + other,
173        )
174    }
175}
176
177impl<'a> Add<f32> for &'a Vec4 {
178    type Output = Vec4;
179
180    fn add(self, other: f32) -> Vec4 {
181        Vec4::new(
182            self.x + other,
183            self.y + other,
184            self.z + other,
185            self.w + other,
186        )
187    }
188}
189
190impl AddAssign<Vec4> for Vec4 {
191    fn add_assign(&mut self, other: Vec4) {
192        self.x += other.x;
193        self.y += other.y;
194        self.z += other.z;
195        self.w += other.w;
196    }
197}
198
199impl<'a> AddAssign<&'a Vec4> for Vec4 {
200    fn add_assign(&mut self, other: &'a Vec4) {
201        self.x += other.x;
202        self.y += other.y;
203        self.z += other.z;
204        self.w += other.w;
205    }
206}
207
208impl AddAssign<f32> for Vec4 {
209    fn add_assign(&mut self, other: f32) {
210        self.x += other;
211        self.y += other;
212        self.z += other;
213        self.w += other;
214    }
215}
216
217impl Sub for Vec4 {
218    type Output = Vec4;
219
220    fn sub(self, other: Vec4) -> Vec4 {
221        Vec4::new(
222            self.x - other.x,
223            self.y - other.y,
224            self.z - other.z,
225            self.w - other.w,
226        )
227    }
228}
229
230impl<'a> Sub for &'a Vec4 {
231    type Output = Vec4;
232
233    fn sub(self, other: &'a Vec4) -> Vec4 {
234        Vec4::new(
235            self.x - other.x,
236            self.y - other.y,
237            self.z - other.z,
238            self.w - other.w,
239        )
240    }
241}
242
243impl<'a> Sub<Vec4> for &'a Vec4 {
244    type Output = Vec4;
245
246    fn sub(self, other: Vec4) -> Vec4 {
247        Vec4::new(
248            self.x - other.x,
249            self.y - other.y,
250            self.z - other.z,
251            self.w - other.w,
252        )
253    }
254}
255
256impl<'a> Sub<&'a Vec4> for Vec4 {
257    type Output = Vec4;
258
259    fn sub(self, other: &'a Vec4) -> Vec4 {
260        Vec4::new(
261            self.x - other.x,
262            self.y - other.y,
263            self.z - other.z,
264            self.w - other.w,
265        )
266    }
267}
268
269impl Sub<f32> for Vec4 {
270    type Output = Vec4;
271
272    fn sub(self, other: f32) -> Vec4 {
273        Vec4::new(
274            self.x - other,
275            self.y - other,
276            self.z - other,
277            self.w - other,
278        )
279    }
280}
281
282impl<'a> Sub<f32> for &'a Vec4 {
283    type Output = Vec4;
284
285    fn sub(self, other: f32) -> Vec4 {
286        Vec4::new(
287            self.x - other,
288            self.y - other,
289            self.z - other,
290            self.w - other,
291        )
292    }
293}
294
295impl SubAssign<Vec4> for Vec4 {
296    fn sub_assign(&mut self, other: Vec4) {
297        self.x -= other.x;
298        self.y -= other.y;
299        self.z -= other.z;
300        self.w -= other.w;
301    }
302}
303
304impl<'a> SubAssign<&'a Vec4> for Vec4 {
305    fn sub_assign(&mut self, other: &'a Vec4) {
306        self.x -= other.x;
307        self.y -= other.y;
308        self.z -= other.z;
309        self.w -= other.w;
310    }
311}
312
313impl SubAssign<f32> for Vec4 {
314    fn sub_assign(&mut self, other: f32) {
315        self.x -= other;
316        self.y -= other;
317        self.z -= other;
318        self.w -= other;
319    }
320}
321
322impl Mul for Vec4 {
323    type Output = Vec4;
324
325    fn mul(self, other: Vec4) -> Vec4 {
326        Vec4::new(
327            self.x * other.x,
328            self.y * other.y,
329            self.z * other.z,
330            self.w * other.w,
331        )
332    }
333}
334
335impl<'a> Mul for &'a Vec4 {
336    type Output = Vec4;
337
338    fn mul(self, other: &'a Vec4) -> Vec4 {
339        Vec4::new(
340            self.x * other.x,
341            self.y * other.y,
342            self.z * other.z,
343            self.w * other.w,
344        )
345    }
346}
347
348impl<'a> Mul<Vec4> for &'a Vec4 {
349    type Output = Vec4;
350
351    fn mul(self, other: Vec4) -> Vec4 {
352        Vec4::new(
353            self.x * other.x,
354            self.y * other.y,
355            self.z * other.z,
356            self.w * other.w,
357        )
358    }
359}
360
361impl<'a> Mul<&'a Vec4> for Vec4 {
362    type Output = Vec4;
363
364    fn mul(self, other: &'a Vec4) -> Vec4 {
365        Vec4::new(
366            self.x * other.x,
367            self.y * other.y,
368            self.z * other.z,
369            self.w * other.w,
370        )
371    }
372}
373
374impl Mul<f32> for Vec4 {
375    type Output = Vec4;
376
377    fn mul(self, other: f32) -> Vec4 {
378        Vec4::new(
379            self.x * other,
380            self.y * other,
381            self.z * other,
382            self.w * other,
383        )
384    }
385}
386
387impl<'a> Mul<f32> for &'a Vec4 {
388    type Output = Vec4;
389
390    fn mul(self, other: f32) -> Vec4 {
391        Vec4::new(
392            self.x * other,
393            self.y * other,
394            self.z * other,
395            self.w * other,
396        )
397    }
398}
399
400impl MulAssign<Vec4> for Vec4 {
401    fn mul_assign(&mut self, other: Vec4) {
402        self.x *= other.x;
403        self.y *= other.y;
404        self.z *= other.z;
405        self.w *= other.w;
406    }
407}
408
409impl<'a> MulAssign<&'a Vec4> for Vec4 {
410    fn mul_assign(&mut self, other: &'a Vec4) {
411        self.x *= other.x;
412        self.y *= other.y;
413        self.z *= other.z;
414        self.w *= other.w;
415    }
416}
417
418impl MulAssign<f32> for Vec4 {
419    fn mul_assign(&mut self, other: f32) {
420        self.x *= other;
421        self.y *= other;
422        self.z *= other;
423        self.w *= other;
424    }
425}