⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 transformationmatrix.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */#include "config.h"#include "TransformationMatrix.h"#include "FloatPoint3D.h"#include "FloatRect.h"#include "FloatQuad.h"#include "IntRect.h"#include <wtf/MathExtras.h>namespace WebCore {//// Supporting Math Functions//// This is a set of function from various places (attributed inline) to do things like// inversion and decomposition of a 4x4 matrix. They are used throughout the code////// Adapted from Matrix Inversion by Richard Carling, Graphics Gems <http://tog.acm.org/GraphicsGems/index.html>.// EULA: The Graphics Gems code is copyright-protected. In other words, you cannot claim the text of the code // as your own and resell it. Using the code is permitted in any program, product, or library, non-commercial // or commercial. Giving credit is not required, though is a nice gesture. The code comes as-is, and if there // are any flaws or problems with any Gems code, nobody involved with Gems - authors, editors, publishers, or // webmasters - are to be held responsible. Basically, don't be a jerk, and remember that anything free comes // with no guarantee.typedef double Vector4[4];typedef double Vector3[3];const double SMALL_NUMBER = 1.e-8;// inverse(original_matrix, inverse_matrix)// // calculate the inverse of a 4x4 matrix// // -1     // A  = ___1__ adjoint A//       det A//  double = determinant2x2(double a, double b, double c, double d)//  //  calculate the determinant of a 2x2 matrix.static double determinant2x2(double a, double b, double c, double d){    return a * d - b * c;}//  double = determinant3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3)//  //  Calculate the determinant of a 3x3 matrix//  in the form// //      | a1,  b1,  c1 |//      | a2,  b2,  c2 |//      | a3,  b3,  c3 |static double determinant3x3(double a1, double a2, double a3, double b1, double b2, double b3, double c1, double c2, double c3){    return a1 * determinant2x2(b2, b3, c2, c3)         - b1 * determinant2x2(a2, a3, c2, c3)         + c1 * determinant2x2(a2, a3, b2, b3);}//  double = determinant4x4(matrix)//  //  calculate the determinant of a 4x4 matrix.static double determinant4x4(const TransformationMatrix::Matrix4& m){    // Assign to individual variable names to aid selecting    // correct elements    double a1 = m[0][0];    double b1 = m[0][1];     double c1 = m[0][2];    double d1 = m[0][3];    double a2 = m[1][0];    double b2 = m[1][1];     double c2 = m[1][2];    double d2 = m[1][3];    double a3 = m[2][0];     double b3 = m[2][1];    double c3 = m[2][2];    double d3 = m[2][3];    double a4 = m[3][0];    double b4 = m[3][1];     double c4 = m[3][2];    double d4 = m[3][3];    return a1 * determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4)         - b1 * determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4)         + c1 * determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4)         - d1 * determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);}// adjoint( original_matrix, inverse_matrix )////   calculate the adjoint of a 4x4 matrix////    Let  a   denote the minor determinant of matrix A obtained by//         ij////    deleting the ith row and jth column from A.// //                  i+j//   Let  b   = (-1)    a//        ij            ji// //  The matrix B = (b  ) is the adjoint of A//                   ijstatic void adjoint(const TransformationMatrix::Matrix4& matrix, TransformationMatrix::Matrix4& result){    // Assign to individual variable names to aid    // selecting correct values    double a1 = matrix[0][0];    double b1 = matrix[0][1];     double c1 = matrix[0][2];    double d1 = matrix[0][3];    double a2 = matrix[1][0];    double b2 = matrix[1][1];     double c2 = matrix[1][2];    double d2 = matrix[1][3];    double a3 = matrix[2][0];    double b3 = matrix[2][1];    double c3 = matrix[2][2];    double d3 = matrix[2][3];    double a4 = matrix[3][0];    double b4 = matrix[3][1];     double c4 = matrix[3][2];    double d4 = matrix[3][3];    // Row column labeling reversed since we transpose rows & columns    result[0][0]  =   determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4);    result[1][0]  = - determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4);    result[2][0]  =   determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4);    result[3][0]  = - determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);            result[0][1]  = - determinant3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4);    result[1][1]  =   determinant3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4);    result[2][1]  = - determinant3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4);    result[3][1]  =   determinant3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4);            result[0][2]  =   determinant3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4);    result[1][2]  = - determinant3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4);    result[2][2]  =   determinant3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4);    result[3][2]  = - determinant3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4);            result[0][3]  = - determinant3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3);    result[1][3]  =   determinant3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3);    result[2][3]  = - determinant3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3);    result[3][3]  =   determinant3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3);}// Returns false if the matrix is not invertiblestatic bool inverse(const TransformationMatrix::Matrix4& matrix, TransformationMatrix::Matrix4& result){    // Calculate the adjoint matrix    adjoint(matrix, result);    // Calculate the 4x4 determinant    // If the determinant is zero,     // then the inverse matrix is not unique.    double det = determinant4x4(matrix);    if (fabs(det) < SMALL_NUMBER)        return false;    // Scale the adjoint matrix to get the inverse    for (int i = 0; i < 4; i++)        for (int j = 0; j < 4; j++)            result[i][j] = result[i][j] / det;    return true;}// End of code adapted from Matrix Inversion by Richard Carling// Perform a decomposition on the passed matrix, return false if unsuccessful// From Graphics Gems: unmatrix.c// Transpose rotation portion of matrix a, return bstatic void transposeMatrix4(const TransformationMatrix::Matrix4& a, TransformationMatrix::Matrix4& b){    for (int i = 0; i < 4; i++)        for (int j = 0; j < 4; j++)            b[i][j] = a[j][i];}// Multiply a homogeneous point by a matrix and return the transformed pointstatic void v4MulPointByMatrix(const Vector4 p, const TransformationMatrix::Matrix4& m, Vector4 result){    result[0] = (p[0] * m[0][0]) + (p[1] * m[1][0]) +                (p[2] * m[2][0]) + (p[3] * m[3][0]);    result[1] = (p[0] * m[0][1]) + (p[1] * m[1][1]) +                (p[2] * m[2][1]) + (p[3] * m[3][1]);    result[2] = (p[0] * m[0][2]) + (p[1] * m[1][2]) +                (p[2] * m[2][2]) + (p[3] * m[3][2]);    result[3] = (p[0] * m[0][3]) + (p[1] * m[1][3]) +                (p[2] * m[2][3]) + (p[3] * m[3][3]);}static double v3Length(Vector3 a){    return sqrt((a[0] * a[0]) + (a[1] * a[1]) + (a[2] * a[2]));}static void v3Scale(Vector3 v, double desiredLength) {    double len = v3Length(v);    if (len != 0) {        double l = desiredLength / len;        v[0] *= l;        v[1] *= l;        v[2] *= l;    }}static double v3Dot(const Vector3 a, const Vector3 b) {    return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]);}// Make a linear combination of two vectors and return the result.// result = (a * ascl) + (b * bscl)static void v3Combine(const Vector3 a, const Vector3 b, Vector3 result, double ascl, double bscl){    result[0] = (ascl * a[0]) + (bscl * b[0]);    result[1] = (ascl * a[1]) + (bscl * b[1]);    result[2] = (ascl * a[2]) + (bscl * b[2]);}// Return the cross product result = a cross b */static void v3Cross(const Vector3 a, const Vector3 b, Vector3 result){    result[0] = (a[1] * b[2]) - (a[2] * b[1]);    result[1] = (a[2] * b[0]) - (a[0] * b[2]);    result[2] = (a[0] * b[1]) - (a[1] * b[0]);}static bool decompose(const TransformationMatrix::Matrix4& mat, TransformationMatrix::DecomposedType& result){    TransformationMatrix::Matrix4 localMatrix;    memcpy(localMatrix, mat, sizeof(TransformationMatrix::Matrix4));    // Normalize the matrix.    if (localMatrix[3][3] == 0)        return false;    int i, j;    for (i = 0; i < 4; i++)        for (j = 0; j < 4; j++)            localMatrix[i][j] /= localMatrix[3][3];    // perspectiveMatrix is used to solve for perspective, but it also provides    // an easy way to test for singularity of the upper 3x3 component.    TransformationMatrix::Matrix4 perspectiveMatrix;    memcpy(perspectiveMatrix, localMatrix, sizeof(TransformationMatrix::Matrix4));    for (i = 0; i < 3; i++)        perspectiveMatrix[i][3] = 0;    perspectiveMatrix[3][3] = 1;    if (determinant4x4(perspectiveMatrix) == 0)        return false;    // First, isolate perspective.  This is the messiest.    if (localMatrix[0][3] != 0 || localMatrix[1][3] != 0 || localMatrix[2][3] != 0) {        // rightHandSide is the right hand side of the equation.        Vector4 rightHandSide;        rightHandSide[0] = localMatrix[0][3];        rightHandSide[1] = localMatrix[1][3];        rightHandSide[2] = localMatrix[2][3];        rightHandSide[3] = localMatrix[3][3];        // Solve the equation by inverting perspectiveMatrix and multiplying        // rightHandSide by the inverse.  (This is the easiest way, not        // necessarily the best.)        TransformationMatrix::Matrix4 inversePerspectiveMatrix, transposedInversePerspectiveMatrix;        inverse(perspectiveMatrix, inversePerspectiveMatrix);        transposeMatrix4(inversePerspectiveMatrix, transposedInversePerspectiveMatrix);        Vector4 perspectivePoint;        v4MulPointByMatrix(rightHandSide, transposedInversePerspectiveMatrix, perspectivePoint);         result.perspectiveX = perspectivePoint[0];        result.perspectiveY = perspectivePoint[1];        result.perspectiveZ = perspectivePoint[2];        result.perspectiveW = perspectivePoint[3];                // Clear the perspective partition        localMatrix[0][3] = localMatrix[1][3] = localMatrix[2][3] = 0;        localMatrix[3][3] = 1;    } else {        // No perspective.        result.perspectiveX = result.perspectiveY = result.perspectiveZ = 0;        result.perspectiveW = 1;    }        // Next take care of translation (easy).    result.translateX = localMatrix[3][0];    localMatrix[3][0] = 0;    result.translateY = localMatrix[3][1];    localMatrix[3][1] = 0;    result.translateZ = localMatrix[3][2];    localMatrix[3][2] = 0;    // Vector4 type and functions need to be added to the common set.    Vector3 row[3], pdum3;    // Now get scale and shear.    for (i = 0; i < 3; i++) {        row[i][0] = localMatrix[i][0];        row[i][1] = localMatrix[i][1];        row[i][2] = localMatrix[i][2];    }    // Compute X scale factor and normalize first row.    result.scaleX = v3Length(row[0]);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -