1use glium::uniforms::AsUniformValue;
2use crate::{matrices::DMat4, quaternions::DQuat, vectors::{DVec3, DVec2}};
3
4use super::DMat2;
5
6#[derive(Clone, Copy, PartialEq, Debug)]
7pub struct DMat3 {
9 matrix: [[f64; 3]; 3]
10}
11impl DMat3 {
12 pub const IDENTITY: Self = DMat3::from_values(
13 1.0, 0.0, 0.0,
14 0.0, 1.0, 0.0,
15 0.0, 0.0, 1.0,
16 );
17 pub const fn from_column_major_array(array: [[f64; 3]; 3]) -> Self { Self { matrix: array } }
18 pub const fn into_column_major_array(self) -> [[f64; 3]; 3] { self.matrix }
19 pub const fn from_row_major_array(array: [[f64; 3]; 3]) -> Self { Self { matrix: array }.transpose() }
20 pub const fn into_row_major_array(self) -> [[f64; 3]; 3] { self.transpose().matrix }
21 pub const fn from_scale(scale: DVec3) -> Self {
22 let (x, y, z) = (scale.x, scale.y, scale.z);
23 DMat3::from_values(
24 x, 0.0, 0.0,
25 0.0, y, 0.0,
26 0.0, 0.0, z,
27 )
28 }
29 pub fn from_2d_transform(pos: DVec2, scale: DVec2, rot: f64) -> Self {
30 Self::from_values(
31 scale.x * rot.cos(), scale.y * -rot.sin(), pos.x,
32 scale.x * rot.sin(), scale.y * rot.cos(), pos.y,
33 0.0, 0.0, 1.0
34 )
35 }
36 pub fn from_transform(scale: DVec3, rot: DQuat) -> Self {
37 let (r, i, j, k) = (rot.r, rot.i, rot.j, rot.k);
38 let (sx, sy, sz) = (scale.x * 2.0, scale.y * 2.0, scale.z * 2.0);
39 DMat3::from_values(
40 sx*(0.5 - (j*j + k*k)), sy*(i*j - k*r), sz*(i*k + j*r),
41 sx*(i*j + k*r), sy*(0.5 - (i*i + k*k)), sz*(j*k - i*r),
42 sx*(i*k - j*r), sy*(j*k + i*r), sz*(0.5 - (i*i + j*j))
43 )
44 }
45 pub fn from_rot(rot: DQuat) -> Self {
46 rot.into()
47 }
48 #[allow(clippy::too_many_arguments)]
60 pub const fn from_values(
61 a: f64, b: f64, c: f64,
62 d: f64, e: f64, f: f64,
63 g: f64, h: f64, i: f64
64 ) -> Self {
65 Self{
66 matrix: [
68 [a, d, g],
69 [b, e, h],
70 [c, f, i],
71 ]
72 }
73 }
74 pub fn scale(&self, scalar: f64) -> DMat3 {
75 let DMat3 { matrix: [
76 [a, d, g],
77 [b, e, h],
78 [c, f, i],
79 ]} = self;
80 Self::from_values(
81 a * scalar, b * scalar, c * scalar,
82 d * scalar, e * scalar, f * scalar,
83 g * scalar, h * scalar, i * scalar
84 )
85 }
86 pub fn determinant(&self) -> f64{
87 let DMat3 { matrix: [
88 [a, d, g],
89 [b, e, h],
90 [c, f, i],
91 ]} = self;
92 a*(e*i - f*h) - b*(d*i - f*g) + c*(d*h - e*g)
93 }
94 #[allow(non_snake_case)]
95 pub fn inverse(&self) -> DMat3{
96 let DMat3 { matrix: [
97 [a, d, g],
98 [b, e, h],
99 [c, f, i],
100 ]} = self;
101 let A = e*i - f*h;
102 let B = -(d*i - f*g);
103 let C = d*h - e*g;
104
105 let determinet = a*A + b*B + c*C;
106 let scalar = 1.0/determinet;
107 Self::from_values(
108 A, -(b*i - c*h), b*f - c*e,
109 B, a*i - c*g, -(a*f - c*d),
110 C, -(a*h - b*g), a*e - b*d
111 ).scale(scalar)
112 }
113 pub const fn transpose(self) -> Self {
114 let DMat3 { matrix: [
115 [a, d, g],
116 [b, e, h],
117 [c, f, i],
118 ]} = self;
119 DMat3::from_values(
120 a, d, g,
121 b, e, h,
122 c, f, i
123 )
124 }
125 pub const fn column(&self, pos: usize) -> [f64; 3] {
126 self.matrix[pos]
127 }
128 pub const fn row(&self, pos: usize) -> [f64; 3] {
129 let matrix = self.matrix;
130 [matrix[0][pos], matrix[1][pos], matrix[2][pos]]
131 }
132}
133
134impl Default for DMat3 {
135 fn default() -> Self {
136 Self { matrix: [
137 [1.0, 0.0, 0.0,],
138 [0.0, 1.0, 0.0,],
139 [0.0, 0.0, 1.0,],
140 ] }
141 }
142}
143impl std::ops::Mul<DVec3> for DMat3 {
144 fn mul(self, rhs: DVec3) -> Self::Output { rhs.transform(self) }
145 type Output = DVec3;
146}
147impl std::ops::Mul<DMat3> for f64 {
148 fn mul(self, rhs: DMat3) -> Self::Output { rhs * self }
149 type Output = DMat3;
150}
151impl std::ops::Mul<f64> for DMat3 {
152 fn mul(self, rhs: f64) -> Self::Output { self.scale(rhs) }
153 type Output = Self;
154}
155impl std::ops::MulAssign<f64> for DMat3 {
156 fn mul_assign(&mut self, rhs: f64) { *self = *self * rhs }
157}
158impl std::ops::Div<DMat3> for f64 {
159 fn div(self, rhs: DMat3) -> Self::Output {
160 let DMat3 { matrix: [
161 [a, d, g],
162 [b, e, h],
163 [c, f, i],
164 ]} = rhs;
165 DMat3::from_values(
166 self/a, self/b, self/c,
167 self/d, self/e, self/f,
168 self/g, self/h, self/i
169 )
170 }
171 type Output = DMat3;
172}
173impl std::ops::Div<f64> for DMat3 {
174 fn div(self, rhs: f64) -> Self::Output { self.scale(1.0/rhs) }
175 type Output = Self;
176}
177impl std::ops::RemAssign<f64> for DMat3 {
178 fn rem_assign(&mut self, rhs: f64) { *self = *self % rhs }
179}
180impl std::ops::Rem<DMat3> for f64 {
181 fn rem(self, rhs: DMat3) -> Self::Output {
182 let DMat3 { matrix: [
183 [a, d, g],
184 [b, e, h],
185 [c, f, i],
186 ]} = rhs;
187 DMat3::from_values(
188 self%a, self%b, self%c,
189 self%d, self%e, self%f,
190 self%g, self%h, self%i
191 )
192 }
193 type Output = DMat3;
194}
195impl std::ops::Rem<f64> for DMat3 {
196 fn rem(self, rhs: f64) -> Self::Output {
197 let DMat3 { matrix: [
198 [a, d, g],
199 [b, e, h],
200 [c, f, i],
201 ]} = self;
202 DMat3::from_values(
203 a%rhs, b%rhs, c%rhs,
204 d%rhs, e%rhs, f%rhs,
205 g%rhs, h%rhs, i%rhs
206 )
207 }
208 type Output = Self;
209}
210impl std::ops::DivAssign<f64> for DMat3 {
211 fn div_assign(&mut self, rhs: f64) { *self = *self / rhs }
212}
213#[allow(clippy::needless_range_loop)]
214impl std::ops::Mul for DMat3{
215 fn mul(self, rhs: Self) -> Self::Output {
216 let mut matrix = [[0.0; 3]; 3];
217 for x in 0..3 {
218 for y in 0..3 {
219 matrix[x][y] = DVec3::dot(self.row(y).into(), rhs.column(x).into());
220 }
221 }
222 Self {
223 matrix
224 }
225 }
226 type Output = Self;
227}
228impl std::ops::MulAssign for DMat3 {
229 fn mul_assign(&mut self, rhs: Self) { *self = *self * rhs }
230}
231#[allow(clippy::suspicious_arithmetic_impl)]
232impl std::ops::Div for DMat3 {
233 fn div(self, rhs: Self) -> Self::Output { self * rhs.inverse() }
234 type Output = Self;
235}
236impl std::ops::DivAssign for DMat3 {
237 fn div_assign(&mut self, rhs: Self) { *self = *self / rhs }
238}
239impl AsUniformValue for DMat3 {
240 fn as_uniform_value(&self) -> glium::uniforms::UniformValue<'_> {
241 glium::uniforms::UniformValue::DoubleMat3(self.matrix)
242 }
243}
244impl std::ops::Add for DMat3 {
245 fn add(self, rhs: Self) -> Self::Output {
246 let a = self.matrix;
247 let b = rhs.matrix;
248 Self{
249 matrix:[
250 [a[0][0] + b[0][0], a[0][1] + b[0][1], a[0][2] + b[0][2]],
251 [a[1][0] + b[1][0], a[1][1] + b[1][1], a[1][2] + b[1][2]],
252 [a[2][0] + b[2][0], a[2][1] + b[2][1], a[2][2] + b[2][2]],
253 ]
254 }
255 }
256 type Output = Self;
257}
258impl std::ops::AddAssign for DMat3 {
259 fn add_assign(&mut self, rhs: Self) {
260 let a = self.matrix;
261 let b = rhs.matrix;
262 *self = Self{
263 matrix:[
264 [a[0][0] + b[0][0], a[0][1] + b[0][1], a[0][2] + b[0][2]],
265 [a[1][0] + b[1][0], a[1][1] + b[1][1], a[1][2] + b[1][2]],
266 [a[2][0] + b[2][0], a[2][1] + b[2][1], a[2][2] + b[2][2]],
267 ]
268 };
269 }
270}
271impl std::ops::Sub for DMat3 {
272 fn sub(self, rhs: Self) -> Self::Output {
273 let a = self.matrix;
274 let b = rhs.matrix;
275 Self { matrix:[
276 [a[0][0] - b[0][0], a[0][1] - b[0][1], a[0][2] - b[0][2]],
277 [a[1][0] - b[1][0], a[1][1] - b[1][1], a[1][2] - b[1][2]],
278 [a[2][0] - b[2][0], a[2][1] - b[2][1], a[2][2] - b[2][2]],
279 ] }
280 }
281 type Output = Self;
282}
283impl std::ops::SubAssign for DMat3 {
284 fn sub_assign(&mut self, rhs: Self) {
285 let a = self.matrix;
286 let b = rhs.matrix;
287 *self = Self { matrix:[
288 [a[0][0] - b[0][0], a[0][1] - b[0][1], a[0][2] - b[0][2]],
289 [a[1][0] - b[1][0], a[1][1] - b[1][1], a[1][2] - b[1][2]],
290 [a[2][0] - b[2][0], a[2][1] - b[2][1], a[2][2] - b[2][2]],
291 ] };
292 }
293}
294impl From<DMat4> for DMat3 {
295 fn from(value: DMat4) -> Self {
296 Self::from_values(
297 value[0][0], value[0][1], value[0][2],
298 value[1][0], value[1][1], value[1][2],
299 value[2][0], value[2][1], value[2][2]
300 )
301 }
302}
303impl From<DMat2> for DMat3 {
304 fn from(value: DMat2) -> Self {
305 Self::from_values(
306 value[0][0], value[0][1], 0.0,
307 value[1][0], value[1][1], 0.0,
308 0.0, 0.0, 1.0
309 )
310 }
311}
312impl From<DQuat> for DMat3 {
313 fn from(value: DQuat) -> DMat3 {
314 let DQuat { r, i, j, k } = value;
315 DMat3::from_values(
316 1.0 - 2.0*(j*j + k*k), 2.0*(i*j - k*r), 2.0*(i*k + j*r),
317 2.0*(i*j + k*r), 1.0 - 2.0*(i*i + k*k), 2.0*(j*k - i*r),
318 2.0*(i*k - j*r), 2.0*(j*k + i*r), 1.0 - 2.0*(i*i + j*j)
319 )
320 }
321}
322impl std::ops::Index<usize> for DMat3 {
323 fn index(&self, index: usize) -> &Self::Output {
324 &self.matrix[index]
325 }
326 type Output = [f64; 3];
327}
328impl std::ops::IndexMut<usize> for DMat3 {
329 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
330 &mut self.matrix[index]
331 }
332}