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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 | 44 |
45 #if CPU(X86_64) | 45 #if CPU(X86_64) |
46 #include <emmintrin.h> | 46 #include <emmintrin.h> |
47 #endif | 47 #endif |
48 | 48 |
49 namespace blink { | 49 namespace blink { |
50 | 50 |
51 // | 51 // |
52 // Supporting Math Functions | 52 // Supporting Math Functions |
53 // | 53 // |
54 // This is a set of function from various places (attributed inline) to do thing
s like | 54 // This is a set of function from various places (attributed inline) to do |
55 // inversion and decomposition of a 4x4 matrix. They are used throughout the cod
e | 55 // things like inversion and decomposition of a 4x4 matrix. They are used |
| 56 // throughout the code |
56 // | 57 // |
57 | 58 |
58 // | 59 // |
59 // Adapted from Matrix Inversion by Richard Carling, Graphics Gems <http://tog.a
cm.org/GraphicsGems/index.html>. | 60 // Adapted from Matrix Inversion by Richard Carling, Graphics Gems |
| 61 // <http://tog.acm.org/GraphicsGems/index.html>. |
60 | 62 |
61 // EULA: The Graphics Gems code is copyright-protected. In other words, you cann
ot claim the text of the code | 63 // EULA: The Graphics Gems code is copyright-protected. In other words, you |
62 // as your own and resell it. Using the code is permitted in any program, produc
t, or library, non-commercial | 64 // cannot claim the text of the code as your own and resell it. Using the code |
63 // or commercial. Giving credit is not required, though is a nice gesture. The c
ode comes as-is, and if there | 65 // is permitted in any program, product, or library, non-commercial or |
64 // are any flaws or problems with any Gems code, nobody involved with Gems - aut
hors, editors, publishers, or | 66 // commercial. Giving credit is not required, though is a nice gesture. The code |
65 // webmasters - are to be held responsible. Basically, don't be a jerk, and reme
mber that anything free comes | 67 // comes as-is, and if there are any flaws or problems with any Gems code, |
66 // with no guarantee. | 68 // nobody involved with Gems - authors, editors, publishers, or webmasters - are |
| 69 // to be held responsible. Basically, don't be a jerk, and remember that |
| 70 // anything free comes with no guarantee. |
67 | 71 |
68 // A clarification about the storage of matrix elements | 72 // A clarification about the storage of matrix elements |
69 // | 73 // |
70 // This class uses a 2 dimensional array internally to store the elements of the
matrix. The first index into | 74 // This class uses a 2 dimensional array internally to store the elements of the |
71 // the array refers to the column that the element lies in; the second index ref
ers to the row. | 75 // matrix. The first index into the array refers to the column that the element |
| 76 // lies in; the second index refers to the row. |
72 // | 77 // |
73 // In other words, this is the layout of the matrix: | 78 // In other words, this is the layout of the matrix: |
74 // | 79 // |
75 // | m_matrix[0][0] m_matrix[1][0] m_matrix[2][0] m_matrix[3][0] | | 80 // | m_matrix[0][0] m_matrix[1][0] m_matrix[2][0] m_matrix[3][0] | |
76 // | m_matrix[0][1] m_matrix[1][1] m_matrix[2][1] m_matrix[3][1] | | 81 // | m_matrix[0][1] m_matrix[1][1] m_matrix[2][1] m_matrix[3][1] | |
77 // | m_matrix[0][2] m_matrix[1][2] m_matrix[2][2] m_matrix[3][2] | | 82 // | m_matrix[0][2] m_matrix[1][2] m_matrix[2][2] m_matrix[3][2] | |
78 // | m_matrix[0][3] m_matrix[1][3] m_matrix[2][3] m_matrix[3][3] | | 83 // | m_matrix[0][3] m_matrix[1][3] m_matrix[2][3] m_matrix[3][3] | |
79 | 84 |
80 typedef double Vector4[4]; | 85 typedef double Vector4[4]; |
81 typedef double Vector3[3]; | 86 typedef double Vector3[3]; |
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 // | 669 // |
665 // Given a plane with normal Pn, and a ray starting at point R0 and | 670 // Given a plane with normal Pn, and a ray starting at point R0 and |
666 // with direction defined by the vector Rd, we can find the | 671 // with direction defined by the vector Rd, we can find the |
667 // intersection point as a distance d from R0 in units of Rd by: | 672 // intersection point as a distance d from R0 in units of Rd by: |
668 // | 673 // |
669 // d = -dot (Pn', R0) / dot (Pn', Rd) | 674 // d = -dot (Pn', R0) / dot (Pn', Rd) |
670 if (clamped) | 675 if (clamped) |
671 *clamped = false; | 676 *clamped = false; |
672 | 677 |
673 if (m33() == 0) { | 678 if (m33() == 0) { |
674 // In this case, the projection plane is parallel to the ray we are trying t
o | 679 // In this case, the projection plane is parallel to the ray we are trying |
675 // trace, and there is no well-defined value for the projection. | 680 // to trace, and there is no well-defined value for the projection. |
676 return FloatPoint(); | 681 return FloatPoint(); |
677 } | 682 } |
678 | 683 |
679 double x = p.x(); | 684 double x = p.x(); |
680 double y = p.y(); | 685 double y = p.y(); |
681 double z = -(m13() * x + m23() * y + m43()) / m33(); | 686 double z = -(m13() * x + m23() * y + m43()) / m33(); |
682 | 687 |
683 // FIXME: use multVecMatrix() | 688 // FIXME: use multVecMatrix() |
684 double outX = x * m11() + y * m21() + z * m31() + m41(); | 689 double outX = x * m11() + y * m21() + z * m31() + m41(); |
685 double outY = x * m12() + y * m22() + z * m32() + m42(); | 690 double outY = x * m12() + y * m22() + z * m32() + m42(); |
686 | 691 |
687 double w = x * m14() + y * m24() + z * m34() + m44(); | 692 double w = x * m14() + y * m24() + z * m34() + m44(); |
688 if (w <= 0) { | 693 if (w <= 0) { |
689 // Using int max causes overflow when other code uses the projected point. T
o | 694 // Using int max causes overflow when other code uses the projected point. |
690 // represent infinity yet reduce the risk of overflow, we use a large but | 695 // To represent infinity yet reduce the risk of overflow, we use a large but |
691 // not-too-large number here when clamping. | 696 // not-too-large number here when clamping. |
692 const int largeNumber = 100000000 / kFixedPointDenominator; | 697 const int largeNumber = 100000000 / kFixedPointDenominator; |
693 outX = copysign(largeNumber, outX); | 698 outX = copysign(largeNumber, outX); |
694 outY = copysign(largeNumber, outY); | 699 outY = copysign(largeNumber, outY); |
695 if (clamped) | 700 if (clamped) |
696 *clamped = true; | 701 *clamped = true; |
697 } else if (w != 1) { | 702 } else if (w != 1) { |
698 outX /= w; | 703 outX /= w; |
699 outY /= w; | 704 outY /= w; |
700 } | 705 } |
(...skipping 11 matching lines...) Expand all Loading... |
712 bool clamped4 = false; | 717 bool clamped4 = false; |
713 | 718 |
714 projectedQuad.setP1(projectPoint(q.p1(), &clamped1)); | 719 projectedQuad.setP1(projectPoint(q.p1(), &clamped1)); |
715 projectedQuad.setP2(projectPoint(q.p2(), &clamped2)); | 720 projectedQuad.setP2(projectPoint(q.p2(), &clamped2)); |
716 projectedQuad.setP3(projectPoint(q.p3(), &clamped3)); | 721 projectedQuad.setP3(projectPoint(q.p3(), &clamped3)); |
717 projectedQuad.setP4(projectPoint(q.p4(), &clamped4)); | 722 projectedQuad.setP4(projectPoint(q.p4(), &clamped4)); |
718 | 723 |
719 if (clamped) | 724 if (clamped) |
720 *clamped = clamped1 || clamped2 || clamped3 || clamped4; | 725 *clamped = clamped1 || clamped2 || clamped3 || clamped4; |
721 | 726 |
722 // If all points on the quad had w < 0, then the entire quad would not be visi
ble to the projected surface. | 727 // If all points on the quad had w < 0, then the entire quad would not be |
| 728 // visible to the projected surface. |
723 bool everythingWasClipped = clamped1 && clamped2 && clamped3 && clamped4; | 729 bool everythingWasClipped = clamped1 && clamped2 && clamped3 && clamped4; |
724 if (everythingWasClipped) | 730 if (everythingWasClipped) |
725 return FloatQuad(); | 731 return FloatQuad(); |
726 | 732 |
727 return projectedQuad; | 733 return projectedQuad; |
728 } | 734 } |
729 | 735 |
730 static float clampEdgeValue(float f) { | 736 static float clampEdgeValue(float f) { |
731 ASSERT(!std::isnan(f)); | 737 ASSERT(!std::isnan(f)); |
732 return clampTo(f, (-LayoutUnit::max() / 2).toFloat(), | 738 return clampTo(f, (-LayoutUnit::max() / 2).toFloat(), |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 rotation.angle); | 877 rotation.angle); |
872 } | 878 } |
873 | 879 |
874 TransformationMatrix& TransformationMatrix::rotate3d(double x, | 880 TransformationMatrix& TransformationMatrix::rotate3d(double x, |
875 double y, | 881 double y, |
876 double z, | 882 double z, |
877 double angle) { | 883 double angle) { |
878 // Normalize the axis of rotation | 884 // Normalize the axis of rotation |
879 double length = std::sqrt(x * x + y * y + z * z); | 885 double length = std::sqrt(x * x + y * y + z * z); |
880 if (length == 0) { | 886 if (length == 0) { |
881 // A direction vector that cannot be normalized, such as [0, 0, 0], will cau
se the rotation to not be applied. | 887 // A direction vector that cannot be normalized, such as [0, 0, 0], will |
| 888 // cause the rotation to not be applied. |
882 return *this; | 889 return *this; |
883 } else if (length != 1) { | 890 } else if (length != 1) { |
884 x /= length; | 891 x /= length; |
885 y /= length; | 892 y /= length; |
886 z /= length; | 893 z /= length; |
887 } | 894 } |
888 | 895 |
889 // Angles are in degrees. Switch to radians. | 896 // Angles are in degrees. Switch to radians. |
890 angle = deg2rad(angle); | 897 angle = deg2rad(angle); |
891 | 898 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
933 mat.m_matrix[2][2] = 1.0; | 940 mat.m_matrix[2][2] = 1.0; |
934 mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; | 941 mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; |
935 mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; | 942 mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; |
936 mat.m_matrix[3][3] = 1.0; | 943 mat.m_matrix[3][3] = 1.0; |
937 } else { | 944 } else { |
938 // This case is the rotation about an arbitrary unit vector. | 945 // This case is the rotation about an arbitrary unit vector. |
939 // | 946 // |
940 // Formula is adapted from Wikipedia article on Rotation matrix, | 947 // Formula is adapted from Wikipedia article on Rotation matrix, |
941 // http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_an
d_angle | 948 // http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_an
d_angle |
942 // | 949 // |
943 // An alternate resource with the same matrix: http://www.fastgraph.com/make
games/3drotation/ | 950 // An alternate resource with the same matrix: |
| 951 // http://www.fastgraph.com/makegames/3drotation/ |
944 // | 952 // |
945 double oneMinusCosTheta = 1 - cosTheta; | 953 double oneMinusCosTheta = 1 - cosTheta; |
946 mat.m_matrix[0][0] = cosTheta + x * x * oneMinusCosTheta; | 954 mat.m_matrix[0][0] = cosTheta + x * x * oneMinusCosTheta; |
947 mat.m_matrix[0][1] = y * x * oneMinusCosTheta + z * sinTheta; | 955 mat.m_matrix[0][1] = y * x * oneMinusCosTheta + z * sinTheta; |
948 mat.m_matrix[0][2] = z * x * oneMinusCosTheta - y * sinTheta; | 956 mat.m_matrix[0][2] = z * x * oneMinusCosTheta - y * sinTheta; |
949 mat.m_matrix[1][0] = x * y * oneMinusCosTheta - z * sinTheta; | 957 mat.m_matrix[1][0] = x * y * oneMinusCosTheta - z * sinTheta; |
950 mat.m_matrix[1][1] = cosTheta + y * y * oneMinusCosTheta; | 958 mat.m_matrix[1][1] = cosTheta + y * y * oneMinusCosTheta; |
951 mat.m_matrix[1][2] = z * y * oneMinusCosTheta + x * sinTheta; | 959 mat.m_matrix[1][2] = z * y * oneMinusCosTheta + x * sinTheta; |
952 mat.m_matrix[2][0] = x * z * oneMinusCosTheta + y * sinTheta; | 960 mat.m_matrix[2][0] = x * z * oneMinusCosTheta + y * sinTheta; |
953 mat.m_matrix[2][1] = y * z * oneMinusCosTheta - x * sinTheta; | 961 mat.m_matrix[2][1] = y * z * oneMinusCosTheta - x * sinTheta; |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1179 "fmla v7.2d, v31.2d, v23.d[1] \t\n" | 1187 "fmla v7.2d, v31.2d, v23.d[1] \t\n" |
1180 | 1188 |
1181 "st1 {v0.2d - v3.2d}, [x9], 64 \t\n" | 1189 "st1 {v0.2d - v3.2d}, [x9], 64 \t\n" |
1182 "st1 {v4.2d - v7.2d}, [x9] \t\n" | 1190 "st1 {v4.2d - v7.2d}, [x9] \t\n" |
1183 : [leftMatrix] "+r"(leftMatrix), [rightMatrix] "+r"(rightMatrix) | 1191 : [leftMatrix] "+r"(leftMatrix), [rightMatrix] "+r"(rightMatrix) |
1184 : | 1192 : |
1185 : "memory", "x9", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", | 1193 : "memory", "x9", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", |
1186 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", "v0", "v1", | 1194 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", "v0", "v1", |
1187 "v2", "v3", "v4", "v5", "v6", "v7"); | 1195 "v2", "v3", "v4", "v5", "v6", "v7"); |
1188 #elif defined(TRANSFORMATION_MATRIX_USE_X86_64_SSE2) | 1196 #elif defined(TRANSFORMATION_MATRIX_USE_X86_64_SSE2) |
1189 // x86_64 has 16 XMM registers which is enough to do the multiplication fully
in registers. | 1197 // x86_64 has 16 XMM registers which is enough to do the multiplication fully |
| 1198 // in registers. |
1190 __m128d matrixBlockA = _mm_load_pd(&(m_matrix[0][0])); | 1199 __m128d matrixBlockA = _mm_load_pd(&(m_matrix[0][0])); |
1191 __m128d matrixBlockC = _mm_load_pd(&(m_matrix[1][0])); | 1200 __m128d matrixBlockC = _mm_load_pd(&(m_matrix[1][0])); |
1192 __m128d matrixBlockE = _mm_load_pd(&(m_matrix[2][0])); | 1201 __m128d matrixBlockE = _mm_load_pd(&(m_matrix[2][0])); |
1193 __m128d matrixBlockG = _mm_load_pd(&(m_matrix[3][0])); | 1202 __m128d matrixBlockG = _mm_load_pd(&(m_matrix[3][0])); |
1194 | 1203 |
1195 // First row. | 1204 // First row. |
1196 __m128d otherMatrixFirstParam = _mm_set1_pd(mat.m_matrix[0][0]); | 1205 __m128d otherMatrixFirstParam = _mm_set1_pd(mat.m_matrix[0][0]); |
1197 __m128d otherMatrixSecondParam = _mm_set1_pd(mat.m_matrix[0][1]); | 1206 __m128d otherMatrixSecondParam = _mm_set1_pd(mat.m_matrix[0][1]); |
1198 __m128d otherMatrixThirdParam = _mm_set1_pd(mat.m_matrix[0][2]); | 1207 __m128d otherMatrixThirdParam = _mm_set1_pd(mat.m_matrix[0][2]); |
1199 __m128d otherMatrixFourthParam = _mm_set1_pd(mat.m_matrix[0][3]); | 1208 __m128d otherMatrixFourthParam = _mm_set1_pd(mat.m_matrix[0][3]); |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1680 decomposition.translateZ, decomposition.scaleX, decomposition.scaleY, | 1689 decomposition.translateZ, decomposition.scaleX, decomposition.scaleY, |
1681 decomposition.scaleZ, decomposition.skewXY, decomposition.skewXZ, | 1690 decomposition.scaleZ, decomposition.skewXY, decomposition.skewXZ, |
1682 decomposition.skewYZ, decomposition.quaternionX, | 1691 decomposition.skewYZ, decomposition.quaternionX, |
1683 decomposition.quaternionY, decomposition.quaternionZ, | 1692 decomposition.quaternionY, decomposition.quaternionZ, |
1684 decomposition.quaternionW, decomposition.perspectiveX, | 1693 decomposition.quaternionW, decomposition.perspectiveX, |
1685 decomposition.perspectiveY, decomposition.perspectiveZ, | 1694 decomposition.perspectiveY, decomposition.perspectiveZ, |
1686 decomposition.perspectiveW); | 1695 decomposition.perspectiveW); |
1687 } | 1696 } |
1688 | 1697 |
1689 } // namespace blink | 1698 } // namespace blink |
OLD | NEW |