vecmath/
lib.rs

1#![deny(missing_docs)]
2
3//! A simple and generic library for vector math.
4//!
5//! Notice that row major is mathematical standard,
6//! while OpenGL uses column major format.
7//! This library supports both formats, prefixing functions with 'row_' or 'col_'.
8//!
9//! For row major affine transforms, use `Matrix2x3` (2D) and `Matrix3x4` (3D).
10//! For column major affine transforms, use `Matrix3x2` (2D) and `Matrix4x3` (3D).
11//!
12//! If you are using `Matrix3` or `Matrix4`,
13//! then you need to pick either row or column major.
14//!
15//! Notice that there are two kinds of transforms: Positions and vectors.
16//! The vector transforms ignores the translate component.
17//! For example, `row_mat2x3_transform_pos2` transforms a position.
18//! `row_mat2x3_transform_vec2` transforms a vector.
19
20extern crate float;
21
22use std::ops::{ Add, Mul, Neg, Sub, Div };
23
24pub mod traits;
25
26/// A 2D vector.
27pub type Vector2<T> = [T; 2];
28
29/// A 3D vector.
30pub type Vector3<T> = [T; 3];
31
32/// A 4D vector.
33pub type Vector4<T> = [T; 4];
34
35/// A 2x3 matrix.
36///
37/// To multiply two matrices use `row_mat2x3_mul`.
38pub type Matrix2x3<T> = [[T; 3]; 2];
39
40/// A 3x2 matrix.
41///
42/// To multiply two matrices use `col_mat3x2_mul`.
43pub type Matrix3x2<T> = [[T; 2]; 3];
44
45/// A 3x3 matrix.
46///
47/// To multiply two matrices use `row_mat3_mul` or `col_mat3_mul`.
48pub type Matrix3<T> = [[T; 3]; 3];
49
50/// A 3x4 matrix.
51///
52/// To multiply two matrices use `row_mat3x4_mul`.
53pub type Matrix3x4<T> = [[T; 4]; 3];
54
55/// A 4x3 matrix.
56///
57/// To multiply two matrices use `col_mat4x3_mul`.
58///
59/// This format can also store vertices of a quad.
60pub type Matrix4x3<T> = [[T; 3]; 4];
61
62/// A 4x4 matrix.
63///
64/// To multiply two matrices use `row_mat4_mul` or `col_mat4_mul`.
65pub type Matrix4<T> = [[T; 4]; 4];
66
67/// Computes column vector in column matrix product.
68///
69/// The semantics of the order is the same as for row matrices.
70#[inline(always)]
71pub fn col_mat3x2_mul_col<T>(
72    a: Matrix3x2<T>,
73    b: Matrix3x2<T>,
74    i: usize
75) -> Vector2<T>
76    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
77{
78    [
79        vec3_dot_vec2(col_mat3x2_row(a, 0), b[i]),
80        vec3_dot_vec2(col_mat3x2_row(a, 1), b[i])
81    ]
82}
83
84/// Computes column vector in column matrix product.
85///
86/// The semantics of the order is the same as for row matrices.
87#[inline(always)]
88pub fn col_mat3_mul_col<T>(
89    a: Matrix3<T>,
90    b: Matrix3<T>,
91    i: usize
92) -> Vector3<T>
93    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
94{
95    [
96        vec3_dot(col_mat3_row(a, 0), b[i]),
97        vec3_dot(col_mat3_row(a, 1), b[i]),
98        vec3_dot(col_mat3_row(a, 2), b[i])
99    ]
100}
101
102/// Computes column vector in column matrix product.
103///
104/// The semantics of the order is the same as for row matrices.
105#[inline(always)]
106pub fn col_mat4x3_mul_col<T>(
107    a: Matrix4x3<T>,
108    b: Matrix4x3<T>,
109    i: usize
110) -> Vector3<T>
111    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
112{
113    [
114        vec4_dot_vec3(col_mat4x3_row(a, 0), b[i]),
115        vec4_dot_vec3(col_mat4x3_row(a, 1), b[i]),
116        vec4_dot_vec3(col_mat4x3_row(a, 2), b[i])
117    ]
118}
119
120/// Computes column vector in column matrix product.
121///
122/// The semantics of the order is the same as for row matrices.
123#[inline(always)]
124pub fn col_mat4_mul_col<T>(
125    a: Matrix4<T>,
126    b: Matrix4<T>,
127    i: usize
128) -> Vector4<T>
129    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
130{
131    [
132        vec4_dot(col_mat4_row(a, 0), b[i]),
133        vec4_dot(col_mat4_row(a, 1), b[i]),
134        vec4_dot(col_mat4_row(a, 2), b[i]),
135        vec4_dot(col_mat4_row(a, 3), b[i])
136    ]
137}
138
139/// Computes row vector in row matrix product.
140#[inline(always)]
141pub fn row_mat2x3_mul_row<T>(
142    a: Matrix2x3<T>,
143    b: Matrix2x3<T>,
144    i: usize
145) -> Vector3<T>
146    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
147{
148    [
149        vec3_dot_vec2(a[i], row_mat2x3_col(b, 0)),
150        vec3_dot_vec2(a[i], row_mat2x3_col(b, 1)),
151        vec3_dot_pos2(a[i], row_mat2x3_col(b, 2))
152    ]
153}
154
155/// Computes row vector in row matrix product.
156#[inline(always)]
157pub fn row_mat3_mul_row<T>(
158    a: Matrix3<T>,
159    b: Matrix3<T>,
160    i: usize
161) -> Vector3<T>
162    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
163{
164    [
165        vec3_dot(a[i], row_mat3_col(b, 0)),
166        vec3_dot(a[i], row_mat3_col(b, 1)),
167        vec3_dot(a[i], row_mat3_col(b, 2)),
168    ]
169}
170
171/// Computes row vector in row matrix product.
172#[inline(always)]
173pub fn row_mat3x4_mul_row<T>(
174    a: Matrix3x4<T>,
175    b: Matrix3x4<T>,
176    i: usize
177) -> Vector4<T>
178    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
179{
180    [
181        vec4_dot_vec3(a[i], row_mat3x4_col(b, 0)),
182        vec4_dot_vec3(a[i], row_mat3x4_col(b, 1)),
183        vec4_dot_vec3(a[i], row_mat3x4_col(b, 2)),
184        vec4_dot_pos3(a[i], row_mat3x4_col(b, 3))
185    ]
186}
187
188/// Computes row vector in row matrix product.
189#[inline(always)]
190pub fn row_mat4_mul_row<T>(
191    a: Matrix4<T>,
192    b: Matrix4<T>,
193    i: usize
194) -> Vector4<T>
195    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
196{
197    [
198        vec4_dot(a[i], row_mat4_col(b, 0)),
199        vec4_dot(a[i], row_mat4_col(b, 1)),
200        vec4_dot(a[i], row_mat4_col(b, 2)),
201        vec4_dot(a[i], row_mat4_col(b, 3))
202    ]
203}
204
205/// Multiplies two matrices.
206#[inline(always)]
207pub fn col_mat3x2_mul<T>(
208    a: Matrix3x2<T>,
209    b: Matrix3x2<T>
210) -> Matrix3x2<T>
211    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
212{
213    [
214        col_mat3x2_mul_col(a, b, 0),
215        col_mat3x2_mul_col(a, b, 1),
216        col_mat3x2_mul_col(a, b, 2)
217    ]
218}
219
220/// Multiplies two matrices.
221#[inline(always)]
222pub fn col_mat3_mul<T>(
223    a: Matrix3<T>,
224    b: Matrix3<T>
225) -> Matrix3<T>
226    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
227{
228    [
229        col_mat3_mul_col(a, b, 0),
230        col_mat3_mul_col(a, b, 1),
231        col_mat3_mul_col(a, b, 2)
232    ]
233}
234
235/// Multiplies two matrices.
236#[inline(always)]
237pub fn col_mat4x3_mul<T>(
238    a: Matrix4x3<T>,
239    b: Matrix4x3<T>
240) -> Matrix4x3<T>
241    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
242{
243    [
244        col_mat4x3_mul_col(a, b, 0),
245        col_mat4x3_mul_col(a, b, 1),
246        col_mat4x3_mul_col(a, b, 2),
247        col_mat4x3_mul_col(a, b, 3)
248    ]
249}
250
251/// Multiplies two matrices.
252#[inline(always)]
253pub fn col_mat4_mul<T>(
254    a: Matrix4<T>,
255    b: Matrix4<T>
256) -> Matrix4<T>
257    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
258{
259    [
260        col_mat4_mul_col(a, b, 0),
261        col_mat4_mul_col(a, b, 1),
262        col_mat4_mul_col(a, b, 2),
263        col_mat4_mul_col(a, b, 3)
264    ]
265}
266
267/// Multiplies two matrices.
268#[inline(always)]
269pub fn row_mat2x3_mul<T>(
270    a: Matrix2x3<T>,
271    b: Matrix2x3<T>
272) -> Matrix2x3<T>
273    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
274{
275    [
276        row_mat2x3_mul_row(a, b, 0),
277        row_mat2x3_mul_row(a, b, 1),
278    ]
279}
280
281/// Multiplies two matrices.
282#[inline(always)]
283pub fn row_mat3_mul<T>(
284    a: Matrix3<T>,
285    b: Matrix3<T>
286) -> Matrix3<T>
287    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
288{
289    [
290        row_mat3_mul_row(a, b, 0),
291        row_mat3_mul_row(a, b, 1),
292        row_mat3_mul_row(a, b, 2)
293    ]
294}
295
296/// Multiplies two matrices.
297#[inline(always)]
298pub fn row_mat3x4_mul<T>(
299    a: Matrix3x4<T>,
300    b: Matrix3x4<T>
301) -> Matrix3x4<T>
302    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
303{
304    [
305        row_mat3x4_mul_row(a, b, 0),
306        row_mat3x4_mul_row(a, b, 1),
307        row_mat3x4_mul_row(a, b, 2)
308    ]
309}
310
311/// Multiplies two matrices.
312#[inline(always)]
313pub fn row_mat4_mul<T>(
314    a: Matrix4<T>,
315    b: Matrix4<T>
316) -> Matrix4<T>
317    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
318{
319    [
320        row_mat4_mul_row(a, b, 0),
321        row_mat4_mul_row(a, b, 1),
322        row_mat4_mul_row(a, b, 2),
323        row_mat4_mul_row(a, b, 3)
324    ]
325}
326
327/// Constructs identity matrix.
328#[inline(always)]
329pub fn mat2x3_id<T>() -> Matrix2x3<T>
330    where T: Copy + traits::One + traits::Zero
331{
332    let one = T::one();
333    let zero = T::zero();
334    [
335        [one, zero, zero],
336        [zero, one, zero]
337    ]
338}
339
340/// Constructs identity matrix.
341#[inline(always)]
342pub fn mat3x2_id<T>() -> Matrix3x2<T>
343    where T: Copy + traits::One + traits::Zero
344{
345    let one = T::one();
346    let zero = T::zero();
347    [
348        [one, zero],
349        [zero, one],
350        [zero, zero]
351    ]
352}
353
354/// Constructs identity matrix.
355#[inline(always)]
356pub fn mat3_id<T>() -> Matrix3<T>
357    where T: Copy + traits::One + traits::Zero
358{
359    let one = T::one();
360    let zero = T::zero();
361    [
362        [one, zero, zero],
363        [zero, one, zero],
364        [zero, zero, one]
365    ]
366}
367
368/// Constructs identity matrix.
369#[inline(always)]
370pub fn mat3x4_id<T>() -> Matrix3x4<T>
371    where T: Copy + traits::One + traits::Zero
372{
373    let one = T::one();
374    let zero = T::zero();
375    [
376        [one, zero, zero, zero],
377        [zero, one, zero, zero],
378        [zero, zero, one, zero]
379    ]
380}
381
382/// Constructs identity matrix.
383#[inline(always)]
384pub fn mat4x3_id<T>() -> Matrix4x3<T>
385    where T: Copy + traits::One + traits::Zero
386{
387    let one = T::one();
388    let zero = T::zero();
389    [
390        [one, zero, zero],
391        [zero, one, zero],
392        [zero, zero, one],
393        [zero, zero, zero]
394    ]
395}
396
397/// Constructs identity matrix.
398#[inline(always)]
399pub fn mat4_id<T>() -> Matrix4<T>
400    where T: Copy + traits::One + traits::Zero
401{
402    let one = T::one();
403    let zero = T::zero();
404    [
405        [one, zero, zero, zero],
406        [zero, one, zero, zero],
407        [zero, zero, one, zero],
408        [zero, zero, zero, one]
409    ]
410}
411
412/// Converts to another vector type.
413#[inline(always)]
414pub fn vec2_cast<T, U>(a: Vector2<T>) -> Vector2<U>
415    where T: Copy + traits::Cast<U>
416{
417    [
418        a[0].cast(),
419        a[1].cast()
420    ]
421}
422
423/// Converts to another vector type.
424#[inline(always)]
425pub fn vec3_cast<T, U>(a: Vector3<T>) -> Vector3<U>
426    where T: Copy + traits::Cast<U>
427{
428    [
429        a[0].cast(),
430        a[1].cast(),
431        a[2].cast()
432    ]
433}
434
435/// Converts to another vector type.
436#[inline(always)]
437pub fn vec4_cast<T, U>(a: Vector4<T>) -> Vector4<U>
438    where T: Copy + traits::Cast<U>
439{
440    [
441        a[0].cast(),
442        a[1].cast(),
443        a[2].cast(),
444        a[3].cast()
445    ]
446}
447
448/// Converts to another matrix type.
449#[inline(always)]
450pub fn mat2x3_cast<T, U>(mat: Matrix2x3<T>) -> Matrix2x3<U>
451    where T: Copy + traits::Cast<U>
452{
453    [
454        vec3_cast(mat[0]),
455        vec3_cast(mat[1])
456    ]
457}
458
459/// Converts to another matrix type.
460#[inline(always)]
461pub fn mat3x2_cast<T, U>(mat: Matrix3x2<T>) -> Matrix3x2<U>
462    where T: Copy + traits::Cast<U>
463{
464    [
465        vec2_cast(mat[0]),
466        vec2_cast(mat[1]),
467        vec2_cast(mat[2])
468    ]
469}
470
471/// Converts to another matrix type.
472#[inline(always)]
473pub fn mat3_cast<T, U>(mat: Matrix3<T>) -> Matrix3<U>
474    where T: Copy + traits::Cast<U>
475{
476    [
477        vec3_cast(mat[0]),
478        vec3_cast(mat[1]),
479        vec3_cast(mat[2])
480    ]
481}
482
483/// Converts to another matrix type.
484#[inline(always)]
485pub fn mat3x4_cast<T, U>(m: Matrix3x4<T>) -> Matrix3x4<U>
486    where T: Copy + traits::Cast<U>
487{
488    [
489        vec4_cast(m[0]),
490        vec4_cast(m[1]),
491        vec4_cast(m[2])
492    ]
493}
494
495/// Converts to another matrix type.
496#[inline(always)]
497pub fn mat4x3_cast<T, U>(m: Matrix4x3<T>) -> Matrix4x3<U>
498    where T: Copy + traits::Cast<U>
499{
500    [
501        vec3_cast(m[0]),
502        vec3_cast(m[1]),
503        vec3_cast(m[2]),
504        vec3_cast(m[3])
505    ]
506}
507
508/// Converts to another matrix type.
509#[inline(always)]
510pub fn mat4_cast<T, U>(m: Matrix4<T>) -> Matrix4<U>
511    where T: Copy + traits::Cast<U>
512{
513    [
514        vec4_cast(m[0]),
515        vec4_cast(m[1]),
516        vec4_cast(m[2]),
517        vec4_cast(m[3])
518    ]
519}
520
521/// Subtracts 'b' from 'a'.
522#[inline(always)]
523pub fn vec2_sub<T>(a: Vector2<T>, b: Vector2<T>) -> Vector2<T>
524    where T: Copy + Sub<T, Output = T>
525{
526    [
527        a[0] - b[0],
528        a[1] - b[1],
529    ]
530}
531
532/// Subtracts 'b' from 'a'.
533#[inline(always)]
534pub fn vec3_sub<T>(a: Vector3<T>, b: Vector3<T>) -> Vector3<T>
535    where T: Copy + Sub<T, Output = T>
536{
537    [
538        a[0] - b[0],
539        a[1] - b[1],
540        a[2] - b[2],
541    ]
542}
543
544/// Subtracts 'b' from 'a'.
545#[inline(always)]
546pub fn vec4_sub<T>(a: Vector4<T>, b: Vector4<T>) -> Vector4<T>
547    where T: Copy + Sub<T, Output = T>
548{
549    [
550        a[0] - b[0],
551        a[1] - b[1],
552        a[2] - b[2],
553        a[3] - b[3]
554    ]
555}
556
557/// Subtracts 'b' from 'a'.
558#[inline(always)]
559pub fn mat2x3_sub<T>(a: Matrix2x3<T>, b: Matrix2x3<T>) -> Matrix2x3<T>
560    where T: Copy + Sub<T, Output = T>
561{
562    [
563        vec3_sub(a[0], b[0]),
564        vec3_sub(a[1], b[1])
565    ]
566}
567
568/// Subtracts 'b' from 'a'.
569#[inline(always)]
570pub fn mat3x2_sub<T>(a: Matrix3x2<T>, b: Matrix3x2<T>) -> Matrix3x2<T>
571    where T: Copy + Sub<T, Output = T>
572{
573    [
574        vec2_sub(a[0], b[0]),
575        vec2_sub(a[1], b[1]),
576        vec2_sub(a[2], b[2])
577    ]
578}
579
580/// Subtracts 'b' from 'a'.
581#[inline(always)]
582pub fn mat3_sub<T>(a: Matrix3<T>, b: Matrix3<T>) -> Matrix3<T>
583    where T: Copy + Sub<T, Output = T>
584{
585    [
586        vec3_sub(a[0], b[0]),
587        vec3_sub(a[1], b[1]),
588        vec3_sub(a[2], b[2])
589    ]
590}
591
592/// Subtracts 'b' from 'a'.
593#[inline(always)]
594pub fn mat3x4_sub<T>(a: Matrix3x4<T>, b: Matrix3x4<T>) -> Matrix3x4<T>
595    where T: Copy + Sub<T, Output = T>
596{
597    [
598        vec4_sub(a[0], b[0]),
599        vec4_sub(a[1], b[1]),
600        vec4_sub(a[2], b[2])
601    ]
602}
603
604/// Subtracts 'b' from 'a'.
605#[inline(always)]
606pub fn mat4x3_sub<T>(a: Matrix4x3<T>, b: Matrix4x3<T>) -> Matrix4x3<T>
607    where T: Copy + Sub<T, Output = T>
608{
609    [
610        vec3_sub(a[0], b[0]),
611        vec3_sub(a[1], b[1]),
612        vec3_sub(a[2], b[2]),
613        vec3_sub(a[3], b[3])
614    ]
615}
616
617/// Subtracts 'b' from 'a'.
618#[inline(always)]
619pub fn mat4_sub<T>(a: Matrix4<T>, b: Matrix4<T>) -> Matrix4<T>
620    where T: Copy + Sub<T, Output = T>
621{
622    [
623        vec4_sub(a[0], b[0]),
624        vec4_sub(a[1], b[1]),
625        vec4_sub(a[2], b[2]),
626        vec4_sub(a[3], b[3])
627    ]
628}
629
630/// Adds two vectors.
631#[inline(always)]
632pub fn vec2_add<T>(a: Vector2<T>, b: Vector2<T>) -> Vector2<T>
633    where T: Copy + Add<T, Output = T>
634{
635    [
636        a[0] + b[0],
637        a[1] + b[1],
638    ]
639}
640
641/// Adds two vectors.
642#[inline(always)]
643pub fn vec3_add<T>(a: Vector3<T>, b: Vector3<T>) -> Vector3<T>
644    where T: Copy + Add<T, Output = T>
645{
646    [
647        a[0] + b[0],
648        a[1] + b[1],
649        a[2] + b[2]
650    ]
651}
652
653/// Adds two vectors.
654#[inline(always)]
655pub fn vec4_add<T>(a: Vector4<T>, b: Vector4<T>) -> Vector4<T>
656    where T: Copy + Add<T, Output = T>
657{
658    [
659        a[0] + b[0],
660        a[1] + b[1],
661        a[2] + b[2],
662        a[3] + b[3]
663    ]
664}
665
666/// Adds two matrices.
667#[inline(always)]
668pub fn mat2x3_add<T>(a: Matrix2x3<T>, b: Matrix2x3<T>) -> Matrix2x3<T>
669    where T: Copy + Add<T, Output = T>
670{
671    [
672        vec3_add(a[0], b[0]),
673        vec3_add(a[1], b[1])
674    ]
675}
676
677/// Adds two matrices.
678#[inline(always)]
679pub fn mat3x2_add<T>(a: Matrix3x2<T>, b: Matrix3x2<T>) -> Matrix3x2<T>
680    where T: Copy + Add<T, Output = T>
681{
682    [
683        vec2_add(a[0], b[0]),
684        vec2_add(a[1], b[1]),
685        vec2_add(a[2], b[2])
686    ]
687}
688
689/// Adds two matrices.
690#[inline(always)]
691pub fn mat3_add<T>(a: Matrix3<T>, b: Matrix3<T>) -> Matrix3<T>
692    where T: Copy + Add<T, Output = T>
693{
694    [
695        vec3_add(a[0], b[0]),
696        vec3_add(a[1], b[1]),
697        vec3_add(a[2], b[2])
698    ]
699}
700
701/// Adds two matrices.
702#[inline(always)]
703pub fn mat3x4_add<T>(a: Matrix3x4<T>, b: Matrix3x4<T>) -> Matrix3x4<T>
704    where T: Copy + Add<T, Output = T>
705{
706    [
707        vec4_add(a[0], b[0]),
708        vec4_add(a[1], b[1]),
709        vec4_add(a[2], b[2])
710    ]
711}
712
713/// Adds two matrices.
714#[inline(always)]
715pub fn mat4x3_add<T>(a: Matrix4x3<T>, b: Matrix4x3<T>) -> Matrix4x3<T>
716    where T: Copy + Add<T, Output = T>
717{
718    [
719        vec3_add(a[0], b[0]),
720        vec3_add(a[1], b[1]),
721        vec3_add(a[2], b[2]),
722        vec3_add(a[3], b[3])
723    ]
724}
725
726/// Adds two matrices.
727#[inline(always)]
728pub fn mat4_add<T>(a: Matrix4<T>, b: Matrix4<T>) -> Matrix4<T>
729    where T: Copy + Add<T, Output = T>
730{
731    [
732        vec4_add(a[0], b[0]),
733        vec4_add(a[1], b[1]),
734        vec4_add(a[2], b[2]),
735        vec4_add(a[3], b[3])
736    ]
737}
738
739/// Multiplies two vectors component wise.
740#[inline(always)]
741pub fn vec2_mul<T>(a: Vector2<T>, b: Vector2<T>) -> Vector2<T>
742    where T: Copy + Mul<T, Output = T>
743{
744    [a[0] * b[0], a[1] * b[1]]
745}
746
747/// Multiplies two vectors component wise.
748#[inline(always)]
749pub fn vec3_mul<T>(a: Vector3<T>, b: Vector3<T>) -> Vector3<T>
750    where T: Copy + Mul<T, Output = T>
751{
752    [a[0] * b[0], a[1] * b[1], a[2] * b[2]]
753}
754
755/// Multiplies two vectors component wise.
756#[inline(always)]
757pub fn vec4_mul<T>(a: Vector4<T>, b: Vector4<T>) -> Vector4<T>
758    where T: Copy + Mul<T, Output = T>
759{
760    [a[0] * b[0], a[1] * b[1], a[2] * b[2], a[3] * b[3]]
761}
762
763/// Computes the dot product.
764#[inline(always)]
765pub fn vec2_dot<T>(a: Vector2<T>, b: Vector2<T>) -> T
766    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
767{
768    a[0] * b[0] + a[1] * b[1]
769}
770
771/// Computes the dot product.
772#[inline(always)]
773pub fn vec3_dot<T>(a: Vector3<T>, b: Vector3<T>) -> T
774    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
775{
776    a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
777}
778
779/// Computes the dot product.
780#[inline(always)]
781pub fn vec4_dot<T>(a: Vector4<T>, b: Vector4<T>) -> T
782    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
783{
784    a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]
785}
786
787/// Computes the square length of a vector.
788#[inline(always)]
789pub fn vec2_square_len<T>(a: Vector2<T>) -> T
790    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
791{
792    a[0] * a[0] + a[1] * a[1]
793}
794
795/// Computes the square length of a vector.
796#[inline(always)]
797pub fn vec3_square_len<T>(a: Vector3<T>) -> T
798    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
799{
800    a[0] * a[0] + a[1] * a[1] + a[2] * a[2]
801}
802
803/// Computes the square length of a vector.
804#[inline(always)]
805pub fn vec4_square_len<T>(a: Vector4<T>) -> T
806    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
807{
808    a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]
809}
810
811/// Computes the cross product.
812#[inline(always)]
813pub fn vec2_cross<T>(a: Vector2<T>, b: Vector2<T>) -> T
814    where T: Copy + Mul<T, Output = T> + Sub<T, Output = T>
815{
816    a[0] * b[1] - a[1] * b[0]
817}
818
819/// Computes the cross product.
820#[inline(always)]
821pub fn vec3_cross<T>(a: Vector3<T>, b: Vector3<T>) -> Vector3<T>
822    where T: Copy + Mul<T, Output = T> + Sub<T, Output = T>
823{
824    [
825        a[1] * b[2] - a[2] * b[1],
826        a[2] * b[0] - a[0] * b[2],
827        a[0] * b[1] - a[1] * b[0]
828    ]
829}
830
831/// Multiplies the vector with a scalar.
832#[inline(always)]
833pub fn vec2_scale<T>(a: Vector2<T>, b: T) -> Vector2<T>
834    where T: Copy + Mul<T, Output = T>
835{
836    [
837        a[0] * b,
838        a[1] * b
839    ]
840}
841
842/// Multiplies the vector with a scalar.
843#[inline(always)]
844pub fn vec3_scale<T>(a: Vector3<T>, b: T) -> Vector3<T>
845    where T: Copy + Mul<T, Output = T>
846{
847    [
848        a[0] * b,
849        a[1] * b,
850        a[2] * b
851    ]
852}
853
854/// Multiplies the vector with a scalar.
855#[inline(always)]
856pub fn vec4_scale<T>(a: Vector4<T>, b: T) -> Vector4<T>
857    where T: Copy + Mul<T, Output = T>
858{
859    [
860        a[0] * b,
861        a[1] * b,
862        a[2] * b,
863        a[3] * b
864    ]
865}
866
867/// Negates the vector.
868#[inline(always)]
869pub fn vec2_neg<T>(a: Vector2<T>) -> Vector2<T>
870    where T: Copy + Neg<Output = T>
871{
872    [-a[0], -a[1]]
873}
874
875/// Negates the vector.
876#[inline(always)]
877pub fn vec3_neg<T>(a: Vector3<T>) -> Vector3<T>
878    where T: Copy + Neg<Output = T>
879{
880    [-a[0], -a[1], -a[2]]
881}
882
883/// Negates the vector.
884#[inline(always)]
885pub fn vec4_neg<T>(a: Vector4<T>) -> Vector4<T>
886    where T: Copy + Neg<Output = T>
887{
888    [-a[0], -a[1], -a[2], -a[3]]
889}
890
891/// Computes the length of vector.
892#[inline(always)]
893pub fn vec2_len<T>(a: Vector2<T>) -> T
894    where T: Copy + traits::Sqrt + Add<T, Output = T> + Mul<T, Output = T>
895{
896    vec2_square_len(a).sqrt()
897}
898
899/// Computes the length of vector.
900#[inline(always)]
901pub fn vec3_len<T>(a: Vector3<T>) -> T
902    where T: Copy + traits::Sqrt + Add<T, Output = T> + Mul<T, Output = T>
903{
904    vec3_square_len(a).sqrt()
905}
906
907/// Computes the length of vector.
908#[inline(always)]
909pub fn vec4_len<T>(a: Vector4<T>) -> T
910    where T: Copy + traits::Sqrt + Add<T, Output = T> + Mul<T, Output = T>
911{
912    vec4_square_len(a).sqrt()
913}
914
915/// Computes the inverse length of a vector.
916#[inline(always)]
917pub fn vec2_inv_len<T>(a: Vector2<T>) -> T
918    where T: Copy + traits::One + traits::Sqrt + Add<T, Output = T>
919        + Mul<T, Output = T> + Div<T, Output = T>
920{
921    let one = T::one();
922    one / vec2_len(a)
923}
924
925/// Computes the inverse length of a vector.
926#[inline(always)]
927pub fn vec3_inv_len<T>(a: Vector3<T>) -> T
928    where T: Copy + traits::One + traits::Sqrt + Add<T, Output = T>
929        + Mul<T, Output = T> + Div<T, Output = T>
930{
931    let one = T::one();
932    one / vec3_len(a)
933}
934
935/// Computes the inverse length of a vector.
936#[inline(always)]
937pub fn vec4_inv_len<T>(a: Vector4<T>) -> T
938    where T: Copy + traits::One + traits::Sqrt + Add<T, Output = T>
939        + Mul<T, Output = T> + Div<T, Output = T>
940{
941    let one = T::one();
942    one / vec4_len(a)
943}
944
945/// Computes the normalized.
946#[inline(always)]
947pub fn vec2_normalized<T>(a: Vector2<T>) -> Vector2<T>
948    where T: Copy + traits::One + traits::Sqrt + Add<T, Output = T>
949        + Mul<T, Output = T> + Div<T, Output = T>
950{
951    vec2_scale(a, vec2_inv_len(a))
952}
953
954/// Computes the normalized.
955#[inline(always)]
956pub fn vec3_normalized<T>(a: Vector3<T>) -> Vector3<T>
957    where T: Copy + traits::One + traits::Sqrt + Add<T, Output = T>
958        + Mul<T, Output = T> + Div<T, Output = T>
959{
960    vec3_scale(a, vec3_inv_len(a))
961}
962
963/// Computes the normalized.
964#[inline(always)]
965pub fn vec4_normalized<T>(a: Vector4<T>) -> Vector4<T>
966    where T: Copy + traits::One + traits::Sqrt + Add<T, Output = T>
967        + Mul<T, Output = T> + Div<T, Output = T>
968{
969    vec4_scale(a, vec4_inv_len(a))
970}
971
972/// Computes the normalized difference between two vectors.
973///
974/// This is often used to get direction from 'b' to 'a'.
975#[inline(always)]
976pub fn vec2_normalized_sub<T>(
977    a: Vector2<T>,
978    b: Vector2<T>
979) -> Vector2<T>
980    where T: Copy + traits::One + traits::Sqrt + Add<T, Output = T>
981        + Mul<T, Output = T> + Div<T, Output = T> + Sub<T, Output = T>
982{
983    vec2_normalized(vec2_sub(a, b))
984}
985
986/// Computes the normalized difference between two vectors.
987///
988/// This is often used to get direction from 'b' to 'a'.
989#[inline(always)]
990pub fn vec3_normalized_sub<T>(
991    a: Vector3<T>,
992    b: Vector3<T>
993) -> Vector3<T>
994    where T: Copy + traits::One + traits::Sqrt + Add<T, Output = T>
995        + Mul<T, Output = T> + Sub<T, Output = T> + Div<T, Output = T>
996{
997    vec3_normalized(vec3_sub(a, b))
998}
999
1000/// Computes the normalized difference between two vectors.
1001///
1002/// This is often used to get direction from 'b' to 'a'.
1003#[inline(always)]
1004pub fn vec4_normalized_sub<T>(
1005    a: Vector4<T>,
1006    b: Vector4<T>
1007) -> Vector4<T>
1008    where T: Copy + traits::One + traits::Sqrt + Add<T, Output = T>
1009        + Mul<T, Output = T> + Sub<T, Output = T> + Div<T, Output = T>
1010{
1011    vec4_normalized(vec4_sub(a, b))
1012}
1013
1014/// Computes transformed vector component.
1015///
1016/// This is used when transforming vectors through matrices.
1017#[inline(always)]
1018pub fn vec3_dot_vec2<T>(a: Vector3<T>, b: Vector2<T>) -> T
1019    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1020{
1021    a[0] * b[0] + a[1] * b[1]
1022}
1023
1024/// Computes transformed vector component.
1025///
1026/// This is used when transforming vectors through matrices.
1027#[inline(always)]
1028pub fn vec4_dot_vec3<T>(a: Vector4<T>, b: Vector3<T>) -> T
1029    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1030{
1031    a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
1032}
1033
1034/// Computes transformed position component.
1035///
1036/// This is used when transforming points through matrices.
1037#[inline(always)]
1038pub fn vec3_dot_pos2<T>(a: Vector3<T>, b: Vector2<T>) -> T
1039    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1040{
1041    vec3_dot_vec2(a, b) + a[2]
1042}
1043
1044/// Computes transformed position component.
1045///
1046/// This is used when transforming points through matrices.
1047#[inline(always)]
1048pub fn vec4_dot_pos3<T>(a: Vector4<T>, b: Vector3<T>) -> T
1049    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1050{
1051    vec4_dot_vec3(a, b) + a[3]
1052}
1053
1054/// Returns a column vector of a row matrix.
1055#[inline(always)]
1056pub fn row_mat2x3_col<T: Copy>(mat: Matrix2x3<T>, i: usize) -> Vector2<T> {
1057    [mat[0][i], mat[1][i]]
1058}
1059
1060/// Returns a row vector of a column matrix.
1061#[inline(always)]
1062pub fn col_mat2x3_row<T: Copy>(mat: Matrix2x3<T>, i: usize) -> Vector2<T> {
1063    row_mat2x3_col(mat, i)
1064}
1065
1066/// Returns a column vector of a row matrix.
1067#[inline(always)]
1068pub fn row_mat3x2_col<T: Copy>(a: Matrix3x2<T>, i: usize) -> Vector3<T> {
1069    [a[0][i], a[1][i], a[2][i]]
1070}
1071
1072/// Returns a row vector of a column matrix.
1073#[inline(always)]
1074pub fn col_mat3x2_row<T: Copy>(a: Matrix3x2<T>, i: usize) -> Vector3<T> {
1075    row_mat3x2_col(a, i)
1076}
1077
1078/// Returns a column vector of a row matrix.
1079#[inline(always)]
1080pub fn row_mat3_col<T: Copy>(a: Matrix3<T>, i: usize) -> Vector3<T> {
1081    [a[0][i], a[1][i], a[2][i]]
1082}
1083
1084/// Returns a row vector of a column matrix.
1085#[inline(always)]
1086pub fn col_mat3_row<T: Copy>(a: Matrix3<T>, i: usize) -> Vector3<T> {
1087    row_mat3_col(a, i)
1088}
1089
1090/// Returns a column vector of a row matrix.
1091#[inline(always)]
1092pub fn row_mat3x4_col<T: Copy>(mat: Matrix3x4<T>, i: usize) -> Vector3<T> {
1093    [mat[0][i], mat[1][i], mat[2][i]]
1094}
1095
1096/// Returns a row vector of a column matrix.
1097#[inline(always)]
1098pub fn col_mat3x4_row<T: Copy>(mat: Matrix3x4<T>, i: usize) -> Vector3<T> {
1099    row_mat3x4_col(mat, i)
1100}
1101
1102/// Returns a column vector of a row matrix.
1103#[inline(always)]
1104pub fn row_mat4x3_col<T: Copy>(a: Matrix4x3<T>, i: usize) -> Vector4<T> {
1105    [a[0][i], a[1][i], a[2][i], a[3][i]]
1106}
1107
1108/// Returns a column vector of a row matrix.
1109#[inline(always)]
1110pub fn col_mat4x3_row<T: Copy>(a: Matrix4x3<T>, i: usize) -> Vector4<T> {
1111    row_mat4x3_col(a, i)
1112}
1113
1114/// Returns a column vector of a row matrix.
1115#[inline(always)]
1116pub fn row_mat4_col<T: Copy>(a: Matrix4<T>, i: usize) -> Vector4<T> {
1117    [a[0][i], a[1][i], a[2][i], a[3][i]]
1118}
1119
1120/// Returns a row vector of a column matrix.
1121#[inline(always)]
1122pub fn col_mat4_row<T: Copy>(a: Matrix4<T>, i: usize) -> Vector4<T> {
1123    row_mat4_col(a, i)
1124}
1125
1126/// Constructs the transpose of a matrix.
1127#[inline(always)]
1128pub fn mat2x3_transposed<T: Copy>(a: Matrix2x3<T>) -> Matrix3x2<T> {
1129    [
1130        row_mat2x3_col(a, 0),
1131        row_mat2x3_col(a, 1),
1132        row_mat2x3_col(a, 2)
1133    ]
1134}
1135
1136/// Constructs the transpose of a matrix.
1137#[inline(always)]
1138pub fn mat3x2_transposed<T: Copy>(a: Matrix3x2<T>) -> Matrix2x3<T> {
1139    [
1140        row_mat3x2_col(a, 0),
1141        row_mat3x2_col(a, 1)
1142    ]
1143}
1144
1145/// Constructs the transpose of a matrix.
1146#[inline(always)]
1147pub fn mat3_transposed<T: Copy>(a: Matrix3<T>) -> Matrix3<T> {
1148    [
1149        row_mat3_col(a, 0),
1150        row_mat3_col(a, 1),
1151        row_mat3_col(a, 2)
1152    ]
1153}
1154
1155/// Constructs the transpose of a matrix.
1156#[inline(always)]
1157pub fn mat3x4_transposed<T: Copy>(a: Matrix3x4<T>) -> Matrix4x3<T> {
1158    [
1159        row_mat3x4_col(a, 0),
1160        row_mat3x4_col(a, 1),
1161        row_mat3x4_col(a, 2),
1162        row_mat3x4_col(a, 3)
1163    ]
1164}
1165
1166/// Constructs the transpose of a matrix.
1167#[inline(always)]
1168pub fn mat4x3_transposed<T: Copy>(a: Matrix4x3<T>) -> Matrix3x4<T> {
1169    [
1170        row_mat4x3_col(a, 0),
1171        row_mat4x3_col(a, 1),
1172        row_mat4x3_col(a, 2)
1173    ]
1174}
1175
1176/// Constructs the transpose of a matrix.
1177#[inline(always)]
1178pub fn mat4_transposed<T: Copy>(a: Matrix4<T>) -> Matrix4<T> {
1179    [
1180        row_mat4_col(a, 0),
1181        row_mat4_col(a, 1),
1182        row_mat4_col(a, 2),
1183        row_mat4_col(a, 3)
1184    ]
1185}
1186
1187/// Transforms a 3D vector through a matrix.
1188#[inline(always)]
1189pub fn col_mat3_transform<T>(
1190    mat: Matrix3<T>,
1191    a: Vector3<T>
1192) -> Vector3<T>
1193    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1194{
1195    [
1196        vec3_dot(col_mat3_row(mat, 0), a),
1197        vec3_dot(col_mat3_row(mat, 1), a),
1198        vec3_dot(col_mat3_row(mat, 2), a)
1199    ]
1200}
1201
1202/// Transforms a 4D vector through a matrix.
1203#[inline(always)]
1204pub fn col_mat4_transform<T>(
1205    mat: Matrix4<T>,
1206    a: Vector4<T>
1207) -> Vector4<T>
1208    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1209{
1210    [
1211        vec4_dot(col_mat4_row(mat, 0), a),
1212        vec4_dot(col_mat4_row(mat, 1), a),
1213        vec4_dot(col_mat4_row(mat, 2), a),
1214        vec4_dot(col_mat4_row(mat, 3), a)
1215    ]
1216}
1217
1218/// Transforms a 3D vector through a matrix.
1219#[inline(always)]
1220pub fn row_mat3_transform<T>(
1221    mat: Matrix3<T>,
1222    a: Vector3<T>
1223) -> Vector3<T>
1224    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1225{
1226    [
1227        vec3_dot(mat[0], a),
1228        vec3_dot(mat[1], a),
1229        vec3_dot(mat[2], a)
1230    ]
1231}
1232
1233/// Transforms a 4D vector through a matrix.
1234#[inline(always)]
1235pub fn row_mat4_transform<T>(
1236    mat: Matrix4<T>,
1237    a: Vector4<T>
1238) -> Vector4<T>
1239    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1240{
1241    [
1242        vec4_dot(mat[0], a),
1243        vec4_dot(mat[1], a),
1244        vec4_dot(mat[2], a),
1245        vec4_dot(mat[3], a)
1246    ]
1247}
1248
1249/// Transforms a 2D position through matrix.
1250#[inline(always)]
1251pub fn row_mat2x3_transform_pos2<T>(
1252    mat: Matrix2x3<T>,
1253    a: Vector2<T>
1254) -> Vector2<T>
1255    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1256{
1257    [
1258        vec3_dot_pos2(mat[0], a),
1259        vec3_dot_pos2(mat[1], a)
1260    ]
1261}
1262
1263/// Transforms a 2D position through matrix.
1264#[inline(always)]
1265pub fn col_mat3x2_transform_pos2<T>(
1266    mat: Matrix3x2<T>,
1267    a: Vector2<T>
1268) -> Vector2<T>
1269    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1270{
1271    [
1272        vec3_dot_pos2(col_mat3x2_row(mat, 0), a),
1273        vec3_dot_pos2(col_mat3x2_row(mat, 1), a)
1274    ]
1275}
1276
1277/// Transforms a 2D position through row matrix.
1278#[inline(always)]
1279pub fn row_mat3_transform_pos2<T>(
1280    mat: Matrix3<T>,
1281    a: Vector2<T>
1282) -> Vector2<T>
1283    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1284{
1285    [
1286        vec3_dot_pos2(mat[0], a),
1287        vec3_dot_pos2(mat[1], a)
1288    ]
1289}
1290
1291/// Transforms a 2D position through column matrix.
1292#[inline(always)]
1293pub fn col_mat3_transform_pos2<T>(
1294    mat: Matrix3<T>,
1295    a: Vector2<T>
1296) -> Vector2<T>
1297    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1298{
1299    [
1300        vec3_dot_pos2(col_mat3_row(mat, 0), a),
1301        vec3_dot_pos2(col_mat3_row(mat, 1), a)
1302    ]
1303}
1304
1305/// Transforms a 3D position through matrix.
1306#[inline(always)]
1307pub fn row_mat3x4_transform_pos3<T>(
1308    mat: Matrix3x4<T>,
1309    a: Vector3<T>
1310) -> Vector3<T>
1311    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1312{
1313    [
1314        vec4_dot_pos3(mat[0], a),
1315        vec4_dot_pos3(mat[1], a),
1316        vec4_dot_pos3(mat[2], a),
1317    ]
1318}
1319
1320/// Transforms a 3D position through matrix.
1321#[inline(always)]
1322pub fn col_mat4x3_transform_pos3<T>(
1323    mat: Matrix4x3<T>,
1324    a: Vector3<T>
1325) -> Vector3<T>
1326    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1327{
1328    [
1329        vec4_dot_pos3(col_mat4x3_row(mat, 0), a),
1330        vec4_dot_pos3(col_mat4x3_row(mat, 1), a),
1331        vec4_dot_pos3(col_mat4x3_row(mat, 2), a)
1332    ]
1333}
1334
1335/// Transforms a 2D vector through matrix.
1336///
1337/// To include the translate component, use the `transform_pos` variant.
1338#[inline(always)]
1339pub fn row_mat2x3_transform_vec2<T>(
1340    mat: Matrix2x3<T>,
1341    a: Vector2<T>
1342) -> Vector2<T>
1343    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1344{
1345    [
1346        vec3_dot_vec2(mat[0], a),
1347        vec3_dot_vec2(mat[1], a)
1348    ]
1349}
1350
1351/// Transforms a 2D vector through matrix.
1352///
1353/// To include the translate component, use the `transform_pos` variant.
1354#[inline(always)]
1355pub fn col_mat3x2_transform_vec2<T>(
1356    mat: Matrix3x2<T>,
1357    a: Vector2<T>
1358) -> Vector2<T>
1359    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1360{
1361    [
1362        vec3_dot_vec2(col_mat3x2_row(mat, 0), a),
1363        vec3_dot_vec2(col_mat3x2_row(mat, 1), a)
1364    ]
1365}
1366
1367/// Transforms a 2D vector through row matrix.
1368///
1369/// To include the translate component, use the `transform_pos` variant.
1370#[inline(always)]
1371pub fn row_mat3_transform_vec2<T>(
1372    mat: Matrix3<T>,
1373    a: Vector2<T>
1374) -> Vector2<T>
1375    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1376{
1377    [
1378        vec3_dot_vec2(mat[0], a),
1379        vec3_dot_vec2(mat[1], a)
1380    ]
1381}
1382
1383/// Transforms a 2D vector through column matrix.
1384///
1385/// To include the translate component, use the `transform_pos` variant.
1386#[inline(always)]
1387pub fn col_mat3_transform_vec2<T>(
1388    mat: Matrix3<T>,
1389    a: Vector2<T>
1390) -> Vector2<T>
1391    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1392{
1393    [
1394        vec3_dot_vec2(col_mat3_row(mat, 0), a),
1395        vec3_dot_vec2(col_mat3_row(mat, 1), a)
1396    ]
1397}
1398
1399/// Transforms a 3D vector through matrix.
1400///
1401/// To include the translate component, use the `transform_pos` variant.
1402#[inline(always)]
1403pub fn row_mat3x4_transform_vec3<T>(
1404    mat: Matrix3x4<T>,
1405    a: Vector3<T>
1406) -> Vector3<T>
1407    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1408{
1409    [
1410        vec4_dot_vec3(mat[0], a),
1411        vec4_dot_vec3(mat[1], a),
1412        vec4_dot_vec3(mat[2], a)
1413    ]
1414}
1415
1416/// Transforms a 3D vector through matrix.
1417///
1418/// To include the translate component, use the `transform_pos` variant.
1419#[inline(always)]
1420pub fn col_mat4x3_transform_vec3<T>(
1421    mat: Matrix4x3<T>,
1422    a: Vector3<T>
1423) -> Vector3<T>
1424    where T: Copy + Add<T, Output = T> + Mul<T, Output = T>
1425{
1426    [
1427        vec4_dot_vec3(col_mat4x3_row(mat, 0), a),
1428        vec4_dot_vec3(col_mat4x3_row(mat, 1), a),
1429        vec4_dot_vec3(col_mat4x3_row(mat, 2), a)
1430    ]
1431}
1432
1433/// Computes the determinant of a matrix.
1434pub fn mat2x3_det<T>(mat: Matrix2x3<T>) -> T
1435    where T: Copy + Mul<T, Output = T> + Sub<T, Output = T>
1436{
1437      mat[0][0] * mat[1][1]
1438    - mat[0][1] * mat[1][0]
1439}
1440
1441/// Computes the determinant of a matrix.
1442pub fn mat3x2_det<T>(mat: Matrix3x2<T>) -> T
1443    where T: Copy + Mul<T, Output = T> + Sub<T, Output = T>
1444{
1445      mat[0][0] * mat[1][1]
1446    - mat[0][1] * mat[1][0]
1447}
1448
1449/// Computes the determinant of a matrix.
1450pub fn mat3_det<T>(mat: Matrix3<T>) -> T
1451    where T: Copy + Add<T, Output = T> + Mul<T, Output = T> + Sub<T, Output = T>
1452{
1453      mat[0][0] * mat[1][1] * mat[2][2]
1454    + mat[0][1] * mat[1][2] * mat[2][0]
1455    + mat[0][2] * mat[1][0] * mat[2][1]
1456    - mat[0][0] * mat[1][2] * mat[2][1]
1457    - mat[0][1] * mat[1][0] * mat[2][2]
1458    - mat[0][2] * mat[1][1] * mat[2][0]
1459}
1460
1461/// Computes the determinant of a matrix.
1462pub fn mat3x4_det<T>(mat: Matrix3x4<T>) -> T
1463    where T: Copy + Add<T, Output = T> + Mul<T, Output = T> + Sub<T, Output = T>
1464{
1465      mat[0][0] * mat[1][1] * mat[2][2]
1466    + mat[0][1] * mat[1][2] * mat[2][0]
1467    + mat[0][2] * mat[1][0] * mat[2][1]
1468    - mat[0][0] * mat[1][2] * mat[2][1]
1469    - mat[0][1] * mat[1][0] * mat[2][2]
1470    - mat[0][2] * mat[1][1] * mat[2][0]
1471}
1472
1473/// Computes the determinant of a matrix.
1474pub fn mat4x3_det<T>(mat: Matrix4x3<T>) -> T
1475    where T: Copy + Add<T, Output = T> + Mul<T, Output = T> + Sub<T, Output = T>
1476{
1477      mat[0][0] * mat[1][1] * mat[2][2]
1478    + mat[0][1] * mat[1][2] * mat[2][0]
1479    + mat[0][2] * mat[1][0] * mat[2][1]
1480    - mat[0][0] * mat[1][2] * mat[2][1]
1481    - mat[0][1] * mat[1][0] * mat[2][2]
1482    - mat[0][2] * mat[1][1] * mat[2][0]
1483}
1484
1485/// Computes the determinant of a 4x4 matrix.
1486pub fn mat4_det<T>(mat: Matrix4<T>) -> T
1487    where T: Copy + Add<T, Output = T> + Mul<T, Output = T> + Sub<T, Output = T>
1488{
1489      mat[0][0] * mat[1][1] * mat[2][2] * mat[3][3]
1490    + mat[0][0] * mat[1][2] * mat[2][3] * mat[3][1]
1491    + mat[0][0] * mat[1][3] * mat[2][1] * mat[3][2]
1492
1493    + mat[0][1] * mat[1][0] * mat[2][3] * mat[3][2]
1494    + mat[0][1] * mat[1][2] * mat[2][0] * mat[3][3]
1495    + mat[0][1] * mat[1][3] * mat[2][2] * mat[3][0]
1496
1497    + mat[0][2] * mat[1][0] * mat[2][1] * mat[3][3]
1498    + mat[0][2] * mat[1][1] * mat[2][3] * mat[3][0]
1499    + mat[0][2] * mat[1][3] * mat[2][0] * mat[3][1]
1500
1501    + mat[0][3] * mat[1][0] * mat[2][2] * mat[3][1]
1502    + mat[0][3] * mat[1][1] * mat[2][0] * mat[3][2]
1503    + mat[0][3] * mat[1][2] * mat[2][1] * mat[3][0]
1504
1505    - mat[0][0] * mat[1][1] * mat[2][3] * mat[3][2]
1506    - mat[0][0] * mat[1][2] * mat[2][1] * mat[3][3]
1507    - mat[0][0] * mat[1][3] * mat[2][2] * mat[3][1]
1508
1509    - mat[0][1] * mat[1][0] * mat[2][2] * mat[3][3]
1510    - mat[0][1] * mat[1][2] * mat[2][3] * mat[3][0]
1511    - mat[0][1] * mat[1][3] * mat[2][0] * mat[3][2]
1512
1513    - mat[0][2] * mat[1][0] * mat[2][3] * mat[3][1]
1514    - mat[0][2] * mat[1][1] * mat[2][0] * mat[3][3]
1515    - mat[0][2] * mat[1][3] * mat[2][1] * mat[3][0]
1516
1517    - mat[0][3] * mat[1][0] * mat[2][1] * mat[3][2]
1518    - mat[0][3] * mat[1][1] * mat[2][2] * mat[3][0]
1519    - mat[0][3] * mat[1][2] * mat[2][0] * mat[3][1]
1520}
1521
1522/// Computes inverse determinant of a 2x3 matrix.
1523#[inline(always)]
1524pub fn mat2x3_inv_det<T>(mat: Matrix2x3<T>) -> T
1525    where T: Copy + traits::One + Add<T, Output = T> + Mul<T, Output = T>
1526        + Sub<T, Output = T> + Div<T, Output = T>
1527{
1528    let one = T::one();
1529    one / mat2x3_det(mat)
1530}
1531
1532/// Computes inverse determinant of a 3x2 matrix.
1533#[inline(always)]
1534pub fn mat3x2_inv_det<T>(mat: Matrix3x2<T>) -> T
1535    where T: Copy + traits::One + Mul<T, Output = T> + Sub<T, Output = T>
1536        + Div<T, Output = T>
1537{
1538    let one = T::one();
1539    one / mat3x2_det(mat)
1540}
1541
1542/// Computes inverse determinant of a 3x3 matrix.
1543#[inline(always)]
1544pub fn mat3_inv_det<T>(mat: Matrix3<T>) -> T
1545    where T: Copy + traits::One + Mul<T, Output = T> + Sub<T, Output = T>
1546        + Div<T, Output = T> + Add<T, Output = T>
1547{
1548    let one = T::one();
1549    one / mat3_det(mat)
1550}
1551
1552/// Computes inverse determinant of a 3x4 matrix.
1553#[inline(always)]
1554pub fn mat3x4_inv_det<T>(mat: Matrix3x4<T>) -> T
1555    where T: Copy + traits::One + Add<T, Output = T> + Mul<T, Output = T>
1556        + Sub<T, Output = T> + Div<T, Output = T>
1557{
1558    let one = T::one();
1559    one / mat3x4_det(mat)
1560}
1561
1562/// Computes inverse determinant of a 4x3 matrix.
1563#[inline(always)]
1564pub fn mat4x3_inv_det<T>(mat: Matrix4x3<T>) -> T
1565    where T: Copy + traits::One + Add<T, Output = T> + Mul<T, Output = T>
1566        + Sub<T, Output = T> + Div<T, Output = T>
1567{
1568    let one = T::one();
1569    one / mat4x3_det(mat)
1570}
1571
1572/// Computes the inverse determinant of a 4x4 matrix.
1573#[inline(always)]
1574pub fn mat4_inv_det<T>(mat: Matrix4<T>) -> T
1575    where T: Copy + traits::One + Add<T, Output = T> + Mul<T, Output = T>
1576        + Sub<T, Output = T> + Div<T, Output = T>
1577{
1578    let one = T::one();
1579    one / mat4_det(mat)
1580}
1581
1582/// Computes the inverse of a 2x3 matrix.
1583pub fn mat2x3_inv<T>(mat: Matrix2x3<T>) -> Matrix2x3<T>
1584    where T: Copy + traits::One + Add<T, Output = T> + Mul<T, Output = T>
1585        + Sub<T, Output = T> + Div<T, Output = T> + Neg<Output = T>
1586{
1587    let inv_det = mat2x3_inv_det(mat);
1588
1589    [
1590        [
1591              mat[1][1] * inv_det,
1592            - mat[0][1] * inv_det,
1593            (
1594              mat[0][1] * mat[1][2]
1595            - mat[0][2] * mat[1][1]
1596            ) * inv_det
1597        ],
1598        [
1599            - mat[1][0] * inv_det,
1600              mat[0][0] * inv_det,
1601            (
1602              mat[0][2] * mat[1][0]
1603            - mat[0][0] * mat[1][2]
1604            ) * inv_det,
1605        ]
1606    ]
1607}
1608
1609/// Computes the inverse of a 3x2 matrix.
1610pub fn mat3x2_inv<T>(mat: Matrix3x2<T>) -> Matrix3x2<T>
1611    where T: Copy + traits::One + Mul<T, Output = T> + Sub<T, Output = T>
1612        + Div<T, Output = T> + Neg<Output = T>
1613{
1614    let inv_det = mat3x2_inv_det(mat);
1615
1616    [
1617        [
1618            mat[1][1] * inv_det,
1619          - mat[0][1] * inv_det
1620        ],
1621        [
1622          - mat[1][0] * inv_det,
1623            mat[0][0] * inv_det
1624        ],
1625        [
1626            (
1627                  mat[1][0] * mat[2][1]
1628                - mat[1][1] * mat[2][0]
1629            ) * inv_det,
1630            (
1631                  mat[0][1] * mat[2][0]
1632                - mat[0][0] * mat[2][1]
1633            ) * inv_det
1634        ]
1635    ]
1636}
1637
1638/// Computes the inverse of a 3x3 matrix.
1639pub fn mat3_inv<T>(mat: Matrix3<T>) -> Matrix3<T>
1640    where T: Copy + traits::One + Mul<T, Output = T> + Sub<T, Output = T>
1641        + Div<T, Output = T> + Add<T, Output = T>
1642{
1643    let inv_det = mat3_inv_det(mat);
1644
1645    [
1646        [   (
1647                  mat[1][1] * mat[2][2]
1648                - mat[1][2] * mat[2][1]
1649            ) * inv_det,
1650            (
1651                  mat[0][2] * mat[2][1]
1652                - mat[0][1] * mat[2][2]
1653            ) * inv_det,
1654            (
1655                  mat[0][1] * mat[1][2]
1656                - mat[0][2] * mat[1][1]
1657            ) * inv_det
1658        ],
1659        [
1660            (
1661                  mat[1][2] * mat[2][0]
1662                - mat[1][0] * mat[2][2]
1663            ) * inv_det,
1664            (
1665                  mat[0][0] * mat[2][2]
1666                - mat[0][2] * mat[2][0]
1667            ) * inv_det,
1668            (
1669                  mat[0][2] * mat[1][0]
1670                - mat[0][0] * mat[1][2]
1671            ) * inv_det
1672        ],
1673        [
1674            (
1675                  mat[1][0] * mat[2][1]
1676                - mat[1][1] * mat[2][0]
1677            ) * inv_det,
1678            (
1679                  mat[0][1] * mat[2][0]
1680                - mat[0][0] * mat[2][1]
1681            ) * inv_det,
1682            (
1683                  mat[0][0] * mat[1][1]
1684                - mat[0][1] * mat[1][0]
1685            ) * inv_det
1686        ]
1687    ]
1688}
1689
1690/// Computes the inverse of a 3x4 matrix.
1691pub fn mat3x4_inv<T>(mat: Matrix3x4<T>) -> Matrix3x4<T>
1692    where T: Copy + traits::One + Add<T, Output = T> + Mul<T, Output = T>
1693        + Sub<T, Output = T> + Div<T, Output = T>
1694{
1695    let inv_det = mat3x4_inv_det(mat);
1696
1697    [
1698        [   (
1699              mat[1][1] * mat[2][2]
1700            - mat[1][2] * mat[2][1]
1701            ) * inv_det,
1702            (
1703              mat[0][2] * mat[2][1]
1704            - mat[0][1] * mat[2][2]
1705            ) * inv_det,
1706            (
1707              mat[0][1] * mat[1][2]
1708            - mat[0][2] * mat[1][1]
1709            ) * inv_det,
1710            (
1711              mat[0][1] * mat[1][3] * mat[2][2]
1712            + mat[0][2] * mat[1][1] * mat[2][3]
1713            + mat[0][3] * mat[1][2] * mat[2][1]
1714            - mat[0][1] * mat[1][2] * mat[2][3]
1715            - mat[0][2] * mat[1][3] * mat[2][1]
1716            - mat[0][3] * mat[1][1] * mat[2][2]
1717            ) * inv_det
1718        ],
1719        [
1720            (
1721              mat[1][2] * mat[2][0]
1722            - mat[1][0] * mat[2][2]
1723            ) * inv_det,
1724            (
1725              mat[0][0] * mat[2][2]
1726            - mat[0][2] * mat[2][0]
1727            ) * inv_det,
1728            (
1729              mat[0][2] * mat[1][0]
1730            - mat[0][0] * mat[1][2]
1731            ) * inv_det,
1732            (
1733              mat[0][0] * mat[1][2] * mat[2][3]
1734            + mat[0][2] * mat[1][3] * mat[2][0]
1735            + mat[0][3] * mat[1][0] * mat[2][2]
1736            - mat[0][0] * mat[1][3] * mat[2][2]
1737            - mat[0][2] * mat[1][0] * mat[2][3]
1738            - mat[0][3] * mat[1][2] * mat[2][0]
1739            ) * inv_det
1740        ],
1741        [
1742            (
1743              mat[1][0] * mat[2][1]
1744            - mat[1][1] * mat[2][0]
1745            ) * inv_det,
1746            (
1747              mat[0][1] * mat[2][0]
1748            - mat[0][0] * mat[2][1]
1749            ) * inv_det,
1750            (
1751              mat[0][0] * mat[1][1]
1752            - mat[0][1] * mat[1][0]
1753            ) * inv_det,
1754            (
1755              mat[0][0] * mat[1][3] * mat[2][1]
1756            + mat[0][1] * mat[1][0] * mat[2][3]
1757            + mat[0][3] * mat[1][1] * mat[2][0]
1758            - mat[0][0] * mat[1][1] * mat[2][3]
1759            - mat[0][1] * mat[1][3] * mat[2][0]
1760            - mat[0][3] * mat[1][0] * mat[2][1]
1761            ) * inv_det
1762        ]
1763    ]
1764}
1765
1766/// Computes the inverse of a 4x3 matrix.
1767pub fn mat4x3_inv<T>(mat: Matrix4x3<T>) -> Matrix4x3<T>
1768    where T: Copy + traits::One + Add<T, Output = T> + Mul<T, Output = T>
1769        + Sub<T, Output = T> + Div<T, Output = T>
1770{
1771    let inv_det = mat4x3_inv_det(mat);
1772
1773    [
1774        [   (
1775                  mat[1][1] * mat[2][2]
1776                - mat[1][2] * mat[2][1]
1777            ) * inv_det,
1778            (
1779                  mat[0][2] * mat[2][1]
1780                - mat[0][1] * mat[2][2]
1781            ) * inv_det,
1782            (
1783                  mat[0][1] * mat[1][2]
1784                - mat[0][2] * mat[1][1]
1785            ) * inv_det
1786        ],
1787        [
1788            (
1789                  mat[1][2] * mat[2][0]
1790                - mat[1][0] * mat[2][2]
1791            ) * inv_det,
1792            (
1793                  mat[0][0] * mat[2][2]
1794                - mat[0][2] * mat[2][0]
1795            ) * inv_det,
1796            (
1797                  mat[0][2] * mat[1][0]
1798                - mat[0][0] * mat[1][2]
1799            ) * inv_det
1800        ],
1801        [
1802            (
1803                  mat[1][0] * mat[2][1]
1804                - mat[1][1] * mat[2][0]
1805            ) * inv_det,
1806            (
1807                  mat[0][1] * mat[2][0]
1808                - mat[0][0] * mat[2][1]
1809            ) * inv_det,
1810            (
1811                  mat[0][0] * mat[1][1]
1812                - mat[0][1] * mat[1][0]
1813            ) * inv_det
1814        ],
1815        [
1816            (
1817                mat[1][0] * mat[2][2] * mat[3][1]
1818                + mat[1][1] * mat[2][0] * mat[3][2]
1819                + mat[1][2] * mat[2][1] * mat[3][0]
1820                - mat[1][0] * mat[2][1] * mat[3][2]
1821                - mat[1][1] * mat[2][2] * mat[3][0]
1822                - mat[1][2] * mat[2][0] * mat[3][1]
1823            ) * inv_det,
1824            (
1825                mat[0][0] * mat[2][1] * mat[3][2]
1826                + mat[0][1] * mat[2][2] * mat[3][0]
1827                + mat[0][2] * mat[2][0] * mat[3][1]
1828                - mat[0][0] * mat[2][2] * mat[3][1]
1829                - mat[0][1] * mat[2][0] * mat[3][2]
1830                - mat[0][2] * mat[2][1] * mat[3][0]
1831            ) * inv_det,
1832            (
1833                mat[0][0] * mat[1][2] * mat[3][1]
1834                + mat[0][1] * mat[1][0] * mat[3][2]
1835                + mat[0][2] * mat[1][1] * mat[3][0]
1836                - mat[0][0] * mat[1][1] * mat[3][2]
1837                - mat[0][1] * mat[1][2] * mat[3][0]
1838                - mat[0][2] * mat[1][0] * mat[3][1]
1839            ) * inv_det
1840        ]
1841    ]
1842}
1843
1844/// Computes the inverse of a 4x4 matrix.
1845pub fn mat4_inv<T>(mat: Matrix4<T>) -> Matrix4<T>
1846    where T: Copy + traits::One + Add<T, Output = T> + Mul<T, Output = T>
1847        + Sub<T, Output = T> + Div<T, Output = T>
1848{
1849    let inv_det = mat4_inv_det(mat);
1850
1851    [
1852        [   (
1853                mat[1][1] * mat[2][2] * mat[3][3]
1854                + mat[1][2] * mat[2][3] * mat[3][1]
1855                + mat[1][3] * mat[2][1] * mat[3][2]
1856                - mat[1][1] * mat[2][3] * mat[3][2]
1857                - mat[1][2] * mat[2][1] * mat[3][3]
1858                - mat[1][3] * mat[2][2] * mat[3][1]
1859            ) * inv_det,
1860            (
1861                mat[0][1] * mat[2][3] * mat[3][2]
1862                + mat[0][2] * mat[2][1] * mat[3][3]
1863                + mat[0][3] * mat[2][2] * mat[3][1]
1864                - mat[0][1] * mat[2][2] * mat[3][3]
1865                - mat[0][2] * mat[2][3] * mat[3][1]
1866                - mat[0][3] * mat[2][1] * mat[3][2]
1867            ) * inv_det,
1868            (
1869                mat[0][1] * mat[1][2] * mat[3][3]
1870                + mat[0][2] * mat[1][3] * mat[3][1]
1871                + mat[0][3] * mat[1][1] * mat[3][2]
1872                - mat[0][1] * mat[1][3] * mat[3][2]
1873                - mat[0][2] * mat[1][1] * mat[3][3]
1874                - mat[0][3] * mat[1][2] * mat[3][1]
1875            ) * inv_det,
1876            (
1877                mat[0][1] * mat[1][3] * mat[2][2]
1878                + mat[0][2] * mat[1][1] * mat[2][3]
1879                + mat[0][3] * mat[1][2] * mat[2][1]
1880                - mat[0][1] * mat[1][2] * mat[2][3]
1881                - mat[0][2] * mat[1][3] * mat[2][1]
1882                - mat[0][3] * mat[1][1] * mat[2][2]
1883            ) * inv_det
1884        ],
1885        [
1886            (
1887                mat[1][0] * mat[2][3] * mat[3][2]
1888                + mat[1][2] * mat[2][0] * mat[3][3]
1889                + mat[1][3] * mat[2][2] * mat[3][0]
1890                - mat[1][0] * mat[2][2] * mat[3][3]
1891                - mat[1][2] * mat[2][3] * mat[3][0]
1892                - mat[1][3] * mat[2][0] * mat[3][2]
1893            ) * inv_det,
1894            (
1895                mat[0][0] * mat[2][2] * mat[3][3]
1896                + mat[0][2] * mat[2][3] * mat[3][0]
1897                + mat[0][3] * mat[2][0] * mat[3][2]
1898                - mat[0][0] * mat[2][3] * mat[3][2]
1899                - mat[0][2] * mat[2][0] * mat[3][3]
1900                - mat[0][3] * mat[2][2] * mat[3][0]
1901            ) * inv_det,
1902            (
1903                mat[0][0] * mat[1][3] * mat[3][2]
1904                + mat[0][2] * mat[1][0] * mat[3][3]
1905                + mat[0][3] * mat[1][2] * mat[3][0]
1906                - mat[0][0] * mat[1][2] * mat[3][3]
1907                - mat[0][2] * mat[1][3] * mat[3][0]
1908                - mat[0][3] * mat[1][0] * mat[3][2]
1909            ) * inv_det,
1910            (
1911                mat[0][0] * mat[1][2] * mat[2][3]
1912                + mat[0][2] * mat[1][3] * mat[2][0]
1913                + mat[0][3] * mat[1][0] * mat[2][2]
1914                - mat[0][0] * mat[1][3] * mat[2][2]
1915                - mat[0][2] * mat[1][0] * mat[2][3]
1916                - mat[0][3] * mat[1][2] * mat[2][0]
1917            ) * inv_det
1918        ],
1919        [
1920            (
1921                mat[1][0] * mat[2][1] * mat[3][3]
1922                + mat[1][1] * mat[2][3] * mat[3][0]
1923                + mat[1][3] * mat[2][0] * mat[3][1]
1924                - mat[1][0] * mat[2][3] * mat[3][1]
1925                - mat[1][1] * mat[2][0] * mat[3][3]
1926                - mat[1][3] * mat[2][1] * mat[3][0]
1927            ) * inv_det,
1928            (
1929                mat[0][0] * mat[2][3] * mat[3][1]
1930                + mat[0][1] * mat[2][0] * mat[3][3]
1931                + mat[0][3] * mat[2][1] * mat[3][0]
1932                - mat[0][0] * mat[2][1] * mat[3][3]
1933                - mat[0][1] * mat[2][3] * mat[3][0]
1934                - mat[0][3] * mat[2][0] * mat[3][1]
1935            ) * inv_det,
1936            (
1937                mat[0][0] * mat[1][1] * mat[3][3]
1938                + mat[0][1] * mat[1][3] * mat[3][0]
1939                + mat[0][3] * mat[1][0] * mat[3][1]
1940                - mat[0][0] * mat[1][3] * mat[3][1]
1941                - mat[0][1] * mat[1][0] * mat[3][3]
1942                - mat[0][3] * mat[1][1] * mat[3][0]
1943            ) * inv_det,
1944            (
1945                mat[0][0] * mat[1][3] * mat[2][1]
1946                + mat[0][1] * mat[1][0] * mat[2][3]
1947                + mat[0][3] * mat[1][1] * mat[2][0]
1948                - mat[0][0] * mat[1][1] * mat[2][3]
1949                - mat[0][1] * mat[1][3] * mat[2][0]
1950                - mat[0][3] * mat[1][0] * mat[2][1]
1951            ) * inv_det
1952        ],
1953        [
1954            (
1955                mat[1][0] * mat[2][2] * mat[3][1]
1956                + mat[1][1] * mat[2][0] * mat[3][2]
1957                + mat[1][2] * mat[2][1] * mat[3][0]
1958                - mat[1][0] * mat[2][1] * mat[3][2]
1959                - mat[1][1] * mat[2][2] * mat[3][0]
1960                - mat[1][2] * mat[2][0] * mat[3][1]
1961            ) * inv_det,
1962            (
1963                mat[0][0] * mat[2][1] * mat[3][2]
1964                + mat[0][1] * mat[2][2] * mat[3][0]
1965                + mat[0][2] * mat[2][0] * mat[3][1]
1966                - mat[0][0] * mat[2][2] * mat[3][1]
1967                - mat[0][1] * mat[2][0] * mat[3][2]
1968                - mat[0][2] * mat[2][1] * mat[3][0]
1969            ) * inv_det,
1970            (
1971                mat[0][0] * mat[1][2] * mat[3][1]
1972                + mat[0][1] * mat[1][0] * mat[3][2]
1973                + mat[0][2] * mat[1][1] * mat[3][0]
1974                - mat[0][0] * mat[1][1] * mat[3][2]
1975                - mat[0][1] * mat[1][2] * mat[3][0]
1976                - mat[0][2] * mat[1][0] * mat[3][1]
1977            ) * inv_det,
1978            (
1979                mat[0][0] * mat[1][1] * mat[2][2]
1980                + mat[0][1] * mat[1][2] * mat[2][0]
1981                + mat[0][2] * mat[1][0] * mat[2][1]
1982                - mat[0][0] * mat[1][2] * mat[2][1]
1983                - mat[0][1] * mat[1][0] * mat[2][2]
1984                - mat[0][2] * mat[1][1] * mat[2][0]
1985            ) * inv_det
1986        ]
1987    ]
1988}
1989
1990
1991#[cfg(test)]
1992mod tests {
1993    use super::*;
1994
1995    #[test]
1996    fn test_row_mat2x3_mul() {
1997        let a: Matrix2x3<f64> = mat2x3_id();
1998        let b = a;
1999        let _ = row_mat2x3_mul(a, b);
2000    }
2001
2002    #[test]
2003    fn test_row_mat3x4_mul() {
2004        let a: Matrix3x4<f64> = mat3x4_id();
2005        let b = a;
2006        let _ = row_mat3x4_mul(a, b);
2007    }
2008}