15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef TransformationMatrix_h
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define TransformationMatrix_h
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
29bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "SkMatrix44.h"
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <string.h> //for memcpy
311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/FloatPoint.h"
321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/FloatPoint3D.h"
331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/IntPoint.h"
3493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/CPU.h"
3593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/FastAllocBase.h"
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
37c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class AffineTransform;
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class IntRect;
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class LayoutRect;
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class FloatRect;
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class FloatQuad;
4476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)class FloatBox;
45926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#if CPU(X86_64)
46926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#define TRANSFORMATION_MATRIX_USE_X86_64_SSE2
47926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif
48926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)class PLATFORM_EXPORT TransformationMatrix {
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    WTF_MAKE_FAST_ALLOCATED;
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
52926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
53926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#if CPU(APPLE_ARMV7S) || defined(TRANSFORMATION_MATRIX_USE_X86_64_SSE2)
54926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#if COMPILER(MSVC)
55926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    __declspec(align(16)) typedef double Matrix4[4][4];
56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#else
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    typedef double Matrix4[4][4] __attribute__((aligned (16)));
58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#else
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    typedef double Matrix4[4][4];
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix() { makeIdentity(); }
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix(const AffineTransform& t);
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix(const TransformationMatrix& t) { *this = t; }
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix(double a, double b, double c, double d, double e, double f) { setMatrix(a, b, c, d, e, f); }
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix(double m11, double m12, double m13, double m14,
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                         double m21, double m22, double m23, double m24,
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                         double m31, double m32, double m33, double m34,
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                         double m41, double m42, double m43, double m44)
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setMatrix(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setMatrix(double a, double b, double c, double d, double e, double f)
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
7702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        m_matrix[0][0] = a; m_matrix[0][1] = b; m_matrix[0][2] = 0; m_matrix[0][3] = 0;
7802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        m_matrix[1][0] = c; m_matrix[1][1] = d; m_matrix[1][2] = 0; m_matrix[1][3] = 0;
7902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        m_matrix[2][0] = 0; m_matrix[2][1] = 0; m_matrix[2][2] = 1; m_matrix[2][3] = 0;
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_matrix[3][0] = e; m_matrix[3][1] = f; m_matrix[3][2] = 0; m_matrix[3][3] = 1;
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setMatrix(double m11, double m12, double m13, double m14,
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                   double m21, double m22, double m23, double m24,
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                   double m31, double m32, double m33, double m34,
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                   double m41, double m42, double m43, double m44)
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
8802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        m_matrix[0][0] = m11; m_matrix[0][1] = m12; m_matrix[0][2] = m13; m_matrix[0][3] = m14;
8902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        m_matrix[1][0] = m21; m_matrix[1][1] = m22; m_matrix[1][2] = m23; m_matrix[1][3] = m24;
9002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        m_matrix[2][0] = m31; m_matrix[2][1] = m32; m_matrix[2][2] = m33; m_matrix[2][3] = m34;
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_matrix[3][0] = m41; m_matrix[3][1] = m42; m_matrix[3][2] = m43; m_matrix[3][3] = m44;
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& operator =(const TransformationMatrix &t)
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setMatrix(t.m_matrix);
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return *this;
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& makeIdentity()
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setMatrix(1, 0, 0, 0,  0, 1, 0, 0,  0, 0, 1, 0,  0, 0, 0, 1);
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return *this;
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isIdentity() const
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_matrix[0][0] == 1 && m_matrix[0][1] == 0 && m_matrix[0][2] == 0 && m_matrix[0][3] == 0 &&
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)               m_matrix[1][0] == 0 && m_matrix[1][1] == 1 && m_matrix[1][2] == 0 && m_matrix[1][3] == 0 &&
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)               m_matrix[2][0] == 0 && m_matrix[2][1] == 0 && m_matrix[2][2] == 1 && m_matrix[2][3] == 0 &&
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)               m_matrix[3][0] == 0 && m_matrix[3][1] == 0 && m_matrix[3][2] == 0 && m_matrix[3][3] == 1;
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // This form preserves the double math from input to output
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void map(double x, double y, double& x2, double& y2) const { multVecMatrix(x, y, x2, y2); }
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Map a 3D point through the transform, returning a 3D point.
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FloatPoint3D mapPoint(const FloatPoint3D&) const;
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Map a 2D point through the transform, returning a 2D point.
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Note that this ignores the z component, effectively projecting the point into the z=0 plane.
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FloatPoint mapPoint(const FloatPoint&) const;
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Like the version above, except that it rounds the mapped point to the nearest integer value.
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IntPoint mapPoint(const IntPoint& p) const
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return roundedIntPoint(mapPoint(FloatPoint(p)));
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If the matrix has 3D components, the z component of the result is
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // dropped, effectively projecting the rect into the z=0 plane
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FloatRect mapRect(const FloatRect&) const;
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Rounds the resulting mapped rectangle out. This is helpful for bounding
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // box computations but may not be what is wanted in other contexts.
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IntRect mapRect(const IntRect&) const;
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutRect mapRect(const LayoutRect&) const;
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If the matrix has 3D components, the z component of the result is
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // dropped, effectively projecting the quad into the z=0 plane
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FloatQuad mapQuad(const FloatQuad&) const;
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Map a point on the z=0 plane into a point on
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // the plane with with the transform applied, by extending
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // a ray perpendicular to the source plane and computing
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // the local x,y position of the point where that ray intersects
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // with the destination plane.
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FloatPoint projectPoint(const FloatPoint&, bool* clamped = 0) const;
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Projects the four corners of the quad
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FloatQuad projectQuad(const FloatQuad&,  bool* clamped = 0) const;
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Projects the four corners of the quad and takes a bounding box,
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // while sanitizing values created when the w component is negative.
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutRect clampedBoundsOfProjectedQuad(const FloatQuad&) const;
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    void transformBox(FloatBox&) const;
15676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m11() const { return m_matrix[0][0]; }
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setM11(double f) { m_matrix[0][0] = f; }
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m12() const { return m_matrix[0][1]; }
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setM12(double f) { m_matrix[0][1] = f; }
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m13() const { return m_matrix[0][2]; }
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setM13(double f) { m_matrix[0][2] = f; }
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m14() const { return m_matrix[0][3]; }
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setM14(double f) { m_matrix[0][3] = f; }
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m21() const { return m_matrix[1][0]; }
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setM21(double f) { m_matrix[1][0] = f; }
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m22() const { return m_matrix[1][1]; }
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setM22(double f) { m_matrix[1][1] = f; }
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m23() const { return m_matrix[1][2]; }
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setM23(double f) { m_matrix[1][2] = f; }
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m24() const { return m_matrix[1][3]; }
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setM24(double f) { m_matrix[1][3] = f; }
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m31() const { return m_matrix[2][0]; }
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setM31(double f) { m_matrix[2][0] = f; }
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m32() const { return m_matrix[2][1]; }
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setM32(double f) { m_matrix[2][1] = f; }
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m33() const { return m_matrix[2][2]; }
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setM33(double f) { m_matrix[2][2] = f; }
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m34() const { return m_matrix[2][3]; }
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setM34(double f) { m_matrix[2][3] = f; }
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m41() const { return m_matrix[3][0]; }
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setM41(double f) { m_matrix[3][0] = f; }
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m42() const { return m_matrix[3][1]; }
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setM42(double f) { m_matrix[3][1] = f; }
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m43() const { return m_matrix[3][2]; }
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setM43(double f) { m_matrix[3][2] = f; }
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m44() const { return m_matrix[3][3]; }
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setM44(double f) { m_matrix[3][3] = f; }
18902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double a() const { return m_matrix[0][0]; }
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setA(double a) { m_matrix[0][0] = a; }
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double b() const { return m_matrix[0][1]; }
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setB(double b) { m_matrix[0][1] = b; }
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double c() const { return m_matrix[1][0]; }
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setC(double c) { m_matrix[1][0] = c; }
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double d() const { return m_matrix[1][1]; }
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setD(double d) { m_matrix[1][1] = d; }
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double e() const { return m_matrix[3][0]; }
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setE(double e) { m_matrix[3][0] = e; }
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double f() const { return m_matrix[3][1]; }
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setF(double f) { m_matrix[3][1] = f; }
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
208926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // this = mat * this.
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& multiply(const TransformationMatrix&);
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& scale(double);
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& scaleNonUniform(double sx, double sy);
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& scale3d(double sx, double sy, double sz);
21402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& rotate(double d) { return rotate3d(0, 0, d); }
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& rotateFromVector(double x, double y);
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& rotate3d(double rx, double ry, double rz);
21802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The vector (x,y,z) is normalized if it's not already. A vector of
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // (0,0,0) uses a vector of (0,0,1).
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& rotate3d(double x, double y, double z, double angle);
22202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& translate(double tx, double ty);
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& translate3d(double tx, double ty, double tz);
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // translation added with a post-multiply
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& translateRight(double tx, double ty);
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& translateRight3d(double tx, double ty, double tz);
22902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& flipX();
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& flipY();
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& skew(double angleX, double angleY);
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& skewX(double angle) { return skew(angle, 0); }
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& skewY(double angle) { return skew(0, angle); }
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& applyPerspective(double p);
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool hasPerspective() const { return m_matrix[2][3] != 0.0f; }
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // returns a transformation that maps a rect to a rect
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    static TransformationMatrix rectToRect(const FloatRect&, const FloatRect&);
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isInvertible() const;
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // This method returns the identity matrix if it is not invertible.
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Use isInvertible() before calling this if you need to know.
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix inverse() const;
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // decompose the matrix into its component parts
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    typedef struct {
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        double scaleX, scaleY, scaleZ;
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        double skewXY, skewXZ, skewYZ;
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        double quaternionX, quaternionY, quaternionZ, quaternionW;
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        double translateX, translateY, translateZ;
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        double perspectiveX, perspectiveY, perspectiveZ, perspectiveW;
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } DecomposedType;
25602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool decompose(DecomposedType& decomp) const;
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void recompose(const DecomposedType& decomp);
25902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void blend(const TransformationMatrix& from, double progress);
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isAffine() const
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
26402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        return (m13() == 0 && m14() == 0 && m23() == 0 && m24() == 0 &&
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m31() == 0 && m32() == 0 && m33() == 1 && m34() == 0 && m43() == 0 && m44() == 1);
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Throw away the non-affine parts of the matrix (lossy!)
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void makeAffine();
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    AffineTransform toAffineTransform() const;
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool operator==(const TransformationMatrix& m2) const
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return (m_matrix[0][0] == m2.m_matrix[0][0] &&
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_matrix[0][1] == m2.m_matrix[0][1] &&
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_matrix[0][2] == m2.m_matrix[0][2] &&
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_matrix[0][3] == m2.m_matrix[0][3] &&
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_matrix[1][0] == m2.m_matrix[1][0] &&
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_matrix[1][1] == m2.m_matrix[1][1] &&
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_matrix[1][2] == m2.m_matrix[1][2] &&
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_matrix[1][3] == m2.m_matrix[1][3] &&
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_matrix[2][0] == m2.m_matrix[2][0] &&
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_matrix[2][1] == m2.m_matrix[2][1] &&
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_matrix[2][2] == m2.m_matrix[2][2] &&
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_matrix[2][3] == m2.m_matrix[2][3] &&
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_matrix[3][0] == m2.m_matrix[3][0] &&
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_matrix[3][1] == m2.m_matrix[3][1] &&
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_matrix[3][2] == m2.m_matrix[3][2] &&
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_matrix[3][3] == m2.m_matrix[3][3]);
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool operator!=(const TransformationMatrix& other) const { return !(*this == other); }
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // *this = *this * t
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix& operator*=(const TransformationMatrix& t)
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return multiply(t);
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
30002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // result = *this * t
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix operator*(const TransformationMatrix& t) const
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        TransformationMatrix result = *this;
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result.multiply(t);
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return result;
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isIdentityOrTranslation() const
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_matrix[0][0] == 1 && m_matrix[0][1] == 0 && m_matrix[0][2] == 0 && m_matrix[0][3] == 0
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            && m_matrix[1][0] == 0 && m_matrix[1][1] == 1 && m_matrix[1][2] == 0 && m_matrix[1][3] == 0
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            && m_matrix[2][0] == 0 && m_matrix[2][1] == 0 && m_matrix[2][2] == 1 && m_matrix[2][3] == 0
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            && m_matrix[3][3] == 1;
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isIntegerTranslation() const;
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // This method returns the matrix without 3D components.
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformationMatrix to2dTransform() const;
32102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    typedef float FloatMatrix4[16];
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void toColumnMajorFloatArray(FloatMatrix4& result) const;
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
325bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    static SkMatrix44 toSkMatrix44(const TransformationMatrix&);
326bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // multiply passed 2D point by matrix (assume z=0)
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void multVecMatrix(double x, double y, double& dstX, double& dstY) const;
330926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    FloatPoint internalMapPoint(const FloatPoint& sourcePoint) const
331926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
332926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        double resultX;
333926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        double resultY;
334926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        multVecMatrix(sourcePoint.x(), sourcePoint.y(), resultX, resultY);
335926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return FloatPoint(static_cast<float>(resultX), static_cast<float>(resultY));
336926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // multiply passed 3D point by matrix
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void multVecMatrix(double x, double y, double z, double& dstX, double& dstY, double& dstZ) const;
340926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    FloatPoint3D internalMapPoint(const FloatPoint3D& sourcePoint) const
341926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
342926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        double resultX;
343926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        double resultY;
344926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        double resultZ;
345926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        multVecMatrix(sourcePoint.x(), sourcePoint.y(), sourcePoint.z(), resultX, resultY, resultZ);
346926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return FloatPoint3D(static_cast<float>(resultX), static_cast<float>(resultY), static_cast<float>(resultZ));
347926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setMatrix(const Matrix4 m)
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m && m != m_matrix)
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            memcpy(m_matrix, m, sizeof(Matrix4));
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Matrix4 m_matrix;
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
358c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // TransformationMatrix_h
361