OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkMatrix44.h" | 8 #include "SkMatrix44.h" |
9 #include "Test.h" | 9 #include "Test.h" |
10 | 10 |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
514 a44flattened.mapScalars(vec4, vec4transformed2); | 514 a44flattened.mapScalars(vec4, vec4transformed2); |
515 REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[0], vec3transf ormed[0])); | 515 REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[0], vec3transf ormed[0])); |
516 REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[1], vec3transf ormed[1])); | 516 REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[1], vec3transf ormed[1])); |
517 REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[3], vec3transf ormed[2])); | 517 REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[3], vec3transf ormed[2])); |
518 REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[0], vec4transf ormed2[0])); | 518 REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[0], vec4transf ormed2[0])); |
519 REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[1], vec4transf ormed2[1])); | 519 REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[1], vec4transf ormed2[1])); |
520 REPORTER_ASSERT(reporter, !nearly_equal_scalar(vec4transformed[2], vec4trans formed2[2])); | 520 REPORTER_ASSERT(reporter, !nearly_equal_scalar(vec4transformed[2], vec4trans formed2[2])); |
521 REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[3], vec4transf ormed2[3])); | 521 REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[3], vec4transf ormed2[3])); |
522 } | 522 } |
523 | 523 |
524 static bool is_rectilinear (SkVector4& p1, SkVector4& p2, SkVector4& p3, SkVecto r4& p4) { | |
525 return (p1.fData[0] == p2.fData[0] && p2.fData[1] == p3.fData[1] && | |
danakj
2014/09/03 19:59:22
The gfx unit test uses within-std::epsilon<float>
| |
526 p3.fData[0] == p4.fData[0] && p4.fData[1] == p1.fData[1]) || | |
527 (p1.fData[1] == p2.fData[1] && p2.fData[0] == p3.fData[0] && | |
528 p3.fData[1] == p4.fData[1] && p4.fData[0] == p1.fData[0]); | |
529 } | |
530 | |
531 static bool empirically_preserves_2d_axis_alignment(skiatest::Reporter* reporter , | |
532 const SkMatrix44& transform) { | |
533 SkVector4 p1(5.0f, 5.0f, 0.0f); | |
534 SkVector4 p2(10.0f, 5.0f, 0.0f); | |
535 SkVector4 p3(10.0f, 20.0f, 0.0f); | |
536 SkVector4 p4(5.0f, 20.0f, 0.0f); | |
537 | |
538 REPORTER_ASSERT(reporter, is_rectilinear(p1, p2, p3, p4)); | |
539 | |
540 p1 = transform * p1; | |
danakj
2014/09/03 19:59:22
The gfx TransformPoint() method does something mor
Ian Vollick
2014/09/05 15:05:27
I wonder if dividing through by w to get the persp
| |
541 p2 = transform * p2; | |
542 p3 = transform * p3; | |
543 p4 = transform * p4; | |
544 | |
545 SkDebugf("p1 %f %f %f %f\n", p1.fData[0], p1.fData[1], p1.fData[2], p1.fData[3]) ; | |
546 SkDebugf("p2 %f %f %f %f\n", p2.fData[0], p2.fData[1], p2.fData[2], p2.fData[3]) ; | |
547 SkDebugf("p3 %f %f %f %f\n", p3.fData[0], p3.fData[1], p3.fData[2], p3.fData[3]) ; | |
548 SkDebugf("p4 %f %f %f %f\n", p4.fData[0], p4.fData[1], p4.fData[2], p4.fData[3]) ; | |
549 | |
550 return is_rectilinear(p1, p2, p3, p4); | |
551 } | |
552 | |
553 static void test_preserves_2d_axis_alignment(skiatest::Reporter* reporter) { | |
554 SkMatrix44 transform(SkMatrix44::kUninitialized_Constructor); | |
555 SkMatrix44 transform2(SkMatrix44::kUninitialized_Constructor); | |
556 | |
557 /* | |
558 static const struct TestCase { | |
559 SkMScalar a; // row 1, column 1 | |
560 SkMScalar b; // row 1, column 2 | |
561 SkMScalar c; // row 2, column 1 | |
562 SkMScalar d; // row 2, column 2 | |
563 bool expected; | |
564 } test_cases[] = { | |
565 { 3.f, 0.f, | |
566 0.f, 4.f, true }, // basic case | |
567 { 0.f, 4.f, | |
568 3.f, 0.f, true }, // rotate by 90 | |
569 { 0.f, 0.f, | |
570 0.f, 4.f, true }, // degenerate x | |
571 { 3.f, 0.f, | |
572 0.f, 0.f, true }, // degenerate y | |
573 { 0.f, 0.f, | |
574 3.f, 0.f, true }, // degenerate x + rotate by 90 | |
575 { 0.f, 4.f, | |
576 0.f, 0.f, true }, // degenerate y + rotate by 90 | |
577 { 3.f, 4.f, | |
578 0.f, 0.f, false }, | |
579 { 0.f, 0.f, | |
580 3.f, 4.f, false }, | |
581 { 0.f, 3.f, | |
582 0.f, 4.f, false }, | |
583 { 3.f, 0.f, | |
584 4.f, 0.f, false }, | |
585 { 3.f, 4.f, | |
586 5.f, 0.f, false }, | |
587 { 3.f, 4.f, | |
588 0.f, 5.f, false }, | |
589 { 3.f, 0.f, | |
590 4.f, 5.f, false }, | |
591 { 0.f, 3.f, | |
592 4.f, 5.f, false }, | |
593 { 2.f, 3.f, | |
594 4.f, 5.f, false }, | |
595 }; | |
596 | |
597 for (size_t i = 0; i < sizeof(test_cases)/sizeof(TestCase); ++i) { | |
598 const TestCase& value = test_cases[i]; | |
599 transform.setIdentity(); | |
600 transform.set(0, 0, value.a); | |
601 transform.set(0, 1, value.b); | |
602 transform.set(1, 0, value.c); | |
603 transform.set(1, 1, value.d); | |
604 | |
605 if (value.expected) { | |
606 REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter , transform)); | |
607 REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment()); | |
608 } else { | |
609 REPORTER_ASSERT(reporter, !empirically_preserves_2d_axis_alignment(reporte r, transform)); | |
610 REPORTER_ASSERT(reporter, !transform.preserves2dAxisAlignment()); | |
611 } | |
612 } | |
613 | |
614 // Try the same test cases again, but this time make sure that other matrix | |
615 // elements (except perspective) have entries, to test that they are ignored. | |
616 for (size_t i = 0; i < sizeof(test_cases)/sizeof(TestCase); ++i) { | |
617 const TestCase& value = test_cases[i]; | |
618 transform.setIdentity(); | |
619 transform.set(0, 0, value.a); | |
620 transform.set(0, 1, value.b); | |
621 transform.set(1, 0, value.c); | |
622 transform.set(1, 1, value.d); | |
623 | |
624 transform.set(0, 2, 1.f); | |
625 transform.set(0, 3, 2.f); | |
626 transform.set(1, 2, 3.f); | |
627 transform.set(1, 3, 4.f); | |
628 transform.set(2, 0, 5.f); | |
629 transform.set(2, 1, 6.f); | |
630 transform.set(2, 2, 7.f); | |
631 transform.set(2, 3, 8.f); | |
632 | |
633 if (value.expected) { | |
634 REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter , transform)); | |
635 REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment()); | |
636 } else { | |
637 REPORTER_ASSERT(reporter, !empirically_preserves_2d_axis_alignment(reporte r, transform)); | |
638 REPORTER_ASSERT(reporter, !transform.preserves2dAxisAlignment()); | |
639 } | |
640 } | |
641 | |
642 // Try the same test cases again, but this time add perspective which is | |
643 // always assumed to not-preserve axis alignment. | |
644 for (size_t i = 0; i < sizeof(test_cases)/sizeof(TestCase); ++i) { | |
645 const TestCase& value = test_cases[i]; | |
646 transform.setIdentity(); | |
647 transform.set(0, 0, value.a); | |
648 transform.set(0, 1, value.b); | |
649 transform.set(1, 0, value.c); | |
650 transform.set(1, 1, value.d); | |
651 | |
652 transform.set(0, 2, 1.f); | |
653 transform.set(0, 3, 2.f); | |
654 transform.set(1, 2, 3.f); | |
655 transform.set(1, 3, 4.f); | |
656 transform.set(2, 0, 5.f); | |
657 transform.set(2, 1, 6.f); | |
658 transform.set(2, 2, 7.f); | |
659 transform.set(2, 3, 8.f); | |
660 transform.set(3, 0, 9.f); | |
661 transform.set(3, 1, 10.f); | |
662 transform.set(3, 2, 11.f); | |
663 transform.set(3, 3, 12.f); | |
664 | |
665 REPORTER_ASSERT(reporter, !empirically_preserves_2d_axis_alignment(reporter, transform)); | |
666 REPORTER_ASSERT(reporter, !transform.preserves2dAxisAlignment()); | |
667 } | |
668 | |
669 // Try a few more practical situations to check precision | |
670 transform.setRotateDegreesAbout(0.0, 0.0, 1.0, 90.0); | |
671 REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, tr ansform)); | |
672 REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment()); | |
673 | |
674 transform.setRotateDegreesAbout(0.0, 0.0, 1.0, 180.0); | |
675 REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, tr ansform)); | |
676 REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment()); | |
677 | |
678 transform.setRotateDegreesAbout(0.0, 0.0, 1.0, 270.0); | |
679 REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, tr ansform)); | |
680 REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment()); | |
681 | |
682 transform.setRotateDegreesAbout(0.0, 1.0, 0.0, 90.0); | |
683 REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, tr ansform)); | |
684 REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment()); | |
685 | |
686 transform.setRotateDegreesAbout(1.0, 0.0, 0.0, 90.0); | |
687 REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, tr ansform)); | |
688 REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment()); | |
689 | |
690 transform.setRotateDegreesAbout(0.0, 0.0, 1.0, 90.0); | |
691 transform2.setRotateDegreesAbout(0.0, 1.0, 0.0, 90.0); | |
692 transform.postConcat(transform2); | |
693 REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, tr ansform)); | |
694 REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment()); | |
695 | |
696 transform.setRotateDegreesAbout(0.0, 0.0, 1.0, 90.0); | |
697 transform2.setRotateDegreesAbout(1.0, 0.0, 0.0, 90.0); | |
698 transform.postConcat(transform2); | |
699 REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, tr ansform)); | |
700 REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment()); | |
701 | |
702 transform.setRotateDegreesAbout(0.0, 1.0, 0.0, 90.0); | |
703 transform2.setRotateDegreesAbout(0.0, 0.0, 1.0, 90.0); | |
704 transform.postConcat(transform2); | |
705 REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, tr ansform)); | |
706 REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment()); | |
707 | |
708 transform.setRotateDegreesAbout(0.0, 0.0, 1.0, 45.0); | |
709 REPORTER_ASSERT(reporter, !empirically_preserves_2d_axis_alignment(reporter, t ransform)); | |
710 REPORTER_ASSERT(reporter, !transform.preserves2dAxisAlignment()); | |
711 | |
712 // 3-d case; In 2d after an orthographic projection, this case does | |
713 // preserve 2d axis alignment. But in 3d, it does not preserve axis | |
714 // alignment. | |
715 transform.setRotateDegreesAbout(0.0, 1.0, 0.0, 45.0); | |
716 REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, tr ansform)); | |
717 REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment()); | |
718 | |
719 transform.setRotateDegreesAbout(1.0, 0.0, 0.0, 45.0); | |
720 REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, tr ansform)); | |
721 REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment()); | |
722 */ | |
723 | |
724 // Perspective cases. | |
725 transform.setIdentity(); | |
726 transform.set(3, 2, -0.1); | |
727 transform2.setRotateDegreesAbout(0.0, 1.0, 0.0, 45.0); | |
728 transform.preConcat(transform2); | |
729 | |
730 transform.dump(); | |
731 | |
732 REPORTER_ASSERT(reporter, !empirically_preserves_2d_axis_alignment(reporter, t ransform)); | |
733 REPORTER_ASSERT(reporter, !transform.preserves2dAxisAlignment()); | |
734 | |
735 transform.setIdentity(); | |
736 transform.set(3, 2, -0.1); | |
737 transform2.setRotateDegreesAbout(0.0, 0.0, 1.0, 90.0); | |
738 transform.preConcat(transform2); | |
739 REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, tr ansform)); | |
740 REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment()); | |
741 } | |
742 | |
743 | |
524 DEF_TEST(Matrix44, reporter) { | 744 DEF_TEST(Matrix44, reporter) { |
525 SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor); | 745 SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor); |
526 SkMatrix44 inverse(SkMatrix44::kUninitialized_Constructor); | 746 SkMatrix44 inverse(SkMatrix44::kUninitialized_Constructor); |
527 SkMatrix44 iden1(SkMatrix44::kUninitialized_Constructor); | 747 SkMatrix44 iden1(SkMatrix44::kUninitialized_Constructor); |
528 SkMatrix44 iden2(SkMatrix44::kUninitialized_Constructor); | 748 SkMatrix44 iden2(SkMatrix44::kUninitialized_Constructor); |
529 SkMatrix44 rot(SkMatrix44::kUninitialized_Constructor); | 749 SkMatrix44 rot(SkMatrix44::kUninitialized_Constructor); |
530 | 750 |
531 mat.setTranslate(1, 1, 1); | 751 mat.setTranslate(1, 1, 1); |
532 mat.invert(&inverse); | 752 mat.invert(&inverse); |
533 iden1.setConcat(mat, inverse); | 753 iden1.setConcat(mat, inverse); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
619 test_gettype(reporter); | 839 test_gettype(reporter); |
620 test_determinant(reporter); | 840 test_determinant(reporter); |
621 test_invert(reporter); | 841 test_invert(reporter); |
622 test_transpose(reporter); | 842 test_transpose(reporter); |
623 test_get_set_double(reporter); | 843 test_get_set_double(reporter); |
624 test_set_row_col_major(reporter); | 844 test_set_row_col_major(reporter); |
625 test_translate(reporter); | 845 test_translate(reporter); |
626 test_scale(reporter); | 846 test_scale(reporter); |
627 test_map2(reporter); | 847 test_map2(reporter); |
628 test_3x3_conversion(reporter); | 848 test_3x3_conversion(reporter); |
849 test_preserves_2d_axis_alignment(reporter); | |
629 } | 850 } |
OLD | NEW |