Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: tests/Matrix44Test.cpp

Issue 508303005: SkMatrix44::preserves2dAxisAlignment() (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: unit test review fixes Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/utils/SkMatrix44.cpp ('K') | « src/utils/SkMatrix44.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 543
544 transform.reset(); 544 transform.reset();
545 transform.set(3, 3, 0.5); 545 transform.set(3, 3, 0.5);
546 REPORTER_ASSERT(reporter, transform.hasPerspective()); 546 REPORTER_ASSERT(reporter, transform.hasPerspective());
547 547
548 transform.reset(); 548 transform.reset();
549 transform.set(3, 3, 0.0); 549 transform.set(3, 3, 0.0);
550 REPORTER_ASSERT(reporter, transform.hasPerspective()); 550 REPORTER_ASSERT(reporter, transform.hasPerspective());
551 } 551 }
552 552
553 static bool is_rectilinear (SkVector4& p1, SkVector4& p2, SkVector4& p3, SkVecto r4& p4) {
554 return (SkScalarNearlyEqual(p1.fData[0], p2.fData[0]) &&
555 SkScalarNearlyEqual(p2.fData[1], p3.fData[1]) &&
556 SkScalarNearlyEqual(p3.fData[0], p4.fData[0]) &&
557 SkScalarNearlyEqual(p4.fData[1], p1.fData[1])) ||
558 (SkScalarNearlyEqual(p1.fData[1], p2.fData[1]) &&
559 SkScalarNearlyEqual(p2.fData[0], p3.fData[0]) &&
560 SkScalarNearlyEqual(p3.fData[1], p4.fData[1]) &&
561 SkScalarNearlyEqual(p4.fData[0], p1.fData[0]));
562 }
563
564 static SkVector4 mul_with_persp_divide(const SkMatrix44& transform, const SkVect or4& target) {
565 SkVector4 result = transform * target;
566 if (result.fData[3] != 0.0f && result.fData[3] != SK_Scalar1) {
567 float wInverse = SK_Scalar1 / result.fData[3];
568 result.set(result.fData[0] * wInverse,
569 result.fData[1] * wInverse,
570 result.fData[2] * wInverse,
571 SK_Scalar1);
572 }
573 return result;
574 }
575
576 static bool empirically_preserves_2d_axis_alignment(skiatest::Reporter* reporter ,
577 const SkMatrix44& transform) {
578 SkVector4 p1(5.0f, 5.0f, 0.0f);
579 SkVector4 p2(10.0f, 5.0f, 0.0f);
580 SkVector4 p3(10.0f, 20.0f, 0.0f);
581 SkVector4 p4(5.0f, 20.0f, 0.0f);
582
583 REPORTER_ASSERT(reporter, is_rectilinear(p1, p2, p3, p4));
584
585 p1 = mul_with_persp_divide(transform, p1);
586 p2 = mul_with_persp_divide(transform, p2);
587 p3 = mul_with_persp_divide(transform, p3);
588 p4 = mul_with_persp_divide(transform, p4);
589
590 return is_rectilinear(p1, p2, p3, p4);
591 }
592
593 static void test(bool expected, skiatest::Reporter* reporter, const SkMatrix44& transform) {
594 if (expected) {
595 REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(report er, transform));
596 REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment());
597 } else {
598 REPORTER_ASSERT(reporter, !empirically_preserves_2d_axis_alignment(repor ter, transform));
599 REPORTER_ASSERT(reporter, !transform.preserves2dAxisAlignment());
600 }
601 }
602
603 static void test_preserves_2d_axis_alignment(skiatest::Reporter* reporter) {
604 SkMatrix44 transform(SkMatrix44::kUninitialized_Constructor);
605 SkMatrix44 transform2(SkMatrix44::kUninitialized_Constructor);
606
607 static const struct TestCase {
608 SkMScalar a; // row 1, column 1
609 SkMScalar b; // row 1, column 2
610 SkMScalar c; // row 2, column 1
611 SkMScalar d; // row 2, column 2
612 bool expected;
613 } test_cases[] = {
614 { 3.f, 0.f,
615 0.f, 4.f, true }, // basic case
616 { 0.f, 4.f,
617 3.f, 0.f, true }, // rotate by 90
618 { 0.f, 0.f,
619 0.f, 4.f, true }, // degenerate x
620 { 3.f, 0.f,
621 0.f, 0.f, true }, // degenerate y
622 { 0.f, 0.f,
623 3.f, 0.f, true }, // degenerate x + rotate by 90
624 { 0.f, 4.f,
625 0.f, 0.f, true }, // degenerate y + rotate by 90
626 { 3.f, 4.f,
627 0.f, 0.f, false },
628 { 0.f, 0.f,
629 3.f, 4.f, false },
630 { 0.f, 3.f,
631 0.f, 4.f, false },
632 { 3.f, 0.f,
633 4.f, 0.f, false },
634 { 3.f, 4.f,
635 5.f, 0.f, false },
636 { 3.f, 4.f,
637 0.f, 5.f, false },
638 { 3.f, 0.f,
639 4.f, 5.f, false },
640 { 0.f, 3.f,
641 4.f, 5.f, false },
642 { 2.f, 3.f,
643 4.f, 5.f, false },
644 };
645
646 for (size_t i = 0; i < sizeof(test_cases)/sizeof(TestCase); ++i) {
647 const TestCase& value = test_cases[i];
648 transform.setIdentity();
649 transform.set(0, 0, value.a);
650 transform.set(0, 1, value.b);
651 transform.set(1, 0, value.c);
652 transform.set(1, 1, value.d);
653
654 test(value.expected, reporter, transform);
655 }
656
657 // Try the same test cases again, but this time make sure that other matrix
658 // elements (except perspective) have entries, to test that they are ignored.
659 for (size_t i = 0; i < sizeof(test_cases)/sizeof(TestCase); ++i) {
660 const TestCase& value = test_cases[i];
661 transform.setIdentity();
662 transform.set(0, 0, value.a);
663 transform.set(0, 1, value.b);
664 transform.set(1, 0, value.c);
665 transform.set(1, 1, value.d);
666
667 transform.set(0, 2, 1.f);
668 transform.set(0, 3, 2.f);
669 transform.set(1, 2, 3.f);
670 transform.set(1, 3, 4.f);
671 transform.set(2, 0, 5.f);
672 transform.set(2, 1, 6.f);
673 transform.set(2, 2, 7.f);
674 transform.set(2, 3, 8.f);
675
676 test(value.expected, reporter, transform);
677 }
678
679 // Try the same test cases again, but this time add perspective which is
680 // always assumed to not-preserve axis alignment.
681 for (size_t i = 0; i < sizeof(test_cases)/sizeof(TestCase); ++i) {
682 const TestCase& value = test_cases[i];
683 transform.setIdentity();
684 transform.set(0, 0, value.a);
685 transform.set(0, 1, value.b);
686 transform.set(1, 0, value.c);
687 transform.set(1, 1, value.d);
688
689 transform.set(0, 2, 1.f);
690 transform.set(0, 3, 2.f);
691 transform.set(1, 2, 3.f);
692 transform.set(1, 3, 4.f);
693 transform.set(2, 0, 5.f);
694 transform.set(2, 1, 6.f);
695 transform.set(2, 2, 7.f);
696 transform.set(2, 3, 8.f);
697 transform.set(3, 0, 9.f);
698 transform.set(3, 1, 10.f);
699 transform.set(3, 2, 11.f);
700 transform.set(3, 3, 12.f);
701
702 test(false, reporter, transform);
703 }
704
705 // Try a few more practical situations to check precision
706 // Reuse TestCase (a, b, c, d) as (x, y, z, degrees) axis to rotate about.
707 TestCase rotation_tests[] = {
708 { 0.0, 0.0, 1.0, 90.0, true },
709 { 0.0, 0.0, 1.0, 180.0, true },
710 { 0.0, 0.0, 1.0, 270.0, true },
711 { 0.0, 1.0, 0.0, 90.0, true },
712 { 1.0, 0.0, 0.0, 90.0, true },
713 { 0.0, 0.0, 1.0, 45.0, false },
714 // In 3d these next two are non-preserving, but we're testing in 2d after
715 // orthographic projection, where they are.
716 { 0.0, 1.0, 0.0, 45.0, true },
717 { 1.0, 0.0, 0.0, 45.0, true },
718 };
719
720 for (size_t i = 0; i < sizeof(rotation_tests)/sizeof(TestCase); ++i) {
721 const TestCase& value = rotation_tests[i];
722 transform.setRotateDegreesAbout(value.a, value.b, value.c, value.d);
723 test(value.expected, reporter, transform);
724 }
725
726 static const struct DoubleRotationCase {
727 SkMScalar x1;
728 SkMScalar y1;
729 SkMScalar z1;
730 SkMScalar degrees1;
731 SkMScalar x2;
732 SkMScalar y2;
733 SkMScalar z2;
734 SkMScalar degrees2;
735 bool expected;
736 } double_rotation_tests[] = {
737 { 0.0, 0.0, 1.0, 90.0, 0.0, 1.0, 0.0, 90.0, true },
738 { 0.0, 0.0, 1.0, 90.0, 1.0, 0.0, 0.0, 90.0, true },
739 { 0.0, 1.0, 0.0, 90.0, 0.0, 0.0, 1.0, 90.0, true },
740 };
741
742 for (size_t i = 0; i < sizeof(double_rotation_tests)/sizeof(DoubleRotationCase ); ++i) {
743 const DoubleRotationCase& value = double_rotation_tests[i];
744 transform.setRotateDegreesAbout(value.x1, value.y1, value.z1, value.degrees1 );
745 transform2.setRotateDegreesAbout(value.x2, value.y2, value.z2, value.degrees 2);
746 transform.postConcat(transform2);
747 test(value.expected, reporter, transform);
748 }
749
750 // Perspective cases.
751 transform.setIdentity();
752 transform.set(3, 2, -0.1); // Perspective depth 10
753 transform2.setRotateDegreesAbout(0.0, 1.0, 0.0, 45.0);
754 transform.preConcat(transform2);
755 test(false, reporter, transform);
756
757 transform.setIdentity();
758 transform.set(3, 2, -0.1); // Perspective depth 10
759 transform2.setRotateDegreesAbout(0.0, 0.0, 1.0, 90.0);
760 transform.preConcat(transform2);
761 test(true, reporter, transform);
762 }
763
764
553 DEF_TEST(Matrix44, reporter) { 765 DEF_TEST(Matrix44, reporter) {
554 SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor); 766 SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
555 SkMatrix44 inverse(SkMatrix44::kUninitialized_Constructor); 767 SkMatrix44 inverse(SkMatrix44::kUninitialized_Constructor);
556 SkMatrix44 iden1(SkMatrix44::kUninitialized_Constructor); 768 SkMatrix44 iden1(SkMatrix44::kUninitialized_Constructor);
557 SkMatrix44 iden2(SkMatrix44::kUninitialized_Constructor); 769 SkMatrix44 iden2(SkMatrix44::kUninitialized_Constructor);
558 SkMatrix44 rot(SkMatrix44::kUninitialized_Constructor); 770 SkMatrix44 rot(SkMatrix44::kUninitialized_Constructor);
559 771
560 mat.setTranslate(1, 1, 1); 772 mat.setTranslate(1, 1, 1);
561 mat.invert(&inverse); 773 mat.invert(&inverse);
562 iden1.setConcat(mat, inverse); 774 iden1.setConcat(mat, inverse);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 test_determinant(reporter); 861 test_determinant(reporter);
650 test_invert(reporter); 862 test_invert(reporter);
651 test_transpose(reporter); 863 test_transpose(reporter);
652 test_get_set_double(reporter); 864 test_get_set_double(reporter);
653 test_set_row_col_major(reporter); 865 test_set_row_col_major(reporter);
654 test_translate(reporter); 866 test_translate(reporter);
655 test_scale(reporter); 867 test_scale(reporter);
656 test_map2(reporter); 868 test_map2(reporter);
657 test_3x3_conversion(reporter); 869 test_3x3_conversion(reporter);
658 test_has_perspective(reporter); 870 test_has_perspective(reporter);
871 test_preserves_2d_axis_alignment(reporter);
659 } 872 }
OLDNEW
« src/utils/SkMatrix44.cpp ('K') | « src/utils/SkMatrix44.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698