1use std::hash::{Hash, Hasher};
10use std::ops::{
11 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
12 Index, IndexMut, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign,
13 Sub, SubAssign,
14};
15
16use crate::math;
17
18#[derive(Clone, Copy, Debug, Default, PartialEq)]
22#[repr(C)]
23pub struct Vec2 {
24 pub x: f64,
25 pub y: f64,
26}
27
28impl Vec2 {
29 #[inline]
30 pub const fn new(x: f64, y: f64) -> Self {
31 Self { x, y }
32 }
33 #[inline]
34 pub const fn splat(v: f64) -> Self {
35 Self { x: v, y: v }
36 }
37 #[inline]
38 pub fn xy(self) -> Vec2 {
39 self
40 }
41}
42
43impl Index<usize> for Vec2 {
44 type Output = f64;
45 fn index(&self, i: usize) -> &f64 {
46 match i {
47 0 => &self.x,
48 1 => &self.y,
49 _ => panic!("Vec2 index out of range: {i}"),
50 }
51 }
52}
53impl IndexMut<usize> for Vec2 {
54 fn index_mut(&mut self, i: usize) -> &mut f64 {
55 match i {
56 0 => &mut self.x,
57 1 => &mut self.y,
58 _ => panic!("Vec2 index out of range: {i}"),
59 }
60 }
61}
62
63impl PartialOrd for Vec2 {
65 fn partial_cmp(&self, o: &Self) -> Option<std::cmp::Ordering> {
66 if self.x != o.x {
67 self.x.partial_cmp(&o.x)
68 } else {
69 self.y.partial_cmp(&o.y)
70 }
71 }
72}
73
74impl From<[f64; 2]> for Vec2 {
75 fn from(a: [f64; 2]) -> Self {
76 Self::new(a[0], a[1])
77 }
78}
79impl From<Vec2> for [f64; 2] {
80 fn from(v: Vec2) -> [f64; 2] {
81 [v.x, v.y]
82 }
83}
84impl From<(f64, f64)> for Vec2 {
85 fn from((x, y): (f64, f64)) -> Self {
86 Self::new(x, y)
87 }
88}
89
90macro_rules! impl_vec2_ops {
91 () => {
92 impl Neg for Vec2 {
93 type Output = Vec2;
94 fn neg(self) -> Vec2 {
95 Vec2::new(-self.x, -self.y)
96 }
97 }
98 impl Add for Vec2 {
99 type Output = Vec2;
100 fn add(self, b: Vec2) -> Vec2 {
101 Vec2::new(self.x + b.x, self.y + b.y)
102 }
103 }
104 impl Sub for Vec2 {
105 type Output = Vec2;
106 fn sub(self, b: Vec2) -> Vec2 {
107 Vec2::new(self.x - b.x, self.y - b.y)
108 }
109 }
110 impl Mul for Vec2 {
112 type Output = Vec2;
113 fn mul(self, b: Vec2) -> Vec2 {
114 Vec2::new(self.x * b.x, self.y * b.y)
115 }
116 }
117 impl Div for Vec2 {
118 type Output = Vec2;
119 fn div(self, b: Vec2) -> Vec2 {
120 Vec2::new(self.x / b.x, self.y / b.y)
121 }
122 }
123 impl Mul<f64> for Vec2 {
124 type Output = Vec2;
125 fn mul(self, s: f64) -> Vec2 {
126 Vec2::new(self.x * s, self.y * s)
127 }
128 }
129 impl Mul<Vec2> for f64 {
130 type Output = Vec2;
131 fn mul(self, v: Vec2) -> Vec2 {
132 Vec2::new(self * v.x, self * v.y)
133 }
134 }
135 impl Div<f64> for Vec2 {
136 type Output = Vec2;
137 fn div(self, s: f64) -> Vec2 {
138 Vec2::new(self.x / s, self.y / s)
139 }
140 }
141 impl Add<f64> for Vec2 {
142 type Output = Vec2;
143 fn add(self, s: f64) -> Vec2 {
144 Vec2::new(self.x + s, self.y + s)
145 }
146 }
147 impl Sub<f64> for Vec2 {
148 type Output = Vec2;
149 fn sub(self, s: f64) -> Vec2 {
150 Vec2::new(self.x - s, self.y - s)
151 }
152 }
153 impl AddAssign for Vec2 {
154 fn add_assign(&mut self, b: Vec2) {
155 *self = *self + b;
156 }
157 }
158 impl SubAssign for Vec2 {
159 fn sub_assign(&mut self, b: Vec2) {
160 *self = *self - b;
161 }
162 }
163 impl MulAssign for Vec2 {
164 fn mul_assign(&mut self, b: Vec2) {
165 *self = *self * b;
166 }
167 }
168 impl MulAssign<f64> for Vec2 {
169 fn mul_assign(&mut self, s: f64) {
170 *self = *self * s;
171 }
172 }
173 impl DivAssign for Vec2 {
174 fn div_assign(&mut self, b: Vec2) {
175 *self = *self / b;
176 }
177 }
178 impl DivAssign<f64> for Vec2 {
179 fn div_assign(&mut self, s: f64) {
180 *self = *self / s;
181 }
182 }
183 };
184}
185impl_vec2_ops!();
186
187#[derive(Clone, Copy, Debug, Default, PartialEq)]
191#[repr(C)]
192pub struct Vec3 {
193 pub x: f64,
194 pub y: f64,
195 pub z: f64,
196}
197
198impl Vec3 {
199 #[inline]
200 pub const fn new(x: f64, y: f64, z: f64) -> Self {
201 Self { x, y, z }
202 }
203 #[inline]
204 pub const fn splat(v: f64) -> Self {
205 Self { x: v, y: v, z: v }
206 }
207 #[inline]
208 pub fn xy(self) -> Vec2 {
209 Vec2::new(self.x, self.y)
210 }
211 #[inline]
212 pub fn yz(self) -> Vec2 {
213 Vec2::new(self.y, self.z)
214 }
215}
216
217impl Index<usize> for Vec3 {
218 type Output = f64;
219 fn index(&self, i: usize) -> &f64 {
220 match i {
221 0 => &self.x,
222 1 => &self.y,
223 2 => &self.z,
224 _ => panic!("Vec3 index out of range: {i}"),
225 }
226 }
227}
228impl IndexMut<usize> for Vec3 {
229 fn index_mut(&mut self, i: usize) -> &mut f64 {
230 match i {
231 0 => &mut self.x,
232 1 => &mut self.y,
233 2 => &mut self.z,
234 _ => panic!("Vec3 index out of range: {i}"),
235 }
236 }
237}
238
239impl PartialOrd for Vec3 {
240 fn partial_cmp(&self, o: &Self) -> Option<std::cmp::Ordering> {
241 if self.x != o.x {
242 self.x.partial_cmp(&o.x)
243 } else if self.y != o.y {
244 self.y.partial_cmp(&o.y)
245 } else {
246 self.z.partial_cmp(&o.z)
247 }
248 }
249}
250
251impl From<[f64; 3]> for Vec3 {
252 fn from(a: [f64; 3]) -> Self {
253 Self::new(a[0], a[1], a[2])
254 }
255}
256impl From<Vec3> for [f64; 3] {
257 fn from(v: Vec3) -> [f64; 3] {
258 [v.x, v.y, v.z]
259 }
260}
261impl From<(f64, f64, f64)> for Vec3 {
262 fn from((x, y, z): (f64, f64, f64)) -> Self {
263 Self::new(x, y, z)
264 }
265}
266impl From<(Vec2, f64)> for Vec3 {
267 fn from((xy, z): (Vec2, f64)) -> Self {
268 Self::new(xy.x, xy.y, z)
269 }
270}
271
272macro_rules! impl_vec3_ops {
273 () => {
274 impl Neg for Vec3 {
275 type Output = Vec3;
276 fn neg(self) -> Vec3 {
277 Vec3::new(-self.x, -self.y, -self.z)
278 }
279 }
280 impl Add for Vec3 {
281 type Output = Vec3;
282 fn add(self, b: Vec3) -> Vec3 {
283 Vec3::new(self.x + b.x, self.y + b.y, self.z + b.z)
284 }
285 }
286 impl Sub for Vec3 {
287 type Output = Vec3;
288 fn sub(self, b: Vec3) -> Vec3 {
289 Vec3::new(self.x - b.x, self.y - b.y, self.z - b.z)
290 }
291 }
292 impl Mul for Vec3 {
293 type Output = Vec3;
294 fn mul(self, b: Vec3) -> Vec3 {
295 Vec3::new(self.x * b.x, self.y * b.y, self.z * b.z)
296 }
297 }
298 impl Div for Vec3 {
299 type Output = Vec3;
300 fn div(self, b: Vec3) -> Vec3 {
301 Vec3::new(self.x / b.x, self.y / b.y, self.z / b.z)
302 }
303 }
304 impl Mul<f64> for Vec3 {
305 type Output = Vec3;
306 fn mul(self, s: f64) -> Vec3 {
307 Vec3::new(self.x * s, self.y * s, self.z * s)
308 }
309 }
310 impl Mul<Vec3> for f64 {
311 type Output = Vec3;
312 fn mul(self, v: Vec3) -> Vec3 {
313 Vec3::new(self * v.x, self * v.y, self * v.z)
314 }
315 }
316 impl Div<f64> for Vec3 {
317 type Output = Vec3;
318 fn div(self, s: f64) -> Vec3 {
319 Vec3::new(self.x / s, self.y / s, self.z / s)
320 }
321 }
322 impl Add<f64> for Vec3 {
323 type Output = Vec3;
324 fn add(self, s: f64) -> Vec3 {
325 Vec3::new(self.x + s, self.y + s, self.z + s)
326 }
327 }
328 impl Sub<f64> for Vec3 {
329 type Output = Vec3;
330 fn sub(self, s: f64) -> Vec3 {
331 Vec3::new(self.x - s, self.y - s, self.z - s)
332 }
333 }
334 impl AddAssign for Vec3 {
335 fn add_assign(&mut self, b: Vec3) {
336 *self = *self + b;
337 }
338 }
339 impl SubAssign for Vec3 {
340 fn sub_assign(&mut self, b: Vec3) {
341 *self = *self - b;
342 }
343 }
344 impl MulAssign for Vec3 {
345 fn mul_assign(&mut self, b: Vec3) {
346 *self = *self * b;
347 }
348 }
349 impl MulAssign<f64> for Vec3 {
350 fn mul_assign(&mut self, s: f64) {
351 *self = *self * s;
352 }
353 }
354 impl DivAssign for Vec3 {
355 fn div_assign(&mut self, b: Vec3) {
356 *self = *self / b;
357 }
358 }
359 impl DivAssign<f64> for Vec3 {
360 fn div_assign(&mut self, s: f64) {
361 *self = *self / s;
362 }
363 }
364 };
365}
366impl_vec3_ops!();
367
368#[derive(Clone, Copy, Debug, Default, PartialEq)]
372#[repr(C)]
373pub struct Vec4 {
374 pub x: f64,
375 pub y: f64,
376 pub z: f64,
377 pub w: f64,
378}
379
380impl Vec4 {
381 #[inline]
382 pub const fn new(x: f64, y: f64, z: f64, w: f64) -> Self {
383 Self { x, y, z, w }
384 }
385 #[inline]
386 pub const fn splat(v: f64) -> Self {
387 Self {
388 x: v,
389 y: v,
390 z: v,
391 w: v,
392 }
393 }
394 #[inline]
395 pub fn xy(self) -> Vec2 {
396 Vec2::new(self.x, self.y)
397 }
398 #[inline]
399 pub fn xyz(self) -> Vec3 {
400 Vec3::new(self.x, self.y, self.z)
401 }
402}
403
404impl Index<usize> for Vec4 {
405 type Output = f64;
406 fn index(&self, i: usize) -> &f64 {
407 match i {
408 0 => &self.x,
409 1 => &self.y,
410 2 => &self.z,
411 3 => &self.w,
412 _ => panic!("Vec4 index out of range: {i}"),
413 }
414 }
415}
416impl IndexMut<usize> for Vec4 {
417 fn index_mut(&mut self, i: usize) -> &mut f64 {
418 match i {
419 0 => &mut self.x,
420 1 => &mut self.y,
421 2 => &mut self.z,
422 3 => &mut self.w,
423 _ => panic!("Vec4 index out of range: {i}"),
424 }
425 }
426}
427
428impl PartialOrd for Vec4 {
429 fn partial_cmp(&self, o: &Self) -> Option<std::cmp::Ordering> {
430 if self.x != o.x {
431 self.x.partial_cmp(&o.x)
432 } else if self.y != o.y {
433 self.y.partial_cmp(&o.y)
434 } else if self.z != o.z {
435 self.z.partial_cmp(&o.z)
436 } else {
437 self.w.partial_cmp(&o.w)
438 }
439 }
440}
441
442impl From<[f64; 4]> for Vec4 {
443 fn from(a: [f64; 4]) -> Self {
444 Self::new(a[0], a[1], a[2], a[3])
445 }
446}
447impl From<Vec4> for [f64; 4] {
448 fn from(v: Vec4) -> [f64; 4] {
449 [v.x, v.y, v.z, v.w]
450 }
451}
452impl From<(Vec3, f64)> for Vec4 {
453 fn from((xyz, w): (Vec3, f64)) -> Self {
454 Self::new(xyz.x, xyz.y, xyz.z, w)
455 }
456}
457impl From<(Vec2, f64, f64)> for Vec4 {
458 fn from((xy, z, w): (Vec2, f64, f64)) -> Self {
459 Self::new(xy.x, xy.y, z, w)
460 }
461}
462
463macro_rules! impl_vec4_ops {
464 () => {
465 impl Neg for Vec4 {
466 type Output = Vec4;
467 fn neg(self) -> Vec4 {
468 Vec4::new(-self.x, -self.y, -self.z, -self.w)
469 }
470 }
471 impl Add for Vec4 {
472 type Output = Vec4;
473 fn add(self, b: Vec4) -> Vec4 {
474 Vec4::new(self.x + b.x, self.y + b.y, self.z + b.z, self.w + b.w)
475 }
476 }
477 impl Sub for Vec4 {
478 type Output = Vec4;
479 fn sub(self, b: Vec4) -> Vec4 {
480 Vec4::new(self.x - b.x, self.y - b.y, self.z - b.z, self.w - b.w)
481 }
482 }
483 impl Mul for Vec4 {
484 type Output = Vec4;
485 fn mul(self, b: Vec4) -> Vec4 {
486 Vec4::new(self.x * b.x, self.y * b.y, self.z * b.z, self.w * b.w)
487 }
488 }
489 impl Div for Vec4 {
490 type Output = Vec4;
491 fn div(self, b: Vec4) -> Vec4 {
492 Vec4::new(self.x / b.x, self.y / b.y, self.z / b.z, self.w / b.w)
493 }
494 }
495 impl Mul<f64> for Vec4 {
496 type Output = Vec4;
497 fn mul(self, s: f64) -> Vec4 {
498 Vec4::new(self.x * s, self.y * s, self.z * s, self.w * s)
499 }
500 }
501 impl Mul<Vec4> for f64 {
502 type Output = Vec4;
503 fn mul(self, v: Vec4) -> Vec4 {
504 Vec4::new(self * v.x, self * v.y, self * v.z, self * v.w)
505 }
506 }
507 impl Div<f64> for Vec4 {
508 type Output = Vec4;
509 fn div(self, s: f64) -> Vec4 {
510 Vec4::new(self.x / s, self.y / s, self.z / s, self.w / s)
511 }
512 }
513 impl Add<f64> for Vec4 {
514 type Output = Vec4;
515 fn add(self, s: f64) -> Vec4 {
516 Vec4::new(self.x + s, self.y + s, self.z + s, self.w + s)
517 }
518 }
519 impl Sub<f64> for Vec4 {
520 type Output = Vec4;
521 fn sub(self, s: f64) -> Vec4 {
522 Vec4::new(self.x - s, self.y - s, self.z - s, self.w - s)
523 }
524 }
525 impl AddAssign for Vec4 {
526 fn add_assign(&mut self, b: Vec4) {
527 *self = *self + b;
528 }
529 }
530 impl SubAssign for Vec4 {
531 fn sub_assign(&mut self, b: Vec4) {
532 *self = *self - b;
533 }
534 }
535 impl MulAssign for Vec4 {
536 fn mul_assign(&mut self, b: Vec4) {
537 *self = *self * b;
538 }
539 }
540 impl MulAssign<f64> for Vec4 {
541 fn mul_assign(&mut self, s: f64) {
542 *self = *self * s;
543 }
544 }
545 impl DivAssign for Vec4 {
546 fn div_assign(&mut self, b: Vec4) {
547 *self = *self / b;
548 }
549 }
550 impl DivAssign<f64> for Vec4 {
551 fn div_assign(&mut self, s: f64) {
552 *self = *self / s;
553 }
554 }
555 };
556}
557impl_vec4_ops!();
558
559pub type Quat = Vec4;
561
562#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
566#[repr(C)]
567pub struct IVec2 {
568 pub x: i32,
569 pub y: i32,
570}
571
572impl IVec2 {
573 #[inline]
574 pub const fn new(x: i32, y: i32) -> Self {
575 Self { x, y }
576 }
577 #[inline]
578 pub const fn splat(v: i32) -> Self {
579 Self { x: v, y: v }
580 }
581}
582
583impl Index<usize> for IVec2 {
584 type Output = i32;
585 fn index(&self, i: usize) -> &i32 {
586 match i {
587 0 => &self.x,
588 1 => &self.y,
589 _ => panic!("IVec2 index out of range: {i}"),
590 }
591 }
592}
593impl IndexMut<usize> for IVec2 {
594 fn index_mut(&mut self, i: usize) -> &mut i32 {
595 match i {
596 0 => &mut self.x,
597 1 => &mut self.y,
598 _ => panic!("IVec2 index out of range: {i}"),
599 }
600 }
601}
602
603impl PartialOrd for IVec2 {
604 fn partial_cmp(&self, o: &Self) -> Option<std::cmp::Ordering> {
605 Some(self.cmp(o))
606 }
607}
608impl Ord for IVec2 {
609 fn cmp(&self, o: &Self) -> std::cmp::Ordering {
610 self.x.cmp(&o.x).then(self.y.cmp(&o.y))
611 }
612}
613
614impl Hash for IVec2 {
615 fn hash<H: Hasher>(&self, state: &mut H) {
616 self.x.hash(state);
617 self.y.hash(state);
618 }
619}
620
621impl From<[i32; 2]> for IVec2 {
622 fn from(a: [i32; 2]) -> Self {
623 Self::new(a[0], a[1])
624 }
625}
626
627impl Neg for IVec2 {
628 type Output = IVec2;
629 fn neg(self) -> IVec2 {
630 IVec2::new(-self.x, -self.y)
631 }
632}
633impl Add for IVec2 {
634 type Output = IVec2;
635 fn add(self, b: IVec2) -> IVec2 {
636 IVec2::new(self.x + b.x, self.y + b.y)
637 }
638}
639impl Sub for IVec2 {
640 type Output = IVec2;
641 fn sub(self, b: IVec2) -> IVec2 {
642 IVec2::new(self.x - b.x, self.y - b.y)
643 }
644}
645impl Mul for IVec2 {
646 type Output = IVec2;
647 fn mul(self, b: IVec2) -> IVec2 {
648 IVec2::new(self.x * b.x, self.y * b.y)
649 }
650}
651impl Mul<i32> for IVec2 {
652 type Output = IVec2;
653 fn mul(self, s: i32) -> IVec2 {
654 IVec2::new(self.x * s, self.y * s)
655 }
656}
657impl Mul<IVec2> for i32 {
658 type Output = IVec2;
659 fn mul(self, v: IVec2) -> IVec2 {
660 IVec2::new(self * v.x, self * v.y)
661 }
662}
663impl AddAssign for IVec2 {
664 fn add_assign(&mut self, b: IVec2) {
665 *self = *self + b;
666 }
667}
668
669#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
671#[repr(C)]
672pub struct IVec3 {
673 pub x: i32,
674 pub y: i32,
675 pub z: i32,
676}
677
678impl IVec3 {
679 #[inline]
680 pub const fn new(x: i32, y: i32, z: i32) -> Self {
681 Self { x, y, z }
682 }
683 #[inline]
684 pub const fn splat(v: i32) -> Self {
685 Self { x: v, y: v, z: v }
686 }
687 #[inline]
688 pub fn xy(self) -> IVec2 {
689 IVec2::new(self.x, self.y)
690 }
691}
692
693impl Index<usize> for IVec3 {
694 type Output = i32;
695 fn index(&self, i: usize) -> &i32 {
696 match i {
697 0 => &self.x,
698 1 => &self.y,
699 2 => &self.z,
700 _ => panic!("IVec3 index out of range: {i}"),
701 }
702 }
703}
704impl IndexMut<usize> for IVec3 {
705 fn index_mut(&mut self, i: usize) -> &mut i32 {
706 match i {
707 0 => &mut self.x,
708 1 => &mut self.y,
709 2 => &mut self.z,
710 _ => panic!("IVec3 index out of range: {i}"),
711 }
712 }
713}
714
715impl PartialOrd for IVec3 {
716 fn partial_cmp(&self, o: &Self) -> Option<std::cmp::Ordering> {
717 Some(self.cmp(o))
718 }
719}
720impl Ord for IVec3 {
721 fn cmp(&self, o: &Self) -> std::cmp::Ordering {
722 self.x.cmp(&o.x).then(self.y.cmp(&o.y)).then(self.z.cmp(&o.z))
723 }
724}
725
726impl Hash for IVec3 {
727 fn hash<H: Hasher>(&self, state: &mut H) {
728 self.x.hash(state);
729 self.y.hash(state);
730 self.z.hash(state);
731 }
732}
733
734impl From<[i32; 3]> for IVec3 {
735 fn from(a: [i32; 3]) -> Self {
736 Self::new(a[0], a[1], a[2])
737 }
738}
739impl From<IVec3> for [i32; 3] {
740 fn from(v: IVec3) -> [i32; 3] {
741 [v.x, v.y, v.z]
742 }
743}
744
745impl Neg for IVec3 {
746 type Output = IVec3;
747 fn neg(self) -> IVec3 {
748 IVec3::new(-self.x, -self.y, -self.z)
749 }
750}
751impl Add for IVec3 {
752 type Output = IVec3;
753 fn add(self, b: IVec3) -> IVec3 {
754 IVec3::new(self.x + b.x, self.y + b.y, self.z + b.z)
755 }
756}
757impl Sub for IVec3 {
758 type Output = IVec3;
759 fn sub(self, b: IVec3) -> IVec3 {
760 IVec3::new(self.x - b.x, self.y - b.y, self.z - b.z)
761 }
762}
763impl Mul for IVec3 {
764 type Output = IVec3;
765 fn mul(self, b: IVec3) -> IVec3 {
766 IVec3::new(self.x * b.x, self.y * b.y, self.z * b.z)
767 }
768}
769impl Mul<i32> for IVec3 {
770 type Output = IVec3;
771 fn mul(self, s: i32) -> IVec3 {
772 IVec3::new(self.x * s, self.y * s, self.z * s)
773 }
774}
775impl AddAssign for IVec3 {
776 fn add_assign(&mut self, b: IVec3) {
777 *self = *self + b;
778 }
779}
780
781#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
783#[repr(C)]
784pub struct IVec4 {
785 pub x: i32,
786 pub y: i32,
787 pub z: i32,
788 pub w: i32,
789}
790
791impl IVec4 {
792 #[inline]
793 pub const fn new(x: i32, y: i32, z: i32, w: i32) -> Self {
794 Self { x, y, z, w }
795 }
796 #[inline]
797 pub const fn splat(v: i32) -> Self {
798 Self {
799 x: v,
800 y: v,
801 z: v,
802 w: v,
803 }
804 }
805 #[inline]
806 pub fn xyz(self) -> IVec3 {
807 IVec3::new(self.x, self.y, self.z)
808 }
809}
810
811impl Index<usize> for IVec4 {
812 type Output = i32;
813 fn index(&self, i: usize) -> &i32 {
814 match i {
815 0 => &self.x,
816 1 => &self.y,
817 2 => &self.z,
818 3 => &self.w,
819 _ => panic!("IVec4 index out of range: {i}"),
820 }
821 }
822}
823impl IndexMut<usize> for IVec4 {
824 fn index_mut(&mut self, i: usize) -> &mut i32 {
825 match i {
826 0 => &mut self.x,
827 1 => &mut self.y,
828 2 => &mut self.z,
829 3 => &mut self.w,
830 _ => panic!("IVec4 index out of range: {i}"),
831 }
832 }
833}
834
835impl PartialOrd for IVec4 {
836 fn partial_cmp(&self, o: &Self) -> Option<std::cmp::Ordering> {
837 Some(self.cmp(o))
838 }
839}
840impl Ord for IVec4 {
841 fn cmp(&self, o: &Self) -> std::cmp::Ordering {
842 self.x
843 .cmp(&o.x)
844 .then(self.y.cmp(&o.y))
845 .then(self.z.cmp(&o.z))
846 .then(self.w.cmp(&o.w))
847 }
848}
849
850impl Hash for IVec4 {
851 fn hash<H: Hasher>(&self, state: &mut H) {
852 self.x.hash(state);
853 self.y.hash(state);
854 self.z.hash(state);
855 self.w.hash(state);
856 }
857}
858
859impl From<[i32; 4]> for IVec4 {
860 fn from(a: [i32; 4]) -> Self {
861 Self::new(a[0], a[1], a[2], a[3])
862 }
863}
864
865impl Neg for IVec4 {
866 type Output = IVec4;
867 fn neg(self) -> IVec4 {
868 IVec4::new(-self.x, -self.y, -self.z, -self.w)
869 }
870}
871impl Add for IVec4 {
872 type Output = IVec4;
873 fn add(self, b: IVec4) -> IVec4 {
874 IVec4::new(self.x + b.x, self.y + b.y, self.z + b.z, self.w + b.w)
875 }
876}
877impl Sub for IVec4 {
878 type Output = IVec4;
879 fn sub(self, b: IVec4) -> IVec4 {
880 IVec4::new(self.x - b.x, self.y - b.y, self.z - b.z, self.w - b.w)
881 }
882}
883impl Mul<i32> for IVec4 {
884 type Output = IVec4;
885 fn mul(self, s: i32) -> IVec4 {
886 IVec4::new(self.x * s, self.y * s, self.z * s, self.w * s)
887 }
888}
889
890#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
894pub struct BVec4 {
895 pub x: bool,
896 pub y: bool,
897 pub z: bool,
898 pub w: bool,
899}
900
901impl BVec4 {
902 #[inline]
903 pub const fn new(x: bool, y: bool, z: bool, w: bool) -> Self {
904 Self { x, y, z, w }
905 }
906 #[inline]
907 pub const fn splat(v: bool) -> Self {
908 Self {
909 x: v,
910 y: v,
911 z: v,
912 w: v,
913 }
914 }
915}
916
917impl Index<usize> for BVec4 {
918 type Output = bool;
919 fn index(&self, i: usize) -> &bool {
920 match i {
921 0 => &self.x,
922 1 => &self.y,
923 2 => &self.z,
924 3 => &self.w,
925 _ => panic!("BVec4 index out of range: {i}"),
926 }
927 }
928}
929impl IndexMut<usize> for BVec4 {
930 fn index_mut(&mut self, i: usize) -> &mut bool {
931 match i {
932 0 => &mut self.x,
933 1 => &mut self.y,
934 2 => &mut self.z,
935 3 => &mut self.w,
936 _ => panic!("BVec4 index out of range: {i}"),
937 }
938 }
939}
940
941impl Not for BVec4 {
942 type Output = BVec4;
943 fn not(self) -> BVec4 {
944 BVec4::new(!self.x, !self.y, !self.z, !self.w)
945 }
946}
947impl BitAnd for BVec4 {
948 type Output = BVec4;
949 fn bitand(self, b: BVec4) -> BVec4 {
950 BVec4::new(self.x & b.x, self.y & b.y, self.z & b.z, self.w & b.w)
951 }
952}
953impl BitOr for BVec4 {
954 type Output = BVec4;
955 fn bitor(self, b: BVec4) -> BVec4 {
956 BVec4::new(self.x | b.x, self.y | b.y, self.z | b.z, self.w | b.w)
957 }
958}
959
960#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
964#[repr(C)]
965pub struct UVec3 {
966 pub x: u32,
967 pub y: u32,
968 pub z: u32,
969}
970
971impl UVec3 {
972 #[inline]
973 pub const fn new(x: u32, y: u32, z: u32) -> Self {
974 Self { x, y, z }
975 }
976}
977
978impl Index<usize> for UVec3 {
979 type Output = u32;
980 fn index(&self, i: usize) -> &u32 {
981 match i {
982 0 => &self.x,
983 1 => &self.y,
984 2 => &self.z,
985 _ => panic!("UVec3 index out of range: {i}"),
986 }
987 }
988}
989
990#[derive(Clone, Copy, Debug, Default, PartialEq)]
996pub struct Mat2 {
997 pub x: Vec2, pub y: Vec2, }
1000
1001impl Mat2 {
1002 #[inline]
1003 pub const fn from_cols(x: Vec2, y: Vec2) -> Self {
1004 Self { x, y }
1005 }
1006 pub fn identity() -> Self {
1008 Self {
1009 x: Vec2::new(1.0, 0.0),
1010 y: Vec2::new(0.0, 1.0),
1011 }
1012 }
1013 pub fn row(&self, i: usize) -> Vec2 {
1014 Vec2::new(self.x[i], self.y[i])
1015 }
1016 pub fn transpose(&self) -> Self {
1017 Self {
1018 x: self.row(0),
1019 y: self.row(1),
1020 }
1021 }
1022 pub fn determinant(&self) -> f64 {
1023 self.x.x * self.y.y - self.x.y * self.y.x
1024 }
1025}
1026
1027impl Index<usize> for Mat2 {
1028 type Output = Vec2;
1029 fn index(&self, j: usize) -> &Vec2 {
1030 match j {
1031 0 => &self.x,
1032 1 => &self.y,
1033 _ => panic!("Mat2 column index out of range: {j}"),
1034 }
1035 }
1036}
1037impl IndexMut<usize> for Mat2 {
1038 fn index_mut(&mut self, j: usize) -> &mut Vec2 {
1039 match j {
1040 0 => &mut self.x,
1041 1 => &mut self.y,
1042 _ => panic!("Mat2 column index out of range: {j}"),
1043 }
1044 }
1045}
1046
1047impl Mul<Vec2> for Mat2 {
1048 type Output = Vec2;
1049 fn mul(self, b: Vec2) -> Vec2 {
1050 self.x * b.x + self.y * b.y
1051 }
1052}
1053impl Mul for Mat2 {
1054 type Output = Mat2;
1055 fn mul(self, b: Mat2) -> Mat2 {
1056 Mat2::from_cols(self * b.x, self * b.y)
1057 }
1058}
1059impl Mul<f64> for Mat2 {
1060 type Output = Mat2;
1061 fn mul(self, s: f64) -> Mat2 {
1062 Mat2::from_cols(self.x * s, self.y * s)
1063 }
1064}
1065impl Add for Mat2 {
1066 type Output = Mat2;
1067 fn add(self, b: Mat2) -> Mat2 {
1068 Mat2::from_cols(self.x + b.x, self.y + b.y)
1069 }
1070}
1071impl Sub for Mat2 {
1072 type Output = Mat2;
1073 fn sub(self, b: Mat2) -> Mat2 {
1074 Mat2::from_cols(self.x - b.x, self.y - b.y)
1075 }
1076}
1077impl Neg for Mat2 {
1078 type Output = Mat2;
1079 fn neg(self) -> Mat2 {
1080 Mat2::from_cols(-self.x, -self.y)
1081 }
1082}
1083
1084#[derive(Clone, Copy, Debug, Default, PartialEq)]
1086pub struct Mat3 {
1087 pub x: Vec3, pub y: Vec3, pub z: Vec3, }
1091
1092impl Mat3 {
1093 #[inline]
1094 pub const fn from_cols(x: Vec3, y: Vec3, z: Vec3) -> Self {
1095 Self { x, y, z }
1096 }
1097 pub fn identity() -> Self {
1098 Self {
1099 x: Vec3::new(1.0, 0.0, 0.0),
1100 y: Vec3::new(0.0, 1.0, 0.0),
1101 z: Vec3::new(0.0, 0.0, 1.0),
1102 }
1103 }
1104 pub fn row(&self, i: usize) -> Vec3 {
1105 Vec3::new(self.x[i], self.y[i], self.z[i])
1106 }
1107 pub fn transpose(&self) -> Self {
1108 Self {
1109 x: self.row(0),
1110 y: self.row(1),
1111 z: self.row(2),
1112 }
1113 }
1114 pub fn adjugate(&self) -> Self {
1116 let a = self;
1117 Self {
1118 x: Vec3::new(
1119 a.y.y * a.z.z - a.z.y * a.y.z,
1120 a.z.y * a.x.z - a.x.y * a.z.z,
1121 a.x.y * a.y.z - a.y.y * a.x.z,
1122 ),
1123 y: Vec3::new(
1124 a.y.z * a.z.x - a.z.z * a.y.x,
1125 a.z.z * a.x.x - a.x.z * a.z.x,
1126 a.x.z * a.y.x - a.y.z * a.x.x,
1127 ),
1128 z: Vec3::new(
1129 a.y.x * a.z.y - a.z.x * a.y.y,
1130 a.z.x * a.x.y - a.x.x * a.z.y,
1131 a.x.x * a.y.y - a.y.x * a.x.y,
1132 ),
1133 }
1134 }
1135 pub fn determinant(&self) -> f64 {
1136 let a = self;
1137 a.x.x * (a.y.y * a.z.z - a.z.y * a.y.z)
1138 + a.x.y * (a.y.z * a.z.x - a.z.z * a.y.x)
1139 + a.x.z * (a.y.x * a.z.y - a.z.x * a.y.y)
1140 }
1141 pub fn inverse(&self) -> Self {
1142 self.adjugate() * (1.0 / self.determinant())
1143 }
1144 pub fn diagonal(&self) -> Vec3 {
1145 Vec3::new(self.x.x, self.y.y, self.z.z)
1146 }
1147 pub fn trace(&self) -> f64 {
1148 self.x.x + self.y.y + self.z.z
1149 }
1150}
1151
1152impl Index<usize> for Mat3 {
1153 type Output = Vec3;
1154 fn index(&self, j: usize) -> &Vec3 {
1155 match j {
1156 0 => &self.x,
1157 1 => &self.y,
1158 2 => &self.z,
1159 _ => panic!("Mat3 column index out of range: {j}"),
1160 }
1161 }
1162}
1163impl IndexMut<usize> for Mat3 {
1164 fn index_mut(&mut self, j: usize) -> &mut Vec3 {
1165 match j {
1166 0 => &mut self.x,
1167 1 => &mut self.y,
1168 2 => &mut self.z,
1169 _ => panic!("Mat3 column index out of range: {j}"),
1170 }
1171 }
1172}
1173
1174impl Mul<Vec3> for Mat3 {
1175 type Output = Vec3;
1176 fn mul(self, b: Vec3) -> Vec3 {
1177 self.x * b.x + self.y * b.y + self.z * b.z
1178 }
1179}
1180impl Mul for Mat3 {
1181 type Output = Mat3;
1182 fn mul(self, b: Mat3) -> Mat3 {
1183 Mat3::from_cols(self * b.x, self * b.y, self * b.z)
1184 }
1185}
1186impl Mul<f64> for Mat3 {
1187 type Output = Mat3;
1188 fn mul(self, s: f64) -> Mat3 {
1189 Mat3::from_cols(self.x * s, self.y * s, self.z * s)
1190 }
1191}
1192impl Add for Mat3 {
1193 type Output = Mat3;
1194 fn add(self, b: Mat3) -> Mat3 {
1195 Mat3::from_cols(self.x + b.x, self.y + b.y, self.z + b.z)
1196 }
1197}
1198impl Sub for Mat3 {
1199 type Output = Mat3;
1200 fn sub(self, b: Mat3) -> Mat3 {
1201 Mat3::from_cols(self.x - b.x, self.y - b.y, self.z - b.z)
1202 }
1203}
1204impl Neg for Mat3 {
1205 type Output = Mat3;
1206 fn neg(self) -> Mat3 {
1207 Mat3::from_cols(-self.x, -self.y, -self.z)
1208 }
1209}
1210
1211#[derive(Clone, Copy, Debug, Default, PartialEq)]
1213pub struct Mat4 {
1214 pub x: Vec4, pub y: Vec4, pub z: Vec4, pub w: Vec4, }
1219
1220impl Mat4 {
1221 #[inline]
1222 pub const fn from_cols(x: Vec4, y: Vec4, z: Vec4, w: Vec4) -> Self {
1223 Self { x, y, z, w }
1224 }
1225 pub fn identity() -> Self {
1226 Self {
1227 x: Vec4::new(1.0, 0.0, 0.0, 0.0),
1228 y: Vec4::new(0.0, 1.0, 0.0, 0.0),
1229 z: Vec4::new(0.0, 0.0, 1.0, 0.0),
1230 w: Vec4::new(0.0, 0.0, 0.0, 1.0),
1231 }
1232 }
1233 pub fn row(&self, i: usize) -> Vec4 {
1234 Vec4::new(self.x[i], self.y[i], self.z[i], self.w[i])
1235 }
1236 pub fn transpose(&self) -> Self {
1237 Self {
1238 x: self.row(0),
1239 y: self.row(1),
1240 z: self.row(2),
1241 w: self.row(3),
1242 }
1243 }
1244 pub fn determinant(&self) -> f64 {
1245 let a = self;
1246 a.x.x
1247 * (a.y.y * a.z.z * a.w.w
1248 + a.w.y * a.y.z * a.z.w
1249 + a.z.y * a.w.z * a.y.w
1250 - a.y.y * a.w.z * a.z.w
1251 - a.z.y * a.y.z * a.w.w
1252 - a.w.y * a.z.z * a.y.w)
1253 + a.x.y
1254 * (a.y.z * a.w.w * a.z.x
1255 + a.z.z * a.y.w * a.w.x
1256 + a.w.z * a.z.w * a.y.x
1257 - a.y.z * a.z.w * a.w.x
1258 - a.w.z * a.y.w * a.z.x
1259 - a.z.z * a.w.w * a.y.x)
1260 + a.x.z
1261 * (a.y.w * a.z.x * a.w.y
1262 + a.w.w * a.y.x * a.z.y
1263 + a.z.w * a.w.x * a.y.y
1264 - a.y.w * a.w.x * a.z.y
1265 - a.z.w * a.y.x * a.w.y
1266 - a.w.w * a.z.x * a.y.y)
1267 + a.x.w
1268 * (a.y.x * a.w.y * a.z.z
1269 + a.z.x * a.y.y * a.w.z
1270 + a.w.x * a.z.y * a.y.z
1271 - a.y.x * a.z.y * a.w.z
1272 - a.w.x * a.y.y * a.z.z
1273 - a.z.x * a.w.y * a.y.z)
1274 }
1275 pub fn adjugate(&self) -> Self {
1276 let a = self;
1277 Self {
1278 x: Vec4::new(
1279 a.y.y * a.z.z * a.w.w
1280 + a.w.y * a.y.z * a.z.w
1281 + a.z.y * a.w.z * a.y.w
1282 - a.y.y * a.w.z * a.z.w
1283 - a.z.y * a.y.z * a.w.w
1284 - a.w.y * a.z.z * a.y.w,
1285 a.x.y * a.w.z * a.z.w
1286 + a.z.y * a.x.z * a.w.w
1287 + a.w.y * a.z.z * a.x.w
1288 - a.w.y * a.x.z * a.z.w
1289 - a.z.y * a.w.z * a.x.w
1290 - a.x.y * a.z.z * a.w.w,
1291 a.x.y * a.y.z * a.w.w
1292 + a.w.y * a.x.z * a.y.w
1293 + a.y.y * a.w.z * a.x.w
1294 - a.x.y * a.w.z * a.y.w
1295 - a.y.y * a.x.z * a.w.w
1296 - a.w.y * a.y.z * a.x.w,
1297 a.x.y * a.z.z * a.y.w
1298 + a.y.y * a.x.z * a.z.w
1299 + a.z.y * a.y.z * a.x.w
1300 - a.x.y * a.y.z * a.z.w
1301 - a.z.y * a.x.z * a.y.w
1302 - a.y.y * a.z.z * a.x.w,
1303 ),
1304 y: Vec4::new(
1305 a.y.z * a.w.w * a.z.x
1306 + a.z.z * a.y.w * a.w.x
1307 + a.w.z * a.z.w * a.y.x
1308 - a.y.z * a.z.w * a.w.x
1309 - a.w.z * a.y.w * a.z.x
1310 - a.z.z * a.w.w * a.y.x,
1311 a.x.z * a.z.w * a.w.x
1312 + a.w.z * a.x.w * a.z.x
1313 + a.z.z * a.w.w * a.x.x
1314 - a.x.z * a.w.w * a.z.x
1315 - a.z.z * a.x.w * a.w.x
1316 - a.w.z * a.z.w * a.x.x,
1317 a.x.z * a.w.w * a.y.x
1318 + a.y.z * a.x.w * a.w.x
1319 + a.w.z * a.y.w * a.x.x
1320 - a.x.z * a.y.w * a.w.x
1321 - a.w.z * a.x.w * a.y.x
1322 - a.y.z * a.w.w * a.x.x,
1323 a.x.z * a.y.w * a.z.x
1324 + a.z.z * a.x.w * a.y.x
1325 + a.y.z * a.z.w * a.x.x
1326 - a.x.z * a.z.w * a.y.x
1327 - a.y.z * a.x.w * a.z.x
1328 - a.z.z * a.y.w * a.x.x,
1329 ),
1330 z: Vec4::new(
1331 a.y.w * a.z.x * a.w.y
1332 + a.w.w * a.y.x * a.z.y
1333 + a.z.w * a.w.x * a.y.y
1334 - a.y.w * a.w.x * a.z.y
1335 - a.z.w * a.y.x * a.w.y
1336 - a.w.w * a.z.x * a.y.y,
1337 a.x.w * a.w.x * a.z.y
1338 + a.z.w * a.x.x * a.w.y
1339 + a.w.w * a.z.x * a.x.y
1340 - a.x.w * a.z.x * a.w.y
1341 - a.w.w * a.x.x * a.z.y
1342 - a.z.w * a.w.x * a.x.y,
1343 a.x.w * a.y.x * a.w.y
1344 + a.w.w * a.x.x * a.y.y
1345 + a.y.w * a.w.x * a.x.y
1346 - a.x.w * a.w.x * a.y.y
1347 - a.y.w * a.x.x * a.w.y
1348 - a.w.w * a.y.x * a.x.y,
1349 a.x.w * a.z.x * a.y.y
1350 + a.y.w * a.x.x * a.z.y
1351 + a.z.w * a.y.x * a.x.y
1352 - a.x.w * a.y.x * a.z.y
1353 - a.z.w * a.x.x * a.y.y
1354 - a.y.w * a.z.x * a.x.y,
1355 ),
1356 w: Vec4::new(
1357 a.y.x * a.w.y * a.z.z
1358 + a.z.x * a.y.y * a.w.z
1359 + a.w.x * a.z.y * a.y.z
1360 - a.y.x * a.z.y * a.w.z
1361 - a.w.x * a.y.y * a.z.z
1362 - a.z.x * a.w.y * a.y.z,
1363 a.x.x * a.z.y * a.w.z
1364 + a.w.x * a.x.y * a.z.z
1365 + a.z.x * a.w.y * a.x.z
1366 - a.x.x * a.w.y * a.z.z
1367 - a.z.x * a.x.y * a.w.z
1368 - a.w.x * a.z.y * a.x.z,
1369 a.x.x * a.w.y * a.y.z
1370 + a.y.x * a.x.y * a.w.z
1371 + a.w.x * a.y.y * a.x.z
1372 - a.x.x * a.y.y * a.w.z
1373 - a.w.x * a.x.y * a.y.z
1374 - a.y.x * a.w.y * a.x.z,
1375 a.x.x * a.y.y * a.z.z
1376 + a.z.x * a.x.y * a.y.z
1377 + a.y.x * a.z.y * a.x.z
1378 - a.x.x * a.z.y * a.y.z
1379 - a.y.x * a.x.y * a.z.z
1380 - a.z.x * a.y.y * a.x.z,
1381 ),
1382 }
1383 }
1384 pub fn inverse(&self) -> Self {
1385 self.adjugate() * (1.0 / self.determinant())
1386 }
1387}
1388
1389impl Index<usize> for Mat4 {
1390 type Output = Vec4;
1391 fn index(&self, j: usize) -> &Vec4 {
1392 match j {
1393 0 => &self.x,
1394 1 => &self.y,
1395 2 => &self.z,
1396 3 => &self.w,
1397 _ => panic!("Mat4 column index out of range: {j}"),
1398 }
1399 }
1400}
1401impl IndexMut<usize> for Mat4 {
1402 fn index_mut(&mut self, j: usize) -> &mut Vec4 {
1403 match j {
1404 0 => &mut self.x,
1405 1 => &mut self.y,
1406 2 => &mut self.z,
1407 3 => &mut self.w,
1408 _ => panic!("Mat4 column index out of range: {j}"),
1409 }
1410 }
1411}
1412
1413impl Mul<Vec4> for Mat4 {
1414 type Output = Vec4;
1415 fn mul(self, b: Vec4) -> Vec4 {
1416 self.x * b.x + self.y * b.y + self.z * b.z + self.w * b.w
1417 }
1418}
1419impl Mul for Mat4 {
1420 type Output = Mat4;
1421 fn mul(self, b: Mat4) -> Mat4 {
1422 Mat4::from_cols(self * b.x, self * b.y, self * b.z, self * b.w)
1423 }
1424}
1425impl Mul<f64> for Mat4 {
1426 type Output = Mat4;
1427 fn mul(self, s: f64) -> Mat4 {
1428 Mat4::from_cols(self.x * s, self.y * s, self.z * s, self.w * s)
1429 }
1430}
1431impl Add for Mat4 {
1432 type Output = Mat4;
1433 fn add(self, b: Mat4) -> Mat4 {
1434 Mat4::from_cols(self.x + b.x, self.y + b.y, self.z + b.z, self.w + b.w)
1435 }
1436}
1437impl Sub for Mat4 {
1438 type Output = Mat4;
1439 fn sub(self, b: Mat4) -> Mat4 {
1440 Mat4::from_cols(self.x - b.x, self.y - b.y, self.z - b.z, self.w - b.w)
1441 }
1442}
1443impl Neg for Mat4 {
1444 type Output = Mat4;
1445 fn neg(self) -> Mat4 {
1446 Mat4::from_cols(-self.x, -self.y, -self.z, -self.w)
1447 }
1448}
1449
1450#[derive(Clone, Copy, Debug, Default, PartialEq)]
1453pub struct Mat3x4 {
1454 pub x: Vec3, pub y: Vec3, pub z: Vec3, pub w: Vec3, }
1459
1460impl Mat3x4 {
1461 #[inline]
1462 pub const fn from_cols(x: Vec3, y: Vec3, z: Vec3, w: Vec3) -> Self {
1463 Self { x, y, z, w }
1464 }
1465 pub fn identity() -> Self {
1467 Self {
1468 x: Vec3::new(1.0, 0.0, 0.0),
1469 y: Vec3::new(0.0, 1.0, 0.0),
1470 z: Vec3::new(0.0, 0.0, 1.0),
1471 w: Vec3::new(0.0, 0.0, 0.0),
1472 }
1473 }
1474 pub fn row(&self, i: usize) -> Vec4 {
1475 Vec4::new(self.x[i], self.y[i], self.z[i], self.w[i])
1476 }
1477 pub fn rotation(&self) -> Mat3 {
1479 Mat3::from_cols(self.x, self.y, self.z)
1480 }
1481 pub fn translation(&self) -> Vec3 {
1483 self.w
1484 }
1485}
1486
1487impl Index<usize> for Mat3x4 {
1488 type Output = Vec3;
1489 fn index(&self, j: usize) -> &Vec3 {
1490 match j {
1491 0 => &self.x,
1492 1 => &self.y,
1493 2 => &self.z,
1494 3 => &self.w,
1495 _ => panic!("Mat3x4 column index out of range: {j}"),
1496 }
1497 }
1498}
1499impl IndexMut<usize> for Mat3x4 {
1500 fn index_mut(&mut self, j: usize) -> &mut Vec3 {
1501 match j {
1502 0 => &mut self.x,
1503 1 => &mut self.y,
1504 2 => &mut self.z,
1505 3 => &mut self.w,
1506 _ => panic!("Mat3x4 column index out of range: {j}"),
1507 }
1508 }
1509}
1510
1511impl Mul<Vec4> for Mat3x4 {
1513 type Output = Vec3;
1514 fn mul(self, b: Vec4) -> Vec3 {
1515 self.x * b.x + self.y * b.y + self.z * b.z + self.w * b.w
1516 }
1517}
1518
1519impl Mul<Mat4> for Mat3x4 {
1521 type Output = Mat3x4;
1522 fn mul(self, b: Mat4) -> Mat3x4 {
1523 Mat3x4::from_cols(self * b.x, self * b.y, self * b.z, self * b.w)
1524 }
1525}
1526
1527impl Mul<Mat3x4> for Mat4 {
1529 type Output = Mat4;
1530 fn mul(self, b: Mat3x4) -> Mat4 {
1531 let b4 = mat3x4_to_mat4(b);
1533 self * b4
1534 }
1535}
1536
1537impl Mul<f64> for Mat3x4 {
1538 type Output = Mat3x4;
1539 fn mul(self, s: f64) -> Mat3x4 {
1540 Mat3x4::from_cols(self.x * s, self.y * s, self.z * s, self.w * s)
1541 }
1542}
1543impl Add for Mat3x4 {
1544 type Output = Mat3x4;
1545 fn add(self, b: Mat3x4) -> Mat3x4 {
1546 Mat3x4::from_cols(self.x + b.x, self.y + b.y, self.z + b.z, self.w + b.w)
1547 }
1548}
1549impl Sub for Mat3x4 {
1550 type Output = Mat3x4;
1551 fn sub(self, b: Mat3x4) -> Mat3x4 {
1552 Mat3x4::from_cols(self.x - b.x, self.y - b.y, self.z - b.z, self.w - b.w)
1553 }
1554}
1555impl Neg for Mat3x4 {
1556 type Output = Mat3x4;
1557 fn neg(self) -> Mat3x4 {
1558 Mat3x4::from_cols(-self.x, -self.y, -self.z, -self.w)
1559 }
1560}
1561
1562#[derive(Clone, Copy, Debug, Default, PartialEq)]
1564pub struct Mat4x3 {
1565 pub x: Vec4,
1566 pub y: Vec4,
1567 pub z: Vec4,
1568}
1569
1570impl Mat4x3 {
1571 #[inline]
1572 pub const fn from_cols(x: Vec4, y: Vec4, z: Vec4) -> Self {
1573 Self { x, y, z }
1574 }
1575 pub fn row(&self, i: usize) -> Vec3 {
1576 Vec3::new(self.x[i], self.y[i], self.z[i])
1577 }
1578}
1579
1580impl Mul<Vec3> for Mat4x3 {
1581 type Output = Vec4;
1582 fn mul(self, b: Vec3) -> Vec4 {
1583 self.x * b.x + self.y * b.y + self.z * b.z
1584 }
1585}
1586
1587#[derive(Clone, Copy, Debug, Default, PartialEq)]
1589pub struct Mat3x2 {
1590 pub x: Vec3,
1591 pub y: Vec3,
1592}
1593
1594impl Mat3x2 {
1595 #[inline]
1596 pub const fn from_cols(x: Vec3, y: Vec3) -> Self {
1597 Self { x, y }
1598 }
1599 pub fn row(&self, i: usize) -> Vec2 {
1600 Vec2::new(self.x[i], self.y[i])
1601 }
1602}
1603
1604impl Mul<Vec2> for Mat3x2 {
1605 type Output = Vec3;
1606 fn mul(self, b: Vec2) -> Vec3 {
1607 self.x * b.x + self.y * b.y
1608 }
1609}
1610
1611#[derive(Clone, Copy, Debug, Default, PartialEq)]
1613pub struct Mat2x3 {
1614 pub x: Vec2,
1615 pub y: Vec2,
1616 pub z: Vec2,
1617}
1618
1619impl Mat2x3 {
1620 #[inline]
1621 pub const fn from_cols(x: Vec2, y: Vec2, z: Vec2) -> Self {
1622 Self { x, y, z }
1623 }
1624}
1625
1626impl Mul<Vec3> for Mat2x3 {
1627 type Output = Vec2;
1628 fn mul(self, b: Vec3) -> Vec2 {
1629 self.x * b.x + self.y * b.y + self.z * b.z
1630 }
1631}
1632
1633pub fn mat3x4_to_mat4(m: Mat3x4) -> Mat4 {
1637 Mat4::from_cols(
1638 Vec4::new(m.x.x, m.x.y, m.x.z, 0.0),
1639 Vec4::new(m.y.x, m.y.y, m.y.z, 0.0),
1640 Vec4::new(m.z.x, m.z.y, m.z.z, 0.0),
1641 Vec4::new(m.w.x, m.w.y, m.w.z, 1.0),
1642 )
1643}
1644
1645pub fn mat4_to_mat3x4(m: Mat4) -> Mat3x4 {
1647 Mat3x4::from_cols(m.x.xyz(), m.y.xyz(), m.z.xyz(), m.w.xyz())
1648}
1649
1650#[inline]
1654pub fn cross2(a: Vec2, b: Vec2) -> f64 {
1655 a.x * b.y - a.y * b.x
1656}
1657
1658#[inline]
1660pub fn cross_sv(a: f64, b: Vec2) -> Vec2 {
1661 Vec2::new(-a * b.y, a * b.x)
1662}
1663
1664#[inline]
1666pub fn cross_vs(a: Vec2, b: f64) -> Vec2 {
1667 Vec2::new(a.y * b, -a.x * b)
1668}
1669
1670#[inline]
1672pub fn cross(a: Vec3, b: Vec3) -> Vec3 {
1673 Vec3::new(
1674 a.y * b.z - a.z * b.y,
1675 a.z * b.x - a.x * b.z,
1676 a.x * b.y - a.y * b.x,
1677 )
1678}
1679
1680#[inline]
1682pub fn dot2(a: Vec2, b: Vec2) -> f64 {
1683 a.x * b.x + a.y * b.y
1684}
1685#[inline]
1686pub fn dot(a: Vec3, b: Vec3) -> f64 {
1687 a.x * b.x + a.y * b.y + a.z * b.z
1688}
1689#[inline]
1690pub fn dot4(a: Vec4, b: Vec4) -> f64 {
1691 a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w
1692}
1693
1694#[inline]
1695pub fn length2_2(a: Vec2) -> f64 {
1696 dot2(a, a)
1697}
1698#[inline]
1699pub fn length2(a: Vec3) -> f64 {
1700 dot(a, a)
1701}
1702#[inline]
1703pub fn length2_4(a: Vec4) -> f64 {
1704 dot4(a, a)
1705}
1706
1707#[inline]
1708pub fn length_2(a: Vec2) -> f64 {
1709 length2_2(a).sqrt()
1710}
1711#[inline]
1712pub fn length(a: Vec3) -> f64 {
1713 length2(a).sqrt()
1714}
1715#[inline]
1716pub fn length_4(a: Vec4) -> f64 {
1717 length2_4(a).sqrt()
1718}
1719
1720#[inline]
1721pub fn normalize2(a: Vec2) -> Vec2 {
1722 a / length_2(a)
1723}
1724#[inline]
1725pub fn normalize(a: Vec3) -> Vec3 {
1726 a / length(a)
1727}
1728#[inline]
1729pub fn normalize4(a: Vec4) -> Vec4 {
1730 a / length_4(a)
1731}
1732
1733#[inline]
1734pub fn distance2_2(a: Vec2, b: Vec2) -> f64 {
1735 length2_2(b - a)
1736}
1737#[inline]
1738pub fn distance2(a: Vec3, b: Vec3) -> f64 {
1739 length2(b - a)
1740}
1741#[inline]
1742pub fn distance_2(a: Vec2, b: Vec2) -> f64 {
1743 length_2(b - a)
1744}
1745#[inline]
1746pub fn distance(a: Vec3, b: Vec3) -> f64 {
1747 length(b - a)
1748}
1749
1750#[inline]
1752pub fn uangle(a: Vec3, b: Vec3) -> f64 {
1753 let d = dot(a, b);
1754 if d > 1.0 {
1755 0.0
1756 } else {
1757 math::acos(if d < -1.0 { -1.0 } else { d })
1758 }
1759}
1760
1761#[inline]
1763pub fn angle(a: Vec3, b: Vec3) -> f64 {
1764 uangle(normalize(a), normalize(b))
1765}
1766
1767#[inline]
1769pub fn rot2(a: f64, v: Vec2) -> Vec2 {
1770 let (s, c) = (math::sin(a), math::cos(a));
1771 Vec2::new(v.x * c - v.y * s, v.x * s + v.y * c)
1772}
1773
1774#[inline]
1776pub fn rotx(a: f64, v: Vec3) -> Vec3 {
1777 let (s, c) = (math::sin(a), math::cos(a));
1778 Vec3::new(v.x, v.y * c - v.z * s, v.y * s + v.z * c)
1779}
1780
1781#[inline]
1783pub fn roty(a: f64, v: Vec3) -> Vec3 {
1784 let (s, c) = (math::sin(a), math::cos(a));
1785 Vec3::new(v.x * c + v.z * s, v.y, -v.x * s + v.z * c)
1786}
1787
1788#[inline]
1790pub fn rotz(a: f64, v: Vec3) -> Vec3 {
1791 let (s, c) = (math::sin(a), math::cos(a));
1792 Vec3::new(v.x * c - v.y * s, v.x * s + v.y * c, v.z)
1793}
1794
1795#[inline]
1797pub fn nlerp(a: Vec3, b: Vec3, t: f64) -> Vec3 {
1798 normalize(lerp3(a, b, t))
1799}
1800
1801#[inline]
1803pub fn slerp(a: Vec3, b: Vec3, t: f64) -> Vec3 {
1804 let th = uangle(a, b);
1805 if th == 0.0 {
1806 a
1807 } else {
1808 a * math::sin(th * (1.0 - t)) / math::sin(th) + b * math::sin(th * t) / math::sin(th)
1809 }
1810}
1811
1812#[inline]
1815pub fn abs2(a: Vec2) -> Vec2 {
1816 Vec2::new(a.x.abs(), a.y.abs())
1817}
1818#[inline]
1819pub fn abs3(a: Vec3) -> Vec3 {
1820 Vec3::new(a.x.abs(), a.y.abs(), a.z.abs())
1821}
1822#[inline]
1823pub fn abs4(a: Vec4) -> Vec4 {
1824 Vec4::new(a.x.abs(), a.y.abs(), a.z.abs(), a.w.abs())
1825}
1826
1827#[inline]
1828pub fn floor2(a: Vec2) -> Vec2 {
1829 Vec2::new(a.x.floor(), a.y.floor())
1830}
1831#[inline]
1832pub fn floor3(a: Vec3) -> Vec3 {
1833 Vec3::new(a.x.floor(), a.y.floor(), a.z.floor())
1834}
1835#[inline]
1836pub fn floor4(a: Vec4) -> Vec4 {
1837 Vec4::new(a.x.floor(), a.y.floor(), a.z.floor(), a.w.floor())
1838}
1839
1840#[inline]
1841pub fn ceil2(a: Vec2) -> Vec2 {
1842 Vec2::new(a.x.ceil(), a.y.ceil())
1843}
1844#[inline]
1845pub fn ceil3(a: Vec3) -> Vec3 {
1846 Vec3::new(a.x.ceil(), a.y.ceil(), a.z.ceil())
1847}
1848
1849#[inline]
1850pub fn round3(a: Vec3) -> Vec3 {
1851 Vec3::new(a.x.round(), a.y.round(), a.z.round())
1852}
1853#[inline]
1854pub fn round4(a: Vec4) -> Vec4 {
1855 Vec4::new(a.x.round(), a.y.round(), a.z.round(), a.w.round())
1856}
1857
1858#[inline]
1859pub fn sqrt3(a: Vec3) -> Vec3 {
1860 Vec3::new(a.x.sqrt(), a.y.sqrt(), a.z.sqrt())
1861}
1862#[inline]
1863pub fn sqrt4(a: Vec4) -> Vec4 {
1864 Vec4::new(a.x.sqrt(), a.y.sqrt(), a.z.sqrt(), a.w.sqrt())
1865}
1866
1867#[inline]
1868pub fn isfinite3(a: Vec3) -> bool {
1869 a.x.is_finite() && a.y.is_finite() && a.z.is_finite()
1870}
1871#[inline]
1872pub fn isfinite4(a: Vec4) -> bool {
1873 a.x.is_finite() && a.y.is_finite() && a.z.is_finite() && a.w.is_finite()
1874}
1875
1876#[inline]
1879pub fn min2(a: Vec2, b: Vec2) -> Vec2 {
1880 Vec2::new(a.x.min(b.x), a.y.min(b.y))
1881}
1882#[inline]
1883pub fn min3(a: Vec3, b: Vec3) -> Vec3 {
1884 Vec3::new(a.x.min(b.x), a.y.min(b.y), a.z.min(b.z))
1885}
1886#[inline]
1887pub fn min4(a: Vec4, b: Vec4) -> Vec4 {
1888 Vec4::new(a.x.min(b.x), a.y.min(b.y), a.z.min(b.z), a.w.min(b.w))
1889}
1890
1891#[inline]
1892pub fn max2(a: Vec2, b: Vec2) -> Vec2 {
1893 Vec2::new(a.x.max(b.x), a.y.max(b.y))
1894}
1895#[inline]
1896pub fn max3(a: Vec3, b: Vec3) -> Vec3 {
1897 Vec3::new(a.x.max(b.x), a.y.max(b.y), a.z.max(b.z))
1898}
1899#[inline]
1900pub fn max4(a: Vec4, b: Vec4) -> Vec4 {
1901 Vec4::new(a.x.max(b.x), a.y.max(b.y), a.z.max(b.z), a.w.max(b.w))
1902}
1903
1904#[inline]
1906pub fn clamp3(x: Vec3, lo: Vec3, hi: Vec3) -> Vec3 {
1907 Vec3::new(
1908 x.x.max(lo.x).min(hi.x),
1909 x.y.max(lo.y).min(hi.y),
1910 x.z.max(lo.z).min(hi.z),
1911 )
1912}
1913#[inline]
1914pub fn clamp4(x: Vec4, lo: Vec4, hi: Vec4) -> Vec4 {
1915 Vec4::new(
1916 x.x.max(lo.x).min(hi.x),
1917 x.y.max(lo.y).min(hi.y),
1918 x.z.max(lo.z).min(hi.z),
1919 x.w.max(lo.w).min(hi.w),
1920 )
1921}
1922
1923#[inline]
1925pub fn clamp_s(x: f64, lo: f64, hi: f64) -> f64 {
1926 x.max(lo).min(hi)
1927}
1928
1929#[inline]
1931pub fn lerp2(a: Vec2, b: Vec2, t: f64) -> Vec2 {
1932 a * (1.0 - t) + b * t
1933}
1934#[inline]
1935pub fn lerp3(a: Vec3, b: Vec3, t: f64) -> Vec3 {
1936 a * (1.0 - t) + b * t
1937}
1938#[inline]
1939pub fn lerp4(a: Vec4, b: Vec4, t: f64) -> Vec4 {
1940 a * (1.0 - t) + b * t
1941}
1942
1943#[inline]
1945pub fn minelem2(a: Vec2) -> f64 {
1946 a.x.min(a.y)
1947}
1948#[inline]
1949pub fn minelem3(a: Vec3) -> f64 {
1950 a.x.min(a.y).min(a.z)
1951}
1952#[inline]
1953pub fn minelem4(a: Vec4) -> f64 {
1954 a.x.min(a.y).min(a.z).min(a.w)
1955}
1956
1957#[inline]
1958pub fn maxelem2(a: Vec2) -> f64 {
1959 a.x.max(a.y)
1960}
1961#[inline]
1962pub fn maxelem3(a: Vec3) -> f64 {
1963 a.x.max(a.y).max(a.z)
1964}
1965#[inline]
1966pub fn maxelem4(a: Vec4) -> f64 {
1967 a.x.max(a.y).max(a.z).max(a.w)
1968}
1969
1970#[inline]
1971pub fn sum3(a: Vec3) -> f64 {
1972 a.x + a.y + a.z
1973}
1974#[inline]
1975pub fn sum4(a: Vec4) -> f64 {
1976 a.x + a.y + a.z + a.w
1977}
1978
1979#[inline]
1981pub fn argmin3(a: Vec3) -> usize {
1982 if a.x <= a.y && a.x <= a.z {
1983 0
1984 } else if a.y <= a.z {
1985 1
1986 } else {
1987 2
1988 }
1989}
1990#[inline]
1992pub fn argmax3(a: Vec3) -> usize {
1993 if a.x >= a.y && a.x >= a.z {
1994 0
1995 } else if a.y >= a.z {
1996 1
1997 } else {
1998 2
1999 }
2000}
2001#[inline]
2002pub fn argmax4(a: Vec4) -> usize {
2003 let mut j = 0usize;
2004 for i in 1..4 {
2005 if a[i] > a[j] {
2006 j = i;
2007 }
2008 }
2009 j
2010}
2011
2012#[inline]
2016pub fn qconj(q: Quat) -> Quat {
2017 Vec4::new(-q.x, -q.y, -q.z, q.w)
2018}
2019
2020#[inline]
2022pub fn qinv(q: Quat) -> Quat {
2023 qconj(q) / length2_4(q)
2024}
2025
2026#[inline]
2028pub fn qmul(a: Quat, b: Quat) -> Quat {
2029 Quat::new(
2030 a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y,
2031 a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z,
2032 a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x,
2033 a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z,
2034 )
2035}
2036
2037#[inline]
2039pub fn qxdir(q: Quat) -> Vec3 {
2040 Vec3::new(
2041 q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z,
2042 (q.x * q.y + q.z * q.w) * 2.0,
2043 (q.z * q.x - q.y * q.w) * 2.0,
2044 )
2045}
2046
2047#[inline]
2049pub fn qydir(q: Quat) -> Vec3 {
2050 Vec3::new(
2051 (q.x * q.y - q.z * q.w) * 2.0,
2052 q.w * q.w - q.x * q.x + q.y * q.y - q.z * q.z,
2053 (q.y * q.z + q.x * q.w) * 2.0,
2054 )
2055}
2056
2057#[inline]
2059pub fn qzdir(q: Quat) -> Vec3 {
2060 Vec3::new(
2061 (q.z * q.x + q.y * q.w) * 2.0,
2062 (q.y * q.z - q.x * q.w) * 2.0,
2063 q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z,
2064 )
2065}
2066
2067#[inline]
2069pub fn qmat(q: Quat) -> Mat3 {
2070 Mat3::from_cols(qxdir(q), qydir(q), qzdir(q))
2071}
2072
2073#[inline]
2075pub fn qrot(q: Quat, v: Vec3) -> Vec3 {
2076 qxdir(q) * v.x + qydir(q) * v.y + qzdir(q) * v.z
2077}
2078
2079#[inline]
2081pub fn qangle(q: Quat) -> f64 {
2082 math::atan2(length(q.xyz()), q.w) * 2.0
2083}
2084
2085#[inline]
2087pub fn qaxis(q: Quat) -> Vec3 {
2088 normalize(q.xyz())
2089}
2090
2091#[inline]
2093pub fn qnlerp(a: Quat, b: Quat, t: f64) -> Quat {
2094 let b2 = if dot4(a, b) < 0.0 { -b } else { b };
2095 normalize4(lerp4(a, b2, t))
2096}
2097
2098#[inline]
2100pub fn qslerp(a: Quat, b: Quat, t: f64) -> Quat {
2101 let b2 = if dot4(a, b) < 0.0 { -b } else { b };
2102 let th = {
2104 let d = dot4(a, b2).max(-1.0).min(1.0);
2105 if d > 1.0 {
2106 0.0
2107 } else {
2108 math::acos(d)
2109 }
2110 };
2111 if th == 0.0 {
2112 a
2113 } else {
2114 a * math::sin(th * (1.0 - t)) / math::sin(th) + b2 * math::sin(th * t) / math::sin(th)
2115 }
2116}
2117
2118#[inline]
2120pub fn rotation_quat_axis_angle(axis: Vec3, angle: f64) -> Quat {
2121 Quat::new(
2122 axis.x * math::sin(angle / 2.0),
2123 axis.y * math::sin(angle / 2.0),
2124 axis.z * math::sin(angle / 2.0),
2125 math::cos(angle / 2.0),
2126 )
2127}
2128
2129pub fn rotation_quat_vec(orig: Vec3, dest: Vec3) -> Quat {
2131 let cos_theta = dot(orig, dest);
2132 let eps = f64::EPSILON;
2133 if cos_theta >= 1.0 - eps {
2134 return Quat::new(0.0, 0.0, 0.0, 1.0);
2135 }
2136 if cos_theta < -1.0 + eps {
2137 let mut axis = cross(Vec3::new(0.0, 0.0, 1.0), orig);
2138 if length2(axis) < eps {
2139 axis = cross(Vec3::new(1.0, 0.0, 0.0), orig);
2140 }
2141 return rotation_quat_axis_angle(normalize(axis), std::f64::consts::PI);
2142 }
2143 let axis = cross(orig, dest);
2144 let s = ((1.0 + cos_theta) * 2.0).sqrt();
2145 Quat::new(axis.x / s, axis.y / s, axis.z / s, s * 0.5)
2146}
2147
2148pub fn rotation_quat_mat(m: Mat3) -> Quat {
2150 let q = Vec4::new(
2151 m.x.x - m.y.y - m.z.z,
2152 m.y.y - m.x.x - m.z.z,
2153 m.z.z - m.x.x - m.y.y,
2154 m.x.x + m.y.y + m.z.z,
2155 );
2156 let s = [
2158 Vec4::new(1.0, m.x.y + m.y.x, m.z.x + m.x.z, m.y.z - m.z.y),
2159 Vec4::new(m.x.y + m.y.x, 1.0, m.y.z + m.z.y, m.z.x - m.x.z),
2160 Vec4::new(m.x.z + m.z.x, m.y.z + m.z.y, 1.0, m.x.y - m.y.x),
2161 Vec4::new(m.y.z - m.z.y, m.z.x - m.x.z, m.x.y - m.y.x, 1.0),
2162 ];
2163 let idx = argmax4(q);
2164 let sq = Vec4::new(
2166 (0.0f64).max(1.0 + q.x).sqrt(),
2167 (0.0f64).max(1.0 + q.y).sqrt(),
2168 (0.0f64).max(1.0 + q.z).sqrt(),
2169 (0.0f64).max(1.0 + q.w).sqrt(),
2170 );
2171 let n = normalize4(sq);
2172 let si = s[idx];
2173 Vec4::new(
2174 n.x.copysign(si.x),
2175 n.y.copysign(si.y),
2176 n.z.copysign(si.z),
2177 n.w.copysign(si.w),
2178 )
2179}
2180
2181pub fn translation_matrix(t: Vec3) -> Mat4 {
2184 Mat4::from_cols(
2185 Vec4::new(1.0, 0.0, 0.0, 0.0),
2186 Vec4::new(0.0, 1.0, 0.0, 0.0),
2187 Vec4::new(0.0, 0.0, 1.0, 0.0),
2188 Vec4::new(t.x, t.y, t.z, 1.0),
2189 )
2190}
2191
2192pub fn rotation_matrix(q: Quat) -> Mat4 {
2193 Mat4::from_cols(
2194 Vec4::from((qxdir(q), 0.0)),
2195 Vec4::from((qydir(q), 0.0)),
2196 Vec4::from((qzdir(q), 0.0)),
2197 Vec4::new(0.0, 0.0, 0.0, 1.0),
2198 )
2199}
2200
2201pub fn scaling_matrix(s: Vec3) -> Mat4 {
2202 Mat4::from_cols(
2203 Vec4::new(s.x, 0.0, 0.0, 0.0),
2204 Vec4::new(0.0, s.y, 0.0, 0.0),
2205 Vec4::new(0.0, 0.0, s.z, 0.0),
2206 Vec4::new(0.0, 0.0, 0.0, 1.0),
2207 )
2208}
2209
2210pub fn pose_matrix(q: Quat, p: Vec3) -> Mat4 {
2211 Mat4::from_cols(
2212 Vec4::from((qxdir(q), 0.0)),
2213 Vec4::from((qydir(q), 0.0)),
2214 Vec4::from((qzdir(q), 0.0)),
2215 Vec4::new(p.x, p.y, p.z, 1.0),
2216 )
2217}
2218
2219pub fn outerprod(a: Vec3, b: Vec3) -> Mat3 {
2221 Mat3::from_cols(a * b.x, a * b.y, a * b.z)
2222}
2223
2224fn hash_f64<H: Hasher>(v: f64, state: &mut H) {
2228 v.to_bits().hash(state);
2230}
2231
2232impl Hash for Vec2 {
2233 fn hash<H: Hasher>(&self, state: &mut H) {
2234 hash_f64(self.x, state);
2235 let mut h2 = std::collections::hash_map::DefaultHasher::new();
2237 hash_f64(self.y, &mut h2);
2238 state.write_u64(std::hash::BuildHasher::build_hasher(&std::collections::hash_map::RandomState::new()).finish() ^ (std::hash::Hasher::finish(&h2) << 1));
2239 }
2240}
2241
2242impl Hash for Vec3 {
2244 fn hash<H: Hasher>(&self, state: &mut H) {
2245 self.x.to_bits().hash(state);
2246 self.y.to_bits().hash(state);
2247 self.z.to_bits().hash(state);
2248 }
2249}
2250
2251impl Hash for Vec4 {
2252 fn hash<H: Hasher>(&self, state: &mut H) {
2253 self.x.to_bits().hash(state);
2254 self.y.to_bits().hash(state);
2255 self.z.to_bits().hash(state);
2256 self.w.to_bits().hash(state);
2257 }
2258}
2259
2260#[cfg(test)]
2264#[path = "linalg_tests.rs"]
2265mod tests;