Skip to main content

maths_rs/
mat.rs

1
2use crate::vec::*;
3use crate::num::*;
4use crate::quat::*;
5
6use std::ops::Index;
7use std::ops::IndexMut;
8use std::ops::Mul;
9use std::ops::MulAssign;
10use std::ops::Deref;
11use std::ops::DerefMut;
12
13use std::cmp::PartialEq;
14
15use std::fmt::Display;
16use std::fmt::Formatter;
17
18/// row major matrix index layouts
19///
20/// Mat2:
21/// 00 01
22/// 02 03
23///
24/// Mat3:
25/// 00 01 02
26/// 03 04 05
27/// 06 07 08
28///
29/// Mat34:
30/// 00 01 02 03
31/// 04 05 06 07
32/// 08 09 10 11
33///
34/// Mat44:
35/// 00 01 02 03
36/// 04 05 06 07
37/// 08 09 10 11
38/// 12 13 14 15
39
40/// creates the basic generic traits for row-major matrices
41macro_rules! mat_impl {
42    ($MatN:ident, $rows:expr, $cols:expr, $elems:expr,
43        $RowVecN:ident { $($row_field:ident, $row_field_index:expr),* },
44        $ColVecN:ident { $($col_field:ident, $col_field_index:expr),* } ) => {
45
46        #[cfg_attr(feature="serde", derive(serde::Serialize, serde::Deserialize))]
47        #[cfg_attr(feature="hash", derive(Hash))]
48        #[derive(Debug, Copy, Clone)]
49        #[repr(C)]
50        pub struct $MatN<T> {
51            pub m: [T; $elems]
52        }
53
54        /// index into matrix with tuple \[(row, column)\]
55        impl<T> Index<(usize, usize)> for $MatN<T> {
56            type Output = T;
57            fn index(&self, rc: (usize, usize)) -> &Self::Output {
58                &self.m[rc.0 * $cols + rc.1]
59            }
60        }
61
62        /// mutably index into matrix with tuple \[(row, column)\]
63        impl<T> IndexMut<(usize, usize)> for $MatN<T> {
64            fn index_mut(&mut self, rc: (usize, usize)) -> &mut Self::Output {
65                &mut self.m[rc.0 * $cols + rc.1]
66            }
67        }
68
69        /// index into matrix raw array single \[index\]
70        impl<T> Index<usize> for $MatN<T> {
71            type Output = T;
72            fn index(&self, index: usize) -> &Self::Output {
73                &self.m[index]
74            }
75        }
76
77        /// mutably index into matrix raw array with single \[index\]
78        impl<T> IndexMut<usize> for $MatN<T> {
79            fn index_mut(&mut self, index: usize) -> &mut Self::Output {
80                &mut self.m[index]
81            }
82        }
83
84        /// deref matrix as a slice of T
85        impl<T> Deref for $MatN<T> where T: Number {
86            type Target = [T];
87            fn deref(&self) -> &Self::Target {
88                // SAFETY: `self.m` is a contiguous array of $elems elements of type T.
89                // The pointer to the first element is valid for $elems reads and the
90                // lifetime is bounded by `&self`.
91                unsafe {
92                    std::slice::from_raw_parts(&self.m[0], $elems)
93                }
94            }
95        }
96
97        /// mutably deref matrix as a slice of T
98        impl<T> DerefMut for $MatN<T> where T: Number {
99            fn deref_mut(&mut self) -> &mut [T] {
100                // SAFETY: `self.m` is a contiguous array of $elems elements of type T.
101                // The pointer to the first element is valid for $elems writes.
102                // Exclusive access is guaranteed by `&mut self`.
103                unsafe {
104                    std::slice::from_raw_parts_mut(&mut self.m[0], $elems)
105                }
106            }
107        }
108
109        /// displays like:
110        /// [1.0, 0.0, 0.0]
111        /// [0.0, 1.0, 1.0]
112        /// [0.0, 0.0, 1.0]
113        impl<T> Display for $MatN<T> where T: Display {
114            fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
115                let mut output = String::from("");
116                for r in 0..$rows {
117                    output += &String::from("[");
118                    for c in 0..$cols {
119                        output += &self[(r, c)].to_string();
120                        if c < $cols-1 {
121                            output += &String::from(", ");
122                        }
123
124                    }
125                    output += "]";
126                    if r < $rows-1 {
127                        output += "\n";
128                    }
129                }
130                write!(f, "{}", output)
131            }
132        }
133
134        /// default to identity matrix
135        impl<T> Default for $MatN<T> where T: Number {
136            fn default() -> Self {
137                Self::identity()
138            }
139        }
140
141        impl<T> Eq for $MatN<T> where T: Eq  {}
142        impl<T> PartialEq for $MatN<T> where T: PartialEq  {
143            fn eq(&self, other: &Self) -> bool {
144                for i in 0..$elems {
145                    if self.m[i] != other.m[i] {
146                        return false;
147                    }
148                }
149                true
150            }
151        }
152
153        impl<T> $MatN<T> where T: Float + FloatOps<T> {
154            /// compare if matrices are approximately equal to account for floating point precision
155            pub fn approx(lhs: Self, rhs: Self, eps: T) -> bool {
156                for i in 0..$elems {
157                    if !T::approx(lhs.m[i], rhs.m[i], eps) {
158                        return false;
159                    }
160                }
161                true
162            }
163        }
164
165        impl<T> $MatN<T> where T: Number {
166            /// initialise matrix to all zero's
167            pub fn zero() -> $MatN<T> {
168                $MatN {
169                    m: [T::zero(); $elems]
170                }
171            }
172
173            /// initialise matrix to identity
174            pub fn identity() -> $MatN<T> {
175                unsafe {
176                    let mut mat : $MatN<T> = std::mem::zeroed();
177                    for r in 0..$rows {
178                        for c in 0..$cols {
179                            if c == r {
180                                mat.set(r, c, T::one());
181                            }
182                        }
183                    }
184                    mat
185                }
186            }
187
188            pub const fn get_num_rows(&self) -> usize {
189                $rows
190            }
191
192            pub const fn get_num_columns(&self) -> usize {
193                $cols
194            }
195
196            /// get single element from the matrix at row, column index
197            pub fn at(self, row: u32, column: u32) -> T {
198                let urow = row as usize;
199                let ucol = column as usize;
200                self.m[urow * $cols + ucol]
201            }
202
203            /// set a single element of the matrix at row, column index
204            pub fn set(&mut self, row: u32, column: u32, value: T) {
205                let urow = row as usize;
206                let ucol = column as usize;
207                self.m[urow * $cols + ucol] = value
208            }
209
210            /// gets a single row of the matrix in n sized vec where in is the column count of the matrix
211            pub fn get_row(self, row: u32) -> $RowVecN<T> {
212                let urow = row as usize;
213                $RowVecN {
214                    $($row_field: self.m[urow * $cols + $row_field_index],)+
215                }
216            }
217
218            /// sets a single row of the matrix by an n sized vec, where n is the column count of the matrix
219            pub fn set_row(&mut self, row: u32, value: $RowVecN<T>) {
220                let urow = row as usize;
221                $(self.m[urow * $cols + $row_field_index] = value.$row_field;)+
222            }
223
224            /// gets a single column of the matrix in n sized vec where in is the row count of the matrix
225            pub fn get_column(self, column: u32) -> $ColVecN<T> {
226                let ucol = column as usize;
227                $ColVecN {
228                    $($col_field: self.m[$col_field_index * $cols + ucol],)+
229                }
230            }
231
232            /// sets a single column of the matrix by an n sized vec, where n is the row count of the matrix
233            pub fn set_column(&mut self, column: u32, value: $ColVecN<T>) {
234                let ucol = column as usize;
235                $(self.m[$col_field_index * $cols + ucol] = value.$col_field;)+
236            }
237
238            /// returns a slice T of the matrix
239            pub fn as_slice(&self) -> &[T] {
240                // SAFETY: `self.m` is a contiguous array of $elems elements of type T.
241                // The pointer to the first element is valid for $elems reads and the
242                // lifetime is bounded by `&self`.
243                unsafe {
244                    std::slice::from_raw_parts(&self.m[0], $elems)
245                }
246            }
247
248            /// returns a mutable slice T of the matrix
249            pub fn as_mut_slice(&mut self) -> &mut [T] {
250                // SAFETY: `self.m` is a contiguous array of $elems elements of type T.
251                // The pointer to the first element is valid for $elems writes.
252                // Exclusive access is guaranteed by `&mut self`.
253                unsafe {
254                    std::slice::from_raw_parts_mut(&mut self.m[0], $elems)
255                }
256            }
257
258            /// returns a slice of bytes for the matrix
259            pub fn as_u8_slice(&self) -> &[u8] {
260                // SAFETY: Any initialized memory can be viewed as bytes. T: Number ensures all
261                // bytes are initialized. The cast to *const u8 is valid since u8 has alignment 1,
262                // and the length is the exact byte size of the struct.
263                unsafe {
264                    std::slice::from_raw_parts((&self.m[0] as *const T) as *const u8, std::mem::size_of::<$MatN<T>>())
265                }
266            }
267        }
268    }
269}
270
271macro_rules! mat_cast {
272    ($MatN:ident, $count:expr, $t:ident, $u:ident) => {
273        impl From<$MatN<$u>> for $MatN<$t> {
274            /// cast matrix from type u to type t
275            fn from(other: $MatN<$u>) -> $MatN<$t> {
276                unsafe {
277                    let mut mm : $MatN<$t> = std::mem::zeroed();
278                    for i in 0..$count {
279                        mm.m[i] = other.m[i] as $t;
280                    }
281                    mm
282                }
283            }
284        }
285
286        impl From<$MatN<$t>> for $MatN<$u> {
287            /// cast matrix from type t to type u
288            fn from(other: $MatN<$t>) -> $MatN<$u> {
289                unsafe {
290                    let mut mm : $MatN<$u> = std::mem::zeroed();
291                    for i in 0..$count {
292                        mm.m[i] = other.m[i] as $u;
293                    }
294                    mm
295                }
296            }
297        }
298    }
299}
300
301#[cfg(feature = "casts")]
302mat_cast!(Mat2, 4, f32, f64);
303
304#[cfg(feature = "casts")]
305mat_cast!(Mat3, 9, f32, f64);
306
307#[cfg(feature = "casts")]
308mat_cast!(Mat34, 12, f32, f64);
309
310#[cfg(feature = "casts")]
311mat_cast!(Mat4, 16, f32, f64);
312
313//
314// From
315//
316
317/// intialse matrix from tuple of 4 elements
318impl<T> From<(T, T, T, T)> for Mat2<T> where T: Number {
319    fn from(other: (T, T, T, T)) -> Mat2<T> {
320        Mat2 {
321            m: [
322                other.0, other.1,
323                other.2, other.3
324            ]
325        }
326    }
327}
328
329/// constructs Mat2 from tuple of 2 2D row vectors
330impl<T> From<(Vec2<T>, Vec2<T>)> for Mat2<T> where T: Number {
331    fn from(other: (Vec2<T>, Vec2<T>)) -> Mat2<T> {
332        Mat2 {
333            m: [
334                other.0.x, other.0.y,
335                other.1.x, other.1.y
336            ]
337        }
338    }
339}
340
341/// constructs Mat2 from 3x3 matrix truncating the 3rd row and column
342impl<T> From<Mat3<T>> for Mat2<T> where T: Number {
343    fn from(other: Mat3<T>) -> Mat2<T> {
344        Mat2 {
345            m: [
346                other.m[0], other.m[1],
347                other.m[3], other.m[4],
348            ]
349        }
350    }
351}
352
353/// constructs Mat2 from 3x4 matrix truncating the 3rd row and 3rd and 4th column
354impl<T> From<Mat34<T>> for Mat2<T> where T: Number {
355    fn from(other: Mat34<T>) -> Mat2<T> {
356        Mat2 {
357            m: [
358                other.m[0], other.m[1],
359                other.m[4], other.m[5],
360            ]
361        }
362    }
363}
364
365/// constructs Mat2 from 3x4 matrix truncating the 3rd and 4th row and 3rd and 4th column
366impl<T> From<Mat4<T>> for Mat2<T> where T: Number {
367    fn from(other: Mat4<T>) -> Mat2<T> {
368        Mat2 {
369            m: [
370                other.m[0], other.m[1],
371                other.m[4], other.m[5],
372            ]
373        }
374    }
375}
376
377/// constructs Mat3 from a Mat2 initialising the 2x2 part and setting the 3rd column and row to identity
378impl<T> From<Mat2<T>> for Mat3<T> where T: Number {
379    fn from(other: Mat2<T>) -> Mat3<T> {
380        Mat3 {
381            m: [
382                other.m[0], other.m[1], T::zero(),
383                other.m[2], other.m[3], T::zero(),
384                T::zero(), T::zero(), T::one()
385            ]
386        }
387    }
388}
389
390/// construct a Mat3 from a Mat34 initialising the 3x3 part and truncation the 4th column
391impl<T> From<Mat34<T>> for Mat3<T> where T: Number {
392    fn from(other: Mat34<T>) -> Mat3<T> {
393        Mat3 {
394            m: [
395                other.m[0], other.m[1], other.m[2],
396                other.m[4], other.m[5], other.m[6],
397                other.m[8], other.m[9], other.m[10],
398            ]
399        }
400    }
401}
402
403/// construct a Mat3 from a Mat44 initialising the 3x3 part and truncation the 4th row and column
404impl<T> From<Mat4<T>> for Mat3<T> where T: Number {
405    fn from(other: Mat4<T>) -> Mat3<T> {
406        Mat3 {
407            m: [
408                other.m[0], other.m[1], other.m[2],
409                other.m[4], other.m[5], other.m[6],
410                other.m[8], other.m[9], other.m[10],
411            ]
412        }
413    }
414}
415
416/// construct a Mat3 from tuple of 9 elements
417impl<T> From<(T, T, T, T, T, T, T, T, T)> for Mat3<T> where T: Number {
418    fn from(other: (T, T, T, T, T, T, T, T, T)) -> Mat3<T> {
419        Mat3 {
420            m: [
421                other.0, other.1, other.2,
422                other.3, other.4, other.5,
423                other.6, other.7, other.8,
424            ]
425        }
426    }
427}
428
429/// constructs Mat3 from tuple of 3 3D row vectors
430impl<T> From<(Vec3<T>, Vec3<T>, Vec3<T>)> for Mat3<T> where T: Number {
431    fn from(other: (Vec3<T>, Vec3<T>, Vec3<T>)) -> Mat3<T> {
432        Mat3 {
433            m: [
434                other.0.x, other.0.y, other.0.z,
435                other.1.x, other.1.y, other.1.z,
436                other.2.x, other.2.y, other.2.z,
437            ]
438        }
439    }
440}
441
442/// constucts a mat3 rotation matrix from quaternion
443impl<T> From<Quat<T>> for Mat3<T> where T: Float + SignedNumber + FloatOps<T> + NumberOps<T> + SignedNumberOps<T> {
444    fn from(other: Quat<T>) -> Mat3<T> {
445        other.get_matrix()
446    }
447}
448
449/// construct a Mat34 from a Mat2 initialising the 2x2 part and setting the 3rd row to identity
450impl<T> From<Mat2<T>> for Mat34<T> where T: Number {
451    fn from(other: Mat2<T>) -> Mat34<T> {
452        Mat34 {
453            m: [
454                other.m[0], other.m[1], T::zero(), T::zero(),
455                other.m[2], other.m[3], T::zero(), T::zero(),
456                T::zero(), T::zero(), T::one(), T::zero(),
457            ]
458        }
459    }
460}
461
462/// construct a Mat34 from a Mat3 initialising the 3x3 part and setting the 4th row to zero
463impl<T> From<Mat3<T>> for Mat34<T> where T: Number {
464    fn from(other: Mat3<T>) -> Mat34<T> {
465        Mat34 {
466            m: [
467                other.m[0], other.m[1], other.m[2], T::zero(),
468                other.m[3], other.m[4], other.m[5], T::zero(),
469                other.m[6], other.m[7], other.m[8], T::zero(),
470            ]
471        }
472    }
473}
474
475/// constucts a mat34 rotation matrix from quaternion
476impl<T> From<Quat<T>> for Mat34<T> where T: Float + SignedNumber + FloatOps<T> + NumberOps<T> + SignedNumberOps<T> {
477    fn from(other: Quat<T>) -> Mat34<T> {
478        Mat34::from(other.get_matrix())
479    }
480}
481
482/// construct a Mat34 from a Mat4 initialising the 3x4 part and truncating the 4th row
483impl<T> From<Mat4<T>> for Mat34<T> where T: Number {
484    fn from(other: Mat4<T>) -> Mat34<T> {
485        Mat34 {
486            m: [
487                other.m[0], other.m[1], other.m[2], other.m[3],
488                other.m[4], other.m[5], other.m[6], other.m[7],
489                other.m[8], other.m[9], other.m[10], other.m[11],
490            ]
491        }
492    }
493}
494
495/// construct a Mat34 from tuple of 12 elements
496impl<T> From<(T, T, T, T, T, T, T, T, T, T, T, T)> for Mat34<T> where T: Number {
497    fn from(other: (T, T, T, T, T, T, T, T, T, T, T, T)) -> Mat34<T> {
498        Mat34 {
499            m: [
500                other.0, other.1, other.2, other.3,
501                other.4, other.5, other.6, other.7,
502                other.8, other.9, other.10, other.11
503            ]
504        }
505    }
506}
507
508/// constructs Mat34 from tuple of 3 4D row vectors
509impl<T> From<(Vec4<T>, Vec4<T>, Vec4<T>)> for Mat34<T> where T: Number {
510    fn from(other: (Vec4<T>, Vec4<T>, Vec4<T>)) -> Mat34<T> {
511        Mat34 {
512            m: [
513                other.0.x, other.0.y, other.0.z, other.0.w,
514                other.1.x, other.1.y, other.1.z, other.1.w,
515                other.2.x, other.2.y, other.2.z, other.2.w,
516            ]
517        }
518    }
519}
520
521/// construct a Mat4 from a Mat2 initialising the 2x2 part and setting the 3rd and 4th rows to identity
522impl<T> From<Mat2<T>> for Mat4<T> where T: Number {
523    fn from(other: Mat2<T>) -> Mat4<T> {
524        Mat4 {
525            m: [
526                other.m[0], other.m[1], T::zero(), T::zero(),
527                other.m[2], other.m[3], T::zero(), T::zero(),
528                T::zero(), T::zero(), T::one(), T::zero(),
529                T::zero(), T::zero(), T::zero(), T::one()
530            ]
531        }
532    }
533}
534
535/// construct a Mat4 from a Mat3 initialising the 3x3 part and setting the 4th row/column to identity
536impl<T> From<Mat3<T>> for Mat4<T> where T: Number {
537    fn from(other: Mat3<T>) -> Mat4<T> {
538        Mat4 {
539            m: [
540                other.m[0], other.m[1], other.m[2], T::zero(),
541                other.m[3], other.m[4], other.m[5], T::zero(),
542                other.m[6], other.m[7], other.m[8], T::zero(),
543                T::zero(), T::zero(), T::zero(), T::one()
544            ]
545        }
546    }
547}
548
549/// construct a Mat4 from a Mat34 initialising the 3x4 part and setting the 4th row to identity
550impl<T> From<Mat34<T>> for Mat4<T> where T: Number {
551    fn from(other: Mat34<T>) -> Mat4<T> {
552        Mat4 {
553            m: [
554                other.m[0], other.m[1], other.m[2], other.m[3],
555                other.m[4], other.m[5], other.m[6], other.m[7],
556                other.m[8], other.m[9], other.m[10], other.m[11],
557                T::zero(), T::zero(), T::zero(), T::one()
558            ]
559        }
560    }
561}
562
563/// construct a Mat4 from tuple of 16 elements
564impl<T> From<(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)> for Mat4<T> where T: Number {
565    fn from(other: (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)) -> Mat4<T> {
566        Mat4 {
567            m: [
568                other.0, other.1, other.2, other.3,
569                other.4, other.5, other.6, other.7,
570                other.8, other.9, other.10, other.11,
571                other.12, other.13, other.14, other.15
572            ]
573        }
574    }
575}
576
577/// constructs Mat4 from tuple of 4 4D row vectors
578impl<T> From<(Vec4<T>, Vec4<T>, Vec4<T>, Vec4<T>)> for Mat4<T> where T: Number {
579    fn from(other: (Vec4<T>, Vec4<T>, Vec4<T>, Vec4<T>)) -> Mat4<T> {
580        Mat4 {
581            m: [
582                other.0.x, other.0.y, other.0.z, other.0.w,
583                other.1.x, other.1.y, other.1.z, other.1.w,
584                other.2.x, other.2.y, other.2.z, other.2.w,
585                other.3.x, other.3.y, other.3.z, other.3.w,
586            ]
587        }
588    }
589}
590
591/// constucts a mat4 rotation matrix from quaternion
592impl<T> From<Quat<T>> for Mat4<T> where T: Float + SignedNumber + FloatOps<T> + NumberOps<T> + SignedNumberOps<T> {
593    fn from(other: Quat<T>) -> Mat4<T> {
594        Mat4::from(other.get_matrix())
595    }
596}
597
598//
599// Mat2 Mul
600//
601
602/// multiply 2x2 * 2x2 matrix
603fn mul2x2<T: Number>(lhs: Mat2<T>, rhs: Mat2<T>) -> Mat2<T> {
604    Mat2 {
605        m: [
606            lhs.m[0] * rhs.m[0] + lhs.m[1] * rhs.m[2],
607            lhs.m[0] * rhs.m[1] + lhs.m[1] * rhs.m[3],
608            lhs.m[2] * rhs.m[0] + lhs.m[3] * rhs.m[2],
609            lhs.m[2] * rhs.m[1] + lhs.m[3] * rhs.m[3],
610        ]
611    }
612}
613
614impl<T> Mul<Self> for Mat2<T> where T: Number {
615    type Output = Self;
616    fn mul(self, rhs: Mat2<T>) -> Self::Output {
617        mul2x2(self, rhs)
618    }
619}
620
621impl<T> MulAssign<Self> for Mat2<T> where T: Number {
622    fn mul_assign(&mut self, rhs: Mat2<T>) {
623        *self = mul2x2(*self, rhs);
624    }
625}
626
627impl<T> MulAssign<&Self> for Mat2<T> where T: Number {
628    fn mul_assign(&mut self, rhs: &Self) {
629        *self = mul2x2(*self, *rhs);
630    }
631}
632
633impl<T> Mul<Vec2<T>> for Mat2<T> where T: Number {
634    type Output = Vec2<T>;
635    fn mul(self, rhs: Vec2<T>) -> Self::Output {
636        Vec2 {
637            x: self.m[0] * rhs.x + self.m[1] * rhs.y,
638            y: self.m[2] * rhs.x + self.m[3] * rhs.y
639        }
640    }
641}
642
643// mul refs
644impl<T> Mul<&Self> for Mat2<T> where T: Number {
645    type Output = Self;
646    fn mul(self, rhs: &Self) -> Self::Output {
647        mul2x2(self, *rhs)
648    }
649}
650
651impl<T> Mul<Mat2<T>> for &Mat2<T> where T: Number {
652    type Output = Mat2<T>;
653    fn mul(self, rhs: Mat2<T>) -> Self::Output {
654        mul2x2(*self, rhs)
655    }
656}
657
658impl<T> Mul<Self> for &Mat2<T> where T: Number {
659    type Output = Mat2<T>;
660    fn mul(self, rhs: Self) -> Self::Output {
661        mul2x2(*self, *rhs)
662    }
663}
664
665impl<T> Mul<&Vec2<T>> for Mat2<T> where T: Number {
666    type Output = Vec2<T>;
667    fn mul(self, rhs: &Vec2<T>) -> Self::Output {
668        Vec2 {
669            x: self.m[0] * rhs.x + self.m[1] * rhs.y,
670            y: self.m[2] * rhs.x + self.m[3] * rhs.y
671        }
672    }
673}
674
675impl<T> Mul<Vec2<T>> for &Mat2<T> where T: Number {
676    type Output = Vec2<T>;
677    fn mul(self, rhs: Vec2<T>) -> Self::Output {
678        Vec2 {
679            x: self.m[0] * rhs.x + self.m[1] * rhs.y,
680            y: self.m[2] * rhs.x + self.m[3] * rhs.y
681        }
682    }
683}
684
685impl<T> Mul<&Vec2<T>> for &Mat2<T> where T: Number {
686    type Output = Vec2<T>;
687    fn mul(self, rhs: &Vec2<T>) -> Self::Output {
688        Vec2 {
689            x: self.m[0] * rhs.x + self.m[1] * rhs.y,
690            y: self.m[2] * rhs.x + self.m[3] * rhs.y
691        }
692    }
693}
694
695//
696// Mat3 Mul
697//
698
699/// multiply 3x3 * 3x3 matrix
700fn mul3x3<T: Number>(lhs: Mat3<T>, rhs: Mat3<T>) -> Mat3<T> {
701    Mat3 {
702        m: [
703            lhs.m[0] * rhs.m[0] + lhs.m[1] * rhs.m[3] + lhs.m[2] * rhs.m[6],
704            lhs.m[0] * rhs.m[1] + lhs.m[1] * rhs.m[4] + lhs.m[2] * rhs.m[7],
705            lhs.m[0] * rhs.m[2] + lhs.m[1] * rhs.m[5] + lhs.m[2] * rhs.m[8],
706
707            lhs.m[3] * rhs.m[0] + lhs.m[4] * rhs.m[3] + lhs.m[5] * rhs.m[6],
708            lhs.m[3] * rhs.m[1] + lhs.m[4] * rhs.m[4] + lhs.m[5] * rhs.m[7],
709            lhs.m[3] * rhs.m[2] + lhs.m[4] * rhs.m[5] + lhs.m[5] * rhs.m[8],
710
711            lhs.m[6] * rhs.m[0] + lhs.m[7] * rhs.m[3] + lhs.m[8] * rhs.m[6],
712            lhs.m[6] * rhs.m[1] + lhs.m[7] * rhs.m[4] + lhs.m[8] * rhs.m[7],
713            lhs.m[6] * rhs.m[2] + lhs.m[7] * rhs.m[5] + lhs.m[8] * rhs.m[8],
714        ]
715    }
716}
717
718impl<T> Mul<Self> for Mat3<T> where T: Number {
719    type Output = Self;
720    fn mul(self, rhs: Mat3<T>) -> Self::Output {
721        mul3x3(self, rhs)
722    }
723}
724
725impl<T> MulAssign<Self> for Mat3<T> where T: Number {
726    fn mul_assign(&mut self, rhs: Mat3<T>) {
727        *self = mul3x3(*self, rhs);
728    }
729}
730
731impl<T> Mul<Vec3<T>> for Mat3<T> where T: Number {
732    type Output = Vec3<T>;
733    fn mul(self, rhs: Vec3<T>) -> Self::Output {
734        Vec3 {
735            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z,
736            y: self.m[3] * rhs.x + self.m[4] * rhs.y + self.m[5] * rhs.z,
737            z: self.m[6] * rhs.x + self.m[7] * rhs.y + self.m[8] * rhs.z,
738        }
739    }
740}
741
742// mul refs
743impl<T> Mul<&Self> for Mat3<T> where T: Number {
744    type Output = Self;
745    fn mul(self, rhs: &Self) -> Self::Output {
746        mul3x3(self, *rhs)
747    }
748}
749
750impl<T> Mul<Mat3<T>> for &Mat3<T> where T: Number {
751    type Output = Mat3<T>;
752    fn mul(self, rhs: Mat3<T>) -> Self::Output {
753        mul3x3(*self, rhs)
754    }
755}
756
757impl<T> Mul<Self> for &Mat3<T> where T: Number {
758    type Output = Mat3<T>;
759    fn mul(self, rhs: Self) -> Self::Output {
760        mul3x3(*self, *rhs)
761    }
762}
763
764impl<T> Mul<&Vec3<T>> for Mat3<T> where T: Number {
765    type Output = Vec3<T>;
766    fn mul(self, rhs: &Vec3<T>) -> Self::Output {
767        Vec3 {
768            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z,
769            y: self.m[3] * rhs.x + self.m[4] * rhs.y + self.m[5] * rhs.z,
770            z: self.m[6] * rhs.x + self.m[7] * rhs.y + self.m[8] * rhs.z,
771        }
772    }
773}
774
775impl<T> Mul<Vec3<T>> for &Mat3<T> where T: Number {
776    type Output = Vec3<T>;
777    fn mul(self, rhs: Vec3<T>) -> Self::Output {
778        Vec3 {
779            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z,
780            y: self.m[3] * rhs.x + self.m[4] * rhs.y + self.m[5] * rhs.z,
781            z: self.m[6] * rhs.x + self.m[7] * rhs.y + self.m[8] * rhs.z,
782        }
783    }
784}
785
786impl<T> Mul<&Vec3<T>> for &Mat3<T> where T: Number {
787    type Output = Vec3<T>;
788    fn mul(self, rhs: &Vec3<T>) -> Self::Output {
789        Vec3 {
790            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z,
791            y: self.m[3] * rhs.x + self.m[4] * rhs.y + self.m[5] * rhs.z,
792            z: self.m[6] * rhs.x + self.m[7] * rhs.y + self.m[8] * rhs.z,
793        }
794    }
795}
796
797//
798// Mat34 Mul
799//
800
801/// multiply 3x4 * 3x4 matrix
802fn mul3x4<T: Number>(lhs: Mat34<T>, rhs: Mat34<T>) -> Mat34<T> {
803    Mat34 {
804        m: [
805            lhs.m[0] * rhs.m[0] + lhs.m[1] * rhs.m[4] + lhs.m[2] * rhs.m[8],
806            lhs.m[0] * rhs.m[1] + lhs.m[1] * rhs.m[5] + lhs.m[2] * rhs.m[9],
807            lhs.m[0] * rhs.m[2] + lhs.m[1] * rhs.m[6] + lhs.m[2] * rhs.m[10],
808            lhs.m[0] * rhs.m[3] + lhs.m[1] * rhs.m[7] + lhs.m[2] * rhs.m[11] + lhs.m[3],
809
810            lhs.m[4] * rhs.m[0] + lhs.m[5] * rhs.m[4] + lhs.m[6] * rhs.m[8],
811            lhs.m[4] * rhs.m[1] + lhs.m[5] * rhs.m[5] + lhs.m[6] * rhs.m[9],
812            lhs.m[4] * rhs.m[2] + lhs.m[5] * rhs.m[6] + lhs.m[6] * rhs.m[10],
813            lhs.m[4] * rhs.m[3] + lhs.m[5] * rhs.m[7] + lhs.m[6] * rhs.m[11] + lhs.m[7],
814
815            lhs.m[8] * rhs.m[0] + lhs.m[9] * rhs.m[4] + lhs.m[10] * rhs.m[8],
816            lhs.m[8] * rhs.m[1] + lhs.m[9] * rhs.m[5] + lhs.m[10] * rhs.m[9],
817            lhs.m[8] * rhs.m[2] + lhs.m[9] * rhs.m[6] + lhs.m[10] * rhs.m[10],
818            lhs.m[8] * rhs.m[3] + lhs.m[9] * rhs.m[7] + lhs.m[10] * rhs.m[11] + lhs.m[11],
819        ]
820    }
821}
822
823impl<T> Mul<Self> for Mat34<T> where T: Number {
824    type Output = Self;
825    fn mul(self, rhs: Mat34<T>) -> Self::Output {
826        mul3x4(self, rhs)
827    }
828}
829
830impl<T> MulAssign<Self> for Mat34<T> where T: Number {
831    fn mul_assign(&mut self, rhs: Mat34<T>) {
832        *self = mul3x4(*self, rhs)
833    }
834}
835
836impl<T> Mul<Vec3<T>> for Mat34<T> where T: Number {
837    type Output = Vec3<T>;
838    fn mul(self, rhs: Vec3<T>) -> Self::Output {
839        Vec3 {
840            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z + self.m[3],
841            y: self.m[4] * rhs.x + self.m[5] * rhs.y + self.m[6] * rhs.z + self.m[7],
842            z: self.m[8] * rhs.x + self.m[9] * rhs.y + self.m[10] * rhs.z + self.m[11]
843        }
844    }
845}
846
847/// multiples vector with implicit 4th row in matrix 0,0,0,1
848impl<T> Mul<Vec4<T>> for Mat34<T> where T: Number {
849    type Output = Vec4<T>;
850    fn mul(self, rhs: Vec4<T>) -> Self::Output {
851        Vec4 {
852            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z + self.m[3] * rhs.w,
853            y: self.m[4] * rhs.x + self.m[5] * rhs.y + self.m[6] * rhs.z + self.m[7] * rhs.w,
854            z: self.m[8] * rhs.x + self.m[9] * rhs.y + self.m[10] * rhs.z + self.m[11] * rhs.w,
855            w: rhs.w,
856        }
857    }
858}
859
860// mul refs
861impl<T> Mul<&Self> for Mat34<T> where T: Number {
862    type Output = Self;
863    fn mul(self, rhs: &Self) -> Self::Output {
864        mul3x4(self, *rhs)
865    }
866}
867
868impl<T> Mul<Mat34<T>> for &Mat34<T> where T: Number {
869    type Output = Mat34<T>;
870    fn mul(self, rhs: Mat34<T>) -> Self::Output {
871        mul3x4(*self, rhs)
872    }
873}
874
875impl<T> Mul<Self> for &Mat34<T> where T: Number {
876    type Output = Mat34<T>;
877    fn mul(self, rhs: Self) -> Self::Output {
878        mul3x4(*self, *rhs)
879    }
880}
881
882impl<T> Mul<&Vec3<T>> for Mat34<T> where T: Number {
883    type Output = Vec3<T>;
884    fn mul(self, rhs: &Vec3<T>) -> Self::Output {
885        Vec3 {
886            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z + self.m[3],
887            y: self.m[4] * rhs.x + self.m[5] * rhs.y + self.m[6] * rhs.z + self.m[7],
888            z: self.m[8] * rhs.x + self.m[9] * rhs.y + self.m[10] * rhs.z + self.m[11]
889        }
890    }
891}
892
893impl<T> Mul<Vec3<T>> for &Mat34<T> where T: Number {
894    type Output = Vec3<T>;
895    fn mul(self, rhs: Vec3<T>) -> Self::Output {
896        Vec3 {
897            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z + self.m[3],
898            y: self.m[4] * rhs.x + self.m[5] * rhs.y + self.m[6] * rhs.z + self.m[7],
899            z: self.m[8] * rhs.x + self.m[9] * rhs.y + self.m[10] * rhs.z + self.m[11]
900        }
901    }
902}
903
904impl<T> Mul<&Vec3<T>> for &Mat34<T> where T: Number {
905    type Output = Vec3<T>;
906    fn mul(self, rhs: &Vec3<T>) -> Self::Output {
907        Vec3 {
908            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z + self.m[3],
909            y: self.m[4] * rhs.x + self.m[5] * rhs.y + self.m[6] * rhs.z + self.m[7],
910            z: self.m[8] * rhs.x + self.m[9] * rhs.y + self.m[10] * rhs.z + self.m[11]
911        }
912    }
913}
914
915impl<T> Mul<&Vec4<T>> for Mat34<T> where T: Number {
916    type Output = Vec4<T>;
917    fn mul(self, rhs: &Vec4<T>) -> Self::Output {
918        Vec4 {
919            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z + self.m[3] * rhs.w,
920            y: self.m[4] * rhs.x + self.m[5] * rhs.y + self.m[6] * rhs.z + self.m[7] * rhs.w,
921            z: self.m[8] * rhs.x + self.m[9] * rhs.y + self.m[10] * rhs.z + self.m[11] * rhs.w,
922            w: rhs.w,
923        }
924    }
925}
926
927impl<T> Mul<Vec4<T>> for &Mat34<T> where T: Number {
928    type Output = Vec4<T>;
929    fn mul(self, rhs: Vec4<T>) -> Self::Output {
930        Vec4 {
931            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z + self.m[3] * rhs.w,
932            y: self.m[4] * rhs.x + self.m[5] * rhs.y + self.m[6] * rhs.z + self.m[7] * rhs.w,
933            z: self.m[8] * rhs.x + self.m[9] * rhs.y + self.m[10] * rhs.z + self.m[11] * rhs.w,
934            w: rhs.w,
935        }
936    }
937}
938
939impl<T> Mul<&Vec4<T>> for &Mat34<T> where T: Number {
940    type Output = Vec4<T>;
941    fn mul(self, rhs: &Vec4<T>) -> Self::Output {
942        Vec4 {
943            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z + self.m[3] * rhs.w,
944            y: self.m[4] * rhs.x + self.m[5] * rhs.y + self.m[6] * rhs.z + self.m[7] * rhs.w,
945            z: self.m[8] * rhs.x + self.m[9] * rhs.y + self.m[10] * rhs.z + self.m[11] * rhs.w,
946            w: rhs.w,
947        }
948    }
949}
950
951//
952// Mat4 Mul
953//
954
955/// multiply 4x4 * 4x4 matrix
956fn mul4x4<T: Number>(lhs: Mat4<T>, rhs: Mat4<T>) -> Mat4<T> {
957    Mat4 {
958        m: [
959            lhs.m[0] * rhs.m[0] + lhs.m[1] * rhs.m[4] + lhs.m[2] * rhs.m[8] + lhs.m[3] * rhs.m[12],
960            lhs.m[0] * rhs.m[1] + lhs.m[1] * rhs.m[5] + lhs.m[2] * rhs.m[9] + lhs.m[3] * rhs.m[13],
961            lhs.m[0] * rhs.m[2] + lhs.m[1] * rhs.m[6] + lhs.m[2] * rhs.m[10] + lhs.m[3] * rhs.m[14],
962            lhs.m[0] * rhs.m[3] + lhs.m[1] * rhs.m[7] + lhs.m[2] * rhs.m[11] + lhs.m[3] * rhs.m[15],
963
964            lhs.m[4] * rhs.m[0] + lhs.m[5] * rhs.m[4] + lhs.m[6] * rhs.m[8] + lhs.m[7] * rhs.m[12],
965            lhs.m[4] * rhs.m[1] + lhs.m[5] * rhs.m[5] + lhs.m[6] * rhs.m[9] + lhs.m[7] * rhs.m[13],
966            lhs.m[4] * rhs.m[2] + lhs.m[5] * rhs.m[6] + lhs.m[6] * rhs.m[10] + lhs.m[7] * rhs.m[14],
967            lhs.m[4] * rhs.m[3] + lhs.m[5] * rhs.m[7] + lhs.m[6] * rhs.m[11] + lhs.m[7] * rhs.m[15],
968
969            lhs.m[8] * rhs.m[0] + lhs.m[9] * rhs.m[4] + lhs.m[10] * rhs.m[8] + lhs.m[11] * rhs.m[12],
970            lhs.m[8] * rhs.m[1] + lhs.m[9] * rhs.m[5] + lhs.m[10] * rhs.m[9] + lhs.m[11] * rhs.m[13],
971            lhs.m[8] * rhs.m[2] + lhs.m[9] * rhs.m[6] + lhs.m[10] * rhs.m[10] + lhs.m[11] * rhs.m[14],
972            lhs.m[8] * rhs.m[3] + lhs.m[9] * rhs.m[7] + lhs.m[10] * rhs.m[11] + lhs.m[11] * rhs.m[15],
973
974            lhs.m[12] * rhs.m[0] + lhs.m[13] * rhs.m[4] + lhs.m[14] * rhs.m[8] + lhs.m[15] * rhs.m[12],
975            lhs.m[12] * rhs.m[1] + lhs.m[13] * rhs.m[5] + lhs.m[14] * rhs.m[9] + lhs.m[15] * rhs.m[13],
976            lhs.m[12] * rhs.m[2] + lhs.m[13] * rhs.m[6] + lhs.m[14] * rhs.m[10] + lhs.m[15] * rhs.m[14],
977            lhs.m[12] * rhs.m[3] + lhs.m[13] * rhs.m[7] + lhs.m[14] * rhs.m[11] + lhs.m[15] * rhs.m[15],
978        ]
979    }
980}
981
982impl<T> Mul<Self> for Mat4<T> where T: Number {
983    type Output = Self;
984    fn mul(self, rhs: Mat4<T>) -> Self::Output {
985        mul4x4(self, rhs)
986    }
987}
988
989impl<T> MulAssign<Self> for Mat4<T> where T: Number {
990    fn mul_assign(&mut self, rhs: Mat4<T>) {
991        *self = mul4x4(*self, rhs);
992    }
993}
994
995impl<T> Mul<Vec4<T>> for Mat4<T> where T: Number {
996    type Output = Vec4<T>;
997    fn mul(self, rhs: Vec4<T>) -> Self::Output {
998        Vec4 {
999            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z + self.m[3] * rhs.w,
1000            y: self.m[4] * rhs.x + self.m[5] * rhs.y + self.m[6] * rhs.z + self.m[7] * rhs.w,
1001            z: self.m[8] * rhs.x + self.m[9] * rhs.y + self.m[10] * rhs.z + self.m[11] * rhs.w,
1002            w: self.m[12] * rhs.x + self.m[13] * rhs.y + self.m[14] * rhs.z + self.m[15] * rhs.w,
1003        }
1004    }
1005}
1006
1007/// performs multiplication on vec3 with implicit w = 1.0, returning Vec3 which has been divided by w
1008impl<T> Mul<Vec3<T>> for Mat4<T> where T: Number {
1009    type Output = Vec3<T>;
1010    fn mul(self, rhs: Vec3<T>) -> Self::Output {
1011        let w = self.m[12] * rhs.x + self.m[13] * rhs.y + self.m[14] * rhs.z + self.m[15];
1012        Vec3 {
1013            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z + self.m[3],
1014            y: self.m[4] * rhs.x + self.m[5] * rhs.y + self.m[6] * rhs.z + self.m[7],
1015            z: self.m[8] * rhs.x + self.m[9] * rhs.y + self.m[10] * rhs.z + self.m[11],
1016        } / w
1017    }
1018}
1019
1020// mat34 implicit last row
1021// 12 13 14 15
1022// 00 00 00 01
1023
1024/// multiply 3x4 * 4x4 matrix
1025fn mul3x4_4x4<T: Number>(lhs: Mat34<T>, rhs: Mat4<T>) -> Mat4<T> {
1026    Mat4 {
1027        m: [
1028            lhs.m[0] * rhs.m[0] + lhs.m[1] * rhs.m[4] + lhs.m[2] * rhs.m[8] + lhs.m[3] * rhs.m[12],
1029            lhs.m[0] * rhs.m[1] + lhs.m[1] * rhs.m[5] + lhs.m[2] * rhs.m[9] + lhs.m[3] * rhs.m[13],
1030            lhs.m[0] * rhs.m[2] + lhs.m[1] * rhs.m[6] + lhs.m[2] * rhs.m[10] + lhs.m[3] * rhs.m[14],
1031            lhs.m[0] * rhs.m[3] + lhs.m[1] * rhs.m[7] + lhs.m[2] * rhs.m[11] + lhs.m[3] * rhs.m[15],
1032
1033            lhs.m[4] * rhs.m[0] + lhs.m[5] * rhs.m[4] + lhs.m[6] * rhs.m[8] + lhs.m[7] * rhs.m[12],
1034            lhs.m[4] * rhs.m[1] + lhs.m[5] * rhs.m[5] + lhs.m[6] * rhs.m[9] + lhs.m[7] * rhs.m[13],
1035            lhs.m[4] * rhs.m[2] + lhs.m[5] * rhs.m[6] + lhs.m[6] * rhs.m[10] + lhs.m[7] * rhs.m[14],
1036            lhs.m[4] * rhs.m[3] + lhs.m[5] * rhs.m[7] + lhs.m[6] * rhs.m[11] + lhs.m[7] * rhs.m[15],
1037
1038            lhs.m[8] * rhs.m[0] + lhs.m[9] * rhs.m[4] + lhs.m[10] * rhs.m[8] + lhs.m[11] * rhs.m[12],
1039            lhs.m[8] * rhs.m[1] + lhs.m[9] * rhs.m[5] + lhs.m[10] * rhs.m[9] + lhs.m[11] * rhs.m[13],
1040            lhs.m[8] * rhs.m[2] + lhs.m[9] * rhs.m[6] + lhs.m[10] * rhs.m[10] + lhs.m[11] * rhs.m[14],
1041            lhs.m[8] * rhs.m[3] + lhs.m[9] * rhs.m[7] + lhs.m[10] * rhs.m[11] + lhs.m[11] * rhs.m[15],
1042
1043            rhs.m[12],
1044            rhs.m[13],
1045            rhs.m[14],
1046            rhs.m[15],
1047        ]
1048    }
1049}
1050
1051impl<T> Mul<Mat4<T>> for Mat34<T> where T: Number {
1052    type Output = Mat4<T>;
1053    fn mul(self, rhs: Mat4<T>) -> Self::Output {
1054        mul3x4_4x4(self, rhs)
1055    }
1056}
1057
1058// mat34 implicit last row
1059// 12 13 14 15
1060// 00 00 00 01
1061
1062/// multiply 4x4 * 3x4 matrix
1063fn mul4x4_3x4<T: Number>(lhs: Mat4<T>, rhs: Mat34<T>) -> Mat4<T> {
1064    Mat4 {
1065        m: [
1066            lhs.m[0] * rhs.m[0] + lhs.m[1] * rhs.m[4] + lhs.m[2] * rhs.m[8],
1067            lhs.m[0] * rhs.m[1] + lhs.m[1] * rhs.m[5] + lhs.m[2] * rhs.m[9],
1068            lhs.m[0] * rhs.m[2] + lhs.m[1] * rhs.m[6] + lhs.m[2] * rhs.m[10],
1069            lhs.m[0] * rhs.m[3] + lhs.m[1] * rhs.m[7] + lhs.m[2] * rhs.m[11] + lhs.m[3],
1070
1071            lhs.m[4] * rhs.m[0] + lhs.m[5] * rhs.m[4] + lhs.m[6] * rhs.m[8],
1072            lhs.m[4] * rhs.m[1] + lhs.m[5] * rhs.m[5] + lhs.m[6] * rhs.m[9],
1073            lhs.m[4] * rhs.m[2] + lhs.m[5] * rhs.m[6] + lhs.m[6] * rhs.m[10],
1074            lhs.m[4] * rhs.m[3] + lhs.m[5] * rhs.m[7] + lhs.m[6] * rhs.m[11] + lhs.m[7],
1075
1076            lhs.m[8] * rhs.m[0] + lhs.m[9] * rhs.m[4] + lhs.m[10] * rhs.m[8],
1077            lhs.m[8] * rhs.m[1] + lhs.m[9] * rhs.m[5] + lhs.m[10] * rhs.m[9],
1078            lhs.m[8] * rhs.m[2] + lhs.m[9] * rhs.m[6] + lhs.m[10] * rhs.m[10],
1079            lhs.m[8] * rhs.m[3] + lhs.m[9] * rhs.m[7] + lhs.m[10] * rhs.m[11] + lhs.m[11],
1080
1081            lhs.m[12] * rhs.m[0] + lhs.m[13] * rhs.m[4] + lhs.m[14] * rhs.m[8],
1082            lhs.m[12] * rhs.m[1] + lhs.m[13] * rhs.m[5] + lhs.m[14] * rhs.m[9],
1083            lhs.m[12] * rhs.m[2] + lhs.m[13] * rhs.m[6] + lhs.m[14] * rhs.m[10],
1084            lhs.m[12] * rhs.m[3] + lhs.m[13] * rhs.m[7] + lhs.m[14] * rhs.m[11] + lhs.m[15],
1085        ]
1086    }
1087}
1088
1089impl<T> Mul<Mat34<T>> for Mat4<T> where T: Number {
1090    type Output = Self;
1091    fn mul(self, rhs: Mat34<T>) -> Self::Output {
1092        mul4x4_3x4(self, rhs)
1093    }
1094}
1095
1096impl<T> MulAssign<Mat34<T>> for Mat4<T> where T: Number {
1097    fn mul_assign(&mut self, rhs: Mat34<T>) {
1098        *self = mul4x4_3x4(*self, rhs)
1099    }
1100}
1101
1102// mul refs
1103impl<T> Mul<&Self> for Mat4<T> where T: Number {
1104    type Output = Self;
1105    fn mul(self, rhs: &Self) -> Self::Output {
1106        mul4x4(self, *rhs)
1107    }
1108}
1109
1110impl<T> Mul<Mat4<T>> for &Mat4<T> where T: Number {
1111    type Output = Mat4<T>;
1112    fn mul(self, rhs: Mat4<T>) -> Self::Output {
1113        mul4x4(*self, rhs)
1114    }
1115}
1116
1117impl<T> Mul<Self> for &Mat4<T> where T: Number {
1118    type Output = Mat4<T>;
1119    fn mul(self, rhs: Self) -> Self::Output {
1120        mul4x4(*self, *rhs)
1121    }
1122}
1123
1124// 4 x 34
1125impl<T> Mul<&Mat34<T>> for Mat4<T> where T: Number {
1126    type Output = Self;
1127    fn mul(self, rhs: &Mat34<T>) -> Self::Output {
1128        mul4x4_3x4(self, *rhs)
1129    }
1130}
1131
1132impl<T> Mul<Mat34<T>> for &Mat4<T> where T: Number {
1133    type Output = Mat4<T>;
1134    fn mul(self, rhs: Mat34<T>) -> Self::Output {
1135        mul4x4_3x4(*self, rhs)
1136    }
1137}
1138
1139impl<T> Mul<&Mat34<T>> for &Mat4<T> where T: Number {
1140    type Output = Mat4<T>;
1141    fn mul(self, rhs: &Mat34<T>) -> Self::Output {
1142        mul4x4_3x4(*self, *rhs)
1143    }
1144}
1145
1146// 34 x 4
1147
1148impl<T> Mul<&Mat4<T>> for Mat34<T> where T: Number {
1149    type Output = Mat4<T>;
1150    fn mul(self, rhs: &Mat4<T>) -> Self::Output {
1151        mul3x4_4x4(self, *rhs)
1152    }
1153}
1154
1155impl<T> Mul<Mat4<T>> for &Mat34<T> where T: Number {
1156    type Output = Mat4<T>;
1157    fn mul(self, rhs: Mat4<T>) -> Self::Output {
1158        mul3x4_4x4(*self, rhs)
1159    }
1160}
1161
1162impl<T> Mul<&Mat4<T>> for &Mat34<T> where T: Number {
1163    type Output = Mat4<T>;
1164    fn mul(self, rhs: &Mat4<T>) -> Self::Output {
1165        mul3x4_4x4(*self, *rhs)
1166    }
1167}
1168
1169impl<T> Mul<&Vec4<T>> for Mat4<T> where T: Number {
1170    type Output = Vec4<T>;
1171    fn mul(self, rhs: &Vec4<T>) -> Self::Output {
1172        Vec4 {
1173            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z + self.m[3] * rhs.w,
1174            y: self.m[4] * rhs.x + self.m[5] * rhs.y + self.m[6] * rhs.z + self.m[7] * rhs.w,
1175            z: self.m[8] * rhs.x + self.m[9] * rhs.y + self.m[10] * rhs.z + self.m[11] * rhs.w,
1176            w: self.m[12] * rhs.x + self.m[13] * rhs.y + self.m[14] * rhs.z + self.m[15] * rhs.w,
1177        }
1178    }
1179}
1180
1181impl<T> Mul<Vec4<T>> for &Mat4<T> where T: Number {
1182    type Output = Vec4<T>;
1183    fn mul(self, rhs: Vec4<T>) -> Self::Output {
1184        Vec4 {
1185            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z + self.m[3] * rhs.w,
1186            y: self.m[4] * rhs.x + self.m[5] * rhs.y + self.m[6] * rhs.z + self.m[7] * rhs.w,
1187            z: self.m[8] * rhs.x + self.m[9] * rhs.y + self.m[10] * rhs.z + self.m[11] * rhs.w,
1188            w: self.m[12] * rhs.x + self.m[13] * rhs.y + self.m[14] * rhs.z + self.m[15] * rhs.w,
1189        }
1190    }
1191}
1192
1193impl<T> Mul<&Vec4<T>> for &Mat4<T> where T: Number {
1194    type Output = Vec4<T>;
1195    fn mul(self, rhs: &Vec4<T>) -> Self::Output {
1196        Vec4 {
1197            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z + self.m[3] * rhs.w,
1198            y: self.m[4] * rhs.x + self.m[5] * rhs.y + self.m[6] * rhs.z + self.m[7] * rhs.w,
1199            z: self.m[8] * rhs.x + self.m[9] * rhs.y + self.m[10] * rhs.z + self.m[11] * rhs.w,
1200            w: self.m[12] * rhs.x + self.m[13] * rhs.y + self.m[14] * rhs.z + self.m[15] * rhs.w,
1201        }
1202    }
1203}
1204
1205impl<T> Mul<&Vec3<T>> for Mat4<T> where T: Number {
1206    type Output = Vec3<T>;
1207    fn mul(self, rhs: &Vec3<T>) -> Self::Output {
1208        let w = self.m[12] * rhs.x + self.m[13] * rhs.y + self.m[14] * rhs.z + self.m[15];
1209        Vec3 {
1210            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z + self.m[3],
1211            y: self.m[4] * rhs.x + self.m[5] * rhs.y + self.m[6] * rhs.z + self.m[7],
1212            z: self.m[8] * rhs.x + self.m[9] * rhs.y + self.m[10] * rhs.z + self.m[11],
1213        } / w
1214    }
1215}
1216
1217impl<T> Mul<Vec3<T>> for &Mat4<T> where T: Number {
1218    type Output = Vec3<T>;
1219    fn mul(self, rhs: Vec3<T>) -> Self::Output {
1220        let w = self.m[12] * rhs.x + self.m[13] * rhs.y + self.m[14] * rhs.z + self.m[15];
1221        Vec3 {
1222            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z + self.m[3],
1223            y: self.m[4] * rhs.x + self.m[5] * rhs.y + self.m[6] * rhs.z + self.m[7],
1224            z: self.m[8] * rhs.x + self.m[9] * rhs.y + self.m[10] * rhs.z + self.m[11],
1225        } / w
1226    }
1227}
1228
1229impl<T> Mul<&Vec3<T>> for &Mat4<T> where T: Number {
1230    type Output = Vec3<T>;
1231    fn mul(self, rhs: &Vec3<T>) -> Self::Output {
1232        let w = self.m[12] * rhs.x + self.m[13] * rhs.y + self.m[14] * rhs.z + self.m[15];
1233        Vec3 {
1234            x: self.m[0] * rhs.x + self.m[1] * rhs.y + self.m[2] * rhs.z + self.m[3],
1235            y: self.m[4] * rhs.x + self.m[5] * rhs.y + self.m[6] * rhs.z + self.m[7],
1236            z: self.m[8] * rhs.x + self.m[9] * rhs.y + self.m[10] * rhs.z + self.m[11],
1237        } / w
1238    }
1239}
1240
1241/// base matrix trait for arithmetic ops
1242pub trait MatN<T: Number, V: VecN<T>>:
1243    Sized + Display + Copy + Clone +
1244    Mul<V, Output=V> + Mul<Self, Output=Self> + MulAssign<Self> +
1245{
1246}
1247
1248impl<T> MatN<T, Vec2<T>> for Mat2<T> where T: Number {}
1249impl<T> MatN<T, Vec3<T>> for Mat3<T> where T: Number {}
1250impl<T> MatN<T, Vec3<T>> for Mat34<T> where T: Number {}
1251impl<T> MatN<T, Vec4<T>> for Mat4<T> where T: Number {}
1252impl<T> MatN<T, Vec3<T>> for Mat4<T> where T: Number {}
1253
1254
1255/// trait for minimum of 4 column matrices to create translation
1256pub trait MatTranslate<V> {
1257    /// create a translation matrix from 3-dimensional vector `t`
1258    fn from_translation(t: V) -> Self;
1259}
1260
1261impl<T> MatTranslate<Vec3<T>> for Mat4<T> where T: Number {
1262    fn from_translation(t: Vec3<T>) -> Self {
1263        let mut m = Mat4::identity();
1264        m.set_column(3, Vec4::from(t));
1265        m.m[15] = T::one();
1266        m
1267    }
1268}
1269
1270impl<T> MatTranslate<Vec3<T>> for Mat34<T> where T: Number {
1271    fn from_translation(t: Vec3<T>) -> Self {
1272        let mut m = Mat34::identity();
1273        m.set_column(3, t);
1274        m
1275    }
1276}
1277
1278/// trait for all matrices to cerate a scaling matrix
1279pub trait MatScale<V> {
1280    /// create a scale matrix from n-dimensional vector `t`
1281    fn from_scale(t: V) -> Self;
1282}
1283
1284impl<T> MatScale<Vec3<T>> for Mat4<T> where T: Number {
1285    fn from_scale(t: Vec3<T>) -> Self {
1286        let mut m = Mat4::identity();
1287        m.set(0, 0, t.x);
1288        m.set(1, 1, t.y);
1289        m.set(2, 2, t.z);
1290        m
1291    }
1292}
1293
1294impl<T> MatScale<Vec3<T>> for Mat34<T> where T: Number {
1295    fn from_scale(t: Vec3<T>) -> Self {
1296        let mut m = Mat34::identity();
1297        m.set(0, 0, t.x);
1298        m.set(1, 1, t.y);
1299        m.set(2, 2, t.z);
1300        m
1301    }
1302}
1303
1304impl<T> MatScale<Vec3<T>> for Mat3<T> where T: Number {
1305    fn from_scale(t: Vec3<T>) -> Self {
1306        let mut m = Mat3::identity();
1307        m.set(0, 0, t.x);
1308        m.set(1, 1, t.y);
1309        m.set(2, 2, t.z);
1310        m
1311    }
1312}
1313
1314impl<T> MatScale<Vec2<T>> for Mat2<T> where T: Number {
1315    fn from_scale(t: Vec2<T>) -> Self {
1316        let mut m = Mat2::identity();
1317        m.set(0, 0, t.x);
1318        m.set(1, 1, t.y);
1319        m
1320    }
1321}
1322
1323/// trait for minimum of 2x2 matrices applying rotation in z-axis
1324pub trait MatRotate2D<T> {
1325    /// create rotation about the z axis by `theta` radians
1326    fn from_z_rotation(theta: T) -> Self;
1327}
1328
1329impl<T> MatRotate2D<T> for Mat2<T> where T: Float + FloatOps<T>  {
1330    fn from_z_rotation(theta: T) -> Self {
1331        let mut m = Mat2::identity();
1332        let cos_theta = T::cos(theta);
1333        let sin_theta = T::sin(theta);
1334        m.set(0, 0, cos_theta);
1335        m.set(0, 1, -sin_theta);
1336        m.set(1, 0, sin_theta);
1337        m.set(1, 1, cos_theta);
1338        m
1339    }
1340}
1341
1342impl<T> MatRotate2D<T> for Mat3<T> where T: Float + FloatOps<T>  {
1343    fn from_z_rotation(theta: T) -> Self {
1344        let mut m = Mat3::identity();
1345        let cos_theta = T::cos(theta);
1346        let sin_theta = T::sin(theta);
1347        m.set(0, 0, cos_theta);
1348        m.set(0, 1, -sin_theta);
1349        m.set(1, 0, sin_theta);
1350        m.set(1, 1, cos_theta);
1351        m
1352    }
1353}
1354
1355impl<T> MatRotate2D<T> for Mat4<T> where T: Float + FloatOps<T>  {
1356    fn from_z_rotation(theta: T) -> Self {
1357        let mut m = Mat4::identity();
1358        let cos_theta = T::cos(theta);
1359        let sin_theta = T::sin(theta);
1360        m.set(0, 0, cos_theta);
1361        m.set(0, 1, -sin_theta);
1362        m.set(1, 0, sin_theta);
1363        m.set(1, 1, cos_theta);
1364        m
1365    }
1366}
1367
1368impl<T> MatRotate2D<T> for Mat34<T> where T: Float + FloatOps<T> {
1369    fn from_z_rotation(theta: T) -> Self {
1370        let mut m = Mat34::identity();
1371        let cos_theta = T::cos(theta);
1372        let sin_theta = T::sin(theta);
1373        m.set(0, 0, cos_theta);
1374        m.set(0, 1, -sin_theta);
1375        m.set(1, 0, sin_theta);
1376        m.set(1, 1, cos_theta);
1377        m
1378    }
1379}
1380
1381/// given the normalised vector `n`, constructs an orthonormal basis returned as tuple
1382pub fn get_orthonormal_basis_hughes_moeller<T: Float + SignedNumberOps<T> + FloatOps<T>>(n: Vec3<T>) -> (Vec3<T>, Vec3<T>) {
1383    // choose a vector orthogonal to n as the direction of b2.
1384    let b2 = if T::abs(n.x) > T::abs(n.z) {
1385        Vec3::new(-n.y, n.x, T::zero())
1386    }
1387    else {
1388        Vec3::new(T::zero(), -n.z, n.y)
1389    };
1390
1391    // normalise b2
1392    let b2 = b2 * T::rsqrt(Vec3::dot(b2, b2));
1393
1394    // construct b1 using cross product
1395    let b1 = Vec3::cross(b2, n);
1396
1397    (b1, b2)
1398}
1399
1400/// given the normalised vector `n` construct an orthonormal basis without sqrt..
1401pub fn get_orthonormal_basis_frisvad<T: Float + SignedNumberOps<T> + FloatOps<T> + From<f64>>(n: Vec3<T>) -> (Vec3<T>, Vec3<T>) {
1402    let epsilon = T::from(-0.99999999);
1403    if n.z < epsilon {
1404        (-Vec3::unit_y(), -Vec3::unit_x())
1405    }
1406    else {
1407        let a = T::one()/(T::one() + n.z);
1408        let b = -n.x * n.y * a;
1409        (Vec3::new(T::one() - n.x * n.x * a, b, -n.x), Vec3::new(b, T::one() - n.y * n.y * a, -n.y))
1410    }
1411}
1412
1413
1414/// trait for minimum of 3x3 matrices applying rotation to x, y or aribtrary 3D axes
1415pub trait MatRotate3D<T, V> {
1416    /// create rotation about the x axis by `theta` radians
1417    fn from_x_rotation(theta: T) -> Self;
1418    /// create rotation about the y axis by `theta` radians
1419    fn from_y_rotation(theta: T) -> Self;
1420    /// create rotation about the abitrary `axis` by `theta` radians
1421    fn from_rotation(axis: V, theta: T) -> Self;
1422    /// create an othonormal basis from the `normal` vector
1423    fn from_orthonormal_basis(normal: Vec3<T>) -> Self;
1424}
1425
1426impl<T> MatRotate3D<T, Vec3<T>> for Mat3<T> where T: Float + FloatOps<T> + SignedNumberOps<T> {
1427    fn from_x_rotation(theta: T) -> Self {
1428        let mut m = Mat3::identity();
1429        let cos_theta = T::cos(theta);
1430        let sin_theta = T::sin(theta);
1431        m.set(1, 1, cos_theta);
1432        m.set(1, 2, -sin_theta);
1433        m.set(2, 1, sin_theta);
1434        m.set(2, 2, cos_theta);
1435        m
1436    }
1437
1438    fn from_y_rotation(theta: T) -> Self {
1439        let mut m = Mat3::identity();
1440        let cos_theta = T::cos(theta);
1441        let sin_theta = T::sin(theta);
1442        m.set(0, 0, cos_theta);
1443        m.set(0, 2, sin_theta);
1444        m.set(2, 0, -sin_theta);
1445        m.set(2, 2, cos_theta);
1446        m
1447    }
1448
1449    fn from_rotation(axis: Vec3<T>, theta: T) -> Self {
1450        let cos_theta = T::cos(theta);
1451        let sin_theta = T::sin(theta);
1452        let inv_cos_theta = T::one() - cos_theta;
1453        Mat3::from((
1454            Vec3::new(
1455                inv_cos_theta * axis.x * axis.x + cos_theta,
1456                inv_cos_theta * axis.x * axis.y - sin_theta * axis.z,
1457                inv_cos_theta * axis.x * axis.z + sin_theta * axis.y
1458            ),
1459            Vec3::new(
1460                inv_cos_theta * axis.x * axis.y + sin_theta * axis.z,
1461                inv_cos_theta * axis.y * axis.y + cos_theta,
1462                inv_cos_theta * axis.y * axis.z - sin_theta * axis.x
1463            ),
1464            Vec3::new(
1465                inv_cos_theta * axis.x * axis.z - sin_theta * axis.y,
1466                inv_cos_theta * axis.y * axis.z + sin_theta * axis.x,
1467                inv_cos_theta * axis.z * axis.z + cos_theta
1468            )
1469        ))
1470    }
1471
1472    fn from_orthonormal_basis(normal: Vec3<T>) -> Self {
1473        let (b1, b2) = get_orthonormal_basis_hughes_moeller(normal);
1474        Mat3::from((
1475            b1,
1476            normal,
1477            b2
1478        ))
1479    }
1480}
1481
1482impl<T> MatRotate3D<T, Vec3<T>> for Mat34<T> where T: Float + FloatOps<T> + SignedNumberOps<T> {
1483    fn from_x_rotation(theta: T) -> Self {
1484        Mat34::from(Mat3::from_x_rotation(theta))
1485    }
1486
1487    fn from_y_rotation(theta: T) -> Self {
1488        Mat34::from(Mat3::from_y_rotation(theta))
1489    }
1490
1491    fn from_rotation(axis: Vec3<T>, theta: T) -> Self {
1492        Mat34::from(Mat3::from_rotation(axis, theta))
1493    }
1494
1495    fn from_orthonormal_basis(normal: Vec3<T>) -> Self {
1496        Mat34::from(Mat3::from_orthonormal_basis(normal))
1497    }
1498}
1499
1500impl<T> MatRotate3D<T, Vec3<T>> for Mat4<T> where T: Float + FloatOps<T> + SignedNumberOps<T> {
1501    fn from_x_rotation(theta: T) -> Self {
1502        Mat4::from(Mat3::from_x_rotation(theta))
1503    }
1504
1505    fn from_y_rotation(theta: T) -> Self {
1506        Mat4::from(Mat3::from_y_rotation(theta))
1507    }
1508
1509    fn from_rotation(axis: Vec3<T>, theta: T) -> Self {
1510        Mat4::from(Mat3::from_rotation(axis, theta))
1511    }
1512
1513    fn from_orthonormal_basis(normal: Vec3<T>) -> Self {
1514        Mat4::from(Mat3::from_orthonormal_basis(normal))
1515    }
1516}
1517
1518/// trait for square matrices to compute determinant
1519pub trait MatDeterminant<T> {
1520    /// return the determinant of the matrix as scalar `T`
1521    fn determinant(&self) -> T;
1522}
1523
1524impl<T> MatDeterminant<T> for Mat2<T> where T: Number {
1525    fn determinant(&self) -> T {
1526        self.m[0] * self.m[3] - self.m[1] * self.m[2]
1527    }
1528}
1529
1530impl<T> MatDeterminant<T> for Mat3<T> where T: Number {
1531    fn determinant(&self) -> T {
1532        self.m[0] * (self.m[4] * self.m[8] - self.m[5] * self.m[7]) -
1533        self.m[1] * (self.m[3] * self.m[8] - self.m[5] * self.m[6]) +
1534        self.m[2] * (self.m[3] * self.m[7] - self.m[4] * self.m[6])
1535    }
1536}
1537
1538/// returns the 4x4 determinant using laplace expansion theorum
1539#[allow(clippy::zero_prefixed_literal)]
1540impl<T> MatDeterminant<T> for Mat4<T> where T: Number {
1541    fn determinant(&self) -> T {
1542        let s0 = (self.m[00] * self.m[05]) - (self.m[01] * self.m[04]);
1543        let s1 = (self.m[00] * self.m[06]) - (self.m[02] * self.m[04]);
1544        let s2 = (self.m[00] * self.m[07]) - (self.m[03] * self.m[04]);
1545        let s3 = (self.m[01] * self.m[06]) - (self.m[02] * self.m[05]);
1546        let s4 = (self.m[01] * self.m[07]) - (self.m[03] * self.m[05]);
1547        let s5 = (self.m[02] * self.m[07]) - (self.m[03] * self.m[06]);
1548        let c5 = (self.m[10] * self.m[15]) - (self.m[11] * self.m[14]);
1549        let c4 = (self.m[09] * self.m[15]) - (self.m[11] * self.m[13]);
1550        let c3 = (self.m[09] * self.m[14]) - (self.m[10] * self.m[13]);
1551        let c2 = (self.m[08] * self.m[15]) - (self.m[11] * self.m[12]);
1552        let c1 = (self.m[08] * self.m[14]) - (self.m[10] * self.m[12]);
1553        let c0 = (self.m[08] * self.m[13]) - (self.m[09] * self.m[12]);
1554        (s0 * c5) - (s1 * c4) + (s2 * c3) + (s3 * c2) - (s4 * c1) + (s5 * c0)
1555    }
1556}
1557
1558/// trait for all kinds of matrices to calculate inverse
1559pub trait MatInverse<T> {
1560    /// returns the inverse of the matrix
1561    fn inverse(&self) -> Self;
1562}
1563
1564impl<T> MatInverse<T> for Mat2<T> where T: SignedNumber {
1565    fn inverse(&self) -> Self {
1566        let det = self.determinant();
1567        let inv_det = T::one()/det;
1568        Mat2 {
1569            m: [
1570                inv_det * self.m[3], inv_det * -self.m[1],
1571                inv_det * -self.m[2], inv_det * self.m[0],
1572            ]
1573        }
1574    }
1575}
1576
1577impl<T> MatInverse<T> for Mat3<T> where T: SignedNumber {
1578    fn inverse(&self) -> Self {
1579        let det = self.determinant();
1580        let inv_det = T::one() / det;
1581        Mat3 {
1582            m: [
1583                (self.m[4] * self.m[8] - self.m[5] * self.m[7]) * inv_det,
1584                -(self.m[1] * self.m[8] - self.m[2] * self.m[7]) * inv_det,
1585                (self.m[1] * self.m[5] - self.m[2] * self.m[4]) * inv_det,
1586
1587                -(self.m[3] * self.m[8] - self.m[5] * self.m[6]) * inv_det,
1588                (self.m[0] * self.m[8] - self.m[2] * self.m[6]) * inv_det,
1589                -(self.m[0] * self.m[5] - self.m[2] * self.m[3]) * inv_det,
1590
1591                (self.m[3] * self.m[7] - self.m[4] * self.m[6]) * inv_det,
1592                -(self.m[0] * self.m[7] - self.m[1] * self.m[6]) * inv_det,
1593                (self.m[0] * self.m[4] - self.m[1] * self.m[3]) * inv_det
1594            ]
1595        }
1596    }
1597}
1598
1599impl<T> MatInverse<T> for Mat34<T> where T: SignedNumber {
1600    fn inverse(&self) -> Self {
1601        let m3_inv = Mat3::<T>::from(*self).inverse();
1602        let mut m34 = Mat34::<T>::from(m3_inv);
1603        let t = Vec3::<T>::from((-self.m[3], -self.m[7], -self.m[11]));
1604        let inv_t = Vec3::<T> {
1605            x: t.x * m3_inv.m[0] + t.y * m3_inv.m[1] + t.z * m3_inv.m[2],
1606            y: t.x * m3_inv.m[3] + t.y * m3_inv.m[4] + t.z * m3_inv.m[5],
1607            z: t.x * m3_inv.m[6] + t.y * m3_inv.m[7] + t.z * m3_inv.m[8],
1608        };
1609        m34.set_column(3, inv_t);
1610        m34
1611    }
1612}
1613
1614#[allow(clippy::zero_prefixed_literal)]
1615impl<T> MatInverse<T> for Mat4<T> where T: SignedNumber {
1616    fn inverse(&self) -> Self {
1617        let s0 = (self.m[00] * self.m[05]) - (self.m[01] * self.m[04]);
1618        let s1 = (self.m[00] * self.m[06]) - (self.m[02] * self.m[04]);
1619        let s2 = (self.m[00] * self.m[07]) - (self.m[03] * self.m[04]);
1620        let s3 = (self.m[01] * self.m[06]) - (self.m[02] * self.m[05]);
1621        let s4 = (self.m[01] * self.m[07]) - (self.m[03] * self.m[05]);
1622        let s5 = (self.m[02] * self.m[07]) - (self.m[03] * self.m[06]);
1623        let c5 = (self.m[10] * self.m[15]) - (self.m[11] * self.m[14]);
1624        let c4 = (self.m[09] * self.m[15]) - (self.m[11] * self.m[13]);
1625        let c3 = (self.m[09] * self.m[14]) - (self.m[10] * self.m[13]);
1626        let c2 = (self.m[08] * self.m[15]) - (self.m[11] * self.m[12]);
1627        let c1 = (self.m[08] * self.m[14]) - (self.m[10] * self.m[12]);
1628        let c0 = (self.m[08] * self.m[13]) - (self.m[09] * self.m[12]);
1629        let det = (s0 * c5) - (s1 * c4) + (s2 * c3) + (s3 * c2) - (s4 * c1) + (s5 * c0);
1630        let inv_det = T::one() / det;
1631        Mat4 {
1632            m: [
1633                (self.m[5] * c5 - self.m[6] * c4 + self.m[7] * c3) * inv_det,
1634                -(self.m[1] * c5 - self.m[2] * c4 + self.m[3] * c3) * inv_det,
1635                (self.m[13] * s5 - self.m[14] * s4 + self.m[15] * s3) * inv_det,
1636                -(self.m[9] * s5 - self.m[10] * s4 + self.m[11] * s3) * inv_det,
1637                -(self.m[4] * c5 - self.m[6] * c2 + self.m[7] * c1) * inv_det,
1638                (self.m[0] * c5 - self.m[2] * c2 + self.m[3] * c1) * inv_det,
1639                -(self.m[12] * s5 - self.m[14] * s2 + self.m[15] * s1) * inv_det,
1640                (self.m[8] * s5 - self.m[10] * s2 + self.m[11] * s1) * inv_det,
1641                (self.m[4] * c4 - self.m[5] * c2 + self.m[7] * c0) * inv_det,
1642                 -(self.m[0] * c4 - self.m[1] * c2 + self.m[3] * c0) * inv_det,
1643                (self.m[12] * s4 - self.m[13] * s2 + self.m[15] * s0) * inv_det,
1644                 -(self.m[8] * s4 - self.m[9] * s2 + self.m[11] * s0) * inv_det,
1645                 -(self.m[4] * c3 - self.m[5] * c1 + self.m[6] * c0) * inv_det,
1646                (self.m[0] * c3 - self.m[1] * c1 + self.m[2] * c0) * inv_det,
1647                 -(self.m[12] * s3 - self.m[13] * s1 + self.m[14] * s0) * inv_det,
1648                (self.m[8] * s3 - self.m[9] * s1 + self.m[10] * s0) * inv_det,
1649            ]
1650        }
1651    }
1652}
1653
1654/// trait for matrix transpose
1655pub trait MatTranspose<T, Other> {
1656    fn transpose(&self) -> Other;
1657}
1658
1659impl<T> MatTranspose<T, Self> for Mat2<T> where T: Number {
1660    fn transpose(&self) -> Self {
1661        let mut t = *self;
1662        for r in 0..t.get_num_rows() as u32 {
1663            for c in 0..t.get_num_columns() as u32 {
1664                t.set(c, r, self.at(r, c));
1665            }
1666        }
1667        t
1668    }
1669}
1670
1671impl<T> MatTranspose<T, Self> for Mat3<T> where T: Number {
1672    fn transpose(&self) -> Self {
1673        let mut t = *self;
1674        for r in 0..t.get_num_rows() as u32 {
1675            for c in 0..t.get_num_columns() as u32 {
1676                t.set(c, r, self.at(r, c));
1677            }
1678        }
1679        t
1680    }
1681}
1682
1683impl<T> MatTranspose<T, Self> for Mat4<T> where T: Number {
1684    fn transpose(&self) -> Self {
1685        let mut t = *self;
1686        for r in 0..t.get_num_rows() as u32 {
1687            for c in 0..t.get_num_columns() as u32 {
1688                t.set(c, r, self.at(r, c));
1689            }
1690        }
1691        t
1692    }
1693}
1694
1695impl<T> MatTranspose<T, Mat43<T>> for Mat34<T> where T: Number {
1696    fn transpose(&self) -> Mat43<T> {
1697        let mut t = Mat43 {
1698            m: [T::zero(); 12]
1699        };
1700        for r in 0..3 {
1701            for c in 0..4 {
1702                let i = c * 3 + r;
1703                let v = self.at(r as u32, c as u32);
1704                t.m[i] = v;
1705            }
1706        }
1707        t
1708    }
1709}
1710
1711impl<T> MatTranspose<T, Mat34<T>> for Mat43<T> where T: Number {
1712    fn transpose(&self) -> Mat34<T> {
1713        let mut t = Mat34 {
1714            m: [T::zero(); 12]
1715        };
1716        for r in 0..4 {
1717            for c in 0..3 {
1718                let i = r * 3 + c;
1719                t.set(c, r, self.m[i as usize]);
1720            }
1721        }
1722        t
1723    }
1724}
1725
1726/// trait for the minor of a matrix
1727/// the minor is the determinant of the matrix without the given row and column
1728pub trait MatMinor<T, Other> {
1729    fn minor(&self, row: u32, column: u32) -> T;
1730}
1731
1732impl<T> MatMinor<T, T> for Mat2<T> where T: Number {
1733    fn minor(&self, row: u32, column: u32) -> T {
1734        self.at(1 - row, 1 - column)
1735    }
1736}
1737
1738impl<T> MatMinor<T, Mat2<T>> for Mat3<T> where T: Number {
1739    fn minor(&self, row: u32, column: u32) -> T {
1740        let mut m = Mat2::zero();
1741        let mut pos = 0;
1742        
1743        for l in 0..3 {
1744            for k in 0..3 {
1745                if l != row && k != column {
1746                    m.set(pos / 2, pos % 2, self.at(l, k));
1747                    pos += 1;
1748                }
1749            }
1750        }
1751        
1752        m.determinant()
1753    }
1754}
1755
1756impl<T> MatMinor<T, Mat3<T>> for Mat4<T> where T: Number {
1757    fn minor(&self, row: u32, column: u32) -> T {
1758        let mut m = Mat3::zero();
1759        let mut pos = 0;
1760        
1761        for l in 0..4 {
1762            for k in 0..4 {
1763                if l != row && k != column {
1764                    m.set(pos / 3, pos % 3, self.at(l, k));
1765                    pos += 1;
1766                }
1767            }
1768        }
1769        
1770        m.determinant()
1771    }
1772}
1773
1774/// trait for the cofactor of a matrix
1775/// the cofactor is the minor with an alternating sign, multiplied by (-1)^(row+column)
1776pub trait MatCofactor<T, Other> {
1777    fn cofactor(&self, row: u32, column: u32) -> T;
1778}
1779
1780impl <T> MatCofactor<T, T> for Mat2<T> where T: SignedNumber {
1781    fn cofactor(&self, row: u32, column: u32) -> T {
1782        let sign = if (row + column & 1) == 1 { T::minus_one() } else { T::one() };
1783        sign * self.minor(row, column)
1784    }
1785}
1786
1787impl<T> MatCofactor<T, T> for Mat3<T> where T: SignedNumber {
1788    fn cofactor(&self, row: u32, column: u32) -> T {
1789        let sign = if (row + column & 1) == 1 { T::minus_one() } else { T::one() };
1790        sign * self.minor(row, column)
1791    }
1792}
1793
1794impl<T> MatCofactor<T, T> for Mat4<T> where T: SignedNumber {
1795    fn cofactor(&self, row: u32, column: u32) -> T {
1796        let sign = if (row + column & 1) == 1 { T::minus_one() } else { T::one() };
1797        sign * self.minor(row, column)
1798    }
1799}
1800
1801/// trait for the adjugate of a matrix
1802/// the adjugate is the transpose of the cofactor matrix
1803/// the cofactor matrix is the matrix where each element is replaced by its cofactor
1804pub trait MatAdjugate<T> {
1805    fn adjugate(&self) -> Self;
1806}
1807
1808impl<T> MatAdjugate<T> for Mat2<T> where T: SignedNumber {
1809    fn adjugate(&self) -> Self {
1810        let mut output = Mat2::zero();
1811        output.set(0, 0, self.cofactor(0, 0));
1812        output.set(0, 1, self.cofactor(1, 0));
1813        output.set(1, 0, self.cofactor(0, 1));
1814        output.set(1, 1, self.cofactor(1, 1));
1815        
1816        output
1817    }
1818}
1819
1820impl<T> MatAdjugate<T> for Mat3<T> where T: SignedNumber {
1821    fn adjugate(&self) -> Self {
1822        let mut output = Mat3::zero();
1823        for j in 0..3 {
1824            for i in 0..3 {
1825                output.set(i, j, self.cofactor(i, j));
1826            }
1827        }
1828        
1829        output.transpose()
1830    }
1831}
1832
1833impl<T> MatAdjugate<T> for Mat4<T> where T: SignedNumber {
1834    fn adjugate(&self) -> Self {
1835        let mut output = Mat4::zero();
1836        for j in 0..4 {
1837            for i in 0..4 {
1838                output.set(i, j, self.cofactor(i, j));
1839            }
1840        }
1841        
1842        output.transpose()
1843    }
1844}
1845
1846/// trait for 4x4 projection matrices
1847pub trait MatProjection<T> {
1848    /// returns 6 frustum planes as `Vec4`'s in the form `.xyz = normal, .w = plane distance`
1849    fn get_frustum_planes(&self) -> [Vec4<T>; 6];
1850    /// returns 8 points which are the corners of the frustum first 4 near, second 4 far
1851    fn get_frustum_corners(&self) -> [Vec3<T>; 8];
1852    /// returns an orthogrpahic projection matrix defined by `left`, `right`, `top`, `bottom` edges and `near` - `far` depth range
1853    fn create_ortho_matrix(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Self;
1854    /// returns a perespective projection matrix (left hand coordinate system with y-up) from `fov` (radians), `aspect` ratio and `near` - `far` depth
1855    fn create_perspective_projection_lh_yup(fov: T, aspect: T, near: T, far: T) -> Self;
1856    /// returns a perespective projection matrix (right hand coordinate system with y-up) from `fov` (radians), `aspect` ratio and `near` - `far` depth
1857    fn create_perspective_projection_rh_yup(fov: T, aspect: T, near: T, far: T) -> Self;
1858}
1859
1860/// internal utility function to extract a plane in the form `.xyz=normal, w=constant` from plane corners (of a frustum)
1861fn plane_from_vectors<T: Float + FloatOps<T>>(plane_vectors: &[Vec3<T>; 18], offset: usize) -> Vec4<T> {
1862    let v1 = super::normalize(plane_vectors[offset + 1] - plane_vectors[offset]);
1863    let v2 = super::normalize(plane_vectors[offset + 2] - plane_vectors[offset]);
1864    let pn = super::cross(v1, v2);
1865    let pd = super::plane_distance(plane_vectors[offset], pn);
1866    Vec4::from((pn, pd))
1867}
1868
1869fn create_perspective_matrix_internal_lh<T: Float + FloatOps<T>>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> {
1870    Mat4::from((
1871        Vec4::new((T::two() * near) / (right - left), T::zero(), (right + left) / (right - left), T::zero()),
1872        Vec4::new(T::zero(), (T::two() * near) / (top - bottom), (top + bottom) / (top - bottom), T::zero()),
1873        Vec4::new(T::zero(), T::zero(), (-far - near) / (far - near), (-(T::two() * near) * far) / (far - near)),
1874        Vec4::new(T::zero(), T::zero(), T::minus_one(), T::zero())
1875    ))
1876}
1877
1878fn create_perspective_matrix_internal_rh<T: Float + FloatOps<T>>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> {
1879    Mat4::from((
1880        Vec4::new((T::two() * near) / (right - left), T::zero(), (right + left) / (right - left), T::zero()),
1881        Vec4::new(T::zero(), (T::two() * near) / (top - bottom), (top + bottom) / (top - bottom), T::zero()),
1882        Vec4::new(T::zero(), T::zero(), (-far - near) / (far - near), (-(T::two() * near) * far) / (far - near)),
1883        Vec4::new(T::zero(), T::zero(), T::one(), T::zero())
1884    ))
1885}
1886
1887impl<T> MatProjection<T> for Mat4<T> where T: Float + FloatOps<T>, Vec3<T>: FloatOps<T> {
1888    fn get_frustum_planes(&self) -> [Vec4<T>; 6] {
1889        // unproject matrix to get frustum corners grouped as 4 near, 4 far.
1890        let ndc_coords = [
1891            Vec2::<T>::new(T::zero(), T::one()),
1892            Vec2::<T>::new(T::one(), T::one()),
1893            Vec2::<T>::new(T::zero(), T::zero()),
1894            Vec2::<T>::new(T::one(), T::zero()),
1895        ];
1896
1897        // construct corner points
1898        let corners = [[
1899            super::unproject_sc(Vec3::from((ndc_coords[0], T::zero())), *self, Vec2::one()),
1900            super::unproject_sc(Vec3::from((ndc_coords[1], T::zero())), *self, Vec2::one()),
1901            super::unproject_sc(Vec3::from((ndc_coords[2], T::zero())), *self, Vec2::one()),
1902            super::unproject_sc(Vec3::from((ndc_coords[3], T::zero())), *self, Vec2::one()),
1903        ],
1904        [
1905            super::unproject_sc(Vec3::from((ndc_coords[0], T::one())), *self, Vec2::one()),
1906            super::unproject_sc(Vec3::from((ndc_coords[1], T::one())), *self, Vec2::one()),
1907            super::unproject_sc(Vec3::from((ndc_coords[2], T::one())), *self, Vec2::one()),
1908            super::unproject_sc(Vec3::from((ndc_coords[3], T::one())), *self, Vec2::one()),
1909        ]];
1910
1911        // construct vectors to obtain normals
1912        let plane_vectors = [
1913            corners[0][0], corners[1][0], corners[0][2], // left
1914            corners[0][0], corners[0][1], corners[1][0], // top
1915            corners[0][1], corners[0][3], corners[1][1], // right
1916            corners[0][2], corners[1][2], corners[0][3], // bottom
1917            corners[0][0], corners[0][2], corners[0][1], // near
1918            corners[1][0], corners[1][1], corners[1][2]  // far
1919        ];
1920
1921        // return array of planes
1922        [
1923            plane_from_vectors(&plane_vectors, 0),
1924            plane_from_vectors(&plane_vectors, 3),
1925            plane_from_vectors(&plane_vectors, 6),
1926            plane_from_vectors(&plane_vectors, 9),
1927            plane_from_vectors(&plane_vectors, 12),
1928            plane_from_vectors(&plane_vectors, 15),
1929        ]
1930    }
1931
1932    fn get_frustum_corners(&self) -> [Vec3<T>; 8] {
1933        // unproject matrix to get frustum corners grouped as 4 near, 4 far.
1934        let ndc_coords = [
1935            Vec2::<T>::new(T::zero(), T::one()),
1936            Vec2::<T>::new(T::one(), T::one()),
1937            Vec2::<T>::new(T::zero(), T::zero()),
1938            Vec2::<T>::new(T::one(), T::zero()),
1939        ];
1940
1941        // construct corner points
1942        [
1943            super::unproject_sc(Vec3::from((ndc_coords[0], T::zero())), *self, Vec2::one()),
1944            super::unproject_sc(Vec3::from((ndc_coords[1], T::zero())), *self, Vec2::one()),
1945            super::unproject_sc(Vec3::from((ndc_coords[2], T::zero())), *self, Vec2::one()),
1946            super::unproject_sc(Vec3::from((ndc_coords[3], T::zero())), *self, Vec2::one()),
1947            super::unproject_sc(Vec3::from((ndc_coords[0], T::one())), *self, Vec2::one()),
1948            super::unproject_sc(Vec3::from((ndc_coords[1], T::one())), *self, Vec2::one()),
1949            super::unproject_sc(Vec3::from((ndc_coords[2], T::one())), *self, Vec2::one()),
1950            super::unproject_sc(Vec3::from((ndc_coords[3], T::one())), *self, Vec2::one()),
1951        ]
1952    }
1953
1954    fn create_ortho_matrix(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> {
1955        Mat4::from((
1956            Vec4::new(T::two() / (right - left), T::zero(), T::zero(), T::zero()),
1957            Vec4::new(T::zero(), T::two() / (top - bottom), T::zero(), T::zero()),
1958            Vec4::new(T::zero(), T::zero(), T::one() / (near - far), T::zero()),
1959            Vec4::new((right + left) / (left - right), (top + bottom) / (bottom - top), near / (near - far), T::one()),
1960        ))
1961    }
1962
1963    fn create_perspective_projection_lh_yup(fov: T, aspect: T, near: T, far: T) -> Mat4<T> {
1964        let tfov = T::tan(fov * T::point_five());
1965        let right = tfov * aspect * near;
1966        let left = -right;
1967        let top = tfov * near;
1968        let bottom = -top;
1969        create_perspective_matrix_internal_lh(left, right, bottom, top, near, far)
1970    }
1971
1972    fn create_perspective_projection_rh_yup(fov: T, aspect: T, near: T, far: T) -> Mat4<T> {
1973        let tfov = T::tan(fov * T::point_five());
1974        let right = tfov * aspect * near;
1975        let left = -right;
1976        let top = tfov * near;
1977        let bottom = -top;
1978        create_perspective_matrix_internal_rh(left, right, bottom, top, near, far)
1979    }
1980}
1981
1982/// trait to construct matrix from 4 scalars
1983pub trait MatNew2<T> {
1984    fn new(
1985        m00: T, m01: T,
1986        m10: T, m11: T
1987    ) -> Self;
1988}
1989
1990impl<T> MatNew2<T> for Mat2<T> where T: Number {
1991    fn new(
1992        m00: T, m01: T,
1993        m10: T, m11: T
1994    ) -> Self {
1995        Self {
1996            m: [
1997                m00, m01,
1998                m10, m11
1999            ]
2000        }
2001    }
2002}
2003
2004#[allow(clippy::too_many_arguments)]
2005/// trait to construct matrix from 9 scalars
2006pub trait MatNew3<T> {
2007    fn new(
2008        m00: T, m01: T, m02: T,
2009        m10: T, m11: T, m12: T,
2010        m20: T, m21: T, m22: T,
2011    ) -> Self;
2012}
2013
2014impl<T> MatNew3<T> for Mat3<T> where T: Number {
2015    fn new(
2016        m00: T, m01: T, m02: T,
2017        m10: T, m11: T, m12: T,
2018        m20: T, m21: T, m22: T,
2019    ) -> Self {
2020        Self {
2021            m: [
2022                m00, m01, m02,
2023                m10, m11, m12,
2024                m20, m21, m22,
2025            ]
2026        }
2027    }
2028}
2029
2030#[allow(clippy::too_many_arguments)]
2031/// trait to construct matrix from 12 scalars
2032pub trait MatNew34<T> {
2033    fn new(
2034        m00: T, m01: T, m02: T, m03: T,
2035        m10: T, m11: T, m12: T, m13: T,
2036        m20: T, m21: T, m22: T, m23: T,
2037    ) -> Self;
2038}
2039
2040impl<T> MatNew34<T> for Mat34<T> where T: Number {
2041    fn new(
2042        m00: T, m01: T, m02: T, m03: T,
2043        m10: T, m11: T, m12: T, m13: T,
2044        m20: T, m21: T, m22: T, m23: T,
2045    ) -> Self {
2046        Self {
2047            m: [
2048                m00, m01, m02, m03,
2049                m10, m11, m12, m13,
2050                m20, m21, m22, m23
2051            ]
2052        }
2053    }
2054}
2055
2056#[allow(clippy::too_many_arguments)]
2057/// trait to construct matrix from 12 scalars
2058pub trait MatNew43<T> {
2059    fn new(
2060        m00: T, m01: T, m02: T,
2061        m03: T, m10: T, m11: T,
2062        m12: T, m13: T, m20: T,
2063        m21: T, m22: T, m23: T,
2064    ) -> Self;
2065}
2066
2067impl<T> MatNew43<T> for Mat43<T> where T: Number {
2068    fn new(
2069        m00: T, m01: T, m02: T,
2070        m03: T, m10: T, m11: T,
2071        m12: T, m13: T, m20: T,
2072        m21: T, m22: T, m23: T,
2073    ) -> Self {
2074        Self {
2075            m: [
2076                m00, m01, m02,
2077                m03, m10, m11,
2078                m12, m13, m20,
2079                m21, m22, m23
2080            ]
2081        }
2082    }
2083}
2084
2085#[allow(clippy::too_many_arguments)]
2086/// trait to construct matrix from 16 scalars
2087pub trait MatNew4<T> {
2088    fn new(
2089        m00: T, m01: T, m02: T, m03: T,
2090        m10: T, m11: T, m12: T, m13: T,
2091        m20: T, m21: T, m22: T, m23: T,
2092        m30: T, m31: T, m32: T, m33: T,
2093    ) -> Self;
2094}
2095
2096impl<T> MatNew4<T> for Mat4<T> where T: Number {
2097    fn new(
2098        m00: T, m01: T, m02: T, m03: T,
2099        m10: T, m11: T, m12: T, m13: T,
2100        m20: T, m21: T, m22: T, m23: T,
2101        m30: T, m31: T, m32: T, m33: T,
2102    ) -> Self {
2103        Self {
2104            m: [
2105                m00, m01, m02, m03,
2106                m10, m11, m12, m13,
2107                m20, m21, m22, m23,
2108                m30, m31, m32, m33
2109            ]
2110        }
2111    }
2112}
2113
2114mat_impl!(Mat2, 2, 2, 4, Vec2 {x, 0, y, 1}, Vec2 {x, 0, y, 1});
2115mat_impl!(Mat3, 3, 3, 9, Vec3 {x, 0, y, 1, z, 2}, Vec3 {x, 0, y, 1, z, 2});
2116mat_impl!(Mat4, 4, 4, 16, Vec4 {x, 0, y, 1, z, 2, w, 3}, Vec4 {x, 0, y, 1, z, 2, w, 3});
2117mat_impl!(Mat34, 3, 4, 12, Vec4 {x, 0, y, 1, z, 2, w, 3}, Vec3 {x, 0, y, 1, z, 2});
2118mat_impl!(Mat43, 4, 3, 12, Vec3 {x, 0, y, 1, z, 2}, Vec4 {x, 0, y, 1, z, 2, w, 3});