summaryrefslogtreecommitdiff
path: root/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp')
-rw-r--r--Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp116
1 files changed, 56 insertions, 60 deletions
diff --git a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
index 1cc0a220e..8e6c14e5f 100644
--- a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
+++ b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
@@ -727,15 +727,13 @@ TransformationMatrix& TransformationMatrix::scale3d(double sx, double sy, double
TransformationMatrix& TransformationMatrix::rotate3d(double x, double y, double z, double angle)
{
- // angles are in degrees. Switch to radians
+ // Angles are in degrees. Switch to radians.
angle = deg2rad(angle);
+
+ double sinTheta = sin(angle);
+ double cosTheta = cos(angle);
- angle /= 2.0f;
- double sinA = sin(angle);
- double cosA = cos(angle);
- double sinA2 = sinA * sinA;
-
- // normalize
+ // Normalize the axis of rotation
double length = sqrt(x * x + y * y + z * z);
if (length == 0) {
// bad vector, just use something reasonable
@@ -750,39 +748,39 @@ TransformationMatrix& TransformationMatrix::rotate3d(double x, double y, double
TransformationMatrix mat;
- // optimize case where axis is along major axis
+ // Optimize cases where the axis is along a major axis
if (x == 1.0f && y == 0.0f && z == 0.0f) {
mat.m_matrix[0][0] = 1.0f;
mat.m_matrix[0][1] = 0.0f;
mat.m_matrix[0][2] = 0.0f;
mat.m_matrix[1][0] = 0.0f;
- mat.m_matrix[1][1] = 1.0f - 2.0f * sinA2;
- mat.m_matrix[1][2] = 2.0f * sinA * cosA;
+ mat.m_matrix[1][1] = cosTheta;
+ mat.m_matrix[1][2] = sinTheta;
mat.m_matrix[2][0] = 0.0f;
- mat.m_matrix[2][1] = -2.0f * sinA * cosA;
- mat.m_matrix[2][2] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[2][1] = -sinTheta;
+ mat.m_matrix[2][2] = cosTheta;
mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f;
mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f;
mat.m_matrix[3][3] = 1.0f;
} else if (x == 0.0f && y == 1.0f && z == 0.0f) {
- mat.m_matrix[0][0] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[0][0] = cosTheta;
mat.m_matrix[0][1] = 0.0f;
- mat.m_matrix[0][2] = -2.0f * sinA * cosA;
+ mat.m_matrix[0][2] = -sinTheta;
mat.m_matrix[1][0] = 0.0f;
mat.m_matrix[1][1] = 1.0f;
mat.m_matrix[1][2] = 0.0f;
- mat.m_matrix[2][0] = 2.0f * sinA * cosA;
+ mat.m_matrix[2][0] = sinTheta;
mat.m_matrix[2][1] = 0.0f;
- mat.m_matrix[2][2] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[2][2] = cosTheta;
mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f;
mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f;
mat.m_matrix[3][3] = 1.0f;
} else if (x == 0.0f && y == 0.0f && z == 1.0f) {
- mat.m_matrix[0][0] = 1.0f - 2.0f * sinA2;
- mat.m_matrix[0][1] = 2.0f * sinA * cosA;
+ mat.m_matrix[0][0] = cosTheta;
+ mat.m_matrix[0][1] = sinTheta;
mat.m_matrix[0][2] = 0.0f;
- mat.m_matrix[1][0] = -2.0f * sinA * cosA;
- mat.m_matrix[1][1] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[1][0] = -sinTheta;
+ mat.m_matrix[1][1] = cosTheta;
mat.m_matrix[1][2] = 0.0f;
mat.m_matrix[2][0] = 0.0f;
mat.m_matrix[2][1] = 0.0f;
@@ -791,19 +789,23 @@ TransformationMatrix& TransformationMatrix::rotate3d(double x, double y, double
mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f;
mat.m_matrix[3][3] = 1.0f;
} else {
- double x2 = x*x;
- double y2 = y*y;
- double z2 = z*z;
-
- mat.m_matrix[0][0] = 1.0f - 2.0f * (y2 + z2) * sinA2;
- mat.m_matrix[0][1] = 2.0f * (x * y * sinA2 + z * sinA * cosA);
- mat.m_matrix[0][2] = 2.0f * (x * z * sinA2 - y * sinA * cosA);
- mat.m_matrix[1][0] = 2.0f * (y * x * sinA2 - z * sinA * cosA);
- mat.m_matrix[1][1] = 1.0f - 2.0f * (z2 + x2) * sinA2;
- mat.m_matrix[1][2] = 2.0f * (y * z * sinA2 + x * sinA * cosA);
- mat.m_matrix[2][0] = 2.0f * (z * x * sinA2 + y * sinA * cosA);
- mat.m_matrix[2][1] = 2.0f * (z * y * sinA2 - x * sinA * cosA);
- mat.m_matrix[2][2] = 1.0f - 2.0f * (x2 + y2) * sinA2;
+ // This case is the rotation about an arbitrary unit vector.
+ //
+ // Formula is adapted from Wikipedia article on Rotation matrix,
+ // http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle
+ //
+ // An alternate resource with the same matrix: http://www.fastgraph.com/makegames/3drotation/
+ //
+ double oneMinusCosTheta = 1 - cosTheta;
+ mat.m_matrix[0][0] = cosTheta + x * x * oneMinusCosTheta;
+ mat.m_matrix[0][1] = y * x * oneMinusCosTheta + z * sinTheta;
+ mat.m_matrix[0][2] = z * x * oneMinusCosTheta - y * sinTheta;
+ mat.m_matrix[1][0] = x * y * oneMinusCosTheta - z * sinTheta;
+ mat.m_matrix[1][1] = cosTheta + y * y * oneMinusCosTheta;
+ mat.m_matrix[1][2] = z * y * oneMinusCosTheta + x * sinTheta;
+ mat.m_matrix[2][0] = x * z * oneMinusCosTheta + y * sinTheta;
+ mat.m_matrix[2][1] = y * z * oneMinusCosTheta - x * sinTheta;
+ mat.m_matrix[2][2] = cosTheta + z * z * oneMinusCosTheta;
mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f;
mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f;
mat.m_matrix[3][3] = 1.0f;
@@ -814,23 +816,21 @@ TransformationMatrix& TransformationMatrix::rotate3d(double x, double y, double
TransformationMatrix& TransformationMatrix::rotate3d(double rx, double ry, double rz)
{
- // angles are in degrees. Switch to radians
+ // Angles are in degrees. Switch to radians.
rx = deg2rad(rx);
ry = deg2rad(ry);
rz = deg2rad(rz);
TransformationMatrix mat;
- rz /= 2.0f;
- double sinA = sin(rz);
- double cosA = cos(rz);
- double sinA2 = sinA * sinA;
+ double sinTheta = sin(rz);
+ double cosTheta = cos(rz);
- mat.m_matrix[0][0] = 1.0f - 2.0f * sinA2;
- mat.m_matrix[0][1] = 2.0f * sinA * cosA;
+ mat.m_matrix[0][0] = cosTheta;
+ mat.m_matrix[0][1] = sinTheta;
mat.m_matrix[0][2] = 0.0f;
- mat.m_matrix[1][0] = -2.0f * sinA * cosA;
- mat.m_matrix[1][1] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[1][0] = -sinTheta;
+ mat.m_matrix[1][1] = cosTheta;
mat.m_matrix[1][2] = 0.0f;
mat.m_matrix[2][0] = 0.0f;
mat.m_matrix[2][1] = 0.0f;
@@ -841,44 +841,40 @@ TransformationMatrix& TransformationMatrix::rotate3d(double rx, double ry, doubl
TransformationMatrix rmat(mat);
- ry /= 2.0f;
- sinA = sin(ry);
- cosA = cos(ry);
- sinA2 = sinA * sinA;
+ sinTheta = sin(ry);
+ cosTheta = cos(ry);
- mat.m_matrix[0][0] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[0][0] = cosTheta;
mat.m_matrix[0][1] = 0.0f;
- mat.m_matrix[0][2] = -2.0f * sinA * cosA;
+ mat.m_matrix[0][2] = -sinTheta;
mat.m_matrix[1][0] = 0.0f;
mat.m_matrix[1][1] = 1.0f;
mat.m_matrix[1][2] = 0.0f;
- mat.m_matrix[2][0] = 2.0f * sinA * cosA;
+ mat.m_matrix[2][0] = sinTheta;
mat.m_matrix[2][1] = 0.0f;
- mat.m_matrix[2][2] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[2][2] = cosTheta;
mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f;
mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f;
mat.m_matrix[3][3] = 1.0f;
-
+
rmat.multiply(mat);
- rx /= 2.0f;
- sinA = sin(rx);
- cosA = cos(rx);
- sinA2 = sinA * sinA;
+ sinTheta = sin(rx);
+ cosTheta = cos(rx);
mat.m_matrix[0][0] = 1.0f;
mat.m_matrix[0][1] = 0.0f;
mat.m_matrix[0][2] = 0.0f;
mat.m_matrix[1][0] = 0.0f;
- mat.m_matrix[1][1] = 1.0f - 2.0f * sinA2;
- mat.m_matrix[1][2] = 2.0f * sinA * cosA;
+ mat.m_matrix[1][1] = cosTheta;
+ mat.m_matrix[1][2] = sinTheta;
mat.m_matrix[2][0] = 0.0f;
- mat.m_matrix[2][1] = -2.0f * sinA * cosA;
- mat.m_matrix[2][2] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[2][1] = -sinTheta;
+ mat.m_matrix[2][2] = cosTheta;
mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f;
mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f;
mat.m_matrix[3][3] = 1.0f;
-
+
rmat.multiply(mat);
multiply(rmat);