diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp')
-rw-r--r-- | src/3rdparty/webkit/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp | 61 |
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 |