1use super::*;
5
6#[derive(Debug, Clone, Copy, PartialEq, Default)]
9pub struct Mat2 {
10 pub cx: Vec2,
11 pub cy: Vec2,
12}
13
14pub const MAT2_ZERO: Mat2 = Mat2 {
16 cx: Vec2 { x: 0.0, y: 0.0 },
17 cy: Vec2 { x: 0.0, y: 0.0 },
18};
19
20pub fn det(m: Matrix3) -> f32 {
22 dot(m.cx, cross(m.cy, m.cz))
23}
24
25pub fn mul_mv(m: Matrix3, a: Vec3) -> Vec3 {
27 Vec3 {
28 x: m.cx.x * a.x + m.cy.x * a.y + m.cz.x * a.z,
29 y: m.cx.y * a.x + m.cy.y * a.y + m.cz.y * a.z,
30 z: m.cx.z * a.x + m.cy.z * a.y + m.cz.z * a.z,
31 }
32}
33
34pub fn mul_mv_sym(m: Matrix3, a: Vec3) -> Vec3 {
41 let cxx = m.cx.x;
42 let cxy = m.cx.y;
43 let cxz = m.cx.z;
44 let cyy = m.cy.y;
45 let cyz = m.cy.z;
46 let czz = m.cz.z;
47 Vec3 {
48 x: cxx * a.x + (cxy * a.y + cxz * a.z),
49 y: cxy * a.x + (cyy * a.y + cyz * a.z),
50 z: cxz * a.x + (cyz * a.y + czz * a.z),
51 }
52}
53
54pub fn negate_mat3(a: Matrix3) -> Matrix3 {
56 Matrix3 {
57 cx: Vec3 {
58 x: -a.cx.x,
59 y: -a.cx.y,
60 z: -a.cx.z,
61 },
62 cy: Vec3 {
63 x: -a.cy.x,
64 y: -a.cy.y,
65 z: -a.cy.z,
66 },
67 cz: Vec3 {
68 x: -a.cz.x,
69 y: -a.cz.y,
70 z: -a.cz.z,
71 },
72 }
73}
74
75pub fn add_mm(a: Matrix3, b: Matrix3) -> Matrix3 {
78 Matrix3 {
79 cx: Vec3 {
80 x: a.cx.x + b.cx.x,
81 y: a.cx.y + b.cx.y,
82 z: a.cx.z + b.cx.z,
83 },
84 cy: Vec3 {
85 x: a.cy.x + b.cy.x,
86 y: a.cy.y + b.cy.y,
87 z: a.cy.z + b.cy.z,
88 },
89 cz: Vec3 {
90 x: a.cz.x + b.cz.x,
91 y: a.cz.y + b.cz.y,
92 z: a.cz.z + b.cz.z,
93 },
94 }
95}
96
97pub fn sub_mm(a: Matrix3, b: Matrix3) -> Matrix3 {
100 Matrix3 {
101 cx: Vec3 {
102 x: a.cx.x - b.cx.x,
103 y: a.cx.y - b.cx.y,
104 z: a.cx.z - b.cx.z,
105 },
106 cy: Vec3 {
107 x: a.cy.x - b.cy.x,
108 y: a.cy.y - b.cy.y,
109 z: a.cy.z - b.cy.z,
110 },
111 cz: Vec3 {
112 x: a.cz.x - b.cz.x,
113 y: a.cz.y - b.cz.y,
114 z: a.cz.z - b.cz.z,
115 },
116 }
117}
118
119pub fn mul_sm(s: f32, a: Matrix3) -> Matrix3 {
121 Matrix3 {
122 cx: Vec3 {
123 x: s * a.cx.x,
124 y: s * a.cx.y,
125 z: s * a.cx.z,
126 },
127 cy: Vec3 {
128 x: s * a.cy.x,
129 y: s * a.cy.y,
130 z: s * a.cy.z,
131 },
132 cz: Vec3 {
133 x: s * a.cz.x,
134 y: s * a.cz.y,
135 z: s * a.cz.z,
136 },
137 }
138}
139
140pub fn mul_mm(a: Matrix3, b: Matrix3) -> Matrix3 {
143 Matrix3 {
144 cx: mul_mv(a, b.cx),
145 cy: mul_mv(a, b.cy),
146 cz: mul_mv(a, b.cz),
147 }
148}
149
150pub fn transpose(m: Matrix3) -> Matrix3 {
152 Matrix3 {
153 cx: Vec3 {
154 x: m.cx.x,
155 y: m.cy.x,
156 z: m.cz.x,
157 },
158 cy: Vec3 {
159 x: m.cx.y,
160 y: m.cy.y,
161 z: m.cz.y,
162 },
163 cz: Vec3 {
164 x: m.cx.z,
165 y: m.cy.z,
166 z: m.cz.z,
167 },
168 }
169}
170
171pub fn invert_matrix(m: Matrix3) -> Matrix3 {
173 let det = det(m);
174 if abs_float(det) > 1000.0 * f32::MIN_POSITIVE {
175 let inv_det = 1.0 / det;
176 let out = Matrix3 {
177 cx: mul_sv(inv_det, cross(m.cy, m.cz)),
178 cy: mul_sv(inv_det, cross(m.cz, m.cx)),
179 cz: mul_sv(inv_det, cross(m.cx, m.cy)),
180 };
181
182 transpose(out)
183 } else {
184 MAT3_ZERO
185 }
186}
187
188pub fn solve3(m: Matrix3, a: Vec3) -> Vec3 {
191 let det = det(m);
192 if abs_float(det) > 1000.0 * f32::MIN_POSITIVE {
193 let inv_det = 1.0 / det;
194 let s = Matrix3 {
195 cx: cross(m.cy, m.cz),
196 cy: cross(m.cz, m.cx),
197 cz: cross(m.cx, m.cy),
198 };
199
200 Vec3 {
201 x: inv_det * dot(s.cx, a),
202 y: inv_det * dot(s.cy, a),
203 z: inv_det * dot(s.cz, a),
204 }
205 } else {
206 VEC3_ZERO
207 }
208}
209
210pub fn invert_t(m: Matrix3) -> Matrix3 {
213 let det = det(m);
214 if abs_float(det) > 1000.0 * f32::MIN_POSITIVE {
215 let inv_det = 1.0 / det;
216 Matrix3 {
217 cx: mul_sv(inv_det, cross(m.cy, m.cz)),
218 cy: mul_sv(inv_det, cross(m.cz, m.cx)),
219 cz: mul_sv(inv_det, cross(m.cx, m.cy)),
220 }
221 } else {
222 MAT3_ZERO
223 }
224}
225
226pub fn abs_matrix3(m: Matrix3) -> Matrix3 {
228 Matrix3 {
229 cx: abs(m.cx),
230 cy: abs(m.cy),
231 cz: abs(m.cz),
232 }
233}
234
235pub fn make_matrix_from_quat(q: Quat) -> Matrix3 {
238 let xx = q.v.x * q.v.x;
239 let yy = q.v.y * q.v.y;
240 let zz = q.v.z * q.v.z;
241 let xy = q.v.x * q.v.y;
242 let xz = q.v.x * q.v.z;
243 let xw = q.v.x * q.s;
244 let yz = q.v.y * q.v.z;
245 let yw = q.v.y * q.s;
246 let zw = q.v.z * q.s;
247
248 Matrix3 {
249 cx: Vec3 {
250 x: 1.0 - 2.0 * (yy + zz),
251 y: 2.0 * (xy + zw),
252 z: 2.0 * (xz - yw),
253 },
254 cy: Vec3 {
255 x: 2.0 * (xy - zw),
256 y: 1.0 - 2.0 * (xx + zz),
257 z: 2.0 * (yz + xw),
258 },
259 cz: Vec3 {
260 x: 2.0 * (xz + yw),
261 y: 2.0 * (yz - xw),
262 z: 1.0 - 2.0 * (xx + yy),
263 },
264 }
265}
266
267pub fn steiner(mass: f32, origin: Vec3) -> Matrix3 {
270 let ixx = mass * (origin.y * origin.y + origin.z * origin.z);
272 let iyy = mass * (origin.x * origin.x + origin.z * origin.z);
273 let izz = mass * (origin.x * origin.x + origin.y * origin.y);
274 let ixy = -mass * origin.x * origin.y;
275 let ixz = -mass * origin.x * origin.z;
276 let iyz = -mass * origin.y * origin.z;
277
278 let mut out = MAT3_ZERO;
280 out.cx.x = ixx;
281 out.cy.x = ixy;
282 out.cz.x = ixz;
283 out.cx.y = ixy;
284 out.cy.y = iyy;
285 out.cz.y = iyz;
286 out.cx.z = ixz;
287 out.cy.z = iyz;
288 out.cz.z = izz;
289
290 out
291}
292
293fn det2(m: Mat2) -> f32 {
294 m.cx.x * m.cy.y - m.cx.y * m.cy.x
295}
296
297pub fn mul_mv2(m: Mat2, a: Vec2) -> Vec2 {
299 Vec2 {
300 x: m.cx.x * a.x + m.cy.x * a.y,
301 y: m.cx.y * a.x + m.cy.y * a.y,
302 }
303}
304
305pub fn mul_mv2_sym(m: Mat2, a: Vec2) -> Vec2 {
307 let cxx = m.cx.x;
308 let cxy = m.cx.y;
309 let cyy = m.cy.y;
310 Vec2 {
311 x: cxx * a.x + cxy * a.y,
312 y: cxy * a.x + cyy * a.y,
313 }
314}
315
316pub fn mul_mm2(m1: Mat2, m2: Mat2) -> Mat2 {
318 Mat2 {
319 cx: mul_mv2(m1, m2.cx),
320 cy: mul_mv2(m1, m2.cy),
321 }
322}
323
324pub fn invert2(m: Mat2) -> Mat2 {
326 let det = det2(m);
327 if abs_float(det) > 1000.0 * f32::MIN_POSITIVE {
328 let inv_det = 1.0 / det;
329 Mat2 {
330 cx: Vec2 {
331 x: inv_det * m.cy.y,
332 y: -inv_det * m.cx.y,
333 },
334 cy: Vec2 {
335 x: -inv_det * m.cy.x,
336 y: inv_det * m.cx.x,
337 },
338 }
339 } else {
340 Mat2 {
341 cx: Vec2 { x: 0.0, y: 0.0 },
342 cy: Vec2 { x: 0.0, y: 0.0 },
343 }
344 }
345}
346
347pub fn solve2(m: Mat2, b: Vec2) -> Vec2 {
350 let det = det2(m);
351 if det > 1000.0 * f32::MIN_POSITIVE {
352 let inv_det = 1.0 / det;
353 Vec2 {
354 x: inv_det * m.cy.y * b.x - inv_det * m.cy.x * b.y,
355 y: -inv_det * m.cx.y * b.x + inv_det * m.cx.x * b.y,
356 }
357 } else {
358 Vec2 { x: 0.0, y: 0.0 }
359 }
360}
361
362pub fn skew(v: Vec3) -> Matrix3 {
364 Matrix3 {
365 cx: Vec3 {
366 x: 0.0,
367 y: v.z,
368 z: -v.y,
369 },
370 cy: Vec3 {
371 x: -v.z,
372 y: 0.0,
373 z: v.x,
374 },
375 cz: Vec3 {
376 x: v.y,
377 y: -v.x,
378 z: 0.0,
379 },
380 }
381}