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 |