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