Chromium Code Reviews| 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 |