1 | use std::{ |
2 | f32, |
3 | ops::{Add, AddAssign, Div, DivAssign, Index, Mul, MulAssign, Neg, Sub, SubAssign}, |
4 | slice, |
5 | }; |
6 | |
7 | use skia_bindings::{self as sb, SkM44, SkV2, SkV3, SkV4}; |
8 | |
9 | use crate::{prelude::*, private::is_finite, scalar, Matrix, Rect}; |
10 | |
11 | #[repr (C)] |
12 | #[derive (Copy, Clone, PartialEq, Default, Debug)] |
13 | pub struct V2 { |
14 | pub x: f32, |
15 | pub y: f32, |
16 | } |
17 | |
18 | native_transmutable!(SkV2, V2, v2_layout); |
19 | |
20 | impl V2 { |
21 | pub const fn new(x: f32, y: f32) -> Self { |
22 | Self { x, y } |
23 | } |
24 | |
25 | pub fn dot(self, b: Self) -> scalar { |
26 | self.x * b.x + self.y * b.y |
27 | } |
28 | |
29 | pub fn cross(self, b: Self) -> scalar { |
30 | self.x * b.y - self.y * b.x |
31 | } |
32 | |
33 | #[must_use ] |
34 | pub fn normalize(self) -> Self { |
35 | self * (1.0 / self.length()) |
36 | } |
37 | |
38 | pub fn length_squared(self) -> scalar { |
39 | Self::dot(self, self) |
40 | } |
41 | |
42 | pub fn length(self) -> scalar { |
43 | self.length_squared().sqrt() |
44 | } |
45 | |
46 | const COMPONENTS: usize = 2; |
47 | |
48 | pub fn as_array(&self) -> &[f32; Self::COMPONENTS] { |
49 | unsafe { slice::from_raw_parts(&self.x, Self::COMPONENTS) } |
50 | .try_into() |
51 | .unwrap() |
52 | } |
53 | |
54 | pub fn as_mut_array(&mut self) -> &mut [f32; Self::COMPONENTS] { |
55 | unsafe { slice::from_raw_parts_mut(&mut self.x, Self::COMPONENTS) } |
56 | .try_into() |
57 | .unwrap() |
58 | } |
59 | } |
60 | |
61 | impl Neg for V2 { |
62 | type Output = Self; |
63 | |
64 | fn neg(self) -> Self::Output { |
65 | Self::new(-self.x, -self.y) |
66 | } |
67 | } |
68 | |
69 | impl Add for V2 { |
70 | type Output = Self; |
71 | |
72 | fn add(self, v: Self) -> Self::Output { |
73 | Self::new(self.x + v.x, self.y + v.y) |
74 | } |
75 | } |
76 | |
77 | impl Sub for V2 { |
78 | type Output = Self; |
79 | |
80 | fn sub(self, v: Self) -> Self::Output { |
81 | Self::new(self.x - v.x, self.y - v.y) |
82 | } |
83 | } |
84 | |
85 | impl Mul for V2 { |
86 | type Output = Self; |
87 | |
88 | fn mul(self, v: Self) -> Self::Output { |
89 | Self::new(self.x * v.x, self.y * v.y) |
90 | } |
91 | } |
92 | |
93 | impl Mul<scalar> for V2 { |
94 | type Output = Self; |
95 | |
96 | fn mul(self, s: scalar) -> Self::Output { |
97 | Self::new(self.x * s, self.y * s) |
98 | } |
99 | } |
100 | |
101 | impl Mul<V2> for scalar { |
102 | type Output = V2; |
103 | |
104 | fn mul(self, v: V2) -> Self::Output { |
105 | V2::new(x:v.x * self, y:v.y * self) |
106 | } |
107 | } |
108 | |
109 | impl Div<V2> for scalar { |
110 | type Output = V2; |
111 | |
112 | fn div(self, v: V2) -> Self::Output { |
113 | V2::new(self / v.x, self / v.y) |
114 | } |
115 | } |
116 | |
117 | impl Div<scalar> for V2 { |
118 | type Output = V2; |
119 | fn div(self, s: scalar) -> Self::Output { |
120 | V2::new(self.x / s, self.y / s) |
121 | } |
122 | } |
123 | |
124 | impl AddAssign for V2 { |
125 | fn add_assign(&mut self, v: Self) { |
126 | *self = *self + v |
127 | } |
128 | } |
129 | |
130 | impl SubAssign for V2 { |
131 | fn sub_assign(&mut self, v: Self) { |
132 | *self = *self - v |
133 | } |
134 | } |
135 | |
136 | impl MulAssign for V2 { |
137 | fn mul_assign(&mut self, v: Self) { |
138 | *self = *self * v |
139 | } |
140 | } |
141 | |
142 | impl MulAssign<scalar> for V2 { |
143 | fn mul_assign(&mut self, s: scalar) { |
144 | *self = *self * s |
145 | } |
146 | } |
147 | |
148 | impl DivAssign<scalar> for V2 { |
149 | fn div_assign(&mut self, s: scalar) { |
150 | *self = *self / s |
151 | } |
152 | } |
153 | |
154 | #[repr (C)] |
155 | #[derive (Copy, Clone, PartialEq, Default, Debug)] |
156 | pub struct V3 { |
157 | pub x: f32, |
158 | pub y: f32, |
159 | pub z: f32, |
160 | } |
161 | |
162 | native_transmutable!(SkV3, V3, v3_layout); |
163 | |
164 | impl V3 { |
165 | pub const fn new(x: f32, y: f32, z: f32) -> Self { |
166 | Self { x, y, z } |
167 | } |
168 | |
169 | pub fn dot(&self, b: &Self) -> scalar { |
170 | self.x * b.x + self.y * b.y + self.z * b.z |
171 | } |
172 | |
173 | #[must_use ] |
174 | pub fn cross(&self, b: &Self) -> Self { |
175 | Self::new( |
176 | self.y * b.z - self.z * b.y, |
177 | self.z * b.x - self.x * b.z, |
178 | self.x * b.y - self.y * b.x, |
179 | ) |
180 | } |
181 | |
182 | #[must_use ] |
183 | pub fn normalize(&self) -> Self { |
184 | *self * (1.0 / self.length()) |
185 | } |
186 | |
187 | pub fn length_squared(&self) -> scalar { |
188 | Self::dot(self, self) |
189 | } |
190 | |
191 | pub fn length(&self) -> scalar { |
192 | Self::dot(self, self).sqrt() |
193 | } |
194 | |
195 | const COMPONENTS: usize = 3; |
196 | |
197 | pub fn as_array(&self) -> &[f32; Self::COMPONENTS] { |
198 | unsafe { slice::from_raw_parts(&self.x, Self::COMPONENTS) } |
199 | .try_into() |
200 | .unwrap() |
201 | } |
202 | |
203 | pub fn as_mut_array(&mut self) -> &mut [f32; Self::COMPONENTS] { |
204 | unsafe { slice::from_raw_parts_mut(&mut self.x, Self::COMPONENTS) } |
205 | .try_into() |
206 | .unwrap() |
207 | } |
208 | } |
209 | |
210 | impl Neg for V3 { |
211 | type Output = Self; |
212 | |
213 | fn neg(self) -> Self::Output { |
214 | Self::new(-self.x, -self.y, -self.z) |
215 | } |
216 | } |
217 | |
218 | impl Add for V3 { |
219 | type Output = Self; |
220 | |
221 | fn add(self, v: Self) -> Self::Output { |
222 | Self::new(self.x + v.x, self.y + v.y, self.z + v.z) |
223 | } |
224 | } |
225 | |
226 | impl Sub for V3 { |
227 | type Output = Self; |
228 | |
229 | fn sub(self, v: Self) -> Self::Output { |
230 | Self::new(self.x - v.x, self.y - v.y, self.z - v.z) |
231 | } |
232 | } |
233 | |
234 | impl Mul for V3 { |
235 | type Output = Self; |
236 | |
237 | fn mul(self, v: Self) -> Self::Output { |
238 | Self::new(self.x * v.x, self.y * v.y, self.z * v.z) |
239 | } |
240 | } |
241 | |
242 | impl Mul<scalar> for V3 { |
243 | type Output = Self; |
244 | |
245 | fn mul(self, s: scalar) -> Self::Output { |
246 | Self::new(self.x * s, self.y * s, self.z * s) |
247 | } |
248 | } |
249 | |
250 | impl Mul<V3> for scalar { |
251 | type Output = V3; |
252 | |
253 | fn mul(self, v: V3) -> Self::Output { |
254 | V3::new(x:v.x * self, y:v.y * self, z:v.z * self) |
255 | } |
256 | } |
257 | |
258 | impl AddAssign for V3 { |
259 | fn add_assign(&mut self, v: Self) { |
260 | *self = *self + v |
261 | } |
262 | } |
263 | |
264 | impl SubAssign for V3 { |
265 | fn sub_assign(&mut self, v: Self) { |
266 | *self = *self - v |
267 | } |
268 | } |
269 | |
270 | impl MulAssign for V3 { |
271 | fn mul_assign(&mut self, v: Self) { |
272 | *self = *self * v |
273 | } |
274 | } |
275 | |
276 | impl MulAssign<scalar> for V3 { |
277 | fn mul_assign(&mut self, s: scalar) { |
278 | *self = *self * s |
279 | } |
280 | } |
281 | |
282 | #[repr (C)] |
283 | #[derive (Copy, Clone, PartialEq, Default, Debug)] |
284 | pub struct V4 { |
285 | pub x: f32, |
286 | pub y: f32, |
287 | pub z: f32, |
288 | pub w: f32, |
289 | } |
290 | |
291 | native_transmutable!(SkV4, V4, v4_layout); |
292 | |
293 | impl V4 { |
294 | pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self { |
295 | Self { x, y, z, w } |
296 | } |
297 | |
298 | pub fn length_squared(&self) -> scalar { |
299 | Self::dot(self, self) |
300 | } |
301 | |
302 | pub fn length(&self) -> scalar { |
303 | scalar::sqrt(Self::dot(self, self)) |
304 | } |
305 | |
306 | pub fn dot(&self, b: &Self) -> scalar { |
307 | self.x * b.x + self.y * b.y + self.z * b.z + self.w * b.w |
308 | } |
309 | |
310 | pub fn normalize(&self) -> Self { |
311 | (*self) * (1.0 / self.length()) |
312 | } |
313 | |
314 | const COMPONENTS: usize = 4; |
315 | |
316 | pub fn as_array(&self) -> &[f32; Self::COMPONENTS] { |
317 | unsafe { slice::from_raw_parts(&self.x, Self::COMPONENTS) } |
318 | .try_into() |
319 | .unwrap() |
320 | } |
321 | |
322 | pub fn as_mut_array(&mut self) -> &mut [f32; Self::COMPONENTS] { |
323 | unsafe { slice::from_raw_parts_mut(&mut self.x, Self::COMPONENTS) } |
324 | .try_into() |
325 | .unwrap() |
326 | } |
327 | } |
328 | |
329 | impl Neg for V4 { |
330 | type Output = Self; |
331 | |
332 | fn neg(self) -> Self::Output { |
333 | Self::new(-self.x, -self.y, -self.z, -self.w) |
334 | } |
335 | } |
336 | |
337 | impl Add for V4 { |
338 | type Output = Self; |
339 | |
340 | fn add(self, v: Self) -> Self::Output { |
341 | Self::new(self.x + v.x, self.y + v.y, self.z + v.z, self.w + v.w) |
342 | } |
343 | } |
344 | |
345 | impl Sub for V4 { |
346 | type Output = Self; |
347 | |
348 | fn sub(self, v: Self) -> Self::Output { |
349 | Self::new(self.x - v.x, self.y - v.y, self.z - v.z, self.w - v.w) |
350 | } |
351 | } |
352 | |
353 | impl Mul for V4 { |
354 | type Output = Self; |
355 | |
356 | fn mul(self, v: Self) -> Self::Output { |
357 | Self::new(self.x * v.x, self.y * v.y, self.z * v.z, self.w * v.w) |
358 | } |
359 | } |
360 | |
361 | impl Mul<scalar> for V4 { |
362 | type Output = Self; |
363 | |
364 | fn mul(self, s: scalar) -> Self::Output { |
365 | Self::new(self.x * s, self.y * s, self.z * s, self.w * s) |
366 | } |
367 | } |
368 | |
369 | impl Mul<V4> for scalar { |
370 | type Output = V4; |
371 | |
372 | fn mul(self, v: V4) -> Self::Output { |
373 | V4::new(x:v.x * self, y:v.y * self, z:v.z * self, w:v.w * self) |
374 | } |
375 | } |
376 | |
377 | impl AddAssign for V4 { |
378 | fn add_assign(&mut self, v: Self) { |
379 | *self = *self + v |
380 | } |
381 | } |
382 | |
383 | impl SubAssign for V4 { |
384 | fn sub_assign(&mut self, v: Self) { |
385 | *self = *self - v |
386 | } |
387 | } |
388 | |
389 | impl MulAssign for V4 { |
390 | fn mul_assign(&mut self, v: Self) { |
391 | *self = *self * v |
392 | } |
393 | } |
394 | |
395 | impl MulAssign<scalar> for V4 { |
396 | fn mul_assign(&mut self, s: scalar) { |
397 | *self = *self * s |
398 | } |
399 | } |
400 | |
401 | impl Index<usize> for V4 { |
402 | type Output = f32; |
403 | |
404 | fn index(&self, index: usize) -> &Self::Output { |
405 | &self.as_array()[index] |
406 | } |
407 | } |
408 | |
409 | #[repr (C)] |
410 | #[derive (Clone, Debug)] |
411 | pub struct M44 { |
412 | mat: [f32; Self::COMPONENTS], |
413 | } |
414 | |
415 | native_transmutable!(SkM44, M44, m44_layout); |
416 | |
417 | impl Default for M44 { |
418 | fn default() -> Self { |
419 | Self::new_identity() |
420 | } |
421 | } |
422 | |
423 | impl PartialEq for M44 { |
424 | fn eq(&self, other: &Self) -> bool { |
425 | unsafe { sb::C_SkM44_equals(self.native(), other.native()) } |
426 | } |
427 | } |
428 | |
429 | impl M44 { |
430 | const COMPONENTS: usize = 16; |
431 | |
432 | pub const fn new_identity() -> Self { |
433 | Self { |
434 | mat: [ |
435 | 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, |
436 | ], |
437 | } |
438 | } |
439 | |
440 | pub fn concat(a: &Self, b: &Self) -> Self { |
441 | let mut m = Self::default(); |
442 | m.set_concat(a, b); |
443 | m |
444 | } |
445 | |
446 | pub const fn nan() -> Self { |
447 | Self { |
448 | mat: [f32::NAN; Self::COMPONENTS], |
449 | } |
450 | } |
451 | |
452 | #[allow (clippy::too_many_arguments)] |
453 | pub const fn new( |
454 | m0: scalar, |
455 | m4: scalar, |
456 | m8: scalar, |
457 | m12: scalar, |
458 | m1: scalar, |
459 | m5: scalar, |
460 | m9: scalar, |
461 | m13: scalar, |
462 | m2: scalar, |
463 | m6: scalar, |
464 | m10: scalar, |
465 | m14: scalar, |
466 | m3: scalar, |
467 | m7: scalar, |
468 | m11: scalar, |
469 | m15: scalar, |
470 | ) -> Self { |
471 | Self { |
472 | mat: [ |
473 | m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, |
474 | ], |
475 | } |
476 | } |
477 | |
478 | pub fn rows(r0: &V4, r1: &V4, r2: &V4, r3: &V4) -> Self { |
479 | let mut m = Self::default(); |
480 | m.set_row(0, r0); |
481 | m.set_row(1, r1); |
482 | m.set_row(2, r2); |
483 | m.set_row(3, r3); |
484 | m |
485 | } |
486 | |
487 | pub fn cols(c0: &V4, c1: &V4, c2: &V4, c3: &V4) -> Self { |
488 | let mut m = Self::default(); |
489 | m.set_col(0, c0); |
490 | m.set_col(1, c1); |
491 | m.set_col(2, c2); |
492 | m.set_col(3, c3); |
493 | m |
494 | } |
495 | |
496 | pub fn row_major(r: &[scalar; Self::COMPONENTS]) -> Self { |
497 | Self::new( |
498 | r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], |
499 | r[14], r[15], |
500 | ) |
501 | } |
502 | |
503 | pub fn col_major(c: &[scalar; Self::COMPONENTS]) -> Self { |
504 | Self::new( |
505 | c[0], c[4], c[8], c[12], c[1], c[5], c[9], c[13], c[2], c[6], c[10], c[14], c[3], c[7], |
506 | c[11], c[15], |
507 | ) |
508 | } |
509 | |
510 | pub fn translate(x: scalar, y: scalar, z: scalar) -> Self { |
511 | Self::new( |
512 | 1.0, 0.0, 0.0, x, 0.0, 1.0, 0.0, y, 0.0, 0.0, 1.0, z, 0.0, 0.0, 0.0, 1.0, |
513 | ) |
514 | } |
515 | |
516 | pub fn scale(x: scalar, y: scalar, z: scalar) -> Self { |
517 | Self::new( |
518 | x, 0.0, 0.0, 0.0, 0.0, y, 0.0, 0.0, 0.0, 0.0, z, 0.0, 0.0, 0.0, 0.0, 1.0, |
519 | ) |
520 | } |
521 | |
522 | pub fn rotate(axis: V3, radians: scalar) -> Self { |
523 | let mut m = Self::default(); |
524 | m.set_rotate(axis, radians); |
525 | m |
526 | } |
527 | |
528 | pub fn rect_to_rect(src: impl AsRef<Rect>, dst: impl AsRef<Rect>) -> Self { |
529 | let (src, dst) = (src.as_ref(), dst.as_ref()); |
530 | Self::construct(|m| unsafe { sb::C_SkM44_RectToRect(src.native(), dst.native(), m) }) |
531 | } |
532 | |
533 | pub fn look_at(eye: &V3, center: &V3, up: &V3) -> Self { |
534 | Self::construct(|m| unsafe { |
535 | sb::C_SkM44_LookAt(eye.native(), center.native(), up.native(), m) |
536 | }) |
537 | } |
538 | |
539 | pub fn perspective(near: f32, far: f32, angle: f32) -> Self { |
540 | Self::construct(|m| unsafe { sb::C_SkM44_Perspective(near, far, angle, m) }) |
541 | } |
542 | |
543 | pub fn get_col_major(&self, v: &mut [scalar; Self::COMPONENTS]) { |
544 | v.copy_from_slice(&self.mat) |
545 | } |
546 | |
547 | pub fn get_row_major(&self, v: &mut [scalar; Self::COMPONENTS]) { |
548 | unsafe { self.native().getRowMajor(v.as_mut_ptr()) } |
549 | } |
550 | |
551 | #[deprecated (since = "0.30.0" , note = "use M44::col_major() instead" )] |
552 | pub fn set_col_major(&mut self, v: &[scalar; Self::COMPONENTS]) -> &mut Self { |
553 | *self = Self::col_major(v); |
554 | self |
555 | } |
556 | |
557 | #[deprecated (since = "0.30.0" , note = "use M44::row_major() instead" )] |
558 | pub fn set_row_major(&mut self, v: &[scalar; Self::COMPONENTS]) -> &mut Self { |
559 | *self = Self::row_major(v); |
560 | self |
561 | } |
562 | |
563 | #[allow (clippy::too_many_arguments)] |
564 | #[deprecated (since = "0.30.0" , note = "use Self::new() instead" )] |
565 | pub fn set_44( |
566 | &mut self, |
567 | m0: scalar, |
568 | m1: scalar, |
569 | m2: scalar, |
570 | m3: scalar, |
571 | m4: scalar, |
572 | m5: scalar, |
573 | m6: scalar, |
574 | m7: scalar, |
575 | m8: scalar, |
576 | m9: scalar, |
577 | m10: scalar, |
578 | m11: scalar, |
579 | m12: scalar, |
580 | m13: scalar, |
581 | m14: scalar, |
582 | m15: scalar, |
583 | ) -> &mut Self { |
584 | *self = Self::new( |
585 | m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, |
586 | ); |
587 | self |
588 | } |
589 | |
590 | pub fn rc(&self, r: usize, c: usize) -> scalar { |
591 | assert!(r <= 3); |
592 | assert!(c <= 3); |
593 | self.mat[c * 4 + r] |
594 | } |
595 | |
596 | pub fn set_rc(&mut self, r: usize, c: usize, value: scalar) { |
597 | assert!(r <= 3); |
598 | assert!(c <= 3); |
599 | self.mat[c * 4 + r] = value; |
600 | } |
601 | |
602 | pub fn row(&self, i: usize) -> V4 { |
603 | assert!(i <= 3); |
604 | V4::new( |
605 | self.mat[i], |
606 | self.mat[i + 4], |
607 | self.mat[i + 8], |
608 | self.mat[i + 12], |
609 | ) |
610 | } |
611 | |
612 | pub fn col(&self, i: usize) -> V4 { |
613 | assert!(i <= 3); |
614 | V4::new( |
615 | self.mat[i * 4], |
616 | self.mat[i * 4 + 1], |
617 | self.mat[i * 4 + 2], |
618 | self.mat[i * 4 + 3], |
619 | ) |
620 | } |
621 | |
622 | pub fn set_row(&mut self, i: usize, v: &V4) { |
623 | assert!(i <= 3); |
624 | self.mat[i] = v.x; |
625 | self.mat[i + 4] = v.y; |
626 | self.mat[i + 8] = v.z; |
627 | self.mat[i + 12] = v.w; |
628 | } |
629 | |
630 | pub fn set_col(&mut self, i: usize, v: &V4) { |
631 | assert!(i <= 3); |
632 | self.mat[(i * 4)..(i * 4 + V4::COMPONENTS)].copy_from_slice(v.as_array()); |
633 | } |
634 | |
635 | pub fn set_identity(&mut self) -> &mut Self { |
636 | *self = Self { |
637 | mat: [ |
638 | 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, |
639 | ], |
640 | }; |
641 | self |
642 | } |
643 | |
644 | pub fn set_translate(&mut self, x: scalar, y: scalar, z: scalar) -> &mut Self { |
645 | *self = Self { |
646 | mat: [ |
647 | 1.0, 0.0, 0.0, x, 0.0, 1.0, 0.0, y, 0.0, 0.0, 1.0, z, 0.0, 0.0, 0.0, 1.0, |
648 | ], |
649 | }; |
650 | self |
651 | } |
652 | |
653 | pub fn set_scale(&mut self, x: scalar, y: scalar, z: scalar) -> &mut Self { |
654 | *self = Self { |
655 | mat: [ |
656 | x, 0.0, 0.0, 0.0, 0.0, y, 0.0, 0.0, 0.0, 0.0, z, 0.0, 0.0, 0.0, 0.0, 1.0, |
657 | ], |
658 | }; |
659 | self |
660 | } |
661 | |
662 | pub fn set_rotate_unit_sin_cos( |
663 | &mut self, |
664 | axis: V3, |
665 | sin_angle: scalar, |
666 | cos_angle: scalar, |
667 | ) -> &mut Self { |
668 | unsafe { |
669 | self.native_mut() |
670 | .setRotateUnitSinCos(axis.into_native(), sin_angle, cos_angle) |
671 | }; |
672 | self |
673 | } |
674 | |
675 | pub fn set_rotate_unit(&mut self, axis: V3, radians: scalar) -> &mut Self { |
676 | self.set_rotate_unit_sin_cos(axis, radians.sin(), radians.cos()) |
677 | } |
678 | |
679 | pub fn set_rotate(&mut self, axis: V3, radians: scalar) -> &mut Self { |
680 | unsafe { self.native_mut().setRotate(axis.into_native(), radians) }; |
681 | self |
682 | } |
683 | |
684 | #[deprecated (since = "0.30.0" , note = "use M44::col_major() and M44::set_concat()" )] |
685 | pub fn set_concat_16(&mut self, a: &M44, col_major: &[scalar; Self::COMPONENTS]) -> &mut Self { |
686 | self.set_concat(a, &Self::col_major(col_major)) |
687 | } |
688 | |
689 | pub fn set_concat(&mut self, a: &M44, b: &M44) -> &mut Self { |
690 | unsafe { |
691 | self.native_mut().setConcat(a.native(), b.native()); |
692 | } |
693 | self |
694 | } |
695 | |
696 | #[deprecated (since = "0.30.0" , note = "use M44::col_major() and M44::pre_concat()" )] |
697 | #[allow (deprecated)] |
698 | pub fn pre_concat_16(&mut self, col_major: &[scalar; Self::COMPONENTS]) -> &mut Self { |
699 | self.set_concat_16(&self.clone(), col_major) |
700 | } |
701 | |
702 | pub fn pre_concat(&mut self, m: &M44) -> &mut Self { |
703 | unsafe { |
704 | let self_ptr = self.native() as *const _; |
705 | self.native_mut().setConcat(self_ptr, m.native()); |
706 | } |
707 | self |
708 | } |
709 | |
710 | pub fn post_concat(&mut self, m: &M44) -> &mut Self { |
711 | unsafe { |
712 | let self_ptr = self.native() as *const _; |
713 | self.native_mut().setConcat(m.native(), self_ptr); |
714 | } |
715 | self |
716 | } |
717 | |
718 | pub fn normalize_perspective(&mut self) { |
719 | unsafe { self.native_mut().normalizePerspective() } |
720 | } |
721 | |
722 | pub fn is_finite(&self) -> bool { |
723 | is_finite(&self.mat) |
724 | } |
725 | |
726 | #[must_use ] |
727 | pub fn invert(&self) -> Option<M44> { |
728 | let mut m = Self::default(); |
729 | unsafe { self.native().invert(m.native_mut()) }.if_true_some(m) |
730 | } |
731 | |
732 | #[must_use ] |
733 | pub fn transpose(&self) -> Self { |
734 | Self::construct(|m| unsafe { sb::C_SkM44_transpose(self.native(), m) }) |
735 | } |
736 | |
737 | pub fn dump(&self) { |
738 | unsafe { self.native().dump() } |
739 | } |
740 | |
741 | pub fn map(&self, x: f32, y: f32, z: f32, w: f32) -> V4 { |
742 | V4::from_native_c(unsafe { sb::C_SkM44_map(self.native(), x, y, z, w) }) |
743 | } |
744 | |
745 | pub fn to_m33(&self) -> Matrix { |
746 | let m = &self.mat; |
747 | Matrix::new_all(m[0], m[4], m[12], m[1], m[5], m[13], m[3], m[7], m[15]) |
748 | } |
749 | |
750 | pub fn pre_translate( |
751 | &mut self, |
752 | x: scalar, |
753 | y: scalar, |
754 | z: impl Into<Option<scalar>>, |
755 | ) -> &mut Self { |
756 | unsafe { |
757 | self.native_mut() |
758 | .preTranslate(x, y, z.into().unwrap_or(0.0)) |
759 | }; |
760 | self |
761 | } |
762 | |
763 | pub fn post_translate( |
764 | &mut self, |
765 | x: scalar, |
766 | y: scalar, |
767 | z: impl Into<Option<scalar>>, |
768 | ) -> &mut Self { |
769 | unsafe { |
770 | self.native_mut() |
771 | .postTranslate(x, y, z.into().unwrap_or(0.0)) |
772 | }; |
773 | self |
774 | } |
775 | |
776 | pub fn pre_scale(&mut self, x: scalar, y: scalar) -> &mut Self { |
777 | unsafe { self.native_mut().preScale(x, y) }; |
778 | self |
779 | } |
780 | |
781 | pub fn pre_scale_xyz(&mut self, x: scalar, y: scalar, z: scalar) -> &mut Self { |
782 | unsafe { self.native_mut().preScale1(x, y, z) }; |
783 | self |
784 | } |
785 | } |
786 | |
787 | impl Mul for &M44 { |
788 | type Output = M44; |
789 | |
790 | fn mul(self, m: Self) -> Self::Output { |
791 | M44::concat(self, b:m) |
792 | } |
793 | } |
794 | |
795 | impl Mul<V4> for &M44 { |
796 | type Output = V4; |
797 | |
798 | fn mul(self, v: V4) -> Self::Output { |
799 | self.map(v.x, v.y, v.z, v.w) |
800 | } |
801 | } |
802 | |
803 | impl Mul<V3> for &M44 { |
804 | type Output = V3; |
805 | |
806 | fn mul(self, v: V3) -> Self::Output { |
807 | let v4: V4 = self.map(v.x, v.y, v.z, w:0.0); |
808 | V3::new(v4.x, v4.y, v4.z) |
809 | } |
810 | } |
811 | |
812 | impl From<&Matrix> for M44 { |
813 | fn from(src: &Matrix) -> Self { |
814 | use crate::matrix::Member::*; |
815 | |
816 | Self::new( |
817 | m0:src[ScaleX], |
818 | m4:src[SkewX], |
819 | m8:0.0, |
820 | m12:src[TransX], |
821 | m1:src[SkewY], |
822 | m5:src[ScaleY], |
823 | m9:0.0, |
824 | m13:src[TransY], |
825 | m2:0.0, |
826 | m6:0.0, |
827 | m10:1.0, |
828 | m14:0.0, |
829 | m3:src[Persp0], |
830 | m7:src[Persp1], |
831 | m11:0.0, |
832 | m15:src[Persp2], |
833 | ) |
834 | } |
835 | } |
836 | |
837 | impl From<Matrix> for M44 { |
838 | fn from(m: Matrix) -> Self { |
839 | M44::from(&m) |
840 | } |
841 | } |
842 | |
843 | #[cfg (test)] |
844 | mod tests { |
845 | use crate::{matrix, Matrix, Rect, M44}; |
846 | |
847 | #[test ] |
848 | pub fn convert_from_matrix_and_back() { |
849 | // taken from skulpin's physics example. |
850 | let vr = Rect::new(-4.5, -4.0, 4.5, 2.0); |
851 | let dst = Rect::new(0.0, 0.0, 1350.0, 900.0); |
852 | |
853 | let m = Matrix::from_rect_to_rect(vr, dst, matrix::ScaleToFit::Center).unwrap(); |
854 | let m44 = M44::from(m); |
855 | let m3 = m44.to_m33(); |
856 | assert_eq!(m, m3); |
857 | } |
858 | } |
859 | |