summaryrefslogtreecommitdiff
path: root/src/3rdparty/webkit/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp')
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp61
1 files changed, 58 insertions, 3 deletions
diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp
index 4887ceee88..919d174f9c 100644
--- a/src/3rdparty/webkit/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp
+++ b/src/3rdparty/webkit/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp
@@ -22,6 +22,11 @@
#include "config.h"
#include "RotateTransformOperation.h"
+#include <algorithm>
+#include <wtf/MathExtras.h>
+
+using namespace std;
+
namespace WebCore {
PassRefPtr<TransformOperation> RotateTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
@@ -30,11 +35,61 @@ PassRefPtr<TransformOperation> RotateTransformOperation::blend(const TransformOp
return this;
if (blendToIdentity)
- return RotateTransformOperation::create(m_angle - m_angle * progress, m_type);
+ return RotateTransformOperation::create(m_x, m_y, m_z, m_angle - m_angle * progress, m_type);
const RotateTransformOperation* fromOp = static_cast<const RotateTransformOperation*>(from);
- double fromAngle = fromOp ? fromOp->m_angle : 0;
- return RotateTransformOperation::create(fromAngle + (m_angle - fromAngle) * progress, m_type);
+
+ // Optimize for single axis rotation
+ if (!fromOp || (fromOp->m_x == 0 && fromOp->m_y == 0 && fromOp->m_z == 1) ||
+ (fromOp->m_x == 0 && fromOp->m_y == 1 && fromOp->m_z == 0) ||
+ (fromOp->m_x == 1 && fromOp->m_y == 0 && fromOp->m_z == 0)) {
+ double fromAngle = fromOp ? fromOp->m_angle : 0;
+ return RotateTransformOperation::create(fromOp ? fromOp->m_x : m_x,
+ fromOp ? fromOp->m_y : m_y,
+ fromOp ? fromOp->m_z : m_z,
+ fromAngle + (m_angle - fromAngle) * progress, m_type);
+ }
+
+ const RotateTransformOperation* toOp = this;
+
+ // Create the 2 rotation matrices
+ TransformationMatrix fromT;
+ TransformationMatrix toT;
+ fromT.rotate3d((float)(fromOp ? fromOp->m_x : 0),
+ (float)(fromOp ? fromOp->m_y : 0),
+ (float)(fromOp ? fromOp->m_z : 1),
+ (float)(fromOp ? fromOp->m_angle : 0));
+
+ toT.rotate3d((float)(toOp ? toOp->m_x : 0),
+ (float)(toOp ? toOp->m_y : 0),
+ (float)(toOp ? toOp->m_z : 1),
+ (float)(toOp ? toOp->m_angle : 0));
+
+ // Blend them
+ toT.blend(fromT, progress);
+
+ // Extract the result as a quaternion
+ TransformationMatrix::DecomposedType decomp;
+ toT.decompose(decomp);
+
+ // Convert that to Axis/Angle form
+ double x = -decomp.quaternionX;
+ double y = -decomp.quaternionY;
+ double z = -decomp.quaternionZ;
+ double length = sqrt(x * x + y * y + z * z);
+ double angle = 0;
+
+ if (length > 0.00001) {
+ x /= length;
+ y /= length;
+ z /= length;
+ angle = rad2deg(acos(decomp.quaternionW) * 2);
+ } else {
+ x = 0;
+ y = 0;
+ z = 1;
+ }
+ return RotateTransformOperation::create(x, y, z, angle, ROTATE_3D);
}
} // namespace WebCore