| OLD | NEW |
| (Empty) |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "config.h" | |
| 6 | |
| 7 #include "CCMathUtil.h" | |
| 8 | |
| 9 #include "CCGeometryTestUtils.h" | |
| 10 #include "FloatRect.h" | |
| 11 #include "testing/gmock/include/gmock/gmock.h" | |
| 12 #include "testing/gtest/include/gtest/gtest.h" | |
| 13 #include <public/WebTransformationMatrix.h> | |
| 14 | |
| 15 using namespace cc; | |
| 16 using WebKit::WebTransformationMatrix; | |
| 17 | |
| 18 namespace { | |
| 19 | |
| 20 TEST(CCMathUtilTest, verifyBackfaceVisibilityBasicCases) | |
| 21 { | |
| 22 WebTransformationMatrix transform; | |
| 23 | |
| 24 transform.makeIdentity(); | |
| 25 EXPECT_FALSE(transform.isBackFaceVisible()); | |
| 26 | |
| 27 transform.makeIdentity(); | |
| 28 transform.rotate3d(0, 80, 0); | |
| 29 EXPECT_FALSE(transform.isBackFaceVisible()); | |
| 30 | |
| 31 transform.makeIdentity(); | |
| 32 transform.rotate3d(0, 100, 0); | |
| 33 EXPECT_TRUE(transform.isBackFaceVisible()); | |
| 34 | |
| 35 // Edge case, 90 degree rotation should return false. | |
| 36 transform.makeIdentity(); | |
| 37 transform.rotate3d(0, 90, 0); | |
| 38 EXPECT_FALSE(transform.isBackFaceVisible()); | |
| 39 } | |
| 40 | |
| 41 TEST(CCMathUtilTest, verifyBackfaceVisibilityForPerspective) | |
| 42 { | |
| 43 WebTransformationMatrix layerSpaceToProjectionPlane; | |
| 44 | |
| 45 // This tests if isBackFaceVisible works properly under perspective transfor
ms. | |
| 46 // Specifically, layers that may have their back face visible in orthographi
c | |
| 47 // projection, may not actually have back face visible under perspective pro
jection. | |
| 48 | |
| 49 // Case 1: Layer is rotated by slightly more than 90 degrees, at the center
of the | |
| 50 // prespective projection. In this case, the layer's back-side is vi
sible to | |
| 51 // the camera. | |
| 52 layerSpaceToProjectionPlane.makeIdentity(); | |
| 53 layerSpaceToProjectionPlane.applyPerspective(1); | |
| 54 layerSpaceToProjectionPlane.translate3d(0, 0, 0); | |
| 55 layerSpaceToProjectionPlane.rotate3d(0, 100, 0); | |
| 56 EXPECT_TRUE(layerSpaceToProjectionPlane.isBackFaceVisible()); | |
| 57 | |
| 58 // Case 2: Layer is rotated by slightly more than 90 degrees, but shifted of
f to the | |
| 59 // side of the camera. Because of the wide field-of-view, the layer'
s front | |
| 60 // side is still visible. | |
| 61 // | |
| 62 // |<-- front side of layer is visible to perspective
camera | |
| 63 // \ | / | |
| 64 // \ | / | |
| 65 // \| / | |
| 66 // | / | |
| 67 // |\ /<-- camera field of view | |
| 68 // | \ / | |
| 69 // back side of layer -->| \ / | |
| 70 // \./ <-- camera origin | |
| 71 // | |
| 72 layerSpaceToProjectionPlane.makeIdentity(); | |
| 73 layerSpaceToProjectionPlane.applyPerspective(1); | |
| 74 layerSpaceToProjectionPlane.translate3d(-10, 0, 0); | |
| 75 layerSpaceToProjectionPlane.rotate3d(0, 100, 0); | |
| 76 EXPECT_FALSE(layerSpaceToProjectionPlane.isBackFaceVisible()); | |
| 77 | |
| 78 // Case 3: Additionally rotating the layer by 180 degrees should of course s
how the | |
| 79 // opposite result of case 2. | |
| 80 layerSpaceToProjectionPlane.rotate3d(0, 180, 0); | |
| 81 EXPECT_TRUE(layerSpaceToProjectionPlane.isBackFaceVisible()); | |
| 82 } | |
| 83 | |
| 84 TEST(CCMathUtilTest, verifyProjectionOfPerpendicularPlane) | |
| 85 { | |
| 86 // In this case, the m33() element of the transform becomes zero, which coul
d cause a | |
| 87 // divide-by-zero when projecting points/quads. | |
| 88 | |
| 89 WebTransformationMatrix transform; | |
| 90 transform.makeIdentity(); | |
| 91 transform.setM33(0); | |
| 92 | |
| 93 FloatRect rect = FloatRect(0, 0, 1, 1); | |
| 94 FloatRect projectedRect = CCMathUtil::projectClippedRect(transform, rect); | |
| 95 | |
| 96 EXPECT_EQ(0, projectedRect.x()); | |
| 97 EXPECT_EQ(0, projectedRect.y()); | |
| 98 EXPECT_TRUE(projectedRect.isEmpty()); | |
| 99 } | |
| 100 | |
| 101 TEST(CCMathUtilTest, verifyEnclosingClippedRectUsesCorrectInitialBounds) | |
| 102 { | |
| 103 HomogeneousCoordinate h1(-100, -100, 0, 1); | |
| 104 HomogeneousCoordinate h2(-10, -10, 0, 1); | |
| 105 HomogeneousCoordinate h3(10, 10, 0, -1); | |
| 106 HomogeneousCoordinate h4(100, 100, 0, -1); | |
| 107 | |
| 108 // The bounds of the enclosing clipped rect should be -100 to -10 for both x
and y. | |
| 109 // However, if there is a bug where the initial xmin/xmax/ymin/ymax are init
ialized to | |
| 110 // numeric_limits<float>::min() (which is zero, not -flt_max) then the enclo
sing | |
| 111 // clipped rect will be computed incorrectly. | |
| 112 FloatRect result = CCMathUtil::computeEnclosingClippedRect(h1, h2, h3, h4); | |
| 113 | |
| 114 EXPECT_FLOAT_RECT_EQ(FloatRect(FloatPoint(-100, -100), FloatSize(90, 90)), r
esult); | |
| 115 } | |
| 116 | |
| 117 TEST(CCMathUtilTest, verifyEnclosingRectOfVerticesUsesCorrectInitialBounds) | |
| 118 { | |
| 119 FloatPoint vertices[3]; | |
| 120 int numVertices = 3; | |
| 121 | |
| 122 vertices[0] = FloatPoint(-10, -100); | |
| 123 vertices[1] = FloatPoint(-100, -10); | |
| 124 vertices[2] = FloatPoint(-30, -30); | |
| 125 | |
| 126 // The bounds of the enclosing rect should be -100 to -10 for both x and y.
However, | |
| 127 // if there is a bug where the initial xmin/xmax/ymin/ymax are initialized t
o | |
| 128 // numeric_limits<float>::min() (which is zero, not -flt_max) then the enclo
sing | |
| 129 // clipped rect will be computed incorrectly. | |
| 130 FloatRect result = CCMathUtil::computeEnclosingRectOfVertices(vertices, numV
ertices); | |
| 131 | |
| 132 EXPECT_FLOAT_RECT_EQ(FloatRect(FloatPoint(-100, -100), FloatSize(90, 90)), r
esult); | |
| 133 } | |
| 134 | |
| 135 TEST(CCMathUtilTest, smallestAngleBetweenVectors) | |
| 136 { | |
| 137 FloatSize x(1, 0); | |
| 138 FloatSize y(0, 1); | |
| 139 FloatSize testVector(0.5, 0.5); | |
| 140 | |
| 141 // Orthogonal vectors are at an angle of 90 degress. | |
| 142 EXPECT_EQ(90, CCMathUtil::smallestAngleBetweenVectors(x, y)); | |
| 143 | |
| 144 // A vector makes a zero angle with itself. | |
| 145 EXPECT_EQ(0, CCMathUtil::smallestAngleBetweenVectors(x, x)); | |
| 146 EXPECT_EQ(0, CCMathUtil::smallestAngleBetweenVectors(y, y)); | |
| 147 EXPECT_EQ(0, CCMathUtil::smallestAngleBetweenVectors(testVector, testVector)
); | |
| 148 | |
| 149 // Parallel but reversed vectors are at 180 degrees. | |
| 150 EXPECT_FLOAT_EQ(180, CCMathUtil::smallestAngleBetweenVectors(x, -x)); | |
| 151 EXPECT_FLOAT_EQ(180, CCMathUtil::smallestAngleBetweenVectors(y, -y)); | |
| 152 EXPECT_FLOAT_EQ(180, CCMathUtil::smallestAngleBetweenVectors(testVector, -te
stVector)); | |
| 153 | |
| 154 // The test vector is at a known angle. | |
| 155 EXPECT_FLOAT_EQ(45, floor(CCMathUtil::smallestAngleBetweenVectors(testVector
, x))); | |
| 156 EXPECT_FLOAT_EQ(45, floor(CCMathUtil::smallestAngleBetweenVectors(testVector
, y))); | |
| 157 } | |
| 158 | |
| 159 TEST(CCMathUtilTest, vectorProjection) | |
| 160 { | |
| 161 FloatSize x(1, 0); | |
| 162 FloatSize y(0, 1); | |
| 163 FloatSize testVector(0.3f, 0.7f); | |
| 164 | |
| 165 // Orthogonal vectors project to a zero vector. | |
| 166 EXPECT_EQ(FloatSize(0, 0), CCMathUtil::projectVector(x, y)); | |
| 167 EXPECT_EQ(FloatSize(0, 0), CCMathUtil::projectVector(y, x)); | |
| 168 | |
| 169 // Projecting a vector onto the orthonormal basis gives the corresponding co
mponent of the | |
| 170 // vector. | |
| 171 EXPECT_EQ(FloatSize(testVector.width(), 0), CCMathUtil::projectVector(testVe
ctor, x)); | |
| 172 EXPECT_EQ(FloatSize(0, testVector.height()), CCMathUtil::projectVector(testV
ector, y)); | |
| 173 | |
| 174 // Finally check than an arbitrary vector projected to another one gives a v
ector parallel to | |
| 175 // the second vector. | |
| 176 FloatSize targetVector(0.5, 0.2f); | |
| 177 FloatSize projectedVector = CCMathUtil::projectVector(testVector, targetVect
or); | |
| 178 EXPECT_EQ(projectedVector.width() / targetVector.width(), | |
| 179 projectedVector.height() / targetVector.height()); | |
| 180 } | |
| 181 | |
| 182 } // namespace | |
| OLD | NEW |