cgl_rs/math/matrix.rs
1//! Matrix math module. Includes a 4x4 matrix struct and associated methods.
2//! NOTE: These matrix library is for graphics programming with OpenGL.
3//! For linear algebra, check the cgl_rs::math::linalg module.
4
5use super::{Vector3, Vector4};
6
7
8/// A 3x3 matrix struct used for graphics programming with OpenGL.
9#[repr(C)]
10#[derive(Debug, Copy, Clone, PartialEq)]
11pub struct Matrix3x3 {
12 m: [f32; 9]
13}
14
15/// A 4x4 matrix struct used for graphics programming with OpenGL.
16#[repr(C)]
17#[derive(Debug, Copy, Clone, PartialEq)]
18pub struct Matrix4x4 {
19 m: [f32; 16]
20}
21
22
23extern {
24 fn CGL_mat3_det(m: &Matrix3x3) -> f32;
25 fn CGL_mat3_transpose(m: &Matrix3x3) -> Matrix3x3;
26 fn CGL_mat3_trace(m: &Matrix3x3) -> f32;
27
28 fn CGL_mat4_zero_MACRO() -> Matrix4x4;
29 fn CGL_mat4_identity_MACRO() -> Matrix4x4;
30 fn CGL_mat4_scale_MACRO(x: f32, y: f32, z: f32) -> Matrix4x4;
31 fn CGL_mat4_translate_MACRO(x: f32, y: f32, z: f32) -> Matrix4x4;
32 fn CGL_mat4_rotate_x_MACRO(angle: f32) -> Matrix4x4;
33 fn CGL_mat4_rotate_y_MACRO(angle: f32) -> Matrix4x4;
34 fn CGL_mat4_rotate_z_MACRO(angle: f32) -> Matrix4x4;
35 fn CGL_mat4_perspective_MACRO(fov: f32, aspect: f32, near: f32, far: f32) -> Matrix4x4;
36 fn CGL_mat4_orthographic_MACRO(left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32) -> Matrix4x4;
37
38 fn CGL_mat4_mul(a: &Matrix4x4, b: &Matrix4x4) -> Matrix4x4;
39 fn CGL_mat4_det(m: &Matrix4x4) -> f32;
40 fn CGL_mat4_det_by_lu(m: &Matrix4x4) -> f32;
41 fn CGL_mat4_det_by_gauss(m: &Matrix4x4) -> f32;
42 fn CGL_mat4_mul_vec4(m: &Matrix4x4, v: &Vector4) -> Vector4;
43 fn CGL_mat4_inverse(m: &Matrix4x4) -> Matrix4x4;
44 fn CGL_mat4_transpose(m: &Matrix4x4) -> Matrix4x4;
45 fn CGL_mat4_adjoint(m: &Matrix4x4) -> Matrix4x4;
46 fn CGL_mat4_gauss_elim(m: &Matrix4x4) -> Matrix4x4;
47 fn CGL_mat4_rank(m: &Matrix4x4) -> i32;
48 fn CGL_mat4_trace(m: &Matrix4x4) -> f32;
49 fn CGL_mat4_to_mat3(m: &Matrix4x4) -> Matrix3x3;
50 fn CGL_mat4_from_mat3(m: &Matrix3x3) -> Matrix4x4;
51 fn CGL_mat4_rotate_about_axis(axis: &Vector3, angle: f32) -> Matrix4x4;
52 fn CGL_mat4_look_at(eye: Vector3, target: Vector3, up: Vector3) -> Matrix4x4;
53 fn CGL_mat4_lerp(a: &Matrix4x4, b: &Matrix4x4, t: f32) -> Matrix4x4;
54 fn CGL_mat4_decompose_lu(m: &Matrix4x4, l: *mut Matrix4x4, u: *mut Matrix4x4) -> std::ffi::c_void;
55}
56
57
58impl std::ops::Add<Matrix3x3> for Matrix3x3 {
59 type Output = Matrix3x3;
60
61 fn add(self, rhs: Matrix3x3) -> Matrix3x3 {
62 Matrix3x3 {
63 m: [
64 self.m[0] + rhs.m[0], self.m[1] + rhs.m[1], self.m[2] + rhs.m[2],
65 self.m[3] + rhs.m[3], self.m[4] + rhs.m[4], self.m[5] + rhs.m[5],
66 self.m[6] + rhs.m[6], self.m[7] + rhs.m[7], self.m[8] + rhs.m[8]
67 ]
68 }
69 }
70}
71
72impl std::ops::Sub<Matrix3x3> for Matrix3x3 {
73 type Output = Matrix3x3;
74
75 fn sub(self, rhs: Matrix3x3) -> Matrix3x3 {
76 Matrix3x3 {
77 m: [
78 self.m[0] - rhs.m[0], self.m[1] - rhs.m[1], self.m[2] - rhs.m[2],
79 self.m[3] - rhs.m[3], self.m[4] - rhs.m[4], self.m[5] - rhs.m[5],
80 self.m[6] - rhs.m[6], self.m[7] - rhs.m[7], self.m[8] - rhs.m[8]
81 ]
82 }
83 }
84}
85
86impl std::ops::Mul<f32> for Matrix3x3 {
87 type Output = Matrix3x3;
88
89 fn mul(self, rhs: f32) -> Matrix3x3 {
90 Matrix3x3 {
91 m: [
92 self.m[0] * rhs, self.m[1] * rhs, self.m[2] * rhs,
93 self.m[3] * rhs, self.m[4] * rhs, self.m[5] * rhs,
94 self.m[6] * rhs, self.m[7] * rhs, self.m[8] * rhs
95 ]
96 }
97 }
98}
99
100impl std::fmt::Display for Matrix3x3 {
101 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
102 write!(f, "{{\n\t[{}, {}, {}]\n\t[{}, {}, {}]\n\t[{}, {}, {}]\n}}",
103 self.m[0], self.m[3], self.m[6],
104 self.m[1], self.m[4], self.m[7],
105 self.m[2], self.m[5], self.m[8]
106 )
107 }
108}
109
110impl Matrix3x3 {
111 /// Creates a new 3x3 matrix.
112 ///
113 /// # Arguments
114 ///
115 /// m0 ... m8: The values of the matrix.
116 ///
117 /// # Returns
118 ///
119 /// A new 3x3 matrix.
120 ///
121 /// # Example
122 ///
123 /// ```
124 /// use cgl_rs::math::Matrix3x3;
125 ///
126 /// let m = Matrix3x3::new(
127 /// 1.0, 0.0, 0.0,
128 /// 0.0, 1.0, 0.0,
129 /// 0.0, 0.0, 1.0
130 /// );
131 /// ```
132 pub fn new(
133 m0: f32, m1: f32, m2: f32,
134 m3: f32, m4: f32, m5: f32,
135 m6: f32, m7: f32, m8: f32
136 ) -> Matrix3x3 {
137 Matrix3x3 {
138 m: [
139 m0, m3, m6,
140 m1, m4, m7,
141 m2, m5, m8
142 ]
143 }
144 }
145
146
147 /// Creates a new 3x3 matrix with all elements set to zero.
148 ///
149 /// # Returns
150 ///
151 /// A new 3x3 matrix with all elements set to zero.
152 ///
153 /// # Example
154 ///
155 /// ```
156 /// use cgl_rs::math::Matrix3x3;
157 ///
158 /// let m = Matrix3x3::zero();
159 /// ```
160 pub fn zero() -> Matrix3x3 {
161 Matrix3x3 {
162 m: [0.0; 9]
163 }
164 }
165
166
167
168 /// Creates a new 3x3 identity matrix.
169 ///
170 /// # Returns
171 ///
172 /// A new 3x3 identity matrix.
173 ///
174 /// # Example
175 ///
176 /// ```
177 /// use cgl_rs::math::Matrix3x3;
178 ///
179 /// let m = Matrix3x3::identity();
180 /// ```
181 pub fn identity() -> Matrix3x3 {
182 Matrix3x3::new(
183 1.0, 0.0, 0.0,
184 0.0, 1.0, 0.0,
185 0.0, 0.0, 1.0
186 )
187 }
188
189
190 /// Transposes the matrix.
191 ///
192 /// # Returns
193 ///
194 /// A new 3x3 matrix that is the transpose of the original matrix.
195 ///
196 /// # Example
197 ///
198 /// ```
199 /// use cgl_rs::math::Matrix3x3;
200 ///
201 /// let m = Matrix3x3::new(
202 /// 1.0, 2.0, 3.0,
203 /// 4.0, 5.0, 6.0,
204 /// 7.0, 8.0, 9.0
205 /// );
206 ///
207 /// let m_transpose = m.transpose();
208 /// ```
209 pub fn transpose(&self) -> Matrix3x3 {
210 unsafe {
211 CGL_mat3_transpose(self)
212 }
213 }
214
215 /// Calculates the trace of the matrix.
216 ///
217 /// # Returns
218 ///
219 /// The sum of the diagonal elements of the matrix.
220 ///
221 /// # Example
222 ///
223 /// ```
224 /// use cgl_rs::math::Matrix3x3;
225 ///
226 /// let m = Matrix3x3::new(
227 /// 1.0, 2.0, 3.0,
228 /// 4.0, 5.0, 6.0,
229 /// 7.0, 8.0, 9.0
230 /// );
231 ///
232 /// let trace = m.trace();
233 /// ```
234 pub fn trace(&self) -> f32 {
235 unsafe {
236 CGL_mat3_trace(self) as f32
237 }
238 }
239
240 /// Calculates the determinant of the matrix.
241 ///
242 /// # Returns
243 ///
244 /// The determinant of the matrix.
245 ///
246 /// # Example
247 ///
248 /// ```
249 /// use cgl_rs::math::Matrix3x3;
250 ///
251 /// let m = Matrix3x3::new(
252 /// 1.0, 2.0, 3.0,
253 /// 4.0, 5.0, 6.0,
254 /// 7.0, 8.0, 9.0
255 /// );
256 ///
257 /// let det = m.determinant();
258 /// ```
259 pub fn determinant(&self) -> f32 {
260 unsafe {
261 CGL_mat3_det(self) as f32
262 }
263 }
264
265}
266
267
268impl std::ops::Add<Matrix4x4> for Matrix4x4 {
269 type Output = Matrix4x4;
270
271 fn add(self, rhs: Matrix4x4) -> Matrix4x4 {
272 Matrix4x4 {
273 m: [
274 self.m[0] + rhs.m[0], self.m[1] + rhs.m[1], self.m[2] + rhs.m[2], self.m[3] + rhs.m[3],
275 self.m[4] + rhs.m[4], self.m[5] + rhs.m[5], self.m[6] + rhs.m[6], self.m[7] + rhs.m[7],
276 self.m[8] + rhs.m[8], self.m[9] + rhs.m[9], self.m[10] + rhs.m[10], self.m[11] + rhs.m[11],
277 self.m[12] + rhs.m[12], self.m[13] + rhs.m[13], self.m[14] + rhs.m[14], self.m[15] + rhs.m[15]
278 ]
279 }
280 }
281}
282
283impl std::ops::Sub<Matrix4x4> for Matrix4x4 {
284 type Output = Matrix4x4;
285
286 fn sub(self, rhs: Matrix4x4) -> Matrix4x4 {
287 Matrix4x4 {
288 m: [
289 self.m[0] - rhs.m[0], self.m[1] - rhs.m[1], self.m[2] - rhs.m[2], self.m[3] - rhs.m[3],
290 self.m[4] - rhs.m[4], self.m[5] - rhs.m[5], self.m[6] - rhs.m[6], self.m[7] - rhs.m[7],
291 self.m[8] - rhs.m[8], self.m[9] - rhs.m[9], self.m[10] - rhs.m[10], self.m[11] - rhs.m[11],
292 self.m[12] - rhs.m[12], self.m[13] - rhs.m[13], self.m[14] - rhs.m[14], self.m[15] - rhs.m[15]
293 ]
294 }
295 }
296}
297
298impl std::ops::Mul<f32> for Matrix4x4 {
299 type Output = Matrix4x4;
300
301 fn mul(self, rhs: f32) -> Matrix4x4 {
302 Matrix4x4 {
303 m: [
304 self.m[0] * rhs, self.m[1] * rhs, self.m[2] * rhs, self.m[3] * rhs,
305 self.m[4] * rhs, self.m[5] * rhs, self.m[6] * rhs, self.m[7] * rhs,
306 self.m[8] * rhs, self.m[9] * rhs, self.m[10] * rhs, self.m[11] * rhs,
307 self.m[12] * rhs, self.m[13] * rhs, self.m[14] * rhs, self.m[15] * rhs
308 ]
309 }
310 }
311}
312
313impl std::fmt::Display for Matrix4x4 {
314 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
315 write!(f, "{{\n\t[{}, {}, {}, {}]\n\t[{}, {}, {}, {}]\n\t[{}, {}, {}, {}]\n\t[{}, {}, {}, {}]\n}}",
316 self.m[0], self.m[1], self.m[2], self.m[3],
317 self.m[4], self.m[5], self.m[6], self.m[7],
318 self.m[8], self.m[9], self.m[10], self.m[11],
319 self.m[12], self.m[13], self.m[14], self.m[15]
320 )
321 }
322}
323
324impl Matrix4x4 {
325
326 /// Creates a new matrix with the given values.
327 ///
328 /// # Arguments
329 ///
330 /// * `m00 .. m33` - The values of the matrix.
331 ///
332 /// # Returns
333 ///
334 /// A new identity matrix.
335 ///
336 /// # Example
337 ///
338 /// ```
339 /// use cgl_rs::math::Matrix4x4;
340 ///
341 /// let m = Matrix4x4::new(
342 /// 1.0, 0.0, 0.0, 0.0,
343 /// 0.0, 1.0, 0.0, 0.0,
344 /// 0.0, 0.0, 1.0, 0.0,
345 /// 0.0, 0.0, 0.0, 1.0
346 /// );
347 ///
348 /// println!("{}", m);
349 /// ```
350 pub fn new(
351 m00: f32, m01: f32, m02: f32, m03: f32,
352 m10: f32, m11: f32, m12: f32, m13: f32,
353 m20: f32, m21: f32, m22: f32, m23: f32,
354 m30: f32, m31: f32, m32: f32, m33: f32
355 ) -> Matrix4x4 {
356 Matrix4x4 {
357 m: [
358 m00, m10, m20, m30,
359 m01, m11, m21, m31,
360 m02, m12, m22, m32,
361 m03, m13, m23, m33
362 ]
363 }
364 }
365
366 /// Creates a new 4x4 matrix from a 3x3 matrix.
367 ///
368 /// # Arguments
369 ///
370 /// * `m` - The 3x3 matrix to convert to a 4x4 matrix.
371 ///
372 /// # Returns
373 ///
374 /// A new 4x4 matrix with the same values as the input 3x3 matrix, with the fourth row and column set to zero.
375 ///
376 /// # Example
377 ///
378 /// ```
379 /// use cgl_rs::math::{Matrix3x3, Matrix4x4};
380 ///
381 /// let m3 = Matrix3x3::new(
382 /// 1.0, 2.0, 3.0,
383 /// 4.0, 5.0, 6.0,
384 /// 7.0, 8.0, 9.0
385 /// );
386 ///
387 /// let m4 = Matrix4x4::from_mat3(&m3);
388 /// ```
389 pub fn from_mat3(m: &Matrix3x3) -> Matrix4x4 {
390 unsafe {
391 CGL_mat4_from_mat3(&m) as Matrix4x4
392 }
393 }
394
395 /// Returns a new matrix with all elements set to zero.
396 ///
397 /// # Returns
398 ///
399 /// A new matrix with all elements set to zero.
400 ///
401 /// # Example
402 ///
403 /// ```
404 /// use cgl_rs::math::Matrix4x4;
405 ///
406 /// let m = Matrix4x4::zero();
407 /// ```
408 pub fn zero() -> Matrix4x4 {
409 unsafe {
410 CGL_mat4_zero_MACRO() as Matrix4x4
411 }
412 }
413
414
415 /// Returns a new identity matrix.
416 ///
417 /// # Returns
418 ///
419 /// A new identity matrix.
420 ///
421 /// # Example
422 ///
423 /// ```
424 /// use cgl_rs::math::Matrix4x4;
425 ///
426 /// let m = Matrix4x4::identity();
427 /// ```
428 pub fn identity() -> Matrix4x4 {
429 unsafe {
430 CGL_mat4_identity_MACRO() as Matrix4x4
431 }
432 }
433
434
435 /// Returns a new scaling matrix.
436 ///
437 /// # Arguments
438 ///
439 /// * `x` - The scaling factor along the x-axis.
440 /// * `y` - The scaling factor along the y-axis.
441 /// * `z` - The scaling factor along the z-axis.
442 ///
443 /// # Returns
444 ///
445 /// A new scaling matrix.
446 ///
447 /// # Example
448 ///
449 /// ```
450 /// use cgl_rs::math::Matrix4x4;
451 ///
452 /// let m = Matrix4x4::scale(2.0, 3.0, 4.0);
453 /// ```
454 pub fn scale(x: f32, y: f32, z: f32) -> Matrix4x4 {
455 unsafe {
456 CGL_mat4_scale_MACRO(x, y, z) as Matrix4x4
457 }
458 }
459
460
461 /// Returns a new translation matrix.
462 ///
463 /// # Arguments
464 ///
465 /// * `x` - The translation along the x-axis.
466 /// * `y` - The translation along the y-axis.
467 /// * `z` - The translation along the z-axis.
468 ///
469 /// # Returns
470 ///
471 /// A new translation matrix.
472 ///
473 /// # Example
474 ///
475 /// ```
476 /// use cgl_rs::math::Matrix4x4;
477 ///
478 /// let m = Matrix4x4::translate(1.0, 2.0, 3.0);
479 /// ```
480 pub fn translate(x: f32, y: f32, z: f32) -> Matrix4x4 {
481 unsafe {
482 CGL_mat4_translate_MACRO(x, y, z) as Matrix4x4
483 }
484 }
485
486
487 /// Returns a new rotation matrix around the x-axis.
488 ///
489 /// # Arguments
490 ///
491 /// * `angle` - The angle of rotation in radians.
492 ///
493 /// # Returns
494 ///
495 /// A new rotation matrix around the x-axis.
496 ///
497 /// # Example
498 ///
499 /// ```
500 /// use cgl_rs::math::Matrix4x4;
501 ///
502 /// let m = Matrix4x4::rotate_x(0.5);
503 /// ```
504 pub fn rotate_x(angle: f32) -> Matrix4x4 {
505 unsafe {
506 CGL_mat4_rotate_x_MACRO(angle) as Matrix4x4
507 }
508 }
509
510 /// Returns a new rotation matrix around the y-axis.
511 ///
512 /// # Arguments
513 ///
514 /// * `angle` - The angle of rotation in radians.
515 ///
516 /// # Returns
517 ///
518 /// A new rotation matrix around the y-axis.
519 ///
520 /// # Example
521 ///
522 /// ```
523 /// use cgl_rs::math::Matrix4x4;
524 ///
525 /// let m = Matrix4x4::rotate_y(0.5);
526 /// ```
527 pub fn rotate_y(angle: f32) -> Matrix4x4 {
528 unsafe {
529 CGL_mat4_rotate_y_MACRO(angle) as Matrix4x4
530 }
531 }
532
533
534 /// Returns a new rotation matrix around the z-axis.
535 ///
536 /// # Arguments
537 ///
538 /// * `angle` - The angle of rotation in radians.
539 ///
540 /// # Returns
541 ///
542 /// A new rotation matrix around the z-axis.
543 ///
544 /// # Example
545 ///
546 /// ```
547 /// use cgl_rs::math::Matrix4x4;
548 ///
549 /// let m = Matrix4x4::rotate_z(0.5);
550 /// ```
551 pub fn rotate_z(angle: f32) -> Matrix4x4 {
552 unsafe {
553 CGL_mat4_rotate_z_MACRO(angle) as Matrix4x4
554 }
555 }
556
557
558 /// Returns a new rotation matrix that rotates around the given axis by the specified angle.
559 ///
560 /// # Arguments
561 ///
562 /// * `axis` - The axis to rotate around.
563 /// * `angle` - The angle of rotation in radians.
564 ///
565 /// # Returns
566 ///
567 /// A new rotation matrix that rotates around the given axis by the specified angle.
568 ///
569 /// # Example
570 ///
571 /// ```
572 /// use cgl_rs::math::{Matrix4x4, Vector3};
573 ///
574 /// let axis = Vector3::new(1.0, 0.0, 0.0);
575 /// let m = Matrix4x4::rotate_about_axis(&axis, 0.5);
576 /// ```
577 pub fn rotate_about_axis(axis: &Vector3, angle: f32) -> Matrix4x4 {
578 unsafe {
579 CGL_mat4_rotate_about_axis(axis, angle) as Matrix4x4
580 }
581 }
582
583
584
585
586
587 /// Returns a new perspective projection matrix.
588 ///
589 /// # Arguments
590 ///
591 /// * `fov` - The field of view angle in radians.
592 /// * `aspect` - The aspect ratio of the projection.
593 /// * `near` - The distance to the near clipping plane.
594 /// * `far` - The distance to the far clipping plane.
595 ///
596 /// # Returns
597 ///
598 /// A new perspective projection matrix.
599 ///
600 /// # Example
601 ///
602 /// ```
603 /// use cgl_rs::math::Matrix4x4;
604 ///
605 /// let m = Matrix4x4::perspective(cgl_rs::math::constants::PI_2, 16.0/9.0, 0.1, 100.0);
606 /// ```
607 pub fn perspective(fov: f32, aspect: f32, near: f32, far: f32) -> Matrix4x4 {
608 unsafe {
609 CGL_mat4_perspective_MACRO(fov, aspect, near, far) as Matrix4x4
610 }
611 }
612
613
614 /// Returns a new orthographic projection matrix.
615 ///
616 /// # Arguments
617 ///
618 /// * `left` - The coordinate for the left vertical clipping plane.
619 /// * `right` - The coordinate for the right vertical clipping plane.
620 /// * `bottom` - The coordinate for the bottom horizontal clipping plane.
621 /// * `top` - The coordinate for the top horizontal clipping plane.
622 /// * `near` - The distance to the near clipping plane.
623 /// * `far` - The distance to the far clipping plane.
624 ///
625 /// # Returns
626 ///
627 /// A new orthographic projection matrix.
628 ///
629 /// # Example
630 ///
631 /// ```
632 /// use cgl_rs::math::Matrix4x4;
633 ///
634 /// let m = Matrix4x4::orthographic(-1.0, 1.0, -1.0, 1.0, 0.1, 100.0);
635 /// ```
636 pub fn orthographic(left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32) -> Matrix4x4 {
637 unsafe {
638 CGL_mat4_orthographic_MACRO(left, right, bottom, top, near, far) as Matrix4x4
639 }
640 }
641
642
643 /// Returns a new view matrix that looks from the eye position towards the target position.
644 ///
645 /// # Arguments
646 ///
647 /// * `eye` - The position of the camera.
648 /// * `target` - The position to look at.
649 /// * `up` - The up direction of the camera.
650 ///
651 /// # Returns
652 ///
653 /// A new view matrix.
654 ///
655 /// # Example
656 ///
657 /// ```
658 /// use cgl_rs::math::{Matrix4x4, Vector3};
659 ///
660 /// let mat = Matrix4x4::look_at(
661 /// Vector3::new(0.0, 0.0, 0.0),
662 /// Vector3::new(0.0, 0.0, -1.0),
663 /// Vector3::new(0.0, 1.0, 0.0)
664 /// );
665 /// ```
666 pub fn look_at(eye: Vector3, target: Vector3, up: Vector3) -> Matrix4x4 {
667 unsafe {
668 CGL_mat4_look_at(eye, target, up) as Matrix4x4
669 }
670 }
671
672 /// Multiplies this matrix by another matrix and returns the result.
673 ///
674 /// # Arguments
675 ///
676 /// * `other` - The matrix to multiply by.
677 ///
678 /// # Returns
679 ///
680 /// The resulting matrix of the multiplication.
681 ///
682 /// # Example
683 ///
684 /// ```
685 /// use cgl_rs::math::Matrix4x4;
686 ///
687 /// let m1 = Matrix4x4::identity();
688 /// let m2 = Matrix4x4::rotate_z(0.5);
689 /// let m3 = m1.mul(&m2);
690 /// ```
691 pub fn mul(&self, other: &Matrix4x4) -> Matrix4x4 {
692 unsafe {
693 CGL_mat4_mul(self, other) as Matrix4x4
694 }
695 }
696
697 /// Calculates the determinant of this matrix.
698 ///
699 /// # Returns
700 ///
701 /// The determinant of this matrix.
702 ///
703 /// # Example
704 ///
705 /// ```
706 /// use cgl_rs::math::Matrix4x4;
707 ///
708 /// let m = Matrix4x4::identity();
709 /// let det = m.determinant();
710 /// ```
711 pub fn determinant(&self) -> f32 {
712 unsafe {
713 CGL_mat4_det(self)
714 }
715 }
716
717 /// Multiplies this matrix by a vector and returns the result.
718 ///
719 /// # Arguments
720 ///
721 /// * `other` - The vector to multiply by.
722 ///
723 /// # Returns
724 ///
725 /// The resulting vector of the multiplication.
726 ///
727 /// # Example
728 ///
729 /// ```
730 /// use cgl_rs::math::{Matrix4x4, Vector4};
731 ///
732 /// let m = Matrix4x4::identity();
733 /// let v = Vector4::new(1.0, 2.0, 3.0, 1.0);
734 /// let result = m.mul_vec4(&v);
735 /// ```
736 pub fn mul_vec4(&self, other: &Vector4) -> Vector4 {
737 unsafe {
738 CGL_mat4_mul_vec4(self, other) as Vector4
739 }
740 }
741
742 /// Calculates the inverse of this matrix.
743 ///
744 /// # Returns
745 ///
746 /// The inverse of this matrix.
747 ///
748 /// # Example
749 ///
750 /// ```
751 /// use cgl_rs::math::Matrix4x4;
752 ///
753 /// let m = Matrix4x4::identity();
754 /// let inv = m.inverse();
755 /// ```
756 pub fn inverse(&self) -> Matrix4x4 {
757 unsafe {
758 CGL_mat4_inverse(self) as Matrix4x4
759 }
760 }
761
762 /// Transposes this matrix.
763 ///
764 /// # Returns
765 ///
766 /// The transposed matrix.
767 ///
768 /// # Example
769 ///
770 /// ```
771 /// use cgl_rs::math::Matrix4x4;
772 ///
773 /// let m = Matrix4x4::identity();
774 /// let transposed = m.transpose();
775 /// ```
776 pub fn transpose(&self) -> Matrix4x4 {
777 unsafe {
778 CGL_mat4_transpose(self) as Matrix4x4
779 }
780 }
781
782 /// Calculates the adjoint of this matrix.
783 ///
784 /// # Returns
785 ///
786 /// The adjoint of this matrix.
787 ///
788 /// # Example
789 ///
790 /// ```
791 /// use cgl_rs::math::Matrix4x4;
792 ///
793 /// let m = Matrix4x4::identity();
794 /// let adj = m.adjoint();
795 /// ```
796 pub fn adjoint(&self) -> Matrix4x4 {
797 unsafe {
798 CGL_mat4_adjoint(self) as Matrix4x4
799 }
800 }
801
802
803 /// Performs Gaussian elimination on this matrix.
804 ///
805 /// # Returns
806 ///
807 /// The matrix in row echelon form.
808 ///
809 /// # Example
810 ///
811 /// ```
812 /// use cgl_rs::math::Matrix4x4;
813 ///
814 /// let m = Matrix4x4::identity();
815 /// let row_echelon = m.gaussian_elimination();
816 /// ```
817 pub fn gaussian_elimination(&self) -> Matrix4x4 {
818 unsafe {
819 CGL_mat4_gauss_elim(self) as Matrix4x4
820 }
821 }
822
823 /// Calculates the rank of this matrix.
824 ///
825 /// # Returns
826 ///
827 /// The rank of this matrix.
828 ///
829 /// # Example
830 ///
831 /// ```
832 /// use cgl_rs::math::Matrix4x4;
833 ///
834 /// let m = Matrix4x4::identity();
835 /// let rank = m.rank();
836 /// ```
837 pub fn rank(&self) -> i32 {
838 unsafe {
839 CGL_mat4_rank(self)
840 }
841 }
842
843 /// Calculates the trace of this matrix.
844 ///
845 /// # Returns
846 ///
847 /// The trace of this matrix.
848 ///
849 /// # Example
850 ///
851 /// ```
852 /// use cgl_rs::math::Matrix4x4;
853 ///
854 /// let m = Matrix4x4::identity();
855 /// let trace = m.trace();
856 /// ```
857 pub fn trace(&self) -> f32 {
858 unsafe {
859 CGL_mat4_trace(self)
860 }
861 }
862
863 /// Converts this Matrix4x4 to a Matrix3x3 by discarding the last row and column.
864 ///
865 /// # Example
866 ///
867 /// ```
868 /// use cgl_rs::math::{Matrix3x3, Matrix4x4};
869 ///
870 /// let m = Matrix4x4::identity();
871 /// let m3 = m.to_mat3();
872 /// ```
873 pub fn to_mat3(&self) -> Matrix3x3 {
874 unsafe {
875 CGL_mat4_to_mat3(self) as Matrix3x3
876 }
877 }
878
879 /// Decomposes this matrix into lower and upper triangular matrices using LU decomposition.
880 ///
881 /// # Returns
882 ///
883 /// A tuple containing the lower and upper triangular matrices.
884 ///
885 /// # Example
886 ///
887 /// ```
888 /// use cgl_rs::math::Matrix4x4;
889 ///
890 /// let m = Matrix4x4::identity();
891 /// let (l, u) = m.decompose_lu();
892 /// ```
893 pub fn decompose_lu(&self) -> (Matrix4x4, Matrix4x4) {
894 unsafe {
895 let mut l = Matrix4x4::identity();
896 let mut u = Matrix4x4::identity();
897 CGL_mat4_decompose_lu(self, &mut l, &mut u);
898 (l, u)
899 }
900 }
901
902 /// Performs a linear interpolation between this matrix and another matrix.
903 ///
904 /// # Arguments
905 ///
906 /// * `other` - The other matrix to interpolate with.
907 /// * `t` - The interpolation factor. Should be between 0.0 and 1.0.
908 ///
909 /// # Returns
910 ///
911 /// The interpolated matrix.
912 ///
913 /// # Example
914 ///
915 /// ```
916 /// use cgl_rs::math::Matrix4x4;
917 ///
918 /// let m1 = Matrix4x4::identity();
919 /// let m2 = Matrix4x4::scale(1.0, 2.0, 3.0);
920 /// let m3 = m1.lerp(&m2, 0.5);
921 /// ```
922 pub fn lerp(&self, other: &Matrix4x4, t: f32) -> Matrix4x4 {
923 unsafe {
924 CGL_mat4_lerp(self, other, t) as Matrix4x4
925 }
926 }
927
928
929}