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