Mercurial > touhou
comparison utils/src/math.rs @ 790:d005f5927447
utils: Use const_for to make more const fn
| author | Link Mauve <linkmauve@linkmauve.fr> |
|---|---|
| date | Sat, 17 Jan 2026 14:12:08 +0100 |
| parents | b5bca9274335 |
| children | a29122662cde |
comparison
equal
deleted
inserted
replaced
| 789:b5bca9274335 | 790:d005f5927447 |
|---|---|
| 1 //! Various helpers to deal with vectors and matrices. | 1 //! Various helpers to deal with vectors and matrices. |
| 2 | |
| 3 use const_for::const_for; | |
| 2 | 4 |
| 3 /// A 4×4 f32 matrix type. | 5 /// A 4×4 f32 matrix type. |
| 4 pub struct Mat4 { | 6 pub struct Mat4 { |
| 5 inner: [[f32; 4]; 4] | 7 inner: [[f32; 4]; 4] |
| 6 } | 8 } |
| 32 pub const fn borrow_inner(&self) -> &[[f32; 4]; 4] { | 34 pub const fn borrow_inner(&self) -> &[[f32; 4]; 4] { |
| 33 &self.inner | 35 &self.inner |
| 34 } | 36 } |
| 35 | 37 |
| 36 /// Scale the matrix in 2D. | 38 /// Scale the matrix in 2D. |
| 37 pub fn scale2d(&mut self, x: f32, y: f32) { | 39 pub const fn scale2d(&mut self, x: f32, y: f32) { |
| 38 for i in 0..4 { | 40 const_for!(i in 0..4 => { |
| 39 self.inner[0][i] *= x; | 41 self.inner[0][i] *= x; |
| 40 self.inner[1][i] *= y; | 42 self.inner[1][i] *= y; |
| 41 } | 43 }); |
| 42 } | 44 } |
| 43 | 45 |
| 44 /// Flip the matrix. | 46 /// Flip the matrix. |
| 45 pub fn flip(&mut self) { | 47 pub const fn flip(&mut self) { |
| 46 for i in 0..4 { | 48 const_for!(i in 0..4 => { |
| 47 self.inner[0][i] = -self.inner[0][i]; | 49 self.inner[0][i] = -self.inner[0][i]; |
| 48 } | 50 }); |
| 49 } | 51 } |
| 50 | 52 |
| 51 /// Rotate the matrix around its x angle (in radians). | 53 /// Rotate the matrix around its x angle (in radians). |
| 52 pub fn rotate_x(&mut self, angle: f32) { | 54 pub fn rotate_x(&mut self, angle: f32) { |
| 53 let mut lines: [f32; 8] = [0.; 8]; | 55 let mut lines: [f32; 8] = [0.; 8]; |
| 54 let cos_a = angle.cos(); | 56 let cos_a = angle.cos(); |
| 55 let sin_a = angle.sin(); | 57 let sin_a = angle.sin(); |
| 56 for i in 0..4 { | 58 const_for!(i in 0..4 => { |
| 57 lines[ i] = self.inner[0][i]; | 59 lines[ i] = self.inner[0][i]; |
| 58 lines[4 + i] = self.inner[1][i]; | 60 lines[4 + i] = self.inner[1][i]; |
| 59 } | 61 }); |
| 60 for i in 0..4 { | 62 const_for!(i in 0..4 => { |
| 61 self.inner[1][i] = cos_a * lines[i] - sin_a * lines[4+i]; | 63 self.inner[1][i] = cos_a * lines[i] - sin_a * lines[4+i]; |
| 62 self.inner[2][i] = sin_a * lines[i] + cos_a * lines[4+i]; | 64 self.inner[2][i] = sin_a * lines[i] + cos_a * lines[4+i]; |
| 63 } | 65 }); |
| 64 } | 66 } |
| 65 | 67 |
| 66 /// Rotate the matrix around its y angle (in radians). | 68 /// Rotate the matrix around its y angle (in radians). |
| 67 pub fn rotate_y(&mut self, angle: f32) { | 69 pub fn rotate_y(&mut self, angle: f32) { |
| 68 let mut lines: [f32; 8] = [0.; 8]; | 70 let mut lines: [f32; 8] = [0.; 8]; |
| 69 let cos_a = angle.cos(); | 71 let cos_a = angle.cos(); |
| 70 let sin_a = angle.sin(); | 72 let sin_a = angle.sin(); |
| 71 for i in 0..4 { | 73 const_for!(i in 0..4 => { |
| 72 lines[ i] = self.inner[0][i]; | 74 lines[ i] = self.inner[0][i]; |
| 73 lines[4 + i] = self.inner[2][i]; | 75 lines[4 + i] = self.inner[2][i]; |
| 74 } | 76 }); |
| 75 for i in 0..4 { | 77 const_for!(i in 0..4 => { |
| 76 self.inner[0][i] = cos_a * lines[i] + sin_a * lines[4+i]; | 78 self.inner[0][i] = cos_a * lines[i] + sin_a * lines[4+i]; |
| 77 self.inner[2][i] = -sin_a * lines[i] + cos_a * lines[4+i]; | 79 self.inner[2][i] = -sin_a * lines[i] + cos_a * lines[4+i]; |
| 78 } | 80 }); |
| 79 } | 81 } |
| 80 | 82 |
| 81 /// Rotate the matrix around its z angle (in radians). | 83 /// Rotate the matrix around its z angle (in radians). |
| 82 pub fn rotate_z(&mut self, angle: f32) { | 84 pub fn rotate_z(&mut self, angle: f32) { |
| 83 let mut lines: [f32; 8] = [0.; 8]; | 85 let mut lines: [f32; 8] = [0.; 8]; |
| 84 let cos_a = angle.cos(); | 86 let cos_a = angle.cos(); |
| 85 let sin_a = angle.sin(); | 87 let sin_a = angle.sin(); |
| 86 for i in 0..4 { | 88 const_for!(i in 0..4 => { |
| 87 lines[ i] = self.inner[0][i]; | 89 lines[ i] = self.inner[0][i]; |
| 88 lines[4 + i] = self.inner[1][i]; | 90 lines[4 + i] = self.inner[1][i]; |
| 89 } | 91 }); |
| 90 for i in 0..4 { | 92 const_for!(i in 0..4 => { |
| 91 self.inner[0][i] = cos_a * lines[i] - sin_a * lines[4+i]; | 93 self.inner[0][i] = cos_a * lines[i] - sin_a * lines[4+i]; |
| 92 self.inner[1][i] = sin_a * lines[i] + cos_a * lines[4+i]; | 94 self.inner[1][i] = sin_a * lines[i] + cos_a * lines[4+i]; |
| 93 } | 95 }); |
| 94 } | 96 } |
| 95 | 97 |
| 96 /// Translate the matrix by a 3D offset. | 98 /// Translate the matrix by a 3D offset. |
| 97 pub fn translate(&mut self, offset: [f32; 3]) { | 99 pub const fn translate(&mut self, offset: [f32; 3]) { |
| 98 let mut item: [f32; 3] = [0.; 3]; | 100 let mut item: [f32; 3] = [0.; 3]; |
| 99 for i in 0..3 { | 101 const_for!(i in 0..3 => { |
| 100 item[i] = self.inner[3][i] * offset[i]; | 102 item[i] = self.inner[3][i] * offset[i]; |
| 101 } | 103 }); |
| 102 for i in 0..3 { | 104 const_for!(i in 0..3 => { |
| 103 for j in 0..4 { | 105 const_for!(j in 0..4 => { |
| 104 self.inner[i][j] += item[i]; | 106 self.inner[i][j] += item[i]; |
| 105 } | 107 }); |
| 106 } | 108 }); |
| 107 } | 109 } |
| 108 | 110 |
| 109 /// Translate the matrix by a 2D offset. | 111 /// Translate the matrix by a 2D offset. |
| 110 pub fn translate_2d(&mut self, x: f32, y: f32) { | 112 pub const fn translate_2d(&mut self, x: f32, y: f32) { |
| 111 let offset = [x, y, 0.]; | 113 let offset = [x, y, 0.]; |
| 112 self.translate(offset); | 114 self.translate(offset); |
| 113 } | 115 } |
| 114 } | 116 } |
| 115 | 117 |
| 116 impl std::ops::Mul<Mat4> for Mat4 { | 118 impl std::ops::Mul<Mat4> for Mat4 { |
| 117 type Output = Mat4; | 119 type Output = Mat4; |
| 118 fn mul(self, rhs: Mat4) -> Mat4 { | 120 fn mul(self, rhs: Mat4) -> Mat4 { |
| 119 let mut tmp = Mat4::zero(); | 121 let mut tmp = Mat4::zero(); |
| 120 for i in 0..4 { | 122 const_for!(i in 0..4 => { |
| 121 for j in 0..4 { | 123 const_for!(j in 0..4 => { |
| 122 for k in 0..4 { | 124 const_for!(k in 0..4 => { |
| 123 tmp.inner[i][j] += self.inner[i][k] * rhs.inner[k][j]; | 125 tmp.inner[i][j] += self.inner[i][k] * rhs.inner[k][j]; |
| 124 } | 126 }); |
| 125 } | 127 }); |
| 126 } | 128 }); |
| 127 tmp | 129 tmp |
| 128 } | 130 } |
| 129 } | 131 } |
| 130 | 132 |
| 131 /// Create an orthographic projection matrix. | 133 /// Create an orthographic projection matrix. |
