| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // MSVC++ requires this to be set before any other includes to get M_PI. | 5 // MSVC++ requires this to be set before any other includes to get M_PI. |
| 6 #define _USE_MATH_DEFINES | 6 #define _USE_MATH_DEFINES |
| 7 | 7 |
| 8 #include "ui/gfx/transform.h" | 8 #include "ui/gfx/transform.h" |
| 9 | 9 |
| 10 #include <cmath> | 10 #include <cmath> |
| 11 #include <ostream> | 11 #include <ostream> |
| 12 #include <limits> | 12 #include <limits> |
| 13 | 13 |
| 14 #include "base/basictypes.h" | 14 #include "base/basictypes.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 16 #include "ui/gfx/point.h" | 16 #include "ui/gfx/point.h" |
| 17 #include "ui/gfx/point3_f.h" | 17 #include "ui/gfx/point3_f.h" |
| 18 #include "ui/gfx/transform_util.h" | 18 #include "ui/gfx/transform_util.h" |
| 19 #include "ui/gfx/vector3d_f.h" |
| 19 | 20 |
| 20 namespace gfx { | 21 namespace gfx { |
| 21 | 22 |
| 22 namespace { | 23 namespace { |
| 23 | 24 |
| 24 bool PointsAreNearlyEqual(const Point3F& lhs, | 25 bool PointsAreNearlyEqual(const Point3F& lhs, |
| 25 const Point3F& rhs) { | 26 const Point3F& rhs) { |
| 26 float epsilon = 0.0001f; | 27 float epsilon = 0.0001f; |
| 27 return lhs.SquaredDistanceTo(rhs) < epsilon; | 28 return lhs.SquaredDistanceTo(rhs) < epsilon; |
| 28 } | 29 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 } | 110 } |
| 110 if (i == 100) { | 111 if (i == 100) { |
| 111 EXPECT_TRUE(rhs == interpolated); | 112 EXPECT_TRUE(rhs == interpolated); |
| 112 } else { | 113 } else { |
| 113 EXPECT_TRUE(rhs != interpolated); | 114 EXPECT_TRUE(rhs != interpolated); |
| 114 } | 115 } |
| 115 } | 116 } |
| 116 lhs = Transform(); | 117 lhs = Transform(); |
| 117 rhs = Transform(); | 118 rhs = Transform(); |
| 118 for (int i = 1; i < 100; ++i) { | 119 for (int i = 1; i < 100; ++i) { |
| 119 lhs.SetTranslate(i, i); | 120 lhs.MakeIdentity(); |
| 120 rhs.SetTranslate(-i, -i); | 121 rhs.MakeIdentity(); |
| 122 lhs.Translate(i, i); |
| 123 rhs.Translate(-i, -i); |
| 121 EXPECT_TRUE(lhs != rhs); | 124 EXPECT_TRUE(lhs != rhs); |
| 122 rhs.ConcatTranslate(2*i, 2*i); | 125 rhs.Translate(2*i, 2*i); |
| 123 EXPECT_TRUE(lhs == rhs); | 126 EXPECT_TRUE(lhs == rhs); |
| 124 } | 127 } |
| 125 } | 128 } |
| 126 | 129 |
| 127 TEST(XFormTest, ConcatTranslate) { | 130 TEST(XFormTest, ConcatTranslate) { |
| 128 static const struct TestCase { | 131 static const struct TestCase { |
| 129 int x1; | 132 int x1; |
| 130 int y1; | 133 int y1; |
| 131 float tx; | 134 float tx; |
| 132 float ty; | 135 float ty; |
| 133 int x2; | 136 int x2; |
| 134 int y2; | 137 int y2; |
| 135 } test_cases[] = { | 138 } test_cases[] = { |
| 136 { 0, 0, 10.0f, 20.0f, 10, 20 }, | 139 { 0, 0, 10.0f, 20.0f, 10, 20 }, |
| 137 { 0, 0, -10.0f, -20.0f, 0, 0 }, | 140 { 0, 0, -10.0f, -20.0f, 0, 0 }, |
| 138 { 0, 0, -10.0f, -20.0f, -10, -20 }, | 141 { 0, 0, -10.0f, -20.0f, -10, -20 }, |
| 139 { 0, 0, | 142 { 0, 0, |
| 140 std::numeric_limits<float>::quiet_NaN(), | 143 std::numeric_limits<float>::quiet_NaN(), |
| 141 std::numeric_limits<float>::quiet_NaN(), | 144 std::numeric_limits<float>::quiet_NaN(), |
| 142 10, 20 }, | 145 10, 20 }, |
| 143 }; | 146 }; |
| 144 | 147 |
| 145 Transform xform; | 148 Transform xform; |
| 146 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { | 149 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { |
| 147 const TestCase& value = test_cases[i]; | 150 const TestCase& value = test_cases[i]; |
| 148 xform.ConcatTranslate(value.tx, value.ty); | 151 Transform translation; |
| 152 translation.Translate(value.tx, value.ty); |
| 153 xform = translation * xform; |
| 149 Point3F p1(value.x1, value.y1, 0); | 154 Point3F p1(value.x1, value.y1, 0); |
| 150 Point3F p2(value.x2, value.y2, 0); | 155 Point3F p2(value.x2, value.y2, 0); |
| 151 xform.TransformPoint(p1); | 156 xform.TransformPoint(p1); |
| 152 if (value.tx == value.tx && | 157 if (value.tx == value.tx && |
| 153 value.ty == value.ty) { | 158 value.ty == value.ty) { |
| 154 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); | 159 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); |
| 155 } | 160 } |
| 156 } | 161 } |
| 157 } | 162 } |
| 158 | 163 |
| 159 TEST(XFormTest, ConcatScale) { | 164 TEST(XFormTest, ConcatScale) { |
| 160 static const struct TestCase { | 165 static const struct TestCase { |
| 161 int before; | 166 int before; |
| 162 float scale; | 167 float scale; |
| 163 int after; | 168 int after; |
| 164 } test_cases[] = { | 169 } test_cases[] = { |
| 165 { 1, 10.0f, 10 }, | 170 { 1, 10.0f, 10 }, |
| 166 { 1, .1f, 1 }, | 171 { 1, .1f, 1 }, |
| 167 { 1, 100.0f, 100 }, | 172 { 1, 100.0f, 100 }, |
| 168 { 1, -1.0f, -100 }, | 173 { 1, -1.0f, -100 }, |
| 169 { 1, std::numeric_limits<float>::quiet_NaN(), 1 } | 174 { 1, std::numeric_limits<float>::quiet_NaN(), 1 } |
| 170 }; | 175 }; |
| 171 | 176 |
| 172 Transform xform; | 177 Transform xform; |
| 173 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { | 178 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { |
| 174 const TestCase& value = test_cases[i]; | 179 const TestCase& value = test_cases[i]; |
| 175 xform.ConcatScale(value.scale, value.scale); | 180 Transform scale; |
| 181 scale.Scale(value.scale, value.scale); |
| 182 xform = scale * xform; |
| 176 Point3F p1(value.before, value.before, 0); | 183 Point3F p1(value.before, value.before, 0); |
| 177 Point3F p2(value.after, value.after, 0); | 184 Point3F p2(value.after, value.after, 0); |
| 178 xform.TransformPoint(p1); | 185 xform.TransformPoint(p1); |
| 179 if (value.scale == value.scale) { | 186 if (value.scale == value.scale) { |
| 180 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); | 187 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); |
| 181 } | 188 } |
| 182 } | 189 } |
| 183 } | 190 } |
| 184 | 191 |
| 185 TEST(XFormTest, ConcatRotate) { | 192 TEST(XFormTest, ConcatRotate) { |
| 186 static const struct TestCase { | 193 static const struct TestCase { |
| 187 int x1; | 194 int x1; |
| 188 int y1; | 195 int y1; |
| 189 float degrees; | 196 float degrees; |
| 190 int x2; | 197 int x2; |
| 191 int y2; | 198 int y2; |
| 192 } test_cases[] = { | 199 } test_cases[] = { |
| 193 { 1, 0, 90.0f, 0, 1 }, | 200 { 1, 0, 90.0f, 0, 1 }, |
| 194 { 1, 0, -90.0f, 1, 0 }, | 201 { 1, 0, -90.0f, 1, 0 }, |
| 195 { 1, 0, 90.0f, 0, 1 }, | 202 { 1, 0, 90.0f, 0, 1 }, |
| 196 { 1, 0, 360.0f, 0, 1 }, | 203 { 1, 0, 360.0f, 0, 1 }, |
| 197 { 1, 0, 0.0f, 0, 1 }, | 204 { 1, 0, 0.0f, 0, 1 }, |
| 198 { 1, 0, std::numeric_limits<float>::quiet_NaN(), 1, 0 } | 205 { 1, 0, std::numeric_limits<float>::quiet_NaN(), 1, 0 } |
| 199 }; | 206 }; |
| 200 | 207 |
| 201 Transform xform; | 208 Transform xform; |
| 202 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { | 209 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { |
| 203 const TestCase& value = test_cases[i]; | 210 const TestCase& value = test_cases[i]; |
| 204 xform.ConcatRotate(value.degrees); | 211 Transform rotation; |
| 212 rotation.Rotate(value.degrees); |
| 213 xform = rotation * xform; |
| 205 Point3F p1(value.x1, value.y1, 0); | 214 Point3F p1(value.x1, value.y1, 0); |
| 206 Point3F p2(value.x2, value.y2, 0); | 215 Point3F p2(value.x2, value.y2, 0); |
| 207 xform.TransformPoint(p1); | 216 xform.TransformPoint(p1); |
| 208 if (value.degrees == value.degrees) { | 217 if (value.degrees == value.degrees) { |
| 209 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); | 218 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); |
| 210 } | 219 } |
| 211 } | 220 } |
| 212 } | 221 } |
| 213 | 222 |
| 214 TEST(XFormTest, SetTranslate) { | 223 TEST(XFormTest, SetTranslate) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 228 | 237 |
| 229 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { | 238 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { |
| 230 const TestCase& value = test_cases[i]; | 239 const TestCase& value = test_cases[i]; |
| 231 for (int k = 0; k < 3; ++k) { | 240 for (int k = 0; k < 3; ++k) { |
| 232 Point3F p0, p1, p2; | 241 Point3F p0, p1, p2; |
| 233 Transform xform; | 242 Transform xform; |
| 234 switch (k) { | 243 switch (k) { |
| 235 case 0: | 244 case 0: |
| 236 p1.SetPoint(value.x1, 0, 0); | 245 p1.SetPoint(value.x1, 0, 0); |
| 237 p2.SetPoint(value.x2, 0, 0); | 246 p2.SetPoint(value.x2, 0, 0); |
| 238 xform.SetTranslateX(value.tx); | 247 xform.Translate(value.tx, 0.0); |
| 239 break; | 248 break; |
| 240 case 1: | 249 case 1: |
| 241 p1.SetPoint(0, value.y1, 0); | 250 p1.SetPoint(0, value.y1, 0); |
| 242 p2.SetPoint(0, value.y2, 0); | 251 p2.SetPoint(0, value.y2, 0); |
| 243 xform.SetTranslateY(value.ty); | 252 xform.Translate(0.0, value.ty); |
| 244 break; | 253 break; |
| 245 case 2: | 254 case 2: |
| 246 p1.SetPoint(value.x1, value.y1, 0); | 255 p1.SetPoint(value.x1, value.y1, 0); |
| 247 p2.SetPoint(value.x2, value.y2, 0); | 256 p2.SetPoint(value.x2, value.y2, 0); |
| 248 xform.SetTranslate(value.tx, value.ty); | 257 xform.Translate(value.tx, value.ty); |
| 249 break; | 258 break; |
| 250 } | 259 } |
| 251 p0 = p1; | 260 p0 = p1; |
| 252 xform.TransformPoint(p1); | 261 xform.TransformPoint(p1); |
| 253 if (value.tx == value.tx && | 262 if (value.tx == value.tx && |
| 254 value.ty == value.ty) { | 263 value.ty == value.ty) { |
| 255 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); | 264 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); |
| 256 xform.TransformPointReverse(p1); | 265 xform.TransformPointReverse(p1); |
| 257 EXPECT_TRUE(PointsAreNearlyEqual(p1, p0)); | 266 EXPECT_TRUE(PointsAreNearlyEqual(p1, p0)); |
| 258 } | 267 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 275 | 284 |
| 276 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { | 285 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { |
| 277 const TestCase& value = test_cases[i]; | 286 const TestCase& value = test_cases[i]; |
| 278 for (int k = 0; k < 3; ++k) { | 287 for (int k = 0; k < 3; ++k) { |
| 279 Point3F p0, p1, p2; | 288 Point3F p0, p1, p2; |
| 280 Transform xform; | 289 Transform xform; |
| 281 switch (k) { | 290 switch (k) { |
| 282 case 0: | 291 case 0: |
| 283 p1.SetPoint(value.before, 0, 0); | 292 p1.SetPoint(value.before, 0, 0); |
| 284 p2.SetPoint(value.after, 0, 0); | 293 p2.SetPoint(value.after, 0, 0); |
| 285 xform.SetScaleX(value.s); | 294 xform.Scale(value.s, 1.0); |
| 286 break; | 295 break; |
| 287 case 1: | 296 case 1: |
| 288 p1.SetPoint(0, value.before, 0); | 297 p1.SetPoint(0, value.before, 0); |
| 289 p2.SetPoint(0, value.after, 0); | 298 p2.SetPoint(0, value.after, 0); |
| 290 xform.SetScaleY(value.s); | 299 xform.Scale(1.0, value.s); |
| 291 break; | 300 break; |
| 292 case 2: | 301 case 2: |
| 293 p1.SetPoint(value.before, value.before, 0); | 302 p1.SetPoint(value.before, value.before, 0); |
| 294 p2.SetPoint(value.after, value.after, 0); | 303 p2.SetPoint(value.after, value.after, 0); |
| 295 xform.SetScale(value.s, value.s); | 304 xform.Scale(value.s, value.s); |
| 296 break; | 305 break; |
| 297 } | 306 } |
| 298 p0 = p1; | 307 p0 = p1; |
| 299 xform.TransformPoint(p1); | 308 xform.TransformPoint(p1); |
| 300 if (value.s == value.s) { | 309 if (value.s == value.s) { |
| 301 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); | 310 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); |
| 302 if (value.s != 0.0f) { | 311 if (value.s != 0.0f) { |
| 303 xform.TransformPointReverse(p1); | 312 xform.TransformPointReverse(p1); |
| 304 EXPECT_TRUE(PointsAreNearlyEqual(p1, p0)); | 313 EXPECT_TRUE(PointsAreNearlyEqual(p1, p0)); |
| 305 } | 314 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 326 { 100, 0, 360.0f, 100, 0 } | 335 { 100, 0, 360.0f, 100, 0 } |
| 327 }; | 336 }; |
| 328 | 337 |
| 329 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(set_rotate_cases); ++i) { | 338 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(set_rotate_cases); ++i) { |
| 330 const SetRotateCase& value = set_rotate_cases[i]; | 339 const SetRotateCase& value = set_rotate_cases[i]; |
| 331 Point3F p0; | 340 Point3F p0; |
| 332 Point3F p1(value.x, value.y, 0); | 341 Point3F p1(value.x, value.y, 0); |
| 333 Point3F p2(value.xprime, value.yprime, 0); | 342 Point3F p2(value.xprime, value.yprime, 0); |
| 334 p0 = p1; | 343 p0 = p1; |
| 335 Transform xform; | 344 Transform xform; |
| 336 xform.SetRotate(value.degree); | 345 xform.Rotate(value.degree); |
| 337 // just want to make sure that we don't crash in the case of NaN. | 346 // just want to make sure that we don't crash in the case of NaN. |
| 338 if (value.degree == value.degree) { | 347 if (value.degree == value.degree) { |
| 339 xform.TransformPoint(p1); | 348 xform.TransformPoint(p1); |
| 340 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); | 349 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); |
| 341 xform.TransformPointReverse(p1); | 350 xform.TransformPointReverse(p1); |
| 342 EXPECT_TRUE(PointsAreNearlyEqual(p1, p0)); | 351 EXPECT_TRUE(PointsAreNearlyEqual(p1, p0)); |
| 343 } | 352 } |
| 344 } | 353 } |
| 345 } | 354 } |
| 346 | 355 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 359 { 0, 0, -10.0f, -20.0f, -10, -20}, | 368 { 0, 0, -10.0f, -20.0f, -10, -20}, |
| 360 { 0, 0, | 369 { 0, 0, |
| 361 std::numeric_limits<float>::quiet_NaN(), | 370 std::numeric_limits<float>::quiet_NaN(), |
| 362 std::numeric_limits<float>::quiet_NaN(), | 371 std::numeric_limits<float>::quiet_NaN(), |
| 363 10, 20}, | 372 10, 20}, |
| 364 }; | 373 }; |
| 365 | 374 |
| 366 Transform xform; | 375 Transform xform; |
| 367 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { | 376 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { |
| 368 const TestCase& value = test_cases[i]; | 377 const TestCase& value = test_cases[i]; |
| 369 xform.ConcatTranslate(value.tx, value.ty); | 378 Transform translation; |
| 379 translation.Translate(value.tx, value.ty); |
| 380 xform = translation * xform; |
| 370 Point p1(value.x1, value.y1); | 381 Point p1(value.x1, value.y1); |
| 371 Point p2(value.x2, value.y2); | 382 Point p2(value.x2, value.y2); |
| 372 xform.TransformPoint(p1); | 383 xform.TransformPoint(p1); |
| 373 if (value.tx == value.tx && | 384 if (value.tx == value.tx && |
| 374 value.ty == value.ty) { | 385 value.ty == value.ty) { |
| 375 EXPECT_EQ(p1.x(), p2.x()); | 386 EXPECT_EQ(p1.x(), p2.x()); |
| 376 EXPECT_EQ(p1.y(), p2.y()); | 387 EXPECT_EQ(p1.y(), p2.y()); |
| 377 } | 388 } |
| 378 } | 389 } |
| 379 } | 390 } |
| 380 | 391 |
| 381 TEST(XFormTest, ConcatScale2D) { | 392 TEST(XFormTest, ConcatScale2D) { |
| 382 static const struct TestCase { | 393 static const struct TestCase { |
| 383 int before; | 394 int before; |
| 384 float scale; | 395 float scale; |
| 385 int after; | 396 int after; |
| 386 } test_cases[] = { | 397 } test_cases[] = { |
| 387 { 1, 10.0f, 10}, | 398 { 1, 10.0f, 10}, |
| 388 { 1, .1f, 1}, | 399 { 1, .1f, 1}, |
| 389 { 1, 100.0f, 100}, | 400 { 1, 100.0f, 100}, |
| 390 { 1, -1.0f, -100}, | 401 { 1, -1.0f, -100}, |
| 391 { 1, std::numeric_limits<float>::quiet_NaN(), 1} | 402 { 1, std::numeric_limits<float>::quiet_NaN(), 1} |
| 392 }; | 403 }; |
| 393 | 404 |
| 394 Transform xform; | 405 Transform xform; |
| 395 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { | 406 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { |
| 396 const TestCase& value = test_cases[i]; | 407 const TestCase& value = test_cases[i]; |
| 397 xform.ConcatScale(value.scale, value.scale); | 408 Transform scale; |
| 409 scale.Scale(value.scale, value.scale); |
| 410 xform = scale * xform; |
| 398 Point p1(value.before, value.before); | 411 Point p1(value.before, value.before); |
| 399 Point p2(value.after, value.after); | 412 Point p2(value.after, value.after); |
| 400 xform.TransformPoint(p1); | 413 xform.TransformPoint(p1); |
| 401 if (value.scale == value.scale) { | 414 if (value.scale == value.scale) { |
| 402 EXPECT_EQ(p1.x(), p2.x()); | 415 EXPECT_EQ(p1.x(), p2.x()); |
| 403 EXPECT_EQ(p1.y(), p2.y()); | 416 EXPECT_EQ(p1.y(), p2.y()); |
| 404 } | 417 } |
| 405 } | 418 } |
| 406 } | 419 } |
| 407 | 420 |
| 408 TEST(XFormTest, ConcatRotate2D) { | 421 TEST(XFormTest, ConcatRotate2D) { |
| 409 static const struct TestCase { | 422 static const struct TestCase { |
| 410 int x1; | 423 int x1; |
| 411 int y1; | 424 int y1; |
| 412 float degrees; | 425 float degrees; |
| 413 int x2; | 426 int x2; |
| 414 int y2; | 427 int y2; |
| 415 } test_cases[] = { | 428 } test_cases[] = { |
| 416 { 1, 0, 90.0f, 0, 1}, | 429 { 1, 0, 90.0f, 0, 1}, |
| 417 { 1, 0, -90.0f, 1, 0}, | 430 { 1, 0, -90.0f, 1, 0}, |
| 418 { 1, 0, 90.0f, 0, 1}, | 431 { 1, 0, 90.0f, 0, 1}, |
| 419 { 1, 0, 360.0f, 0, 1}, | 432 { 1, 0, 360.0f, 0, 1}, |
| 420 { 1, 0, 0.0f, 0, 1}, | 433 { 1, 0, 0.0f, 0, 1}, |
| 421 { 1, 0, std::numeric_limits<float>::quiet_NaN(), 1, 0} | 434 { 1, 0, std::numeric_limits<float>::quiet_NaN(), 1, 0} |
| 422 }; | 435 }; |
| 423 | 436 |
| 424 Transform xform; | 437 Transform xform; |
| 425 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { | 438 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { |
| 426 const TestCase& value = test_cases[i]; | 439 const TestCase& value = test_cases[i]; |
| 427 xform.ConcatRotate(value.degrees); | 440 Transform rotation; |
| 441 rotation.Rotate(value.degrees); |
| 442 xform = rotation * xform; |
| 428 Point p1(value.x1, value.y1); | 443 Point p1(value.x1, value.y1); |
| 429 Point p2(value.x2, value.y2); | 444 Point p2(value.x2, value.y2); |
| 430 xform.TransformPoint(p1); | 445 xform.TransformPoint(p1); |
| 431 if (value.degrees == value.degrees) { | 446 if (value.degrees == value.degrees) { |
| 432 EXPECT_EQ(p1.x(), p2.x()); | 447 EXPECT_EQ(p1.x(), p2.x()); |
| 433 EXPECT_EQ(p1.y(), p2.y()); | 448 EXPECT_EQ(p1.y(), p2.y()); |
| 434 } | 449 } |
| 435 } | 450 } |
| 436 } | 451 } |
| 437 | 452 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 454 const TestCase& value = test_cases[i]; | 469 const TestCase& value = test_cases[i]; |
| 455 for (int j = -1; j < 2; ++j) { | 470 for (int j = -1; j < 2; ++j) { |
| 456 for (int k = 0; k < 3; ++k) { | 471 for (int k = 0; k < 3; ++k) { |
| 457 float epsilon = 0.0001f; | 472 float epsilon = 0.0001f; |
| 458 Point p0, p1, p2; | 473 Point p0, p1, p2; |
| 459 Transform xform; | 474 Transform xform; |
| 460 switch (k) { | 475 switch (k) { |
| 461 case 0: | 476 case 0: |
| 462 p1.SetPoint(value.x1, 0); | 477 p1.SetPoint(value.x1, 0); |
| 463 p2.SetPoint(value.x2, 0); | 478 p2.SetPoint(value.x2, 0); |
| 464 xform.SetTranslateX(value.tx + j * epsilon); | 479 xform.Translate(value.tx + j * epsilon, 0.0); |
| 465 break; | 480 break; |
| 466 case 1: | 481 case 1: |
| 467 p1.SetPoint(0, value.y1); | 482 p1.SetPoint(0, value.y1); |
| 468 p2.SetPoint(0, value.y2); | 483 p2.SetPoint(0, value.y2); |
| 469 xform.SetTranslateY(value.ty + j * epsilon); | 484 xform.Translate(0.0, value.ty + j * epsilon); |
| 470 break; | 485 break; |
| 471 case 2: | 486 case 2: |
| 472 p1.SetPoint(value.x1, value.y1); | 487 p1.SetPoint(value.x1, value.y1); |
| 473 p2.SetPoint(value.x2, value.y2); | 488 p2.SetPoint(value.x2, value.y2); |
| 474 xform.SetTranslate(value.tx + j * epsilon, | 489 xform.Translate(value.tx + j * epsilon, |
| 475 value.ty + j * epsilon); | 490 value.ty + j * epsilon); |
| 476 break; | 491 break; |
| 477 } | 492 } |
| 478 p0 = p1; | 493 p0 = p1; |
| 479 xform.TransformPoint(p1); | 494 xform.TransformPoint(p1); |
| 480 if (value.tx == value.tx && | 495 if (value.tx == value.tx && |
| 481 value.ty == value.ty) { | 496 value.ty == value.ty) { |
| 482 EXPECT_EQ(p1.x(), p2.x()); | 497 EXPECT_EQ(p1.x(), p2.x()); |
| 483 EXPECT_EQ(p1.y(), p2.y()); | 498 EXPECT_EQ(p1.y(), p2.y()); |
| 484 xform.TransformPointReverse(p1); | 499 xform.TransformPointReverse(p1); |
| 485 EXPECT_EQ(p1.x(), p0.x()); | 500 EXPECT_EQ(p1.x(), p0.x()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 507 const TestCase& value = test_cases[i]; | 522 const TestCase& value = test_cases[i]; |
| 508 for (int j = -1; j < 2; ++j) { | 523 for (int j = -1; j < 2; ++j) { |
| 509 for (int k = 0; k < 3; ++k) { | 524 for (int k = 0; k < 3; ++k) { |
| 510 float epsilon = 0.0001f; | 525 float epsilon = 0.0001f; |
| 511 Point p0, p1, p2; | 526 Point p0, p1, p2; |
| 512 Transform xform; | 527 Transform xform; |
| 513 switch (k) { | 528 switch (k) { |
| 514 case 0: | 529 case 0: |
| 515 p1.SetPoint(value.before, 0); | 530 p1.SetPoint(value.before, 0); |
| 516 p2.SetPoint(value.after, 0); | 531 p2.SetPoint(value.after, 0); |
| 517 xform.SetScaleX(value.s + j * epsilon); | 532 xform.Scale(value.s + j * epsilon, 1.0); |
| 518 break; | 533 break; |
| 519 case 1: | 534 case 1: |
| 520 p1.SetPoint(0, value.before); | 535 p1.SetPoint(0, value.before); |
| 521 p2.SetPoint(0, value.after); | 536 p2.SetPoint(0, value.after); |
| 522 xform.SetScaleY(value.s + j * epsilon); | 537 xform.Scale(1.0, value.s + j * epsilon); |
| 523 break; | 538 break; |
| 524 case 2: | 539 case 2: |
| 525 p1.SetPoint(value.before, | 540 p1.SetPoint(value.before, |
| 526 value.before); | 541 value.before); |
| 527 p2.SetPoint(value.after, | 542 p2.SetPoint(value.after, |
| 528 value.after); | 543 value.after); |
| 529 xform.SetScale(value.s + j * epsilon, | 544 xform.Scale(value.s + j * epsilon, |
| 530 value.s + j * epsilon); | 545 value.s + j * epsilon); |
| 531 break; | 546 break; |
| 532 } | 547 } |
| 533 p0 = p1; | 548 p0 = p1; |
| 534 xform.TransformPoint(p1); | 549 xform.TransformPoint(p1); |
| 535 if (value.s == value.s) { | 550 if (value.s == value.s) { |
| 536 EXPECT_EQ(p1.x(), p2.x()); | 551 EXPECT_EQ(p1.x(), p2.x()); |
| 537 EXPECT_EQ(p1.y(), p2.y()); | 552 EXPECT_EQ(p1.y(), p2.y()); |
| 538 if (value.s != 0.0f) { | 553 if (value.s != 0.0f) { |
| 539 xform.TransformPointReverse(p1); | 554 xform.TransformPointReverse(p1); |
| 540 EXPECT_EQ(p1.x(), p0.x()); | 555 EXPECT_EQ(p1.x(), p0.x()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 564 { 100, 0, 360.0f, 100, 0} | 579 { 100, 0, 360.0f, 100, 0} |
| 565 }; | 580 }; |
| 566 | 581 |
| 567 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(set_rotate_cases); ++i) { | 582 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(set_rotate_cases); ++i) { |
| 568 const SetRotateCase& value = set_rotate_cases[i]; | 583 const SetRotateCase& value = set_rotate_cases[i]; |
| 569 for (int j = 1; j >= -1; --j) { | 584 for (int j = 1; j >= -1; --j) { |
| 570 float epsilon = 0.1f; | 585 float epsilon = 0.1f; |
| 571 Point pt(value.x, value.y); | 586 Point pt(value.x, value.y); |
| 572 Transform xform; | 587 Transform xform; |
| 573 // should be invariant to small floating point errors. | 588 // should be invariant to small floating point errors. |
| 574 xform.SetRotate(value.degree + j * epsilon); | 589 xform.Rotate(value.degree + j * epsilon); |
| 575 // just want to make sure that we don't crash in the case of NaN. | 590 // just want to make sure that we don't crash in the case of NaN. |
| 576 if (value.degree == value.degree) { | 591 if (value.degree == value.degree) { |
| 577 xform.TransformPoint(pt); | 592 xform.TransformPoint(pt); |
| 578 EXPECT_EQ(value.xprime, pt.x()); | 593 EXPECT_EQ(value.xprime, pt.x()); |
| 579 EXPECT_EQ(value.yprime, pt.y()); | 594 EXPECT_EQ(value.yprime, pt.y()); |
| 580 xform.TransformPointReverse(pt); | 595 xform.TransformPointReverse(pt); |
| 581 EXPECT_EQ(pt.x(), value.x); | 596 EXPECT_EQ(pt.x(), value.x); |
| 582 EXPECT_EQ(pt.y(), value.y); | 597 EXPECT_EQ(pt.y(), value.y); |
| 583 } | 598 } |
| 584 } | 599 } |
| 585 } | 600 } |
| 586 } | 601 } |
| 587 | 602 |
| 588 TEST(XFormTest, BlendTranslate) { | 603 TEST(XFormTest, BlendTranslate) { |
| 589 Transform from; | 604 Transform from; |
| 590 for (int i = 0; i < 10; ++i) { | 605 for (int i = 0; i < 10; ++i) { |
| 591 Transform to; | 606 Transform to; |
| 592 to.SetTranslate3d(1, 1, 1); | 607 to.Translate3d(1, 1, 1); |
| 593 double t = i / 9.0; | 608 double t = i / 9.0; |
| 594 EXPECT_TRUE(to.Blend(from, t)); | 609 EXPECT_TRUE(to.Blend(from, t)); |
| 595 EXPECT_FLOAT_EQ(t, to.matrix().get(0, 3)); | 610 EXPECT_FLOAT_EQ(t, to.matrix().get(0, 3)); |
| 596 EXPECT_FLOAT_EQ(t, to.matrix().get(1, 3)); | 611 EXPECT_FLOAT_EQ(t, to.matrix().get(1, 3)); |
| 597 EXPECT_FLOAT_EQ(t, to.matrix().get(2, 3)); | 612 EXPECT_FLOAT_EQ(t, to.matrix().get(2, 3)); |
| 598 } | 613 } |
| 599 } | 614 } |
| 600 | 615 |
| 601 TEST(XFormTest, BlendRotate) { | 616 TEST(XFormTest, BlendRotate) { |
| 602 Point3F axes[] = { | 617 Vector3dF axes[] = { |
| 603 Point3F(1, 0, 0), | 618 Vector3dF(1, 0, 0), |
| 604 Point3F(0, 1, 0), | 619 Vector3dF(0, 1, 0), |
| 605 Point3F(0, 0, 1), | 620 Vector3dF(0, 0, 1), |
| 606 Point3F(1, 1, 1) | 621 Vector3dF(1, 1, 1) |
| 607 }; | 622 }; |
| 608 Transform from; | 623 Transform from; |
| 609 for (size_t index = 0; index < ARRAYSIZE_UNSAFE(axes); ++index) { | 624 for (size_t index = 0; index < ARRAYSIZE_UNSAFE(axes); ++index) { |
| 610 for (int i = 0; i < 10; ++i) { | 625 for (int i = 0; i < 10; ++i) { |
| 611 Transform to; | 626 Transform to; |
| 612 to.SetRotateAbout(axes[index], 90); | 627 to.RotateAbout(axes[index], 90); |
| 613 double t = i / 9.0; | 628 double t = i / 9.0; |
| 614 EXPECT_TRUE(to.Blend(from, t)); | 629 EXPECT_TRUE(to.Blend(from, t)); |
| 615 | 630 |
| 616 Transform expected; | 631 Transform expected; |
| 617 expected.SetRotateAbout(axes[index], 90 * t); | 632 expected.RotateAbout(axes[index], 90 * t); |
| 618 | 633 |
| 619 EXPECT_TRUE(MatricesAreNearlyEqual(expected, to)); | 634 EXPECT_TRUE(MatricesAreNearlyEqual(expected, to)); |
| 620 } | 635 } |
| 621 } | 636 } |
| 622 } | 637 } |
| 623 | 638 |
| 624 TEST(XFormTest, CannotBlend180DegreeRotation) { | 639 TEST(XFormTest, CannotBlend180DegreeRotation) { |
| 625 Point3F axes[] = { | 640 Vector3dF axes[] = { |
| 626 Point3F(1, 0, 0), | 641 Vector3dF(1, 0, 0), |
| 627 Point3F(0, 1, 0), | 642 Vector3dF(0, 1, 0), |
| 628 Point3F(0, 0, 1), | 643 Vector3dF(0, 0, 1), |
| 629 Point3F(1, 1, 1) | 644 Vector3dF(1, 1, 1) |
| 630 }; | 645 }; |
| 631 Transform from; | 646 Transform from; |
| 632 for (size_t index = 0; index < ARRAYSIZE_UNSAFE(axes); ++index) { | 647 for (size_t index = 0; index < ARRAYSIZE_UNSAFE(axes); ++index) { |
| 633 Transform to; | 648 Transform to; |
| 634 to.SetRotateAbout(axes[index], 180); | 649 to.RotateAbout(axes[index], 180); |
| 635 EXPECT_FALSE(to.Blend(from, 0.5)); | 650 EXPECT_FALSE(to.Blend(from, 0.5)); |
| 636 } | 651 } |
| 637 } | 652 } |
| 638 | 653 |
| 639 TEST(XFormTest, BlendScale) { | 654 TEST(XFormTest, BlendScale) { |
| 640 Transform from; | 655 Transform from; |
| 641 for (int i = 0; i < 10; ++i) { | 656 for (int i = 0; i < 10; ++i) { |
| 642 Transform to; | 657 Transform to; |
| 643 to.SetScale3d(5, 4, 3); | 658 to.Scale3d(5, 4, 3); |
| 644 double t = i / 9.0; | 659 double t = i / 9.0; |
| 645 EXPECT_TRUE(to.Blend(from, t)); | 660 EXPECT_TRUE(to.Blend(from, t)); |
| 646 EXPECT_FLOAT_EQ(t * 4 + 1, to.matrix().get(0, 0)); | 661 EXPECT_FLOAT_EQ(t * 4 + 1, to.matrix().get(0, 0)); |
| 647 EXPECT_FLOAT_EQ(t * 3 + 1, to.matrix().get(1, 1)); | 662 EXPECT_FLOAT_EQ(t * 3 + 1, to.matrix().get(1, 1)); |
| 648 EXPECT_FLOAT_EQ(t * 2 + 1, to.matrix().get(2, 2)); | 663 EXPECT_FLOAT_EQ(t * 2 + 1, to.matrix().get(2, 2)); |
| 649 } | 664 } |
| 650 } | 665 } |
| 651 | 666 |
| 652 TEST(XFormTest, BlendSkew) { | 667 TEST(XFormTest, BlendSkew) { |
| 653 Transform from; | 668 Transform from; |
| 654 for (int i = 0; i < 2; ++i) { | 669 for (int i = 0; i < 2; ++i) { |
| 655 Transform to; | 670 Transform to; |
| 656 to.SetSkewX(20); | 671 to.SkewX(20); |
| 657 to.PreconcatSkewY(10); | 672 to.SkewY(10); |
| 658 double t = i; | 673 double t = i; |
| 659 Transform expected; | 674 Transform expected; |
| 660 expected.SetSkewX(t * 20); | 675 expected.SkewX(t * 20); |
| 661 expected.PreconcatSkewY(t * 10); | 676 expected.SkewY(t * 10); |
| 662 EXPECT_TRUE(to.Blend(from, t)); | 677 EXPECT_TRUE(to.Blend(from, t)); |
| 663 EXPECT_TRUE(MatricesAreNearlyEqual(expected, to)); | 678 EXPECT_TRUE(MatricesAreNearlyEqual(expected, to)); |
| 664 } | 679 } |
| 665 } | 680 } |
| 666 | 681 |
| 667 TEST(XFormTest, BlendPerspective) { | 682 TEST(XFormTest, BlendPerspective) { |
| 668 Transform from; | 683 Transform from; |
| 669 from.SetPerspectiveDepth(200); | 684 from.ApplyPerspectiveDepth(200); |
| 670 for (int i = 0; i < 2; ++i) { | 685 for (int i = 0; i < 2; ++i) { |
| 671 Transform to; | 686 Transform to; |
| 672 to.SetPerspectiveDepth(800); | 687 to.ApplyPerspectiveDepth(800); |
| 673 double t = i; | 688 double t = i; |
| 674 Transform expected; | 689 Transform expected; |
| 675 expected.SetPerspectiveDepth(t * 600 + 200); | 690 expected.ApplyPerspectiveDepth(t * 600 + 200); |
| 676 EXPECT_TRUE(to.Blend(from, t)); | 691 EXPECT_TRUE(to.Blend(from, t)); |
| 677 EXPECT_TRUE(MatricesAreNearlyEqual(expected, to)); | 692 EXPECT_TRUE(MatricesAreNearlyEqual(expected, to)); |
| 678 } | 693 } |
| 679 } | 694 } |
| 680 | 695 |
| 681 TEST(XFormTest, BlendIdentity) { | 696 TEST(XFormTest, BlendIdentity) { |
| 682 Transform from; | 697 Transform from; |
| 683 Transform to; | 698 Transform to; |
| 684 EXPECT_TRUE(to.Blend(from, 0.5)); | 699 EXPECT_TRUE(to.Blend(from, 0.5)); |
| 685 EXPECT_EQ(to, from); | 700 EXPECT_EQ(to, from); |
| 686 } | 701 } |
| 687 | 702 |
| 688 TEST(XFormTest, CannotBlendSingularMatrix) { | 703 TEST(XFormTest, CannotBlendSingularMatrix) { |
| 689 Transform from; | 704 Transform from; |
| 690 Transform to; | 705 Transform to; |
| 691 to.matrix().set(1, 1, SkDoubleToMScalar(0)); | 706 to.matrix().set(1, 1, SkDoubleToMScalar(0)); |
| 692 EXPECT_FALSE(to.Blend(from, 0.5)); | 707 EXPECT_FALSE(to.Blend(from, 0.5)); |
| 693 } | 708 } |
| 694 | 709 |
| 695 TEST(XFormTest, VerifyBlendForTranslation) | 710 TEST(XFormTest, VerifyBlendForTranslation) |
| 696 { | 711 { |
| 697 Transform from; | 712 Transform from; |
| 698 from.PreconcatTranslate3d(100, 200, 100); | 713 from.Translate3d(100, 200, 100); |
| 699 | 714 |
| 700 Transform to; | 715 Transform to; |
| 701 | 716 |
| 702 to.PreconcatTranslate3d(200, 100, 300); | 717 to.Translate3d(200, 100, 300); |
| 703 to.Blend(from, 0); | 718 to.Blend(from, 0); |
| 704 EXPECT_EQ(from, to); | 719 EXPECT_EQ(from, to); |
| 705 | 720 |
| 706 to = Transform(); | 721 to = Transform(); |
| 707 to.PreconcatTranslate3d(200, 100, 300); | 722 to.Translate3d(200, 100, 300); |
| 708 to.Blend(from, 0.25); | 723 to.Blend(from, 0.25); |
| 709 EXPECT_ROW1_EQ(1, 0, 0, 125, to); | 724 EXPECT_ROW1_EQ(1, 0, 0, 125, to); |
| 710 EXPECT_ROW2_EQ(0, 1, 0, 175, to); | 725 EXPECT_ROW2_EQ(0, 1, 0, 175, to); |
| 711 EXPECT_ROW3_EQ(0, 0, 1, 150, to); | 726 EXPECT_ROW3_EQ(0, 0, 1, 150, to); |
| 712 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 727 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 713 | 728 |
| 714 to = Transform(); | 729 to = Transform(); |
| 715 to.PreconcatTranslate3d(200, 100, 300); | 730 to.Translate3d(200, 100, 300); |
| 716 to.Blend(from, 0.5); | 731 to.Blend(from, 0.5); |
| 717 EXPECT_ROW1_EQ(1, 0, 0, 150, to); | 732 EXPECT_ROW1_EQ(1, 0, 0, 150, to); |
| 718 EXPECT_ROW2_EQ(0, 1, 0, 150, to); | 733 EXPECT_ROW2_EQ(0, 1, 0, 150, to); |
| 719 EXPECT_ROW3_EQ(0, 0, 1, 200, to); | 734 EXPECT_ROW3_EQ(0, 0, 1, 200, to); |
| 720 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 735 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 721 | 736 |
| 722 to = Transform(); | 737 to = Transform(); |
| 723 to.PreconcatTranslate3d(200, 100, 300); | 738 to.Translate3d(200, 100, 300); |
| 724 to.Blend(from, 1); | 739 to.Blend(from, 1); |
| 725 EXPECT_ROW1_EQ(1, 0, 0, 200, to); | 740 EXPECT_ROW1_EQ(1, 0, 0, 200, to); |
| 726 EXPECT_ROW2_EQ(0, 1, 0, 100, to); | 741 EXPECT_ROW2_EQ(0, 1, 0, 100, to); |
| 727 EXPECT_ROW3_EQ(0, 0, 1, 300, to); | 742 EXPECT_ROW3_EQ(0, 0, 1, 300, to); |
| 728 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 743 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 729 } | 744 } |
| 730 | 745 |
| 731 TEST(XFormTest, VerifyBlendForScale) | 746 TEST(XFormTest, VerifyBlendForScale) |
| 732 { | 747 { |
| 733 Transform from; | 748 Transform from; |
| 734 from.PreconcatScale3d(100, 200, 100); | 749 from.Scale3d(100, 200, 100); |
| 735 | 750 |
| 736 Transform to; | 751 Transform to; |
| 737 | 752 |
| 738 to.PreconcatScale3d(200, 100, 300); | 753 to.Scale3d(200, 100, 300); |
| 739 to.Blend(from, 0); | 754 to.Blend(from, 0); |
| 740 EXPECT_EQ(from, to); | 755 EXPECT_EQ(from, to); |
| 741 | 756 |
| 742 to = Transform(); | 757 to = Transform(); |
| 743 to.PreconcatScale3d(200, 100, 300); | 758 to.Scale3d(200, 100, 300); |
| 744 to.Blend(from, 0.25); | 759 to.Blend(from, 0.25); |
| 745 EXPECT_ROW1_EQ(125, 0, 0, 0, to); | 760 EXPECT_ROW1_EQ(125, 0, 0, 0, to); |
| 746 EXPECT_ROW2_EQ(0, 175, 0, 0, to); | 761 EXPECT_ROW2_EQ(0, 175, 0, 0, to); |
| 747 EXPECT_ROW3_EQ(0, 0, 150, 0, to); | 762 EXPECT_ROW3_EQ(0, 0, 150, 0, to); |
| 748 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 763 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 749 | 764 |
| 750 to = Transform(); | 765 to = Transform(); |
| 751 to.PreconcatScale3d(200, 100, 300); | 766 to.Scale3d(200, 100, 300); |
| 752 to.Blend(from, 0.5); | 767 to.Blend(from, 0.5); |
| 753 EXPECT_ROW1_EQ(150, 0, 0, 0, to); | 768 EXPECT_ROW1_EQ(150, 0, 0, 0, to); |
| 754 EXPECT_ROW2_EQ(0, 150, 0, 0, to); | 769 EXPECT_ROW2_EQ(0, 150, 0, 0, to); |
| 755 EXPECT_ROW3_EQ(0, 0, 200, 0, to); | 770 EXPECT_ROW3_EQ(0, 0, 200, 0, to); |
| 756 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 771 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 757 | 772 |
| 758 to = Transform(); | 773 to = Transform(); |
| 759 to.PreconcatScale3d(200, 100, 300); | 774 to.Scale3d(200, 100, 300); |
| 760 to.Blend(from, 1); | 775 to.Blend(from, 1); |
| 761 EXPECT_ROW1_EQ(200, 0, 0, 0, to); | 776 EXPECT_ROW1_EQ(200, 0, 0, 0, to); |
| 762 EXPECT_ROW2_EQ(0, 100, 0, 0, to); | 777 EXPECT_ROW2_EQ(0, 100, 0, 0, to); |
| 763 EXPECT_ROW3_EQ(0, 0, 300, 0, to); | 778 EXPECT_ROW3_EQ(0, 0, 300, 0, to); |
| 764 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 779 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 765 } | 780 } |
| 766 | 781 |
| 767 TEST(XFormTest, VerifyBlendForSkewX) | 782 TEST(XFormTest, VerifyBlendForSkewX) |
| 768 { | 783 { |
| 769 Transform from; | 784 Transform from; |
| 770 from.PreconcatSkewX(0); | 785 from.SkewX(0); |
| 771 | 786 |
| 772 Transform to; | 787 Transform to; |
| 773 | 788 |
| 774 to.PreconcatSkewX(45); | 789 to.SkewX(45); |
| 775 to.Blend(from, 0); | 790 to.Blend(from, 0); |
| 776 EXPECT_EQ(from, to); | 791 EXPECT_EQ(from, to); |
| 777 | 792 |
| 778 to = Transform(); | 793 to = Transform(); |
| 779 to.PreconcatSkewX(45); | 794 to.SkewX(45); |
| 780 to.Blend(from, 0.5); | 795 to.Blend(from, 0.5); |
| 781 EXPECT_ROW1_EQ(1, 0.5, 0, 0, to); | 796 EXPECT_ROW1_EQ(1, 0.5, 0, 0, to); |
| 782 EXPECT_ROW2_EQ(0, 1, 0, 0, to); | 797 EXPECT_ROW2_EQ(0, 1, 0, 0, to); |
| 783 EXPECT_ROW3_EQ(0, 0, 1, 0, to); | 798 EXPECT_ROW3_EQ(0, 0, 1, 0, to); |
| 784 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 799 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 785 | 800 |
| 786 to = Transform(); | 801 to = Transform(); |
| 787 to.PreconcatSkewX(45); | 802 to.SkewX(45); |
| 788 to.Blend(from, 0.25); | 803 to.Blend(from, 0.25); |
| 789 EXPECT_ROW1_EQ(1, 0.25, 0, 0, to); | 804 EXPECT_ROW1_EQ(1, 0.25, 0, 0, to); |
| 790 EXPECT_ROW2_EQ(0, 1, 0, 0, to); | 805 EXPECT_ROW2_EQ(0, 1, 0, 0, to); |
| 791 EXPECT_ROW3_EQ(0, 0, 1, 0, to); | 806 EXPECT_ROW3_EQ(0, 0, 1, 0, to); |
| 792 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 807 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 793 | 808 |
| 794 to = Transform(); | 809 to = Transform(); |
| 795 to.PreconcatSkewX(45); | 810 to.SkewX(45); |
| 796 to.Blend(from, 1); | 811 to.Blend(from, 1); |
| 797 EXPECT_ROW1_EQ(1, 1, 0, 0, to); | 812 EXPECT_ROW1_EQ(1, 1, 0, 0, to); |
| 798 EXPECT_ROW2_EQ(0, 1, 0, 0, to); | 813 EXPECT_ROW2_EQ(0, 1, 0, 0, to); |
| 799 EXPECT_ROW3_EQ(0, 0, 1, 0, to); | 814 EXPECT_ROW3_EQ(0, 0, 1, 0, to); |
| 800 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 815 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 801 } | 816 } |
| 802 | 817 |
| 803 TEST(XFormTest, VerifyBlendForSkewY) | 818 TEST(XFormTest, VerifyBlendForSkewY) |
| 804 { | 819 { |
| 805 // NOTE CAREFULLY: Decomposition of skew and rotation terms of the matrix | 820 // NOTE CAREFULLY: Decomposition of skew and rotation terms of the matrix |
| 806 // is inherently underconstrained, and so it does not always compute the | 821 // is inherently underconstrained, and so it does not always compute the |
| 807 // originally intended skew parameters. The current implementation uses QR | 822 // originally intended skew parameters. The current implementation uses QR |
| 808 // decomposition, which decomposes the shear into a rotation + non-uniform | 823 // decomposition, which decomposes the shear into a rotation + non-uniform |
| 809 // scale. | 824 // scale. |
| 810 // | 825 // |
| 811 // It is unlikely that the decomposition implementation will need to change | 826 // It is unlikely that the decomposition implementation will need to change |
| 812 // very often, so to get any test coverage, the compromise is to verify the | 827 // very often, so to get any test coverage, the compromise is to verify the |
| 813 // exact matrix that the.Blend() operation produces. | 828 // exact matrix that the.Blend() operation produces. |
| 814 // | 829 // |
| 815 // This problem also potentially exists for skewX, but the current QR | 830 // This problem also potentially exists for skewX, but the current QR |
| 816 // decomposition implementation just happens to decompose those test | 831 // decomposition implementation just happens to decompose those test |
| 817 // matrices intuitively. | 832 // matrices intuitively. |
| 818 // | 833 // |
| 819 // Unfortunately, this case suffers from uncomfortably large precision | 834 // Unfortunately, this case suffers from uncomfortably large precision |
| 820 // error. | 835 // error. |
| 821 | 836 |
| 822 Transform from; | 837 Transform from; |
| 823 from.PreconcatSkewY(0); | 838 from.SkewY(0); |
| 824 | 839 |
| 825 Transform to; | 840 Transform to; |
| 826 | 841 |
| 827 to.PreconcatSkewY(45); | 842 to.SkewY(45); |
| 828 to.Blend(from, 0); | 843 to.Blend(from, 0); |
| 829 EXPECT_EQ(from, to); | 844 EXPECT_EQ(from, to); |
| 830 | 845 |
| 831 to = Transform(); | 846 to = Transform(); |
| 832 to.PreconcatSkewY(45); | 847 to.SkewY(45); |
| 833 to.Blend(from, 0.25); | 848 to.Blend(from, 0.25); |
| 834 EXPECT_ROW1_NEAR(1.0823489449280947471976333, | 849 EXPECT_ROW1_NEAR(1.0823489449280947471976333, |
| 835 0.0464370719145053845178239, | 850 0.0464370719145053845178239, |
| 836 0, | 851 0, |
| 837 0, | 852 0, |
| 838 to, | 853 to, |
| 839 LOOSE_ERROR_THRESHOLD); | 854 LOOSE_ERROR_THRESHOLD); |
| 840 EXPECT_ROW2_NEAR(0.2152925909665224513123150, | 855 EXPECT_ROW2_NEAR(0.2152925909665224513123150, |
| 841 0.9541702441750861130032035, | 856 0.9541702441750861130032035, |
| 842 0, | 857 0, |
| 843 0, | 858 0, |
| 844 to, | 859 to, |
| 845 LOOSE_ERROR_THRESHOLD); | 860 LOOSE_ERROR_THRESHOLD); |
| 846 EXPECT_ROW3_EQ(0, 0, 1, 0, to); | 861 EXPECT_ROW3_EQ(0, 0, 1, 0, to); |
| 847 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 862 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 848 | 863 |
| 849 to = Transform(); | 864 to = Transform(); |
| 850 to.PreconcatSkewY(45); | 865 to.SkewY(45); |
| 851 to.Blend(from, 0.5); | 866 to.Blend(from, 0.5); |
| 852 EXPECT_ROW1_NEAR(1.1152212925809066312865525, | 867 EXPECT_ROW1_NEAR(1.1152212925809066312865525, |
| 853 0.0676495144007326631996335, | 868 0.0676495144007326631996335, |
| 854 0, | 869 0, |
| 855 0, | 870 0, |
| 856 to, | 871 to, |
| 857 LOOSE_ERROR_THRESHOLD); | 872 LOOSE_ERROR_THRESHOLD); |
| 858 EXPECT_ROW2_NEAR(0.4619397844342648662419037, | 873 EXPECT_ROW2_NEAR(0.4619397844342648662419037, |
| 859 0.9519009045724774464858342, | 874 0.9519009045724774464858342, |
| 860 0, | 875 0, |
| 861 0, | 876 0, |
| 862 to, | 877 to, |
| 863 LOOSE_ERROR_THRESHOLD); | 878 LOOSE_ERROR_THRESHOLD); |
| 864 EXPECT_ROW3_EQ(0, 0, 1, 0, to); | 879 EXPECT_ROW3_EQ(0, 0, 1, 0, to); |
| 865 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 880 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 866 | 881 |
| 867 to = Transform(); | 882 to = Transform(); |
| 868 to.PreconcatSkewY(45); | 883 to.SkewY(45); |
| 869 to.Blend(from, 1); | 884 to.Blend(from, 1); |
| 870 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, LOOSE_ERROR_THRESHOLD); | 885 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, LOOSE_ERROR_THRESHOLD); |
| 871 EXPECT_ROW2_NEAR(1, 1, 0, 0, to, LOOSE_ERROR_THRESHOLD); | 886 EXPECT_ROW2_NEAR(1, 1, 0, 0, to, LOOSE_ERROR_THRESHOLD); |
| 872 EXPECT_ROW3_EQ(0, 0, 1, 0, to); | 887 EXPECT_ROW3_EQ(0, 0, 1, 0, to); |
| 873 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 888 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 874 } | 889 } |
| 875 | 890 |
| 876 TEST(XFormTest, VerifyBlendForRotationAboutX) | 891 TEST(XFormTest, VerifyBlendForRotationAboutX) |
| 877 { | 892 { |
| 878 // Even though.Blending uses quaternions, axis-aligned rotations should. | 893 // Even though.Blending uses quaternions, axis-aligned rotations should. |
| 879 // Blend the same with quaternions or Euler angles. So we can test | 894 // Blend the same with quaternions or Euler angles. So we can test |
| 880 // rotation.Blending by comparing against manually specified matrices from | 895 // rotation.Blending by comparing against manually specified matrices from |
| 881 // Euler angles. | 896 // Euler angles. |
| 882 | 897 |
| 883 Transform from; | 898 Transform from; |
| 884 from.PreconcatRotateAbout(Point3F(1, 0, 0), 0); | 899 from.RotateAbout(Vector3dF(1, 0, 0), 0); |
| 885 | 900 |
| 886 Transform to; | 901 Transform to; |
| 887 | 902 |
| 888 to.PreconcatRotateAbout(Point3F(1, 0, 0), 90); | 903 to.RotateAbout(Vector3dF(1, 0, 0), 90); |
| 889 to.Blend(from, 0); | 904 to.Blend(from, 0); |
| 890 EXPECT_EQ(from, to); | 905 EXPECT_EQ(from, to); |
| 891 | 906 |
| 892 double expectedRotationAngle = 22.5 * M_PI / 180.0; | 907 double expectedRotationAngle = 22.5 * M_PI / 180.0; |
| 893 to = Transform(); | 908 to = Transform(); |
| 894 to.PreconcatRotateAbout(Point3F(1, 0, 0), 90); | 909 to.RotateAbout(Vector3dF(1, 0, 0), 90); |
| 895 to.Blend(from, 0.25); | 910 to.Blend(from, 0.25); |
| 896 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD); | 911 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD); |
| 897 EXPECT_ROW2_NEAR(0, | 912 EXPECT_ROW2_NEAR(0, |
| 898 std::cos(expectedRotationAngle), | 913 std::cos(expectedRotationAngle), |
| 899 -std::sin(expectedRotationAngle), | 914 -std::sin(expectedRotationAngle), |
| 900 0, | 915 0, |
| 901 to, | 916 to, |
| 902 ERROR_THRESHOLD); | 917 ERROR_THRESHOLD); |
| 903 EXPECT_ROW3_NEAR(0, | 918 EXPECT_ROW3_NEAR(0, |
| 904 std::sin(expectedRotationAngle), | 919 std::sin(expectedRotationAngle), |
| 905 std::cos(expectedRotationAngle), | 920 std::cos(expectedRotationAngle), |
| 906 0, | 921 0, |
| 907 to, | 922 to, |
| 908 ERROR_THRESHOLD); | 923 ERROR_THRESHOLD); |
| 909 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 924 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 910 | 925 |
| 911 expectedRotationAngle = 45 * M_PI / 180.0; | 926 expectedRotationAngle = 45 * M_PI / 180.0; |
| 912 to = Transform(); | 927 to = Transform(); |
| 913 to.PreconcatRotateAbout(Point3F(1, 0, 0), 90); | 928 to.RotateAbout(Vector3dF(1, 0, 0), 90); |
| 914 to.Blend(from, 0.5); | 929 to.Blend(from, 0.5); |
| 915 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD); | 930 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD); |
| 916 EXPECT_ROW2_NEAR(0, | 931 EXPECT_ROW2_NEAR(0, |
| 917 std::cos(expectedRotationAngle), | 932 std::cos(expectedRotationAngle), |
| 918 -std::sin(expectedRotationAngle), | 933 -std::sin(expectedRotationAngle), |
| 919 0, | 934 0, |
| 920 to, | 935 to, |
| 921 ERROR_THRESHOLD); | 936 ERROR_THRESHOLD); |
| 922 EXPECT_ROW3_NEAR(0, | 937 EXPECT_ROW3_NEAR(0, |
| 923 std::sin(expectedRotationAngle), | 938 std::sin(expectedRotationAngle), |
| 924 std::cos(expectedRotationAngle), | 939 std::cos(expectedRotationAngle), |
| 925 0, | 940 0, |
| 926 to, | 941 to, |
| 927 ERROR_THRESHOLD); | 942 ERROR_THRESHOLD); |
| 928 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 943 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 929 | 944 |
| 930 to = Transform(); | 945 to = Transform(); |
| 931 to.PreconcatRotateAbout(Point3F(1, 0, 0), 90); | 946 to.RotateAbout(Vector3dF(1, 0, 0), 90); |
| 932 to.Blend(from, 1); | 947 to.Blend(from, 1); |
| 933 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD); | 948 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD); |
| 934 EXPECT_ROW2_NEAR(0, 0, -1, 0, to, ERROR_THRESHOLD); | 949 EXPECT_ROW2_NEAR(0, 0, -1, 0, to, ERROR_THRESHOLD); |
| 935 EXPECT_ROW3_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD); | 950 EXPECT_ROW3_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD); |
| 936 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 951 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 937 } | 952 } |
| 938 | 953 |
| 939 TEST(XFormTest, VerifyBlendForRotationAboutY) | 954 TEST(XFormTest, VerifyBlendForRotationAboutY) |
| 940 { | 955 { |
| 941 Transform from; | 956 Transform from; |
| 942 from.PreconcatRotateAbout(Point3F(0, 1, 0), 0); | 957 from.RotateAbout(Vector3dF(0, 1, 0), 0); |
| 943 | 958 |
| 944 Transform to; | 959 Transform to; |
| 945 | 960 |
| 946 to.PreconcatRotateAbout(Point3F(0, 1, 0), 90); | 961 to.RotateAbout(Vector3dF(0, 1, 0), 90); |
| 947 to.Blend(from, 0); | 962 to.Blend(from, 0); |
| 948 EXPECT_EQ(from, to); | 963 EXPECT_EQ(from, to); |
| 949 | 964 |
| 950 double expectedRotationAngle = 22.5 * M_PI / 180.0; | 965 double expectedRotationAngle = 22.5 * M_PI / 180.0; |
| 951 to = Transform(); | 966 to = Transform(); |
| 952 to.PreconcatRotateAbout(Point3F(0, 1, 0), 90); | 967 to.RotateAbout(Vector3dF(0, 1, 0), 90); |
| 953 to.Blend(from, 0.25); | 968 to.Blend(from, 0.25); |
| 954 EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle), | 969 EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle), |
| 955 0, | 970 0, |
| 956 std::sin(expectedRotationAngle), | 971 std::sin(expectedRotationAngle), |
| 957 0, | 972 0, |
| 958 to, | 973 to, |
| 959 ERROR_THRESHOLD); | 974 ERROR_THRESHOLD); |
| 960 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD); | 975 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD); |
| 961 EXPECT_ROW3_NEAR(-std::sin(expectedRotationAngle), | 976 EXPECT_ROW3_NEAR(-std::sin(expectedRotationAngle), |
| 962 0, | 977 0, |
| 963 std::cos(expectedRotationAngle), | 978 std::cos(expectedRotationAngle), |
| 964 0, | 979 0, |
| 965 to, | 980 to, |
| 966 ERROR_THRESHOLD); | 981 ERROR_THRESHOLD); |
| 967 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 982 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 968 | 983 |
| 969 expectedRotationAngle = 45 * M_PI / 180.0; | 984 expectedRotationAngle = 45 * M_PI / 180.0; |
| 970 to = Transform(); | 985 to = Transform(); |
| 971 to.PreconcatRotateAbout(Point3F(0, 1, 0), 90); | 986 to.RotateAbout(Vector3dF(0, 1, 0), 90); |
| 972 to.Blend(from, 0.5); | 987 to.Blend(from, 0.5); |
| 973 EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle), | 988 EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle), |
| 974 0, | 989 0, |
| 975 std::sin(expectedRotationAngle), | 990 std::sin(expectedRotationAngle), |
| 976 0, | 991 0, |
| 977 to, | 992 to, |
| 978 ERROR_THRESHOLD); | 993 ERROR_THRESHOLD); |
| 979 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD); | 994 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD); |
| 980 EXPECT_ROW3_NEAR(-std::sin(expectedRotationAngle), | 995 EXPECT_ROW3_NEAR(-std::sin(expectedRotationAngle), |
| 981 0, | 996 0, |
| 982 std::cos(expectedRotationAngle), | 997 std::cos(expectedRotationAngle), |
| 983 0, | 998 0, |
| 984 to, | 999 to, |
| 985 ERROR_THRESHOLD); | 1000 ERROR_THRESHOLD); |
| 986 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 1001 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 987 | 1002 |
| 988 to = Transform(); | 1003 to = Transform(); |
| 989 to.PreconcatRotateAbout(Point3F(0, 1, 0), 90); | 1004 to.RotateAbout(Vector3dF(0, 1, 0), 90); |
| 990 to.Blend(from, 1); | 1005 to.Blend(from, 1); |
| 991 EXPECT_ROW1_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD); | 1006 EXPECT_ROW1_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD); |
| 992 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD); | 1007 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD); |
| 993 EXPECT_ROW3_NEAR(-1, 0, 0, 0, to, ERROR_THRESHOLD); | 1008 EXPECT_ROW3_NEAR(-1, 0, 0, 0, to, ERROR_THRESHOLD); |
| 994 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 1009 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 995 } | 1010 } |
| 996 | 1011 |
| 997 TEST(XFormTest, VerifyBlendForRotationAboutZ) | 1012 TEST(XFormTest, VerifyBlendForRotationAboutZ) |
| 998 { | 1013 { |
| 999 Transform from; | 1014 Transform from; |
| 1000 from.PreconcatRotateAbout(Point3F(0, 0, 1), 0); | 1015 from.RotateAbout(Vector3dF(0, 0, 1), 0); |
| 1001 | 1016 |
| 1002 Transform to; | 1017 Transform to; |
| 1003 | 1018 |
| 1004 to.PreconcatRotateAbout(Point3F(0, 0, 1), 90); | 1019 to.RotateAbout(Vector3dF(0, 0, 1), 90); |
| 1005 to.Blend(from, 0); | 1020 to.Blend(from, 0); |
| 1006 EXPECT_EQ(from, to); | 1021 EXPECT_EQ(from, to); |
| 1007 | 1022 |
| 1008 double expectedRotationAngle = 22.5 * M_PI / 180.0; | 1023 double expectedRotationAngle = 22.5 * M_PI / 180.0; |
| 1009 to = Transform(); | 1024 to = Transform(); |
| 1010 to.PreconcatRotateAbout(Point3F(0, 0, 1), 90); | 1025 to.RotateAbout(Vector3dF(0, 0, 1), 90); |
| 1011 to.Blend(from, 0.25); | 1026 to.Blend(from, 0.25); |
| 1012 EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle), | 1027 EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle), |
| 1013 -std::sin(expectedRotationAngle), | 1028 -std::sin(expectedRotationAngle), |
| 1014 0, | 1029 0, |
| 1015 0, | 1030 0, |
| 1016 to, | 1031 to, |
| 1017 ERROR_THRESHOLD); | 1032 ERROR_THRESHOLD); |
| 1018 EXPECT_ROW2_NEAR(std::sin(expectedRotationAngle), | 1033 EXPECT_ROW2_NEAR(std::sin(expectedRotationAngle), |
| 1019 std::cos(expectedRotationAngle), | 1034 std::cos(expectedRotationAngle), |
| 1020 0, | 1035 0, |
| 1021 0, | 1036 0, |
| 1022 to, | 1037 to, |
| 1023 ERROR_THRESHOLD); | 1038 ERROR_THRESHOLD); |
| 1024 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD); | 1039 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD); |
| 1025 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 1040 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 1026 | 1041 |
| 1027 expectedRotationAngle = 45 * M_PI / 180.0; | 1042 expectedRotationAngle = 45 * M_PI / 180.0; |
| 1028 to = Transform(); | 1043 to = Transform(); |
| 1029 to.PreconcatRotateAbout(Point3F(0, 0, 1), 90); | 1044 to.RotateAbout(Vector3dF(0, 0, 1), 90); |
| 1030 to.Blend(from, 0.5); | 1045 to.Blend(from, 0.5); |
| 1031 EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle), | 1046 EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle), |
| 1032 -std::sin(expectedRotationAngle), | 1047 -std::sin(expectedRotationAngle), |
| 1033 0, | 1048 0, |
| 1034 0, | 1049 0, |
| 1035 to, | 1050 to, |
| 1036 ERROR_THRESHOLD); | 1051 ERROR_THRESHOLD); |
| 1037 EXPECT_ROW2_NEAR(std::sin(expectedRotationAngle), | 1052 EXPECT_ROW2_NEAR(std::sin(expectedRotationAngle), |
| 1038 std::cos(expectedRotationAngle), | 1053 std::cos(expectedRotationAngle), |
| 1039 0, | 1054 0, |
| 1040 0, | 1055 0, |
| 1041 to, | 1056 to, |
| 1042 ERROR_THRESHOLD); | 1057 ERROR_THRESHOLD); |
| 1043 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD); | 1058 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD); |
| 1044 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 1059 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 1045 | 1060 |
| 1046 to = Transform(); | 1061 to = Transform(); |
| 1047 to.PreconcatRotateAbout(Point3F(0, 0, 1), 90); | 1062 to.RotateAbout(Vector3dF(0, 0, 1), 90); |
| 1048 to.Blend(from, 1); | 1063 to.Blend(from, 1); |
| 1049 EXPECT_ROW1_NEAR(0, -1, 0, 0, to, ERROR_THRESHOLD); | 1064 EXPECT_ROW1_NEAR(0, -1, 0, 0, to, ERROR_THRESHOLD); |
| 1050 EXPECT_ROW2_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD); | 1065 EXPECT_ROW2_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD); |
| 1051 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD); | 1066 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD); |
| 1052 EXPECT_ROW4_EQ(0, 0, 0, 1, to); | 1067 EXPECT_ROW4_EQ(0, 0, 0, 1, to); |
| 1053 } | 1068 } |
| 1054 | 1069 |
| 1055 TEST(XFormTest, VerifyBlendForCompositeTransform) | 1070 TEST(XFormTest, VerifyBlendForCompositeTransform) |
| 1056 { | 1071 { |
| 1057 // Verify that the.Blending was done with a decomposition in correct order | 1072 // Verify that the.Blending was done with a decomposition in correct order |
| 1058 // by blending a composite transform. Using matrix x vector notation | 1073 // by blending a composite transform. Using matrix x vector notation |
| 1059 // (Ax = b, where x is column vector), the ordering should be: | 1074 // (Ax = b, where x is column vector), the ordering should be: |
| 1060 // perspective * translation * rotation * skew * scale | 1075 // perspective * translation * rotation * skew * scale |
| 1061 // | 1076 // |
| 1062 // It is not as important (or meaningful) to check intermediate | 1077 // It is not as important (or meaningful) to check intermediate |
| 1063 // interpolations; order of operations will be tested well enough by the | 1078 // interpolations; order of operations will be tested well enough by the |
| 1064 // end cases that are easier to specify. | 1079 // end cases that are easier to specify. |
| 1065 | 1080 |
| 1066 Transform from; | 1081 Transform from; |
| 1067 Transform to; | 1082 Transform to; |
| 1068 | 1083 |
| 1069 Transform expectedEndOfAnimation; | 1084 Transform expectedEndOfAnimation; |
| 1070 expectedEndOfAnimation.PreconcatPerspectiveDepth(1); | 1085 expectedEndOfAnimation.ApplyPerspectiveDepth(1); |
| 1071 expectedEndOfAnimation.PreconcatTranslate3d(10, 20, 30); | 1086 expectedEndOfAnimation.Translate3d(10, 20, 30); |
| 1072 expectedEndOfAnimation.PreconcatRotateAbout(Point3F(0, 0, 1), 25); | 1087 expectedEndOfAnimation.RotateAbout(Vector3dF(0, 0, 1), 25); |
| 1073 expectedEndOfAnimation.PreconcatSkewY(45); | 1088 expectedEndOfAnimation.SkewY(45); |
| 1074 expectedEndOfAnimation.PreconcatScale3d(6, 7, 8); | 1089 expectedEndOfAnimation.Scale3d(6, 7, 8); |
| 1075 | 1090 |
| 1076 to = expectedEndOfAnimation; | 1091 to = expectedEndOfAnimation; |
| 1077 to.Blend(from, 0); | 1092 to.Blend(from, 0); |
| 1078 EXPECT_EQ(from, to); | 1093 EXPECT_EQ(from, to); |
| 1079 | 1094 |
| 1080 to = expectedEndOfAnimation; | 1095 to = expectedEndOfAnimation; |
| 1081 // We short circuit if blend is >= 1, so to check the numerics, we will | 1096 // We short circuit if blend is >= 1, so to check the numerics, we will |
| 1082 // check that we get close to what we expect when we're nearly done | 1097 // check that we get close to what we expect when we're nearly done |
| 1083 // interpolating. | 1098 // interpolating. |
| 1084 to.Blend(from, .99999); | 1099 to.Blend(from, .99999); |
| 1085 | 1100 |
| 1086 // Recomposing the matrix results in a normalized matrix, so to verify we | 1101 // Recomposing the matrix results in a normalized matrix, so to verify we |
| 1087 // need to normalize the expectedEndOfAnimation before comparing elements. | 1102 // need to normalize the expectedEndOfAnimation before comparing elements. |
| 1088 // Normalizing means dividing everything by expectedEndOfAnimation.m44(). | 1103 // Normalizing means dividing everything by expectedEndOfAnimation.m44(). |
| 1089 Transform normalizedExpectedEndOfAnimation = expectedEndOfAnimation; | 1104 Transform normalizedExpectedEndOfAnimation = expectedEndOfAnimation; |
| 1090 Transform normalizationMatrix; | 1105 Transform normalizationMatrix; |
| 1091 normalizationMatrix.matrix().set( | 1106 normalizationMatrix.matrix().set( |
| 1092 0, 0, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3))); | 1107 0, 0, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3))); |
| 1093 normalizationMatrix.matrix().set( | 1108 normalizationMatrix.matrix().set( |
| 1094 1, 1, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3))); | 1109 1, 1, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3))); |
| 1095 normalizationMatrix.matrix().set( | 1110 normalizationMatrix.matrix().set( |
| 1096 2, 2, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3))); | 1111 2, 2, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3))); |
| 1097 normalizationMatrix.matrix().set( | 1112 normalizationMatrix.matrix().set( |
| 1098 3, 3, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3))); | 1113 3, 3, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3))); |
| 1099 normalizedExpectedEndOfAnimation.PreconcatTransform(normalizationMatrix); | 1114 normalizedExpectedEndOfAnimation.PreconcatTransform(normalizationMatrix); |
| 1100 | 1115 |
| 1101 EXPECT_TRUE(MatricesAreNearlyEqual(normalizedExpectedEndOfAnimation, to)); | 1116 EXPECT_TRUE(MatricesAreNearlyEqual(normalizedExpectedEndOfAnimation, to)); |
| 1102 } | 1117 } |
| 1103 | 1118 |
| 1104 TEST(XFormTest, SetScaleZ) | |
| 1105 { | |
| 1106 Transform scaled; | |
| 1107 scaled.SetScaleZ(2); | |
| 1108 EXPECT_FLOAT_EQ(2, scaled.matrix().get(2, 2)); | |
| 1109 } | |
| 1110 | |
| 1111 TEST(XFormTest, SetTranslateZ) | |
| 1112 { | |
| 1113 Transform translated; | |
| 1114 translated.SetTranslateZ(2); | |
| 1115 EXPECT_FLOAT_EQ(2, translated.matrix().get(2, 3)); | |
| 1116 } | |
| 1117 | |
| 1118 TEST(XFormTest, DecomposedTransformCtor) | 1119 TEST(XFormTest, DecomposedTransformCtor) |
| 1119 { | 1120 { |
| 1120 DecomposedTransform decomp; | 1121 DecomposedTransform decomp; |
| 1121 for (int i = 0; i < 3; ++i) { | 1122 for (int i = 0; i < 3; ++i) { |
| 1122 EXPECT_EQ(0.0, decomp.translate[i]); | 1123 EXPECT_EQ(0.0, decomp.translate[i]); |
| 1123 EXPECT_EQ(1.0, decomp.scale[i]); | 1124 EXPECT_EQ(1.0, decomp.scale[i]); |
| 1124 EXPECT_EQ(0.0, decomp.skew[i]); | 1125 EXPECT_EQ(0.0, decomp.skew[i]); |
| 1125 EXPECT_EQ(0.0, decomp.quaternion[i]); | 1126 EXPECT_EQ(0.0, decomp.quaternion[i]); |
| 1126 EXPECT_EQ(0.0, decomp.perspective[i]); | 1127 EXPECT_EQ(0.0, decomp.perspective[i]); |
| 1127 } | 1128 } |
| 1128 EXPECT_EQ(1.0, decomp.quaternion[3]); | 1129 EXPECT_EQ(1.0, decomp.quaternion[3]); |
| 1129 EXPECT_EQ(1.0, decomp.perspective[3]); | 1130 EXPECT_EQ(1.0, decomp.perspective[3]); |
| 1130 Transform identity; | 1131 Transform identity; |
| 1131 Transform composed = ComposeTransform(decomp); | 1132 Transform composed = ComposeTransform(decomp); |
| 1132 EXPECT_TRUE(MatricesAreNearlyEqual(identity, composed)); | 1133 EXPECT_TRUE(MatricesAreNearlyEqual(identity, composed)); |
| 1133 } | 1134 } |
| 1134 | 1135 |
| 1135 } // namespace | 1136 } // namespace |
| 1136 | 1137 |
| 1137 } // namespace gfx | 1138 } // namespace gfx |
| OLD | NEW |