| Index: ui/gfx/transform_unittest.cc
|
| diff --git a/ui/gfx/transform_unittest.cc b/ui/gfx/transform_unittest.cc
|
| index 1984feab23c8375acfb834524005febac2e3d70f..a4985fb8410af23e269a391a62b88b031070c4af 100644
|
| --- a/ui/gfx/transform_unittest.cc
|
| +++ b/ui/gfx/transform_unittest.cc
|
| @@ -22,25 +22,6 @@ namespace gfx {
|
|
|
| namespace {
|
|
|
| -bool PointsAreNearlyEqual(const Point3F& lhs,
|
| - const Point3F& rhs) {
|
| - float epsilon = 0.0001f;
|
| - return lhs.SquaredDistanceTo(rhs) < epsilon;
|
| -}
|
| -
|
| -bool MatricesAreNearlyEqual(const Transform& lhs,
|
| - const Transform& rhs) {
|
| - float epsilon = 0.0001f;
|
| - for (int row = 0; row < 4; ++row) {
|
| - for (int col = 0; col < 4; ++col) {
|
| - if (std::abs(lhs.matrix().get(row, col) -
|
| - rhs.matrix().get(row, col)) > epsilon)
|
| - return false;
|
| - }
|
| - }
|
| - return true;
|
| -}
|
| -
|
| #define EXPECT_ROW1_EQ(a, b, c, d, transform) \
|
| EXPECT_FLOAT_EQ((a), (transform).matrix().get(0, 0)); \
|
| EXPECT_FLOAT_EQ((b), (transform).matrix().get(0, 1)); \
|
| @@ -68,24 +49,95 @@ bool MatricesAreNearlyEqual(const Transform& lhs,
|
| // Checking float values for equality close to zero is not robust using
|
| // EXPECT_FLOAT_EQ (see gtest documentation). So, to verify rotation matrices,
|
| // we must use a looser absolute error threshold in some places.
|
| -#define EXPECT_ROW1_NEAR(a, b, c, d, transform, errorThreshold) \
|
| - EXPECT_NEAR((a), (transform).matrix().get(0, 0), (errorThreshold)); \
|
| - EXPECT_NEAR((b), (transform).matrix().get(0, 1), (errorThreshold)); \
|
| - EXPECT_NEAR((c), (transform).matrix().get(0, 2), (errorThreshold)); \
|
| +#define EXPECT_ROW1_NEAR(a, b, c, d, transform, errorThreshold) \
|
| + EXPECT_NEAR((a), (transform).matrix().get(0, 0), (errorThreshold)); \
|
| + EXPECT_NEAR((b), (transform).matrix().get(0, 1), (errorThreshold)); \
|
| + EXPECT_NEAR((c), (transform).matrix().get(0, 2), (errorThreshold)); \
|
| EXPECT_NEAR((d), (transform).matrix().get(0, 3), (errorThreshold));
|
|
|
| -#define EXPECT_ROW2_NEAR(a, b, c, d, transform, errorThreshold) \
|
| - EXPECT_NEAR((a), (transform).matrix().get(1, 0), (errorThreshold)); \
|
| - EXPECT_NEAR((b), (transform).matrix().get(1, 1), (errorThreshold)); \
|
| - EXPECT_NEAR((c), (transform).matrix().get(1, 2), (errorThreshold)); \
|
| +#define EXPECT_ROW2_NEAR(a, b, c, d, transform, errorThreshold) \
|
| + EXPECT_NEAR((a), (transform).matrix().get(1, 0), (errorThreshold)); \
|
| + EXPECT_NEAR((b), (transform).matrix().get(1, 1), (errorThreshold)); \
|
| + EXPECT_NEAR((c), (transform).matrix().get(1, 2), (errorThreshold)); \
|
| EXPECT_NEAR((d), (transform).matrix().get(1, 3), (errorThreshold));
|
|
|
| -#define EXPECT_ROW3_NEAR(a, b, c, d, transform, errorThreshold) \
|
| - EXPECT_NEAR((a), (transform).matrix().get(2, 0), (errorThreshold)); \
|
| - EXPECT_NEAR((b), (transform).matrix().get(2, 1), (errorThreshold)); \
|
| - EXPECT_NEAR((c), (transform).matrix().get(2, 2), (errorThreshold)); \
|
| +#define EXPECT_ROW3_NEAR(a, b, c, d, transform, errorThreshold) \
|
| + EXPECT_NEAR((a), (transform).matrix().get(2, 0), (errorThreshold)); \
|
| + EXPECT_NEAR((b), (transform).matrix().get(2, 1), (errorThreshold)); \
|
| + EXPECT_NEAR((c), (transform).matrix().get(2, 2), (errorThreshold)); \
|
| EXPECT_NEAR((d), (transform).matrix().get(2, 3), (errorThreshold));
|
|
|
| +bool PointsAreNearlyEqual(const Point3F& lhs,
|
| + const Point3F& rhs) {
|
| + float epsilon = 0.0001f;
|
| + return lhs.SquaredDistanceTo(rhs) < epsilon;
|
| +}
|
| +
|
| +bool MatricesAreNearlyEqual(const Transform& lhs,
|
| + const Transform& rhs) {
|
| + float epsilon = 0.0001f;
|
| + for (int row = 0; row < 4; ++row) {
|
| + for (int col = 0; col < 4; ++col) {
|
| + if (std::abs(lhs.matrix().get(row, col) -
|
| + rhs.matrix().get(row, col)) > epsilon)
|
| + return false;
|
| + }
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +void InitializeTestMatrix(Transform* transform) {
|
| + SkMatrix44& matrix = transform->matrix();
|
| + matrix.setDouble(0, 0, 10.0);
|
| + matrix.setDouble(1, 0, 11.0);
|
| + matrix.setDouble(2, 0, 12.0);
|
| + matrix.setDouble(3, 0, 13.0);
|
| + matrix.setDouble(0, 1, 14.0);
|
| + matrix.setDouble(1, 1, 15.0);
|
| + matrix.setDouble(2, 1, 16.0);
|
| + matrix.setDouble(3, 1, 17.0);
|
| + matrix.setDouble(0, 2, 18.0);
|
| + matrix.setDouble(1, 2, 19.0);
|
| + matrix.setDouble(2, 2, 20.0);
|
| + matrix.setDouble(3, 2, 21.0);
|
| + matrix.setDouble(0, 3, 22.0);
|
| + matrix.setDouble(1, 3, 23.0);
|
| + matrix.setDouble(2, 3, 24.0);
|
| + matrix.setDouble(3, 3, 25.0);
|
| +
|
| + // Sanity check
|
| + EXPECT_ROW1_EQ(10.0f, 14.0f, 18.0f, 22.0f, (*transform));
|
| + EXPECT_ROW2_EQ(11.0f, 15.0f, 19.0f, 23.0f, (*transform));
|
| + EXPECT_ROW3_EQ(12.0f, 16.0f, 20.0f, 24.0f, (*transform));
|
| + EXPECT_ROW4_EQ(13.0f, 17.0f, 21.0f, 25.0f, (*transform));
|
| +}
|
| +
|
| +void InitializeTestMatrix2(Transform* transform) {
|
| + SkMatrix44& matrix = transform->matrix();
|
| + matrix.setDouble(0, 0, 30.0);
|
| + matrix.setDouble(1, 0, 31.0);
|
| + matrix.setDouble(2, 0, 32.0);
|
| + matrix.setDouble(3, 0, 33.0);
|
| + matrix.setDouble(0, 1, 34.0);
|
| + matrix.setDouble(1, 1, 35.0);
|
| + matrix.setDouble(2, 1, 36.0);
|
| + matrix.setDouble(3, 1, 37.0);
|
| + matrix.setDouble(0, 2, 38.0);
|
| + matrix.setDouble(1, 2, 39.0);
|
| + matrix.setDouble(2, 2, 40.0);
|
| + matrix.setDouble(3, 2, 41.0);
|
| + matrix.setDouble(0, 3, 42.0);
|
| + matrix.setDouble(1, 3, 43.0);
|
| + matrix.setDouble(2, 3, 44.0);
|
| + matrix.setDouble(3, 3, 45.0);
|
| +
|
| + // Sanity check
|
| + EXPECT_ROW1_EQ(30.0f, 34.0f, 38.0f, 42.0f, (*transform));
|
| + EXPECT_ROW2_EQ(31.0f, 35.0f, 39.0f, 43.0f, (*transform));
|
| + EXPECT_ROW3_EQ(32.0f, 36.0f, 40.0f, 44.0f, (*transform));
|
| + EXPECT_ROW4_EQ(33.0f, 37.0f, 41.0f, 45.0f, (*transform));
|
| +}
|
| +
|
| #ifdef SK_MSCALAR_IS_DOUBLE
|
| #define ERROR_THRESHOLD 1e-14
|
| #else
|
| @@ -707,116 +759,112 @@ TEST(XFormTest, CannotBlendSingularMatrix) {
|
| EXPECT_FALSE(to.Blend(from, 0.5));
|
| }
|
|
|
| -TEST(XFormTest, VerifyBlendForTranslation)
|
| -{
|
| +TEST(XFormTest, VerifyBlendForTranslation) {
|
| Transform from;
|
| - from.Translate3d(100, 200, 100);
|
| + from.Translate3d(100.0, 200.0, 100.0);
|
|
|
| Transform to;
|
|
|
| - to.Translate3d(200, 100, 300);
|
| - to.Blend(from, 0);
|
| + to.Translate3d(200.0, 100.0, 300.0);
|
| + to.Blend(from, 0.0);
|
| EXPECT_EQ(from, to);
|
|
|
| to = Transform();
|
| - to.Translate3d(200, 100, 300);
|
| + to.Translate3d(200.0, 100.0, 300.0);
|
| to.Blend(from, 0.25);
|
| - EXPECT_ROW1_EQ(1, 0, 0, 125, to);
|
| - EXPECT_ROW2_EQ(0, 1, 0, 175, to);
|
| - EXPECT_ROW3_EQ(0, 0, 1, 150, to);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 125.0f, to);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 175.0f, to);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 150.0f, to);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
|
|
| to = Transform();
|
| - to.Translate3d(200, 100, 300);
|
| + to.Translate3d(200.0, 100.0, 300.0);
|
| to.Blend(from, 0.5);
|
| - EXPECT_ROW1_EQ(1, 0, 0, 150, to);
|
| - EXPECT_ROW2_EQ(0, 1, 0, 150, to);
|
| - EXPECT_ROW3_EQ(0, 0, 1, 200, to);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 150.0f, to);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 150.0f, to);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 200.0f, to);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
|
|
| to = Transform();
|
| - to.Translate3d(200, 100, 300);
|
| - to.Blend(from, 1);
|
| - EXPECT_ROW1_EQ(1, 0, 0, 200, to);
|
| - EXPECT_ROW2_EQ(0, 1, 0, 100, to);
|
| - EXPECT_ROW3_EQ(0, 0, 1, 300, to);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + to.Translate3d(200.0, 100.0, 300.0);
|
| + to.Blend(from, 1.0);
|
| + EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 200.0f, to);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 100.0f, to);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 300.0f, to);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
| }
|
|
|
| -TEST(XFormTest, VerifyBlendForScale)
|
| -{
|
| +TEST(XFormTest, VerifyBlendForScale) {
|
| Transform from;
|
| - from.Scale3d(100, 200, 100);
|
| + from.Scale3d(100.0, 200.0, 100.0);
|
|
|
| Transform to;
|
|
|
| - to.Scale3d(200, 100, 300);
|
| - to.Blend(from, 0);
|
| + to.Scale3d(200.0, 100.0, 300.0);
|
| + to.Blend(from, 0.0);
|
| EXPECT_EQ(from, to);
|
|
|
| to = Transform();
|
| - to.Scale3d(200, 100, 300);
|
| + to.Scale3d(200.0, 100.0, 300.0);
|
| to.Blend(from, 0.25);
|
| - EXPECT_ROW1_EQ(125, 0, 0, 0, to);
|
| - EXPECT_ROW2_EQ(0, 175, 0, 0, to);
|
| - EXPECT_ROW3_EQ(0, 0, 150, 0, to);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + EXPECT_ROW1_EQ(125.0f, 0.0f, 0.0f, 0.0f, to);
|
| + EXPECT_ROW2_EQ(0.0f, 175.0f, 0.0f, 0.0f, to);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 150.0f, 0.0f, to);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
|
|
| to = Transform();
|
| - to.Scale3d(200, 100, 300);
|
| + to.Scale3d(200.0, 100.0, 300.0);
|
| to.Blend(from, 0.5);
|
| - EXPECT_ROW1_EQ(150, 0, 0, 0, to);
|
| - EXPECT_ROW2_EQ(0, 150, 0, 0, to);
|
| - EXPECT_ROW3_EQ(0, 0, 200, 0, to);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + EXPECT_ROW1_EQ(150.0f, 0.0f, 0.0f, 0.0f, to);
|
| + EXPECT_ROW2_EQ(0.0f, 150.0f, 0.0f, 0.0f, to);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 200.0f, 0.0f, to);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
|
|
| to = Transform();
|
| - to.Scale3d(200, 100, 300);
|
| - to.Blend(from, 1);
|
| - EXPECT_ROW1_EQ(200, 0, 0, 0, to);
|
| - EXPECT_ROW2_EQ(0, 100, 0, 0, to);
|
| - EXPECT_ROW3_EQ(0, 0, 300, 0, to);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + to.Scale3d(200.0, 100.0, 300.0);
|
| + to.Blend(from, 1.0);
|
| + EXPECT_ROW1_EQ(200.0f, 0.0f, 0.0f, 0.0f, to);
|
| + EXPECT_ROW2_EQ(0.0f, 100.0f, 0.0f, 0.0f, to);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 300.0f, 0.0f, to);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
| }
|
|
|
| -TEST(XFormTest, VerifyBlendForSkewX)
|
| -{
|
| +TEST(XFormTest, VerifyBlendForSkewX) {
|
| Transform from;
|
| - from.SkewX(0);
|
| + from.SkewX(0.0);
|
|
|
| Transform to;
|
|
|
| - to.SkewX(45);
|
| - to.Blend(from, 0);
|
| + to.SkewX(45.0);
|
| + to.Blend(from, 0.0);
|
| EXPECT_EQ(from, to);
|
|
|
| to = Transform();
|
| - to.SkewX(45);
|
| + to.SkewX(45.0);
|
| to.Blend(from, 0.5);
|
| - EXPECT_ROW1_EQ(1, 0.5, 0, 0, to);
|
| - EXPECT_ROW2_EQ(0, 1, 0, 0, to);
|
| - EXPECT_ROW3_EQ(0, 0, 1, 0, to);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + EXPECT_ROW1_EQ(1.0f, 0.5f, 0.0f, 0.0f, to);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, to);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
|
|
| to = Transform();
|
| - to.SkewX(45);
|
| + to.SkewX(45.0);
|
| to.Blend(from, 0.25);
|
| - EXPECT_ROW1_EQ(1, 0.25, 0, 0, to);
|
| - EXPECT_ROW2_EQ(0, 1, 0, 0, to);
|
| - EXPECT_ROW3_EQ(0, 0, 1, 0, to);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + EXPECT_ROW1_EQ(1.0f, 0.25f, 0.0f, 0.0f, to);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, to);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
|
|
| to = Transform();
|
| - to.SkewX(45);
|
| - to.Blend(from, 1);
|
| - EXPECT_ROW1_EQ(1, 1, 0, 0, to);
|
| - EXPECT_ROW2_EQ(0, 1, 0, 0, to);
|
| - EXPECT_ROW3_EQ(0, 0, 1, 0, to);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + to.SkewX(45.0);
|
| + to.Blend(from, 1.0);
|
| + EXPECT_ROW1_EQ(1.0f, 1.0f, 0.0f, 0.0f, to);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, to);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
| }
|
|
|
| -TEST(XFormTest, VerifyBlendForSkewY)
|
| -{
|
| +TEST(XFormTest, VerifyBlendForSkewY) {
|
| // NOTE CAREFULLY: Decomposition of skew and rotation terms of the matrix
|
| // is inherently underconstrained, and so it does not always compute the
|
| // originally intended skew parameters. The current implementation uses QR
|
| @@ -835,240 +883,236 @@ TEST(XFormTest, VerifyBlendForSkewY)
|
| // error.
|
|
|
| Transform from;
|
| - from.SkewY(0);
|
| + from.SkewY(0.0);
|
|
|
| Transform to;
|
|
|
| - to.SkewY(45);
|
| - to.Blend(from, 0);
|
| + to.SkewY(45.0);
|
| + to.Blend(from, 0.0);
|
| EXPECT_EQ(from, to);
|
|
|
| to = Transform();
|
| - to.SkewY(45);
|
| + to.SkewY(45.0);
|
| to.Blend(from, 0.25);
|
| EXPECT_ROW1_NEAR(1.0823489449280947471976333,
|
| 0.0464370719145053845178239,
|
| - 0,
|
| - 0,
|
| + 0.0,
|
| + 0.0,
|
| to,
|
| LOOSE_ERROR_THRESHOLD);
|
| EXPECT_ROW2_NEAR(0.2152925909665224513123150,
|
| 0.9541702441750861130032035,
|
| - 0,
|
| - 0,
|
| + 0.0,
|
| + 0.0,
|
| to,
|
| LOOSE_ERROR_THRESHOLD);
|
| - EXPECT_ROW3_EQ(0, 0, 1, 0, to);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
|
|
| to = Transform();
|
| - to.SkewY(45);
|
| + to.SkewY(45.0);
|
| to.Blend(from, 0.5);
|
| EXPECT_ROW1_NEAR(1.1152212925809066312865525,
|
| 0.0676495144007326631996335,
|
| - 0,
|
| - 0,
|
| + 0.0,
|
| + 0.0,
|
| to,
|
| LOOSE_ERROR_THRESHOLD);
|
| EXPECT_ROW2_NEAR(0.4619397844342648662419037,
|
| 0.9519009045724774464858342,
|
| - 0,
|
| - 0,
|
| + 0.0,
|
| + 0.0,
|
| to,
|
| LOOSE_ERROR_THRESHOLD);
|
| - EXPECT_ROW3_EQ(0, 0, 1, 0, to);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
|
|
| to = Transform();
|
| - to.SkewY(45);
|
| - to.Blend(from, 1);
|
| - EXPECT_ROW1_NEAR(1, 0, 0, 0, to, LOOSE_ERROR_THRESHOLD);
|
| - EXPECT_ROW2_NEAR(1, 1, 0, 0, to, LOOSE_ERROR_THRESHOLD);
|
| - EXPECT_ROW3_EQ(0, 0, 1, 0, to);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + to.SkewY(45.0);
|
| + to.Blend(from, 1.0);
|
| + EXPECT_ROW1_NEAR(1.0, 0.0, 0.0, 0.0, to, LOOSE_ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(1.0, 1.0, 0.0, 0.0, to, LOOSE_ERROR_THRESHOLD);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, to);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
| }
|
|
|
| -TEST(XFormTest, VerifyBlendForRotationAboutX)
|
| -{
|
| +TEST(XFormTest, VerifyBlendForRotationAboutX) {
|
| // Even though.Blending uses quaternions, axis-aligned rotations should.
|
| // Blend the same with quaternions or Euler angles. So we can test
|
| // rotation.Blending by comparing against manually specified matrices from
|
| // Euler angles.
|
|
|
| Transform from;
|
| - from.RotateAbout(Vector3dF(1, 0, 0), 0);
|
| + from.RotateAbout(Vector3dF(1.0, 0.0, 0.0), 0.0);
|
|
|
| Transform to;
|
|
|
| - to.RotateAbout(Vector3dF(1, 0, 0), 90);
|
| - to.Blend(from, 0);
|
| + to.RotateAbout(Vector3dF(1.0, 0.0, 0.0), 90.0);
|
| + to.Blend(from, 0.0);
|
| EXPECT_EQ(from, to);
|
|
|
| double expectedRotationAngle = 22.5 * M_PI / 180.0;
|
| to = Transform();
|
| - to.RotateAbout(Vector3dF(1, 0, 0), 90);
|
| + to.RotateAbout(Vector3dF(1.0, 0.0, 0.0), 90.0);
|
| to.Blend(from, 0.25);
|
| - EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD);
|
| - EXPECT_ROW2_NEAR(0,
|
| + EXPECT_ROW1_NEAR(1.0, 0.0, 0.0, 0.0, to, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(0.0,
|
| std::cos(expectedRotationAngle),
|
| -std::sin(expectedRotationAngle),
|
| - 0,
|
| + 0.0,
|
| to,
|
| ERROR_THRESHOLD);
|
| - EXPECT_ROW3_NEAR(0,
|
| + EXPECT_ROW3_NEAR(0.0,
|
| std::sin(expectedRotationAngle),
|
| std::cos(expectedRotationAngle),
|
| - 0,
|
| + 0.0,
|
| to,
|
| ERROR_THRESHOLD);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
|
|
| - expectedRotationAngle = 45 * M_PI / 180.0;
|
| + expectedRotationAngle = 45.0 * M_PI / 180.0;
|
| to = Transform();
|
| - to.RotateAbout(Vector3dF(1, 0, 0), 90);
|
| + to.RotateAbout(Vector3dF(1.0, 0.0, 0.0), 90.0);
|
| to.Blend(from, 0.5);
|
| - EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD);
|
| - EXPECT_ROW2_NEAR(0,
|
| + EXPECT_ROW1_NEAR(1.0, 0.0, 0.0, 0.0, to, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(0.0,
|
| std::cos(expectedRotationAngle),
|
| -std::sin(expectedRotationAngle),
|
| - 0,
|
| + 0.0,
|
| to,
|
| ERROR_THRESHOLD);
|
| - EXPECT_ROW3_NEAR(0,
|
| + EXPECT_ROW3_NEAR(0.0,
|
| std::sin(expectedRotationAngle),
|
| std::cos(expectedRotationAngle),
|
| - 0,
|
| + 0.0,
|
| to,
|
| ERROR_THRESHOLD);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
|
|
| to = Transform();
|
| - to.RotateAbout(Vector3dF(1, 0, 0), 90);
|
| - to.Blend(from, 1);
|
| - EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD);
|
| - EXPECT_ROW2_NEAR(0, 0, -1, 0, to, ERROR_THRESHOLD);
|
| - EXPECT_ROW3_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + to.RotateAbout(Vector3dF(1.0, 0.0, 0.0), 90.0);
|
| + to.Blend(from, 1.0);
|
| + EXPECT_ROW1_NEAR(1.0, 0.0, 0.0, 0.0, to, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(0.0, 0.0, -1.0, 0.0, to, ERROR_THRESHOLD);
|
| + EXPECT_ROW3_NEAR(0.0, 1.0, 0.0, 0.0, to, ERROR_THRESHOLD);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
| }
|
|
|
| -TEST(XFormTest, VerifyBlendForRotationAboutY)
|
| -{
|
| +TEST(XFormTest, VerifyBlendForRotationAboutY) {
|
| Transform from;
|
| - from.RotateAbout(Vector3dF(0, 1, 0), 0);
|
| + from.RotateAbout(Vector3dF(0.0, 1.0, 0.0), 0.0);
|
|
|
| Transform to;
|
|
|
| - to.RotateAbout(Vector3dF(0, 1, 0), 90);
|
| - to.Blend(from, 0);
|
| + to.RotateAbout(Vector3dF(0.0, 1.0, 0.0), 90.0);
|
| + to.Blend(from, 0.0);
|
| EXPECT_EQ(from, to);
|
|
|
| double expectedRotationAngle = 22.5 * M_PI / 180.0;
|
| to = Transform();
|
| - to.RotateAbout(Vector3dF(0, 1, 0), 90);
|
| + to.RotateAbout(Vector3dF(0.0, 1.0, 0.0), 90.0);
|
| to.Blend(from, 0.25);
|
| EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle),
|
| - 0,
|
| + 0.0,
|
| std::sin(expectedRotationAngle),
|
| - 0,
|
| + 0.0,
|
| to,
|
| ERROR_THRESHOLD);
|
| - EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(0.0, 1.0, 0.0, 0.0, to, ERROR_THRESHOLD);
|
| EXPECT_ROW3_NEAR(-std::sin(expectedRotationAngle),
|
| - 0,
|
| + 0.0,
|
| std::cos(expectedRotationAngle),
|
| - 0,
|
| + 0.0,
|
| to,
|
| ERROR_THRESHOLD);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
|
|
| - expectedRotationAngle = 45 * M_PI / 180.0;
|
| + expectedRotationAngle = 45.0 * M_PI / 180.0;
|
| to = Transform();
|
| - to.RotateAbout(Vector3dF(0, 1, 0), 90);
|
| + to.RotateAbout(Vector3dF(0.0, 1.0, 0.0), 90.0);
|
| to.Blend(from, 0.5);
|
| EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle),
|
| - 0,
|
| + 0.0,
|
| std::sin(expectedRotationAngle),
|
| - 0,
|
| + 0.0,
|
| to,
|
| ERROR_THRESHOLD);
|
| - EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(0.0, 1.0, 0.0, 0.0, to, ERROR_THRESHOLD);
|
| EXPECT_ROW3_NEAR(-std::sin(expectedRotationAngle),
|
| - 0,
|
| + 0.0,
|
| std::cos(expectedRotationAngle),
|
| - 0,
|
| + 0.0,
|
| to,
|
| ERROR_THRESHOLD);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
|
|
| to = Transform();
|
| - to.RotateAbout(Vector3dF(0, 1, 0), 90);
|
| - to.Blend(from, 1);
|
| - EXPECT_ROW1_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD);
|
| - EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD);
|
| - EXPECT_ROW3_NEAR(-1, 0, 0, 0, to, ERROR_THRESHOLD);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + to.RotateAbout(Vector3dF(0.0, 1.0, 0.0), 90.0);
|
| + to.Blend(from, 1.0);
|
| + EXPECT_ROW1_NEAR(0.0, 0.0, 1.0, 0.0, to, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(0.0, 1.0, 0.0, 0.0, to, ERROR_THRESHOLD);
|
| + EXPECT_ROW3_NEAR(-1.0, 0.0, 0.0, 0.0, to, ERROR_THRESHOLD);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
| }
|
|
|
| -TEST(XFormTest, VerifyBlendForRotationAboutZ)
|
| -{
|
| +TEST(XFormTest, VerifyBlendForRotationAboutZ) {
|
| Transform from;
|
| - from.RotateAbout(Vector3dF(0, 0, 1), 0);
|
| + from.RotateAbout(Vector3dF(0.0, 0.0, 1.0), 0.0);
|
|
|
| Transform to;
|
|
|
| - to.RotateAbout(Vector3dF(0, 0, 1), 90);
|
| - to.Blend(from, 0);
|
| + to.RotateAbout(Vector3dF(0.0, 0.0, 1.0), 90.0);
|
| + to.Blend(from, 0.0);
|
| EXPECT_EQ(from, to);
|
|
|
| double expectedRotationAngle = 22.5 * M_PI / 180.0;
|
| to = Transform();
|
| - to.RotateAbout(Vector3dF(0, 0, 1), 90);
|
| + to.RotateAbout(Vector3dF(0.0, 0.0, 1.0), 90.0);
|
| to.Blend(from, 0.25);
|
| EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle),
|
| -std::sin(expectedRotationAngle),
|
| - 0,
|
| - 0,
|
| + 0.0,
|
| + 0.0,
|
| to,
|
| ERROR_THRESHOLD);
|
| EXPECT_ROW2_NEAR(std::sin(expectedRotationAngle),
|
| std::cos(expectedRotationAngle),
|
| - 0,
|
| - 0,
|
| + 0.0,
|
| + 0.0,
|
| to,
|
| ERROR_THRESHOLD);
|
| - EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + EXPECT_ROW3_NEAR(0.0, 0.0, 1.0, 0.0, to, ERROR_THRESHOLD);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
|
|
| - expectedRotationAngle = 45 * M_PI / 180.0;
|
| + expectedRotationAngle = 45.0 * M_PI / 180.0;
|
| to = Transform();
|
| - to.RotateAbout(Vector3dF(0, 0, 1), 90);
|
| + to.RotateAbout(Vector3dF(0.0, 0.0, 1.0), 90.0);
|
| to.Blend(from, 0.5);
|
| EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle),
|
| -std::sin(expectedRotationAngle),
|
| - 0,
|
| - 0,
|
| + 0.0,
|
| + 0.0,
|
| to,
|
| ERROR_THRESHOLD);
|
| EXPECT_ROW2_NEAR(std::sin(expectedRotationAngle),
|
| std::cos(expectedRotationAngle),
|
| - 0,
|
| - 0,
|
| + 0.0,
|
| + 0.0,
|
| to,
|
| ERROR_THRESHOLD);
|
| - EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + EXPECT_ROW3_NEAR(0.0, 0.0, 1.0, 0.0, to, ERROR_THRESHOLD);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
|
|
| to = Transform();
|
| - to.RotateAbout(Vector3dF(0, 0, 1), 90);
|
| - to.Blend(from, 1);
|
| - EXPECT_ROW1_NEAR(0, -1, 0, 0, to, ERROR_THRESHOLD);
|
| - EXPECT_ROW2_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD);
|
| - EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, to);
|
| + to.RotateAbout(Vector3dF(0.0, 0.0, 1.0), 90.0);
|
| + to.Blend(from, 1.0);
|
| + EXPECT_ROW1_NEAR(0.0, -1.0, 0.0, 0.0, to, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(1.0, 0.0, 0.0, 0.0, to, ERROR_THRESHOLD);
|
| + EXPECT_ROW3_NEAR(0.0, 0.0, 1.0, 0.0, to, ERROR_THRESHOLD);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, to);
|
| }
|
|
|
| -TEST(XFormTest, VerifyBlendForCompositeTransform)
|
| -{
|
| +TEST(XFormTest, VerifyBlendForCompositeTransform) {
|
| // Verify that the.Blending was done with a decomposition in correct order
|
| // by blending a composite transform. Using matrix x vector notation
|
| // (Ax = b, where x is column vector), the ordering should be:
|
| @@ -1082,14 +1126,14 @@ TEST(XFormTest, VerifyBlendForCompositeTransform)
|
| Transform to;
|
|
|
| Transform expectedEndOfAnimation;
|
| - expectedEndOfAnimation.ApplyPerspectiveDepth(1);
|
| - expectedEndOfAnimation.Translate3d(10, 20, 30);
|
| - expectedEndOfAnimation.RotateAbout(Vector3dF(0, 0, 1), 25);
|
| - expectedEndOfAnimation.SkewY(45);
|
| - expectedEndOfAnimation.Scale3d(6, 7, 8);
|
| + expectedEndOfAnimation.ApplyPerspectiveDepth(1.0);
|
| + expectedEndOfAnimation.Translate3d(10.0, 20.0, 30.0);
|
| + expectedEndOfAnimation.RotateAbout(Vector3dF(0.0, 0.0, 1.0), 25.0);
|
| + expectedEndOfAnimation.SkewY(45.0);
|
| + expectedEndOfAnimation.Scale3d(6.0, 7.0, 8.0);
|
|
|
| to = expectedEndOfAnimation;
|
| - to.Blend(from, 0);
|
| + to.Blend(from, 0.0);
|
| EXPECT_EQ(from, to);
|
|
|
| to = expectedEndOfAnimation;
|
| @@ -1104,20 +1148,27 @@ TEST(XFormTest, VerifyBlendForCompositeTransform)
|
| Transform normalizedExpectedEndOfAnimation = expectedEndOfAnimation;
|
| Transform normalizationMatrix;
|
| normalizationMatrix.matrix().set(
|
| - 0, 0, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3)));
|
| + 0.0,
|
| + 0.0,
|
| + SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3.0, 3.0)));
|
| normalizationMatrix.matrix().set(
|
| - 1, 1, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3)));
|
| + 1.0,
|
| + 1.0,
|
| + SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3.0, 3.0)));
|
| normalizationMatrix.matrix().set(
|
| - 2, 2, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3)));
|
| + 2.0,
|
| + 2.0,
|
| + SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3.0, 3.0)));
|
| normalizationMatrix.matrix().set(
|
| - 3, 3, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3)));
|
| + 3.0,
|
| + 3.0,
|
| + SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3.0, 3.0)));
|
| normalizedExpectedEndOfAnimation.PreconcatTransform(normalizationMatrix);
|
|
|
| EXPECT_TRUE(MatricesAreNearlyEqual(normalizedExpectedEndOfAnimation, to));
|
| }
|
|
|
| -TEST(XFormTest, DecomposedTransformCtor)
|
| -{
|
| +TEST(XFormTest, DecomposedTransformCtor) {
|
| DecomposedTransform decomp;
|
| for (int i = 0; i < 3; ++i) {
|
| EXPECT_EQ(0.0, decomp.translate[i]);
|
| @@ -1182,64 +1233,991 @@ TEST(XFormTest, IntegerTranslation) {
|
| EXPECT_FALSE(transform.IsIdentityOrIntegerTranslation());
|
| }
|
|
|
| -TEST(XFormTest, verifyMatrixInversion)
|
| -{
|
| +TEST(XFormTest, verifyMatrixInversion) {
|
| {
|
| // Invert a translation
|
| gfx::Transform translation;
|
| - translation.Translate3d(2, 3, 4);
|
| + translation.Translate3d(2.0, 3.0, 4.0);
|
| EXPECT_TRUE(translation.IsInvertible());
|
|
|
| gfx::Transform inverse_translation;
|
| bool is_invertible = translation.GetInverse(&inverse_translation);
|
| EXPECT_TRUE(is_invertible);
|
| - EXPECT_ROW1_EQ(1, 0, 0, -2, inverse_translation);
|
| - EXPECT_ROW2_EQ(0, 1, 0, -3, inverse_translation);
|
| - EXPECT_ROW3_EQ(0, 0, 1, -4, inverse_translation);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, inverse_translation);
|
| + EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, -2.0f, inverse_translation);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, -3.0f, inverse_translation);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, -4.0f, inverse_translation);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, inverse_translation);
|
| }
|
|
|
| {
|
| // Invert a non-uniform scale
|
| gfx::Transform scale;
|
| - scale.Scale3d(4, 10, 100);
|
| + scale.Scale3d(4.0, 10.0, 100.0);
|
| EXPECT_TRUE(scale.IsInvertible());
|
|
|
| gfx::Transform inverse_scale;
|
| bool is_invertible = scale.GetInverse(&inverse_scale);
|
| EXPECT_TRUE(is_invertible);
|
| - EXPECT_ROW1_EQ(0.25, 0, 0, 0, inverse_scale);
|
| - EXPECT_ROW2_EQ(0, .1f, 0, 0, inverse_scale);
|
| - EXPECT_ROW3_EQ(0, 0, .01f, 0, inverse_scale);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, inverse_scale);
|
| + EXPECT_ROW1_EQ(0.25f, 0.0f, 0.0f, 0.0f, inverse_scale);
|
| + EXPECT_ROW2_EQ(0.0f, 0.1f, 0.0f, 0.0f, inverse_scale);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 0.01f, 0.0f, inverse_scale);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, inverse_scale);
|
| }
|
|
|
| {
|
| // Try to invert a matrix that is not invertible.
|
| // The inverse() function should reset the output matrix to identity.
|
| gfx::Transform uninvertible;
|
| - uninvertible.matrix().setDouble(0, 0, 0);
|
| - uninvertible.matrix().setDouble(1, 1, 0);
|
| - uninvertible.matrix().setDouble(2, 2, 0);
|
| - uninvertible.matrix().setDouble(3, 3, 0);
|
| + uninvertible.matrix().setDouble(0, 0, 0.0);
|
| + uninvertible.matrix().setDouble(1, 1, 0.0);
|
| + uninvertible.matrix().setDouble(2, 2, 0.0);
|
| + uninvertible.matrix().setDouble(3, 3, 0.0);
|
| EXPECT_FALSE(uninvertible.IsInvertible());
|
|
|
| gfx::Transform inverse_of_uninvertible;
|
|
|
| // Add a scale just to more easily ensure that inverse_of_uninvertible is
|
| // reset to identity.
|
| - inverse_of_uninvertible.Scale3d(4, 10, 100);
|
| + inverse_of_uninvertible.Scale3d(4.0, 10.0, 100.0);
|
|
|
| bool is_invertible = uninvertible.GetInverse(&inverse_of_uninvertible);
|
| EXPECT_FALSE(is_invertible);
|
| EXPECT_TRUE(inverse_of_uninvertible.IsIdentity());
|
| - EXPECT_ROW1_EQ(1, 0, 0, 0, inverse_of_uninvertible);
|
| - EXPECT_ROW2_EQ(0, 1, 0, 0, inverse_of_uninvertible);
|
| - EXPECT_ROW3_EQ(0, 0, 1, 0, inverse_of_uninvertible);
|
| - EXPECT_ROW4_EQ(0, 0, 0, 1, inverse_of_uninvertible);
|
| + EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 0.0f, inverse_of_uninvertible);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, inverse_of_uninvertible);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, inverse_of_uninvertible);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, inverse_of_uninvertible);
|
| }
|
| }
|
|
|
| +TEST(XFormTest, verifyBackfaceVisibilityBasicCases) {
|
| + Transform transform;
|
| +
|
| + transform.MakeIdentity();
|
| + EXPECT_FALSE(transform.IsBackFaceVisible());
|
| +
|
| + transform.MakeIdentity();
|
| + transform.RotateAboutYAxis(80.0);
|
| + EXPECT_FALSE(transform.IsBackFaceVisible());
|
| +
|
| + transform.MakeIdentity();
|
| + transform.RotateAboutYAxis(100.0);
|
| + EXPECT_TRUE(transform.IsBackFaceVisible());
|
| +
|
| + // Edge case, 90 degree rotation should return false.
|
| + transform.MakeIdentity();
|
| + transform.RotateAboutYAxis(90.0);
|
| + EXPECT_FALSE(transform.IsBackFaceVisible());
|
| +}
|
| +
|
| +TEST(XFormTest, verifyBackfaceVisibilityForPerspective) {
|
| + Transform layer_space_to_projection_plane;
|
| +
|
| + // This tests if IsBackFaceVisible works properly under perspective
|
| + // transforms. Specifically, layers that may have their back face visible in
|
| + // orthographic projection, may not actually have back face visible under
|
| + // perspective projection.
|
| +
|
| + // Case 1: Layer is rotated by slightly more than 90 degrees, at the center
|
| + // of the prespective projection. In this case, the layer's back-side
|
| + // is visible to the camera.
|
| + layer_space_to_projection_plane.MakeIdentity();
|
| + layer_space_to_projection_plane.ApplyPerspectiveDepth(1.0);
|
| + layer_space_to_projection_plane.Translate3d(0.0, 0.0, 0.0);
|
| + layer_space_to_projection_plane.RotateAboutYAxis(100.0);
|
| + EXPECT_TRUE(layer_space_to_projection_plane.IsBackFaceVisible());
|
| +
|
| + // Case 2: Layer is rotated by slightly more than 90 degrees, but shifted off
|
| + // to the side of the camera. Because of the wide field-of-view, the
|
| + // layer's front side is still visible.
|
| + //
|
| + // |<-- front side of layer is visible to camera
|
| + // \ | /
|
| + // \ | /
|
| + // \| /
|
| + // | /
|
| + // |\ /<-- camera field of view
|
| + // | \ /
|
| + // back side of layer -->| \ /
|
| + // \./ <-- camera origin
|
| + //
|
| + layer_space_to_projection_plane.MakeIdentity();
|
| + layer_space_to_projection_plane.ApplyPerspectiveDepth(1.0);
|
| + layer_space_to_projection_plane.Translate3d(-10.0, 0.0, 0.0);
|
| + layer_space_to_projection_plane.RotateAboutYAxis(100.0);
|
| + EXPECT_FALSE(layer_space_to_projection_plane.IsBackFaceVisible());
|
| +
|
| + // Case 3: Additionally rotating the layer by 180 degrees should of course
|
| + // show the opposite result of case 2.
|
| + layer_space_to_projection_plane.RotateAboutYAxis(180.0);
|
| + EXPECT_TRUE(layer_space_to_projection_plane.IsBackFaceVisible());
|
| +}
|
| +
|
| +TEST(XFormTest, verifyDefaultConstructorCreatesIdentityMatrix) {
|
| + Transform A;
|
| + EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| + EXPECT_TRUE(A.IsIdentity());
|
| +}
|
| +
|
| +TEST(XFormTest, verifyCopyConstructor) {
|
| + Transform A;
|
| + InitializeTestMatrix(&A);
|
| +
|
| + // Copy constructor should produce exact same elements as matrix A.
|
| + Transform B(A);
|
| + EXPECT_ROW1_EQ(10.0f, 14.0f, 18.0f, 22.0f, B);
|
| + EXPECT_ROW2_EQ(11.0f, 15.0f, 19.0f, 23.0f, B);
|
| + EXPECT_ROW3_EQ(12.0f, 16.0f, 20.0f, 24.0f, B);
|
| + EXPECT_ROW4_EQ(13.0f, 17.0f, 21.0f, 25.0f, B);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyConstructorFor16Elements) {
|
| + Transform transform(1.0, 2.0, 3.0, 4.0,
|
| + 5.0, 6.0, 7.0, 8.0,
|
| + 9.0, 10.0, 11.0, 12.0,
|
| + 13.0, 14.0, 15.0, 16.0);
|
| +
|
| + EXPECT_ROW1_EQ(1.0f, 2.0f, 3.0f, 4.0f, transform);
|
| + EXPECT_ROW2_EQ(5.0f, 6.0f, 7.0f, 8.0f, transform);
|
| + EXPECT_ROW3_EQ(9.0f, 10.0f, 11.0f, 12.0f, transform);
|
| + EXPECT_ROW4_EQ(13.0f, 14.0f, 15.0f, 16.0f, transform);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyConstructorFor2dElements) {
|
| + Transform transform(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
|
| +
|
| + EXPECT_ROW1_EQ(1.0f, 2.0f, 0.0f, 5.0f, transform);
|
| + EXPECT_ROW2_EQ(3.0f, 4.0f, 0.0f, 6.0f, transform);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, transform);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, transform);
|
| +}
|
| +
|
| +
|
| +TEST(XFormTest, verifyAssignmentOperator) {
|
| + Transform A;
|
| + InitializeTestMatrix(&A);
|
| + Transform B;
|
| + InitializeTestMatrix2(&B);
|
| + Transform C;
|
| + InitializeTestMatrix2(&C);
|
| + C = B = A;
|
| +
|
| + // Both B and C should now have been re-assigned to the value of A.
|
| + EXPECT_ROW1_EQ(10.0f, 14.0f, 18.0f, 22.0f, B);
|
| + EXPECT_ROW2_EQ(11.0f, 15.0f, 19.0f, 23.0f, B);
|
| + EXPECT_ROW3_EQ(12.0f, 16.0f, 20.0f, 24.0f, B);
|
| + EXPECT_ROW4_EQ(13.0f, 17.0f, 21.0f, 25.0f, B);
|
| +
|
| + EXPECT_ROW1_EQ(10.0f, 14.0f, 18.0f, 22.0f, C);
|
| + EXPECT_ROW2_EQ(11.0f, 15.0f, 19.0f, 23.0f, C);
|
| + EXPECT_ROW3_EQ(12.0f, 16.0f, 20.0f, 24.0f, C);
|
| + EXPECT_ROW4_EQ(13.0f, 17.0f, 21.0f, 25.0f, C);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyEqualsBooleanOperator) {
|
| + Transform A;
|
| + InitializeTestMatrix(&A);
|
| +
|
| + Transform B;
|
| + InitializeTestMatrix(&B);
|
| + EXPECT_TRUE(A == B);
|
| +
|
| + // Modifying multiple elements should cause equals operator to return false.
|
| + Transform C;
|
| + InitializeTestMatrix2(&C);
|
| + EXPECT_FALSE(A == C);
|
| +
|
| + // Modifying any one individual element should cause equals operator to
|
| + // return false.
|
| + Transform D;
|
| + D = A;
|
| + D.matrix().setDouble(0, 0, 0.0);
|
| + EXPECT_FALSE(A == D);
|
| +
|
| + D = A;
|
| + D.matrix().setDouble(1, 0, 0.0);
|
| + EXPECT_FALSE(A == D);
|
| +
|
| + D = A;
|
| + D.matrix().setDouble(2, 0, 0.0);
|
| + EXPECT_FALSE(A == D);
|
| +
|
| + D = A;
|
| + D.matrix().setDouble(3, 0, 0.0);
|
| + EXPECT_FALSE(A == D);
|
| +
|
| + D = A;
|
| + D.matrix().setDouble(0, 1, 0.0);
|
| + EXPECT_FALSE(A == D);
|
| +
|
| + D = A;
|
| + D.matrix().setDouble(1, 1, 0.0);
|
| + EXPECT_FALSE(A == D);
|
| +
|
| + D = A;
|
| + D.matrix().setDouble(2, 1, 0.0);
|
| + EXPECT_FALSE(A == D);
|
| +
|
| + D = A;
|
| + D.matrix().setDouble(3, 1, 0.0);
|
| + EXPECT_FALSE(A == D);
|
| +
|
| + D = A;
|
| + D.matrix().setDouble(0, 2, 0.0);
|
| + EXPECT_FALSE(A == D);
|
| +
|
| + D = A;
|
| + D.matrix().setDouble(1, 2, 0.0);
|
| + EXPECT_FALSE(A == D);
|
| +
|
| + D = A;
|
| + D.matrix().setDouble(2, 2, 0.0);
|
| + EXPECT_FALSE(A == D);
|
| +
|
| + D = A;
|
| + D.matrix().setDouble(3, 2, 0.0);
|
| + EXPECT_FALSE(A == D);
|
| +
|
| + D = A;
|
| + D.matrix().setDouble(0, 3, 0.0);
|
| + EXPECT_FALSE(A == D);
|
| +
|
| + D = A;
|
| + D.matrix().setDouble(1, 3, 0.0);
|
| + EXPECT_FALSE(A == D);
|
| +
|
| + D = A;
|
| + D.matrix().setDouble(2, 3, 0.0);
|
| + EXPECT_FALSE(A == D);
|
| +
|
| + D = A;
|
| + D.matrix().setDouble(3, 3, 0.0);
|
| + EXPECT_FALSE(A == D);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyMultiplyOperator) {
|
| + Transform A;
|
| + InitializeTestMatrix(&A);
|
| +
|
| + Transform B;
|
| + InitializeTestMatrix2(&B);
|
| +
|
| + Transform C = A * B;
|
| + EXPECT_ROW1_EQ(2036.0f, 2292.0f, 2548.0f, 2804.0f, C);
|
| + EXPECT_ROW2_EQ(2162.0f, 2434.0f, 2706.0f, 2978.0f, C);
|
| + EXPECT_ROW3_EQ(2288.0f, 2576.0f, 2864.0f, 3152.0f, C);
|
| + EXPECT_ROW4_EQ(2414.0f, 2718.0f, 3022.0f, 3326.0f, C);
|
| +
|
| + // Just an additional sanity check; matrix multiplication is not commutative.
|
| + EXPECT_FALSE(A * B == B * A);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyMultiplyAndAssignOperator) {
|
| + Transform A;
|
| + InitializeTestMatrix(&A);
|
| +
|
| + Transform B;
|
| + InitializeTestMatrix2(&B);
|
| +
|
| + A *= B;
|
| + EXPECT_ROW1_EQ(2036.0f, 2292.0f, 2548.0f, 2804.0f, A);
|
| + EXPECT_ROW2_EQ(2162.0f, 2434.0f, 2706.0f, 2978.0f, A);
|
| + EXPECT_ROW3_EQ(2288.0f, 2576.0f, 2864.0f, 3152.0f, A);
|
| + EXPECT_ROW4_EQ(2414.0f, 2718.0f, 3022.0f, 3326.0f, A);
|
| +
|
| + // Just an additional sanity check; matrix multiplication is not commutative.
|
| + Transform C = A;
|
| + C *= B;
|
| + Transform D = B;
|
| + D *= A;
|
| + EXPECT_FALSE(C == D);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyMatrixMultiplication) {
|
| + Transform A;
|
| + InitializeTestMatrix(&A);
|
| +
|
| + Transform B;
|
| + InitializeTestMatrix2(&B);
|
| +
|
| + A.PreconcatTransform(B);
|
| + EXPECT_ROW1_EQ(2036.0f, 2292.0f, 2548.0f, 2804.0f, A);
|
| + EXPECT_ROW2_EQ(2162.0f, 2434.0f, 2706.0f, 2978.0f, A);
|
| + EXPECT_ROW3_EQ(2288.0f, 2576.0f, 2864.0f, 3152.0f, A);
|
| + EXPECT_ROW4_EQ(2414.0f, 2718.0f, 3022.0f, 3326.0f, A);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyMakeIdentiy) {
|
| + Transform A;
|
| + InitializeTestMatrix(&A);
|
| + A.MakeIdentity();
|
| + EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| + EXPECT_TRUE(A.IsIdentity());
|
| +}
|
| +
|
| +TEST(XFormTest, verifyTranslate) {
|
| + Transform A;
|
| + A.Translate(2.0, 3.0);
|
| + EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 2.0f, A);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 3.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +
|
| + // Verify that Translate() post-multiplies the existing matrix.
|
| + A.MakeIdentity();
|
| + A.Scale(5.0, 5.0);
|
| + A.Translate(2.0, 3.0);
|
| + EXPECT_ROW1_EQ(5.0f, 0.0f, 0.0f, 10.0f, A);
|
| + EXPECT_ROW2_EQ(0.0f, 5.0f, 0.0f, 15.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyTranslate3d) {
|
| + Transform A;
|
| + A.Translate3d(2.0, 3.0, 4.0);
|
| + EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 2.0f, A);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 3.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 4.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +
|
| + // Verify that Translate3d() post-multiplies the existing matrix.
|
| + A.MakeIdentity();
|
| + A.Scale3d(6.0, 7.0, 8.0);
|
| + A.Translate3d(2.0, 3.0, 4.0);
|
| + EXPECT_ROW1_EQ(6.0f, 0.0f, 0.0f, 12.0f, A);
|
| + EXPECT_ROW2_EQ(0.0f, 7.0f, 0.0f, 21.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 32.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyScale) {
|
| + Transform A;
|
| + A.Scale(6.0, 7.0);
|
| + EXPECT_ROW1_EQ(6.0f, 0.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW2_EQ(0.0f, 7.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +
|
| + // Verify that Scale() post-multiplies the existing matrix.
|
| + A.MakeIdentity();
|
| + A.Translate3d(2.0, 3.0, 4.0);
|
| + A.Scale(6.0, 7.0);
|
| + EXPECT_ROW1_EQ(6.0f, 0.0f, 0.0f, 2.0f, A);
|
| + EXPECT_ROW2_EQ(0.0f, 7.0f, 0.0f, 3.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 4.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyScale3d) {
|
| + Transform A;
|
| + A.Scale3d(6.0, 7.0, 8.0);
|
| + EXPECT_ROW1_EQ(6.0f, 0.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW2_EQ(0.0f, 7.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +
|
| + // Verify that scale3d() post-multiplies the existing matrix.
|
| + A.MakeIdentity();
|
| + A.Translate3d(2.0, 3.0, 4.0);
|
| + A.Scale3d(6.0, 7.0, 8.0);
|
| + EXPECT_ROW1_EQ(6.0f, 0.0f, 0.0f, 2.0f, A);
|
| + EXPECT_ROW2_EQ(0.0f, 7.0f, 0.0f, 3.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 4.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyRotate) {
|
| + Transform A;
|
| + A.Rotate(90.0);
|
| + EXPECT_ROW1_NEAR(0.0, -1.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(1.0, 0.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +
|
| + // Verify that Rotate() post-multiplies the existing matrix.
|
| + A.MakeIdentity();
|
| + A.Scale3d(6.0, 7.0, 8.0);
|
| + A.Rotate(90.0);
|
| + EXPECT_ROW1_NEAR(0.0, -6.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(7.0, 0.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyRotateAboutXAxis) {
|
| + Transform A;
|
| + double sin45 = 0.5 * sqrt(2.0);
|
| + double cos45 = sin45;
|
| +
|
| + A.MakeIdentity();
|
| + A.RotateAboutXAxis(90.0);
|
| + EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW2_NEAR(0.0, 0.0, -1.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW3_NEAR(0.0, 1.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +
|
| + A.MakeIdentity();
|
| + A.RotateAboutXAxis(45.0);
|
| + EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW2_NEAR(0.0, cos45, -sin45, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW3_NEAR(0.0, sin45, cos45, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +
|
| + // Verify that RotateAboutXAxis(angle) post-multiplies the existing matrix.
|
| + A.MakeIdentity();
|
| + A.Scale3d(6.0, 7.0, 8.0);
|
| + A.RotateAboutXAxis(90.0);
|
| + EXPECT_ROW1_NEAR(6.0, 0.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(0.0, 0.0, -7.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW3_NEAR(0.0, 8.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyRotateAboutYAxis) {
|
| + Transform A;
|
| + double sin45 = 0.5 * sqrt(2.0);
|
| + double cos45 = sin45;
|
| +
|
| + // Note carefully, the expected pattern is inverted compared to rotating
|
| + // about x axis or z axis.
|
| + A.MakeIdentity();
|
| + A.RotateAboutYAxis(90.0);
|
| + EXPECT_ROW1_NEAR(0.0, 0.0, 1.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW3_NEAR(-1.0, 0.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +
|
| + A.MakeIdentity();
|
| + A.RotateAboutYAxis(45.0);
|
| + EXPECT_ROW1_NEAR(cos45, 0.0, sin45, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW3_NEAR(-sin45, 0.0, cos45, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +
|
| + // Verify that RotateAboutYAxis(angle) post-multiplies the existing matrix.
|
| + A.MakeIdentity();
|
| + A.Scale3d(6.0, 7.0, 8.0);
|
| + A.RotateAboutYAxis(90.0);
|
| + EXPECT_ROW1_NEAR(0.0, 0.0, 6.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(0.0, 7.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW3_NEAR(-8.0, 0.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyRotateAboutZAxis) {
|
| + Transform A;
|
| + double sin45 = 0.5 * sqrt(2.0);
|
| + double cos45 = sin45;
|
| +
|
| + A.MakeIdentity();
|
| + A.RotateAboutZAxis(90.0);
|
| + EXPECT_ROW1_NEAR(0.0, -1.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(1.0, 0.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +
|
| + A.MakeIdentity();
|
| + A.RotateAboutZAxis(45.0);
|
| + EXPECT_ROW1_NEAR(cos45, -sin45, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(sin45, cos45, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +
|
| + // Verify that RotateAboutZAxis(angle) post-multiplies the existing matrix.
|
| + A.MakeIdentity();
|
| + A.Scale3d(6.0, 7.0, 8.0);
|
| + A.RotateAboutZAxis(90.0);
|
| + EXPECT_ROW1_NEAR(0.0, -6.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(7.0, 0.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyRotateAboutForAlignedAxes) {
|
| + Transform A;
|
| +
|
| + // Check rotation about z-axis
|
| + A.MakeIdentity();
|
| + A.RotateAbout(Vector3dF(0.0, 0.0, 1.0), 90.0);
|
| + EXPECT_ROW1_NEAR(0.0, -1.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(1.0, 0.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +
|
| + // Check rotation about x-axis
|
| + A.MakeIdentity();
|
| + A.RotateAbout(Vector3dF(1.0, 0.0, 0.0), 90.0);
|
| + EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW2_NEAR(0.0, 0.0, -1.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW3_NEAR(0.0, 1.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +
|
| + // Check rotation about y-axis. Note carefully, the expected pattern is
|
| + // inverted compared to rotating about x axis or z axis.
|
| + A.MakeIdentity();
|
| + A.RotateAbout(Vector3dF(0.0, 1.0, 0.0), 90.0);
|
| + EXPECT_ROW1_NEAR(0.0, 0.0, 1.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW3_NEAR(-1.0, 0.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +
|
| + // Verify that rotate3d(axis, angle) post-multiplies the existing matrix.
|
| + A.MakeIdentity();
|
| + A.Scale3d(6.0, 7.0, 8.0);
|
| + A.RotateAboutZAxis(90.0);
|
| + EXPECT_ROW1_NEAR(0.0, -6.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(7.0, 0.0, 0.0, 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyRotateAboutForArbitraryAxis) {
|
| + // Check rotation about an arbitrary non-axis-aligned vector.
|
| + Transform A;
|
| + A.RotateAbout(Vector3dF(1.0, 1.0, 1.0), 90.0);
|
| + EXPECT_ROW1_NEAR(0.3333333333333334258519187,
|
| + -0.2440169358562924717404030,
|
| + 0.9106836025229592124219380,
|
| + 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW2_NEAR(0.9106836025229592124219380,
|
| + 0.3333333333333334258519187,
|
| + -0.2440169358562924717404030,
|
| + 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW3_NEAR(-0.2440169358562924717404030,
|
| + 0.9106836025229592124219380,
|
| + 0.3333333333333334258519187,
|
| + 0.0, A, ERROR_THRESHOLD);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyRotateAboutForDegenerateAxis) {
|
| + // Check rotation about a degenerate zero vector.
|
| + // It is expected to skip applying the rotation.
|
| + Transform A;
|
| +
|
| + A.RotateAbout(Vector3dF(0.0, 0.0, 0.0), 45.0);
|
| + // Verify that A remains unchanged.
|
| + EXPECT_TRUE(A.IsIdentity());
|
| +
|
| + InitializeTestMatrix(&A);
|
| + A.RotateAbout(Vector3dF(0.0, 0.0, 0.0), 35.0);
|
| +
|
| + // Verify that A remains unchanged.
|
| + EXPECT_ROW1_EQ(10.0f, 14.0f, 18.0f, 22.0f, A);
|
| + EXPECT_ROW2_EQ(11.0f, 15.0f, 19.0f, 23.0f, A);
|
| + EXPECT_ROW3_EQ(12.0f, 16.0f, 20.0f, 24.0f, A);
|
| + EXPECT_ROW4_EQ(13.0f, 17.0f, 21.0f, 25.0f, A);
|
| +}
|
| +
|
| +TEST(XFormTest, verifySkewX) {
|
| + Transform A;
|
| + A.SkewX(45.0);
|
| + EXPECT_ROW1_EQ(1.0f, 1.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +
|
| + // Verify that skewX() post-multiplies the existing matrix. Row 1, column 2,
|
| + // would incorrectly have value "7" if the matrix is pre-multiplied instead
|
| + // of post-multiplied.
|
| + A.MakeIdentity();
|
| + A.Scale3d(6.0, 7.0, 8.0);
|
| + A.SkewX(45.0);
|
| + EXPECT_ROW1_EQ(6.0f, 6.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW2_EQ(0.0f, 7.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +}
|
| +
|
| +TEST(XFormTest, verifySkewY) {
|
| + Transform A;
|
| + A.SkewY(45.0);
|
| + EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW2_EQ(1.0f, 1.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +
|
| + // Verify that skewY() post-multiplies the existing matrix. Row 2, column 1 ,
|
| + // would incorrectly have value "6" if the matrix is pre-multiplied instead
|
| + // of post-multiplied.
|
| + A.MakeIdentity();
|
| + A.Scale3d(6.0, 7.0, 8.0);
|
| + A.SkewY(45.0);
|
| + EXPECT_ROW1_EQ(6.0f, 0.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW2_EQ(7.0f, 7.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 8.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, 0.0f, 1.0f, A);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyPerspectiveDepth) {
|
| + Transform A;
|
| + A.ApplyPerspectiveDepth(1.0);
|
| + EXPECT_ROW1_EQ(1.0f, 0.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, 0.0f, 0.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, -1.0f, 1.0f, A);
|
| +
|
| + // Verify that PerspectiveDepth() post-multiplies the existing matrix.
|
| + A.MakeIdentity();
|
| + A.Translate3d(2.0, 3.0, 4.0);
|
| + A.ApplyPerspectiveDepth(1.0);
|
| + EXPECT_ROW1_EQ(1.0f, 0.0f, -2.0f, 2.0f, A);
|
| + EXPECT_ROW2_EQ(0.0f, 1.0f, -3.0f, 3.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, -3.0f, 4.0f, A);
|
| + EXPECT_ROW4_EQ(0.0f, 0.0f, -1.0f, 1.0f, A);
|
| +}
|
| +
|
| +TEST(XFormTest, verifyHasPerspective) {
|
| + Transform A;
|
| + A.ApplyPerspectiveDepth(1.0);
|
| + EXPECT_TRUE(A.HasPerspective());
|
| +
|
| + A.MakeIdentity();
|
| + A.ApplyPerspectiveDepth(0.0);
|
| + EXPECT_FALSE(A.HasPerspective());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 0, -1.0);
|
| + EXPECT_TRUE(A.HasPerspective());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 1, -1.0);
|
| + EXPECT_TRUE(A.HasPerspective());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 2, -0.3);
|
| + EXPECT_TRUE(A.HasPerspective());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 3, 0.5);
|
| + EXPECT_TRUE(A.HasPerspective());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 3, 0.0);
|
| + EXPECT_TRUE(A.HasPerspective());
|
| +}
|
| +
|
| +TEST(XFormTest, verifyIsInvertible) {
|
| + Transform A;
|
| +
|
| + // Translations, rotations, scales, skews and arbitrary combinations of them
|
| + // are invertible.
|
| + A.MakeIdentity();
|
| + EXPECT_TRUE(A.IsInvertible());
|
| +
|
| + A.MakeIdentity();
|
| + A.Translate3d(2.0, 3.0, 4.0);
|
| + EXPECT_TRUE(A.IsInvertible());
|
| +
|
| + A.MakeIdentity();
|
| + A.Scale3d(6.0, 7.0, 8.0);
|
| + EXPECT_TRUE(A.IsInvertible());
|
| +
|
| + A.MakeIdentity();
|
| + A.RotateAboutXAxis(10.0);
|
| + A.RotateAboutYAxis(20.0);
|
| + A.RotateAboutZAxis(30.0);
|
| + EXPECT_TRUE(A.IsInvertible());
|
| +
|
| + A.MakeIdentity();
|
| + A.SkewX(45.0);
|
| + EXPECT_TRUE(A.IsInvertible());
|
| +
|
| + // A perspective matrix (projection plane at z=0) is invertible. The
|
| + // intuitive explanation is that perspective is eqivalent to a skew of the
|
| + // w-axis; skews are invertible.
|
| + A.MakeIdentity();
|
| + A.ApplyPerspectiveDepth(1.0);
|
| + EXPECT_TRUE(A.IsInvertible());
|
| +
|
| + // A "pure" perspective matrix derived by similar triangles, with m44() set
|
| + // to zero (i.e. camera positioned at the origin), is not invertible.
|
| + A.MakeIdentity();
|
| + A.ApplyPerspectiveDepth(1.0);
|
| + A.matrix().setDouble(3, 3, 0.0);
|
| + EXPECT_FALSE(A.IsInvertible());
|
| +
|
| + // Adding more to a non-invertible matrix will not make it invertible in the
|
| + // general case.
|
| + A.MakeIdentity();
|
| + A.ApplyPerspectiveDepth(1.0);
|
| + A.matrix().setDouble(3, 3, 0.0);
|
| + A.Scale3d(6.0, 7.0, 8.0);
|
| + A.RotateAboutXAxis(10.0);
|
| + A.RotateAboutYAxis(20.0);
|
| + A.RotateAboutZAxis(30.0);
|
| + A.Translate3d(6.0, 7.0, 8.0);
|
| + EXPECT_FALSE(A.IsInvertible());
|
| +
|
| + // A degenerate matrix of all zeros is not invertible.
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(0, 0, 0.0);
|
| + A.matrix().setDouble(1, 1, 0.0);
|
| + A.matrix().setDouble(2, 2, 0.0);
|
| + A.matrix().setDouble(3, 3, 0.0);
|
| + EXPECT_FALSE(A.IsInvertible());
|
| +}
|
| +
|
| +TEST(XFormTest, verifyIsIdentity) {
|
| + Transform A;
|
| +
|
| + InitializeTestMatrix(&A);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +
|
| + A.MakeIdentity();
|
| + EXPECT_TRUE(A.IsIdentity());
|
| +
|
| + // Modifying any one individual element should cause the matrix to no longer
|
| + // be identity.
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(0, 0, 2.0);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(1, 0, 2.0);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(2, 0, 2.0);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 0, 2.0);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(0, 1, 2.0);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(1, 1, 2.0);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(2, 1, 2.0);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 1, 2.0);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(0, 2, 2.0);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(1, 2, 2.0);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(2, 2, 2.0);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 2, 2.0);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(0, 3, 2.0);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(1, 3, 2.0);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(2, 3, 2.0);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 3, 2.0);
|
| + EXPECT_FALSE(A.IsIdentity());
|
| +}
|
| +
|
| +TEST(XFormTest, verifyIsIdentityOrTranslation) {
|
| + Transform A;
|
| +
|
| + InitializeTestMatrix(&A);
|
| + EXPECT_FALSE(A.IsIdentityOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + EXPECT_TRUE(A.IsIdentityOrTranslation());
|
| +
|
| + // Modifying any non-translation components should cause
|
| + // IsIdentityOrTranslation() to return false. NOTE: (0, 3), (1, 3), and
|
| + // (2, 3) are the translation components, so modifying them should still
|
| + // return true.
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(0, 0, 2.0);
|
| + EXPECT_FALSE(A.IsIdentityOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(1, 0, 2.0);
|
| + EXPECT_FALSE(A.IsIdentityOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(2, 0, 2.0);
|
| + EXPECT_FALSE(A.IsIdentityOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 0, 2.0);
|
| + EXPECT_FALSE(A.IsIdentityOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(0, 1, 2.0);
|
| + EXPECT_FALSE(A.IsIdentityOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(1, 1, 2.0);
|
| + EXPECT_FALSE(A.IsIdentityOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(2, 1, 2.0);
|
| + EXPECT_FALSE(A.IsIdentityOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 1, 2.0);
|
| + EXPECT_FALSE(A.IsIdentityOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(0, 2, 2.0);
|
| + EXPECT_FALSE(A.IsIdentityOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(1, 2, 2.0);
|
| + EXPECT_FALSE(A.IsIdentityOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(2, 2, 2.0);
|
| + EXPECT_FALSE(A.IsIdentityOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 2, 2.0);
|
| + EXPECT_FALSE(A.IsIdentityOrTranslation());
|
| +
|
| + // Note carefully - expecting true here.
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(0, 3, 2.0);
|
| + EXPECT_TRUE(A.IsIdentityOrTranslation());
|
| +
|
| + // Note carefully - expecting true here.
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(1, 3, 2.0);
|
| + EXPECT_TRUE(A.IsIdentityOrTranslation());
|
| +
|
| + // Note carefully - expecting true here.
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(2, 3, 2.0);
|
| + EXPECT_TRUE(A.IsIdentityOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 3, 2.0);
|
| + EXPECT_FALSE(A.IsIdentityOrTranslation());
|
| +}
|
| +
|
| +TEST(XFormTest, verifyIsScaleOrTranslation) {
|
| + Transform A;
|
| +
|
| + InitializeTestMatrix(&A);
|
| + EXPECT_FALSE(A.IsScaleOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + EXPECT_TRUE(A.IsScaleOrTranslation());
|
| +
|
| + // Modifying any non-scale or non-translation components should cause
|
| + // IsScaleOrTranslation() to return false. (0, 0), (1, 1), (2, 2), (0, 3),
|
| + // (1, 3), and (2, 3) are the scale and translation components, so
|
| + // modifying them should still return true.
|
| +
|
| + // Note carefully - expecting true here.
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(0, 0, 2.0);
|
| + EXPECT_TRUE(A.IsScaleOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(1, 0, 2.0);
|
| + EXPECT_FALSE(A.IsScaleOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(2, 0, 2.0);
|
| + EXPECT_FALSE(A.IsScaleOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 0, 2.0);
|
| + EXPECT_FALSE(A.IsScaleOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(0, 1, 2.0);
|
| + EXPECT_FALSE(A.IsScaleOrTranslation());
|
| +
|
| + // Note carefully - expecting true here.
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(1, 1, 2.0);
|
| + EXPECT_TRUE(A.IsScaleOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(2, 1, 2.0);
|
| + EXPECT_FALSE(A.IsScaleOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 1, 2.0);
|
| + EXPECT_FALSE(A.IsScaleOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(0, 2, 2.0);
|
| + EXPECT_FALSE(A.IsScaleOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(1, 2, 2.0);
|
| + EXPECT_FALSE(A.IsScaleOrTranslation());
|
| +
|
| + // Note carefully - expecting true here.
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(2, 2, 2.0);
|
| + EXPECT_TRUE(A.IsScaleOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 2, 2.0);
|
| + EXPECT_FALSE(A.IsScaleOrTranslation());
|
| +
|
| + // Note carefully - expecting true here.
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(0, 3, 2.0);
|
| + EXPECT_TRUE(A.IsScaleOrTranslation());
|
| +
|
| + // Note carefully - expecting true here.
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(1, 3, 2.0);
|
| + EXPECT_TRUE(A.IsScaleOrTranslation());
|
| +
|
| + // Note carefully - expecting true here.
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(2, 3, 2.0);
|
| + EXPECT_TRUE(A.IsScaleOrTranslation());
|
| +
|
| + A.MakeIdentity();
|
| + A.matrix().setDouble(3, 3, 2.0);
|
| + EXPECT_FALSE(A.IsScaleOrTranslation());
|
| +}
|
| +
|
| +TEST(XFormTest, verifyFlattenTo2d) {
|
| + Transform A;
|
| + InitializeTestMatrix(&A);
|
| +
|
| + A.FlattenTo2d();
|
| + EXPECT_ROW1_EQ(10.0f, 14.0f, 0.0f, 22.0f, A);
|
| + EXPECT_ROW2_EQ(11.0f, 15.0f, 0.0f, 23.0f, A);
|
| + EXPECT_ROW3_EQ(0.0f, 0.0f, 1.0f, 0.0f, A);
|
| + EXPECT_ROW4_EQ(13.0f, 17.0f, 0.0f, 25.0f, A);
|
| +}
|
| +
|
| } // namespace
|
|
|
| } // namespace gfx
|
|
|