OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. |
3 * Copyright (C) 2009 Torch Mobile, Inc. | 3 * Copyright (C) 2009 Torch Mobile, Inc. |
4 * Copyright (C) 2013 Google Inc. All rights reserved. | 4 * Copyright (C) 2013 Google Inc. All rights reserved. |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 24 matching lines...) Expand all Loading... |
35 #include "platform/geometry/LayoutRect.h" | 35 #include "platform/geometry/LayoutRect.h" |
36 #include "platform/transforms/AffineTransform.h" | 36 #include "platform/transforms/AffineTransform.h" |
37 | 37 |
38 #include "wtf/Assertions.h" | 38 #include "wtf/Assertions.h" |
39 #include "wtf/MathExtras.h" | 39 #include "wtf/MathExtras.h" |
40 | 40 |
41 #if CPU(X86_64) | 41 #if CPU(X86_64) |
42 #include <emmintrin.h> | 42 #include <emmintrin.h> |
43 #endif | 43 #endif |
44 | 44 |
45 using namespace std; | |
46 | |
47 namespace blink { | 45 namespace blink { |
48 | 46 |
49 // | 47 // |
50 // Supporting Math Functions | 48 // Supporting Math Functions |
51 // | 49 // |
52 // This is a set of function from various places (attributed inline) to do thing
s like | 50 // This is a set of function from various places (attributed inline) to do thing
s like |
53 // inversion and decomposition of a 4x4 matrix. They are used throughout the cod
e | 51 // inversion and decomposition of a 4x4 matrix. They are used throughout the cod
e |
54 // | 52 // |
55 | 53 |
56 // | 54 // |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 result[1] = (p[0] * m[0][1]) + (p[1] * m[1][1]) + | 252 result[1] = (p[0] * m[0][1]) + (p[1] * m[1][1]) + |
255 (p[2] * m[2][1]) + (p[3] * m[3][1]); | 253 (p[2] * m[2][1]) + (p[3] * m[3][1]); |
256 result[2] = (p[0] * m[0][2]) + (p[1] * m[1][2]) + | 254 result[2] = (p[0] * m[0][2]) + (p[1] * m[1][2]) + |
257 (p[2] * m[2][2]) + (p[3] * m[3][2]); | 255 (p[2] * m[2][2]) + (p[3] * m[3][2]); |
258 result[3] = (p[0] * m[0][3]) + (p[1] * m[1][3]) + | 256 result[3] = (p[0] * m[0][3]) + (p[1] * m[1][3]) + |
259 (p[2] * m[2][3]) + (p[3] * m[3][3]); | 257 (p[2] * m[2][3]) + (p[3] * m[3][3]); |
260 } | 258 } |
261 | 259 |
262 static double v3Length(Vector3 a) | 260 static double v3Length(Vector3 a) |
263 { | 261 { |
264 return sqrt((a[0] * a[0]) + (a[1] * a[1]) + (a[2] * a[2])); | 262 return std::sqrt((a[0] * a[0]) + (a[1] * a[1]) + (a[2] * a[2])); |
265 } | 263 } |
266 | 264 |
267 static void v3Scale(Vector3 v, double desiredLength) | 265 static void v3Scale(Vector3 v, double desiredLength) |
268 { | 266 { |
269 double len = v3Length(v); | 267 double len = v3Length(v); |
270 if (len != 0) { | 268 if (len != 0) { |
271 double l = desiredLength / len; | 269 double l = desiredLength / len; |
272 v[0] *= l; | 270 v[0] *= l; |
273 v[1] *= l; | 271 v[1] *= l; |
274 v[2] *= l; | 272 v[2] *= l; |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 // } else { | 428 // } else { |
431 // ret.rotateX = atan2(-row[2][0], row[1][1]); | 429 // ret.rotateX = atan2(-row[2][0], row[1][1]); |
432 // ret.rotateZ = 0; | 430 // ret.rotateZ = 0; |
433 // } | 431 // } |
434 | 432 |
435 double s, t, x, y, z, w; | 433 double s, t, x, y, z, w; |
436 | 434 |
437 t = row[0][0] + row[1][1] + row[2][2] + 1.0; | 435 t = row[0][0] + row[1][1] + row[2][2] + 1.0; |
438 | 436 |
439 if (t > 1e-4) { | 437 if (t > 1e-4) { |
440 s = 0.5 / sqrt(t); | 438 s = 0.5 / std::sqrt(t); |
441 w = 0.25 / s; | 439 w = 0.25 / s; |
442 x = (row[2][1] - row[1][2]) * s; | 440 x = (row[2][1] - row[1][2]) * s; |
443 y = (row[0][2] - row[2][0]) * s; | 441 y = (row[0][2] - row[2][0]) * s; |
444 z = (row[1][0] - row[0][1]) * s; | 442 z = (row[1][0] - row[0][1]) * s; |
445 } else if (row[0][0] > row[1][1] && row[0][0] > row[2][2]) { | 443 } else if (row[0][0] > row[1][1] && row[0][0] > row[2][2]) { |
446 s = sqrt (1.0 + row[0][0] - row[1][1] - row[2][2]) * 2.0; // S=4*qx | 444 s = std::sqrt(1.0 + row[0][0] - row[1][1] - row[2][2]) * 2.0; // S=4*qx |
447 x = 0.25 * s; | 445 x = 0.25 * s; |
448 y = (row[0][1] + row[1][0]) / s; | 446 y = (row[0][1] + row[1][0]) / s; |
449 z = (row[0][2] + row[2][0]) / s; | 447 z = (row[0][2] + row[2][0]) / s; |
450 w = (row[2][1] - row[1][2]) / s; | 448 w = (row[2][1] - row[1][2]) / s; |
451 } else if (row[1][1] > row[2][2]) { | 449 } else if (row[1][1] > row[2][2]) { |
452 s = sqrt (1.0 + row[1][1] - row[0][0] - row[2][2]) * 2.0; // S=4*qy | 450 s = std::sqrt(1.0 + row[1][1] - row[0][0] - row[2][2]) * 2.0; // S=4*qy |
453 x = (row[0][1] + row[1][0]) / s; | 451 x = (row[0][1] + row[1][0]) / s; |
454 y = 0.25 * s; | 452 y = 0.25 * s; |
455 z = (row[1][2] + row[2][1]) / s; | 453 z = (row[1][2] + row[2][1]) / s; |
456 w = (row[0][2] - row[2][0]) / s; | 454 w = (row[0][2] - row[2][0]) / s; |
457 } else { | 455 } else { |
458 s = sqrt(1.0 + row[2][2] - row[0][0] - row[1][1]) * 2.0; // S=4*qz | 456 s = std::sqrt(1.0 + row[2][2] - row[0][0] - row[1][1]) * 2.0; // S=4*qz |
459 x = (row[0][2] + row[2][0]) / s; | 457 x = (row[0][2] + row[2][0]) / s; |
460 y = (row[1][2] + row[2][1]) / s; | 458 y = (row[1][2] + row[2][1]) / s; |
461 z = 0.25 * s; | 459 z = 0.25 * s; |
462 w = (row[1][0] - row[0][1]) / s; | 460 w = (row[1][0] - row[0][1]) / s; |
463 } | 461 } |
464 | 462 |
465 result.quaternionX = x; | 463 result.quaternionX = x; |
466 result.quaternionY = y; | 464 result.quaternionY = y; |
467 result.quaternionZ = z; | 465 result.quaternionZ = z; |
468 result.quaternionW = w; | 466 result.quaternionW = w; |
(...skipping 17 matching lines...) Expand all Loading... |
486 angle = ax * bx + ay * by + az * bz + aw * bw; | 484 angle = ax * bx + ay * by + az * bz + aw * bw; |
487 | 485 |
488 if (angle < 0.0) { | 486 if (angle < 0.0) { |
489 ax = -ax; ay = -ay; | 487 ax = -ax; ay = -ay; |
490 az = -az; aw = -aw; | 488 az = -az; aw = -aw; |
491 angle = -angle; | 489 angle = -angle; |
492 } | 490 } |
493 | 491 |
494 if (angle + 1.0 > .05) { | 492 if (angle + 1.0 > .05) { |
495 if (1.0 - angle >= .05) { | 493 if (1.0 - angle >= .05) { |
496 th = acos (angle); | 494 th = std::acos(angle); |
497 invth = 1.0 / sin (th); | 495 invth = 1.0 / std::sin(th); |
498 scale = sin (th * (1.0 - t)) * invth; | 496 scale = std::sin(th * (1.0 - t)) * invth; |
499 invscale = sin (th * t) * invth; | 497 invscale = std::sin(th * t) * invth; |
500 } else { | 498 } else { |
501 scale = 1.0 - t; | 499 scale = 1.0 - t; |
502 invscale = t; | 500 invscale = t; |
503 } | 501 } |
504 } else { | 502 } else { |
505 bx = -ay; | 503 bx = -ay; |
506 by = ax; | 504 by = ax; |
507 bz = -aw; | 505 bz = -aw; |
508 bw = az; | 506 bw = az; |
509 scale = sin(piDouble * (.5 - t)); | 507 scale = std::sin(piDouble * (.5 - t)); |
510 invscale = sin (piDouble * t); | 508 invscale = std::sin(piDouble * t); |
511 } | 509 } |
512 | 510 |
513 cx = ax * scale + bx * invscale; | 511 cx = ax * scale + bx * invscale; |
514 cy = ay * scale + by * invscale; | 512 cy = ay * scale + by * invscale; |
515 cz = az * scale + bz * invscale; | 513 cz = az * scale + bz * invscale; |
516 cw = aw * scale + bw * invscale; | 514 cw = aw * scale + bw * invscale; |
517 | 515 |
518 qa[0] = cx; qa[1] = cy; qa[2] = cz; qa[3] = cw; | 516 qa[0] = cx; qa[1] = cy; qa[2] = cz; qa[3] = cw; |
519 } | 517 } |
520 | 518 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 bool everythingWasClipped = clamped1 && clamped2 && clamped3 && clamped4; | 613 bool everythingWasClipped = clamped1 && clamped2 && clamped3 && clamped4; |
616 if (everythingWasClipped) | 614 if (everythingWasClipped) |
617 return FloatQuad(); | 615 return FloatQuad(); |
618 | 616 |
619 return projectedQuad; | 617 return projectedQuad; |
620 } | 618 } |
621 | 619 |
622 static float clampEdgeValue(float f) | 620 static float clampEdgeValue(float f) |
623 { | 621 { |
624 ASSERT(!std::isnan(f)); | 622 ASSERT(!std::isnan(f)); |
625 return min<float>(max<float>(f, (-LayoutUnit::max() / 2).toFloat()), (Layout
Unit::max() / 2).toFloat()); | 623 return std::min<float>(std::max<float>(f, (-LayoutUnit::max() / 2).toFloat()
), (LayoutUnit::max() / 2).toFloat()); |
626 } | 624 } |
627 | 625 |
628 LayoutRect TransformationMatrix::clampedBoundsOfProjectedQuad(const FloatQuad& q
) const | 626 LayoutRect TransformationMatrix::clampedBoundsOfProjectedQuad(const FloatQuad& q
) const |
629 { | 627 { |
630 FloatRect mappedQuadBounds = projectQuad(q).boundingBox(); | 628 FloatRect mappedQuadBounds = projectQuad(q).boundingBox(); |
631 | 629 |
632 float left = clampEdgeValue(floorf(mappedQuadBounds.x())); | 630 float left = clampEdgeValue(floorf(mappedQuadBounds.x())); |
633 float top = clampEdgeValue(floorf(mappedQuadBounds.y())); | 631 float top = clampEdgeValue(floorf(mappedQuadBounds.y())); |
634 | 632 |
635 float right; | 633 float right; |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 m_matrix[2][0] *= sz; | 752 m_matrix[2][0] *= sz; |
755 m_matrix[2][1] *= sz; | 753 m_matrix[2][1] *= sz; |
756 m_matrix[2][2] *= sz; | 754 m_matrix[2][2] *= sz; |
757 m_matrix[2][3] *= sz; | 755 m_matrix[2][3] *= sz; |
758 return *this; | 756 return *this; |
759 } | 757 } |
760 | 758 |
761 TransformationMatrix& TransformationMatrix::rotate3d(double x, double y, double
z, double angle) | 759 TransformationMatrix& TransformationMatrix::rotate3d(double x, double y, double
z, double angle) |
762 { | 760 { |
763 // Normalize the axis of rotation | 761 // Normalize the axis of rotation |
764 double length = sqrt(x * x + y * y + z * z); | 762 double length = std::sqrt(x * x + y * y + z * z); |
765 if (length == 0) { | 763 if (length == 0) { |
766 // A direction vector that cannot be normalized, such as [0, 0, 0], will
cause the rotation to not be applied. | 764 // A direction vector that cannot be normalized, such as [0, 0, 0], will
cause the rotation to not be applied. |
767 return *this; | 765 return *this; |
768 } else if (length != 1) { | 766 } else if (length != 1) { |
769 x /= length; | 767 x /= length; |
770 y /= length; | 768 y /= length; |
771 z /= length; | 769 z /= length; |
772 } | 770 } |
773 | 771 |
774 // Angles are in degrees. Switch to radians. | 772 // Angles are in degrees. Switch to radians. |
775 angle = deg2rad(angle); | 773 angle = deg2rad(angle); |
776 | 774 |
777 double sinTheta = sin(angle); | 775 double sinTheta = std::sin(angle); |
778 double cosTheta = cos(angle); | 776 double cosTheta = std::cos(angle); |
779 | 777 |
780 TransformationMatrix mat; | 778 TransformationMatrix mat; |
781 | 779 |
782 // Optimize cases where the axis is along a major axis | 780 // Optimize cases where the axis is along a major axis |
783 if (x == 1.0 && y == 0.0 && z == 0.0) { | 781 if (x == 1.0 && y == 0.0 && z == 0.0) { |
784 mat.m_matrix[0][0] = 1.0; | 782 mat.m_matrix[0][0] = 1.0; |
785 mat.m_matrix[0][1] = 0.0; | 783 mat.m_matrix[0][1] = 0.0; |
786 mat.m_matrix[0][2] = 0.0; | 784 mat.m_matrix[0][2] = 0.0; |
787 mat.m_matrix[1][0] = 0.0; | 785 mat.m_matrix[1][0] = 0.0; |
788 mat.m_matrix[1][1] = cosTheta; | 786 mat.m_matrix[1][1] = cosTheta; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
847 | 845 |
848 TransformationMatrix& TransformationMatrix::rotate3d(double rx, double ry, doubl
e rz) | 846 TransformationMatrix& TransformationMatrix::rotate3d(double rx, double ry, doubl
e rz) |
849 { | 847 { |
850 // Angles are in degrees. Switch to radians. | 848 // Angles are in degrees. Switch to radians. |
851 rx = deg2rad(rx); | 849 rx = deg2rad(rx); |
852 ry = deg2rad(ry); | 850 ry = deg2rad(ry); |
853 rz = deg2rad(rz); | 851 rz = deg2rad(rz); |
854 | 852 |
855 TransformationMatrix mat; | 853 TransformationMatrix mat; |
856 | 854 |
857 double sinTheta = sin(rz); | 855 double sinTheta = std::sin(rz); |
858 double cosTheta = cos(rz); | 856 double cosTheta = std::cos(rz); |
859 | 857 |
860 mat.m_matrix[0][0] = cosTheta; | 858 mat.m_matrix[0][0] = cosTheta; |
861 mat.m_matrix[0][1] = sinTheta; | 859 mat.m_matrix[0][1] = sinTheta; |
862 mat.m_matrix[0][2] = 0.0; | 860 mat.m_matrix[0][2] = 0.0; |
863 mat.m_matrix[1][0] = -sinTheta; | 861 mat.m_matrix[1][0] = -sinTheta; |
864 mat.m_matrix[1][1] = cosTheta; | 862 mat.m_matrix[1][1] = cosTheta; |
865 mat.m_matrix[1][2] = 0.0; | 863 mat.m_matrix[1][2] = 0.0; |
866 mat.m_matrix[2][0] = 0.0; | 864 mat.m_matrix[2][0] = 0.0; |
867 mat.m_matrix[2][1] = 0.0; | 865 mat.m_matrix[2][1] = 0.0; |
868 mat.m_matrix[2][2] = 1.0; | 866 mat.m_matrix[2][2] = 1.0; |
869 mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; | 867 mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; |
870 mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; | 868 mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; |
871 mat.m_matrix[3][3] = 1.0; | 869 mat.m_matrix[3][3] = 1.0; |
872 | 870 |
873 TransformationMatrix rmat(mat); | 871 TransformationMatrix rmat(mat); |
874 | 872 |
875 sinTheta = sin(ry); | 873 sinTheta = std::sin(ry); |
876 cosTheta = cos(ry); | 874 cosTheta = std::cos(ry); |
877 | 875 |
878 mat.m_matrix[0][0] = cosTheta; | 876 mat.m_matrix[0][0] = cosTheta; |
879 mat.m_matrix[0][1] = 0.0; | 877 mat.m_matrix[0][1] = 0.0; |
880 mat.m_matrix[0][2] = -sinTheta; | 878 mat.m_matrix[0][2] = -sinTheta; |
881 mat.m_matrix[1][0] = 0.0; | 879 mat.m_matrix[1][0] = 0.0; |
882 mat.m_matrix[1][1] = 1.0; | 880 mat.m_matrix[1][1] = 1.0; |
883 mat.m_matrix[1][2] = 0.0; | 881 mat.m_matrix[1][2] = 0.0; |
884 mat.m_matrix[2][0] = sinTheta; | 882 mat.m_matrix[2][0] = sinTheta; |
885 mat.m_matrix[2][1] = 0.0; | 883 mat.m_matrix[2][1] = 0.0; |
886 mat.m_matrix[2][2] = cosTheta; | 884 mat.m_matrix[2][2] = cosTheta; |
887 mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; | 885 mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; |
888 mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; | 886 mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; |
889 mat.m_matrix[3][3] = 1.0; | 887 mat.m_matrix[3][3] = 1.0; |
890 | 888 |
891 rmat.multiply(mat); | 889 rmat.multiply(mat); |
892 | 890 |
893 sinTheta = sin(rx); | 891 sinTheta = std::sin(rx); |
894 cosTheta = cos(rx); | 892 cosTheta = std::cos(rx); |
895 | 893 |
896 mat.m_matrix[0][0] = 1.0; | 894 mat.m_matrix[0][0] = 1.0; |
897 mat.m_matrix[0][1] = 0.0; | 895 mat.m_matrix[0][1] = 0.0; |
898 mat.m_matrix[0][2] = 0.0; | 896 mat.m_matrix[0][2] = 0.0; |
899 mat.m_matrix[1][0] = 0.0; | 897 mat.m_matrix[1][0] = 0.0; |
900 mat.m_matrix[1][1] = cosTheta; | 898 mat.m_matrix[1][1] = cosTheta; |
901 mat.m_matrix[1][2] = sinTheta; | 899 mat.m_matrix[1][2] = sinTheta; |
902 mat.m_matrix[2][0] = 0.0; | 900 mat.m_matrix[2][0] = 0.0; |
903 mat.m_matrix[2][1] = -sinTheta; | 901 mat.m_matrix[2][1] = -sinTheta; |
904 mat.m_matrix[2][2] = cosTheta; | 902 mat.m_matrix[2][2] = cosTheta; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 return *this; | 960 return *this; |
963 } | 961 } |
964 | 962 |
965 TransformationMatrix& TransformationMatrix::skew(double sx, double sy) | 963 TransformationMatrix& TransformationMatrix::skew(double sx, double sy) |
966 { | 964 { |
967 // angles are in degrees. Switch to radians | 965 // angles are in degrees. Switch to radians |
968 sx = deg2rad(sx); | 966 sx = deg2rad(sx); |
969 sy = deg2rad(sy); | 967 sy = deg2rad(sy); |
970 | 968 |
971 TransformationMatrix mat; | 969 TransformationMatrix mat; |
972 mat.m_matrix[0][1] = tan(sy); // note that the y shear goes in the first row | 970 mat.m_matrix[0][1] = std::tan(sy); // note that the y shear goes in the firs
t row |
973 mat.m_matrix[1][0] = tan(sx); // and the x shear in the second row | 971 mat.m_matrix[1][0] = std::tan(sx); // and the x shear in the second row |
974 | 972 |
975 multiply(mat); | 973 multiply(mat); |
976 return *this; | 974 return *this; |
977 } | 975 } |
978 | 976 |
979 TransformationMatrix& TransformationMatrix::applyPerspective(double p) | 977 TransformationMatrix& TransformationMatrix::applyPerspective(double p) |
980 { | 978 { |
981 TransformationMatrix mat; | 979 TransformationMatrix mat; |
982 if (p != 0) | 980 if (p != 0) |
983 mat.m_matrix[2][3] = -1/p; | 981 mat.m_matrix[2][3] = -1/p; |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1521 ret.setDouble(2, 2, matrix.m33()); | 1519 ret.setDouble(2, 2, matrix.m33()); |
1522 ret.setDouble(2, 3, matrix.m43()); | 1520 ret.setDouble(2, 3, matrix.m43()); |
1523 ret.setDouble(3, 0, matrix.m14()); | 1521 ret.setDouble(3, 0, matrix.m14()); |
1524 ret.setDouble(3, 1, matrix.m24()); | 1522 ret.setDouble(3, 1, matrix.m24()); |
1525 ret.setDouble(3, 2, matrix.m34()); | 1523 ret.setDouble(3, 2, matrix.m34()); |
1526 ret.setDouble(3, 3, matrix.m44()); | 1524 ret.setDouble(3, 3, matrix.m44()); |
1527 return ret; | 1525 return ret; |
1528 } | 1526 } |
1529 | 1527 |
1530 } | 1528 } |
OLD | NEW |