1#![allow(dead_code)]
2
3use std::{
4 fmt::Display,
5 ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
6};
7
8use crate::algebra::{vec4f, Mat2f, Mat3f, Mat4d, Vec3f, Vec4f};
9
10#[derive(Clone, Copy, PartialEq, Debug)]
11pub struct Mat4f {
12 x_axis: Vec4f,
13 y_axis: Vec4f,
14 z_axis: Vec4f,
15 w_axis: Vec4f,
16}
17
18pub fn mat4f(
19 m00: f32,
20 m01: f32,
21 m02: f32,
22 m03: f32,
23 m10: f32,
24 m11: f32,
25 m12: f32,
26 m13: f32,
27 m20: f32,
28 m21: f32,
29 m22: f32,
30 m23: f32,
31 m30: f32,
32 m31: f32,
33 m32: f32,
34 m33: f32,
35) -> Mat4f {
36 Mat4f::from_array([
37 m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33,
38 ])
39}
40
41impl Display for Mat4f {
42 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43 let (m00, m01, m02, m03) = self.x_axis.to_tuple();
44 let (m10, m11, m12, m13) = self.y_axis.to_tuple();
45 let (m20, m21, m22, m23) = self.z_axis.to_tuple();
46 let (m30, m31, m32, m33) = self.w_axis.to_tuple();
47 write!(
48 f,
49 "Mat4f({}, {}, {}, {} | {}, {}, {}, {} | {}, {}, {}, {} | {}, {}, {}, {})",
50 m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33
51 )
52 }
53}
54
55impl Default for Mat4f {
56 fn default() -> Self {
57 Self {
58 x_axis: Vec4f::default(),
59 y_axis: Vec4f::default(),
60 z_axis: Vec4f::default(),
61 w_axis: Vec4f::default(),
62 }
63 }
64}
65
66impl Add<Mat4f> for Mat4f {
67 type Output = Mat4f;
68
69 fn add(self, rhs: Mat4f) -> Self::Output {
70 Mat4f::new(
71 self.x_axis + rhs.x_axis,
72 self.y_axis + rhs.y_axis,
73 self.z_axis + rhs.z_axis,
74 self.w_axis + rhs.w_axis,
75 )
76 }
77}
78
79impl Add<f32> for Mat4f {
80 type Output = Mat4f;
81
82 fn add(self, rhs: f32) -> Self::Output {
83 Mat4f::new(
84 self.x_axis + rhs,
85 self.y_axis + rhs,
86 self.z_axis + rhs,
87 self.w_axis + rhs,
88 )
89 }
90}
91
92impl Add<Mat4f> for f32 {
93 type Output = Mat4f;
94
95 fn add(self, rhs: Mat4f) -> Self::Output {
96 Mat4f::new(
97 self + rhs.x_axis,
98 self + rhs.y_axis,
99 self + rhs.z_axis,
100 self + rhs.w_axis,
101 )
102 }
103}
104
105impl AddAssign<Mat4f> for Mat4f {
106 fn add_assign(&mut self, rhs: Mat4f) {
107 *self = *self + rhs;
108 }
109}
110
111impl AddAssign<f32> for Mat4f {
112 fn add_assign(&mut self, rhs: f32) {
113 *self = *self + rhs;
114 }
115}
116
117impl Sub<Mat4f> for Mat4f {
118 type Output = Mat4f;
119
120 fn sub(self, rhs: Mat4f) -> Self::Output {
121 Mat4f::new(
122 self.x_axis - rhs.x_axis,
123 self.y_axis - rhs.y_axis,
124 self.z_axis - rhs.z_axis,
125 self.w_axis - rhs.w_axis,
126 )
127 }
128}
129
130impl Sub<f32> for Mat4f {
131 type Output = Mat4f;
132
133 fn sub(self, rhs: f32) -> Self::Output {
134 Mat4f::new(
135 self.x_axis - rhs,
136 self.y_axis - rhs,
137 self.z_axis - rhs,
138 self.w_axis - rhs,
139 )
140 }
141}
142
143impl Sub<Mat4f> for f32 {
144 type Output = Mat4f;
145
146 fn sub(self, rhs: Mat4f) -> Self::Output {
147 Mat4f::new(
148 self - rhs.x_axis,
149 self - rhs.y_axis,
150 self - rhs.z_axis,
151 self - rhs.w_axis,
152 )
153 }
154}
155
156impl SubAssign<Mat4f> for Mat4f {
157 fn sub_assign(&mut self, rhs: Mat4f) {
158 *self = *self - rhs;
159 }
160}
161
162impl SubAssign<f32> for Mat4f {
163 fn sub_assign(&mut self, rhs: f32) {
164 *self = *self - rhs;
165 }
166}
167
168impl Mul<Mat4f> for Mat4f {
169 type Output = Mat4f;
170
171 fn mul(self, rhs: Mat4f) -> Self::Output {
172 let m00 = self
173 .x_axis
174 .dot(vec4f(rhs[0][0], rhs[1][0], rhs[2][0], rhs[3][0]));
175 let m01 = self
176 .x_axis
177 .dot(vec4f(rhs[0][1], rhs[1][1], rhs[2][1], rhs[3][1]));
178 let m02 = self
179 .x_axis
180 .dot(vec4f(rhs[0][2], rhs[1][2], rhs[2][2], rhs[3][2]));
181 let m03 = self
182 .x_axis
183 .dot(vec4f(rhs[0][3], rhs[1][3], rhs[2][3], rhs[3][3]));
184
185 let m10 = self
186 .y_axis
187 .dot(vec4f(rhs[0][0], rhs[1][0], rhs[2][0], rhs[3][0]));
188 let m11 = self
189 .y_axis
190 .dot(vec4f(rhs[0][1], rhs[1][1], rhs[2][1], rhs[3][1]));
191 let m12 = self
192 .y_axis
193 .dot(vec4f(rhs[0][2], rhs[1][2], rhs[2][2], rhs[3][2]));
194 let m13 = self
195 .y_axis
196 .dot(vec4f(rhs[0][3], rhs[1][3], rhs[2][3], rhs[3][3]));
197
198 let m20 = self
199 .z_axis
200 .dot(vec4f(rhs[0][0], rhs[1][0], rhs[2][0], rhs[3][0]));
201 let m21 = self
202 .z_axis
203 .dot(vec4f(rhs[0][1], rhs[1][1], rhs[2][1], rhs[3][1]));
204 let m22 = self
205 .z_axis
206 .dot(vec4f(rhs[0][2], rhs[1][2], rhs[2][2], rhs[3][2]));
207 let m23 = self
208 .z_axis
209 .dot(vec4f(rhs[0][3], rhs[1][3], rhs[2][3], rhs[3][3]));
210
211 let m30 = self
212 .w_axis
213 .dot(vec4f(rhs[0][0], rhs[1][0], rhs[2][0], rhs[3][0]));
214 let m31 = self
215 .w_axis
216 .dot(vec4f(rhs[0][1], rhs[1][1], rhs[2][1], rhs[3][1]));
217 let m32 = self
218 .w_axis
219 .dot(vec4f(rhs[0][2], rhs[1][2], rhs[2][2], rhs[3][2]));
220 let m33 = self
221 .w_axis
222 .dot(vec4f(rhs[0][3], rhs[1][3], rhs[2][3], rhs[3][3]));
223
224 Mat4f::new(
225 vec4f(m00, m01, m02, m03),
226 vec4f(m10, m11, m12, m13),
227 vec4f(m20, m21, m22, m23),
228 vec4f(m30, m31, m32, m33),
229 )
230 }
231}
232
233impl Mul<Vec4f> for Mat4f {
234 type Output = Vec4f;
235
236 fn mul(self, rhs: Vec4f) -> Self::Output {
237 let v0 = self.x_axis.dot(rhs);
238 let v1 = self.y_axis.dot(rhs);
239 let v2 = self.z_axis.dot(rhs);
240 let v3 = self.w_axis.dot(rhs);
241 vec4f(v0, v1, v2, v3)
242 }
243}
244
245impl Mul<f32> for Mat4f {
246 type Output = Mat4f;
247
248 fn mul(self, rhs: f32) -> Self::Output {
249 Mat4f::new(
250 self.x_axis * rhs,
251 self.y_axis * rhs,
252 self.z_axis * rhs,
253 self.w_axis * rhs,
254 )
255 }
256}
257
258impl Mul<Mat4f> for f32 {
259 type Output = Mat4f;
260
261 fn mul(self, rhs: Mat4f) -> Self::Output {
262 Mat4f::new(
263 self * rhs.x_axis,
264 self * rhs.y_axis,
265 self * rhs.z_axis,
266 self * rhs.w_axis,
267 )
268 }
269}
270
271impl MulAssign<Mat4f> for Mat4f {
272 fn mul_assign(&mut self, rhs: Mat4f) {
273 *self = *self * rhs;
274 }
275}
276
277impl MulAssign<f32> for Mat4f {
278 fn mul_assign(&mut self, rhs: f32) {
279 *self = *self * rhs;
280 }
281}
282
283impl Div<f32> for Mat4f {
284 type Output = Mat4f;
285
286 fn div(self, rhs: f32) -> Self::Output {
287 Mat4f::new(
288 self.x_axis / rhs,
289 self.y_axis / rhs,
290 self.z_axis / rhs,
291 self.w_axis / rhs,
292 )
293 }
294}
295
296impl DivAssign<f32> for Mat4f {
297 fn div_assign(&mut self, rhs: f32) {
298 *self = *self / rhs;
299 }
300}
301
302impl Index<usize> for Mat4f {
303 type Output = Vec4f;
304
305 fn index(&self, index: usize) -> &Self::Output {
306 match index {
307 0 => &self.x_axis,
308 1 => &self.y_axis,
309 2 => &self.z_axis,
310 3 => &self.w_axis,
311 _ => panic!("`rmath::algebra::Mat4f::index`: index out of bounds."),
312 }
313 }
314}
315
316impl IndexMut<usize> for Mat4f {
317 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
318 match index {
319 0 => &mut self.x_axis,
320 1 => &mut self.y_axis,
321 2 => &mut self.z_axis,
322 3 => &mut self.w_axis,
323 _ => panic!("`rmath::algebra::Mat4f::index_mut`: index out of bounds."),
324 }
325 }
326}
327
328impl Mat4f {
329 pub fn new(x_axis: Vec4f, y_axis: Vec4f, z_axis: Vec4f, w_axis: Vec4f) -> Self {
330 Self {
331 x_axis,
332 y_axis,
333 z_axis,
334 w_axis,
335 }
336 }
337
338 pub fn zero() -> Self {
339 Self::new(
340 vec4f(0.0, 0.0, 0.0, 0.0),
341 vec4f(0.0, 0.0, 0.0, 0.0),
342 vec4f(0.0, 0.0, 0.0, 0.0),
343 vec4f(0.0, 0.0, 0.0, 0.0),
344 )
345 }
346
347 pub fn identity() -> Self {
348 Self::new(
349 vec4f(1.0, 0.0, 0.0, 0.0),
350 vec4f(0.0, 1.0, 0.0, 0.0),
351 vec4f(0.0, 0.0, 1.0, 0.0),
352 vec4f(0.0, 0.0, 0.0, 1.0),
353 )
354 }
355}
356
357impl Mat4f {
358 pub fn col(&self, index: usize) -> Vec4f {
359 match index {
360 0 => vec4f(self[0][0], self[1][0], self[2][0], self[3][0]),
361 1 => vec4f(self[0][1], self[1][1], self[2][1], self[3][1]),
362 2 => vec4f(self[0][2], self[1][2], self[2][2], self[3][2]),
363 3 => vec4f(self[0][3], self[1][3], self[2][3], self[3][3]),
364 _ => panic!("`rmath::algebra::Mat4f::col`: index out of bounds."),
365 }
366 }
367
368 pub fn row(&self, index: usize) -> Vec4f {
369 match index {
370 0 => self.x_axis,
371 1 => self.y_axis,
372 2 => self.z_axis,
373 3 => self.w_axis,
374 _ => panic!("`rmath::algebra::Mat4f::row`: index out of bounds."),
375 }
376 }
377
378 pub fn is_nan(&self) -> bool {
379 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan() || self.w_axis.is_nan()
380 }
381
382 pub fn is_infinite(&self) -> bool {
383 self.x_axis.is_infinite()
384 || self.y_axis.is_infinite()
385 || self.z_axis.is_infinite()
386 || self.z_axis.is_infinite()
387 }
388
389 pub fn is_finite(&self) -> bool {
390 self.x_axis.is_finite()
391 && self.y_axis.is_finite()
392 && self.z_axis.is_finite()
393 && self.w_axis.is_finite()
394 }
395
396 pub fn transpose(&self) -> Self {
397 let (m00, m01, m02, m03) = self.x_axis.to_tuple();
398 let (m10, m11, m12, m13) = self.y_axis.to_tuple();
399 let (m20, m21, m22, m23) = self.z_axis.to_tuple();
400 let (m30, m31, m32, m33) = self.w_axis.to_tuple();
401 Self::new(
402 vec4f(m00, m10, m20, m30),
403 vec4f(m01, m11, m21, m31),
404 vec4f(m02, m12, m22, m32),
405 vec4f(m03, m13, m23, m33),
406 )
407 }
408
409 pub fn determinant(&self) -> f32 {
410 let (m00, m01, m02, m03) = self.x_axis.to_tuple();
411 let (m10, m11, m12, m13) = self.y_axis.to_tuple();
412 let (m20, m21, m22, m23) = self.z_axis.to_tuple();
413 let (m30, m31, m32, m33) = self.w_axis.to_tuple();
414
415 let c23 = m22 * m33 - m23 * m32;
416 let c13 = m21 * m33 - m23 * m31;
417 let c12 = m21 * m32 - m22 * m31;
418 let c03 = m20 * m33 - m23 * m30;
419 let c02 = m20 * m32 - m22 * m30;
420 let c01 = m20 * m31 - m21 * m30;
421
422 let a00 = m11 * c23 - m12 * c13 + m13 * c12;
423 let a01 = m10 * c23 - m12 * c03 + m13 * c02;
424 let a02 = m10 * c13 - m11 * c03 + m13 * c01;
425 let a03 = m10 * c12 - m11 * c02 + m12 * c01;
426
427 m00 * a00 - m01 * a01 + m02 * a02 - m03 * a03
428 }
429
430 pub fn inverse(&self) -> Self {
431 let det = self.determinant();
432 ruby_assert!(!(det.abs() < f32::EPSILON));
433
434 let (m00, m01, m02, m03) = self.x_axis.to_tuple();
435 let (m10, m11, m12, m13) = self.y_axis.to_tuple();
436 let (m20, m21, m22, m23) = self.z_axis.to_tuple();
437 let (m30, m31, m32, m33) = self.w_axis.to_tuple();
438
439 let c1201 = m10 * m21 - m11 * m20;
440 let c1202 = m10 * m22 - m12 * m20;
441 let c1203 = m10 * m23 - m13 * m20;
442 let c1212 = m11 * m22 - m12 * m21;
443 let c1213 = m11 * m23 - m13 * m21;
444 let c1223 = m12 * m23 - m13 * m22;
445
446 let c1301 = m10 * m31 - m11 * m30;
447 let c1302 = m10 * m32 - m12 * m30;
448 let c1303 = m10 * m33 - m13 * m30;
449 let c1312 = m11 * m32 - m12 * m31;
450 let c1313 = m11 * m33 - m13 * m31;
451 let c1323 = m12 * m33 - m13 * m32;
452
453 let c2301 = m20 * m31 - m21 * m30;
454 let c2302 = m20 * m32 - m22 * m30;
455 let c2303 = m20 * m33 - m23 * m30;
456 let c2312 = m21 * m32 - m22 * m31;
457 let c2313 = m21 * m33 - m22 * m31;
458 let c2323 = m22 * m33 - m23 * m32;
459
460 let a00 = m11 * c2323 - m12 * c2313 + m13 * c2312;
461 let a01 = -(m10 * c2323 - m12 * c2303 + m13 * c2302);
462 let a02 = m10 * c2313 - m11 * c2303 + m13 * c2301;
463 let a03 = -(m10 * c2312 - m11 * c2302 + m12 * c2301);
464
465 let a10 = -(m01 * c2323 - m02 * c2313 + m03 * c2312);
466 let a11 = m00 * c2323 - m02 * c2303 + m03 * c2302;
467 let a12 = -(m00 * c2313 - m01 * c2303 + m03 * c2301);
468 let a13 = m00 * c2312 - m01 * c2302 + m02 * c2301;
469
470 let a20 = m01 * c1323 - m02 * c1313 + m03 * c1312;
471 let a21 = -(m00 * c1323 - m02 * c1303 + m03 * c1302);
472 let a22 = m00 * c1313 - m01 * c1303 + m03 * c1301;
473 let a23 = -(m00 * c1312 - m01 * c1302 + m02 * c1301);
474
475 let a30 = -(m01 * c1223 - m02 * c1213 + m03 * c1212);
476 let a31 = m00 * c1223 - m02 * c1203 + m03 * c1202;
477 let a32 = -(m00 * c1213 - m01 * c1203 + m03 * c1201);
478 let a33 = m00 * c1212 - m01 * c1202 + m02 * c1201;
479
480 Self::new(
481 vec4f(a00, a10, a20, a30),
482 vec4f(a01, a11, a21, a31),
483 vec4f(a02, a12, a22, a32),
484 vec4f(a03, a13, a23, a33),
485 )
486 .mul(det.recip())
487 }
488
489 pub fn try_inverse(&self) -> Option<Self> {
490 let det = self.determinant();
491 if det.abs() < f32::EPSILON {
492 return None;
493 }
494
495 let (m00, m01, m02, m03) = self.x_axis.to_tuple();
496 let (m10, m11, m12, m13) = self.y_axis.to_tuple();
497 let (m20, m21, m22, m23) = self.z_axis.to_tuple();
498 let (m30, m31, m32, m33) = self.w_axis.to_tuple();
499
500 let c1201 = m10 * m21 - m11 * m20;
501 let c1202 = m10 * m22 - m12 * m20;
502 let c1203 = m10 * m23 - m13 * m20;
503 let c1212 = m11 * m22 - m12 * m21;
504 let c1213 = m11 * m23 - m13 * m21;
505 let c1223 = m12 * m23 - m13 * m22;
506
507 let c1301 = m10 * m31 - m11 * m30;
508 let c1302 = m10 * m32 - m12 * m30;
509 let c1303 = m10 * m33 - m13 * m30;
510 let c1312 = m11 * m32 - m12 * m31;
511 let c1313 = m11 * m33 - m13 * m31;
512 let c1323 = m12 * m33 - m13 * m32;
513
514 let c2301 = m20 * m31 - m21 * m30;
515 let c2302 = m20 * m32 - m22 * m30;
516 let c2303 = m20 * m33 - m23 * m30;
517 let c2312 = m21 * m32 - m22 * m31;
518 let c2313 = m21 * m33 - m22 * m31;
519 let c2323 = m22 * m33 - m23 * m32;
520
521 let a00 = m11 * c2323 - m12 * c2313 + m13 * c2312;
522 let a01 = -(m10 * c2323 - m12 * c2303 + m13 * c2302);
523 let a02 = m10 * c2313 - m11 * c2303 + m13 * c2301;
524 let a03 = -(m10 * c2312 - m11 * c2302 + m12 * c2301);
525
526 let a10 = -(m01 * c2323 - m02 * c2313 + m03 * c2312);
527 let a11 = m00 * c2323 - m02 * c2303 + m03 * c2302;
528 let a12 = -(m00 * c2313 - m01 * c2303 + m03 * c2301);
529 let a13 = m00 * c2312 - m01 * c2302 + m02 * c2301;
530
531 let a20 = m01 * c1323 - m02 * c1313 + m03 * c1312;
532 let a21 = -(m00 * c1323 - m02 * c1303 + m03 * c1302);
533 let a22 = m00 * c1313 - m01 * c1303 + m03 * c1301;
534 let a23 = -(m00 * c1312 - m01 * c1302 + m02 * c1301);
535
536 let a30 = -(m01 * c1223 - m02 * c1213 + m03 * c1212);
537 let a31 = m00 * c1223 - m02 * c1203 + m03 * c1202;
538 let a32 = -(m00 * c1213 - m01 * c1203 + m03 * c1201);
539 let a33 = m00 * c1212 - m01 * c1202 + m02 * c1201;
540
541 Some(
542 Self::new(
543 vec4f(a00, a10, a20, a30),
544 vec4f(a01, a11, a21, a31),
545 vec4f(a02, a12, a22, a32),
546 vec4f(a03, a13, a23, a33),
547 )
548 .mul(det.recip()),
549 )
550 }
551}
552
553impl From<Mat2f> for Mat4f {
554 fn from(m: Mat2f) -> Self {
555 mat4f(
556 m[0][0], m[0][1], 0.0, 0.0, m[1][0], m[1][1], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
557 0.0, 1.0,
558 )
559 }
560}
561
562impl From<Mat3f> for Mat4f {
563 fn from(m: Mat3f) -> Self {
564 mat4f(
565 m[0][0], m[0][1], m[0][2], 0.0, m[1][0], m[1][1], m[1][2], 0.0, m[2][0], m[2][1],
566 m[2][2], 0.0, 0.0, 0.0, 0.0, 1.0,
567 )
568 }
569}
570
571impl Mat4f {
572 pub fn from_array(m: [f32; 16]) -> Self {
573 Self::new(
574 vec4f(m[0], m[1], m[2], m[3]),
575 vec4f(m[4], m[5], m[6], m[7]),
576 vec4f(m[8], m[9], m[10], m[11]),
577 vec4f(m[12], m[13], m[14], m[15]),
578 )
579 }
580
581 pub fn from_array_2d(m: [[f32; 4]; 4]) -> Self {
582 Self::new(
583 vec4f(m[0][0], m[0][1], m[0][2], m[0][3]),
584 vec4f(m[1][0], m[1][1], m[1][2], m[1][3]),
585 vec4f(m[2][0], m[2][1], m[2][2], m[2][3]),
586 vec4f(m[3][0], m[3][1], m[3][2], m[3][3]),
587 )
588 }
589
590 pub fn from_diagonal(diagonal: Vec4f) -> Self {
591 Self::new(
592 vec4f(diagonal.x(), 0.0, 0.0, 0.0),
593 vec4f(0.0, diagonal.y(), 0.0, 0.0),
594 vec4f(0.0, 0.0, diagonal.z(), 0.0),
595 vec4f(0.0, 0.0, 0.0, diagonal.w()),
596 )
597 }
598}
599
600impl Mat4f {
601 pub fn to_array(self) -> [f32; 16] {
602 [
603 self[0][0], self[0][1], self[0][2], self[0][3], self[1][0], self[1][1], self[1][2],
604 self[1][3], self[2][0], self[2][1], self[2][2], self[2][3], self[3][0], self[3][1],
605 self[3][2], self[3][3],
606 ]
607 }
608
609 pub fn to_array_2d(self) -> [[f32; 4]; 4] {
610 [
611 [self[0][0], self[0][1], self[0][2], self[0][3]],
612 [self[1][0], self[1][1], self[1][2], self[1][3]],
613 [self[2][0], self[2][1], self[2][2], self[2][3]],
614 [self[3][0], self[3][1], self[3][2], self[3][3]],
615 ]
616 }
617
618 pub fn to_mat2f(self) -> Mat2f {
619 Mat2f::from(self)
620 }
621
622 pub fn to_mat3f(self) -> Mat3f {
623 Mat3f::from(self)
624 }
625
626 pub fn to_mat4d(self) -> Mat4d {
627 Mat4d::new(
628 self.x_axis.to_vec4d(),
629 self.y_axis.to_vec4d(),
630 self.z_axis.to_vec4d(),
631 self.w_axis.to_vec4d(),
632 )
633 }
634}
635
636impl Mat4f {
637 pub fn translation(translate: Vec3f) -> Self {
638 Self::new(
639 vec4f(1.0, 0.0, 0.0, translate.x()),
640 vec4f(0.0, 1.0, 0.0, translate.y()),
641 vec4f(0.0, 0.0, 1.0, translate.z()),
642 vec4f(0.0, 0.0, 0.0, 1.0),
643 )
644 }
645
646 pub fn rotation_x(angle: f32) -> Self {
647 let (sin, cos) = angle.to_radians().sin_cos();
648 Self::new(
649 vec4f(1.0, 0.0, 0.0, 0.0),
650 vec4f(0.0, cos, -sin, 0.0),
651 vec4f(0.0, sin, cos, 0.0),
652 vec4f(0.0, 0.0, 0.0, 1.0),
653 )
654 }
655
656 pub fn rotation_y(angle: f32) -> Self {
657 let (sin, cos) = angle.to_radians().sin_cos();
658 Self::new(
659 vec4f(cos, 0.0, sin, 0.0),
660 vec4f(0.0, 1.0, 0.0, 0.0),
661 vec4f(-sin, 0.0, cos, 0.0),
662 vec4f(0.0, 0.0, 0.0, 1.0),
663 )
664 }
665
666 pub fn rotation_z(angle: f32) -> Self {
667 let (sin, cos) = angle.to_radians().sin_cos();
668 Self::new(
669 vec4f(cos, -sin, 0.0, 0.0),
670 vec4f(sin, cos, 0.0, 0.0),
671 vec4f(0.0, 0.0, 1.0, 0.0),
672 vec4f(0.0, 0.0, 0.0, 1.0),
673 )
674 }
675
676 pub fn rotation_axis(axis: Vec3f, angle: f32) -> Self {
677 let axis = axis.normalize();
678 let (sin, cos) = angle.to_radians().sin_cos();
679 let rotation = cos * Self::identity()
680 + (1.0 - cos)
681 * Self::new(
682 axis.x().mul(axis).to_homogeneous_coord_vector(),
683 axis.y().mul(axis).to_homogeneous_coord_vector(),
684 axis.z().mul(axis).to_homogeneous_coord_vector(),
685 Vec4f::zero(),
686 )
687 + sin
688 * Self::new(
689 vec4f(0.0, -axis.z(), axis.y(), 0.0),
690 vec4f(axis.z(), 0.0, -axis.x(), 0.0),
691 vec4f(-axis.y(), axis.x(), 0.0, 0.0),
692 Vec4f::zero(),
693 );
694 rotation
695 }
696
697 pub fn scale(scale: Vec3f) -> Self {
698 Self::new(
699 vec4f(scale.x(), 0.0, 0.0, 0.0),
700 vec4f(0.0, scale.y(), 0.0, 0.0),
701 vec4f(0.0, 0.0, scale.z(), 0.0),
702 vec4f(0.0, 0.0, 0.0, 1.0),
703 )
704 }
705
706 pub fn look_at(eye: Vec3f, target: Vec3f, up: Vec3f) -> Self {
707 let g = (target - eye).normalize();
708 let u = up.normalize();
709 let s = g.cross(u).normalize();
710 let u = s.cross(g);
711 let g = -g;
712
713 Self::new(
714 vec4f(s.x(), s.y(), s.z(), s.dot(-eye)),
715 vec4f(u.x(), u.y(), u.z(), u.dot(-eye)),
716 vec4f(g.x(), g.y(), g.z(), g.dot(-eye)),
717 vec4f(0.0, 0.0, 0.0, 1.0),
718 )
719 }
720
721 pub fn perspective(fovy: f32, aspect: f32, z_near: f32, z_far: f32) -> Self {
722 ruby_assert!(aspect.abs() > f32::EPSILON);
723
724 let (n, f) = (z_near, z_far);
725 let tan_half_theta = fovy.to_radians().mul(0.5).tan();
726
727 let perspective = Self::new(
728 vec4f(tan_half_theta.mul(aspect).recip(), 0.0, 0.0, 0.0),
729 vec4f(0.0, tan_half_theta.recip(), 0.0, 0.0),
730 vec4f(0.0, 0.0, -(n + f) / (f - n), -2.0 * n * f / (f - n)),
731 vec4f(0.0, 0.0, -1.0, 0.0),
732 );
733
734 perspective
735 }
736}